Converting multiple ffmpeg command into one line (burn subtitle & watermark) - ffmpeg

i'm first burning subtitles of mkv and then adding watermark which is taking so long to convert one video. It takes like x2 time i guess. For example on my current server it takes 30 min on each command. My server may not be good enough. But i was thinking if there way to do this in one command instead? will it effect the speed? i really have almost zero knowledge on ffmpeg:
here is command for burning subtitle. I'm using python for achieving this:
ffmpeg -i subtitles=/Users/Test/Desktop/test.mkv -vf subtitles=subtitles=subtitles=/Users/Test/Desktop/test.mkv -c:v libx264 -c:a aac -preset ultrafast -strict -2 /Users/Test/Desktop/test.mp4
command for adding watermark:
ffmpeg -i /Users/Test/Desktop/test.mp4 -i /Users/Test/Desktop/watermark-logo.png -filter_complex "[1][0]scale2ref=w='iw*10/100':h='ow/mdar'[wm][vid]; [vid][wm]overlay=main_w-overlay_w-5:main_h-overlay_h-5" /Users/Test/Desktop/output.mp4
If there are more ways to speed up then kindly let me know. All i want to achieve this faster and expecting best result.
Thank you.

First apply the subtitles on the video and then feed that to scale2ref inside the complex filtergraph.
Use
ffmpeg -i /Users/Test/Desktop/test.mkv -i /Users/Test/Desktop/watermark-logo.png -filter_complex "[0]subtitles=/Users/Test/Desktop/test.mkv[v];[1][v]scale2ref=w='iw*10/100':h='ow/mdar'[wm][vid]; [vid][wm]overlay=main_w-overlay_w-5:main_h-overlay_h-5" -preset fast /Users/Test/Desktop/output.mp4

Related

FFmpeg Drawtext Fade Out Performance

I am developing an application that makes system calls to FFmpeg.
I found a way to get the drawtext filter isolated and fade out, but the render time increased about 5x.
I just want to see if there is something obviously wrong with the command I came up with.
ffmpeg -y -i input.mp4 -c:v libx264 -filter_complex "[0]scale=1920:1080,format=rgba, split[base][text];[text]drawtext=fontfile=font1.ttf:text='Text1':fontcolor= 'white':fontsize=34:box=1:boxcolor=mediumpurple:boxborderw=50:x=0:y=690,format=yuva444p,drawtext=fontfile=./resources/fonts/font2.ttf:text='Text2':fontcolor='white':fontsize=26:x=0:y=725,fade=t=out:st=12:d=0.2:alpha=1[title];[base][title]overlay" -force_key_frames "expr:gte(t,n_forced*0.05)" output.mp4
Yes! There is something obviously wrong with it. There is no need to split the stream and process both.
After some trial and error, I was able to put together this command which runs much much faster; virtually no overhead to add the fading title card.
ffmpeg -i input.mp4 -filter_complex "scale=1920:1080,drawtext=fontfile=font1.ttf:text=Text1':fontcolor='white':fontsize=34:box=1:boxcolor=mediumpurple:boxborderw=50:x=12:y=690:alpha='min(between(t,0,2.2),lerp(0,1,(1+((2-t)/0.2))))',drawtext=fontfile=font2.ttf:text='Text2':fontcolor='white':fontsize=26:x=12:y=730:alpha='min(between(t,0,2.2),lerp(0,1,(1+((2-t)/0.2))))'" output.mp4

multiple input files with complex operations in ffmpeg

I have just started using ffmpeg for one of my project. I have very limited knowledge of ffmpeg.
I need a help on below problem. Thanks in advance.
I have two files:-
Audio File
Video File
I want to generate single file after performing below operations:-
trim the audio file to custom start and stop point.
merge audio and video file to a single file (video file is of same size)
apply speed filter on the generated file.
I am able to achieve the output but with three different ffmpeg commands due to which it is taking lot of time. I want to achieve the all there tasks in a single ffmpeg command.
Thanks.
Use the setpts and atempo (or rubberband) filters. This example will double the speed:
ffmpeg -i video.mp4 -ss 3 -t 10 -i audio.mp3 -filter_complex "[0:v]setpts=0.5*PTS[v];[1:a]atempo=2[a]" -map "[v]" -map "[a]" -shortest output.mp4
-ss 3 will skip beginning 3 seconds in audio.mp3.
-t 10 will limit audio.mp3 duration to 10 seconds.
-shortest will make output.mp4 duration the same as the shortest output stream duration.

