### 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);
```