How to generate tile with video thumbnails with right timecode - ffmpeg

I'm using FFMPEG library for generating video thumbnails every 5 sec with time codes using following command:
ffmpeg \
-i 20051210-w50s.flv \
-y \
-frames 1 \
-vf " \
select=not(mod(t\,5)), \
scale=320:-1, \
drawtext=fontfile=/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf: \
timecode='00\\:00\\:00\\:00': r=25: fontcolor=white: x=220: y=220: box=1: boxcolor=black#0.5, \
tile=5x2" \
-vsync 0 \
out.jpg
It gererate right thumbnails tile, but timecodes is wrong. How to solve this issue?

The drawtext filter is not referencing the timestamp. It uses a simple counter that increments the timecode for each new frame. So, the way to do this is to draw each timecode and then drop frames.
ffmpeg \
-i 20051210-w50s.flv \
-y \
-frames 1 \
-vf " \
scale=320:-1, \
drawtext=fontfile=/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf: \
timecode='00\\:00\\:00\\:00': r=25: fontcolor=white: x=220: y=220: box=1: boxcolor=black#0.5, \
select=not(mod(t\,5)), \
tile=5x2" \
-vsync 0 \
out.jpg

Drawing text for each frame before selecting the useful ones solves the problem but also introduces performance losses. I made an experiment about it, and the result confirmed my guess.
A better solution would be keeping calling "select" first and using text='%{pts:hms}' instead of timecode.
ffmpeg \
-i 20051210-w50s.flv \
-y \
-frames 1 \
-vf \
"select=not(mod(t\,5)), \
scale=320:-1, \
drawtext=text='%{pts:hms}': fontfile=/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf: \
fontcolor=white: x=220: y=220: box=1: boxcolor=black#0.5, \
tile=5x2" \
-vsync 0 \
out.jpg

Related

ffmpeg - create a morph video between 2 images (png solid hex color) 0.55 seconds for a length of 10 seconds

