Video Compression

VideoNerd

Preamble: Some Details on HLS

In HTTP-based rate-adaptive streaming protocols, like HLS, videos are encoded into multiple representations at different bitrates and resolutions. Each representation is then partitioned into segments of lengths that are several seconds long. At any moment, Client can dynamically choose a segment from an appropriate representation (according to current channel capacity) to download. Thus, it’s up to Client to adapt itself to its current channel capacity.

HLS Server generates a playlist file (or manifest file or m3u8 file). It’s up to Client to download and to parse the playlist file and get a link (URL) to an appropriate stream replica (bitrate/resolution/frame-rate).

In Live mode the playlist is refreshed periodically to support live broadcasts, where new media chunks are generated and and added to the manifest file continuously. The playlist provides the client with a URL of the segmented files. Each URL is published on the server and refers to a media chunk of a single video bitstream.

In HLS live streaming, for instance, the succession of media frames arriving from the broadcaster is normally aggregated into mpegts segments where each segment is a few seconds long. Only when a segment is complete the URL of the segment is added to the playlist.

HLS is not optimized for low latency. 

Originally, HLS supported only TS files as segments, but Apple introduced support for fmp4 (fragmented mp4) files later in 2016.

 

shaka-packager Tool

shaka-packager is a tool to convert input streams into HLS or MPEG-DASH format for both mode static (or VOD) and real-time.

Clone shaka packager sources:

https://github.com/shaka-project/shaka-packager.git

 

Tutorial how to use shaka-packager:

https://shaka-project.github.io/shaka-packager/html/tutorials/tutorials.html

 

You can attempt to compile shaka packager in Windows, but it’s a headache (you need install ninja-tool and so forth), it’s better to take the recent shaka binary packager-win-x64 from:

https://github.com/shaka-project/shaka-packager/releases

 

I rename packager-win-x64.exe to shaka-packager.exe to distinguish shaka packager with other packagers. 

 

Example: getting some info from input file (format mpeg2ts or mp4):

shaka-packager    input=crowdrun1080p.ts       --dump_stream_info

[0520/110908:INFO:demuxer.cc(89)] Demuxer::Run() on file ‘crowdrun1080p.ts’.

[0520/110908:INFO:demuxer.cc(155)] Initialize Demuxer for file ‘crowdrun1080p.ts’.

File “crowdrun1080p.ts”:

Found 1 stream(s).

Stream [0] type: Video

 codec_string: avc1.64002a

 time_scale: 90000

 duration: Infinite

 is_encrypted: false

 codec: H264

 width: 1920

 height: 1080

 pixel_aspect_ratio: 1:1

 trick_play_factor: 0

 nalu_length_size: 4

[0520/110908:WARNING:es_parser_h26x.cc(334)] [MPEG-2 TS] PID 256 Possible GAP at dts 126000 with next sample at dts 129600 (difference 3600)

Packaging completed successfully.

 

Example:   HLS formatting single mpeg2ts stream into mp4-fragmented,  expected segment size 2s: 

shaka-packager.exe  in=../crowdrun1080p.ts,stream=video,init_segment=crowdrun_init.mp4,segment_template=crowdrun$Number$.m4s,playlist_name=crowdrun.m3u8   --min_buffer_time=0.5 --segment_duration=2  -hls_master_playlist_output master.m3u8

Note: Segmentation is performed at key frames and if key frames are scarce in the stream segment sizes might be larger ‘–segment_duration’

you can play HLS streams with ‘ffplay     crowdrun.m3u8’

Example:  HLS formatting two mpeg2ts streams (same sequence in different resolutions – 1080p and 720p)  into mp4-fragmented,  expected segment size 2s: 

shaka-packager.exe   in=../crowdrun1080p.ts,stream=video,init_segment=crowdrun1080p_init.mp4,segment_template=crowdrun1080p$Number$.m4s,playlist_name=crowdrun1080p.m3u8                                       in=../crowdrun720p.ts,stream=video,init_segment=crowdrun720p_init.mp4,segment_template=crowdrun720p$Number$.m4s,playlist_name=crowdrun720p.m3u8            --min_buffer_time=0.5 --segment_duration=2 -hls_master_playlist_output master.m3u8

 

