### Create Custom Build Configuration for Plugins Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/plugins.md This example shows how to create a custom build configuration file to manage a list of customizations, including adding and removing features and plugins. It starts with a complete build, removes subtitle support and default networking plugins, and then adds custom HTTP and polyfill plugins. ```sh # Start with a complete library +@complete # Drop subtitle support -@text # Remove default networking plugins -@networking # Add my custom HTTP implementation +/path/to/my_http_plugin.js # Add an additional polyfill for some odd platform I'm targeting +/path/to/my_platform_polyfill.js ``` -------------------------------- ### Full MoQT Configuration Example Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/moq.md An example demonstrating a comprehensive configuration for Shaka Player's MoQT manifest settings. ```js player.configure({ manifest: { msf: { fingerprintUri: '', // Set for self-signed cert servers namespaces: ['live', 'ch1'], // Known namespace; leave [] to auto-discover authorizationToken: '', // Bearer token if required by server useFetchCatalog: false, // true = one-shot FETCH, false = SUBSCRIBE version: shaka.config.MsfVersion.AUTO, // Version negotiation strategy subscribeFilterType: shaka.config.MsfFilterType.LARGEST_OBJECT, catalogPreprocessor: (catalog) => catalog, // Identity (no-op) } } }); ``` -------------------------------- ### Install Linux Prerequisites Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/welcome.md Use this script to quickly install Shaka Player build prerequisites on Ubuntu or Debian. ```sh curl https://raw.githubusercontent.com/shaka-project/shaka-player/main/build/install-linux-prereqs.sh | bash ``` -------------------------------- ### Install Legacy FairPlay Polyfill Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/fairplay.md Use this to install the legacy Apple Media Keys polyfill if your provider does not support Modern EME. ```js shaka.polyfill.PatchedMediaKeysApple.install(); ``` -------------------------------- ### Full Manifest Parser Example Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/manifest-parser.md This example demonstrates a complete manifest parser implementation, including methods for loading the manifest, variants, streams, and segment references. It's useful for understanding the structure and components required for custom manifest parsing. ```js MyManifestParser.prototype.loadManifest_ = function(data) { // |data| is the response data from load(); but in this example, we ignore it. // The arguments are only used for live. const timeline = new shaka.media.PresentationTimeline(null, 0); timeline.setDuration(3600); // seconds return { presentationTimeline: timeline, offlineSessionIds: [], variants: [ this.loadVariant_(true, true), this.loadVariant_(true, false) ], textStreams: [ this.loadStream_('text'), this.loadStream_('text') ] }; }; MyManifestParser.prototype.loadVariant_ = function(hasVideo, hasAudio) { console.assert(hasVideo || hasAudio); return { id: this.curId_++, language: 'en', primary: false, audio: hasAudio ? this.loadStream_('audio') : null, video: hasVideo ? this.loadStream_('video') : null, bandwidth: 8000, // bits/sec, audio+video combined allowedByApplication: true, // always initially true allowedByKeySystem: true // always initially true }; }; MyManifestParser.prototype.loadStream_ = function(type) { const getUris = function() { return ['https://example.com/init']; }; const initSegmentReference = new shaka.media.InitSegmentReference(getUris, /* startByte= */ 0, /* endByte= */ null); const index = new shaka.media.SegmentIndex([ // Times are in seconds, relative to the presentation this.loadReference_(0, 0, 10, initSegmentReference), this.loadReference_(1, 10, 20, initSegmentReference), this.loadReference_(2, 20, 30, initSegmentReference), ]); const id = this.curId_++; return { id: id, // globally unique ID originalId: id, // original ID from manifest, if any createSegmentIndex: function() { return Promise.resolve(); }, segmentIndex: index, mimeType: type == 'video' ? 'video/webm' : (type == 'audio' ? 'audio/webm' : 'text/vtt'), codecs: type == 'video' ? 'vp9' : (type == 'audio' ? 'vorbis' : ''), frameRate: type == 'video' ? 24 : undefined, pixelAspectRatio: type == 'video' ? 4 / 3 : undefined, bandwidth: 4000, // bits/sec width: type == 'video' ? 640 : undefined, height: type == 'video' ? 480 : undefined, kind: type == 'text' ? 'subtitles' : undefined, channelsCount: type == 'audio' ? 2 : undefined, encrypted: false, drmInfos: [], keyIds: new Set(), language: 'en', label: 'my_stream', type: type, primary: false, trickModeVideo: null, emsgSchemeIdUris: null, roles: [] channelsCount: type == 'audio' ? 6 : null, audioSamplingRate: type == 'audio' ? 44100 : null, closedCaptions: new Map(), }; }; MyManifestParser.prototype.loadReference_ = function(position, start, end, initSegmentReference) { const getUris = function() { return ['https://example.com/ref_' + position]; }; return new shaka.media.SegmentReference( start, end, getUris, /* startByte */ 0, /* endByte */ null, initSegmentReference, /* timestampOffset */ 0, /* appendWindowStart */ 0, /* appendWindowEnd */ Infinity); }; ``` -------------------------------- ### Configure Basic License Server Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/license-server-auth.md Configure the player with a manifest URI and a license server that does not require authentication. This is the starting point for the tutorial. ```javascript const manifestUri = 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'; const licenseServer = 'https://cwip-shaka-proxy.appspot.com/no_auth'; ``` ```javascript player.configure({ drm: { servers: { 'com.widevine.alpha': licenseServer } } }); // Try to load a manifest. try { await player.load(manifestUri); // The video should now be playing! } catch (e) { onError(e); } ``` -------------------------------- ### Navigate and Inspect Queue Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/queue-manager.md Provides examples for controlling playback within the queue, such as jumping to a specific item by its index, retrieving the currently playing item's details, and getting the total number of items in the queue. ```javascript // Play the third item (zero-based index) await queueManager.playItem(2); // Get the currently playing item const currentItem = queueManager.getCurrentItem(); console.log('Now playing:', currentItem.manifestUri); // Get the current index const index = queueManager.getCurrentItemIndex(); // Get a snapshot of all items in the queue const allItems = queueManager.getItems(); console.log(`Queue has ${allItems.length} items`); ``` -------------------------------- ### Example Wrapped License Response JSON Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/license-wrapping.md This is an example of a wrapped license response format sent by the license server. It includes the raw license encoded in base64. ```json { "rawLicenseBase64": "VGhlIHJhdyBsaWNlbnNlIGZyb20gdGhlIGxpY2Vuc2Ugc2VydmVyIGJhY2tlbmQ=", ... } ``` -------------------------------- ### Example Wrapped License Request Structure Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/license-wrapping.md This is an example of the JSON structure expected by the license server for a wrapped license request. It includes the raw license request encoded in base64. ```json { "rawLicenseRequestBase64": "VGhlIHJhdyBsaWNlbnNlIHJlcXVlc3QgZ2VuZXJhdGVkIGJ5IHRoZSBDRE0=", ... } ``` -------------------------------- ### Console Output for Async Token Fetch Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/license-server-auth.md Example console output demonstrating the flow of fetching an authentication token asynchronously before the license request is completed. ```html
Need auth token.
Received auth token VGhpc0lzQVRlc3QK
License request can now continue.
``` -------------------------------- ### Load MoQ Stream with Shaka Player Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/moq.md Basic example demonstrating how to initialize Shaka Player and load a MoQ stream. The 'application/msf' mimeType is mandatory for MoQ streams. ```javascript const manifestUri = 'https://relay.example.com/moq-endpoint'; async function initPlayer() { shaka.polyfill.installAll(); if (!shaka.Player.isBrowserSupported()) { console.error('Browser not supported!'); return; } const video = document.getElementById('video'); const player = new shaka.Player(); await player.attach(video); player.addEventListener('error', (event) => { console.error('Error code', event.detail.code, event.detail); }); try { // The mimeType 'application/msf' is REQUIRED for MOQ streams. await player.load(manifestUri, /* startTime= */ null, 'application/msf'); console.log('MOQ stream loaded!'); } catch (e) { console.error('Load failed', e); } } document.addEventListener('DOMContentLoaded', initPlayer); ``` -------------------------------- ### Run build.py with PRINT_ARGUMENTS Source: https://github.com/shaka-project/shaka-player/blob/main/build/README.md This example shows how to run the `build.py` script with the `PRINT_ARGUMENTS` environment variable set to 1. This will print the command-line arguments passed to subprocesses, which can be useful for debugging. ```shell PRINT_ARGUMENTS=1 build.py git -C /path/to/shaka describe --tags --dirty Compiling the library... java -jar /path/to/shaka/node_modules/.../compiler.jar --language_in ... ``` -------------------------------- ### Manifest Parser `start` Method in v2.4 Source: https://github.com/shaka-project/shaka-player/blob/main/docs/upgrades/upgrade-v2.0-to-v2.4.md The v2.4 manifest parser interface's `start` method now accepts a single `playerInterface` object, consolidating Player-related parameters for better extensibility. This change is necessary for compatibility with newer Shaka Player versions. ```javascript // v2.4 /** * @param {string} uri The URI of the manifest. * @param {shakaExtern.ManifestParser.PlayerInterface} playerInterface Contains * the interface to the Player. * @return {!Promise.} */ MyManifestParser.prototype.start = function(uri, playerInterface) { this.playerInterface_ = playerInterface; var type = shaka.net.NetworkingEngine.RequestType.MANIFEST; var request = shaka.net.NetworkingEngine.makeRequest( [uri], this.config_.retryParameters); return this.playerInterface_.networkingEngine.request(type, request).then( function(response) { this.manifest_ = this.parseInternal_(response.data); this.updateInterval_ = setInterval(this.updateManifest_.bind(this), 5000); return this.manifest_; }); }; ``` -------------------------------- ### Preload Asset with Start Time and MIME Type Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/preload.md Preloads an asset specifying an optional start time and MIME type, similar to the `load` method. This allows for more control over the initial loading process. ```javascript const preloadManager = await player.preload( 'https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd', 15, 'application/dash+xml'); ``` -------------------------------- ### ClearKey Configuration in Shaka Player v2 Source: https://github.com/shaka-project/shaka-player/blob/main/docs/upgrades/upgrade-v1-to-v2.md v2 simplifies ClearKey setup using player.configure() with a clearKeys object mapping key IDs to license URLs. ```javascript // v2: player.configure({ drm: { clearKeys: { 'deadbeefdeadbeefdeadbeefdeadbeef': '18675309186753091867530918675309', '02030507011013017019023029031037': '03050701302303204201080425098033' } } }); ``` -------------------------------- ### Manifest Parser `start` Method in v2.0 Source: https://github.com/shaka-project/shaka-player/blob/main/docs/upgrades/upgrade-v2.0-to-v2.4.md The v2.0 manifest parser interface's `start` method accepted multiple parameters directly from the Player object. This version is now deprecated. ```javascript // v2.0 /** @constructor */ function MyManifestParser() {} /** @param {shakaExtern.ManifestConfiguration} config */ MyManifestParser.configure = function(config) { this.config_ = config; }; /** * @param {string} uri * @param {!shaka.net.NetworkingEngine} networkingEngine * @param {function(shakaExtern.Period)} filterPeriod * @param {function(!shaka.util.Error)} onError * @param {function(!Event)} onEvent * @return {!Promise.} */ MyManifestParser.prototype.start = function(networkingEngine, filterPeriod, onError, onEvent) { this.networkingEngine_ = networkingEngine; this.filterPeriod_ = filterPeriod; this.onError_ = onError; this.onEvent_ = onEvent; var type = shaka.net.NetworkingEngine.RequestType.MANIFEST; var request = shaka.net.NetworkingEngine.makeRequest( [uri], this.config_.retryParameters); return this.networkingEngine_.request(type, request).promise .then(function(response) { this.manifest_ = this.parseInternal_(response.data); this.updateInterval_ = setInterval(this.updateManifest_.bind(this), 5000); return this.manifest_; }); }; /** @return {!Promise} */ MyManifestParser.prototype.stop = function() { clearInterval(this.updateInterval_); return Promise.resolve(); }; ``` -------------------------------- ### Locale Search Order Example (en) Source: https://github.com/shaka-project/shaka-player/blob/main/docs/design/current/localization-design-principles.md Illustrates the search order for locale 'en', prioritizing self, then parent, then siblings, and finally children locales. ```text Available locales: "en", "en-US", "en-GB", en-CA", "fr", "fr-CA" Search order for "en": | 1. self | -> | 2. parent | -> | 3. siblings | -> | 4. children | ----------------------------------------------------------------- | a. en | | | | | | a. en-US | | | | | | | | b. en-GB | | | | | | | | c. en-CA | ``` -------------------------------- ### Async Function Declaration Examples Source: https://github.com/shaka-project/shaka-player/blob/main/docs/style.md Demonstrates various ways to declare asynchronous functions using the `async` keyword, which enables the use of `await`. ```javascript const f = async function () { ... }; ``` ```javascript const f = async () => { }; ``` ```javascript class X { async f() { ... } } ``` -------------------------------- ### Locale Search Order Example (en-US) Source: https://github.com/shaka-project/shaka-player/blob/main/docs/design/current/localization-design-principles.md Demonstrates the search order for locale 'en-US', showing the preference for self, parent, siblings, and then children locales. ```text Available locales: "en", "en-US", "en-GB", en-CA", "fr", "fr-CA" Search order for "en-US": | 1. self | -> | 2. parent | -> | 3. siblings | -> | 4. children | ------------------------------------------------------------------- | a. en-US | | a. en | | a. en-GB | | | | | | | | b. en-CA | | | ``` -------------------------------- ### Configure MoQ Namespaces Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/moq.md Example of configuring the 'namespaces' option for MoQ streams. This explicitly sets the namespace to subscribe to for the catalog track, reducing startup latency. ```javascript player.configure({ manifest: { msf: { // Subscribe to the catalog in namespace ['live', 'channel1'] namespaces: ['live', 'channel1'], } } }); ``` -------------------------------- ### JavaScript: Perform Shaka Player Support Test Source: https://github.com/shaka-project/shaka-player/blob/main/support.html Installs all Shaka Player polyfills, checks browser support, probes media feature support, and prints the results. ```javascript function doTest() { shaka.polyfill.installAll(); if (shaka.Player.isBrowserSupported()) { shaka.Player.probeSupport().then(function(support) { printSupport(JSON.stringify(support, null, ' ')); }); } else { printSupport('This browser is not supported.'); } } whenLoaded(doTest); ``` -------------------------------- ### Install FairPlay Polyfill with Uninstall Option Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/fairplay.md Enables uninstalling the legacy Apple Media Keys polyfill, useful when supporting multiple DRM providers that require both legacy and Modern EME. ```js shaka.polyfill.PatchedMediaKeysApple.install(/* enableUninstall= */ true); shaka.polyfill.PatchedMediaKeysApple.uninstall(); ``` -------------------------------- ### Get Native and English Language Names with langmap Source: https://github.com/shaka-project/shaka-player/blob/main/third_party/language-mapping-list/README.md Use the `langmap` package to retrieve the native and English names for specified locales. Install the package using `npm install langmap`. ```javascript var langmap = require("langmap"); "Native" => English (US) var native = langmap["en-US"]["nativeName"]; "Native" => ภาษาไทย var native = langmap["th"]["nativeName"]; "English" => Thai var native = langmap["th"]["englishName"]; ``` -------------------------------- ### Add Custom Overlay Interstitial Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/ad_monetization.md Use this to add a custom overlay ad. Configure properties like start time, URI, and overlay dimensions. If using Shaka UI, container setup is not necessary. ```javascript const video = document.getElementById('video'); const ui = video['ui']; const controls = ui.getControls(); const player = controls.getPlayer(); const adManager = player.getAdManager(); // If you're using a non-UI build, this is the div you'll need to create // for your layout. const csContainer = controls.getClientSideAdContainer(); const ssContainer = controls.getServerSideAdContainer(); // Note: If you are using Shaka UI this call is not necessary. adManager.setContainers(csContainer, ssContainer); adManager.addCustomInterstitial({ id: null, groupId: null, startTime: 10, endTime: null, uri: 'YOUR_URL', mimeType: null, isSkippable: true, skipOffset: 10, skipFor: null, canJump: false, resumeOffset: null, playoutLimit: null, once: true, pre: false, post: false, timelineRange: false, loop: false, overlay: { // Show interstitial in upper right quadrant viewport: { x: 1920, // Pixels y: 1080, // Pixels }, topLeft: { x: 960, // Pixels y: 0, // Pixels }, size: { x: 960, // Pixels y: 540, // Pixels }, }, displayOnBackground: false, currentVideo: null, background: null, clickThroughUrl: null, tracking: null, }); ``` -------------------------------- ### Setting Playback Start Time in Shaka Player v1 Source: https://github.com/shaka-project/shaka-player/blob/main/docs/upgrades/upgrade-v1-to-v2.md v1 used setPlaybackStartTime() before calling load() to specify an arbitrary playback start time. ```javascript // v1: player.setPlaybackStartTime(123.45); player.load(manifestUri); ``` -------------------------------- ### Initialize Shaka Player Instance Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/offline.md Sets up the Shaka Player instance, attaches it to the video element, configures storage, and sets up UI event handlers for download and content management. ```javascript async function initPlayer() { // Create a Player instance. const video = document.getElementById('video'); const player = new shaka.Player(); await player.attach(video); // Attach player and storage to the window to make it easy to access // in the JS console and so we can access it in other methods. window.player = player; // Listen for error events. player.addEventListener('error', onErrorEvent); initStorage(player); const downloadButton = document.getElementById('download-button'); downloadButton.onclick = onDownloadClick; // Update the content list to show what items we initially have // stored offline. refreshContentList(); } ``` -------------------------------- ### Shaka Player UI with LCEVC Setup Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/lcevc.md Sample HTML structure for setting up Shaka Player UI with LCEVC enhancement. Ensure Shaka Player UI, default CSS, and the LCEVC decoder are included. ```html
``` -------------------------------- ### Setting Playback Start Time in Shaka Player v2 Source: https://github.com/shaka-project/shaka-player/blob/main/docs/upgrades/upgrade-v1-to-v2.md v2 integrates playback start time setting as an optional parameter directly within the load() method. ```javascript // v2: player.load(manifestUri, 123.45); ``` -------------------------------- ### Initialize Screenshot Display and Event Handlers Source: https://github.com/shaka-project/shaka-player/blob/main/test/test/assets/screenshots/review.html Sets up options for platforms, prefixes, and tests, appends screenshot elements, and adds event listeners for keyboard and focus events. It also consumes URL hash parameters for initial filter settings. ```javascript const allOptions = {}; const allScreenshots = []; const allTestOptionContainers = []; for (const platform of platforms) { appendOption(platformsElement, 'platform', platform, applyFilters); } for (const prefix of prefixes) { appendOption(prefixesElement, 'prefix', prefix, applyFilters); } for (const suite in suites) { appendOption(suitesElement, 'suite', suite, applySuiteFilters); for (const test of suites[suite]) { const container = appendOption(testsElement, 'test', test, applyFilters); container.dataset.suite = suite; allTestOptionContainers.push(container); } } appendOption(miscElement, 'misc', 'break between tests', applyFilters); for (const suite in suites) { for (const test of suites[suite]) { for (const prefix of prefixes) { if (excludes.includes(`${suite}-${prefix}-${test}`)) { continue; } for (const platform of platforms) { appendScreenshot(platform, suite, prefix, test); } appendScreenshotLineBreak(); } } } document.body.addEventListener('keydown', keyHandler); document.body.addEventListener('keyup', keyHandler); window.addEventListener('blur', focusHandler); window.addEventListener('focus', focusHandler); // Consume URL hash parameters that indicate filters. // Ignore the '#' in location.hash with substr(1). for (const param of location.hash.substr(1).split('&')) { const [key, value] = param.split('='); try { allOptions[key][decodeURIComponent(value)].checked = true; } catch (error) {} // ignore errors } // Apply the initial filters. initializeFilters(); ``` -------------------------------- ### Initialize Player and Queue Manager Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/queue-manager.md Demonstrates how to initialize a Shaka Player instance, attach it to a video element, retrieve the Queue Manager, and insert initial media items into the playlist. Playback starts from the first item. ```javascript async function initPlayer() { const video = document.getElementById('video'); const player = new shaka.Player(); await player.attach(video); const queueManager = player.getQueueManager(); // Insert one or more items into the queue queueManager.insertItems([ { manifestUri: 'https://example.com/video1/dash.mpd' }, { manifestUri: 'https://example.com/video2/dash.mpd' }, { manifestUri: 'https://example.com/video3/dash.mpd' }, ]); // Start playback from the first item await queueManager.playItem(0); } ``` -------------------------------- ### Shaka Player Initialization with LCEVC Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/lcevc.md Initialize Shaka Player within the UI library, enable LCEVC, and load a manifest. Error handling is included for load failures. ```javascript // app.js const manifestUri = 'https://dyctis843rxh5.cloudfront.net/vnIAZIaowG1K7qOt/master.m3u8'; // Initialise Shaka Player with LCEVC enhancement. async function init() { // When using the UI, the player is made automatically by the UI object. const video = document.getElementById('video'); const ui = video['ui']; const controls = ui.getControls(); const player = controls.getPlayer(); // Enable the LCEVC enhancement. player.configure('lcevc.enabled', true); // Listen for error events. player.addEventListener('error', onError); controls.addEventListener('error', onError); // Try to load a manifest. // This is an asynchronous process. try { await player.load(manifestUri); // This runs if the asynchronous load is successful. console.log('The video has now been loaded!'); } catch (error) { onError(error); } } // Handle errors. function onError(error) { console.error('Error', error); } // Listen to the custom shaka-ui-loaded event, to wait until the UI is loaded. document.addEventListener('shaka-ui-loaded', init); // Listen to the custom shaka-ui-load-failed event, in case Shaka Player fails // to load (e.g. due to lack of browser support). document.addEventListener('shaka-ui-load-failed', onError); ``` -------------------------------- ### Programmatic UI Setup with Shaka Player Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/ui.md Initialize Shaka Player and its UI programmatically using shaka.ui.Overlay. This is useful for integrating with UI frameworks. Configure player options like castReceiverAppId and castAndroidReceiverCompatible. ```javascript // "local" because it is for local playback only, as opposed to the player proxy // object, which will route your calls to the ChromeCast receiver as necessary. const localPlayer = new shaka.Player(); // "Overlay" because the UI will add DOM elements inside the container, // to visually overlay the video element const ui = new shaka.ui.Overlay(localPlayer, videoContainerElement, videoElement); // Now that the player has been configured to be part of a UI, attach it to the // video. await localPlayer.attach(videoElement); // As with DOM-based setup, get access to the UI controls and player from the // UI. const controls = ui.getControls(); // These are cast-enabled proxy objects, so that when you are casting, // your API calls will be routed to the remote playback session. const player = controls.getPlayer(); const video = controls.getVideo(); // Programmatically configure the Chromecast Receiver App Id and Android // Receiver Compatibility. ui.configure({ // Set the castReceiverAppId 'castReceiverAppId': '07AEE832', // Enable casting to native Android Apps (e.g. Android TV Apps) 'castAndroidReceiverCompatible': true, }); ``` -------------------------------- ### Initialize Shaka Player Offline Storage Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/offline.md Create a storage instance and configure optional callbacks for download progress and track selection. Assign the instance to `window.storage` for global access. ```javascript // Create a storage instance and configure it with optional // callbacks. Set the progress callback so that we visualize // download progress and override the track selection callback. window.storage = new shaka.offline.Storage(player); window.storage.configure({ offline: { progressCallback: setDownloadProgress, trackSelectionCallback: selectTracks } }); ``` -------------------------------- ### Calculate Live Edge in DASH Source: https://github.com/shaka-project/shaka-player/blob/main/docs/design/current/dash-manifests.md Calculates the live edge for DASH playback using availability start time, current time, and maximum segment size. This value is then used to set the video's current time to start playback at the live edge. ```javascript const ast = 1518717600; // availabilityStartTime="2018-02-15T18:00:00Z" const now = 1518718680; // (Date.now() / 1000) -> 2018-02-15T18:18:00Z const maxSegmentSize = 10; // seconds const liveEdge = now - ast - maxSegmentSize; // 1070 video.currentTime = liveEdge; // Start playing at live edge. // We'll start playing segments with a *presentation time* around 1070. ``` -------------------------------- ### Include LCEVC Decoder Locally Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/lcevc.md Include the LCEVC Decoder library locally by installing it via npm. ```html ``` -------------------------------- ### Initialize Ad Manager and Containers Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/ad_monetization.md Initialize the ad manager and set ad containers. This is necessary if you are not using Shaka's UI library. ```javascript const video = document.getElementById('video'); const ui = video['ui']; const controls = video.ui.getControls(); const player = controls.getPlayer(); const adManager = player.getAdManager(); // If you're using a non-UI build, this is the div you'll need to create // for your layout. const csContainer = controls.getClientSideAdContainer(); const ssContainer = controls.getServerSideAdContainer(); // Note: If you are using Shaka UI this call is not necessary. adManager.setContainers(csContainer, ssContainer); ``` -------------------------------- ### Get Shaka Player Source Code Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/welcome.md Clone the Shaka Player repository and navigate into the project directory. ```sh git clone https://github.com/shaka-project/shaka-player.git cd shaka-player ``` -------------------------------- ### Create a 32x32 green pixel image Source: https://github.com/shaka-project/shaka-player/blob/main/test/test/assets/green-pixel.txt Uses the `convert` command to create a base image. Ensure ImageMagick is installed. ```bash mkdir -p pixel # Create a 32x32 green pixel image convert xc:#008000[32x32] pixel/pixel0.png ``` -------------------------------- ### Map Key Systems for Broad Support Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/drm-config.md Configure a mapping to choose a specific key system implementation when a broader one is detected in the manifest. For example, this allows selecting 'com.microsoft.playready.recommendation' when the manifest uses 'com.microsoft.playready'. ```javascript player.configure({ drm: { keySystemsMapping: { 'com.microsoft.playready': 'com.microsoft.playready.recommendation' } } }); ``` -------------------------------- ### Revert Configuration to Default Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/config.md Set a configuration field to `undefined` to revert it to its default value. This example reverts the buffering goal. ```javascript player.configure({ streaming: { bufferingGoal: undefined, rebufferingGoal: 15 } }); ``` -------------------------------- ### Configure Use Fetch Catalog for MoQT Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/moq.md Enable or disable fetching the catalog using a one-shot FETCH instead of an ongoing SUBSCRIBE. Use true when the catalog is static. ```js player.configure({ manifest: { msf: { useFetchCatalog: true, } } }); ``` -------------------------------- ### Get Ad Manager Instance Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/ad_monetization.md Retrieve the ad manager instance from the player. This is the primary object for interacting with ad functionalities. ```javascript const adManager = player.getAdManager(); ``` -------------------------------- ### Get Current Player Configuration Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/config.md Retrieve the current configuration of the Shaka Player. This is useful for inspecting default or applied settings. ```javascript player.getConfiguration(); ``` -------------------------------- ### Configure Overflow Menu Buttons Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/ui-customization.md Use 'overflowMenuButtons' to specify which buttons appear in the overflow menu. This example adds only the 'cast' button. ```javascript const config = { 'overflowMenuButtons' : ['cast'] } ui.configure(config); ``` -------------------------------- ### Configure Buffering Parameters Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/network-and-buffering-config.md Set buffering goals and buffer behind playhead. Adjust bufferingGoal, rebufferingGoal, and bufferBehind in seconds. Ensure rebufferingGoal is less than bufferingGoal. ```js { streaming: { bufferingGoal: 30, rebufferingGoal: 15, bufferBehind: 30 } } ``` -------------------------------- ### Build custom Shaka Player with specific features Source: https://github.com/shaka-project/shaka-player/blob/main/build/README.md This command demonstrates building a custom version of Shaka Player with a specified name and including only manifests and networking features, along with a custom plugin from a local file. Use `--name` to set the build name and `+` or `-` prefixes for including or excluding features and files. ```shell build.py --name custom +@manifests +@networking +../my_plugin.js ``` -------------------------------- ### Configure Big Buttons Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/ui-customization.md Use 'bigButtons' to specify which buttons appear as large buttons in the control panel. This example adds only the 'play_pause' button. ```javascript const config = { 'bigButtons' : ['play_pause'] } ui.configure(config); ``` -------------------------------- ### Check and Probe Browser Support (v2) Source: https://github.com/shaka-project/shaka-player/blob/main/docs/upgrades/upgrade-v1-to-v2.md In v2, `shaka.Player.isBrowserSupported()` remains for basic checks, while `shaka.Player.probeSupport()` provides detailed, asynchronous diagnostics about EME capabilities. ```javascript // v2: if (!shaka.Player.isBrowserSupported()) { // Show an error and abort. } else { // Only call this method if the browser is supported. shaka.Player.probeSupport().then(function(support) { // The check is asynchronous because the EME API is asynchronous. // The support object contains much more information about what the browser // offers, if you need it. For example, if you require both Widevine and // WebM/VP9: if (!support.drm['com.widevine.alpha'] || !support.media['video/webm; codecs="vp9"']) { // Show an error and abort. } }); } ``` -------------------------------- ### Text Parser API Change: v2.1 Source: https://github.com/shaka-project/shaka-player/blob/main/docs/upgrades/upgrade-v2.1-to-v2.4.md Example of the text-parsing plugin API in v2.1, which returned VTTCue or TextTrackCue objects and accepted an ArrayBuffer. ```javascript // v2.1 /** * @param {!ArrayBuffer} data * @param {shakaExtern.TextParser.TimeContext} timeContext * @return {!Array.} */ MyTextParser.prototype.parseMedia = function(data, timeContext) { var cues = []; var parserState = new MyInternalParser(data); while (parserState.more()) { cues.push(new VTTCue(...)); } return cues; }; ``` -------------------------------- ### Set Multiple Configuration Options Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/config.md Apply multiple configuration changes simultaneously, including nested settings like preferred text language and buffering goal. ```javascript player.configure({ preferredTextLanguage: 'el', streaming: { bufferingGoal: 120 } }); ``` -------------------------------- ### Configure MoQ Fingerprint URI Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/moq.md Example of configuring the 'fingerprintUri' option for MoQ streams. This is required when connecting to a server with a self-signed TLS certificate. ```javascript player.configure({ manifest: { msf: { fingerprintUri: 'https://relay.example.com/cert.hex', } } }); ``` -------------------------------- ### Register Custom Text Displayer Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/text-displayer.md Provides an example of how to register a custom text displayer implementation with Shaka Player by providing a factory function. ```javascript player.configure({ textDisplayFactory: (player) => new CustomTextDisplayer(player), }); ``` -------------------------------- ### Basic HTML Setup for Shaka Player UI Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/ui.md This HTML structure includes the Shaka Player UI library, its default CSS, and the Chromecast SDK. It also sets up a container for the player and a video element, using data attributes to configure the UI. ```html
``` -------------------------------- ### Configure Queue Repeat Mode Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/queue-manager.md Shows how to set the repeat mode for the entire queue using the `configure` method. Supported modes include OFF, SINGLE, and ALL, affecting how playback behaves after the last item. ```javascript queueManager.configure({ repeatMode: shaka.config.RepeatMode.ALL, // Repeat the whole queue }); ``` -------------------------------- ### Browser Error Message for Invalid Credentials Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/license-server-auth.md Example of a browser console error message when attempting to send credentials cross-origin to a server that does not explicitly allow them. ```html Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials. Origin 'http://localhost' is therefore not allowed access. ``` -------------------------------- ### Load M3U Playlist and Play Immediately Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/queue-manager.md Populate the queue from a remote M3U or M3U8 playlist and start playing the first item immediately. The playlist is fetched using the player's networking engine. ```javascript // Load a playlist and start playing the first channel immediately. await queueManager.loadFromM3uPlaylist( 'https://example.com/channels.m3u', /* playOnLoad= */ true, ); ``` -------------------------------- ### CastProxy Constructor and Methods Source: https://github.com/shaka-project/shaka-player/blob/main/docs/design/current/chromecast.md Instantiate `CastProxy` with video, player, and receiver app ID. Use `destroy` to clean up, `getPlayer` and `getVideo` to access proxied objects, `canCast` and `isCasting` to check status, `cast` to connect, `setAppData` to send custom data, and `disconnect` to end the session. ```javascript new shaka.cast.CastProxy(video, player, receiverAppId, androidReceiverCompatible) // Also destroys the underlying local Player object shaka.cast.CastProxy.prototype.destroy() => Promise // Looks like shaka.Player, proxies to local or remote player based on cast // state shaka.cast.CastProxy.prototype.getPlayer() => shaka.Player // Looks like HTMLMediaElement, proxies to local or remote video based on cast // state shaka.cast.CastProxy.prototype.getVideo() => HTMLMediaElement // True if there are cast receivers available shaka.cast.CastProxy.prototype.canCast() => boolean // True if we are currently casting shaka.cast.CastProxy.prototype.isCasting() => boolean // Fired when either canCast or isCasting changes shaka.cast.CastProxy.CastStatusChangedEvent // Resolved when connected to a receiver, rejected if the connection fails shaka.cast.CastProxy.prototype.cast() => Promise // Transmits application-specific data to the receiver (now or on later connect) shaka.cast.CastProxy.prototype.setAppData(appData) // Disconnect from the receiver shaka.cast.CastProxy.prototype.disconnect() ``` -------------------------------- ### Locale Search Order Example Source: https://github.com/shaka-project/shaka-player/blob/main/docs/design/current/localization-design-principles.md Illustrates the hierarchical search order when multiple locales are available. The system prioritizes more specific locales first, falling back to more general ones if no matches are found. ```text Available locales: "en", "en-US", "en-GB", en-CA", "fr", "fr-CA", "fr-FR", ... Search Order for multiple preferences: | Preference 1 | -> | Preference 2 | -> ... -> | Preference N | | (en-US) | | (fr-CA) | | (...) | ---------------------------------------------------------------- | a. en-US | | a. fr-CA | | ... | | b. en | | b. fr | | | | c. en-GB | | c. fr-FR | | | | d. en-CA | | | | | ``` -------------------------------- ### Configure Authorization Token for MoQT Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/moq.md Set an authorization token to be sent during the MoQT client setup handshake. The token is encoded with alias type USE_VALUE. ```js player.configure({ manifest: { msf: { authorizationToken: 'Bearer my-secret-token', } } }); ``` -------------------------------- ### Migrating Audio Preferences in Shaka Player v6.0 Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/upgrade.md Demonstrates the transition from individual audio preference configurations to the new structured 'preferredAudio' array in Shaka Player v6.0. This new method allows for prioritized sets of preferences. ```javascript player.configure('preferredAudioLanguage', 'ko'); player.configure('preferredAudioChannelCount', 6); ``` ```javascript player.configure('preferredAudio', [ {language: 'ko', channelCount: 6}, {language: 'ko'}, {language: 'en'}, ]); ``` -------------------------------- ### Configure Header Authentication for License Server Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/license-server-auth.md Configure the player to use a license server that requires a custom authentication header. This uses the 'advanced' configuration option. ```javascript player.configure({ drm: { servers: { 'com.widevine.alpha': 'https://cwip-shaka-proxy.appspot.com/header_auth' }, advanced: { 'com.widevine.alpha': { 'headers': { // This is the specific header name and value the server wants: 'CWIP-Auth-Header': 'VGhpc0lzQVRlc3QK', } } } } }); ``` -------------------------------- ### Update PresentationTimeline notifySegments API Source: https://github.com/shaka-project/shaka-player/blob/main/docs/tutorials/upgrade-manifest.md The notifySegments method in PresentationTimeline no longer accepts a period start time or boolean flag. Pass only the segment reference array. ```javascript timeline.notifySegments(segmentList, /* periodStart= */ 0); ``` ```javascript timeline.notifySegments(segmentList, /* isFirstPeriod= */ true); ``` ```javascript timeline.notifySegments(segmentList); ```