FFMPEG getting exact desired file size - ffmpeg

I have a 2 seconds length 1920x1080 dimensions video and I want to size of the file to be 3Mb
I tried the method below:
const fileSize = 3000; // Kilobytes
const duration = 2; // Second
const videoBitRate = Math.round((fileSize * 8) / duration));
So videoBitRate is 12000 right now
Then I use Two-Pass encoding
ffmpeg -y -i input -c:v libx264 -preset medium -b:v 12000k -pass 1 -c:a aac -b:a 128k -f mp4 /dev/null && \
ffmpeg -i input -c:v libx264 -preset medium -b:v 12000k -pass 2 -c:a aac -b:a 128k output.mp4
Expecting file size: 3Mb
Actual file size: 2.6Mb
If I'd use a 35 seconds video,
videoBitRate = 685k
ffmpeg -y -i input -c:v libx264 -preset medium -b:v 685k -pass 1 -c:a aac -b:a 128k -f mp4 /dev/null && \
ffmpeg -i input -c:v libx264 -preset medium -b:v 685k -pass 2 -c:a aac -b:a 128k output.mp4
Expecting file size: 3Mb
Actual file size: 3.6Mb
What is the point I'm doing wrong?
Isn't there a more accurate way to calculate? Why are the results always different?

Related

ffmpeg text overlay both ${frame_num} and :timecode values?

Text overlay does not work if framenum 1..n and timecode hh:mm:ss:frame attributes are used together, how do overlay both running values?
Does not work, only timecode is incrementing and framenum is a as a text:
ffmpeg.exe -hide_banner -nostats ^
-i "video_25fps.mp4" -threads 4 -preset fast ^
-c:v libx264 -profile:v main -level 4.0 -s:v 640x360 -b:v 512k -pix_fmt yuv420p ^
-refs 3 -bf 3 -g 50 -keyint_min 25 -b_strategy 1 -flags +cgop -sc_threshold 0 ^
-movflags "negative_cts_offsets+faststart" ^
-vf "drawtext=fontfile=/fonts/Roboto-Regular.ttf:fontcolor=White:fontsize=38:box=1:boxcolor=black:x=(w-text_w)/2:y=text_h-line_h+60:text='H264\ 640x360\ 512k\ frame\: %{frame_num}\ ':start_number=1:timecode=00\\:00\\:00\\:00:rate=25" ^
-an -sn -t 30 -y output.mp4
Works if framenum only:
-vf "drawtext=fontfile=/fonts/Roboto-Regular.ttf:fontcolor=White:fontsize=38:box=1:boxcolor=black:x=(w-text_w)/2:y=text_h-line_h+60:text='H264\ 640x360\ 512k\ frame\: %{frame_num}':start_number=1"
Works if timecode only:
-vf "drawtext=fontfile=/fonts/Roboto-Regular.ttf:fontcolor=White:fontsize=38:box=1:boxcolor=black:x=(w-text_w)/2:y=text_h-line_h+60:text='H264\ 640x360\ 512k\ ':timecode='00\:00\:00\:00':rate=25"
You need to double up on the drawtext instruction, separating them with a comma.
i.e.
ffmpeg -i input.mp4 -vf "drawtext=text='Frame\: %{frame_num}': start_number=1: x=(w-tw)/2: y=h-(2*lh):font='Noto mono':fontsize=40:alpha=0.5:box=1:boxborderw=4,drawtext=text='':x=(w-tw)/2:y=(lh):fontsize=40:fontcolor=white:timecode='00\:00\:00\:00':timecode_rate=25" -c:a copy output2.mp4

ffmpeg mpegts muxer to dvb receiver

transport stream over ip generated by ffmpeg is not detected by DVB Receiver.Receiver status is PCR not detected.I am using the following command
ffmpeg -re -i testvideo.mp4 -map 0:v:0 -map 0:a:0 -pix_fmt yuv420p -r 25 -s 720x576 -aspect 4:3 -qmin 2 -qmax 35 -b:v 1000k -minrate 1000k -maxrate 1000k -bufsize 500k -vcodec libx264 -acodec aac -ab 128k -ac 2 -f mpegts -mpegts_original_network_id 1 -mpegts_transport_stream_id 1 -mpegts_service_id 1 -mpegts_pmt_start_pid 4096 -streamid 0:289 -streamid 1:337 -program title="service1":st=0:st=1 -metadata service_provider="MYCALL" -muxrate 2000k -metadata service_name="My Station ID" -y udp://239.0.0.1:5000?pkt_size=1316&localaddr=192.168.100.114

How to reset PTS for Stream

I am trying reset pts on input stream and create new pts and publish stream to RTMP.
ffmpeg -re -f lavfi -i "movie=${SOURCE}:s=0+1[out0][out1];[0:v]setpts=N/(FRAME_RATE*TB),[0:a]asetpts=N/(FRAME_RATE*TB)" \
-r 24 -crf 20 \
-c:v libx264 \
-c:a aac -ar 44100 -ab 128k -ac 2 -strict -2 \
-f flv ${DEST}
If I remove the setpts and asetpts filters them command works. But I need to setpts and asetpts at source before it is given to encoder.
Please help.
Alter the PTS outside the source graph.
ffmpeg -re -f lavfi -i "movie=${SOURCE}:s=0+1" \
-vf setpts=N/FRAME_RATE/TB -af asetpts=N/SR/TB
-r 24 -crf 20 \
-c:v libx264 \
-c:a aac -ar 44100 -ab 128k -ac 2 -strict -2 \
-f flv ${DEST}

Encode input stream mpg2 to output stream h264 CBR

