I'm trying to batch concat a outro video to multiple videos.
I am just tetsing it using the following command:
ffmpeg -i test.mp4 -i hello.mp4 -filter comp
lex “[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]” -map “[v]” -map “[a]” outpu
t_video.mp4
However I get the following Error:
[NULL # 04fc2c00] Unable to find a suitable output format for '[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]'
[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]: Invalid argument
Change -filter complex to -filter_complex
Replace the “smart / fancy” quotes with normal double quotes (").
Related
I need to trim and merge the video into one. I need to implement a cross fade or any smooth transitioning between each cut. Can I implement and how to implement the xfade or other ffmpeg smooth transition?
I did read this from multiple source.
Merging multiple video files with ffmpeg and xfade filter
But I still fail to generate a working code
Below is the example command and video section that I need to trim
ffmpeg -y -i example.mp4 -filter_complex
"[0:v]trim=start=0.1:end=0.7333333333333333,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=1.2333333333333334:end=4.8,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=4.966666666666667:end=10.466666666666667,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=10.6:end=13.066666666666666,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=13.733333333333333:end=17.333333333333332,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=39.9:end=40.56666666666667,setpts=PTS-STARTPTS[v0];
[0:a]atrim=start=0.1:end=0.7333333333333333,asetpts=PTS-STARTPTS[a0];
[0:a]atrim=start=1.2333333333333334:end=4.8,asetpts=PTS-STARTPTS[a1];
[0:a]atrim=start=4.966666666666667:end=10.466666666666667,asetpts=PTS-STARTPTS[a2];
[0:a]atrim=start=10.6:end=13.066666666666666,asetpts=PTS-STARTPTS[a3];
[0:a]atrim=start=13.733333333333333:end=17.333333333333332,asetpts=PTS-STARTPTS[a4];
[0:a]atrim=start=39.9:end=40.56666666666667,asetpts=PTS-STARTPTS[a5];
[v0] [a0] [v1] [a1] [v2] [a2] [v3] [a3] [v4] [a4] [v5] [a5] [a0] [a1] [a2] [a3] [a4] [a5]concat=n=6:v=1:a=1 [out]"
-map "[out]" example_COMPLEX.mp4
I generate this script file with xfade effect
ffmpeg -y -i example.mp4 -filter_complex
"[0:v]trim=start=0.1:end=0.7333333333333333,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=1.2333333333333334:end=4.8,setpts=PTS-STARTPTS[v1];
[0:v]trim=start=4.966666666666667:end=10.466666666666667,setpts=PTS-STARTPTS[v2];
[0:v]trim=start=10.6:end=13.066666666666666,setpts=PTS-STARTPTS[v3];
[0:v]trim=start=13.733333333333333:end=17.333333333333332,setpts=PTS-STARTPTS[v4];
[0:v]trim=start=39.9:end=40.56666666666667,setpts=PTS-STARTPTS[v5];
[0:a]atrim=start=0.1:end=0.7333333333333333,asetpts=PTS-STARTPTS[a0];
[0:a]atrim=start=1.2333333333333334:end=4.8,asetpts=PTS-STARTPTS[a1];
[0:a]atrim=start=4.966666666666667:end=10.466666666666667,asetpts=PTS-STARTPTS[a2];
[0:a]atrim=start=10.6:end=13.066666666666666,asetpts=PTS-STARTPTS[a3];
[0:a]atrim=start=13.733333333333333:end=17.333333333333332,asetpts=PTS-STARTPTS[a4];
[0:a]atrim=start=39.9:end=40.56666666666667,asetpts=PTS-STARTPTS[a5];
[v0][v1]xfade=transition=fade:duration=0.5:offset=8.2[x1];
[x1][v2]xfade=transition=fade:duration=0.5:offset=8.2[x2];
[x2][v3]xfade=transition=fade:duration=0.5:offset=10.166666666666666[x3];
[x3][v4]xfade=transition=fade:duration=0.5:offset=13.266666666666666[x4];
[x4][v5]xfade=transition=fade:duration=0.5:offset=13.433333333333337,format=yuv420p[video];
[a0] [a1] [a2] [a3] [a4] [a5]concat=n=6:v=1:a=1 [out]"
-map "[video]" -map "[out]" example_COMPLEX.mp4
But there is an error message
[Parsed_asetpts_13 # 0000014db55ea140] Media type mismatch between the 'Parsed_asetpts_13' filter output pad 0 (audio) and the 'Parsed_concat_30' filter input pad 0 (video)
[AVFilterGraph # 0000014db5414580] Cannot create the link asetpts:0 -> concat:0
Error initializing complex filters.
Invalid argument
I want to use a filter in an ffmpeg version compiled for Javascript (ffmpeg.js). But the parser doesn't seem to handle quotes, so I need to write the full command without quotes.
How can I write the following command without quotes?
ffmpeg -i video.mp4 -i image.jpg -filter_complex "[1][0]scale2ref[i][v];[v][i]overlay=10:10:enable=\'between(t,1,2)\'" -c:a copy output.mp4
In javascript I specify the command as follows:
worker.postMessage({
type: 'command',
arguments: "-i video.mp4 -i image.jpg -filter_complex '[1][0]scale2ref[i][v];[v][i]overlay=10:10' -c:a copy output.mp4".split(' '),
files: [
{
data: new Uint8Array(videofile),
name: 'video.mp4'
},
{
data: new Uint8Array(imagefile),
name: 'image.jpg'
},
]
});
Which however results in:
[AVFilterGraph # 0xdf4c30] No such filter:
'[1][0]scale2ref[i][v];[v][i]overlay=10:10'
I checked and the overlay filter works in simpler version without quotes, for example this command works:
arguments: "-i video.mp4 -i image.jpg -filter_complex overlay=10:10 -c:a copy output.mp4".split(' '),
I think the problem is that the ' will still be around after the split which makes ffmpeg confused. If this was a real shell the argument parser would split and parse the quotes properly.
Try to remove the ' in the original string like this:
arguments: "-i video.mp4 -i image.jpg -filter_complex [1][0]scale2ref[i][v];[v][i]overlay=10:10 -c:a copy output.mp4".split(' ')
Or maybe even skip doing split and pass a list of arguments directly instead:
arguments: ["-i", "video.mp4", "-i", "image.jpg", "-filter_complex", "[1][0]scale2ref[i][v];[v][i]overlay=10:10", "-c:a", "copy", "output.mp4"]
Here the code is for concat two video and adding watermark to that video but this code working perfectly in local but not in server.
The code is as follows:
$videoFileName = rand('111111', '999999').'_'.time().'.'.$request->file('video1')->getClientOriginalExtension();
$intermediateVideo1 = rand('1111111', '9999999').'_'.time().'.ts';
$intermediateVideo2 = rand('1111111', '9999999').'_'.time().'.ts';
$concatVideoFileName = rand('111111', '999999').'_'.time().'.'.$request->file('video1')->getClientOriginalExtension();
exec('ffmpeg -i '.$request->file('video1').' -c copy -bsf:v h264_mp4toannexb -f mpegts '.$intermediateVideo1);
exec('ffmpeg -i '.$request->file('video2').' -c copy -bsf:v h264_mp4toannexb -f mpegts '.$intermediateVideo2);
exec('ffmpeg -i "concat:'.$intermediateVideo1.'|'.$intermediateVideo2.'" -c copy -bsf:a aac_adtstoasc '.public_path('uploads/videos/'.$concatVideoFileName));
exec('ffmpeg -i '.public_path('uploads/videos/'.$concatVideoFileName).' -i '.storage_path("assets/image/watermark.png").' -filter_complex "overlay" '.public_path('uploads/videos/'.$videoFileName));
File::delete($intermediateVideo1);
File::delete($intermediateVideo2);
File::delete(public_path('uploads/videos/'.$concatVideoFileName));
I am having trouble rescaling the resolution of a video with complex filters to 720p, adding the scale to reference the video seems to cause an error
ffmpeg -re -i "https://mnmedias.api.telequebec.tv/m3u8/29880.m3u8" -i
./public/images/ACE.png -i ./public/images/logo2.jpg -i
./public/images/crunchy.png -i ./public/images/red.jpg -filter_complex "
[0]scale=1280:720[ovrl0], [va][ovrl0][v0];[1]scale=40:40[ovrl1], [v0]
[ovrl1] overlay=580:10:enable='lt(mod(t,40),10)'[v1];[2]scale=40:40[ovrl2],
[v1][ovrl2] overlay=580:10:enable='between(mod(t,40),10,20)'[v2];
[3]scale=40:40[ovrl3], [v2][ovrl3]
overlay=580:10:enable='gt(mod(t,40),20)'[v3];[4]scale=40:40[ovrl4], [v3]
[ovrl4] overlay=580:10:enable='gt(mod(t,40),30)'" -acodec aac -vcodec
libx264 -f flv "rtmp://a.rtmp.youtube.com/live2/2222-2222-2222-2222"
error output is [AVFilterGraph # 0x7f964163e9a0] No such filter: ''
Your filtergraph is malformed:
, [va][ovrl0][v0] appears to be a typo and is not applied to any filter.
Your first scale filter is referencing [v0] but [v0] does not exist (other than the orphaned declaration in the typo).
, is use to join linear filters to create a filterchain. ; is used to separate distinct filterchains. You're using , instead of ; in some locations. See FFmpeg Filter Syntax.
I'm guessing you want something like:
-filter_complex \
"[0]scale=1280:720[ovrl0]; \
[1]scale=40:40[ovrl1]; \
[2]scale=40:40[ovrl2]; \
[3]scale=40:40[ovrl3]; \
[4]scale=40:40[ovrl4]; \
[ovrl0][ovrl1] overlay=580:10:enable='lt(mod(t,40),10)'[v1]; \
[v1][ovrl2] overlay=580:10:enable='between(mod(t,40),10,20)'[v2]; \
[v2][ovrl3] overlay=580:10:enable='gt(mod(t,40),20)'[v3]; \
[v3][ovrl4] overlay=580:10:enable='gt(mod(t,40),30)'"
I am facing some problems with spaces in variables:
ALBUM=' -metadata album="Peregrinações Alheias"'
This command:
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k "$ALBUM" -y $OUT
Returns:
Unable to find a suitable output format for ' -metadata album="Peregrinações Alheias"'
And if I take out the "" from the variable:
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k $ALBUM -y $OUT
Returns:
Unable to find a suitable output format for 'Alheias"'
And I am sure I am missing something in the bash sintax...
UPDATE:
So it looks that the matter is not with spaces but with the "-metadata" argument...
The problem is that I have many metadata and I'd like to put them in just one variable. Like this:
META=' -metadata album="Peregrinações" -metadata title="Passeio ao PETAR" -metadata author="Rogério Madureira" -metadata date="2012" -metadata description="Áudio de um passeio ao PETAR" -metadata comment="Áudio capturado com TACAM DR-07MKII e Foto capturada com Canon PowerShot S5IS" '
And then:
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k $META -y $OUT
Bash interprets words in quotes as a single argument. Try
ALBUM='album="Peregrinações Alheias"'
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND \
-acodec libmp3lame -ab 128k -metadata "$ALBUM" -y $OUT
Put your command in an array instead.
ALBUM='album=Peregrinações Alheias'
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k -metadata "$ALBUM" -y $OUT
If you always want to set ALBUM, then Adam's answer is OK. But if you want to optionally set ALBUM then use this:
ALBUM="Peregrinações Alheias"
TITLE="Passeio ao PETAR"
OPTIONAL=
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND \
-acodec libmp3lame -ab 128k \
${ALBUM:+-metadata album="$ALBUM"} \
${TITLE:+-metadata title="$TITLE"} \
${OPTIONAL:+-metadata optional="$OPTIONAL"} \
-y $OUT
When not setting ALBUM the complete ${var:+subst} block is omitted. Other vars are just the same of course-
Of course this scales up to several -metadata options if there is a fixed set of data you want to set.
Using eval can do what you want... Depending on what you have in $R_IMG, $SOUND and $OUT, they may need double-quote escaping, eg. \"$SOUND\" ....
Your $META (which I assume is another name for youur originally named $ALBUM) doesn't need to be laid out like this, but it surely helps (me) ... Just spaces, as in your original works just as well.
META='
-metadata album="Peregrinações"
-metadata title="Passeio ao PETAR"
-metadata author="Rogério Madureira"
-metadata date="2012"
-metadata description="Áudio de um passeio ao PETAR"
-metadata comment="Áudio capturado com TACAM DR-07MKII e Foto capturada com Canon PowerShot S5IS"
'; META="$(echo "$META" |sed 's|"|\\\\"|g' |tr '\n' ' ')"
eval "ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k $META -y $OUT"
If you prefer to not use the sed conversion line, you simply need to change each " in $META to \\" as in this next example:
META=' -metadata album=\\"Peregrinações\\" -metadata title=\\"Passeio ao PETAR\\" -metadata author=\\"Rogério Madureira\\" -metadata date=\\"2012\\" -metadata description=\\"Áudio de um passeio ao PETAR\\" -metadata comment=\\"Áudio capturado com TACAM DR-07MKII e Foto capturada com Canon PowerShot S5IS" '
eval "ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k $META -y $OUT"
I've tested it successfully with the following ffmpeg encoding parameters:
eval "ffmpeg -i ~/input.flv -sameq -acodec libmp3lame -ab 128k $META -y ~/output.mp3"