you can play for example 720p stream

 ‘ffplay     crowdrun720p.m3u8’

 

Note: Shorter segment lengths (--segment_duration) make more HTTP/TCP overhead and a shorter deadline for the next segment during the initial buffer period. For live streaming, a shorter segment length will provide less latency between the live event and the viewer’s experience.

 

Example: MPEG-DASH, VOD mode, create mpd-file

input three streams:  1080p, 720p and 640×360

output the three streams in the folder ‘mpegdash’ plus corresponding mpd-file (fifa17.mpd)

shaka_packager.exe in=fifa17_1080p_b10M.mp4,stream=video,out=mpegdash/1920x1080.mp4 in=fifa17_720p_b5M.mp4,stream=video,out=mpegdash/1280x720.mp4 in=fifa17_640x360_b3M.mp4,stream=video,out=mpegdash/640x360.mp4  --mpd_output mpegdash/fifa17.mpd

 

the mpd-file specifies  three Representations:

….

<Representation id="0" bandwidth="3079188" codecs="avc1.64001f" mimeType="video/mp4" sar="1:1" width="640" height="360">
<BaseURL>640x360.mp4</BaseURL>
<SegmentBase indexRange="882-949" timescale="15360">
<Initialization range="0-881"/>
</SegmentBase>
</Representation>

<Representation id="1" bandwidth="5089590" codecs="avc1.640020" mimeType="video/mp4" sar="1:1" width="1280" height="720">
<BaseURL>1280x720.mp4</BaseURL>
<SegmentBase indexRange="881-948" timescale="15360">
<Initialization range="0-880"/>
</SegmentBase>
</Representation>

<Representation id="2" bandwidth="10424016" codecs="avc1.640032" mimeType="video/mp4" sar="1:1" width="1920" height="1080">
<BaseURL>1920x1080.mp4</BaseURL>
<SegmentBase indexRange="882-949" timescale="15360">
<Initialization range="0-881"/>
</SegmentBase>
</Representation>

….

 

Example: MPEG-DASH, VOD mode, create mpd-file and m4s-segments

input three streams:  1080p, 720p and 640×360

chop input streams into segments of duration 2s in the format m4s (the fragmented mp4), m4s files are stored in ‘mpegdash’ folder, in addition the corresponding mpd-file (fifa17.mpd) is created

shaka_packager.exe in=fifa17_1080p_b10M.mp4,stream=video,init_segment=mpegdash/1920x1080_init.mp4,segment_template=mpegdash/1920x1080_$Number%03d$.m4s in=fifa17_720p_b5M.mp4,stream=video,init_segment=mpegdash/1280x720_init.mp4,segment_template=mpegdash/1280x720_$Number%03d$.m4s in=fifa17_640x360_b3M.mp4,stream=video,init_segment=mpegdash/640x360_init.mp4,segment_template=mpegdash/640x360_$Number%03d$.m4s --segment_duration 2 --fragment_duration 2 --generate_static_live_mpd --mpd_output mpegdash/fifa17.mpd

 

For testing play ‘ffplay fifa17.mpd

 

13 Responses

  1. Do you mind if I quote a few of your articles as long as I provide credit and sources back to your blog? My website is in the very same niche as yours and my users would definitely benefit from some of the information you provide here. Please let me know if this okay with you. Appreciate it!

  2. Hello there! Quick question that’s entirely off topic. Do you know how to make your site mobile friendly? My weblog looks weird when browsing from my iphone4. I’m trying to find a template or plugin that might be able to fix this issue. If you have any recommendations, please share. Appreciate it!

  3. My partner and I absolutely love your blog and find almost all of your post’s to be just what I’m looking for. can you offer guest writers to write content available for you? I wouldn’t mind publishing a post or elaborating on some of the subjects you write in relation to here. Again, awesome website!

Leave a Reply

Your email address will not be published. Required fields are marked *