How to repackage mov/mp4 file into HLS playlist with multiple audio streams

Viewed 66

I'm trying to convert some videos (in the different formats, e.g., mp4, mov) which contain one video stream and multiple audio streams into one HLS playlist with multiple audio streams (treated as languages) and only one video stream.

I already browsed a lot of stack threads and tried many different approaches, but I was only able to find answers for creating different HLS playlists with different audios.

Sample scenario which I have to handle:

  1. I have one mov file, containing one video stream and 2 audio streams.
  2. I need to create an HLS playlist from this mov file, which will use this one video stream, but would encode these 2 audio streams as language tracks (so let's say it's ENG and FRA)
  3. Such prepared HLS can be later streamed in the player, and the end user would have a possibility to switch between audio tracks while watching the clip.

What I was able to achieve is to create multiple hls playlists each with different audio track.

ffmpeg -i "file_name.mp4" \
-map 0:v -map 0:a -c:v copy -c:a copy -start_number 0 \
-f hls \
-hls_time 10 \
-hls_playlist_type vod \
-hls_list_size 0 \
-master_pl_name master_playlist_name.m3u8 \
-var_stream_map "v:0,agroup:groupname a:0,agroup:groupname,language:ENG a:1,agroup:groupname" file_name_%v_.m3u8

My biggest issue is that I'm having hard time understanding how -map and -var_stream_map options should be used in my case, or if they even should be used in this scenario.

An example of the result of ffmpeg -i command on the original mov file which should be converted into HLS.

  Stream #0:0[0x1](eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080, 8786 kb/s, 25 fps, 25 tbr, 12800 tbn (default)
    Metadata:
      handler_name    : Apple Video Media Handler
      vendor_id       : [0][0][0][0]
      timecode        : 00:00:56:05
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
  Stream #0:2[0x3](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]

I also checked this blogpost and I would like to achieve this exact effect, but with video, not with audio.

For example, -var_stream_map "v:0,a:0 v:1,a:0 v:2,a:0" implies that the audio stream denoted by a:0 is used in all three video renditions.

1 Answers

The stream_map looks fine. However the hls_muxer will not create a valid HLS playlist since it is missing the codec and bitrate information from the input stream since the audio and the video stream are copied (remember -c:v copy -c:a copy) and not parsed / re-encoded. To add those, use the -tag and -b options to specify the properties for all your video and audio streams in HLS.

Example for your video stream: -tag:v:0 h264 -b:v:0 8786k

Related