Skip to content

Latest commit

 

History

History
2222 lines (1634 loc) · 92.5 KB

API.md

File metadata and controls

2222 lines (1634 loc) · 92.5 KB

HLS.js v1 API

See API Reference for a complete list of interfaces available in the hls.js package.

Getting started

First step: setup and support

First include https://cdn.jsdelivr.net/npm/hls.js@1 (or /hls.js for unminified) in your web page.

<script src="//cdn.jsdelivr.net/npm/hls.js@1"></script>

Invoke the following static method: Hls.isSupported() to check whether your browser supports MediaSource Extensions with any baseline codecs.

<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
<script>
  if (Hls.isSupported()) {
    console.log('Hello HLS.js!');
  }
</script>

If you want to test for MSE support without testing for baseline codecs, use isMSESupported:

if (
  Hls.isMSESupported() &&
  Hls.getMediaSource().isTypeSupported('video/mp4;codecs="av01.0.01M.08"')
) {
  console.log('Hello AV1 playback! AVC who?');
}

Second step: instantiate Hls object and bind it to <video> element

Let's

  • create a <video> element
  • create a new HLS object
  • bind video element to this HLS object
<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>

<video id="video"></video>
<script>
  if (Hls.isSupported()) {
    var video = document.getElementById('video');

    // If you are using the ESM version of the library (hls.mjs), you
    // should specify the "workerPath" config option here if you want
    // web workers to be used. Note that bundlers (such as webpack)
    // will likely use the ESM version by default.
    var hls = new Hls();

    // bind them together
    hls.attachMedia(video);
    // MEDIA_ATTACHED event is fired by hls object once MediaSource is ready
    hls.on(Hls.Events.MEDIA_ATTACHED, function () {
      console.log('video and hls.js are now bound together !');
    });
  }
</script>

Third step: load a manifest

You need to provide manifest URL as below:

<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>

<video id="video"></video>
<script>
  if (Hls.isSupported()) {
    var video = document.getElementById('video');
    var hls = new Hls();
    hls.on(Hls.Events.MEDIA_ATTACHED, function () {
      console.log('video and hls.js are now bound together !');
    });
    hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
      console.log(
        'manifest loaded, found ' + data.levels.length + ' quality level',
      );
    });
    hls.loadSource('http://my.streamURL.com/playlist.m3u8');
    // bind them together
    hls.attachMedia(video);
  }
</script>

Fourth step: control through <video> element

Video is controlled through HTML <video> element.

HTMLVideoElement control and events could be used seamlessly.

video.play();

Fifth step: error handling

All errors are signalled through a unique single event.

Each error is categorized by an error type, error details, and whether or not is is fatal:

  • Error Types:
    • Hls.ErrorTypes.NETWORK_ERROR for network related errors
    • Hls.ErrorTypes.MEDIA_ERROR for media/video related errors
    • Hls.ErrorTypes.KEY_SYSTEM_ERROR for EME related errors
    • Hls.ErrorTypes.MUX_ERROR for demuxing/remuxing related errors
    • Hls.ErrorTypes.OTHER_ERROR for all other errors
  • Error Details:
  • Error is fatal:
    • false if error is not fatal, hls.js will try to recover.
    • true if error is fatal, all attempts to recover have been performed. See LoadPolicies details on how to configure retries.

Full details are described below

See sample code below to listen to errors:

hls.on(Hls.Events.ERROR, function (event, data) {
  var errorType = data.type;
  var errorDetails = data.details;
  var errorFatal = data.fatal;

  switch (data.details) {
    case Hls.ErrorDetails.FRAG_LOAD_ERROR:
      // ....
      break;
    default:
      break;
  }
});

Fatal Error Recovery

hls.js provides means to 'try to' recover fatal media errors, through these methods:

hls.recoverMediaError()

Should be invoked to recover media error.

Error recovery sample code
hls.on(Hls.Events.ERROR, function (event, data) {
  if (data.fatal) {
    switch (data.type) {
      case Hls.ErrorTypes.MEDIA_ERROR:
        console.log('fatal media error encountered, try to recover');
        hls.recoverMediaError();
        break;
      case Hls.ErrorTypes.NETWORK_ERROR:
        console.error('fatal network error encountered', data);
        // All retries and media options have been exhausted.
        // Immediately trying to restart loading could cause loop loading.
        // Consider modifying loading policies to best fit your asset and network
        // conditions (manifestLoadPolicy, playlistLoadPolicy, fragLoadPolicy).
        break;
      default:
        // cannot recover
        hls.destroy();
        break;
    }
  }
});
hls.swapAudioCodec()

If media error are still raised after calling hls.recoverMediaError(), calling this method, could be useful to workaround audio codec mismatch. the workflow should be:

on First Media Error : call hls.recoverMediaError()

if another Media Error is raised 'quickly' after this first Media Error : first call hls.swapAudioCodec(), then call hls.recoverMediaError().

Final step: destroying, switching between streams

hls.destroy() should be called to free used resources and destroy hls context.

Fine Tuning

Configuration parameters could be provided to hls.js upon instantiation of Hls object.

