dashjs
Version:
A reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.
794 lines (717 loc) • 130 kB
HTML
<!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="https://dashif.org/img/favicon.ico"><link type="text/css" rel="stylesheet" href="jsdoc-custom.css"><title>Source: streaming/MediaPlayer.js</title><!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="light"><div class="sidebar-container"><div class="sidebar" id="sidebar"><a href="/" class="sidebar-title sidebar-title-anchor">Home</a><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-DashAdapter.html">DashAdapter</a></div><div class="sidebar-section-children"><a href="module-DashMetrics.html">DashMetrics</a></div><div class="sidebar-section-children"><a href="module-MediaPlayer.html">MediaPlayer</a></div><div class="sidebar-section-children"><a href="module-OfflineController.html">OfflineController</a></div><div class="sidebar-section-children"><a href="module-ProtectionController.html">ProtectionController</a></div><div class="sidebar-section-children"><a href="module-Settings.html">Settings</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="Errors.html">Errors</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html">MediaPlayerEvents</a></div><div class="sidebar-section-children"><a href="MediaPlayerModel.html">MediaPlayerModel</a></div><div class="sidebar-section-children"><a href="MetricsReportingEvents.html">MetricsReportingEvents</a></div><div class="sidebar-section-children"><a href="MssErrors.html">MssErrors</a></div><div class="sidebar-section-children"><a href="OfflineErrors.html">OfflineErrors</a></div><div class="sidebar-section-children"><a href="OfflineEvents.html">OfflineEvents</a></div><div class="sidebar-section-children"><a href="ProtectionErrors.html">ProtectionErrors</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html">ProtectionEvents</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-events"><div>Events</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:ADAPTATION_SET_REMOVED_NO_CAPABILITIES">ADAPTATION_SET_REMOVED_NO_CAPABILITIES</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:AST_IN_FUTURE">AST_IN_FUTURE</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:BASE_URLS_UPDATED">BASE_URLS_UPDATED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:BUFFER_EMPTY">BUFFER_EMPTY</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:BUFFER_LEVEL_STATE_CHANGED">BUFFER_LEVEL_STATE_CHANGED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:BUFFER_LEVEL_UPDATED">BUFFER_LEVEL_UPDATED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:BUFFER_LOADED">BUFFER_LOADED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:CAN_PLAY">CAN_PLAY</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:CAN_PLAY_THROUGH">CAN_PLAY_THROUGH</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:CAPTION_CONTAINER_RESIZE">CAPTION_CONTAINER_RESIZE</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:CAPTION_RENDERED">CAPTION_RENDERED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:CONFORMANCE_VIOLATION">CONFORMANCE_VIOLATION</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:CONTENT_STEERING_REQUEST_COMPLETED">CONTENT_STEERING_REQUEST_COMPLETED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:CUE_ENTER">CUE_ENTER</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:CUE_ENTER">CUE_ENTER</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:DVB_FONT_DOWNLOAD_ADDED">DVB_FONT_DOWNLOAD_ADDED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:DVB_FONT_DOWNLOAD_COMPLETE">DVB_FONT_DOWNLOAD_COMPLETE</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:DVB_FONT_DOWNLOAD_FAILED">DVB_FONT_DOWNLOAD_FAILED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:DYNAMIC_TO_STATIC">DYNAMIC_TO_STATIC</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:ERROR">ERROR</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:EVENT_MODE_ON_RECEIVE">EVENT_MODE_ON_RECEIVE</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:EVENT_MODE_ON_START">EVENT_MODE_ON_START</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:FRAGMENT_LOADING_ABANDONED">FRAGMENT_LOADING_ABANDONED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:FRAGMENT_LOADING_COMPLETED">FRAGMENT_LOADING_COMPLETED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:FRAGMENT_LOADING_PROGRESS">FRAGMENT_LOADING_PROGRESS</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:FRAGMENT_LOADING_STARTED">FRAGMENT_LOADING_STARTED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:INBAND_PRFT">INBAND_PRFT</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:LOG">LOG</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:MANIFEST_LOADED">MANIFEST_LOADED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:MANIFEST_LOADING_FINISHED">MANIFEST_LOADING_FINISHED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:MANIFEST_LOADING_STARTED">MANIFEST_LOADING_STARTED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:MANIFEST_VALIDITY_CHANGED">MANIFEST_VALIDITY_CHANGED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:METRIC_ADDED">METRIC_ADDED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:METRIC_CHANGED">METRIC_CHANGED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:METRIC_UPDATED">METRIC_UPDATED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:METRICS_CHANGED">METRICS_CHANGED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PERIOD_SWITCH_COMPLETED">PERIOD_SWITCH_COMPLETED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PERIOD_SWITCH_STARTED">PERIOD_SWITCH_STARTED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_ENDED">PLAYBACK_ENDED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_ERROR">PLAYBACK_ERROR</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_LOADED_DATA">PLAYBACK_LOADED_DATA</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_METADATA_LOADED">PLAYBACK_METADATA_LOADED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_NOT_ALLOWED">PLAYBACK_NOT_ALLOWED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_PAUSED">PLAYBACK_PAUSED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_PLAYING">PLAYBACK_PLAYING</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_PROGRESS">PLAYBACK_PROGRESS</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_RATE_CHANGED">PLAYBACK_RATE_CHANGED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_SEEKED">PLAYBACK_SEEKED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_SEEKING">PLAYBACK_SEEKING</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_STALLED">PLAYBACK_STALLED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_STARTED">PLAYBACK_STARTED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_TIME_UPDATED">PLAYBACK_TIME_UPDATED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_VOLUME_CHANGED">PLAYBACK_VOLUME_CHANGED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:PLAYBACK_WAITING">PLAYBACK_WAITING</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:QUALITY_CHANGE_RENDERED">QUALITY_CHANGE_RENDERED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:QUALITY_CHANGE_REQUESTED">QUALITY_CHANGE_REQUESTED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:REPRESENTATION_SWITCH">REPRESENTATION_SWITCH</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:STREAM_ACTIVATED">STREAM_ACTIVATED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:STREAM_DEACTIVATED">STREAM_DEACTIVATED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:STREAM_INITIALIZED">STREAM_INITIALIZED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:STREAM_INITIALIZING">STREAM_INITIALIZING</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:STREAM_TEARDOWN_COMPLETE">STREAM_TEARDOWN_COMPLETE</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:STREAM_UPDATED">STREAM_UPDATED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:TEXT_TRACK_ADDED">TEXT_TRACK_ADDED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:TEXT_TRACKS_ADDED">TEXT_TRACKS_ADDED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:THROUGHPUT_MEASUREMENT_STORED">THROUGHPUT_MEASUREMENT_STORED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:TRACK_CHANGE_RENDERED">TRACK_CHANGE_RENDERED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:TTML_PARSED">TTML_PARSED</a></div><div class="sidebar-section-children"><a href="MediaPlayerEvents.html#event:TTML_TO_PARSE">TTML_TO_PARSE</a></div><div class="sidebar-section-children"><a href="MetricsReportingEvents.html#event:CMCD_DATA_GENERATED">CMCD_DATA_GENERATED</a></div><div class="sidebar-section-children"><a href="OfflineEvents.html#event:OFFLINE_RECORD_FINISHED">OFFLINE_RECORD_FINISHED</a></div><div class="sidebar-section-children"><a href="OfflineEvents.html#event:OFFLINE_RECORD_LOADEDMETADATA">OFFLINE_RECORD_LOADEDMETADATA</a></div><div class="sidebar-section-children"><a href="OfflineEvents.html#event:OFFLINE_RECORD_STARTED">OFFLINE_RECORD_STARTED</a></div><div class="sidebar-section-children"><a href="OfflineEvents.html#event:OFFLINE_RECORD_STOPPED">OFFLINE_RECORD_STOPPED</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:KEY_ADDED">KEY_ADDED</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:KEY_ERROR">KEY_ERROR</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:KEY_MESSAGE">KEY_MESSAGE</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:KEY_SESSION_CLOSED">KEY_SESSION_CLOSED</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:KEY_SESSION_CREATED">KEY_SESSION_CREATED</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:KEY_SESSION_REMOVED">KEY_SESSION_REMOVED</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:KEY_STATUSES_CHANGED">KEY_STATUSES_CHANGED</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:KEY_SYSTEM_ACCESS_COMPLETE">KEY_SYSTEM_ACCESS_COMPLETE</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:KEY_SYSTEM_SELECTED">KEY_SYSTEM_SELECTED</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:LICENSE_REQUEST_COMPLETE">LICENSE_REQUEST_COMPLETE</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:LICENSE_REQUEST_SENDING">LICENSE_REQUEST_SENDING</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:PROTECTION_CREATED">PROTECTION_CREATED</a></div><div class="sidebar-section-children"><a href="ProtectionEvents.html#event:PROTECTION_DESTROYED">PROTECTION_DESTROYED</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#LICENSE_SERVER_MANIFEST_CONFIGURATIONS">LICENSE_SERVER_MANIFEST_CONFIGURATIONS</a></div><div class="sidebar-section-children"><a href="global.html#MediaType">MediaType</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#dark-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">streaming_MediaPlayer.js</h1></header><article><pre class="prettyprint source lang-js"><code>/**
* The copyright in this software is being made available under the BSD License,
* included below. This software may be subject to other third party and contributor
* rights, including patent rights, and no such rights are granted under this license.
*
* Copyright (c) 2013, Dash Industry Forum.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * Neither the name of Dash Industry Forum nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
import cea608parser from '../../externals/cea608-parser';
import Constants from './constants/Constants';
import DashConstants from '../dash/constants/DashConstants';
import MetricsConstants from './constants/MetricsConstants';
import PlaybackController from './controllers/PlaybackController';
import StreamController from './controllers/StreamController';
import GapController from './controllers/GapController';
import CatchupController from './controllers/CatchupController';
import ServiceDescriptionController from '../dash/controllers/ServiceDescriptionController';
import ContentSteeringController from '../dash/controllers/ContentSteeringController';
import MediaController from './controllers/MediaController';
import BaseURLController from './controllers/BaseURLController';
import ManifestLoader from './ManifestLoader';
import ErrorHandler from './utils/ErrorHandler';
import Capabilities from './utils/Capabilities';
import CapabilitiesFilter from './utils/CapabilitiesFilter';
import RequestModifier from './utils/RequestModifier';
import URIFragmentModel from './models/URIFragmentModel';
import ManifestModel from './models/ManifestModel';
import MediaPlayerModel from './models/MediaPlayerModel';
import AbrController from './controllers/AbrController';
import SchemeLoaderFactory from './net/SchemeLoaderFactory';
import VideoModel from './models/VideoModel';
import CmcdModel from './models/CmcdModel';
import CmsdModel from './models/CmsdModel';
import DOMStorage from './utils/DOMStorage';
import Debug from './../core/Debug';
import Errors from './../core/errors/Errors';
import EventBus from './../core/EventBus';
import Events from './../core/events/Events';
import MediaPlayerEvents from './MediaPlayerEvents';
import FactoryMaker from '../core/FactoryMaker';
import Settings from '../core/Settings';
import {getVersionString} from '../core/Version';
//Dash
import SegmentBaseController from '../dash/controllers/SegmentBaseController';
import DashAdapter from '../dash/DashAdapter';
import DashMetrics from '../dash/DashMetrics';
import TimelineConverter from '../dash/utils/TimelineConverter';
import {
HTTPRequest
} from './vo/metrics/HTTPRequest';
import BASE64 from '../../externals/base64';
import ISOBoxer from 'codem-isoboxer';
import DashJSError from './vo/DashJSError';
import {checkParameterType} from './utils/SupervisorTools';
import ManifestUpdater from './ManifestUpdater';
import URLUtils from '../streaming/utils/URLUtils';
import BoxParser from './utils/BoxParser';
import TextController from './text/TextController';
import CustomParametersModel from './models/CustomParametersModel';
/**
* The media types
* @typedef {("video" | "audio" | "text" | "image")} MediaType
*/
/**
* @module MediaPlayer
* @description The MediaPlayer is the primary dash.js Module and a Facade to build your player around.
* It will allow you access to all the important dash.js properties/methods via the public API and all the
* events to build a robust DASH media player.
*/
function MediaPlayer() {
/**
* @constant {string} STREAMING_NOT_INITIALIZED_ERROR error string thrown when a function is called before the dash.js has been fully initialized
* @inner
*/
const STREAMING_NOT_INITIALIZED_ERROR = 'You must first call initialize() and set a source before calling this method';
/**
* @constant {string} PLAYBACK_NOT_INITIALIZED_ERROR error string thrown when a function is called before the dash.js has been fully initialized
* @inner
*/
const PLAYBACK_NOT_INITIALIZED_ERROR = 'You must first call initialize() and set a valid source and view before calling this method';
/**
* @constant {string} ELEMENT_NOT_ATTACHED_ERROR error string thrown when a function is called before the dash.js has received a reference of an HTML5 video element
* @inner
*/
const ELEMENT_NOT_ATTACHED_ERROR = 'You must first call attachView() to set the video element before calling this method';
/**
* @constant {string} SOURCE_NOT_ATTACHED_ERROR error string thrown when a function is called before the dash.js has received a valid source stream.
* @inner
*/
const SOURCE_NOT_ATTACHED_ERROR = 'You must first call attachSource() with a valid source before calling this method';
/**
* @constant {string} MEDIA_PLAYER_NOT_INITIALIZED_ERROR error string thrown when a function is called before the dash.js has been fully initialized.
* @inner
*/
const MEDIA_PLAYER_NOT_INITIALIZED_ERROR = 'MediaPlayer not initialized!';
const context = this.context;
const eventBus = EventBus(context).getInstance();
let settings = Settings(context).getInstance();
const debug = Debug(context).getInstance({ settings: settings });
let instance,
logger,
source,
protectionData,
mediaPlayerInitialized,
streamingInitialized,
playbackInitialized,
autoPlay,
providedStartTime,
abrController,
schemeLoaderFactory,
timelineConverter,
mediaController,
protectionController,
metricsReportingController,
mssHandler,
offlineController,
adapter,
mediaPlayerModel,
customParametersModel,
errHandler,
baseURLController,
capabilities,
capabilitiesFilter,
streamController,
textController,
gapController,
playbackController,
serviceDescriptionController,
contentSteeringController,
catchupController,
dashMetrics,
manifestModel,
cmcdModel,
cmsdModel,
videoModel,
uriFragmentModel,
domStorage,
segmentBaseController;
/*
---------------------------------------------------------------------------
INIT FUNCTIONS
---------------------------------------------------------------------------
*/
function setup() {
logger = debug.getLogger(instance);
mediaPlayerInitialized = false;
playbackInitialized = false;
streamingInitialized = false;
autoPlay = true;
providedStartTime = NaN;
protectionController = null;
offlineController = null;
protectionData = null;
adapter = null;
segmentBaseController = null;
Events.extend(MediaPlayerEvents);
mediaPlayerModel = MediaPlayerModel(context).getInstance();
customParametersModel = CustomParametersModel(context).getInstance();
videoModel = VideoModel(context).getInstance();
uriFragmentModel = URIFragmentModel(context).getInstance();
}
/**
* Configure media player with customs controllers. Helpful for tests
*
* @param {object=} config controllers configuration
* @memberof module:MediaPlayer
* @instance
*/
function setConfig(config) {
if (!config) {
return;
}
if (config.capabilities) {
capabilities = config.capabilities;
}
if (config.capabilitiesFilter) {
capabilitiesFilter = config.capabilitiesFilter;
}
if (config.streamController) {
streamController = config.streamController;
}
if (config.textController) {
textController = config.textController;
}
if (config.gapController) {
gapController = config.gapController;
}
if (config.playbackController) {
playbackController = config.playbackController;
}
if (config.serviceDescriptionController) {
serviceDescriptionController = config.serviceDescriptionController
}
if (config.contentSteeringController) {
contentSteeringController = config.contentSteeringController;
}
if (config.catchupController) {
catchupController = config.catchupController;
}
if (config.mediaPlayerModel) {
mediaPlayerModel = config.mediaPlayerModel;
}
if (config.customParametersModel) {
customParametersModel = config.customParametersModel;
}
if (config.abrController) {
abrController = config.abrController;
}
if (config.schemeLoaderFactory) {
schemeLoaderFactory = config.schemeLoaderFactory;
}
if (config.mediaController) {
mediaController = config.mediaController;
}
if (config.settings) {
settings = config.settings;
}
}
/**
* Upon creating the MediaPlayer you must call initialize before you call anything else.
* There is one exception to this rule. It is crucial to call {@link module:MediaPlayer#extend extend()}
* with all your extensions prior to calling initialize.
*
* ALL arguments are optional and there are individual methods to set each argument later on.
* The args in this method are just for convenience and should only be used for a simple player setup.
*
* @param {HTML5MediaElement=} view - Optional arg to set the video element. {@link module:MediaPlayer#attachView attachView()}
* @param {string=} source - Optional arg to set the media source. {@link module:MediaPlayer#attachSource attachSource()}
* @param {boolean=} autoPlay - Optional arg to set auto play. {@link module:MediaPlayer#setAutoPlay setAutoPlay()}
* @param {number|string} startTime - For VoD content the start time is relative to the start time of the first period.
* For live content
* If the parameter starts from prefix posix: it signifies the absolute time range defined in seconds of Coordinated Universal Time (ITU-R TF.460-6). This is the number of seconds since 01-01-1970 00:00:00 UTC. Fractions of seconds may be optionally specified down to the millisecond level.
* If no posix prefix is used the starttime is relative to MPD@availabilityStartTime
* @see {@link module:MediaPlayer#attachSource attachSource()}
* @see {@link module:MediaPlayer#setAutoPlay setAutoPlay()}
* @memberof module:MediaPlayer
* @instance
*/
function initialize(view, source, autoPlay, startTime = NaN) {
if (!capabilities) {
capabilities = Capabilities(context).getInstance();
capabilities.setConfig({
settings
})
}
if (!errHandler) {
errHandler = ErrorHandler(context).getInstance();
}
if (!capabilities.supportsMediaSource()) {
errHandler.error(new DashJSError(Errors.CAPABILITY_MEDIASOURCE_ERROR_CODE, Errors.CAPABILITY_MEDIASOURCE_ERROR_MESSAGE));
return;
}
if (!mediaPlayerInitialized) {
mediaPlayerInitialized = true;
// init some controllers and models
timelineConverter = TimelineConverter(context).getInstance();
if (!abrController) {
abrController = AbrController(context).getInstance();
abrController.setConfig({
settings: settings
});
}
if (!schemeLoaderFactory) {
schemeLoaderFactory = SchemeLoaderFactory(context).getInstance();
}
if (!playbackController) {
playbackController = PlaybackController(context).getInstance();
}
if (!mediaController) {
mediaController = MediaController(context).getInstance();
}
if (!streamController) {
streamController = StreamController(context).getInstance();
}
if (!gapController) {
gapController = GapController(context).getInstance();
}
if (!catchupController) {
catchupController = CatchupController(context).getInstance();
}
if (!serviceDescriptionController) {
serviceDescriptionController = ServiceDescriptionController(context).getInstance();
}
if (!contentSteeringController) {
contentSteeringController = ContentSteeringController(context).getInstance();
}
if (!capabilitiesFilter) {
capabilitiesFilter = CapabilitiesFilter(context).getInstance();
}
adapter = DashAdapter(context).getInstance();
manifestModel = ManifestModel(context).getInstance();
cmcdModel = CmcdModel(context).getInstance();
cmsdModel = CmsdModel(context).getInstance();
dashMetrics = DashMetrics(context).getInstance({
settings: settings
});
domStorage = DOMStorage(context).getInstance({
settings: settings
});
adapter.setConfig({
constants: Constants,
cea608parser: cea608parser,
errHandler: errHandler,
BASE64: BASE64
});
if (!baseURLController) {
baseURLController = BaseURLController(context).create();
}
baseURLController.setConfig({
adapter,
contentSteeringController
});
serviceDescriptionController.setConfig({
adapter
});
if (!segmentBaseController) {
segmentBaseController = SegmentBaseController(context).getInstance({
dashMetrics: dashMetrics,
mediaPlayerModel: mediaPlayerModel,
errHandler: errHandler,
baseURLController: baseURLController,
events: Events,
eventBus: eventBus,
debug: debug,
boxParser: BoxParser(context).getInstance(),
requestModifier: RequestModifier(context).getInstance(),
errors: Errors
});
}
// configure controllers
mediaController.setConfig({
domStorage,
settings,
customParametersModel
});
mediaPlayerModel.setConfig({
playbackController,
serviceDescriptionController
});
contentSteeringController.setConfig({
adapter,
errHandler,
dashMetrics,
mediaPlayerModel,
manifestModel,
serviceDescriptionController,
eventBus,
requestModifier: RequestModifier(context).getInstance()
})
restoreDefaultUTCTimingSources();
setAutoPlay(autoPlay !== undefined ? autoPlay : true);
// Detect and initialize offline module to support offline contents playback
_detectOffline();
}
if (view) {
attachView(view);
}
if (source) {
attachSource(source, startTime);
}
logger.info('[dash.js ' + getVersion() + '] ' + 'MediaPlayer has been initialized');
}
/**
* Sets the MPD source and the video element to null. You can also reset the MediaPlayer by
* calling attachSource with a new source file.
*
* This call does not destroy the MediaPlayer. To destroy the MediaPlayer and free all of its
* memory, call destroy().
*
* @memberof module:MediaPlayer
* @instance
*/
function reset() {
attachSource(null);
attachView(null);
protectionData = null;
if (protectionController) {
protectionController.reset();
protectionController = null;
}
if (metricsReportingController) {
metricsReportingController.reset();
metricsReportingController = null;
}
if (customParametersModel) {
customParametersModel.reset();
}
settings.reset();
if (offlineController) {
offlineController.reset();
offlineController = null;
}
}
/**
* Completely destroys the media player and frees all memory.
*
* @memberof module:MediaPlayer
* @instance
*/
function destroy() {
reset();
FactoryMaker.deleteSingletonInstances(context);
}
/**
* The ready state of the MediaPlayer based on both the video element and MPD source being defined.
*
* @returns {boolean} The current ready state of the MediaPlayer
* @see {@link module:MediaPlayer#attachView attachView()}
* @see {@link module:MediaPlayer#attachSource attachSource()}
* @memberof module:MediaPlayer
* @instance
*/
function isReady() {
return (!!source && !!videoModel.getElement());
}
/**
* Use the on method to listen for public events found in MediaPlayer.events. {@link MediaPlayerEvents}
*
* @param {string} type - {@link MediaPlayerEvents}
* @param {Function} listener - callback method when the event fires.
* @param {Object} scope - context of the listener so it can be removed properly.
* @param {Object} options - object to define various options such as priority and mode
* @memberof module:MediaPlayer
* @instance
*/
function on(type, listener, scope, options) {
eventBus.on(type, listener, scope, options);
}
/**
* Use the off method to remove listeners for public events found in MediaPlayer.events. {@link MediaPlayerEvents}
*
* @param {string} type - {@link MediaPlayerEvents}
* @param {Function} listener - callback method when the event fires.
* @param {Object} scope - context of the listener so it can be removed properly.
* @memberof module:MediaPlayer
* @instance
*/
function off(type, listener, scope) {
eventBus.off(type, listener, scope);
}
/**
* Current version of Dash.js
* @returns {string} the current dash.js version string.
* @memberof module:MediaPlayer
* @instance
*/
function getVersion() {
return getVersionString();
}
/**
* Use this method to access the dash.js logging class.
*
* @returns {Debug}
* @memberof module:MediaPlayer
* @instance
*/
function getDebug() {
return debug;
}
/*
---------------------------------------------------------------------------
PLAYBACK FUNCTIONS
---------------------------------------------------------------------------
*/
/**
* Causes the player to begin streaming the media as set by the {@link module:MediaPlayer#attachSource attachSource()}
* method in preparation for playing. It specifically does not require a view to be attached with {@link module:MediaPlayer#attachSource attachView()} to begin preloading.
* When a view is attached after preloading, the buffered data is transferred to the attached mediaSource buffers.
*
* @see {@link module:MediaPlayer#attachSource attachSource()}
* @see {@link module:MediaPlayer#attachView attachView()}
* @memberof module:MediaPlayer
* @throws {@link module:MediaPlayer~SOURCE_NOT_ATTACHED_ERROR SOURCE_NOT_ATTACHED_ERROR} if called before attachSource function
* @instance
*/
function preload() {
if (videoModel.getElement() || streamingInitialized) {
return;
}
if (source) {
_initializePlayback(providedStartTime);
} else {
throw SOURCE_NOT_ATTACHED_ERROR;
}
}
/**
* The play method initiates playback of the media defined by the {@link module:MediaPlayer#attachSource attachSource()} method.
* This method will call play on the native Video Element.
*
* @see {@link module:MediaPlayer#attachSource attachSource()}
* @throws {@link module:MediaPlayer~PLAYBACK_NOT_INITIALIZED_ERROR PLAYBACK_NOT_INITIALIZED_ERROR} if called before initializePlayback function
* @memberof module:MediaPlayer
* @instance
*/
function play() {
if (!playbackInitialized) {
throw PLAYBACK_NOT_INITIALIZED_ERROR;
}
if (!autoPlay || (isPaused() && playbackInitialized)) {
playbackController.play(true);
}
}
/**
* This method will call pause on the native Video Element.
*
* @throws {@link module:MediaPlayer~PLAYBACK_NOT_INITIALIZED_ERROR PLAYBACK_NOT_INITIALIZED_ERROR} if called before initializePlayback function
* @memberof module:MediaPlayer
* @instance
*/
function pause() {
if (!playbackInitialized) {
throw PLAYBACK_NOT_INITIALIZED_ERROR;
}
playbackController.pause();
}
/**
* Returns a Boolean that indicates whether the Video Element is paused.
* @return {boolean}
* @throws {@link module:MediaPlayer~PLAYBACK_NOT_INITIALIZED_ERROR PLAYBACK_NOT_INITIALIZED_ERROR} if called before initializePlayback function
* @memberof module:MediaPlayer
* @instance
*/
function isPaused() {
if (!playbackInitialized) {
throw PLAYBACK_NOT_INITIALIZED_ERROR;
}
return playbackController.isPaused();
}
/**
* Sets the currentTime property of the attached video element. If it is a live stream with a
* timeShiftBufferLength, then the DVR window offset will be automatically calculated.
*
* @param {number} value - A relative time, in seconds, based on the return value of the {@link module:MediaPlayer#duration duration()} method is expected.
* For dynamic streams duration() returns DVRWindow.end - DVRWindow.start. Consequently, the value provided to this function should be relative to DVRWindow.start.
* @see {@link module:MediaPlayer#getDVRSeekOffset getDVRSeekOffset()}
* @throws {@link module:MediaPlayer~PLAYBACK_NOT_INITIALIZED_ERROR PLAYBACK_NOT_INITIALIZED_ERROR} if called before initializePlayback function
* @throws {@link Constants#BAD_ARGUMENT_ERROR BAD_ARGUMENT_ERROR} if called with an invalid argument, not number type or is NaN.
* @memberof module:MediaPlayer
* @instance
*/
function seek(value) {
if (!playbackInitialized) {
throw PLAYBACK_NOT_INITIALIZED_ERROR;
}
checkParameterType(value, 'number');
if (isNaN(value)) {
throw Constants.BAD_ARGUMENT_ERROR;
}
if (value < 0) {
value = 0;
}
let s = playbackController.getIsDynamic() ? getDVRSeekOffset(value) : value;
// For VoD limit the seek to the duration of the content
const videoElement = getVideoElement();
if (!playbackController.getIsDynamic() && videoElement.duration) {
s = Math.min(videoElement.duration, s);
}
playbackController.seek(s, false, false, true);
}
/**
* Seeks back to the original live edge (live edge as calculated at playback start). Only applies to live streams, for VoD streams this call will be ignored.
*/
function seekToOriginalLive() {
if (!playbackInitialized || !isDynamic()) {
return;
}
playbackController.seekToOriginalLive();
}
/**
* Returns a Boolean that indicates whether the media is in the process of seeking to a new position.
* @return {boolean}
* @throws {@link module:MediaPlayer~PLAYBACK_NOT_INITIALIZED_ERROR PLAYBACK_NOT_INITIALIZED_ERROR} if called before initializePlayback function
* @memberof module:MediaPlayer
* @instance
*/
function isSeeking() {
if (!playbackInitialized) {
throw PLAYBACK_NOT_INITIALIZED_ERROR;
}
return playbackController.isSeeking();
}
/**
* Returns a Boolean that indicates whether the media is in the process of dynamic.
* @return {boolean}
* @throws {@link module:MediaPlayer~PLAYBACK_NOT_INITIALIZED_ERROR PLAYBACK_NOT_INITIALIZED_ERROR} if called before initializePlayback function
* @memberof module:MediaPlayer
* @instance
*/
function isDynamic() {
if (!playbackInitialized) {
throw PLAYBACK_NOT_INITIALIZED_ERROR;
}
return playbackController.getIsDynamic();
}
/**
* Returns a boolean that indicates whether the player is operating in low latency mode.
* @return {boolean}
* @memberof module:MediaPlayer
* @instance
*/
function getLowLatencyModeEnabled() {
if (!playbackInitialized) {
throw PLAYBACK_NOT_INITIALIZED_ERROR;
}
return playbackController.getLowLatencyModeEnabled();
}
/**
* Use this method to set the native Video Element's playback rate.
* @param {number} value
* @memberof module:MediaPlayer
* @instance
*/
function setPlaybackRate(value) {
getVideoElement().playbackRate = value;
}
/**
* Returns the current playback rate.
* @returns {number}
* @memberof module:MediaPlayer
* @instance
*/
function getPlaybackRate() {
return getVideoElement().playbackRate;
}
/**
* Use this method to set the native Video Element's muted state. Takes a Boolean that determines whether audio is muted. true if the audio is muted and false otherwise.
* @param {boolean} value
* @memberof module:MediaPlayer
* @throws {@link Constants#BAD_ARGUMENT_ERROR BAD_ARGUMENT_ERROR} if called with an invalid argument, not boolean type.
* @instance
*/
function setMute(value) {
checkParameterType(value, 'boolean');
getVideoElement().muted = value;
}
/**
* A Boolean that determines whether audio is muted.
* @returns {boolean}
* @memberof module:MediaPlayer
* @instance
*/
function isMuted() {
return getVideoElement().muted;
}
/**
* A double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest).
* @param {number} value
* @memberof module:MediaPlayer
* @throws {@link Constants#BAD_ARGUMENT_ERROR BAD_ARGUMENT_ERROR} if called with an invalid argument, not number type, or is NaN or not between 0 and 1.
* @instance
*/
function setVolume(value) {
if (typeof value !== 'number' || isNaN(value) || value < 0.0 || value > 1.0) {
throw Constants.BAD_ARGUMENT_ERROR;
}
getVideoElement().volume = value;
}
/**
* Returns the current audio volume, from 0.0 (silent) to 1.0 (loudest).
* @returns {number}
* @memberof module:MediaPlayer
* @instance
*/
function getVolume() {
return getVideoElement().volume;
}
/**
* The length of the buffer for a given media type, in seconds. Valid media
* types are "video", "audio" and "text". If no type is passed
* in, then the minimum of video, audio and text buffer length is
* returned. NaN is returned if an invalid type is requested, the
* presentation does not contain that type, or if no arguments are passed
* and the presentation does not include any adaption sets of valid media
* type.
*
* @param {MediaType} type - 'video', 'audio' or 'text'
* @returns {number} The length of the buffer for the given media type, in
* seconds, or NaN
* @memberof module:MediaPlayer
* @instance
*/
function getBufferLength(type) {
const types = [Constants.VIDEO, Constants.AUDIO, Constants.TEXT];
if (!type) {
const buffer = types.map(
t => getTracksFor(t).length > 0 ? getDashMetrics().getCurrentBufferLevel(t) : Number.MAX_VALUE
).reduce(
(p, c) => Math.min(p, c)
);
return buffer === Number.MAX_VALUE ? NaN : buffer;
} else {
if (types.indexOf(type) !== -1) {
const buffer = getDas