Output should be:
- 2,5 Mbit/s CBR H.264/mpeg4
- Audio 128kbit/s joint stereo mpeg2
Command i am using as last looks like this, and stream is not CBR.
ffmpeg.exe "udp://xxx.xx.xxx.x:xxxx?fifo_size=700000&buffer_size=12000k&pkt_size=1316"
-vf "hqdn3d" -c:v libx264 -refs 4
-minrate:v 2500k -me_method hex -maxrate 2500k -sc_threshold 45 -bufsize 300k -b:v 2500k-bsf
h264_mp4toannexb -flags +ilme+ildct+loop+mv4+cgop -profile:v baseline
-x264opts 8x8dct -x264opts mixed-refs -x264opts weightp=0 -g 100
-c:a mp2 -ab 128k -ar 48000 -fflags +igndts+genpts+sortdts -f mpegts
"udp://#xxx.xxx.x.x:xxxx?buffer_size=100k&pkt_size=1316" -threads 0 -v 0
Try
ffmpeg "udp://xxx.xx.xxx.x:xxxx?fifo_size=700000&buffer_size=12000k&pkt_size=1316"
-vf "hqdn3d" -me_method hex -sc_threshold 45 -refs 4 -flags +ilme+ildct+loop+mv4+cgop -g 100
-c:v libx264 -minrate:v 2300k -maxrate 2372k -bufsize 2400k -b:v 2300k
-bsf h264_mp4toannexb -profile:v baseline
-x264opts mixed-refs:weightp=0:nal-hrd=cbr
-c:a mp2 -ab 128k -ar 48000 -fflags +igndts+genpts+sortdts
-threads 0 -v 0
-f mpegts -muxrate 2500k "udp://#xxx.xxx.x.x:xxxx?buffer_size=100k&pkt_size=1316"
Added nal-hrd=cbr to x264opts and removed 8x8dct which is used in High profile.
If your input is interlaced, deinterlace it (add yadif filter).

How to scale and add correct a logo in ffmpeg command?

I am trying to apply a watermark and also to scale it to the current video size via ffmpeg command:
Here is my inital comand that works without watermark
ffmpeg -v 0 -vcodec h264_qsv -i 'udp://#some.ip:1234?fifo_size=1000000&overrun_nonfatal=1&buffer_size=1000000' -vf scale=iw:ih -profile baseline -acodec aac -ac 1 -ar 44100 -ab 64k -deinterlace -vcodec h264_qsv -bufsize 4000k -maxrate 3500k -preset veryfast -vb 2000k -f flv rtmp://127.0.0.1/app/720
Now I tried to add the picture as a watermark. There was a conflict while using with -vf scale=-1:ih*.5, in order to eliminate the problem I used -s 1280x720 to specify the resolution for the video stream, it worked but not properly.
ffmpeg -v 0 -vcodec h264_qsv -i 'udp://#some.ip:1234?fifo_size=1000000&overrun_nonfatal=1&buffer_size=1000000' -i logo.png -filter_complex "overlay=10:10" -s 1280x720 -profile baseline -acodec aac -ac 1 -ar 44100 -ab 64k -deinterlace -vcodec h264_qsv -bufsize 4000k -maxrate 3500k -preset veryfast -vb 2000k -f flv rtmp://some.ip/app/720
The problem:
How can I specify in the ffmpeg command the both sizes of video and logo(watermark) so they don't conflict with each other and they auto adjust like -vf scale=-1:ih*.5 dose.
Thank you!
The scale2ref filter allows one to a video/image stream with reference to the dimensions of another video or image stream
e.g.
ffmpeg -v 0 -vcodec h264_qsv -i 'udp://#some.ip:1234?fifo_size=1000000&overrun_nonfatal=1&buffer_size=1000000' \
-loop 1 -i logo.png \
-filter_complex "[1:v][0:v]scale2ref=iw/8:-1[logo][0v];[0v][logo]overlay=10:10[v]" \
-map "[v]" -map 0:a \
-profile baseline -acodec aac -ac 1 -ar 44100 -ab 64k \
-deinterlace -vcodec h264_qsv -bufsize 4000k -maxrate 3500k \
-preset veryfast -vb 2000k \
-f flv rtmp://some.ip/app/720
Here 1:v - the logo image - is being scaled to 1/8th the width of [0:v], the H.264 stream.
For the command given in the comments:
ffmpeg -v 0 -vcodec h264_qsv -i 'input' \
-loop 1 -i logo.png \
-filter_complex "[0:v]scale=iw:ih[v0]; \
[1:v][v0]scale2ref=iw/8:-1[logo][0v];[0v][logo]overlay=10:10[v]" \
-map "[v]" -map 0:a \
-profile baseline -acodec aac -ac 1 -ar 44100 -ab 64k \
-deinterlace -vcodec h264_qsv -bufsize 4000k -maxrate 3500k \
-preset veryfast -vb 2000k \
-f flv out1 \
-filter_complex "[0:v]scale=-1:ih/2[v0]; \
[1:v][v0]scale2ref=iw/8:-1[logo][0v];[0v][logo]overlay=10:10[v2]" \
-map "[v2]" -map 0:a \
-profile baseline -acodec aac -ac 1 -ar 44100 -ab 64k \
-deinterlace -vcodec h264_qsv -bufsize 4000k -maxrate 2000k \
-preset veryfast -vb 1000k \
-f flv out2 \
-filter_complex "[0:v]scale=-1:ih/4[v0]; \
[1:v][v0]scale2ref=iw/8:-1[logo][0v];[0v][logo]overlay=10:10[v3]" \
-map "[v3]" -map 0:a \
-profile baseline -acodec aac -ac 1 -ar 44100 -ab 64k \
-deinterlace -vcodec h264_qsv -bufsize 4000k -maxrate 1000k \
-preset veryfast -vb 512k \
-f flv out3 \

Resources