var config = {
  autoStartLoad: true,
  startPosition: -1,
  debug: false,
  capLevelOnFPSDrop: false,
  capLevelToPlayerSize: false,
  defaultAudioCodec: undefined,
  initialLiveManifestSize: 1,
  maxBufferLength: 30,
  maxMaxBufferLength: 600,
  backBufferLength: Infinity,
  frontBufferFlushThreshold: Infinity,
  maxBufferSize: 60 * 1000 * 1000,
  maxBufferHole: 0.5,
  highBufferWatchdogPeriod: 2,
  nudgeOffset: 0.1,
  nudgeMaxRetry: 3,
  maxFragLookUpTolerance: 0.25,
  liveSyncDurationCount: 3,
  liveMaxLatencyDurationCount: Infinity,
  liveDurationInfinity: false,
  preferManagedMediaSource: false,
  enableWorker: true,
  enableSoftwareAES: true,
  fragLoadPolicy: {
    default: {
      maxTimeToFirstByteMs: 9000,
      maxLoadTimeMs: 100000,
      timeoutRetry: {
        maxNumRetry: 2,
        retryDelayMs: 0,
        maxRetryDelayMs: 0,
      },
      errorRetry: {
        maxNumRetry: 5,
        retryDelayMs: 3000,
        maxRetryDelayMs: 15000,
        backoff: 'linear',
      },
    },
  },
  startLevel: undefined,
  audioPreference: {
    characteristics: 'public.accessibility.describes-video',
  },
  subtitlePreference: {
    lang: 'en-US',
  },
  startFragPrefetch: false,
  testBandwidth: true,
  progressive: false,
  lowLatencyMode: true,
  fpsDroppedMonitoringPeriod: 5000,
  fpsDroppedMonitoringThreshold: 0.2,
  appendErrorMaxRetry: 3,
  loader: customLoader,
  fLoader: customFragmentLoader,
  pLoader: customPlaylistLoader,
  xhrSetup: XMLHttpRequestSetupCallback,
  fetchSetup: FetchSetupCallback,
  abrController: AbrController,
  bufferController: BufferController,
  capLevelController: CapLevelController,
  fpsController: FPSController,
  timelineController: TimelineController,
  enableDateRangeMetadataCues: true,
  enableEmsgMetadataCues: true,
  enableID3MetadataCues: true,
  enableWebVTT: true,
  enableIMSC1: true,
  enableCEA708Captions: true,
  stretchShortVideoTrack: false,
  maxAudioFramesDrift: 1,
  forceKeyFrameOnDiscontinuity: true,
  abrEwmaFastLive: 3.0,
  abrEwmaSlowLive: 9.0,
  abrEwmaFastVoD: 3.0,
  abrEwmaSlowVoD: 9.0,
  abrEwmaDefaultEstimate: 500000,
  abrEwmaDefaultEstimateMax: 5000000,
  abrBandWidthFactor: 0.95,
  abrBandWidthUpFactor: 0.7,
  abrMaxWithRealBitrate: false,
  maxStarvationDelay: 4,
  maxLoadingDelay: 4,
  minAutoBitrate: 0,
  emeEnabled: false,
  licenseXhrSetup: undefined,
  drmSystems: {},
  drmSystemOptions: {},
  requestMediaKeySystemAccessFunc: requestMediaKeySystemAccess,
  cmcd: {
    sessionId: uuid(),
    contentId: hash(contentURL),
    useHeaders: false,
  },
};

var hls = new Hls(config);

Hls.DefaultConfig get/set

This getter/setter allows retrieval and override of the Hls default configuration. This configuration will be applied by default to all instances.

capLevelToPlayerSize

(default: false)

  • if set to true, the adaptive algorithm with limit levels usable in auto-quality by the HTML video element dimensions (width and height). If dimensions between multiple levels are equal, the cap is chosen as the level with the greatest bandwidth. In some devices, the video element dimensions will be multiplied by the device pixel ratio. Use ignoreDevicePixelRatio for a strict level limitation based on the size of the video element.
  • if set to false, levels will not be limited. All available levels could be used in auto-quality mode taking only bandwidth into consideration.

capLevelOnFPSDrop

(default: false)

  • when set to true, if the number of dropped frames over the period config.fpsDroppedMonitoringPeriod exceeds the ratio set by config.fpsDroppedMonitoringThreshold, then the quality level is dropped and capped at this lower level.
  • when set to false, levels will not be limited. All available levels could be used in auto-quality mode taking only bandwidth into consideration.

ignoreDevicePixelRatio

(default: false)

  • when set to true, calculations related to player size will ignore browser devicePixelRatio.
  • when set to false, calculations related to player size will respect browser devicePixelRatio.

debug

(default: false)

Setting config.debug = true; will turn on debug logs on JS console.

A logger object could also be provided for custom logging: config.debug = customLogger;.

autoStartLoad

(default: true)

  • if set to true, start level playlist and first fragments will be loaded automatically, after triggering of Hls.Events.MANIFEST_PARSED event
  • if set to false, an explicit API call (hls.startLoad(startPosition=-1)) will be needed to start quality level/fragment loading.

startPosition

(default -1)

  • if set to -1, playback will start from initialTime=0 for VoD and according to liveSyncDuration/liveSyncDurationCount config params for Live
  • Otherwise, playback will start from predefined value. (unless stated otherwise in autoStartLoad=false mode : in that case startPosition can be overridden using hls.startLoad(startPosition)).

defaultAudioCodec

(default: undefined)

If audio codec is not signaled in variant manifest, or if only a stream manifest is provided, hls.js tries to guess audio codec by parsing audio sampling rate in ADTS header. If sampling rate is less or equal than 22050 Hz, then hls.js assumes it is HE-AAC, otherwise it assumes it is AAC-LC. This could result in bad guess, leading to audio decode error, ending up in media error. It is possible to hint default audiocodec to hls.js by configuring this value as below:

  • mp4a.40.2 (AAC-LC) or
  • mp4a.40.5 (HE-AAC) or
  • undefined (guess based on sampling rate)

