[FFmpeg-user] ffmpeg command required to convert MPEG TS to HLS with transcoding to aac

Robin van der Linden linden at venom.one
Sun Dec 11 05:56:46 EET 2022


Hello again,

I was now able to pull out some of my code.
First, I want to talk a bit of the import process.
I personally go with mp4 files as they are just a container which can 
contain almost every codec according to Audio/Video.
Why mp4 for input data? Most importantly, you can place a lot of 
different metadata aka atoms inside mp4 containers, which your app can 
later pull out and write to a database to later build queries onto. 
Sadly, there is no tooling available under Windows that really allows 
you to set >>all<< mp4 atoms/metadata which are available and fully 
QuickTime conform. There is only one tool available called "Subler" and 
it's only for Mac... You could first metarize all your mp4 files using 
Subler and later on read information via ffprobe using JSON output 
format, which is fine for parsing:

ffprobe -print_format json -export_all true -show_streams -show_format 
-loglevel quiet -hide_banner my_file.mp4

Sadly, ffprobe has a limitation if it comes to enforced subtitles. 
ffprobe is not able to read if a subtitle is enforced by a specific mp4 
atom for a tx3g embedded subtitle tracks (default track selection is not 
meaning = forced, some people are thinking this, and It's simply not 
true, there is a extra atom available for text tracks only to set them 
forced), so you will have to hack around this using a scoring mechanism 
for comparing length of enforced subtitle tracks against normal subtitle 
tracks e.g. your video input has the subtitle tracks "English" and 
"English forced", the shorter one will be the enforced one and the 
longer the normal one according to nb_frames comparison. But as I 
already said, there are some limits, e.g. what do you do if you have 
"English", "English SDH" and "English forced"? Without ffprobe being 
able to really pull this information out of the container/track, you are 
kinda lost. Just wanted to say this in forehand, as you will most likely 
face this issue in the future during development.

Second, the solution Dave suggested in his previous post, please correct 
me if I'm wrong Dave, but I guess he is referring to: 
https://github.com/kaltura/nginx-vod-module . This solution is fine if 
you really just have plenty amount of users. If you have many users, 
this solution will rip every CPU apart and is not suitable if you want 
to build a Netflix like application as you will have to transcode every 
playback of every user in real time.
If you have lots of Videos, this is not the way to go. You better go for 
transcoding the videos once, placing them onto a S3 storage and deliver 
them from here to your users. There are also many steps here in between, 
like authentication for pulling segments, DRM etc.


But now to your actual question:

Assuming you want to transcode a mp4 8 Bit 4K input to HLS, pretty sure 
it works with a ts file as well, the command to only transcode the video 
should look something like this:
_______________

/usr/bin/ffmpeg -i "/tmp/VODProcessing/my_file.mp4" -map 0:0 -c:v 
libx264 -b:v 10485760 -maxrate:v 11010048 -bufsize 41943040 -vf 
zscale=width=3840:height=2160 -strict -1 -f yuv4mpegpipe -profile:v high 
-level 5.1 -pix_fmt yuv420p -crf 16 -preset fast -bf 0 -tune fastdecode 
-force_key_frames "expr:gte(t,n_forced*2)" -keyint_min 48 -use_timeline 
1 -use_template 1 -map_metadata -1 -map_chapters -1 -sc_threshold 0 -f 
hls -seg_duration 4 -hls_time 4 -streaming 1 -hls_list_size 0 
-hls_segment_filename 
"/tmp/VODProcessing/output/my_file/v-h264-2160p-avc1.640033/f-%04d.m4s"  
-hls_fmp4_init_filename "init-v-h264-2160p-avc1.640033.m4s"  
-hls_segment_type fmp4 -hls_playlist_type vod -movflags 
frag_keyframe+frag_every_frame+write_colr+prefer_icc+skip_trailer+faststart 
-hls_flags independent_segments 
"/tmp/VODProcessing/output/my_file/v-h264-2160p-avc1.640033/master.m3u8"
_______________
And for your audio, in this example a 5.1 source, it should look like 
this:
_______________

