Encode input stream mpg2 to output stream h264 CBR - ffmpeg

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).

Related

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 do I create an HLS master playlist with ffmpeg?

There is a command that generates hls videos in different sizes.
Now I need to merge them into one master playlist. (What is a master playlist) How do I do this? What and where do I need to add in this command?
ffmpeg -hide_banner -y -i input.mp4 \
-vf scale=w=640:h=360:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_segment_filename output/360p_%03d.ts output/360p.m3u8 \
-vf scale=w=842:h=480:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 1400k -maxrate 1498k -bufsize 2100k -b:a 128k -hls_segment_filename output/480p_%03d.ts output/480p.m3u8 \
-vf scale=w=1280:h=720:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_segment_filename output/720p_%03d.ts output/720p.m3u8 \
-vf scale=w=1920:h=1080:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_segment_filename output/1080p_%03d.ts output/1080p.m3u8
What I am interested in is the automatic creation of a master playlist using ffmpeg in this command.
UPD: I answered my own question
After several attempts, I still got the desired result. I modified the command and now it looks like this
ffmpeg -hide_banner -re -i input.mp4 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 \
-c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -c:a aac -ar 48000 \
-filter:v:0 scale=w=640:h=360:force_original_aspect_ratio=decrease -maxrate:v:0 856k -bufsize:v:0 1200k -b:a:0 96k \
-filter:v:1 scale=w=842:h=480:force_original_aspect_ratio=decrease -maxrate:v:1 1498k -bufsize:v:1 2100k -b:a:1 128k \
-filter:v:2 scale=w=1280:h=720:force_original_aspect_ratio=decrease -maxrate:v:2 2996k -bufsize:v:2 4200k -b:a:2 128k \
-filter:v:3 scale=w=1920:h=1080:force_original_aspect_ratio=decrease -maxrate:v:3 5350k -bufsize:v:3 7500k -b:a:3 192k \
-var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2 v:3,a:3" \
-hls_time 4 \
-hls_list_size 0 \
-master_pl_name master.m3u8 \
-hls_segment_filename output/%v_%03d.ts output/%v.m3u8
After several attempts, I still got the desired result. I modified the command and now it looks like this
ffmpeg -hide_banner -re -i input.mp4 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 \
-c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -c:a aac -ar 48000 \
-filter:v:0 scale=w=640:h=360:force_original_aspect_ratio=decrease -maxrate:v:0 856k -bufsize:v:0 1200k -b:a:0 96k \
-filter:v:1 scale=w=842:h=480:force_original_aspect_ratio=decrease -maxrate:v:1 1498k -bufsize:v:1 2100k -b:a:1 128k \
-filter:v:2 scale=w=1280:h=720:force_original_aspect_ratio=decrease -maxrate:v:2 2996k -bufsize:v:2 4200k -b:a:2 128k \
-filter:v:3 scale=w=1920:h=1080:force_original_aspect_ratio=decrease -maxrate:v:3 5350k -bufsize:v:3 7500k -b:a:3 192k \
-var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2 v:3,a:3" \
-hls_time 4 \
-master_pl_name master.m3u8 \
-hls_segment_filename output/%v_%03d.ts output/%v.m3u8
In case anyone facing an issue with the above command.
ffmpeg -hide_banner -re -i input.mp4 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -c:a aac -ar 48000 -filter:v:0 scale=w=640:h=360:force_original_aspect_ratio=decrease -maxrate:v:0 856k -bufsize:v:0 1200k -b:a:0 96k -filter:v:1 scale=w=960:h=540:force_original_aspect_ratio=decrease -maxrate:v:1 1498k -bufsize:v:1 2100k -b:a:1 128k -filter:v:2 scale=w=1280:h=720:force_original_aspect_ratio=decrease -maxrate:v:2 2996k -bufsize:v:2 4200k -b:a:2 128k -filter:v:3 scale=w=1920:h=1080:force_original_aspect_ratio=decrease -maxrate:v:3 5350k -bufsize:v:3 7500k -b:a:3 192k -var_stream_map "v:0,a:0,name:1080p v:1,a:1,name:720p v:2,a:2,name:540p v:3,a:3,name:360p" -master_pl_name master.m3u8 -f hls -hls_time 10 -hls_playlist_type vod -hls_list_size 0 -hls_segment_filename "v%v/segment%d.ts" v%v/index.m3u8
Full text-
ffmpeg -hide_banner -re -i input.mp4 -map 0:v:0 -map 0:a:0 -map 0:v:0
-map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -c:a aac -ar 48000 -filter:v:0 scale=w=640:h=360:force_original_aspect_ratio=decrease -maxrate:v:0
856k -bufsize:v:0 1200k -b:a:0 96k -filter:v:1
scale=w=960:h=540:force_original_aspect_ratio=decrease -maxrate:v:1
1498k -bufsize:v:1 2100k -b:a:1 128k -filter:v:2
scale=w=1280:h=720:force_original_aspect_ratio=decrease -maxrate:v:2
2996k -bufsize:v:2 4200k -b:a:2 128k -filter:v:3
scale=w=1920:h=1080:force_original_aspect_ratio=decrease -maxrate:v:3
5350k -bufsize:v:3 7500k -b:a:3 192k -var_stream_map
"v:0,a:0,name:1080p v:1,a:1,name:720p v:2,a:2,name:540p
v:3,a:3,name:360p" -master_pl_name master.m3u8 -f hls -hls_time 10
-hls_playlist_type vod -hls_list_size 0 -hls_segment_filename "v%v/segment%d.ts" v%v/index.m3u8

