Synchronization and concurrency for creating hls resolutions for Live Streaming - ffmpeg

Is there a single command to transcode mp4 video + aac into HLS at multiple resolutions ?
I have a convert server, and I think to live stream multiple resolutions, I must create all resolutions at the same time and this process must be concurrent.
I raised this issue,because I do this process wtih running these below codes at 4 cmd seperately for creating 4 resolutions of a video examply at the same time:
1- 720p
ffmpeg -i 123.mp4 -c:a aac -strict experimental -c:v libx264 -s hd720 -aspect 16:9 -f hls -hls_list_size 0 -hls_time 2 720p/out.m3u8
2- 480p
ffmpeg -i 123.mp4 -c:a aac -strict experimental -c:v libx264 -s hd480 -aspect 16:9 -f hls -hls_list_size 0 -hls_time 2 480p/out.m3u8
3- 360p
ffmpeg -i 123.mp4 -c:a aac -strict experimental -c:v libx264 -s nhd -aspect 16:9 -f hls -hls_list_size 0 -hls_time 2 360p/out.m3u8
4- 200p
ffmpeg -i 123.mp4 -c:a aac -strict experimental -c:v libx264 -s cga -aspect 16:9 -f hls -hls_list_size 0 -hls_time 2 200p/out.m3u8
but doing in this way have some problems.
1- the .TS parts of each resolutions doesn't create with another resolutions part at the same time(this issue makes that in switching resolutions, player cannot seek to the continue of selected resolution,because that part doesn't create yet).
2- You have run some threads for each live streaming.

Here is the answer of mine,Note that you must be set -hls_time If you want the number part of each resolutions be same.
ffmpeg -re -i 123.mp4
-c:a aac -c:v libx264 -s hd480 -aspect 16:9 -f hls -hls_list_size 0 -hls_time 2 480p/out.m3u8
-c:a aac -c:v libx264 -s nhd -aspect 16:9 -f hls -hls_list_size 0 -hls_time 2 360p/out.m3u8
-c:a aac -c:v libx264 -s cga -aspect 16:9 -f hls -hls_list_size 0 -hls_time 2 200p/out.m3u8

Related

How to set youtube live title and description in ffmpeg

I am using following code to live stream video in youtube.
ffmpeg -y -loop 1 -i "still.jpg" -i "audio.mp3" " -c:v libx264 -pix_fmt yuv420p -crf 21 -r 1 -g 30 -keyint_min 5 -x264opts "keyint=5:min-keyint=5:no-scenecut" -s 1280x720 -tune zerolatency -b:a 128k -c:a aac -ar 48000 -strict experimental -f flv rtmp://a.rtmp.youtube.com/live2/steam-key.
I would like to set youtube live title and description in the above command. Is it possible?

FFMPEG -re Insurance

FFMPEG -re according to the ffmpeg docs:
Read input at native frame rate. Mainly used to simulate a grab
device, or live input stream (e.g. when reading from a file). Should
not be used with actual grab devices or live input streams (where it
can cause packet loss).
My ffmpeg stream command is:
ffmpeg -re -i https://www.example.com/video.mp4 -filter_complex tpad=start_duration=10:stop_duration=15:start_mode=add:color=black:stop_mode=add -af adelay=10000|10000 -maxrate 2M -crf 24 -bufsize 6000k -c:v libx264 -preset superfast -tune zerolatency -strict -2 -c:a aac -ar 44100 -attempt_recovery 1 -max_recovery_attempts 5 -drop_pkts_on_overflow 1 -f flv rtmp://live.example.com/123453
Except this does not always work, and sometimes I have livestreams ending early because ffmpeg is playing faster than the frame rate. Is there another command that can be used to ensure ffmpeg streams the video in real time?
Remove -re and add filter-based throttling.
ffmpeg -i https://www.example.com/video.mp4 -filter_complex tpad=start_duration=10:stop_duration=15:start_mode=add:color=black:stop_mode=add,fifo,realtime -af adelay=10000|10000,afifo,arealtime -maxrate 2M -crf 24 -bufsize 6000k -c:v libx264 -preset superfast -tune zerolatency -strict -2 -c:a aac -ar 44100 -attempt_recovery 1 -max_recovery_attempts 5 -drop_pkts_on_overflow 1 -f flv rtmp://live.example.com/123453

How to stream to multiple destinations with ffmpeg

I want to stream my video to 4 destinations. My input signal needs to be recoded to "H.264 AAC", so I want to send it to my server. This works already.
Client -> Server with ffmpeg -> Destinations
Now I have a performance problem: One should get the stream in 1080p and two in 720p.
So it would make sense to first get the stream in the desired formats H.264 1080p and AAC with 30 FPS and then calculate the stream once, send it 1:1 to the two HD targets.
and create a 720p stream in parallel and send it to the two remaining destinations.
What is the best way to do this on a Ubuntu 16.04 machine?
My previous approach:
ffmpeg -i rtmp://livestream.domain.example/live/<key> \
-threads 2 -s hd1080 -preset veryfast -f flv rtmp://destination1.example/live2/<key> \
-threads 2 -s hd1080 -preset veryfast -f flv rtmp://destination2.example/live2/<key> \
-threads 1 -s hd720 -c:v libx264 -c:a aac -preset veryfast -r 30 -g 60 -b:v 3000k -f flv rtmp://destination3.example/x/<key> \
-threads 1 -s hd720 -c:v libx264 -preset veryfast -c:a aac -f flv 'rtmps://destination4.exmple/rtmp/<key>'
You can see the repetitions in the code. :-/
Use the tee muxer:
ffmpeg -i rtmp://livestream.domain.example/live/<key> \
-filter_complex "[0:v]scale=-2:1080,fps=30,split=outputs=2[1080a][1080b];[0:v]scale=-2:720,fps=30,split=outputs=2[720a][720b]" \
-map "[1080a]" -map "[1080b]" -map "[720a]" -map "[720b]" -map 0:a \
-c:v libx264 -c:a aac -preset veryfast -g 60 -b:v 3000k -maxrate 3000k -bufsize 6000k -f tee \
"[select=\'v:0,a\':f=flv:onfail=ignore]rtmp://destination1.example/live2/<key>| \
[select=\'v:1,a\':f=flv:onfail=ignore]rtmp://destination2.example/live2/<key>| \
[select=\'v:2,a\':f=flv:onfail=ignore]rtmp://destination3.example/live2/<key>| \
[select=\'v:3,a\':f=flv:onfail=ignore]rtmp://destination4.example/live2/<key>"