initialLiveManifestSize

(default 1)

number of segments needed to start a playback of Live stream. Buffering will begin after N chunks are available in the current playlist. If you want playback to begin liveSyncDurationCount chunks from the live edge at the beginning of a stream, set initialLiveManifestSize to liveSyncDurationCount or higher.

maxBufferLength

(default: 30 seconds)

Maximum buffer length in seconds. If buffer length is/become less than this value, a new fragment will be loaded. This is the guaranteed buffer length hls.js will try to reach, regardless of maxBufferSize.

backBufferLength

(default: Infinity)

The maximum duration of buffered media to keep once it has been played, in seconds. Any video buffered past this duration will be evicted. Infinity means no restriction on back buffer length; 0 keeps the minimum amount. The minimum amount is equal to the target duration of a segment to ensure that current playback is not interrupted. Keep in mind, the browser can and does evict media from the buffer on its own, so with the Infinity setting, hls.js will let the browser do what it needs to do. (Ref: the MSE spec under coded frame eviction).

frontBufferFlushThreshold

(default: Infinity)

The maximum duration of buffered media, in seconds, from the play position to keep before evicting non-contiguous forward ranges. A value of Infinity means no active eviction will take place; This value will always be at least the maxBufferLength.

maxBufferSize

(default: 60 MB)

'Minimum' maximum buffer size in bytes. If buffer size upfront is bigger than this value, no fragment will be loaded.

maxBufferHole

(default: 0.5 seconds)

'Maximum' inter-fragment buffer hole tolerance that hls.js can cope with when searching for the next fragment to load. When switching between quality level, fragments might not be perfectly aligned. This could result in small overlapping or hole in media buffer. This tolerance factor helps cope with this.

maxStarvationDelay

(default 4s)

ABR algorithm will always try to choose a quality level that should avoid rebuffering. In case no quality level with this criteria can be found (lets say for example that buffer length is 1s, but fetching a fragment at lowest quality is predicted to take around 2s ... ie we can forecast around 1s of rebuffering ...) then ABR algorithm will try to find a level that should guarantee less than maxStarvationDelay of buffering.

maxLoadingDelay

(default 4s)

max video loading delay used in automatic start level selection : in that mode ABR controller will ensure that video loading time (ie the time to fetch the first fragment at lowest quality level + the time to fetch the fragment at the appropriate quality level is less than maxLoadingDelay )

lowBufferWatchdogPeriod (deprecated)

lowBufferWatchdogPeriod has been deprecated. Use highBufferWatchdogPeriod instead.

highBufferWatchdogPeriod

(default 3s)

if media element is expected to play and if currentTime has not moved for more than highBufferWatchdogPeriod and if there are more than maxBufferHole seconds buffered upfront, hls.js will jump buffer gaps, or try to nudge playhead to recover playback

nudgeOffset

(default 0.1s)

In case playback continues to stall after first playhead nudging, currentTime will be nudged evenmore following nudgeOffset to try to restore playback. media.currentTime += (nb nudge retry -1)*nudgeOffset

nudgeMaxRetry

(default 3)

Max nb of nudge retries before hls.js raise a fatal BUFFER_STALLED_ERROR

maxFragLookUpTolerance

(default 0.25s)

This tolerance factor is used during fragment lookup. Instead of checking whether buffered.end is located within [start, end] range, frag lookup will be done by checking within [start-maxFragLookUpTolerance, end-maxFragLookUpTolerance] range.

This tolerance factor is used to cope with situations like:

buffered.end = 9.991
frag[0] : [0,10]
frag[1] : [10,20]

buffered.end is within frag[0] range, but as we are close to frag[1], frag[1] should be choosen instead

If maxFragLookUpTolerance = 0.2, this lookup will be adjusted to

frag[0] : [-0.2,9.8]
frag[1] : [9.8,19.8]

This time, buffered.end is within frag[1] range, and frag[1] will be the next fragment to be loaded, as expected.

maxMaxBufferLength

(default 600s)

Maximum buffer length in seconds. Hls.js will never exceed this value, even if maxBufferSize is not reached yet.

hls.js tries to buffer up to a maximum number of bytes (60 MB by default) rather than to buffer up to a maximum nb of seconds. this is to mimic the browser behaviour (the buffer eviction algorithm is starting after the browser detects that video buffer size reaches a limit in bytes)

maxBufferLength is the minimum guaranteed buffer length that hls.js will try to achieve, even if that value exceeds the amount of bytes 60 MB of memory. maxMaxBufferLength acts as a capping value, as if bitrate is really low, you could need more than one hour of buffer to fill 60 MB.

liveSyncDurationCount

(default: 3)

edge of live delay, expressed in multiple of EXT-X-TARGETDURATION. if set to 3, playback will start from fragment N-3, N being the last fragment of the live playlist. decreasing this value is likely to cause playback stalls.

liveMaxLatencyDurationCount

(default: Infinity)

maximum delay allowed from edge of live, expressed in multiple of EXT-X-TARGETDURATION. if set to 10, the player will seek back to liveSyncDurationCount whenever the next fragment to be loaded is older than N-10, N being the last fragment of the live playlist. If set, this value must be stricly superior to liveSyncDurationCount a value too close from liveSyncDurationCount is likely to cause playback stalls.