currently i create with imagick (convert -size 640x480 xc:#FF000 hex1.png and hex2.png) 2 png images and save both png files.
now i need the following (but i have no idea how i can do that (maybe ffmpeg?)):
create a video 640x480 for example a length of 10 seconds like this method:
0.00s (hex1) > 0.55s (hex2) > 1.10s (hex1) > 1.65s (hex2) > 2.2s (hex1).... until the 10 seconds has reached.
the hex1 and hex2 images should always morph/fade from hex1 => hex2 => hex1, ...
but the time is very critical. the time must be exact always have 0.55.
maybe i can create on same way direct the HEX colors without creating first a png image for that purposes.
can anybody helps me how i can do that best way?
thank you so much and many greets iceget
currently i have created only a single image with that function:
ffmpeg -loop 1 -i hex1.png -c:v libx264 -t 10 -pix_fmt yuv420p video.mp4
Here is one of the approaches to achieving your goal without pre-creation of images:
ffmpeg -hide_banner -y \
-f lavfi -i color=c=0x0000ff:size=640x480:duration=0.55:rate=20 \
-filter_complex \
"[0]fade=type=out:duration=0.55:color=0xffff00[fade_first_color]; \
[fade_first_color]split[fade_first_color1][fade_first_color2]; \
[fade_first_color1]reverse[fade_second_color]; \
[fade_first_color2][fade_second_color]concat[fade_cycle]; \
[fade_cycle]loop=loop=10/(0.55*2):size=0.55*2*20,trim=duration=10" \
flicker.mp4
Since loop filter operates with frames, not seconds, and you have time constraints, you may choose only the few FPS rates correspondig to the integer number of frames that fit in the 0.55 seconds period (e.g. 20, 40, 60).
The filtergraph is self-explanable.
The result of such command will be like this:
Almost universal way (added in response to the OP's new questions)
#!/bin/bash
# Input parameters
color_1=0x0000ff
color_2=0xffff00
segment_duration=0.55
total_duration=10
# Magic calculations
sd_numerator=${segment_duration#*.}
sd_denominator=$(( 10**${#sd_numerator} ))
FPS=$(ffprobe -v error -f lavfi "aevalsrc=print('$sd_denominator/gcd($sd_numerator,$sd_denominator)'\,16):s=1:d=1" 2>&1)
FPS=${FPS%.*}
# Preparing the output a little bit longer than total_duration
# and mark the cut point with the forced keyframe
ffmpeg -hide_banner -y \
-f lavfi -i color=c=$color_1:size=640x480:duration=$segment_duration:rate=$FPS \
-filter_complex \
"[0]fade=type=out:duration=$segment_duration:color=$color_2[fade_first_color]; \
[fade_first_color]split[fade_first_color1][fade_first_color2]; \
[fade_first_color1]reverse[fade_second_color]; \
[fade_first_color2][fade_second_color]concat[fade_cycle]; \
[fade_cycle]loop=loop=ceil($total_duration/($segment_duration*2))+1: \
size=$segment_duration*2*$FPS,fps=fps=25" \
-force_key_frames $total_duration \
flicker_temp.mp4
# Fine cut of total_duration
ffmpeg -hide_banner -y -i flicker_temp.mp4 -to $total_duration flicker_${total_duration}s.mp4
# Clean up
rm flicker_temp.mp4

How to increase line-height of text using drawtext with FFMPEG?

I'm using the current code to create a video with some text of several lines. When executed I'm receiving a video with the text joined vertically because of lacking space. How do I do to add line-height space?
ffmpeg -i videoInput.mp4 \
-vf drawtext="./font/Roboto/Roboto-Bold.ttf: \
text='testing text \ntesting text \ntesting text':\
fontcolor=yellow:\
fontsize=36:\
box=1:\
boxcolor=black#0.5: \
boxborderw=160:\
x=(w-text_w)/2:\
y=(h-text_h)/2"\
-codec:a copy \
videoOutput.mp4
To increase the line-height add a line_spacing parameter to the command,(http://ffmpeg.org/ffmpeg-filters.html#drawtext-1)
So it looks like:
ffmpeg -i videoInput.mp4 \
-vf drawtext="./font/Roboto/Roboto-Bold.ttf: \
text='testing text \ntesting text \ntesting text':\
line_spacing=30:\
fontcolor=yellow:\
fontsize=36:\
box=1:\
boxcolor=black#0.5: \
boxborderw=160:\
x=(w-text_w)/2:\
y=(h-text_h)/2"\
-codec:a copy \
videoOutput.mp4
Or
Some trick is to append a double breakline on the desired text. It would look like:
text='testing text \n\ntesting text \n\ntesting text'
ffmpeg -i videoInput.mp4 \
-vf drawtext="./font/Roboto/Roboto-Bold.ttf: \
text='testing text \n\ntesting text \n\ntesting text':\
fontcolor=yellow:\
fontsize=36:\
box=1:\
boxcolor=black#0.5: \
boxborderw=160:\
x=(w-text_w)/2:\
y=(h-text_h)/2"\
-codec:a copy \
videoOutput.mp4

How to crossfade 3 videos using ffmpeg?

I am currently using below command that is working fine for 2 videos but how to crossfade for 3 videos:
ffmpeg -report -i "video2.mp4" -i "video3.mp4" -an \
-filter_complex \
"[0:v]trim=start=0:end=9,setpts=PTS-STARTPTS[firstclip]; \
[1:v]trim=start=1,setpts=PTS-STARTPTS[secondclip]; \
[0:v]trim=start=9:end=10,setpts=PTS-STARTPTS[fadeoutsrc]; \
[1:v]trim=start=0:end=1,setpts=PTS-STARTPTS[fadeinsrc]; \
[fadeinsrc]format=pix_fmts=yuva420p,fade=t=in:st=0:d=1:alpha=1[fadein]; \
[fadeoutsrc]format=pix_fmts=yuva420p,fade=t=out:st=0:d=1:alpha=1[fadeout]; \
[fadein]fifo[fadeinfifo]; \
[fadeout]fifo[fadeoutfifo]; \
[fadeoutfifo][fadeinfifo]overlay[crossfade]; \
[firstclip][crossfade][secondclip]concat=n=3" \ outputname.mp4
Thanks!

ffmpeg - overlay multiple fading texts with different colors

I have problem with this ffmpeg command, it works fine if the fading text is in white font color, but if I change the fontcolor to something else (for example black), the fading text will not appear, any ideas?
ffmpeg -i ./based_video/480/clip3.mp4 -filter_complex "color=black:100x100[c]; [c][0]scale2ref[ct][mv0]; \
[ct]setsar=1,split=3[t1][t2][t3]; \
[t1]drawtext=fontfile=/usr/share/fonts/truetype/roboto/Roboto-Bold.ttf:text='\$30,000.0':fontsize=40:fontcolor=white,split[text1][alpha1]; \
[text1][alpha1]alphamerge,fade=t=in:st=1:d=1:alpha=1,fade=t=out:st=5:d=1:alpha=1[txta1]; \
[t2]drawtext=fontfile=/usr/share/fonts/truetype/roboto/Roboto-Bold.ttf:text='\$30,000.0':fontsize=40:fontcolor=white,split[text2][alpha2]; \
[text2][alpha2]alphamerge,fade=t=in:st=1:d=1:alpha=1,fade=t=out:st=5:d=1:alpha=1[txta2]; \
[t3]drawtext=fontfile=/usr/share/fonts/truetype/roboto/Roboto-Bold.ttf:text='\$30,000.0':fontsize=40:fontcolor=white,split[text3][alpha3]; \
[text3][alpha3]alphamerge,fade=t=in:st=1:d=1:alpha=1,fade=t=out:st=5:d=1:alpha=1[txta3]; \
[mv0][txta1]overlay=x='100':y='200':shortest=1[mv1]; \
[mv1][txta2]overlay=x='300':y='200':shortest=1[mv2]; \
[mv2][txta3]overlay=x='500':y='200':shortest=1" \
-c:v libx264 -c:a copy ./output_video/testnew-clip3-output.mp4
full log is here :
https://docs.google.com/document/d/1y9Dnn0Df75J8P_hZ6LjHTX2dk-8z97UnTjlX8dnc0v0/edit?usp=sharing
Thanks in advance
You're feeding the plane with the drawn text as the alpha. If the text is black, then the alpha is black and so the text won't appear. You can skip the alpha creation and merging altogether.
ffmpeg -i ./based_video/480/clip3.mp4 -filter_complex "color=black#0:100x100,format=yuva444p[c]; [c][0]scale2ref[ct][mv0]; \
[ct]setsar=1,split=3[t1][t2][t3]; \
[t1]drawtext=fontfile=/usr/share/fonts/truetype/roboto/Roboto-Bold.ttf:text='\$30,000.0':fontsize=40:fontcolor=white,fade=t=in:st=1:d=1:alpha=1,fade=t=out:st=5:d=1:alpha=1[txta1]; \
[t2]drawtext=fontfile=/usr/share/fonts/truetype/roboto/Roboto-Bold.ttf:text='\$30,000.0':fontsize=40:fontcolor=white,fade=t=in:st=1:d=1:alpha=1,fade=t=out:st=5:d=1:alpha=1[txta2]; \
[t3]drawtext=fontfile=/usr/share/fonts/truetype/roboto/Roboto-Bold.ttf:text='\$30,000.0':fontsize=40:fontcolor=white,fade=t=in:st=1:d=1:alpha=1,fade=t=out:st=5:d=1:alpha=1[txta3]; \
[mv0][txta1]overlay=x='100':y='200':shortest=1[mv1]; \
[mv1][txta2]overlay=x='300':y='200':shortest=1[mv2]; \
[mv2][txta3]overlay=x='500':y='200':shortest=1" \
-c:v libx264 -c:a copy ./output_video/testnew-clip3-output.mp4

FFMPEG | AVFilterGraph error WINDOWS and DEBIAN

I trying to use FFMPEG for modify a vidéo.
I have this command on this forum but I have some error
ffmpeg -i input -filter_complex \
"[0:v]crop=iw/2:ih/2:0:0[lt]; \
[0:v]crop=iw/2:ih/2:ow:0[rt]; \
[0:v]crop=iw/2:ih/2:0:oh[lb]; \
[0:v]crop=iw/2:ih/2:ow:oh[rb]; \
[lb][lt]hstack[top]; \
[rt][rb]hstack[bottom]; \
[top][bottom]vstack" \
-c:a copy output
Error windows : [AVFilterGraph # 00000000035ecc20] No such filter: '\'
Error Debian : [AVFilterGraph # 0xe152ceab4e0] No such filter: ' '
Any solution to fix it ? Thx !
I have the solution ! Just remove all \ an all in single line !
ffmpeg -i big_buck_bunny.mp4 -filter_complex "[0:v]crop=iw/2:ih/2:0:0[lt]; [0:v]crop=iw/2:ih/2:ow:0[rt]; [0:v]crop=iw/2:ih/2:0:oh[lb]; [0:v]crop=iw/2:ih/2:ow:oh[rb]; [lb][lt]hstack[top]; [rt][rb]hstack[bottom]; [top][bottom]vstack" -c:a copy test.mp4

Resources