### 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
``` ### Alternative Setup An alternative way to setup the dash.js player on your web page is to use the MediaPlayerFactory. The MediaPlayerFactory will automatically instantiate and initialize the MediaPlayer module on appropriately tagged video elements. Create a video element somewhere in your html and provide the path to your `mpd` file as src. Also ensure that your video element has the `data-dashjs-player` attribute on it. ```html ``` Add dash.all.min.js to the end of the body. ```html ... ``` When it is all done, it should look similar to this: ```html Dash.js Rocks
``` ## ESM You can also import dash.js as an ES module: ```html dash.js Rocks
``` ## NPM dash.js is available on [npm](https://www.npmjs.com/package/dashjs). Install it as a dependency of your project: ```bash npm install dashjs ``` In projects that use a module bundler (Webpack, Vite, Rollup, ...) you can then import dash.js directly. The package resolves to the modern ESM bundle: ```javascript import { MediaPlayer } from 'dashjs'; const url = 'https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd'; const player = MediaPlayer().create(); player.initialize(document.querySelector('video'), url, true); ``` To play Microsoft Smooth Streaming content, additionally import the MSS module via the `dashjs/mss` subpath: ```javascript import { MediaPlayer } from 'dashjs'; import 'dashjs/mss'; ``` ## Typescript and Webpack You can also use dash.js in your Typescript or Webpack based JavaScript project. Multiple examples can be found in the `samples/modules` directory of the dash.js repository. A simple Typescript example is shown below. It also imports the Smooth Streaming module that is not exported by default. ```typescript import * as dashjs from 'dashjs'; import '../node_modules/dashjs/dist/modern/esm/dash.mss.min.js'; let url = "https://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest"; let player = dashjs.MediaPlayer().create(); player.initialize(document.querySelector('#myMainVideoPlayer'), url, true); ``` ---