liveSyncDuration

(default: undefined)

Alternative parameter to liveSyncDurationCount, expressed in seconds vs number of segments. If defined in the configuration object, liveSyncDuration will take precedence over the default liveSyncDurationCount. You can't define this parameter and either liveSyncDurationCount or liveMaxLatencyDurationCount in your configuration object at the same time. A value too low (inferior to ~3 segment durations) is likely to cause playback stalls.

liveMaxLatencyDuration

(default: undefined)

Alternative parameter to liveMaxLatencyDurationCount, expressed in seconds vs number of segments. If defined in the configuration object, liveMaxLatencyDuration will take precedence over the default liveMaxLatencyDurationCount. If set, this value must be stricly superior to liveSyncDuration which must be defined as well. You can't define this parameter and either liveSyncDurationCount or liveMaxLatencyDurationCount in your configuration object at the same time. A value too close from liveSyncDuration is likely to cause playback stalls.

maxLiveSyncPlaybackRate

(default: 1 min: 1 max: 2)

When set to a value greater than 1, the latency-controller will adjust video.playbackRate up to maxLiveSyncPlaybackRate to catch up to target latency in a live stream. hls.targetLatency is based on liveSyncDuration|Count or manifest PART-|HOLD-BACK. Defaults to 1, which disables playback rate adjustment. Set maxLiveSyncPlaybackRate to a value greater than 1 to enable playback rate adjustment at the live edge.

liveDurationInfinity

(default: false)

Override current Media Source duration to Infinity for a live broadcast. Useful, if you are building a player which relies on native UI capabilities in modern browsers. If you want to have a native Live UI in environments like iOS Safari, Safari, Android Google Chrome, etc. set this value to true.

liveBackBufferLength (deprecated)

liveBackBufferLength has been deprecated. Use backBufferLength instead.

preferManagedMediaSource

(default true)

HLS.js uses the Managed Media Source API (ManagedMediaSource global) instead of the MediaSource global by default when present. Setting this to false will only use ManagedMediaSource when MediaSource is undefined.

enableWorker

(default: true)

Enable WebWorker (if available on browser) for TS demuxing/MP4 remuxing, to improve performance and avoid lag/frame drops.

workerPath

(default: null)

Provide a path to hls.worker.js as an alternative to injecting the worker based on the iife library wrapper function. When workerPath is defined as a string, the transmuxer interface will initialize a WebWorker using the resolved workerPath URL.

When using the ESM version of the library (hls.mjs), this option is required in order for web workers to be used.

enableSoftwareAES

(default: true)

Enable to use JavaScript version AES decryption for fallback of WebCrypto API.

startLevel

(default: undefined)

When set, use this level as the default hls.startLevel. Keep in mind that the startLevel set with the API takes precedence over config.startLevel configuration parameter. startLevel should be set to value between 0 and the maximum index of hls.levels.

fragLoadingTimeOut / manifestLoadingTimeOut / levelLoadingTimeOut (deprecated)

(default: 20000ms for fragment / 10000ms for level and manifest)

x-LoadingTimeOut settings have been deprecated. Use one of the LoadPolicy settings instead.

fragLoadingMaxRetry / manifestLoadingMaxRetry / levelLoadingMaxRetry (deprecated)

(default: 6 / 1 / 4)

x-LoadingMaxRetry settings have been deprecated. Use one of the LoadPolicy settings instead.

fragLoadingMaxRetryTimeout / manifestLoadingMaxRetryTimeout / levelLoadingMaxRetryTimeout (deprecated)

(default: 64000 ms)

x-LoadingMaxRetryTimeout settings have been deprecated. Use one of the LoadPolicy settings instead.

Maximum frag/manifest/key retry timeout (in milliseconds). This value is used as capping value for exponential grow of loading retry delays, i.e. the retry delay can not be bigger than this value, but overall time will be based on the overall number of retries.

fragLoadingRetryDelay / manifestLoadingRetryDelay / levelLoadingRetryDelay (deprecated)

(default: 1000 ms)

x-LoadingRetryDelay settings have been deprecated. Use one of the LoadPolicy settings instead.

Initial delay between XMLHttpRequest error and first load retry (in ms). Any I/O error will trigger retries every 500ms,1s,2s,4s,8s, ... capped to fragLoadingMaxRetryTimeout / manifestLoadingMaxRetryTimeout / levelLoadingMaxRetryTimeout value (exponential backoff).

fragLoadPolicy / keyLoadPolicy / certLoadPolicy / playlistLoadPolicy / manifestLoadPolicy / steeringManifestLoadPolicy

LoadPolicies specify the default settings for request timeouts and the timing and number of retries after a request error or timeout for a particular type of asset.

  • manifestLoadPolicy: The LoadPolicy for Multivariant Playlist requests
  • playlistLoadPolicy: The LoadPolicy for Media Playlist requests
  • fragLoadPolicy: The LoadPolicy for Segment and Part* requests
  • keyLoadPolicy: The LoadPolicy for Key requests
  • certLoadPolicy: The LoadPolicy for License Server certificate requests
  • steeringManifestLoadPolicy: The LoadPolicy for Content Steering manifest requests

*Some timeout settings are adjusted for Low-Latency Part requests based on Part duration or target.

Each LoadPolicy contains a set of contexts. The default property is the only context supported at this time. It contains the LoaderConfig for that asset type. Future releases may include support for other policy contexts besides default.

