ffmpeg append video with different dimensions - bash

I am cropping and adding subtitles to a video using the following:
ffmpeg -i inputfile.mov -lavfi "crop=720:720:280:360,subtitles=subs.srt:force_style='OutlineColour=&H100000000,BorderStyle=3,Outline=1,Shadow=0,MarginV=20,Fontsize=18'" -crf 1 -c:a copy output.mov
I have another video called credits.mp4 which has the same dimensions as the output.mov (after cropping). Can I do this during the above process, or would I have to use something like concat afterwards?
Using bash in Terminal on a Mac

Use the concat filter:
ffmpeg -i inputfile.mov -i credits.mp4 -lavfi "[0]crop=720:720:280:360,subtitles=subs.srt:force_style='OutlineColour=&H100000000,BorderStyle=3,Outline=1,Shadow=0,MarginV=20,Fontsize=18',setpts=PTS-STARTPTS[v0];[1]setpts=PTS-STARTPTS[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" output.mp4
Because no info was provided about your inputs I made some assumptions:
The attributes of both input files are the same as they are fed to concat. If not then perform additional filtering to conform them to a common set of parameters.
credits.mp4 has audio. If not, then add an audio file or use the anullsrc filter as an input to create silent/dummy/filler audio for proper concatenation.

Related

concatenate audio files with an image

I am trying to concatenate multiple audio files and a single image into one video file using one command.
I have list of mp3 files and a playlist file (.m3u) in a direcotry.
I managed to do this but my solution is bad:
reading the playlist file and creating a new .txt in the ffmpeg required format
concatenating the audio files using the .txt into an .mp3
concatenating the large audio file and the static image into a video
This creates 2 unnecessary files that I have to delete.
I tried a different command
ffmpeg -loop 1 -framerate 1 -i myImage.jpg -i file1.mp3 -i file2.mp3 -i file3.mp3 -filter_complex '[0:0][1:0][2:0]concat=n=3:v=0:a=1' -tune stillimage -shortest output.mp4
however im getting a Error initializing complex filters.
Invalid argument error
Another kick in the nuts is that the system im working on has spaces in the folder names.
i tried using -i "concat:file1.mp3|file2.mp3|..." however i cannot use double quote marks to quote out the path so I get an invalid argument error.
Thank you very much for your help.
Method 1: concat demuxer
Make input.txt containing the following:
file 'file1.mp3'
file 'file2.mp3'
file 'file3.mp3'
Run ffmpeg:
ffmpeg -loop 1 -framerate 1 -i myImage.jpg -f concat -i input.txt -filter_complex "[0]scale='iw-mod(iw,2)':'ih-mod(ih,2)',format=yuv420p[v]" -map "[v]" -r 15 -tune stillimage -map 1:a -shortest -movflags +faststart output.mp4
All MP3 files being input to the concat demuxer must have the same channel layout and sample rate. If they do not then convert them using the -ac and -ar options so they are all the same.
Method 2: concat filter
Update: There seems to be a bug with -shortest not working with the concat filter (I keep forgetting about that). See the method above using the concat demuxer, or replace -shortest with -t. The value for -t should equal the total duration of all three MP3 files.
ffmpeg -loop 1 -framerate 1 -i myImage.jpg -i file1.mp3 -i file2.mp3 -i file3.mp3 -filter_complex "[0]scale='iw-mod(iw,2)':'ih-mod(ih,2)',format=yuv420p[v];[1:a][2:a][3:a]concat=n=3:v=0:a=1[a]" -map "[v]" -r 15 -map "[a]" -tune stillimage -shortest -movflags +faststart output.mp4
Option descriptions
scale filter makes image have even width and height which is required when outputting YUV 4:2:0 with libx264.
format filter sets chroma subsampling to 4:2:0, otherwise libx264 will try to limit subsampling, but most players can only handle 4:2:0.
concat filter is accepting file1.mp3, file2.mp3, and file3.mp3 as inputs. Your original command was trying to concat the video to the audio resulting in Invalid argument.
-map "[v]" chooses the video output from -filter_complex.
-r 15 sets output frame rate to 15 because most players can't handle 1 fps. This is faster than setting -framerate 15.
-map "[a]" chooses the audio output from -filter_complex.
-map 1:a chooses the audio from input #1 (the second input as counting starts from 0).
-movflags +faststart after encoding finishes this option moves some data from the end of the MP4 output file to the beginning. This allows playback to begin faster otherwise the complete file will have to be downloaded first.

ffmpeg -vg -filtercomplex, create gif with color kway and limited fps

I need to create a gif file with color key (greenscreen) with 10FPS and specified size. I try to combine -vg and -filter_complex:
ffmpeg -i testdatei-c.avi -vf "fps=10,scale=320:-1:flags=lanczos" -filter_complex "[0:v]chromakey=0xFFFFFF,split[v0][v1];[v0]palettegen[p];[v1][p]paletteuse" output.gif
I get the error:
Filtergraph 'fps=10,scale=320:-1:flags=lanczos' was specified through the -vf/-af/-filter option for output stream 0:0, which is fed from a complex filtergraph.
-vf/-af/-filter and -filter_complex cannot be used together for the same stream.
All filters for a stream should be within the same filtergraph, so inside the -filter_complex
ffmpeg -i testdatei-c.avi -filter_complex "[0:v]chromakey=0xFFFFFF,fps=10,scale=320:-1:flags=lanczos,split[v0][v1];[v0]palettegen[p];[v1][p]paletteuse" output.gif