/usr/bin/ffmpeg -i "/tmp/VODProcessing/my_file.mp4" -map 0:2 -c:a 
libfdk_aac -b:a 384000 -ac 6 -bf 0 -tune fastdecode -force_key_frames 
"expr:gte(t,n_forced*2)" -keyint_min 48 -use_timeline 1 -use_template 1 
-map_metadata -1 -map_chapters -1 -sc_threshold 0 -f hls -seg_duration 4 
-hls_time 4 -streaming 1 -hls_list_size 0 -hls_segment_filename 
"/tmp/VODProcessing/output/my_file/a-aac-en-mp4a.40.2_384000/f-%04d.m4s" 
  -hls_fmp4_init_filename "init-a-aac-en-mp4a.40.2_384000.m4s"  
-hls_segment_type fmp4 -hls_playlist_type vod -movflags 
frag_keyframe+frag_every_frame+write_colr+prefer_icc+skip_trailer+faststart 
-hls_flags independent_segments 
"/tmp/VODProcessing/output/my_file/a-aac-en-mp4a.40.2_384000/master.m3u8"
_______________
The movflags on the audio will get ignored partly as e.g. "write_colr" 
does not make much sense with an audio only track.

Your master.m3u8 which will later on reference the other master.m3u8 
files generated by ffmpeg should look like this:
_______________
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-PLAYLIST-TYPE VOD

#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="a-1",NAME="English 
(5.1)",CHANNELS=6,AUTOSELECT="YES",DEFAULT="NO",LANGUAGE="en",URI="a-aac-en-mp4a.40.2_384000/master.m3u8"

#EXT-X-STREAM-INF:BANDWIDTH=11956736,RESOLUTION=3840x2160,CODECS="avc1.640033,mp4a.40.2",AUDIO="a-1"
v-h264-2160p-avc1.640033/master.m3u8
_______________

There are many other parameters you can set here. This is very basic. If 
you have HDR content for example you will also need to announce this in 
your master.m3u8 file, and also use codecs which support 10 Bit/HDR like 
HEVC or AV1 (SVT-AV1). Second you also have to think about the way of 
transportation here, HEVC and AV1 will only work with fmp4 (.m4s) 
segments, not with mpegts segments (.ts).

I can only recommend reading through the whole HLS documentation 
published by Apple: 
https://developer.apple.com/documentation/http_live_streaming/understanding_the_http_live_streaming_architecture 
It will give you a very good understanding about compatibility along 
different devices, codecs, and ways of delivering your content.

Without going too much into detail, all encoding commands I showed above 
will create independent segments, meaning your video gets split into 
many thousand files. It's questionable if this is the way you wanted to 
go. It's also possible to have single files for each of your output 
tracks. But then the delivery only works using byte-range requests which 
your webserver must also support and which again are not compatible with 
XHR authentication requests by common browsers. Just in case you want to 
protect your segment pulling outside of CORS validation. So there is a 
lot of stuff you have to experiment yourself with. Professional HLS 
authoring and delivery is really not an easy task.


Third, Build stuff yourself, espacially when building such a complex app 
like yours. Build ffmpeg from scratch, build nginx or even better use 
OpenResty and build it from scratch, build a performantd FUSE Filesystem 
for mounting your S3 buckets etc. It really pay off in the end. Going 
with half baked solutions you haven't written yourself will get you 
stuck at at a specific point, I'm pretty sure onto that.


Kind regards,

Robin