Fastest way to Add Image into Video using FFMPEG at First 20 Seconds

Anyone knows the fastest way to add image into video at first 20 seconds?
I have tried it, but it seemed like FFMPEG re-encoded the whole video even after 20 seconds which took a long time..
here my code:
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=5:5:enable='between(t,0,20)'" output.mp4
Fast
Use a faster -preset and stream copy (re-mux) the audio instead of re-encoding it:
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=5:5:enable='between(t,0,20)'" -preset fast -c:a copy output.mp4
Faster
You could encode the ~20 segment conforming to the same parameters as the main input, then concatenate with the concat demuxer in stream copy mode. However, this will be troublesome because conforming parameters is not trivial for most users, the concat inpoint directive is not guaranteed to seek accurately with non-intra inputs, and you could end up with timestamp issues anyway.
Fastest
The most fastest way is to use a player to overlay the logo:
mpv --lavfi-complex="[vid1][vid2]overlay=5:5:enable='between(t,0,20)[vo]" video.mp4 --external-file=image.png

FFmpeg how generate a sequence of videos with bash

i try to write an .sh that read a folder create a playlist of mp4 files and then generate an only big video with a sequence of all videos find in the folder, and encode it for dash:
printf "file '%s'\n" ./*.mp4 > playlist.sh
ffmpeg -f concat -safe 0 -i playlist.sh -c copy concat.mp4
Till now i follow the demux concat official guido to ffmpeg website.
Without result, also the following give me "more than 1000 frames duplicated between videos of the sequence"
ffmpeg -f concat -i playlist.sh -c:a aac -b:a 384k -ar 48000 -ac 2 -c:v libx264 -x264opts 'keyint=50:min-keyint=50:no-scenecut' -r 25 -b:v 2400k -maxrate 2400k -bufsize 1200k -vf "scale=-1:432 " out.mp4
Thanks a lot
Sry, cannot comment (yet)...
Your commands are correct, I could just concat some sample videos.
Do you always get the mentioned error, or also something else? And is the video working, or no video is created?
In most cases, the input video is incorrect. Wrong input format (not fitting to file extension) or worse like ending at wrong frame.
Perhaps you can make the video available?
PS: Needed to add -safe 0 to the second command to avoid error [concat # 0x7fbfd1000000] Unsafe file name './small.mp4'
Hint: Do not use file extension .sh for your list of video files. This extension is used for shell scripts, so it can be confusing. Just use .txt.
UPDATE #Massimo Vantaggio
We should not create new answers, but I cannot comment yours and I also don't know how to continue our discussion, so I edit my answer.
Your videos don't look very different. Can't see, what's wrong with the first one.
Perhaps you could use ffprobe -report input.mp4 to get more informations. Look for errors or warnings.
My assumption is still that the video was cut in a hard way (by conversion software), so keyframes are messed up or something else.
You can also try to first reencode your video with ffmpeg. After that, it should be complete compatible with ffmpeg ;)
Something like this:
ffmpeg -i small.mp4 -acodec aac -ab 192k -vcodec libx264 -vb 1024k -f mp4 output.mp4
Use -ab and -vb from your input video, or at least the bitrate from input. Quality will decrease a little bit and file size increase, but it should be okay.

bad quality output when using ffmpeg and drawtext filter

I have vps server and i setup ffmpeg successfully. I downloaded 720p hd video. I need only add text on video. And i added successfuly but video quality is very low after adding. I use this command
ffmpeg -i a.mp4 -vf "drawtext=fontsize=30:box=1:fontfile=/usr/share/fonts/a.ttf:text='Stack Overflow':x=(w-text_w)/2:y=(h-text_h-line_h)/2" -strict -2 c.mp4
I dont know -strict -2 command. i try and ffmpeg error say add -strict -2 then i add. Now i need only add text, not change video quality.
You haven't specified any bitrate. So it is going to go for default bitrate of 200kbps which will give you bad output if your size is 720p like you claim. Please specify the bitrate to a reasonable value.
Define Bitrate..
For example
ffmpeg -i input.mp4 -filter_complex "drawtext=fontsize=27:text=\'hellow\':x=(10):y=(main_h-30):fontcolor=white" -b:v 3M output.mp4

Resources