In ffmpeg: Can't get peak bitrate values within 10% error tolerance for HLS playlist files

I'm using ffmpeg to produce several HLS variant playlists from an .mp4 file. When I check master.m3u8 file with mediastreamvalidator I get:
Error: Measured peak bitrate compared to master playlist declared value exceeds error tolerance
I understand that the error percentage needs to be less than 10%, and figured it out on 1 variant but not the three others. I've spent quite a bit of time adjusting the -maxrate and the -buffsize but the error percentage change is minimal. Beginning to wonder if I'm misunderstanding something?
This is the latest of what I enter:
ffmpeg -i FHVid.mp4 \
-b:v:0 5000k -maxrate 5250k -bufsize 5500k -profile:v main -c:v h264 -crf 20 -sc_threshold 0 -g 48 \
-b:v:1 2800k -maxrate 2940k -bufsize 3100k -profile:v main -c:v h264 -crf 20 -sc_threshold 0 -g 48 \
-b:v:2 1400k -maxrate 1540k -bufsize 1700k -profile:v main -c:v h264 -crf 20 -sc_threshold 0 -g 48 \
-b:v:3 800k -maxrate 840k -bufsize 1050k -profile:v main -c:v h264 -crf 20 -sc_threshold 0 -g 48 \
-b:a:0 192k \
-b:a:1 128k \
-b:a:2 128k \
-b:a:3 96k \
-c:a aac -ar 48000 -keyint_min 48 -map 0:v -map 0:a -map 0:v -map 0:a -map 0:v -map 0:a -map 0:v -map 0:a \
-f hls -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2 v:3,a:3" \
-master_pl_name FHVidmaster.m3u8 -hls_time 4 -hls_playlist_type vod \
-hls_segment_filename 'file_%v_%03d.ts' out_%v.m3u8
but I've also tried max rates that seem to be more standard
-b:v:0 5000k -maxrate 5500k -bufsize 6500k
-b:v:1 2800k -maxrate 3080k -bufsize 3200k
-b:v:2 1400k -maxrate 1540k -bufsize 1900k
-b:v:3 800k -maxrate 880k -bufsize 1050k
The latest error message:
Error: Measured peak bitrate compared to master playlist declared value exceeds error tolerance
--> Detail: Measured: 1111.54 kb/s, Master playlist: 1680.80 kb/s, Error: 33.87%
--> Source: /Users/Bun/Documents/CODING/CosmicPerspectiveAssets/01-FalconHeavy/HLS/FHVidmaster.m3u8
--> Compare: out_2.m3u8
--> Detail: Measured: 1178.21 kb/s, Master playlist: 5711.20 kb/s, Error: 79.37%
--> Source: /Users/Bun/Documents/CODING/CosmicPerspectiveAssets/01-FalconHeavy/HLS/FHVidmaster.m3u8
--> Compare: out_0.m3u8
--> Detail: Measured: 1109.03 kb/s, Master playlist: 3220.80 kb/s, Error: 65.57%
--> Source: /Users/Bun/Documents/CODING/CosmicPerspectiveAssets/01-FalconHeavy/HLS/FHVidmaster.m3u8
--> Compare: out_1.m3u8
Any help would be greatly appreciated on the -maxrate and -buffsize for variant playlists 0, 1, and 2. No adjustment I make seems to make any difference.

how do I only output a single video stream per HLS output

