videojs-http-streaming (VHS)
repository·main·Indexed 25 days ago
https://github.com/videojs/http-streamingA library that enables Video.js to play HLS and MPEG-DASH streaming protocols using Media Source Extensions (MSE), providing playback support even where it is not natively available. It handles downloading segmented video data and converting it into playable video, supporting both VOD and Live modes, adaptive bitrate switching, and integration with videojs-contrib-eme for DRM.
What's inside videojs-http-streaming
- videojs-http-streaming (VHS) is a library that enables [HLS][hls] and [MPEG-DASH][dash] playback within the video.js player. It handles the process of downloading segmented video data from a server and converting it into playable video on the user's display.
Understand Transmuxing in HLS playback
mainTransmuxing is the process of transforming media from one container format to another without modifying the underlying media data. Because many browsers do not natively support the file types used in HLS segments, VHS uses a transmuxer to repackage HLS segments (often as FLVs) so they can be processed by the browser's Media Source Extensions (MSE).Understand Media Groups in VHS
mainIn
videojs-http-streaming(VHS), Media Groups are used to represent non-video media tracks, specifically:- Alternate audio tracks in HLS (sometimes referred to as MAAT in the source)
- Audio tracks in DASH
- Text tracks (VTT) defined in both DASH and HLS
Understand the PlaylistLoader purpose and responsibilities
mainThe
PlaylistLoader(PL) is a core component ofvideojs-http-streaming(VHS) used for HLS sources. It works in conjunction with aSegmentLoaderto manage the lifecycle of media fragments (like.tsor.fmp4).Its primary responsibilities include:
- Requesting
.m3u8manifests. - Parsing
.m3u8files into a format compatible with VHS. - Enabling the selection of specific media streams.
- Refreshing live
.m3u8manifests to track updates.
- Requesting
Understand the core responsibilities of videojs-http-streaming
mainThe
videojs-http-streaming(VHS) project performs three primary functions to enable HLS playback:- Playlist Management: Downloading and parsing playlist files.
- Interface Implementation: Implementing the
HTMLVideoElementinterface to provide a standard video control surface. - Media Feeding: Downloading video segments and transmuxing them to feed content bits into a
SourceBuffer.
Understand the DASH Playlist Loader (DPL) purpose and responsibilities
mainThe
DashPlaylistLoader(DPL) is responsible for managing DASH Media Presentation Descriptions (MPDs). It works in conjunction with aSegmentLoaderto load fmp4 fragments from a DASH source.Key Responsibilities:
- Requesting and parsing MPDs.
- Converting MPDs into a format compatible with
videojs-http-streaming(VHS). - Refreshing MPDs based on their
minimumUpdatePeriod. - Enabling selection of specific media streams.
- Synchronizing the client clock with the server clock using the
UTCTimingnode. - Refreshing live MPDs to account for changes.
Understand the VHS internal architecture
mainVHS follows a hierarchical structure to manage the transition from a manifest URL to active video playback:
- VhsSourceHandler: Registered with Video.js. It uses
canHandleSourceto check if the source type (e.g.,application/x-mpegURL) is supported by the browser's MSE. - VhsHandler: Created by the source handler. It performs initial setup, merges options, and interfaces with Video.js and plugins (like
videojs-contrib-emefor DRM). - PlaylistController (PC): The central hub of VHS. It manages the lifecycle of most other modules and facilitates communication between them.
- PlaylistLoader: Created by the
PlaylistControllerto download and parse manifests. It usesHLS PlaylistLoaderorDashPlaylistLoaderdepending on the source type. - Media Source Extensions (MSE): The
PlaylistControllermanagesthis.mediaSourceandthis.sourceBuffers. To handle the single-operation limitation of source buffers, VHS usesthis.sourceUpdater_as a queue for append operations.
- VhsSourceHandler: Registered with Video.js. It uses
Understand Content Steering in VHS
mainContent Steering allows content creators to control at runtime which locations (CDNs/servers) are used to fetch media segments. VHS implements this by reading steering tags in the media manifest (
#EXT-X-CONTENT-STEERINGfor HLS or<ContentSteering>for DASH) and requesting a steering manifest from the specified location.VHS will periodically refresh the steering manifest based on the interval defined within it. The steering manifest provides a priority list of identifiers (pathways or service locations) that VHS uses to select segment fetch locations. During playback, VHS can provide Quality of Experience (QoE) metrics back to the steering server to allow for dynamic steering adjustments.
Understanding LHLS (Low-Latency HLS) Support
mainLHLS (Low-Latency HLS) is designed for ultra-low latency live streaming. It allows a server to send pieces of a segment before the entire segment is finished being written. This enables the player to append these pieces to the browser progressively, achieving sub-segment duration latency.
To support LHLS, the following infrastructure is required:
- A Server: Must support chunked transfer encoding.
- A Client (VHS): Must be capable of requesting segment pieces, transmuxing those pieces (for browsers that don't natively support the media type, like TS), and appending those pieces to the media source.
Understand MPEG-DASH playback
mainMPEG-DASH is a segmented video format delivered over HTTP(S) using a Media Presentation Description (MPD). The MPD contains metadata such as timing, URLs, resolution, and bitrate.
Key concepts in DASH playback:
- Representations: Collections of segments at different bitrates, allowing the player to perform adaptive bitrate switching.
- Segment Organization: Representations can be organized via
SegmentList,SegmentTemplate,SegmentBase, orSegmentTimeline. - Modes: Supports both Video-on-Demand (VOD) and Live streaming (using the ISOBMFF Live profile for ISOBMFF segments).
Encrypt segments for HLS using AES-128 CBC
mainTo comply with the HLS specification, segments must be encrypted using AES-128 in CBC mode with PKCS7 padding. You can achieve this using a combination of the
pkcs7utility andopenssl.Warning: When performing testing, you may use the
-nosaltflag with OpenSSL to ensure stable output, but using-nosaltin a production environment is highly discouraged.# encrypt the text "hello" into a file # since this is for testing, skip the key salting so the output is stable # using -nosalt outside of testing is a terrible idea! echo -n "hello" | pkcs7 | \ openssl enc -aes-128-cbc -nopad -nosalt -K $KEY -iv $IV > hello.encryptedCreate joined HLS initialization segments (fMP4)
mainWhen using DASH,
ffmpegtypically produces separate initialization segments for video and audio. To produce a single joined initialization segment for HLS using fMP4, use the-hls_segment_type fmp4flag.ffmpeg -i input.mp4 -f hls -hls_fmp4_init_filename init.mp4 -hls_segment_type fmp4 out.m3u8