HLS.js config defines the following default policies. Each can be overridden on player instantiation in the user configuration:

manifestLoadPolicy: {
  default: {
    maxTimeToFirstByteMs: Infinity,
    maxLoadTimeMs: 20000,
    timeoutRetry: {
      maxNumRetry: 2,
      retryDelayMs: 0,
      maxRetryDelayMs: 0,
    },
    errorRetry: {
      maxNumRetry: 1,
      retryDelayMs: 1000,
      maxRetryDelayMs: 8000,
    },
  },
},
playlistLoadPolicy: {
  default: {
    maxTimeToFirstByteMs: 10000,
    maxLoadTimeMs: 20000,
    timeoutRetry: {
      maxNumRetry: 2,
      retryDelayMs: 0,
      maxRetryDelayMs: 0,
    },
    errorRetry: {
      maxNumRetry: 2,
      retryDelayMs: 1000,
      maxRetryDelayMs: 8000,
    },
  },
},
fragLoadPolicy: {
  default: {
    maxTimeToFirstByteMs: 10000,
    maxLoadTimeMs: 120000,
    timeoutRetry: {
      maxNumRetry: 4,
      retryDelayMs: 0,
      maxRetryDelayMs: 0,
    },
    errorRetry: {
      maxNumRetry: 6,
      retryDelayMs: 1000,
      maxRetryDelayMs: 8000,
    },
  },
},
keyLoadPolicy: {
  default: {
    maxTimeToFirstByteMs: 8000,
    maxLoadTimeMs: 20000,
    timeoutRetry: {
      maxNumRetry: 1,
      retryDelayMs: 1000,
      maxRetryDelayMs: 20000,
      backoff: 'linear',
    },
    errorRetry: {
      maxNumRetry: 8,
      retryDelayMs: 1000,
      maxRetryDelayMs: 20000,
      backoff: 'linear',
    },
  },
},
certLoadPolicy: {
  default: {
    maxTimeToFirstByteMs: 8000,
    maxLoadTimeMs: 20000,
    timeoutRetry: null,
    errorRetry: null,
  },
},
steeringManifestLoadPolicy: {
  default: {
    maxTimeToFirstByteMs: 10000,
    maxLoadTimeMs: 20000,
    timeoutRetry: {
      maxNumRetry: 2,
      retryDelayMs: 0,
      maxRetryDelayMs: 0,
    },
    errorRetry: {
      maxNumRetry: 1,
      retryDelayMs: 1000,
      maxRetryDelayMs: 8000,
    },
  }
}

LoaderConfig

Each LoaderConfig has the following properties:

maxTimeToFirstByteMs: number

Maximum time-to-first-byte in milliseconds. If no bytes or readyState change happens in this time, a network timeout error will be triggered for the asset.

Non-finite values and 0 will be ignored, resulting in only a single maxLoadTimeMs timeout timer for the entire request.

maxLoadTimeMs: number

Maximum time to load the asset in milliseconds. If the request is not completed in time, a network timeout error will be triggered for the asset.

timeoutRetry: RetryConfig | null

Retry rules for timeout errors. Specifying null results in no retries after a timeout error for the asset type.

errorRetry: RetryConfig | null

Retry rules for network I/O errors. Specifying null results in no retries after a timeout error for the asset type.

RetryConfig

Each RetryConfig has the following properties:

maxNumRetry: number

Maximum number of retries. After an error, the request will be retried this many times before other recovery measures are taken. For example, after having retried a segment or playlist request this number of times*, if it continues to error, the player will try switching to another level or fall back to another Pathway to recover playback.

When no valid recovery options are available, the error will escalate to fatal, and the player will stop loading all media and asset types.

*Requests resulting in a stall may trigger a level switch before all retries are performed.

retryDelayMs: number

The time to wait before performing a retry in milliseconds. Delays are added to prevent the player from overloading servers having trouble responding to requests.

Retry delay = 2^retryCount _ retryDelayMs (exponential) or retryCount _ retryDelayMs (linear)

maxRetryDelayMs: number

Maximum delay between retries in milliseconds. With each retry, the delay is increased up to maxRetryDelayMs.

backoff?: 'exponential' | 'linear'

Used to determine retry backoff duration: Retry delay = 2^retryCount * retryDelayMs (exponential).

shouldRetry

(default: internal shouldRetry function, type: (retryConfig: RetryConfig | null | undefined, retryCount: number, isTimeout: boolean, httpStatus: number | undefined,retry: boolean) => boolean)

Override default shouldRetry check

startFragPrefetch

(default: false)

Start prefetching start fragment although media not attached yet.

testBandwidth

(default: true)

You must also set startLevel = -1 for this to have any impact. Otherwise, hls.js will load the first level in the manifest and start playback from there. If you do set startLevel = -1, a fragment of the lowest level will be downloaded to establish a bandwidth estimate before selecting the first auto-level. Disable this test if you'd like to provide your own estimate or use the default abrEwmaDefaultEstimate.

progressive

(default: false)

Enable streaming segment data with fetch loader (experimental).

lowLatencyMode

(default: true)

Enable Low-Latency HLS part playlist and segment loading, and start live streams at playlist PART-HOLD-BACK rather than HOLD-BACK.

fpsDroppedMonitoringPeriod

(default: 5000)

The period used by the default fpsController to observe fpsDroppedMonitoringThreshold.

fpsDroppedMonitoringThreshold

(default: 0.2)

