videojs-http-streaming (VHS)

repository·main·Indexed 25 days ago

https://github.com/videojs/http-streaming

A 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.

Tokens
18.2K
Snippets
37
Records
118
Agent score
83%

What's inside videojs-http-streaming

  1. Overview of videojs-http-streaming (VHS)

    main
    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.
  2. Understand Transmuxing in HLS playback

    main
    Transmuxing 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).
  3. Understand the PlaylistLoader purpose and responsibilities

    main

    The PlaylistLoader (PL) is a core component of videojs-http-streaming (VHS) used for HLS sources. It works in conjunction with a SegmentLoader to manage the lifecycle of media fragments (like .ts or .fmp4).

    Its primary responsibilities include:

    1. Requesting .m3u8 manifests.
    2. Parsing .m3u8 files into a format compatible with VHS.
    3. Enabling the selection of specific media streams.
    4. Refreshing live .m3u8 manifests to track updates.
  4. Understand the core responsibilities of videojs-http-streaming

    main

    The videojs-http-streaming (VHS) project performs three primary functions to enable HLS playback:

    1. Playlist Management: Downloading and parsing playlist files.
    2. Interface Implementation: Implementing the HTMLVideoElement interface to provide a standard video control surface.
    3. Media Feeding: Downloading video segments and transmuxing them to feed content bits into a SourceBuffer.
  5. Understand the DASH Playlist Loader (DPL) purpose and responsibilities

    main

    The DashPlaylistLoader (DPL) is responsible for managing DASH Media Presentation Descriptions (MPDs). It works in conjunction with a SegmentLoader to 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 UTCTiming node.
    • Refreshing live MPDs to account for changes.
  6. Understand the VHS internal architecture

    main

    VHS follows a hierarchical structure to manage the transition from a manifest URL to active video playback:

    1. VhsSourceHandler: Registered with Video.js. It uses canHandleSource to check if the source type (e.g., application/x-mpegURL) is supported by the browser's MSE.
    2. VhsHandler: Created by the source handler. It performs initial setup, merges options, and interfaces with Video.js and plugins (like videojs-contrib-eme for DRM).
    3. PlaylistController (PC): The central hub of VHS. It manages the lifecycle of most other modules and facilitates communication between them.
    4. PlaylistLoader: Created by the PlaylistController to download and parse manifests. It uses HLS PlaylistLoader or DashPlaylistLoader depending on the source type.
    5. Media Source Extensions (MSE): The PlaylistController manages this.mediaSource and this.sourceBuffers. To handle the single-operation limitation of source buffers, VHS uses this.sourceUpdater_ as a queue for append operations.
  7. Understand Content Steering in VHS

    main

    Content 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-STEERING for 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.

  8. Understanding LHLS (Low-Latency HLS) Support

    main

    LHLS (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:

    1. A Server: Must support chunked transfer encoding.
    2. 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.
  9. Understand MPEG-DASH playback

    main

    MPEG-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, or SegmentTimeline.
    • Modes: Supports both Video-on-Demand (VOD) and Live streaming (using the ISOBMFF Live profile for ISOBMFF segments).
  10. Encrypt segments for HLS using AES-128 CBC

    main

    To 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 pkcs7 utility and openssl.

    Warning: When performing testing, you may use the -nosalt flag with OpenSSL to ensure stable output, but using -nosalt in 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.encrypted
  11. Create joined HLS initialization segments (fMP4)

    main

    When using DASH, ffmpeg typically produces separate initialization segments for video and audio. To produce a single joined initialization segment for HLS using fMP4, use the -hls_segment_type fmp4 flag.

    ffmpeg -i input.mp4 -f hls -hls_fmp4_init_filename init.mp4 -hls_segment_type fmp4 out.m3u8