1

My initial task was to find a segmenter for Windows that will split a h264\aac video file without changing its codecs and make it playable through HLS.

The best way that worked for me is to use ffmpeg like this:

ffmpeg -i encoded.mp4 -c copy -map 0 -vbsf h264_mp4toannexb -flags -global_header -f segment -segment_time 10 -segment_format mpegts stream%d.ts

Now, this splits the file more or less correctly, although mediastreamvalidator threw a couple of warnings, still I was able to play the video.

But, here's the tricky part: ffmpeg cannot create .m3u8 files for you. Which is not a problem, unless you need to create a variant playlist file what I do need. So now I need to either find or write an app for Windows that imitates varianplaylistcreator

So let's say you have the same video encoded for each different bandwidth: 64, 150, 300, 500, 800, 1200 and 2400. Now after you segment each video, you'd probably like to put those segments into separate folders including playlist files for each rendition.

Now we can create a variant playlist file where we list all the rendtions with instructions on what bandwidth server automatically should switch serving different rendition.

Typically variant playlist look like this:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=512376
500/500k_512x384_x264_372_quicktime_128.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=68795
64/64k_256x192_x264_32_quicktime_32.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=155580
150/150k_256x192_x264_118_quicktime_32.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=308895
300/300k_512x384_x264_172_quicktime_128.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=811310
800/800k_512x384_x264_672_quicktime_128.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1210182
1200/1200k_1024x768_x264_1072_quicktime_128.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2408106
2400/2400k_1024x768_x264_2272_quicktime_128.m3u8

Notice the BANDWITH attribute values. These I suspect are values calculated by varinatplaylistcreator.

And I don't know how it does that. I guess somehow it takes average bitrate of videos(segments) for each rendtion and based on that does that.

So my question is: how those get calculated. Or maybe someone already created a tool that can run on Windows and create varinant playlists.

Charles
  • 50,943
  • 13
  • 104
  • 142
iLemming
  • 34,477
  • 60
  • 195
  • 309
  • 1
    The BANDWIDTH attribute is not average bandwidth, but actually the maximum bandwidth. – vipw Jun 21 '12 at 07:30
  • 1
    Another thing you have to worry about is if each rendition is segmented at precisely the same positions. Generally, this means that you will want a fixed "GOP" (group of pictures -- how often an I-frame occurs) size. – vipw Jun 21 '12 at 07:32
  • @vipw... can you explain that in more details? thanks – iLemming Jun 21 '12 at 21:33
  • 1
    When switching between different bitrates, it's supposed to be completely transparent to the user. This requires that the ts files for each bitrate to be segmented at exactly the same logical boundaries. However, segmenting is only possible in certain positions. It must be a point where all past frames have no forward references, and all future frames will not reference back in the stream. This independent part of a video stream is often called a GOP. For HLS, you'll want to have each stream encoded with a fixed GOP size so that all streams will always have synchronized GOP boundaries. – vipw Jun 22 '12 at 07:13
  • @vipw So how does it exactly calculate the max bandwidth? I still can't get it. I've tried to get it by simply dividing filesize to duration and multiplying it by 8. Tried to use MediaInfo and ffprobe, still can't get the number that would match with what variantplaylistcreator puts there for BANDWIDTH attribute – iLemming Jun 25 '12 at 19:02

2 Answers2

2

FFmpeg can report the bitrate of the ts stream. Use the ffprobe tool and you'll get output like this:

Input #0, mpegts, from 'foo.ts':
  Duration: 00:04:50.87, start: 2.000011, bitrate: 10381 kb/s
  Program 1
    Stream #0.0[0x810]: Video: h264 (High), yuv420p, 1280x720 [PAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc

The bitrate is being given in kilobits per second, so multiply it by 1024 and you'll have the value you need for the BANDWIDTH tag.

vipw
  • 7,593
  • 4
  • 25
  • 48
  • This doesn't match the value that varianplaylistcreator puts there. I've tried everything, tried to get values with MediaInfo and ffprobe, tried to divide filesize by duration and multiply that by 8 - still numbers aren't matching... WTH? – iLemming Jun 25 '12 at 18:55
  • 1
    @Agzam Precision isn't required. If you're within 10%, I wouldn't sweat it. The requirement is for the stated bandwidth to not be lower than the actual bandwidth. But back here in the real world, it's just to let the client guess which stream will be best for its network connection, and adapt accordingly. – vipw Jun 27 '12 at 05:58
  • 1
    @Agzam When it comes to bitrate and not byterate, you multiply by 1000 instead of 1024. 1 kbps == 1000 bps while 1KBps == 1024 Bps. – NSProgrammer Aug 21 '13 at 16:51
0

You can use Bento4. They have specified in the document saying we can use this instead of Apple's variantplaylistcreator

RecklessSergio
  • 806
  • 3
  • 10
  • 34