The ratio of frames dropped to frames elapsed within fpsDroppedMonitoringPeriod needed for the default fpsController to emit an FPS_DROP event.

appendErrorMaxRetry

(default: 3)

Max number of sourceBuffer.appendBuffer() retry upon error. Such error could happen in loop with UHD streams, when internal buffer is full. (Quota Exceeding Error will be triggered). In that case we need to wait for the browser to evict some data before being able to append buffer correctly.

loader

(default: standard XMLHttpRequest-based URL loader)

Override standard URL loader by a custom one. Use composition and wrap internal implementation which could be exported by Hls.DefaultConfig.loader. Could be useful for P2P or stubbing (testing).

Use this, if you want to overwrite both the fragment and the playlist loader.

Note: If fLoader or pLoader are used, they overwrite loader!

var customLoader = function () {
  /**
     * Calling load() will start retrieving content located at given URL (HTTP GET).
     *
     * @param {object} context - loader context
     * @param {string} context.url - target URL
     * @param {string} context.responseType - loader response type (arraybuffer or default response type for playlist)
     * @param {number} [context.rangeStart] - start byte range offset
     * @param {number} [context.rangeEnd] - end byte range offset
     * @param {Boolean} [context.progressData] - true if onProgress should report partial chunk of loaded content
     * @param {object} config - loader config params
     * @param {number} config.maxRetry - Max number of load retries
     * @param {number} config.timeout - Timeout after which `onTimeOut` callback will be triggered (if loading is still not finished after that delay)
     * @param {number} config.retryDelay - Delay between an I/O error and following connection retry (ms). This to avoid spamming the server
     * @param {number} config.maxRetryDelay - max connection retry delay (ms)
     * @param {object} callbacks - loader callbacks
     * @param {onSuccessCallback} callbacks.onSuccess - Callback triggered upon successful loading of URL.
     * @param {onProgressCallback} callbacks.onProgress - Callback triggered while loading is in progress.
     * @param {onErrorCallback} callbacks.onError - Callback triggered if any I/O error is met while loading fragment.
     * @param {onTimeoutCallback} callbacks.onTimeout - Callback triggered if loading is still not finished after a certain duration.

      @callback onSuccessCallback
      @param response {object} - response data
      @param response.url {string} - response URL (which might have been redirected)
      @param response.data {string/arraybuffer/sharedarraybuffer} - response data (reponse type should be as per context.responseType)
      @param stats {LoadStats} - loading stats
      @param stats.aborted {boolean} - must be set to true once the request has been aborted
      @param stats.loaded {number} - nb of loaded bytes
      @param stats.total {number} - total nb of bytes
      @param stats.retry {number} - number of retries performed
      @param stats.chunkCount {number} - number of chunk progress events
      @param stats.bwEstimate {number} - download bandwidth in bits/s
      @param stats.loading { start: 0, first: 0, end: 0 }
      @param stats.parsing { start: 0, end: 0 }
      @param stats.buffering { start: 0, first: 0, end: 0 }
      @param context {object} - loader context
      @param networkDetails {object} - loader network details (the xhr for default loaders)

      @callback onProgressCallback
      @param stats {LoadStats} - loading stats
      @param context {object} - loader context
      @param data {string/arraybuffer/sharedarraybuffer} - onProgress data (should be defined only if context.progressData === true)
      @param networkDetails {object} - loader network details (the xhr for default loaders)

      @callback onErrorCallback
      @param error {object} - error data
      @param error.code {number} - error status code
      @param error.text {string} - error description
      @param context {object} - loader context
      @param networkDetails {object} - loader network details (the xhr for default loaders)

      @callback onTimeoutCallback
      @param stats {LoadStats} - loading stats
      @param context {object} - loader context

   */
  this.load = function (context, config, callbacks) {};

  /** Abort any loading in progress. */
  this.abort = function () {};

  /** Destroy loading context. */
  this.destroy = function () {};
};

fLoader

(default: undefined)

This enables the manipulation of the fragment loader. Note: This will overwrite the default loader, as well as your own loader function (see above).

var customFragmentLoader = function () {
  // See `loader` for details.
};

pLoader

(default: undefined)

This enables the manipulation of the playlist loader. Note: This will overwrite the default loader, as well as your own loader function (see above).

var customPlaylistLoader = function () {
  // See `loader` for details.
};

if you want to just make slight adjustments to existing loader implementation, you can also eventually override it, see an example below :

// special playlist post processing function
function process(playlist) {
  return playlist;
}

class pLoader extends Hls.DefaultConfig.loader {
  constructor(config) {
    super(config);
    var load = this.load.bind(this);
    this.load = function (context, config, callbacks) {
      if (context.type == 'manifest') {
        var onSuccess = callbacks.onSuccess;
        callbacks.onSuccess = function (response, stats, context) {
          response.data = process(response.data);
          onSuccess(response, stats, context);
        };
      }
      load(context, config, callbacks);
    };
  }
}

var hls = new Hls({
  pLoader: pLoader,
});

xhrSetup

(default: undefined)

XMLHttpRequest customization callback for default XHR based loader.

xhrSetup should be a function with two arguments (xhr: XMLHttpRequest, url: string). If xhrSetup is specified, the default loader will invoke it before calling xhr.send(). This allows users to easily modify the XMLHttpRequest instance before sending a request. Optionally, a Promise can be returned to wait before the request is sent.

Note that xhr.open() should be called in xhrSetup if the callback modifies the XMLHttpRequest instance in ways that require it to be opened first. If xhrSetup throws, the error will be caught, and xhrSetup will be called a second time after opening a GET request.