Video file is hanging after concatenating video files and drawtext to output

I'm trying to concat 3 video files and add text to output using ffmpeg.
Each part is 10 sec long.
I've end up with this code:
ffmpeg -i output3.mp4 -i output2.mp4 -i output1.mp4 -filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[v][a]; [0:v:0]drawtext=fontfile=tahoma.ttf:text=Sample text:fontcolor=white:fontsize=40:box=1:boxcolor=black#0.7:boxborderw=5:x=100:y=100" -map "[v]" -map "[a]" output.mp4
The result video has 30 seconds but it hangs after 1st part (10s). When I remove drawtext filter part (just concat), then video is fine, but without text...
Anyone can help ?
Use
ffmpeg -i output3.mp4 -i output2.mp4 -i output1.mp4 -filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[v][a]; [v]drawtext=fontfile=tahoma.ttf:text=Sample text:fontcolor=white:fontsize=40:box=1:boxcolor=black#0.7:boxborderw=5:x=100:y=100[v]" -map "[v]" -map "[a]" output.mp4
Your existing syntax applied the text on top of the video stream of the first input file, instead of the resultant video from the concat filter.

Where I made a mistake - FFmpeg (Linux) basic problem

I just started learning FFmpeg. I have code (like below), but it's doing nothing.
fmpeg -i videoplayback.mp4 -filter_complex "[1:v]trim=start=0:end=1,setpts=PTS-STARTPTS,scale=480x360,setsar=sar=16/9[intro1];
[1:v]trim=start=1:end=123.39,setpts=PTS-STARTPTS,scale=480x360,setsar=sar=16/9[main1];
[1:v]trim=start=123.39:end=124.39,setpts=PTS-STARTPTS,scale=480x360,setsar=sar=16/9[end1];
[intro1]format=pix_fmts=yuva420p, fade=t=in:st=0:d=1:alpha=1[intro1];
[end1]format=pix_fmts=yuva420p, fade=t=in:st=0:d=1:alpha=1[end1];
[intro1][main1][end1][output];
[a:1][audio]; -vcodec libx264 -map "[output]" -map"[audio]" "output.mp4"
fmpeg should be ffmpeg.
You only have one input so [1:v] should be [0:v] (it starts counting from 0).
No need for alpha for fading because you are not overlapping or blending frames.
Ending fade needs to be a fade out (not fade in).
You can't re-use filter output labels within the filtergraph.
Some of your filterchains can be combined.
Some of your labels are not associated with a filter (it appears you forgot to use the concat filter).
You can add scale and setsar at the end instead of using them for each segment.
Replace the last ; with ".
You didn't map the audio properly.
Stream copy (re-mux) the audio.
Example:
ffmpeg -i videoplayback.mp4 -filter_complex "[0:v]trim=end=1,setpts=PTS-STARTPTS,fade=t=in:d=1[intro];[0:v]trim=start=1:end=123.39,setpts=PTS-STARTPTS[main];[0:v]trim=start=123.39,setpts=PTS-STARTPTS,fade=t=out:d=1[end];[intro][main][end]concat=n=3:v=1:a=0,scale=480x360,setsar=16/9[v]" -map "[v]" -map 0:a -c:a copy output.mp4

How to combine a video and an image using "reverse" vstack?

I have an image and a video (same width). I now want to use ffmpeg to add the image above the video. Google and other SO threads the use of the vstack filter_complex tag, which works great - except that it puts the image under the video.
I've tried putting the image first and then the video, but this doesnt work. I've also tried giving the vstack command reverse inputs, but also didnt work!
The video may also contain audio which I would need to keep.
See code below:
// Works, but puts image below video (instead of above)
ffmpeg -i test.mp4 -i text.png -filter_complex vstack result.mp4
// Doesn't work at all
ffmpeg -i test.mp4 -i text.png -filter_complex '[1:v][0:v]vstack' result.mp4
// Doesn't work at all
ffmpeg -i test.mp4 -i text.png -filter_complex '[1:v][0:v]vstack=inputs=2[v]' -map '[v]' -map 0:a result.mp4
Google / SO did not yield any tips on how to achieve this so far. Do you know a solution?
Use
ffmpeg -i test.mp4 -i text.png -filter_complex '[1:v][0:v]vstack' -c:a copy -pix_fmt yuv420p result.mp4
Videos and images can have different pixel formats. When the various inputs to a stack filter don't have the same format, the filter picks the format of the first input and converts all other inputs to that format. However, some video players don't support a wide variety of formats. yuv420p is the widely supported format and so the command above forces the output to that one. Audio, if present in the MP4, will get carried over.
ffmpeg -i test.mp4 -i text.png -filter_complex '[1:v]format=yuv444p[img];[img][0:v]vstack' -c:a copy -pix_fmt yuv420p result.mp4

Resources