Shaka Player Documentation

repository·main·Indexed 27 days ago

https://github.com/shaka-project/shaka-player

An open-source JavaScript library for adaptive media streaming, supporting DASH, HLS, and experimental MOQT. It leverages MSE and EME for high-quality video and audio playback across browsers and devices. Key features include adaptive bitrate streaming, offline playback via IndexedDB, DRM support (Widevine, PlayReady, FairPlay, ClearKey), and extensive support for various manifest formats, media containers, and subtitles.

Tokens
67.4K
Snippets
171
Records
306
Agent score
93%

What's inside Shaka Player

  1. Overview of Shaka UI Library

    main

    Shaka UI is a customizable, easy-to-set-up UI layer designed for Shaka Player. It provides a default set of video controls that are visually similar to Chrome native controls. Key features include:

    • Built-in Accessibility: Designed with accessibility standards in mind.
    • Localization Support: Built-in support for different languages.
    • Customization: Can be styled via CSS or customized through the UI API.
    • Build Integration: The UI layer is included in the default Shaka Player build, but can be excluded if not needed to reduce bundle size.
  2. Overview of Shaka Player

    main

    Shaka Player is an open-source JavaScript library designed for adaptive media streaming. It enables playback of adaptive formats like DASH and HLS in web browsers using standard web technologies: MediaSource Extensions (MSE) and Encrypted Media Extensions (EME).

    Key capabilities include:

    • Adaptive Bitrate Streaming: Support for DASH and HLS.
    • Offline Playback: Support for offline storage and playback using IndexedDB.
    • Lightweight Design: Minimal third-party dependencies.
  3. Choose between NativeTextDisplayer and UITextDisplayer

    main

    Shaka Player provides two implementations of shaka.extern.TextDisplayer for rendering and styling subtitles:

    1. shaka.text.NativeTextDisplayer: Uses the browser's native cue renderer by creating text tracks on the video element. This is the default when Shaka UI is not used, and it is also used during Picture-in-Picture (PiP) or when using the video element's native Fullscreen API.

    2. shaka.text.UITextDisplayer: Renders subtitles inside a DOM container. This is used automatically when using Shaka UI. To use it manually, you must provide a container via the shaka.Player constructor or the setVideoContainer method.

    // Take your custom video container element.
    const container = document.getElementById('video_container');
    // Attach container using player constructor.
    const player = new shaka.Player(/* mediaElement= */ null, container);
    // Alternatively, pass it using dedicated method.
    player.setVideoContainer(container);
  4. Understand Gap Jumping in Shaka Player

    main

    Gap jumping is a feature designed to automatically skip over missing content (gaps) in a stream to prevent the player from stalling. Shaka Player handles two types of gaps:

    1. Gaps in the manifest: These are detected during parsing. The manifest parser removes these gaps and ensures the internal segment index remains continuous. This allows the StreamingEngine to buffer segments normally without being aware of the gaps.
    2. Gaps in the media: These are gaps in the actual media content that are not explicitly defined in the manifest. These can only be detected once media is appended to the MediaSource and the browser reports a gap in the buffered ranges. The Playhead component is responsible for detecting these gaps and jumping the playhead to the next available content.
  5. Understand translation maintenance and locale types

    main

    Shaka Player translations are categorized into three types:

    1. Google-maintained locales: Most translations are managed by Google. While you can contribute changes directly on GitHub, they must be synced back to Google's internal systems by a Googler to prevent them from being overwritten.
    2. Meta-languages (Testing only): These are fake locales used for automated testing and are maintained by internal systems:
      • ar-XB: Right-to-left English (used to identify RTL issues).
      • en-XA: Accented English (used to spot hard-coded text).
    3. Community-maintained locales: These are not maintained by Google and require community updates:
      • oc (Occitan)
      • sjn (Sindarin)
  6. Understand the Google App Engine compatibility shim

    main
    The app-engine directory contains source code for services previously hosted on Google App Engine. Most primary services have been shut down. The remaining component, shaka-player-demo, acts as a compatibility shim that parses outdated links to the old hosted demo and redirects users to the new demo hosted on GitHub Pages.
  7. Understand DASH Presentation Timeline and Time Types

    main

    DASH playback relies on a unified presentation timeline that starts at 0. Shaka Player maps this timeline directly to the HTML5 <video> element, meaning video.currentTime represents the presentation time.

    Key time concepts:

    • Presentation time: The time elapsed since the start of the presentation (0 for VOD, or since the live stream started for live content). This is what the player uses for seeking.
    • Media time: The timestamp encoded within a media segment. It is used by the browser's media engine to place the segment in the <video> element. The manifest uses presentationTimeOffset (PTO) and Period@start to adjust media times so they align with the presentation timeline.
    • Wall-Clock time: Real-world time (e.g., Unix epoch). It is used to calculate the live edge but does not represent the actual playback position.
  8. Understand Shaka Player locale definitions

    main

    Shaka Player uses a hierarchical locale system to manage languages, regions, and dialects. A locale is composed of three optional components:

    1. language: A lowercase 2-character code (preferably ISO 639).
    2. region: An uppercase 2-character code (preferably ISO 3166).
    3. dialect: A lowercase n-character code.

    Locales must follow one of these three patterns:

    • language (e.g., en)
    • language-REGION (e.g., en-US)
    • language-REGION-dialect (e.g., en-US-wa)
  9. Use Shaka Player with Vue.js

    main

    Shaka Player cannot be used as a reactive Vue object. Wrapping the player instance in a Vue ref() or a reactive data() object will cause failures because Vue's Proxy mechanism interferes with Shaka's internal values.

    Best Practice:

    • Do not use ref() for the player instance.
    • If using data(), prefix the player property name with $ or _ (e.g., $player) to prevent Vue from proxying it.
  10. Create custom UI elements

    main

    To add custom buttons, implement the shaka.extern.IUIElement interface. It is recommended to extend shaka.ui.Element. You must also provide a Factory class with a create(rootElement, controls) method and register it using shaka.ui.Controls.registerElement(name, factory).

    // 1. Implement the element
    myapp.SkipButton = class extends shaka.ui.Element {
      constructor(parent, controls) {
        super(parent, controls);
        this.button_ = document.createElement('button');
        this.button_.textContent = 'Skip current video';
        this.parent.appendChild(this.button_);
    
        this.eventManager.listen(this.button_, 'click', () => {
          const nextManifest = myapp.getNextManifest();
          this.player.load(nextManifest);
        });
      }
    };
    
    // 2. Implement the Factory
    myapp.SkipButton.Factory = class {
      create(rootElement, controls) {
        return new myapp.SkipButton(rootElement, controls);
      }
    };
    
    // 3. Register the element
    shaka.ui.Controls.registerElement('skip', new myapp.SkipButton.Factory());
    
    // 4. Use in config
    uiConfig['controlPanelElements'] = ['rewind', 'fast_forward', 'skip'];
  11. Use metadata for application-side data

    main

    Each QueueItem can include a metadata object of type shaka.extern.QueueItemMetadata. While Shaka Player does not use this data internally, it is useful for driving your own UI. Common properties include title and poster.

    Example of reading metadata during a change:

    queueManager.addEventListener('currentitemchanged', () => {
      const item = queueManager.getCurrentItem();
      if (item?.metadata) {
        document.getElementById('title').textContent = item.metadata.title ?? '';
        document.getElementById('poster').src = item.metadata.poster ?? '';
      }
    });