var config = {
  xhrSetup: function (xhr, url) {
    xhr.withCredentials = true; // do send cookies
  },
};

fetchSetup

(default: undefined)

Fetch customization callback for Fetch based loader.

Parameter should be a function with two arguments (context and Request Init Params). If fetchSetup is specified and Fetch loader is used, fetchSetup will be triggered to instantiate Request Object. This allows user to easily tweak Fetch loader. See example below.

var config = {
  fetchSetup: function (context, initParams) {
    // Always send cookies, even for cross-origin calls.
    initParams.credentials = 'include';
    return new Request(context.url, initParams);
  },
};

videoPreference

(default undefined)

These settings determine whether HDR video should be selected before SDR video. Which VIDEO-RANGE values are allowed, and in what order of priority can also be specified.

Format { preferHDR: boolean, allowedVideoRanges: ('SDR' | 'PQ' | 'HLG')[] }

  • Allow all video ranges if allowedVideoRanges is unspecified.
  • If preferHDR is defined, use the value to filter allowedVideoRanges.
  • Else check window for HDR support and set preferHDR to the result.

When preferHDR is set, skip checking if the window supports HDR and instead use the value provided to determine level selection preference via dynamic range. A value of preferHDR === true will attempt to use HDR levels before selecting from SDR levels.

allowedVideoRanges can restrict playback to a limited set of VIDEO-RANGE transfer functions and set their priority for selection. For example, to ignore all HDR variants, set allowedVideoRanges to ['SDR']. Or, to ignore all HLG variants, set allowedVideoRanges to ['SDR', 'PQ']. To prioritize PQ variants over HLG, set allowedVideoRanges to ['SDR', 'HLG', 'PQ'].

audioPreference

(default: undefined)

Set a preference used to find and select the best matching audio track on start. The selection can influence starting level selection based on the audio group(s) available to match the preference. audioPreference accepts a value of an audio track object (MediaPlaylist), AudioSelectionOption (track fields to match), or undefined. If not set or set to a value of undefined, HLS.js will auto select a default track on start.

subtitlePreference

(default: undefined)

Set a preference used to find and select the best matching subtitle track on start. subtitlePreference accepts a value of a subtitle track object (MediaPlaylist), SubtitleSelectionOption (track fields to match), or undefined. If not set or set to a value of undefined, HLS.js will not enable subtitles unless there is a default or forced option.

abrController

(default: internal ABR controller)

Customized Adaptive Bitrate Streaming Controller.

Parameter should be a class providing a getter/setter and a destroy() method:

  • get/set nextAutoLevel: return next auto-quality level/force next auto-quality level that should be returned (currently used for emergency switch down)
  • destroy(): should clean-up all used resources

For hls.bandwidthEstimate() to return an estimate from your custom controller, it will also need to satisfy abrController.bwEstimator.getEstimate().

bufferController

(default: internal buffer controller)

Customized buffer controller.

A class in charge of managing SourceBuffers.

capLevelController

(default: internal cap level controller)

Customized level capping controller.

A class in charge of setting hls.autoLevelCapping to limit ABR level selection based on player size. Enable the default cap level controller by setting capLevelToPlayerSize to true.

fpsController

(default: internal fps controller)

Customized fps controller.

A class in charge of monitoring frame rate, that emits FPS_DROP events when frames dropped exceeds configured threshold. Enable the default fps controller by setting capLevelOnFPSDrop to true.

timelineController

(default: internal track timeline controller)

Customized text track synchronization controller.

Parameter should be a class with a destroy() method:

  • destroy() : should clean-up all used resources

enableDateRangeMetadataCues

(default: true)

whether or not to add, update, and remove cues from the metadata TextTrack for EXT-X-DATERANGE playlist tags

parameter should be a boolean

enableEmsgMetadataCues

(default: true)

whether or not to add, update, and remove cues from the metadata TextTrack for ID3 Timed Metadata found in CMAF Event Message (emsg) boxes

parameter should be a boolean

enableID3MetadataCues

(default: true)

whether or not to add, update, and remove cues from the metadata TextTrack for ID3 Timed Metadata found in audio and MPEG-TS containers

parameter should be a boolean

enableWebVTT

(default: true)

whether or not to enable WebVTT captions on HLS

parameter should be a boolean

enableIMSC1

(default: true)

whether or not to enable IMSC1 captions on HLS

parameter should be a boolean

enableCEA708Captions

(default: true)

whether or not to enable CEA-708 captions

parameter should be a boolean

captionsTextTrack1Label

(default: English)

Label for the text track generated for CEA-708 captions track 1. This is how it will appear in the browser's native menu for subtitles and captions.

parameter should be a string

captionsTextTrack1LanguageCode

(default: en)

RFC 3066 language code for the text track generated for CEA-708 captions track 1.

parameter should be a string

captionsTextTrack2Label

(default: Spanish)

Label for the text track generated for CEA-708 captions track 2. This is how it will appear in the browser's native menu for subtitles and captions.

parameter should be a string

captionsTextTrack2LanguageCode

(default: es)

RFC 3066 language code for the text track generated for CEA-708 captions track 2.

parameter should be a string

captionsTextTrack3Label

(default: Unknown CC)

Label for the text track generated for CEA-708 captions track 3. This is how it will appear in the browser's native menu for subtitles and captions.

parameter should be a string

captionsTextTrack3LanguageCode

