MetaCoder
MetaCoder

Reputation: 478

FFMPEG -- Error when trying to concat multiple files with and without audio

Ok so thanks to a fellow user I have the following FFMPEG command that concats 4 videos together. Now if I use this command with 4 video files that all have audio everything works! However, if 1 or more of the videos do not have sound I get a "matches no streams" error.

Can someone spot whats wrong here please?

Video Input 1 - No Audio so adding the anullsrc Video 2 - Has Audio Video 3 - No Audio Video 4 - Has Audio

ffmpeg -i noSound1.mp4 -i story1.mp4 -i noSound2.mp4 -i story2.mp4 -t 0.1 -f lavfi -i anullsrc=channel_layout=stereo -filter_complex 
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v0]; 
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v1]; 
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v2]; 
 [3:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v3]; 
 [0:a]aformat=sample_rates=48000:channel_layouts=stereo[a0]; 
 [1:a]aformat=sample_rates=48000:channel_layouts=stereo[a1]; 
 [2:a]aformat=sample_rates=48000:channel_layouts=stereo[a2]; 
 [3:a]aformat=sample_rates=48000:channel_layouts=stereo[a3]; 
 [v0][a0][v1][a1][v2][a2][v3][a3]concat=n=4:v=1:a=1[v][a]" 
-map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart testOutput.mp4

Here is the error:

Stream specifier ':a' in filtergraph description [0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v0];  [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v1];  [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v2];  [3:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v3];  [0:a]aformat=sample_rates=48000:channel_layouts=stereo[a0];  [1:a]aformat=sample_rates=48000:channel_layouts=stereo[a1];  [2:a]aformat=sample_rates=48000:channel_layouts=stereo[a2];  [3:a]aformat=sample_rates=48000:channel_layouts=stereo[a3];  [v0][a0][v1][a1][v2][a2][v3][a3]concat=n=4:v=1:a=1[v][a] matches no streams.

Now a slightly separate question. If I have N input videos where i do not know if they have sound or not, is there a way I can have a loop that does the above without having massive amounts of command lines? Many thanks!

Upvotes: 0

Views: 463

Answers (1)

llogan
llogan

Reputation: 134093

Can someone spot whats wrong here please?

In your command you are attempting to feed the audio from noSound1.mp4 ([0:a]) and noSound2.mp4 ([2:a]) to aformat, but these inputs have no audio.

All inputs must either have audio or no audio: you can't mix them. So that's what anullsrc (the silent audio generator) is for. It will make dummy/silent/filler audio for the inputs without audio. For the inputs without audio you need to feed anullsrc ([4] or [4:a] in your example) to concat:

ffmpeg -i noSound1.mp4 -i story1.mp4 -i noSound2.mp4 -i story2.mp4 -t 0.1 -f lavfi -i anullsrc=channel_layout=stereo -filter_complex 
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v0]; 
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v1]; 
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v2]; 
 [3:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v3]; 
 [1:a]aformat=sample_rates=48000:channel_layouts=stereo[a1]; 
 [3:a]aformat=sample_rates=48000:channel_layouts=stereo[a3]; 
 [v0][4][v1][a1][v2][4][v3][a3]concat=n=4:v=1:a=1[v][a]" 
-map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart testOutput.mp4

To understand the [0:a] syntax see FFMPEG mux video and audio (from another video) - mapping issue and FFmpeg Wiki: Map.

Now a slightly separate question. If I have N input videos where i do not know if they have sound or not, is there a way I can have a loop that does the above without having massive amounts of command lines?

No, but you can use ffprobe to determine if an input has audio or not which should be helpful in scripting a solution. See Using ffprobe to check audio-only files.

Upvotes: 1

Related Questions