Am 2022-12-11 00:01, schrieb Robin van der Linden via ffmpeg-user:
> I give you a detailed answer in the next 24 Hrs. I currently dont have
> Access to my system and code 
> 
> Cheers,
> 
> Robin
> 
> ________________________________
> Von: Mahesh Velankar <mvelanka at gmail.com>
> Gesendet: Samstag, 10. Dezember 2022 22:38
> An: ffmpeg-user at ffmpeg.org
> Betreff: Re: [FFmpeg-user] ffmpeg command required to convert MPEG TS
> to HLS with transcoding to aac
> 
> Robin,
> 
> This is not for a single video, I have to keep the application ready
> that will be receiving different input TS and the app will need to
> prepare the playlists,  segments and master playlist.
> 
> I am  aware that I need to write script/app for this.
> 
> Please tell me the command line to prepare individual playlists and
> segments............and I will be able to write the master playlist
> myself.
> 
> Thanks in advance for your help
> 
> -Mahesh
> 
> ---------------------------
> 
> Robin wrote:
> 
> Hello,
> 
> ffmpeg can do this, at least some parts. It will create the segments
> and a master.m3u8 file for each track by itself. Still you will need
> to create master.m3u8 File wich references all the tracks master.m3u8
> yourself. My Script is about 3500 lines long, so be prepared that you
> have to code lot yourself.
> 
> Im currently on the go, but I will try to provide you some more
> advice. Are you about to encode a single Video or do you need a full
> implemented rapackaging process for many vidz?
> 
> 
> Kind regards,
> 
> Robin
> 
> ________________________________
> 
> 
> On Sat, Dec 10, 2022 at 1:53 PM Mahesh Velankar <mvelanka at gmail.com> 
> wrote:
> 
>> I have a transport stream file with following details (given by 
>> ffprobe)
>> 
>> Input #0, mpegts, from 'f-13324-ccrtpa_before_tc_1669374838.ts':
>>    Duration: 00:04:23.44, start: 8879.809433, bitrate: 2373 kb/s
>>    Program 3
>>      Stream #0:0[0x31]: Video: h264 (Main) ([27][0][0][0] / 0x001B),
>> yuv420p(tv, bt709, progressive), 856x480 [SAR 320:321 DAR 16:9], 
>> Closed
>> Captions, 30 fps, 29.97 tbr, 90k tbn, 60 tbc
>>      Stream #0:1[0x34](eng): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz,
>> 5.1(side), fltp, 320 kb/s
>>      Stream #0:2[0x35](spa): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz,
>> stereo, fltp, 192 kb/s (visual impaired)
>>      Stream #0:3[0x36]: Data: klv (KLVA / 0x41564C4B)
>> 
>> 
>> I want to convert this into HLS playlists and segments. The 
>> requirements
>> are as follows
>> There will be two playlists
>> 
>> playlist 1 will have a listing of TS segments. Each such segment will 
>> have
>> 1. Video stream (Stream #0:0) from the above input (h264) and
>> 2. Audio stream 1 (Stream #0:1) from the above input (ac3 5.1) .... 
>> but
>> converted to aac format
>> 
>> playlist 2 will have a listing of TS segments. Each such segment will 
>> have
>> 1. Video stream (Stream #0:0) from the above input (h264) and
>> 2. Audio stream 2 (Stream #0:2) from the above input (ac3 stereo) .... 
>> but
>> converted to aac format
>> 
>> In short the output segments will have one video and one audio stream.
>> Since there are two audio streams I need to convert it into two 
>> different
>> playlists ... each having video and one of the audio streams
>> 
>> ac3 to aac conversion is mandatory,  as it has to be played in the 
>> browser.
>> 
>> How can I achieve this with the ffmpeg command line? Please help or 
>> point
>> me to any such recipe if already available.
>> 
>> Thanks
>> 
> _______________________________________________
> ffmpeg-user mailing list
> ffmpeg-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> 
> To unsubscribe, visit link above, or email
> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
> _______________________________________________
> ffmpeg-user mailing list
> ffmpeg-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> 
> To unsubscribe, visit link above, or email
> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".

-- 
Grüße / Kind regards,

Robin van der Linden


More information about the ffmpeg-user mailing list