How to generate TS streams from middle of a source video?

I am using ffmpeg to create m3u8 playlist for a video (actually a live video stream). I am using the following command:
ffmpeg -i /home/ubuntu/Download/1459530099245.mkv -c:a aac -strict experimental -ac 2 -ar 48k -ab 64k -c:v libx264 -s 480x270 -aspect 16:9 -b:v 400k -r 15 -g 45 -profile:v baseline -level 3.0 -f hls -hls_time 9 -hls_list_size 0 /home/ubuntu/Download/New Playlist.m3u8
It produces m3u8 file as well as ts files.
Question: simply, how can we produce m3u8 playlist and TS files for a particular duration of source video? E.g., I want to get playlist only for first 20 seconds or so?
You can use command -to. Just add -to 00:00:20 after input path
In your variant:
ffmpeg -i /home/ubuntu/Download/1459530099245.mkv -to 00:00:20 -c:a aac -strict experimental -ac 2 -ar 48k -ab 64k -c:v libx264 -s 480x270 -aspect 16:9 -b:v 400k -r 15 -g 45 -profile:v baseline -level 3.0 -f hls -hls_time 9 -hls_list_size 0 /home/ubuntu/Download/New Playlist.m3u8
More information here: http://www.bogotobogo.com/FFMpeg/ffmpeg_seeking_ss_option_cutting_section_video_image.php

FFmpeg Live Stream - Loop Video?

I am trying to stream a video loop to justin.tv using FFmpeg? I have managed to loop an image sequence and combine it with line in audio:
ffmpeg -loop 1 -i imageSequence%04d.jpg -f alsa -ac 2 -ar 22050 -ab 64k \
-i pulse -acodec adpcm_swf -r 10 -vcodec flv \
-f flv rtmp://live.justin.tv/app/<yourStreamKeyHere>
Is it possible to do this with a video file?
Definitely possible. In the recent versions of ffmpeg they have added a -stream_loop flag that allows you to loop the input as many times as required.
The gotcha is that if you don't regenerate the pts from the source, ffmpeg will drop frames after the first loop (as the timestamp will suddenly go back in time). To avoid this, you need to tell ffmpeg to generate the pts so you get an increasing timestamp between loops. This is done with the +genpts call (it has to be before the -i arg).
Here's an example ffmpeg call (replace $F with your input file). This example generates two output streams and the -stream_loop -1 argument tells ffmpeg to continuously loop the input. The output in this case is for a similar stream broadcast ingest (MetaCDN), adjust accordingly to your requirements.
ffmpeg -threads 2 -re -fflags +genpts -stream_loop -1 -i $F \
-s 640x360 -ac 2 -f flv -vcodec libx264 -profile:v baseline -b:v 600k -maxrate 600k -bufsize 600k -r 24 -ar 44100 -g 48 -c:a libfdk_aac -b:a 64k "rtmp://publish.live.metacdn.com/2050C7/dfsdfsd/lowquality_664?hello&adbe-live-event=lowquality_" \
-s 1920x1080 -ac 2 -f flv -vcodec libx264 -profile:v baseline -b:v 2000k -maxrate 2000k -bufsize 2000k -r 24 -ar 44100 -g 48 -c:a libfdk_aac -b:a 64k "rtmp://publish.live.metacdn.com/2050C7/dfsdfsd/highquality_2064?mate&adbe-live-event=highquality_"
Sinclair Media has found a solution by using the lavfi filter and appending :loop=0 to the file name :
This is untested:
ffmpeg -f lavfi -re -i movie=StreamTest.avi:loop=0 \
-acodec libfaac -b:a 64k -pix_fmt yuv420p -vcodec libx264 \
-x264opts level=41 -r 25 -profile:v baseline -b:v 1500k \
-maxrate 2000k -force_key_frames 50 -s 640×360 -map 0 -flags \
-global_header -f segment -segment_list index_1500.m3u8 \
-segment_time 10 -segment_format mpeg_ts \
-segment_list_type m3u8 segmented.ts
But it should create a local "index_1500.m3u8" file that streams the video in "StreamTest.avi".
I just reuse the Rob's answers with a few of modifications in order to provide a file to live streaming
ffmpeg -threads 2 -re -fflags +genpts -stream_loop -1 -i gvf.mp4 -c copy -f mpegts -mpegts_service_id 102 -metadata service_name=My_channel -metadata service_provider=My_Self -max_interleave_delta 0 -use_wallclock_as_timestamps 1 -flush_packets 1 "udp://233.0.0.1:1001?localaddr=10.60.4.237&pkt_size=188"

Resources