### Site/Pages/Usage/Abr/Abandon Request Rule
---
title: AbandonRequestRule
---
# AbandonRequestRule
## Description
During the download of a media segment dash.js receives multiple `progress` events from the underlying API that is
used for downloading the data (e.g. `XMLHttpRequest`). These events have a timestamp and contain information about the
number of bytes that have been received so far. Using this information dash.js decides whether to abort the download of
a segment.
The `AbandonRequestRule` implements the logic to decide whether the download of a media segment shall be aborted.
Moreover, the rules decides to which quality to switch in such a scenario. Segment downloads are aborted if the current
throughput is not
sufficient to finish the download of the current media segment in a "reasonable" time.
For that reason, the `AbandonRequestRule` calculates the throughput based on the received samples (`progress` event)
from the current media segment. If the remaining download time for the current segment is larger than the current
segment duration multiplied
by `abandonDurationMultiplier` and the number of remaining bytes to download is larger than the number of total bytes
for the new quality the `AbandonRequestRule` triggers a switch to a lower quality:
```js
if (estimatedTimeOfDownloadInSeconds < request.duration * settings.get().streaming.abr.rules.abandonRequestsRule.parameters.abandonDurationMultiplier || abrController.isPlayingAtLowestQuality(representation)) {
return switchRequest;
}
const remainingBytesToDownload = request.bytesTotal - request.bytesLoaded;
const optimalRepresentationForBitrate = abrController.getOptimalRepresentationForBitrate(mediaInfo, throughputInKbit, true);
const totalBytesForOptimalRepresentation = request.bytesTotal * optimalRepresentationForBitrate.bitrateInKbit / currentRequestedRepresentation.bitrateInKbit;
// Switch quality in case there is a Representation that requires less bytes to download
if (remainingBytesToDownload > totalBytesForOptimalRepresentation) {
switchRequest.representation = optimalRepresentationForBitrate;
switchRequest.reason = {
throughputInKbit
}
abandonDict[request.index] = true;
logger.info(`[AbandonRequestRule][${mediaType} is asking to abandon and switch to quality to ${optimalRepresentationForBitrate.absoluteIndex}. The measured bandwidth was ${throughputInKbit} kbit/s`);
}
```
## Configuration Options
| Parameter | Description |
|:--------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------|
| `abandonDurationMultiplier` | Factor to multiply with the segment duration to compare against the estimated remaining download time of the current segment. See code example above. |
| `minSegmentDownloadTimeThresholdInMs` | The `AbandonRequestRule` only kicks if the download time of the current segment exceeds this value. |
| `minThroughputSamplesThreshold` | Minimum throughput samples (equivalent to number of `progress` events) required before the `AbandonRequestRule` kicks in. |
## Example
```js
player.updateSettings({
streaming: {
abr: {
rules: {
abandonRequestsRule: {
active: true,
parameters: {
abandonDurationMultiplier: 1.8,
minSegmentDownloadTimeThresholdInMs: 500,
minThroughputSamplesThreshold: 6
}
}
}
}
}
});
```
---
### Site/Pages/Usage/Abr/Bola Rule
---
title: BolaRule
---
# BolaRule
## Description
The `BolaRule` is a buffer based ABR rule. BOLA uses a bitrate selection function that maps the current buffer level to
the bitrate of the next segment to be downloaded. The illustration below shows an example of a bitrate selection
function for a video that is encoded in three bitrates (1000, 2500 and 5000 kbps) and has a buffer capacity of 18
seconds. The thresholds for switching to a different quality are at 5 and 10 seconds of buffer.
For additional details about the BOLA rule check out the following two paper:
* [From Theory to Practice: Improving Bitrate Adaptation in the DASH Reference Player](https://dl.acm.org/doi/pdf/10.1145/3336497)
* [BOLA: Near-optimal bitrate adaptation for online videos](https://ieeexplore.ieee.org/document/7524428)
## Example
```js
player.updateSettings({
streaming: {
abr: {
rules: {
bolaRule: {
active: true
}
}
}
}
});
```
---
### Site/Pages/Usage/Abr/Dropped Frames Rule
---
title: DroppedFramesRule
---
# DroppedFramesRule
## Description
While the current throughput and the current buffer level might allow playing the video stream on a high
quality `Representation` the underlying platform might not be able to render the content without dropping frames.
Dropped frames refer to video frames that are not successfully delivered or displayed during playback. This can occur
when the video playback system is unable to keep up with the required frame rate, resulting in skipped frames. Dropped
frames can cause a decrease in video quality and a disruption in smooth playback.
The `DroppedFramesRule` monitors the ratio of dropped frames and total frames and reduces the video quality if the ratio
exceeds the value defined in `droppedFramesPercentageThreshold`:
````js
if (totalFrames > settings.get().streaming.abr.rules.droppedFramesRule.parameters.minimumSampleSize
&& droppedFrames / totalFrames > settings.get().streaming.abr.rules.droppedFramesRule.parameters.droppedFramesPercentageThreshold) {
newRepresentation = representations[i - 1];
}
````
## Configuration Options
| Parameter | Description |
|:-----------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------|
| `minimumSampleSize` | Sum of rendered and dropped frames required for each Representation before the rule kicks in. |
| `droppedFramesPercentageThreshold` | Minimum percentage of dropped frames compared to total frames to trigger a quality downs-switch. Values are defined in the range of 0 - 1 |
## Example
```js
player.updateSettings({
streaming: {
abr: {
rules: {
droppedFramesRule: {
active: true,
parameters: {
minimumSampleSize: 375,
droppedFramesPercentageThreshold: 0.15
}
}
}
}
}
});
```
---
### Site/Pages/Usage/Abr/Index
---
title: Adaptive Bitrate Streaming
---
# Adaptive Bitrate Streaming
Encoding and packaging the media content with multiple bitrates and resolutions enables adaptive media streaming.
Mediaplayers such as dash.js can dynamically switch between different bitrates and resolutions based on factors such as
the current throughput, the current buffer level and the resolution on the end device.
dash.js has a flexible ABR decision logic in place that can be dynamically adjusted and extended. On the following pages
you can find information about the various settings that dash.js offers and how to plug in your own ABR algorithm:
* [ABR Settings](settings.html) - configure the ABR behavior and select the active algorithm
* [Manual quality selection](manual-quality-selection.html) - disable ABR and select qualities manually
* [Throughput Calculation](throughput-calculation.html) - how dash.js estimates the available bandwidth
## ABR Rules
The ABR decision logic is composed of individual rules. Each rule casts a switch request, the results are aggregated
into the final quality decision. The following pages describe the built-in rules in detail:
* [ThroughputRule](throughput-rule.html) - selects the quality based on the estimated throughput
* [BolaRule](bola-rule.html) - buffer based quality selection using the BOLA algorithm
* [InsufficientBufferRule](insufficient-buffer-rule.html) - avoids rebuffering by reacting to critical buffer levels
* [AbandonRequestRule](abandon-request-rule.html) - abandons segment downloads that take too long
* [DroppedFramesRule](dropped-frames-rule.html) - avoids qualities that cause dropped frames
* [SwitchHistoryRule](switch-history-rule.html) - penalizes qualities that were recently abandoned
* [L2A Rule](l2a.html) - learn2adapt rule for low latency streaming
* [LoL+ Rule](lol_plus.html) - low-on-latency rule set for low latency streaming
---
### Site/Pages/Usage/Abr/Insufficient Buffer Rule
---
title: InsufficientBufferRule
---
# InsufficientBufferRule
## Description
The `InsufficientBufferRule` verifies each ABR choice to make sure the download is unlikely
to cause a rebuffering event. The rule is best explained by looking at a concrete example. Assume the following values:
* `currentThroughput` = 5Mbit/s
* `currentSafeThroughput` = `currentThroughput` * `throughputSafetyFactor` = 5Mbit/s * 0.9 = 4.5 Mbit/s
* `currentBufferLevel` = 10 seconds
* `segmentDuration` = 4 seconds
To avoid a buffer underrun we need to finish the download of the next segment in 10 seconds. This means we need to
download 4 seconds of content in 10 seconds. This leads us to the following expression that we need to solve:
`possibleBitrate <= currentSafeThroughput * currentBufferLevel / segmentDuration`
Plugging the examples values from above we get:
`possibleBitrate <= 4.5 Mbit/s * 10s / 4s`
So in this case we can select a maximum bitrate of `11.25 Mbit/s`.
## Configuration Options
| Parameter | Description |
|:-------------------------|:--------------------------------------------------------------------------------------------------------------------------|
| `throughputSafetyFactor` | The safety factor that is applied to the derived throughput, see example in the Description. |
| `segmentIgnoreCount` | This rule is not taken into account until the first `segmentIgnoreCount` media segments have been appended to the buffer. |
## Example
```js
player.updateSettings({
streaming: {
abr: {
rules: {
insufficientBufferRule: {
active: true,
parameters: {
throughputSafetyFactor: 0.9,
segmentIgnoreCount: 2
}
}
}
}
}
});
```
---
### Site/Pages/Usage/Abr/L2a
---
title: L2A Rule
---
# L2A
## Description
In the context of adaptive streaming, an ABR algorithm aims at seamlessly adjusting (or adapting) the rate of the media
stream, to compensate for changing network conditions. Additionally, a buffer is typically deployed to protect the
client from abrupt changes in the communication channel (throughput, jitter etc.), or temporal misestimations of the ABR
algorithm. Since long buffer queues compound delay of the media rendering process, low-latency streaming requires very
short buffers, that in turn offer less protection against channel state estimation errors. Such errors are propagated to
the ABR decisions, that in turn can have a detrimental effect on streaming experience.
Therefore the goal of **Learn2Adapt-LowLatency (L2A-LL)**, a low-latency ABR, is to strike a favorable balance between
keeping the buffer as short as possible, while provisioning against its complete depletion. This is achieved by
selecting the highest sustainable bitrate for each video fragment, that does not completely consume the buffer budget
available at the time of request. L2A-LL is, in essence, an optimization solution with the objective of minimizing
latency, while at the same time maximizing achievable video bitrate and ensuring uninterrupted and stable streaming.
L2A-LL formulates the ABR optimization problem under an online (machine) learning framework, based on convex
optimization. First, the streaming client is modelled by a learning agent, whose objective is to minimize the average
buffer displacement of a streaming session. Second, certain requirements regarding the decision set (available bitrates)
and constraint functions are fulfilled by a) allowing the learning agent to make decisions on the video bitrate of each
fragment, according to a probability distribution and by b) deriving an appropriate constraint function associated with
the upper bound of the buffer queue, that adheres to time averaging constraints.
## Basic dash.js configuration
How to enable L2A:
```js
player.updateSettings({
streaming: {
abr: {
rules: {
l2a: {
active: true
}
}
}
}
});
```
## Advanced Tuning parameters
The following changes are for experienced users and need to be made in `streaming/rules/abr/L2ARule.js`. Please check
the [paper](https://dl.acm.org/doi/pdf/10.1145/3339825.3397042) for further details.
| Line | Parameter | Description | Conclusion |
|------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 306 | `horizon=4` | **Optimization horizon**: This parameter is used to specify the amount of steps required to achieve convergence. In live streaming settings this parameter must be kept low for stable performance. The selected value has been verified experimentally and alteration is not suggested. This parameter is used in lines 307 and 308, at the calculation of the 'vl' and 'alpha' parameters respectively. The calculation of 'vl' and 'alpha' are according to the theoretical performance guarantees as specified in the MMSys Publication [5]. Higher 'vl' values make the algorithm more aggressive in the bitrate selection and 'alpha' is the step size of the gradient descent approach of the learning process. | higher 'horizon' leads to more aggressive bitrate selection (higher 'vl') and less exploration (large 'alpha'). Not advisable for live streaming scenarios with short buffers. |
| 322 | `react=2` | **Reactiveness to volatility** (abrupt throughput drops). This parameter is used to recalibrate the 'l2AParameter.Q'. Higher values make the algorithm more conservative. The chosen value has been experimentally selected and alteration is not suggested. | Higher 'react' results in a more conservative algorithm (higher l2AParameter.Q). Caution: 'react' values higher than the selected (react=2) may make the algorithm select lowest bitrate for extended periods, until recovery of the l2AParameter.Q (updated at every fragment download) |
## Reference
* [Theo Karagkioules,R. Mekuria,Dirk Griffioen, Arjen Wagenaar - Online learning for low-latency adaptive streaming](https://dl.acm.org/doi/pdf/10.1145/3339825.3397042)
---
### Site/Pages/Usage/Abr/Lol Plus
---
title: LoL+ Rule
---
# LoL+
## Description
LoL+ is an algorithm optimized for CMAF low latency. As such it should not be used for "standard" VoD and live content
and only be activated if the CMAG segments contain CMAF chunks. LoL+ is designed as a series of sophisticated yet robust
player improvements for low latency live (LLL) streaming. LoL+ consists of five essential modules:
1. The **bitrate selection module** implements a learning-based ABR algorithm to choose a suitable bitrate at each
segment download. The ABR algorithm is based on an SOM model that considers multiple QoE metrics as well as bandwidth
variability.
2. The **playback speed control module** implements a hybrid algorithm that considers both the current latency and
buffer level to control the playback speed.
3. The **throughput measurement module** accurately calculates the throughout by removing the idle times between the
chunks of a segment through a three-step algorithm.
4. The **QoE evaluation module** computes the QoE considering five key metrics: selected bitrate, number of bitrate
switches, rebuffering duration, latency and playback speed.
5. Lastly, the **weight selection module** implements a two-step dynamic weight assignment for the SOM model features.
We also added manual (equal value of 0.4 each) and random (based on Xavier formula) weight assignment for the SOM
model features for comparison.
The modules can be found in the following files:
1. Bitrate selection module (i.e., ABR algorithm):
`dash.js/src/streaming/rules/abr/lolp/LoLpRule.js` and
`LearningAbrController.js`
2. Playback speed control module:
`dash.js/src/streaming/controllers/CatchupController.js`
3. Throughput measurement module:
`dash.js/src/streaming/net/FetchLoader.js`
4. QoE evaluation module:
`dash.js/src/streaming/rules/abr/lolp/LoLpQoeInfo.js` and `dash.js/src/streaming/rules/abr/lolp/LoLpQoEEvaluator.js`
5. Weight selection module:
`dash.js/src/streaming/rules/abr/lolp/LoLpWeightSelector.js`
## Basic dash.js configuration
How to enable each of the LoL+ modules:
```javascript
player.updateSettings({
streaming: {
abr: {
rules : {
loLPRule: {
active: true
}
},
throughput: {
lowLatencyDownloadTimeCalculationMode: dashjs.Constants.LOW_LATENCY_DOWNLOAD_TIME_CALCULATION_MODE.MOOF_PARSING
}
},
liveCatchup: {
mode: dashjs.Constants.LIVE_CATCHUP_MODE_LOLP
}
}
});
```
Note: The weight selection module is used in the bitrate selection module and does not need to be enabled separately.
## Advanced tuning parameters
The parameters below are available but not advised to be changed. For advanced users, please refer to the paper [3] for
further details on these parameters. The following parameters are not exposed in the `settings` object and have to be
changed in the respective classes.
Module | Parameter(s) | Remarks
--------------------------|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Bitrate selection module | targetLatency = 0 | SOM target latency
Bitrate selection module | targetRebufferLevel = 0 | SOM target rebuffering duration.
Bitrate selection module | targetSwitch = 0 | SOM target number of switches.
Bitrate selection module | throughputDelta = 10000 | SOM variation in throughput.
Weight selection module | DWS_TARGET_LATENCY = 1.5 | Latency constraint used in weight selection module (set in `LolpRule.js`).
Weight selection module | DWS_BUFFER_MIN = 0.3 | Minimum buffer value constraint used in weight selection module (set in `LolpRule.js`).
Weight selection module | weightObj.throughput, weightObj.latency, weightObj.buffer, weightObj.switch | The weight (value ranges between 0 and 1) of the current throughput, latency, rebuffering duration, and number of switches features of the SOM model (Bitrate selection module) will be assigned dynamically by this module based on the defined optimization function.
### Detailed code description
At each segment download, the bitrate selection module is triggered and works as follows:
##### (1) Obtain input parameters (pseudocode lines 4-10):
* Current player state: throughput, latency, rebuffer duration, bitrate variation (normalized)
* Weight vector from weight selection module: w
##### (2) Update previously selected neuron with current player state values (pseudocode line 11):
```javascript
// Code snippet from `LearningAbrController.js`
_updateNeurons(currentNeuron, somElements, [throughputNormalized, latency, rebuffer, bitrateSwitch]);
```
##### (3) Iterate all neurons to find the winner neuron that is closest (i.e., shortest distance) to the target state, while not violating special condition (pseudocode lines 12-27):
```js
// Code snippet from `LearningAbrController.js`
// special condition downshift immediately
if (somNeuron.bitrate > throughput - throughputDelta || isBufferLow) {
if (somNeuron.bitrate !== minBitrate) {
// encourage to pick smaller bitrates throughputWeight=100
distanceWeights[0] = 100;
}
}
// calculate the distance with the target
let distance = _getDistance(somData, [throughputNormalized, targetLatency, targetRebufferLevel, targetSwitch], distanceWeights);
if (minDistance === null || distance < minDistance) {
minDistance = distance;
minIndex = somNeuron.qualityIndex;
winnerNeuron = somNeuron;
winnerWeights = distanceWeights;
}
```
##### (4) Update the winner neuron with target state values. (pseudocode line 28):
```javascript
// Code snippet from `LearningAbrController.js`
_updateNeurons(winnerNeuron, somElements, [throughputNormalized, targetLatency, targetRebufferLevel, bitrateSwitch]);
```
Note: The QoE evaluation module is provided but QoE score is not used as a SOM factor in the current implementation of
the ABR algorithm. Advanced users may consider using it.
## Reference
* [May Lim, Mehmet N Akcay, Abdelhak Bentaleb, Ali C. Begen, R. Zimmermann - When they go high, we go low: low-latency live streaming in dash.js with LoL](https://dl.acm.org/doi/abs/10.1145/3339825.3397043)
---
### Site/Pages/Usage/Abr/Manual Quality Selection
---
title: Manual quality selection
---
# Manual quality selection
Next to the adaptive quality selection of dash.js there is also the possibility for applications and users to
manually select a specific quality (Representation). For that reason, dash.js provides two API endpoints, namely
`setRepresentationForTypeById()` and `setRepresentationForTypeByIndex()`.
## Selecting a Representation by ID
The recommended way to select a specific quality is by using the `id` attribute of the target Representation. A simple
example illustrating this behavior is depicted below:
````js
const availableQualities = player.getRepresentationsByType('video');
const targetRepresentation = availableQualities[0];
player.setRepresentationForTypeById('video', targetRepresentation.id);
````
In the example above we are querying the available qualities. dash.js will return an array of `Representation` objects
with a unique `id` attribute for each of the objects. Finally, we select the first entry in the array and tell dash.js
to switch to this Representation by using the `id` attribute.
## Selecting a Representation by index
Another way to select a specific Representation is by providing its index to dash.js. A simple example illustrating this
behavior is depicted below:
````js
const availableQualities = player.getRepresentationsByType('video');
const targetRepresentationIndex = availableQualities.length - 1;
player.setRepresentationForTypeByIndex('video', targetRepresentationIndex);
````
In the example above we are querying the available qualities. dash.js will return an array of `Representation` objects.
Finally, we count the number of entries in the array and select the one with the highest index.
**Note:** Each `Representation` object has an attribute `absoluteIndex`. This attribute is used internally by
dash.js
and might be different from the index of the `Representation` in the array returned by `getRepresentationsByType()`. For
that reason do **not** use the `absoluteIndex` when selecting a quality with `setRepresentationForTypeByIndex()`.
Instead, use the index of the target Representation in the array returned by `getRepresentationsByType()`.
---
### Site/Pages/Usage/Abr/Settings
---
title: ABR Settings
---
# ABR Settings
## ABR Examples
Multiple samples implementing the functionalities described in this documentation can be found in
the [ABR section](https://reference.dashif.org/dash.js/nightly/samples/index.html).
## Changing the default ABR algorithm
dash.js ships with multiple ABR rules. Per default, dash.js combines a throughput based ABR rule (`throughputRule`) with
a buffer based
ABR rule (`bolaRule`). The `abr` section in `Settings.js` allows a reconfiguration of the default ABR algorithms:
```js
player.updateSettings({
streaming: {
abr: {
rules: {
throughputRule: {
active: true
},
bolaRule: {
active: true
}
}
}
}
});
```
| ABR Rule | Description |
|:-----------------|:---------------------------------------|
| `throughputRule` | [ThroughputRule](throughput-rule.html) |
| `bolaRule` | [BolaRule](bola-rule.html) |
**Important**: If both `throughputRule` and `bolaRule` are enabled dash.js dynamically switches between those two
rules based on the current buffer level.
An example illustrating how to change the ABR rules is
available [here](https://reference.dashif.org/dash.js/nightly/samples/abr/abr.html).
## Additional ABR rules
Next to the two main ABR rules described above, dash.js defines additional ABR rules that run alongside the main rules
and
can be dynamically enabled and disabled.
```js
player.updateSettings({
abr: {
rules: {
insufficientBufferRule: {
active: false
},
switchHistoryRule: {
active: false
},
droppedFramesRule: {
active: false
},
abandonRequestsRule: {
active: false
},
l2ARule: {
active: false
},
loLPRule: {
active: false
}
}
}
});
```
| ABR Rule | Description |
|:-------------------------|:--------------------------------------------------------|
| `insufficientBufferRule` | [InsufficientBufferRule](insufficient-buffer-rule.html) |
| `switchHistoryRule` | [SwitchHistoryRule](switch-history-rule.html) |
| `droppedFramesRule` | [DroppedFramesRule](dropped-frames-rule.html) |
| `abandonRequestsRule` | [AbandonRequestRule](abandon-request-rule.html) |
| `l2ARule` | [L2ARule](l2a.html) |
| `loLPRule` | [LoL+](lol_plus.html) |
A detailed example is available [here](https://reference.dashif.org/dash.js/nightly/samples/abr/abr.html).
## Adding a custom ABR rule
dash.js allows applications to define their own ABR algorithms. For that reason, disable the default ABR rules and
use `player.addABRCustomRule()` to add your new rule:
```js
/* don't use dash.js default rules */
player.updateSettings({
abr: {
rules: {
throughputRule: {
active: false
},
bolaRule: {
active: false
},
insufficientBufferRule: {
active: false
},
switchHistoryRule: {
active: false
},
droppedFramesRule: {
active: false
},
abandonRequestsRule: {
active: false
}
}
}
});
/* add my custom quality switch rule. Look at LowestBitrateRule.js to know more */
/* about the structure of a custom rule */
player.addABRCustomRule('qualitySwitchRules', 'LowestBitrateRule', LowestBitrateRule);
```
A detailed example is available [here](https://reference.dashif.org/dash.js/nightly/samples/abr/custom-abr-rules.html).
## Disabling the ABR behavior
dash.js allows applications to disable the adaptive bitrate behavior for the `audio` and/or `video` media type. For that
reason, simply disable the `autoSwitchBitrate` setting for the respective media type:
```js
player.updateSettings({
streaming: {
abr: {
autoSwitchBitrate: { audio: true, video: false },
}
}
});
```
A detailed example is available [here](https://reference.dashif.org/dash.js/nightly/samples/abr/disable-abr.html).
## Selecting the initial bitrate
In some cases the application might want to define the initial bitrate for either the audio track or the video track
prior to
the start of the playback.
For that reason, dash.js exposes the `initialBitrate` setting. The target value is specified in kbps. In the example
below
the initial bitrate for video is set to 800 kbit/s.
```js
player.updateSettings({
streaming: {
abr: {
initialBitrate: { audio: -1, video: 800 }
}
}
});
```
A detailed example is available [here](https://reference.dashif.org/dash.js/nightly/samples/abr/initial-bitrate.html).
## Defining a minium/maximum bitrate
It is also possible to define a minimum and/or a maximum bitrate for the ABR algorithms. dash.js will then only adapt
the bitrate
within these thresholds.
In the example below the maximum bitrate for video is set to 5000 kbit/s while the minimum bitrate for video is defined
as 2000 kbit/s.
```js
player.updateSettings({
streaming: {
abr: {
maxBitrate: { audio: -1, video: 5000 },
minBitrate: { audio: -1, video: 2000 },
}
}
});
```
A detailed example is available [here](http://reference.dashif.org/dash.js/nightly/samples/abr/max-min-bitrate.html).
## Fast bitrate switching
When the quality/bitrate for a certain media type is changed dash.js has two options. It can either append the next
fragment at the end of the current buffer or replace existing parts of the buffer with the newly selected quality.
When `fastSwitchEnabled` is set to `true` the next fragment is requested and appended close to the current playback
time. Note: When ABR down-switch is detected, dash.js appends the lower quality at the end of the buffer range to
preserve the
higher quality media for as long as possible.
```js
player.updateSettings({
streaming: {
buffer: {
fastSwitchEnabled: true
}
}
});
```
A detailed example is available [here](https://reference.dashif.org/dash.js/nightly/samples/abr/fastswitch.html).
---
### Site/Pages/Usage/Abr/Switch History Rule
---
title: SwitchHistoryRule
---
# SwitchHistoryRule
## Description
Frequent quality switches result in a negative QoE for the end-user. The main objective of the `SwitchHistoryRule` is to
to detect and avoid any extreme bitrate oscillations allowed by the ABR algorithms. For that reason,
the `SwitchHistoryRule` monitors quality down-switches. It derives a ratio of down-switches divided by the number of
times the quality stayed the same or even improved. If this ratio exceeds the `switchPercentageThreshold` the quality is
reduced.
````js
if (drops + noDrops >= settings.get().streaming.abr.rules.switchHistoryRule.parameters.sampleSize
&& (drops / noDrops > settings.get().streaming.abr.rules.switchHistoryRule.parameters.switchPercentageThreshold)) {
switchRequest.representation = (i > 0 && switchRequests[currentPossibleRepresentation.id].drops > 0) ? representations[i - 1] : currentPossibleRepresentation;
}
````
## Configuration Options
| Parameter | Description |
|:----------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `minimumSampleSize` | Sum of ABR quality checks required before the rule kicks in. |
| `switchPercentageThreshold` | Ratio of quality drops compared to no quality drops must exceed this threshold before a potential quality down-switch by the `SwitchHistoryRule` is enforced. |
## Example
```js
player.updateSettings({
streaming: {
abr: {
rules: {
switchHistoryRule: {
active: true,
parameters: {
minimumSampleSize: 8,
switchPercentageThreshold: 0.075
}
}
}
}
}
});
```
---
### Site/Pages/Usage/Abr/Throughput Calculation
---
title: Throughput Calculation
---
# Throughput Calculation
## Description
dash.js provides multiple options to configure the calculation of the current average throughput. This calculation is an
important input for most of the ABR rules e.g. the [ThroughputRule](throughput-rule.html).
## Configuration Options
The following options are available:
| Throughput Calculation Mode | Description |
|:-------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `EWMA` | Exponential Weighted Moving Average (EWMA) is a calculation mode that assigns exponentially decreasing weights to the historical data points. It gives more importance to recent data while gradually decreasing the influence of older data points. The `settings.abr.throughput.ewma` object allows the configuration of the EWMA parameters. |
| `ZLEMA` | Zero-Lag Exponential Moving Average (ZLEMA) is a calculation mode that aims to reduce or eliminate the lag typically associated with traditional exponential moving averages. It achieves this by using a specific formula that adjusts the weights of the data points to minimize lag |
| `ARITHMETIC_MEAN` | Arithmetic mean, also known as the average, is a statistical measure that calculates the sum of a set of values divided by the number of values in the set. |
| `BYTE_SIZE_WEIGHTED_ARITHMETIC_MEAN` | Byte size weighted arithmetic mean is a calculation method that assigns weights to different values based on their respective byte sizes. To calculate the byte size weighted arithmetic mean, you multiply each value by its corresponding byte size, then sum up the weighted values, and divide the sum by the total byte size. |
| `DATE_WEIGHTED_ARITHMETIC_MEAN` | Date-weighted arithmetic mean is a calculation method that assigns weights to different values based on their respective dates. To calculate the date-weighted arithmetic mean, you multiply each value by its corresponding weight based on the date, then sum up the weighted values, and divide the sum by the total weight. |
| `HARMONIC_MEAN` | To calculate the harmonic mean, you take the total number of values in the set, divide it by the sum of the reciprocals of each value, and then take the reciprocal of that result. As the harmonic mean involves taking the reciprocals of the values, extremely large values have a significant impact on the calculation. |
| `BYTE_SIZE_WEIGHTED_HARMONIC_MEAN` | Similar to the harmonic mean calculation but assigns weights to the different sample values based on their respective byte sizes. |
| `DATE_WEIGHTED_HARMONIC_MEAN` | Similar to the harmonic mean calculation but assigns weights to the different sample values based on their respective dates. The most recent sample has a higher weight than the previous samples. |
The default mode is `EWMA`. Most of the throughput calculation modes work on a fixed number of throughput samples.
The `settings.abr.throughput.sampleSettings` objects allows the configuration of sample related settings.
## Example
In the example below we change the default mode to byte size weighted harmonic mean. In addition, we change the number
of samples to be used to five and disable the automatic adjustment of the sample
size.
A detailed example is
available [here](https://reference.dashif.org/dash.js/nightly/samples/abr/average-calculation-mode.html).
```js
player.updateSettings({
streaming: {
abr: {
throughput: {
averageCalculationMode: dashjs.Constants.THROUGHPUT_CALCULATION_MODES.BYTE_SIZE_WEIGHTED_HARMONIC_MEAN,
sampleSettings: {
vod: 5,
enableSampleSizeAdjustment: false
}
},
}
}
});
```
---
### Site/Pages/Usage/Abr/Throughput Rule
---
title: ThroughputRule
---
# ThroughputRule
## Description
The `ThroughputRule` is a very simple ABR rule that uses the average throughput of the previous media segment downloads
to derive the optimal bitrate for the next media segment request.
The essential lines in the implementation are depicted below:
```js
const throughput = throughputController.getSafeAverageThroughput(mediaType);
switchRequest.representation = abrController.getOptimalRepresentationForBitrate(mediaInfo, throughput, true);
```
## Configuration Options
There are no values that are specifically targeting the rule. However, there are some throughput related parameters that
implicitly influence this rule as it is using `throughputController.getSafeAverageThroughput()`. The throughput related
parameters are documented [here](throughput-calculation.html).
## Example
```js
player.updateSettings({
streaming: {
abr: {
rules: {
throughputRule: {
active: true
}
}
}
}
});
```
---
### Site/Pages/Usage/Subtitles And Captions/Custom Webvtt Rendering
---
title: Custom WebVTT Rendering
---
# Description
Next to the default WebVTT rendering using the native browser APIs, dash.js also provides a way to use the `vtt.js`
library to render WebVTT subtitles. This allows for more customization and control over the rendering process.
# Setup
To enable custom WebVTT rendering we first need to enable the `customRenderingEnabled` flag in the settings:
```js
player.updateSettings({
streaming: {
text: {
webvtt: {
customRenderingEnabled: true
}
}
}
})
```
Next we add add an HTML `
` element as the target container for rendering the subtitles:
```html
```
Now, we can attach the `
` element to the dash.js player:
```js
let vttRenderingDiv = document.querySelector("#vtt-rendering-div");
player.attachVttRenderingDiv(vttRenderingDiv)
```
Finally we need to include the `vtt.js` library in our HTML file. The library is part of the `contrib` folder of
dash.js:
```html
```
# Example
A complete working example can be found in
our [sample section](https://reference.dashif.org/dash.js/nightly/samples/captioning/vttjs.html).
---
### Site/Pages/Usage/Subtitles And Captions/Dvb Font Downloading
---
title: DVB Font Downloading
---
# DVB Font Downloading
dash.js supports the mechanism described in the DVB DASH profile ([ETSI TS 103 285](https://www.etsi.org/deliver/etsi_ts/103200_103299/103285/01.03.01_60/ts_103285v010301p.pdf) Section 7.2 Downloadable Fonts) for signalling downloadable fonts using descriptors within an MPD.
This is intended for use with [EBU-TT-D](https://tech.ebu.ch/publications/tech3380) (compatible with [IMSC1](https://www.w3.org/TR/ttml-imsc1.0.1/) Text Profile) subtitles.
The key details of the mechanism and how to use it are covered here.
## Usage
As a content provider, you may choose to specify fonts within your TTML subtitles that the subtitles should be rendered with.
This could be for accessibility, language, or stylistic reasons.
However this will only work if the specified fonts are available on the device or browser where the dash player is being used, which may not always be under the control of the content provider.
To assist with this, the DVB font download mechanism allows you to [signal font resources for download in an MPD](#signalling-downloadable-fonts), and associate them with specific font family names used within the TTML.
This is achieved by including Supplemental or Essential Property descriptors with the specified scheme in the MPD.
Reference media which signals fonts for download can be found in the [dash.js reference player](http://reference.dashif.org/dash.js/nightly/samples/dash-if-reference-player/).
This functionality is always available and does not need to be enabled through player settings.
If a downloadable font is correctly signalled, the download will be attempted.
## Signalling Downloadable Fonts
Downloadable fonts are signalled in an MPD by using a `` descriptor, or a `` descriptor, within an ``.
The descriptor used must have a `schemeIdUri` attribute set to `"urn:dvb:dash:fontdownload:2014"` and a `value` attribute set to `"1"`.
### DVB Attributes
Additional attributes are required on the descriptors to signal information about the downloadable font.
These attributes are defined in the DVB namespace `urn:dvb:dash-extensions:2014-1`.
Below gives an example of mapping the namespace to a `dvb:` prefix in an MPD.
```xml
```
The table below details the attributes themselves.
| Name | Type | Description |
|:---------------- |:-------|:---------------------------------------------------------------------------------------|
| `dvb:url` | URI | The URL of the font to download. Can be absolute or can make use of relative BaseURLs. |
| `dvb:fontFamily` | String | The font family used in EBU-TT-D documents, within the [`tts:fontFamily`](https://www.w3.org/TR/ttml1/#style-attribute-fontFamily) style attribute. |
| `dvb:mimeType` | String | The mimeType of the font available from the URL. |
### Property Descriptor Example
```xml
```
### Mimetype Support
The DVB DASH specification denotes support for two mimeTypes:
* `application/font-sfnt` - This covers `.ttf` and `.otf` fonts.
* `application/font-woff` - Covering `.woff` fonts.
No further support for unspecified mimeTypes has been provided.
### Supplemental vs Essential Property Descriptors
SupplementalProperty descriptors are used when it is acceptable to show the subtitles in another font if the download fails.
EssentialProperty descriptors are used when the subtitles must not be shown at all if the download fails.
As such the player acts based on what kind of property descriptor was used to describe the downloadable font.
If a `` descriptor was used and download fails, then the `` containing the descriptor continues to be presented as if the `` descriptor was not present.
If an `` descriptor was used and download fails, then the `` containing the descriptor is not be presented at all.
What this looks like on a client is [described in a later section](#download-process).
## Using the Downloaded Fonts
### TTML Font Family Attribute
The EBU-TT-D subtitles need to indicate that they want to use the downloaded font.
To do this, they must include the font family name within the comma-separated list of fonts in the [`tts:fontFamily`](https://www.w3.org/TR/ttml1/#style-attribute-fontFamily) attribute, and the name must match the value of the `dvb:fontFamily` attribute in the MPD.
So, for example, if we have this attribute in an MPD,
```xml
```
we would need to ensure this is present in the subtitle TTML documents to put the font to use.
```xml
```
Note that fallback fonts can still be specified.
In this case we have "Arial" specified as an expected system font, and "default" which is interpreted by [IMSC1](https://www.w3.org/TR/ttml-imsc1.0.1/) as the default monospace serif font provided by the browser/device in use.
### Download Process
Download of fonts happens alongside other media, as to not impede the start of playback.
If the download is successful then the font is added to the `document` interface.
When the player is reset, or a new source is added, any added fonts are then removed from the `document`.
The download status of a font and the type of property descriptor used to describe the font have an effect on display of the `` it is related to.
Consider a situation where subtitles are set to display on load, and we have the correct entries in our MPD and TTML documents to use our hypothetical 'SubtitleDisplay' font.
The process followed for the different property descriptors is described below.
For a `` descriptor, the displayed subtitles can appear in a 'fall-back' font before 'SubtitleDisplay' has been downloaded, in this case 'Arial'.
This causes, in effect, a flash of unstyled text ([FOUT](https://fonts.google.com/knowledge/glossary/fout)).
The subtitles, handled as a [TextTrack](https://developer.mozilla.org/en-US/docs/Web/API/TextTrack) can retain a [mode property](https://developer.mozilla.org/en-US/docs/Web/API/TextTrack/mode) of `"showing"` throughout the process.
For an `` descriptor, the subtitles will not appear unless the 'SubtitleDisplay' font downloads. Until this has downloaded, the mode property of the TextTrack handling these subtitles is set to `"disabled"`. This is done to best replicate what is expected by the DVB DASH specification, and also given there is no method to delete a TextTrack from a TextTrackList if the tracks are not linked to DOM elements. Once 'SubtitleDisplay' has downloaded the text track mode can be set to `"showing"`.
---
### Site/Pages/Usage/Subtitles And Captions/Index
---
title: Subtitles & Captions
---
# Subtitles & Captions
dash.js has support for multiple subtitling and captioning formats including VTT captions, embedded CEA 608/708
captions, and TTML EBU timed text tracks.
Additionally, dash.js has a mechanism for consuming subtitle events so subtitles can be rendered separately, outside of
dash.js.
Multiple samples demonstrating subtitle handling in dash.js can be found in
our [sample section](https://reference.dashif.org/dash.js/nightly/samples/index.html#SubtitlesandCaptions). For more
detailed usage instructions check the links below:
---
### Site/Pages/Usage/Subtitles And Captions/Subtitle Handling
---
title: Basic Subtitle Handling
---
# Basic Subtitle Handling
Many examples can be found in
our [samples section](https://reference.dashif.org/dash.js/latest/samples/index.html#SubtitlesandCaptions).
## Enabling / Disabling by default
Subtitles can be enabled and disabled by default by changing the `defaultEnabled` property:
````js
player.updateSettings({
streaming: {
text: {
defaultEnabled: true
}
}
});
````
## Initial track selection
The initial language or role can be set using the `setInitialMediaSettingsFor` method. Please refer to
the [track selection](../track-selection.html#initial-track-selection) documentation for details.
A working sample can be
found [here](https://reference.dashif.org/dash.js/nightly/samples/captioning/multi-track-captions.html).
## Track selection at runtime
To select a specific text track during playback use the `setTextTrack` method. You need to provide a valid index of a
track. To disable the texttrack rendering pass `-1` to the `setTextTrack` method.
```` js
var textTrackList = {};
var streamId = null;
var _onTracksAdded = function (e) {
if (!textTrackList[e.streamId]) {
textTrackList[e.streamId] = [];
}
streamId = e.streamId;
textTrackList[e.streamId] = textTrackList[e.streamId].concat(e.tracks);
};
player.on(dashjs.MediaPlayer.events.TEXT_TRACKS_ADDED, _onTracksAdded, this);
var item = textTrackList[streamId][0];
player.setTextTrack(item.index);
````
Another way to change the texttrack is to use the `setCurrentTrack` method. For details refer to
the [track selection](../track-selection.html#track-selection-at-runtime) documentation.
---
### Site/Pages/Usage/Buffer Management
---
title: Buffer Management
---
# Buffer Management
dash.js offers a variety of settings to manage the buffer. The buffer is used to store media segments that have been
downloaded but not yet played. The buffer is managed by the player and can be adjusted to meet specific requirements.
The dash.js settings allow the configuration of the initial, backward and forward buffer.
## Configuration Options
The buffer can be configured using the following settings:
| Setting | Description |
|:-----------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `initialBufferLevel` | Initial buffer level to be reached before playback is automatically started. Not that this setting only applies at playback start and is not taken into account after a seek or when the buffer ran dry. |
| `bufferToKeep` | Defines how much backward buffer to keep. The backward buffer is the buffer behind the current play position. |
| `bufferTimeDefault` | The time that the forward buffer target will be set to when not playing at the top quality. |
| `bufferTimeAtTopQuality` | The time that the forward buffer target will be set to if playing the top quality. If there are multiple bitrates available, and the media is playing at the highest bitrate, then dash.js tries to build a larger buffer at the top quality to increase stability and to maintain media quality. |
| `bufferTimeAtTopQualityLongForm` | The time that the forward buffer target will be set to if playing the top quality for long form content. |
| `longFormContentDurationThreshold` | The threshold which defines if the media is considered long form content. This will directly affect the buffer targets when playing back at the top quality. |
> Note: For a full list of all buffer related options including enabling and disabling specific features of the Media
> Source Extensions (MSE) buffer
> objects please refer to our [API documentation](https://cdn.dashjs.org/latest/jsdoc/module-Settings.html#~Buffer).
## Examples
In the example below we change the default buffer settings to reduce the forward and backward buffer.
````js
player.updateSettings({
streaming: {
buffer: {
bufferTimeAtTopQuality: 20,
bufferTimeAtTopQualityLongForm: 30,
bufferTimeDefault: 10,
longFormContentDurationThreshold: 300,
}
}
});
````
More detailed examples are
available in the [buffer section](https://reference.dashif.org/dash.js/nightly/samples/index.html#Buffer) of the dash.js
sample page.
---
### Site/Pages/Usage/Clock Sync
---
title: Clock Synchronization
---
# Clock synchronization
During playback of dynamic presentations, a wall clock is used as the timing reference for DASH client decisions. This
is a synchronized clock shared by the DASH client and service.
It is critical to synchronize the clocks of the DASH client and service when using a dynamic presentation because the
MPD timeline of a dynamic presentation is mapped to wall clock time and many playback decisions are clock driven and
assume a common understanding of time by the DASH client and service.
Clock synchronization mechanisms are described by UTCTiming elements in the MPD ([DASH] 5.8.4.11). For further
information please check the References [1] and [2].
## Clock synchronization in dash.js
dash.js supports multiple schemeIdUri and value combinations for clock synchronization:
* `urn:mpeg:dash:utc:http-head:2014`
* `urn:mpeg:dash:utc:http-xsdate:2014`
* `urn:mpeg:dash:utc:http-iso:2014`
* `urn:mpeg:dash:utc:direct:2014`
* `urn:mpeg:dash:utc:http-head:2012`
* `urn:mpeg:dash:utc:http-xsdate:2012`
* `urn:mpeg:dash:utc:http-iso:2012`
* `urn:mpeg:dash:utc:direct:2012`
The default timing source in dash.js uses the following `schemeIdUri` / `value` combination and can be configured as
follows:
```js
player.updateSettings({
streaming: {
utcSynchronization: {
defaultTimingSource: {
scheme: 'urn:mpeg:dash:utc:http-xsdate:2014',
value: 'https://time.akamai.com/?iso&ms'
}
}
}
});
```
`UTCTiming` elements in the MPD take precedence over the default timing source specified in the settings.
### Regular synchronization
By default, dash.js performs a clock synchronization at playback start and after each MPD update.
#### Synchronization at startup
At playback start an initial request to the timing server is issued. The offset between the client and the server clock
is calculated as described in the Section [Offset calculation](#offset-calculation).
In addition, dash.js performs a predefined number of background requests to verify the initially calculated offset. The
number of background attempts can be adjusted in the settings:
```js
player.updateSettings({
streaming: {
utcSynchronization: {
backgroundAttempts: 2
}
}
});
```
#### Synchronization after MPD updates
By default, dash.js initiates a synchronization request after each MPD update. This behavior is modified by certain
settings parameters. The general workflow is as follows:
An MPD update triggers an event to attempt a clock synchronization. The `TimeSyncController` handles the event and
checks if a synchronization request is to be made:
```js
function _shouldPerformSynchronization() {
try {
const timeBetweenSyncAttempts = !isNaN(internalTimeBetweenSyncAttempts) ? internalTimeBetweenSyncAttempts : DEFAULT_TIME_BETWEEN_SYNC_ATTEMPTS;
if (!timeOfLastSync || !timeBetweenSyncAttempts || isNaN(timeBetweenSyncAttempts)) {
return true;
}
return ((Date.now() - timeOfLastSync) / 1000) >= timeBetweenSyncAttempts;
} catch (e) {
return true;
}
}
```
`_shouldPerformSynchronization()` compares the current wallclock time against the time of the last sync attempt. If the
difference is larger than `timeBetweenSyncAttempts` a synchronization request is issued. Otherwise, playback continues
without a clock sync.
The initial time between the sync attempts can be configured the following way:
```javascript
player.updateSettings({
streaming: {
utcSynchronization: {
timeBetweenSyncAttempts: 30
}
}
});
```
#### Post-synchronization parameter adjustment
After each regular synchronization attempt, dash.js adjusts its internal `internalTimeBetweenSyncAttempts` parameter
based on certain criteria:
```
/* Detailed source-code truncated for AI context efficiency. */
```
In the first step the player checks if the offset is within certain boundaries:
```javascript
function _isOffsetDriftWithinThreshold(offset) {
try {
if (isNaN(lastOffset)) {
return true;
}
const maxAllowedDrift = settings.get().streaming.utcSynchronization.maximumAllowedDrift && !isNaN(settings.get().streaming.utcSynchronization.maximumAllowedDrift) ? settings.get().streaming.utcSynchronization.maximumAllowedDrift : DEFAULT_MAXIMUM_ALLOWED_DRIFT;
const lowerBound = lastOffset - maxAllowedDrift;
const upperBound = lastOffset + maxAllowedDrift;
return offset >= lowerBound && offset <= upperBound;
} catch (e) {
return true;
}
}
```
Depending on whether the offset is included in the calculated boundaries, `adjustedTimeBetweenSyncAttempts` is derived
by either multiplying or dividing the current `internalTimeBetweenSyncAttempts`
by `timeBetweenSyncAttemptsAdjustmentFactor`. By assigning specific values to `maximumTimeBetweenSyncAttempts`
and `minimumTimeBetweenSyncAttempts` upper and lower bounds for `internalTimeBetweenSyncAttempts` can be set.
The parameters can be adjusted in the settings:
```javascript
player.updateSettings({
streaming: {
utcSynchronization: {
timeBetweenSyncAttempts: 30,
maximumTimeBetweenSyncAttempts: 600,
minimumTimeBetweenSyncAttempts: 2,
timeBetweenSyncAttemptsAdjustmentFactor: 2,
maximumAllowedDrift: 100,
}
}
})
```
### Synchronization after download errors
In addition to regular synchronization attempts, dash.js triggers a background synchronization in case requests to media
segments result in errors (e.g 404 errors). This is to make sure that the client clock is still synchronized and the
request error is not caused by an erroneous offset.
This feature can be enabled/disabled by adjusting the settings:
```javascript
player.updateSettings({
streaming: {
utcSynchronization: {
enableBackgroundSyncAfterSegmentDownloadError: true
}
}
})
```
### Offset calculation
The offset between two consecutive synchronization requests is calculated by accounting for the round trip time:
```javascript
function _calculateOffset(deviceTimeBeforeSync, deviceTimeAfterSync, serverTime) {
const deviceReferenceTime = deviceTimeAfterSync - ((deviceTimeAfterSync - deviceTimeBeforeSync) / 2);
return serverTime - deviceReferenceTime;
}
```
### Configuration example
The available configuration parameters:
| Parameter | Description |
|:------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `enable` | Enable/Disable UTC Time synchronization. |
| `useManifestDateHeaderTimeSource` | Allows you to enable the use of the Date Header, if exposed with CORS, as a timing source for live edge detection. The use of the date header will happen only after the other timing source that take precedence fail or are omitted as described. |
| `backgroundAttempts` | Number of synchronization attempts to perform in the background after an initial synchronization request has been done. This is used to verify that the derived client-server offset is correct. |
| `timeBetweenSyncAttempts` | The time in seconds between two consecutive sync attempts. Note: This value is used as an initial starting value. The internal value of the TimeSyncController is adjusted during playback based on the drift between two consecutive synchronization attempts. |
| `maximumTimeBetweenSyncAttempts` | The maximum time in seconds between two consecutive sync attempts. |
| `minimumTimeBetweenSyncAttempts` | The minimum time in seconds between two consecutive sync attempts |
| `timeBetweenSyncAttemptsAdjustmentFactor` | The factor used to multiply or divide the timeBetweenSyncAttempts parameter after a sync. The maximumAllowedDrift defines whether this value is used as a factor or a dividend. |
| `maximumAllowedDrift` | The maximum allowed drift specified in milliseconds between two consecutive synchronization attempts. |
| `enableBackgroundSyncAfterSegmentDownloadError` | Enables or disables the background sync after the player ran into a segment download error. |
| `defaultTimingSource` | The default timing source to be used. The timing sources in the MPD take precedence over this one. |
An example of a full configuration object looks the following:
```javascript
player.updateSettings({
streaming: {
utcSynchronization: {
enable: true,
useManifestDateHeaderTimeSource: true,
backgroundAttempts: 2,
timeBetweenSyncAttempts: 30,
maximumTimeBetweenSyncAttempts: 600,
minimumTimeBetweenSyncAttempts: 2,
timeBetweenSyncAttemptsAdjustmentFactor: 2,
maximumAllowedDrift: 100,
enableBackgroundSyncAfterSegmentDownloadError: true,
defaultTimingSource: {
scheme: 'urn:mpeg:dash:utc:http-xsdate:2014',
value: 'http://time.akamai.com/?iso&ms'
}
}
}
})
```
## References
* [1] [DASH-IF Implementation Guidelines](https://dashif.org/Guidelines-TimingModel/#clock-sync)
* [2] [DASH-IF IOP Guidelines](https://dash-industry-forum.github.io/docs/DASH-IF-IOP-v4.3.pdf)
---
### Site/Pages/Usage/Cmcd
---
title: Common Media Client Data
---
# Common Media Client Data
[CTA-5004 - Common Media Client Data](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf) (
CMCD) defines data
that is collected by the media player and is sent as a custom HTTP header or query parameter alongside each object
request to a CDN. This enables use cases such as log analysis, quality of service monitoring, prioritization of
requests, cross correlation of performance problems with specific devices and platforms and improved edge caching.
CMCD version 1 is fully supported in dash.js. CMCD version 2 fields are gradually being added to dash.js.
## Configuration Options
dash.js offers various configuration options related to CMCD. The following settings can be configured:
| Setting | Description |
|------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| applyParametersFromMpd | Enable if dash.js should use the CMCD parameters defined in the MPD |
| enabled | Enable or disable the CMCD reporting. |
| sid | GUID identifying the current playback session.Should be defined in UUID format |
| cid | A unique string to identify the current content. If not specified it will be a hash of the MPD URL. |
| rtp | The requested maximum throughput that the client considers sufficient for delivery of the asset. If not specified this value will be dynamically calculated in the CMCDModel based on the current buffer level. |
| rtpSafetyFactor | This value is used as a factor for the rtp value calculation: rtp = minBandwidth * rtpSafetyFactor. If not specified this value defaults to 5. Note that this value is only used when no static rtp value is defined. |
| mode | The method to use to attach cmcd metrics to the requests. 'query' to use query parameters, 'header' to use http headers.If not specified this value defaults to 'query'. |
| enabledKeys | This value is used to specify the desired CMCD parameters. Parameters not included in this list are not reported. |
| includeInRequests | Specifies which HTTP GET requests shall carry parameters. If not specified this value defaults to ['segment', 'mpd]. |
| version | The version of the CMCD to use. If not specified this value defaults to 1. |
For a full documentation of all CMCD related options please refer to
our [API documentation](https://cdn.dashjs.org/latest/jsdoc/module-Settings.html#~CmcdSettings).
Example configuration:
````js
player.updateSettings({
streaming: {
cmcd: {
applyParametersFromMpd: true,
enabled: false,
sid: null,
cid: null,
rtp: null,
rtpSafetyFactor: 5,
mode: 'query',
enabledKeys: ['br', 'd', 'ot', 'tb', 'bl', 'dl', 'mtp', 'nor', 'nrr', 'su', 'bs', 'rtp', 'cid', 'pr', 'sf', 'sid', 'st', 'v'],
includeInRequests: ['segment', 'mpd'],
version: 1
}
},
})
````
## CMCD Version 2
CMCD version 2 extends version 1 with additional keys and new reporting modes. dash.js supports CMCD v2 based on
the [Common Media Library](https://github.com/streaming-video-technology-alliance/common-media-library). To enable it,
set `version: 2` in the CMCD settings.
### Additional keys
Among others, the following v2 keys are reported by dash.js:
| Key | Description |
|-------|------------------------------------------------------------------------------|
| `ltc` | Live latency: the delay between the live edge and the current playback position |
| `msd` | Media start delay: time from the playback request until the first frame is rendered |
| `sta` | Player state (e.g. playing, paused, seeking) |
| `e` | Event that triggered an event mode report |
### Reporting modes
In addition to the v1 request mode (CMCD data attached to segment and MPD requests as query parameters or HTTP
headers), version 2 introduces dedicated reporting targets. dash.js supports these via the `eventTargets` setting:
- **Response mode**: reports are sent to a reporting endpoint after a response was received (`rr` event).
- **Event mode**: reports are triggered by player events such as play state changes (`ps`) or errors, or periodically
via a time interval (`t`).
- **Batching**: reports can be collected and sent in batches using the `batchSize` attribute.
Each target is configured individually:
````js
player.updateSettings({
streaming: {
cmcd: {
enabled: true,
version: 2,
eventTargets: [
{
enabled: true,
url: 'https://example.com/cmcd/response-mode',
events: ['rr'],
includeInRequests: ['segment']
},
{
enabled: true,
url: 'https://example.com/cmcd/event-mode',
events: ['ps'],
interval: 10,
enabledKeys: ['e', 'msd', 'sta']
}
]
}
},
})
````
## Example
An example illustrating CMCD reporting can be found in our
dash.js [sample section](https://reference.dashif.org/dash.js/latest/samples/advanced/cmcd.html). A dedicated CMCD v2
example including response and event mode reporting is available in
the [CMCD v2 sample](https://reference.dashif.org/dash.js/nightly/samples/cmcd/cmcd-v2.html).
---
### Site/Pages/Usage/Cmsd
---
title: Common Media Server Data
---
# Common Media Server Data
[CTA-5006 - Common Media Server Data](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5006-final.pdf) (
CMSD) defines a structure for data transmitted in the response to a request from a media player
for an HTTP adaptive streaming media object. The response usually originates at an origin server
and is then propagated through a series of intermediaries to the player.
The purpose of the Common Media Server Data (CMSD) specification is to define a standard
means by which every media server (intermediate and origin) can communicate data with each
media object response and have it received and processed consistently by every intermediary
and player, for the purpose of improving the efficiency and performance of distribution and
ultimately the quality of experience enjoyed by the users.
dash.js currently supports two CMSD keys, namely `etp` (estimated throughput) and `mb` (maximum suggested bitrate).
## Configuration Options
dash.js offers configuration options related to CMSD. The following settings can be configured:
| Setting | Description |
|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `enabled` | Enable or disable the CMSD response headers parsing. |
| `abr.applyMb` | Set to true if dash.js should apply the maximum suggested bitrate derived from the CMSD `mb` key in its ABR logic. |
| `abr.etpWeightRatio` | Sets the weight ratio (between 0 and 1) that shall be applied on the value of the CMSD `etp` key compared to the measured throughput on client side. For instance, setting this value to 0.5 will result in an equal 50% weight on the throughput value provided by the server via CMSD and 50% weight on the throughput value calculated by dash.js on the client-side. |
For a full documentation of all CMSD related options please refer to
our [API documentation](https://cdn.dashjs.org/latest/jsdoc/module-Settings.html#~CmsdSettings).
### Example configuration:
````js
player.updateSettings({
streaming: {
cmsd: {
enabled: true,
abr: {
applyMb: true,
etpWeightRatio: 0.5
}
},
},
})
````
---
### Site/Pages/Usage/Content Steering
---
title: Content Steering
---
# Content Steering
Content steering describes a deterministic capability for a content distributor to switch the content source that a
player uses either at start-up
or midstream by means of a remote steering service.
It adds new `` element to the MPD and the `` elements will contain a `serviceLocation`
attribute that can be used as an identifier. In addition, a steering server is required to provide the player with the
required steering information.
dash.js applies content steering if the required information are present in the MPD and the steering server is returning a valid steering manifest
## Example
An example of content steering can be found in our [sample section](https://reference.dashif.org/dash.js/nightly/samples/advanced/content-steering.html).
To disable content steering, set the `applyContentSteering` property to `false` in the `streaming` section of the player settings.
````js
player.updateSettings({
streaming: {
applyContentSteering: false
}
});
````
---
### Site/Pages/Usage/Controlbar
---
title: Controlbar
---
# Controlbar
dash.js ships with a self-contained, reusable control bar located in `contrib/controlbar`. It generates its own DOM
structure, so you only need to provide a wrapper element. The control bar implements the various APIs of the player —
play/pause, seeking, volume, live edge, bitrate and track selection — and is used by the
[DASH-IF Reference Player](https://reference.dashif.org/dash.js/nightly/samples/dash-if-reference-player/index.html).
## Example
An example is available as part of the
[sample section](https://reference.dashif.org/dash.js/nightly/samples/getting-started/controlbar.html).
## Prerequisites
- **dash.js** loaded (the global `dashjs` object must be available)
- **Bootstrap Icons** CSS for icon display:
```html
```
## Usage
Include the control bar CSS:
```html
```
Provide a wrapper element in your HTML (must have `position: relative`):
```html
```
Import and initialize the control bar as an ES module after initializing the player:
```js
import { ControlBar } from 'path/to/contrib/controlbar/ControlBar.js';
const player = dashjs.MediaPlayer().create();
const video = document.getElementById('video-element');
player.initialize(video, url, true);
const controlbar = new ControlBar(player, video);
controlbar.init(document.getElementById('video-wrapper'));
controlbar.enable();
```
## API
```js
new ControlBar(player, videoElement)
```
| Parameter | Type | Description |
|:---------------|:--------------------------|:-----------------------------------------------|
| `player` | `dashjs.MediaPlayerClass` | A dash.js MediaPlayer instance |
| `videoElement` | `HTMLVideoElement` | The `