I have successfully output 3 HLS output using -map 360, 720 & 1080p. My source file is 540p. once generated I use ffprobe on the newly created 360.ts, 720.ts, and 1080.ts and notice that there is a second video channel. This channel is the input video. How do I have FFmpeg not output the original video as part of the output?
this is the ffprobe on 360.ts
Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0:10x101: Audio: aac ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 100 kb/s
Stream #0:2[0x102]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 960x540 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
This is the FFmpeg command
%ffmpeg% -loglevel fatal -threads %threads% -hide_banner -y -i %input% -i %overlayImg%^
-filter_complex "[1]colorchannelmixer=aa=%thumbopacity%,scale=iw*%thumbscale%:-1[wm];[0:v][wm]overlay=(main_w-overlay_w)-36:(main_h-overlay_h)-21,split=4[a][b][c][d];[a]scale=w=640:h=360:force_original_aspect_ratio=decrease[a];[b]scale=w=1280:h=720:force_original_aspect_ratio=decrease[b];[c]scale=w=1920:h=1080:force_original_aspect_ratio=decrease[c];[d]scale=w=1280:h=720:force_original_aspect_ratio=decrease[d]"^
-map "[a]" -map 0 -c:a aac -ar 48000 -c:v h264 -profile:v main -movflags +faststart -tune film -crf %crf% -preset %preset% -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_flags single_file^
%output%\360p.m3u8^
-map "[b]" -map 0 -c:a aac -ar 48000 -c:v h264 -profile:v main -movflags +faststart -tune film -crf %crf% -preset %preset% -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_flags single_file^
%output%\720p.m3u8^
-map "[c]" -map 0 -c:a aac -ar 48000 -c:v h264 -profile:v main -movflags +faststart -tune film -crf %crf% -preset %preset% -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_flags single_file^
%output%\1080p.m3u8^
-map "[d]" -map 0 -c:a aac -ar 48000 -c:v h264 -profile:v main -preset %preset%^
%output%\720.mp4^
-map 0:v -y -ss 0.5 -vframes 1 -s %thumbsize% -ss 30^
%outputthumb%
thank you.
1) -map 0 will include all original streams, including the video. Change to -map 0:a
2) You don't need to scale to 720p twice. scale once and split.
3) b:v and crf are exclusive in libx264 (h264 encoder). Pick one (crf is preferable)
Use
%ffmpeg% -loglevel fatal -threads %threads% -hide_banner -y -i %input% -i %overlayImg%^ -filter_complex "[1]colorchannelmixer=aa=%thumbopacity%,scale=iw*%thumbscale%:-1[wm];[0:v][wm]overlay=(main_w-overlay_w)-36:(main_h-overlay_h)-21,split=4[a][b][c][d];[a]scale=w=640:h=360:force_original_aspect_ratio=decrease[a];[b]scale=w=1280:h=720:force_original_aspect_ratio=decrease,split=2[b][d];[c]scale=w=1920:h=1080:force_original_aspect_ratio=decrease[c]"^ -map "[a]" -map 0:a -c:a aac -ar 48000 -c:v h264 -profile:v main -movflags +faststart -tune film -crf %crf% -preset %preset% -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_flags single_file^ %output%\360p.m3u8^ -map "[b]" -map 0:a -c:a aac -ar 48000 -c:v h264 -profile:v main -movflags +faststart -tune film -crf %crf% -preset %preset% -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_flags single_file^ %output%\720p.m3u8^ -map "[c]" -map 0:a -c:a aac -ar 48000 -c:v h264 -profile:v main -movflags +faststart -tune film -crf %crf% -preset %preset% -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_flags single_file^ %output%\1080p.m3u8^ -map "[d]" -map 0:a -c:a aac -ar 48000 -c:v h264 -profile:v main -preset %preset%^ %output%\720.mp4^ -map 0:v -y -ss 0.5 -vframes 1 -s %thumbsize% -ss 30^ %outputthumb%

Add PNG overlay to multi output HLS M3U8 with FFmpeg

I've been banging my head for 2 days now. I can currently output 3 M3U8 "HLS" outputs resized but now I need to add an overlay to each output. The overlay image would need to be resized as well. My take on this is that the image should be applied to the source and then the 3 outputs can be generated. I have read that -vf cannot be used since there are 2 inputs. Here is what I am currently using which works.
How could I add an image overlay?
ffmpeg -hide_banner -y -i input.mov^
-vf scale=w=640:h=360:force_original_aspect_ratio=decrease -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_flags single_file^
360p.m3u8
-vf scale=w=1280:h=720:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_flags single_file 720p.m3u8^
-vf scale=w=1920:h=1080:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_flags single_file 1080p.m3u8
Any advice would be greatly appreciated.
Thanks in advance.
You need to use a filter_complex for the overlay filter, and then splitting the result into 3 and scaling each copy:
ffmpeg -hide_banner -y -i input.mov -i image.png
-filter_complex "[0][1]overlay,split=3[a][b][c];[a]scale=w=640:h=360:force_original_aspect_ratio=decrease[a];[b]scale=w=1280:h=720:force_original_aspect_ratio=decrease[b];[c]scale=w=1920:h=1080:force_original_aspect_ratio=decrease[c]"
-map "[a]" -map 0:a -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_flags single_file 360p.m3u8
-map "[b]" -map 0:a -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_flags single_file 720p.m3u8
-map "[c]" -map 0:a -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 72 -keyint_min 72 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_flags single_file 1080p.m3u8
(If your h264 encoder is x264, b:v has no effect when used with crf, but maxrate and bufsize do.)

Resources