(default: ``)

RFC 3066 language code for the text track generated for CEA-708 captions track 3.

parameter should be a string

captionsTextTrack4Label

(default: Unknown CC)

Label for the text track generated for CEA-708 captions track 4. This is how it will appear in the browser's native menu for subtitles and captions.

parameter should be a string

captionsTextTrack4LanguageCode

(default: ``)

RFC 3066 language code for the text track generated for CEA-708 captions track 4.

parameter should be a string

renderTextTracksNatively

(default: true)

Whether or not render captions natively using the HTMLMediaElement's TextTracks. Disable native captions rendering when you want to handle rending of track and track cues using Hls.Events.NON_NATIVE_TEXT_TRACKS_FOUND and Hls.Events.CUES_PARSED events.

parameter should be a boolean

stretchShortVideoTrack

(default: false)

If a segment's video track is shorter than its audio track by > maxBufferHole, extend the final video frame's duration to match the audio track's duration. This helps playback continue in certain cases that might otherwise get stuck.

parameter should be a boolean

maxAudioFramesDrift

(default: 1)

Browsers are really strict about audio frames timings. They usually play audio frames one after the other, regardless of the timestamps advertised in the fmp4. If audio timestamps are not consistent (consecutive audio frames too close or too far from each other), audio will easily drift. hls.js is restamping audio frames so that the distance between consecutive audio frame remains constant. if the distance is larger than the max allowed drift, hls.js will either

  • drop the next audio frame if distance is too small (if next audio frame timestamp is smaller than expected time stamp - max allowed drift)
  • insert silent frames if distance is too big (next audio frame timestamp is bigger than expected timestamp + max allowed drift)

parameter should be an integer representing the max number of audio frames allowed to drift. keep in mind that one audio frame is 1024 audio samples (if using AAC), at 44.1 kHz, it gives 1024/44100 = 23ms

forceKeyFrameOnDiscontinuity

(default: true)

Whether or not to force having a key frame in the first AVC sample after a discontinuity. If set to true, after a discontinuity, the AVC samples without any key frame will be dropped until finding one that contains a key frame. If set to false, all AVC samples will be kept, which can help avoid holes in the stream. Setting this parameter to false can also generate decoding weirdness when switching level or seeking.

parameter should be a boolean

abrEwmaFastLive

(default: 3.0)

Fast bitrate Exponential moving average half-life, used to compute average bitrate for Live streams. Half of the estimate is based on the last abrEwmaFastLive seconds of sample history. Each of the sample is weighted by the fragment loading duration.

parameter should be a float greater than 0

abrEwmaSlowLive

(default: 9.0)

Slow bitrate Exponential moving average half-life, used to compute average bitrate for Live streams. Half of the estimate is based on the last abrEwmaSlowLive seconds of sample history. Each of the sample is weighted by the fragment loading duration.

parameter should be a float greater than abrEwmaFastLive

abrEwmaFastVoD

(default: 3.0)

Fast bitrate Exponential moving average half-life, used to compute average bitrate for VoD streams. Half of the estimate is based on the last abrEwmaFastVoD seconds of sample history. Each of the sample is weighted by the fragment loading duration.

parameter should be a float greater than 0

abrEwmaSlowVoD

(default: 9.0)

Slow bitrate Exponential moving average half-life, used to compute average bitrate for VoD streams. Half of the estimate is based on the last abrEwmaSlowVoD seconds of sample history. Each of the sample is weighted by the fragment loading duration.

parameter should be a float greater than abrEwmaFastVoD

abrEwmaDefaultEstimate

(default: 500000)

Default bandwidth estimate in bits/s prior to collecting fragment bandwidth samples.

abrEwmaDefaultEstimateMax

(default: 5000000)

Limits value of updated bandwidth estimate taken from first variant found in multivariant playlist on start.

abrBandWidthFactor

(default: 0.95)

Scale factor to be applied against measured bandwidth average, to determine whether we can stay on current or lower quality level. If abrBandWidthFactor * bandwidth average > level.bitrate then ABR can switch to that level providing that it is equal or less than current level.

abrBandWidthUpFactor

(default: 0.7)

Scale factor to be applied against measured bandwidth average, to determine whether we can switch up to a higher quality level. If abrBandWidthUpFactor * bandwidth average > level.bitrate then ABR can switch up to that quality level.

abrMaxWithRealBitrate

(default: false)

max bitrate used in ABR by avg measured bitrate i.e. if bitrate signaled in variant manifest for a given level is 2Mb/s but average bitrate measured on this level is 2.5Mb/s, then if config value is set to true, ABR will use 2.5 Mb/s for this quality level.

minAutoBitrate

(default: 0)

Return the capping/min bandwidth value that could be used by automatic level selection algorithm. Useful when browser or tab of the browser is not in the focus and bandwidth drops

emeEnabled

(default: false)

Set to true to enable DRM key system access and license retrieval.

widevineLicenseUrl (deprecated)

(default: undefined)

widevineLicenseUrl has been deprecated. Use drmSystems['com.widevine.alpha'].licenseUrl instead.

licenseXhrSetup

(default: undefined, type (xhr: XMLHttpRequest, url: string, keyContext: MediaKeySessionContext, licenseChallenge: Uint8Array) => void | Uint8Array | Promise<Uint8Array | void>)

A pre-processor function for modifying license requests. The license request URL, request headers, and payload can all be modified prior to sending the license request, based on operating conditions, the current key-session, and key-system.