hls.ts 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536
  1. import { uuid } from '@svta/common-media-library/utils/uuid';
  2. import { EventEmitter } from 'eventemitter3';
  3. import { buildAbsoluteURL } from 'url-toolkit';
  4. import { enableStreamingMode, hlsDefaultConfig, mergeConfig } from './config';
  5. import { FragmentTracker } from './controller/fragment-tracker';
  6. import GapController from './controller/gap-controller';
  7. import ID3TrackController from './controller/id3-track-controller';
  8. import LatencyController from './controller/latency-controller';
  9. import LevelController from './controller/level-controller';
  10. import StreamController from './controller/stream-controller';
  11. import { ErrorDetails, ErrorTypes } from './errors';
  12. import { Events } from './events';
  13. import { isMSESupported, isSupported } from './is-supported';
  14. import KeyLoader from './loader/key-loader';
  15. import PlaylistLoader from './loader/playlist-loader';
  16. import { MetadataSchema } from './types/demuxer';
  17. import { type HdcpLevel, isHdcpLevel, type Level } from './types/level';
  18. import { PlaylistLevelType } from './types/loader';
  19. import { enableLogs, type ILogger } from './utils/logger';
  20. import { getMediaDecodingInfoPromise } from './utils/mediacapabilities-helper';
  21. import { getMediaSource } from './utils/mediasource-helper';
  22. import { getAudioTracksByGroup } from './utils/rendition-helper';
  23. import { version } from './version';
  24. import type { HlsConfig } from './config';
  25. import type AbrController from './controller/abr-controller';
  26. import type AudioStreamController from './controller/audio-stream-controller';
  27. import type AudioTrackController from './controller/audio-track-controller';
  28. import type BasePlaylistController from './controller/base-playlist-controller';
  29. import type { InFlightData, State } from './controller/base-stream-controller';
  30. import type BaseStreamController from './controller/base-stream-controller';
  31. import type BufferController from './controller/buffer-controller';
  32. import type CapLevelController from './controller/cap-level-controller';
  33. import type CMCDController from './controller/cmcd-controller';
  34. import type ContentSteeringController from './controller/content-steering-controller';
  35. import type EMEController from './controller/eme-controller';
  36. import type ErrorController from './controller/error-controller';
  37. import type FPSController from './controller/fps-controller';
  38. import type InterstitialsController from './controller/interstitials-controller';
  39. import type { InterstitialsManager } from './controller/interstitials-controller';
  40. import type { SubtitleStreamController } from './controller/subtitle-stream-controller';
  41. import type SubtitleTrackController from './controller/subtitle-track-controller';
  42. import type Decrypter from './crypt/decrypter';
  43. import type TransmuxerInterface from './demux/transmuxer-interface';
  44. import type { HlsEventEmitter, HlsListeners } from './events';
  45. import type FragmentLoader from './loader/fragment-loader';
  46. import type { LevelDetails } from './loader/level-details';
  47. import type M3U8Parser from './loader/m3u8-parser';
  48. import type TaskLoop from './task-loop';
  49. import type { AttachMediaSourceData } from './types/buffer';
  50. import type {
  51. AbrComponentAPI,
  52. ComponentAPI,
  53. NetworkComponentAPI,
  54. } from './types/component-api';
  55. import type { MediaAttachingData } from './types/events';
  56. import type {
  57. AudioSelectionOption,
  58. MediaPlaylist,
  59. SubtitleSelectionOption,
  60. VideoSelectionOption,
  61. } from './types/media-playlist';
  62. import type { BufferInfo, BufferTimeRange } from './utils/buffer-helper';
  63. import type Cues from './utils/cues';
  64. import type EwmaBandWidthEstimator from './utils/ewma-bandwidth-estimator';
  65. import type FetchLoader from './utils/fetch-loader';
  66. import type { MediaDecodingInfo } from './utils/mediacapabilities-helper';
  67. import type XhrLoader from './utils/xhr-loader';
  68. /**
  69. * The `Hls` class is the core of the HLS.js library used to instantiate player instances.
  70. * @public
  71. */
  72. export default class Hls implements HlsEventEmitter {
  73. private static defaultConfig: HlsConfig | undefined;
  74. /**
  75. * The runtime configuration used by the player. At instantiation this is combination of `hls.userConfig` merged over `Hls.DefaultConfig`.
  76. */
  77. public readonly config: HlsConfig;
  78. /**
  79. * The configuration object provided on player instantiation.
  80. */
  81. public readonly userConfig: Partial<HlsConfig>;
  82. /**
  83. * The logger functions used by this player instance, configured on player instantiation.
  84. */
  85. public readonly logger: ILogger;
  86. private coreComponents: ComponentAPI[];
  87. private networkControllers: NetworkComponentAPI[];
  88. private _emitter: HlsEventEmitter = new EventEmitter();
  89. private _autoLevelCapping: number = -1;
  90. private _maxHdcpLevel: HdcpLevel = null;
  91. private abrController: AbrComponentAPI;
  92. private bufferController: BufferController;
  93. private capLevelController: CapLevelController;
  94. private latencyController: LatencyController;
  95. private levelController: LevelController;
  96. private streamController: StreamController;
  97. private audioStreamController?: AudioStreamController;
  98. private subtititleStreamController?: SubtitleStreamController;
  99. private audioTrackController?: AudioTrackController;
  100. private subtitleTrackController?: SubtitleTrackController;
  101. private interstitialsController?: InterstitialsController;
  102. private gapController: GapController;
  103. private emeController?: EMEController;
  104. private cmcdController?: CMCDController;
  105. private _media: HTMLMediaElement | null = null;
  106. private _url: string | null = null;
  107. private _sessionId?: string;
  108. private triggeringException?: boolean;
  109. private started: boolean = false;
  110. /**
  111. * Get the video-dev/hls.js package version.
  112. */
  113. static get version(): string {
  114. return version;
  115. }
  116. /**
  117. * Check if the required MediaSource Extensions are available.
  118. */
  119. static isMSESupported(): boolean {
  120. return isMSESupported();
  121. }
  122. /**
  123. * Check if MediaSource Extensions are available and isTypeSupported checks pass for any baseline codecs.
  124. */
  125. static isSupported(): boolean {
  126. return isSupported();
  127. }
  128. /**
  129. * Get the MediaSource global used for MSE playback (ManagedMediaSource, MediaSource, or WebKitMediaSource).
  130. */
  131. static getMediaSource(): typeof MediaSource | undefined {
  132. return getMediaSource();
  133. }
  134. static get Events(): typeof Events {
  135. return Events;
  136. }
  137. static get MetadataSchema(): typeof MetadataSchema {
  138. return MetadataSchema;
  139. }
  140. static get ErrorTypes(): typeof ErrorTypes {
  141. return ErrorTypes;
  142. }
  143. static get ErrorDetails(): typeof ErrorDetails {
  144. return ErrorDetails;
  145. }
  146. /**
  147. * Get the default configuration applied to new instances.
  148. */
  149. static get DefaultConfig(): HlsConfig {
  150. if (!Hls.defaultConfig) {
  151. return hlsDefaultConfig;
  152. }
  153. return Hls.defaultConfig;
  154. }
  155. /**
  156. * Replace the default configuration applied to new instances.
  157. */
  158. static set DefaultConfig(defaultConfig: HlsConfig) {
  159. Hls.defaultConfig = defaultConfig;
  160. }
  161. /**
  162. * Creates an instance of an HLS client that can attach to exactly one `HTMLMediaElement`.
  163. * @param userConfig - Configuration options applied over `Hls.DefaultConfig`
  164. */
  165. constructor(userConfig: Partial<HlsConfig> = {}) {
  166. const logger = (this.logger = enableLogs(
  167. userConfig.debug || false,
  168. 'Hls instance',
  169. userConfig.assetPlayerId,
  170. ));
  171. const config = (this.config = mergeConfig(
  172. Hls.DefaultConfig,
  173. userConfig,
  174. logger,
  175. ));
  176. this.userConfig = userConfig;
  177. if (config.progressive) {
  178. enableStreamingMode(config, logger);
  179. }
  180. // core controllers and network loaders
  181. const {
  182. abrController: _AbrController,
  183. bufferController: _BufferController,
  184. capLevelController: _CapLevelController,
  185. errorController: _ErrorController,
  186. fpsController: _FpsController,
  187. } = config;
  188. const errorController = new _ErrorController(this);
  189. const abrController = (this.abrController = new _AbrController(this));
  190. // FragmentTracker must be defined before StreamController because the order of event handling is important
  191. const fragmentTracker = new FragmentTracker(this);
  192. const _InterstitialsController = config.interstitialsController;
  193. const interstitialsController = _InterstitialsController
  194. ? (this.interstitialsController = new _InterstitialsController(this, Hls))
  195. : null;
  196. const bufferController = (this.bufferController = new _BufferController(
  197. this,
  198. fragmentTracker,
  199. ));
  200. const capLevelController = (this.capLevelController =
  201. new _CapLevelController(this));
  202. const fpsController = new _FpsController(this);
  203. const playListLoader = new PlaylistLoader(this);
  204. const _ContentSteeringController = config.contentSteeringController;
  205. // Instantiate ConentSteeringController before LevelController to receive Multivariant Playlist events first
  206. const contentSteering = _ContentSteeringController
  207. ? new _ContentSteeringController(this)
  208. : null;
  209. const levelController = (this.levelController = new LevelController(
  210. this,
  211. contentSteering,
  212. ));
  213. const id3TrackController = new ID3TrackController(this);
  214. const keyLoader = new KeyLoader(this.config);
  215. const streamController = (this.streamController = new StreamController(
  216. this,
  217. fragmentTracker,
  218. keyLoader,
  219. ));
  220. const gapController = (this.gapController = new GapController(
  221. this,
  222. fragmentTracker,
  223. ));
  224. // Cap level controller uses streamController to flush the buffer
  225. capLevelController.setStreamController(streamController);
  226. // fpsController uses streamController to switch when frames are being dropped
  227. fpsController.setStreamController(streamController);
  228. const networkControllers: NetworkComponentAPI[] = [
  229. playListLoader,
  230. levelController,
  231. streamController,
  232. ];
  233. if (interstitialsController) {
  234. networkControllers.splice(1, 0, interstitialsController);
  235. }
  236. if (contentSteering) {
  237. networkControllers.splice(1, 0, contentSteering);
  238. }
  239. this.networkControllers = networkControllers;
  240. const coreComponents: ComponentAPI[] = [
  241. abrController,
  242. bufferController,
  243. gapController,
  244. capLevelController,
  245. fpsController,
  246. id3TrackController,
  247. fragmentTracker,
  248. ];
  249. this.audioTrackController = this.createController(
  250. config.audioTrackController,
  251. networkControllers,
  252. );
  253. const AudioStreamControllerClass = config.audioStreamController;
  254. if (AudioStreamControllerClass) {
  255. networkControllers.push(
  256. (this.audioStreamController = new AudioStreamControllerClass(
  257. this,
  258. fragmentTracker,
  259. keyLoader,
  260. )),
  261. );
  262. }
  263. // Instantiate subtitleTrackController before SubtitleStreamController to receive level events first
  264. this.subtitleTrackController = this.createController(
  265. config.subtitleTrackController,
  266. networkControllers,
  267. );
  268. const SubtitleStreamControllerClass = config.subtitleStreamController;
  269. if (SubtitleStreamControllerClass) {
  270. networkControllers.push(
  271. (this.subtititleStreamController = new SubtitleStreamControllerClass(
  272. this,
  273. fragmentTracker,
  274. keyLoader,
  275. )),
  276. );
  277. }
  278. this.createController(config.timelineController, coreComponents);
  279. keyLoader.emeController = this.emeController = this.createController(
  280. config.emeController,
  281. coreComponents,
  282. );
  283. this.cmcdController = this.createController(
  284. config.cmcdController,
  285. coreComponents,
  286. );
  287. this.latencyController = this.createController(
  288. LatencyController,
  289. coreComponents,
  290. );
  291. this.coreComponents = coreComponents;
  292. // Error controller handles errors before and after all other controllers
  293. // This listener will be invoked after all other controllers error listeners
  294. networkControllers.push(errorController);
  295. const onErrorOut = errorController.onErrorOut;
  296. if (typeof onErrorOut === 'function') {
  297. this.on(Events.ERROR, onErrorOut, errorController);
  298. }
  299. // Autostart load handler
  300. this.on(
  301. Events.MANIFEST_LOADED,
  302. playListLoader.onManifestLoaded,
  303. playListLoader,
  304. );
  305. }
  306. createController(ControllerClass, components) {
  307. if (ControllerClass) {
  308. const controllerInstance = new ControllerClass(this);
  309. if (components) {
  310. components.push(controllerInstance);
  311. }
  312. return controllerInstance;
  313. }
  314. return null;
  315. }
  316. // Delegate the EventEmitter through the public API of Hls.js
  317. on<E extends keyof HlsListeners, Context = undefined>(
  318. event: E,
  319. listener: HlsListeners[E],
  320. context: Context = this as any,
  321. ) {
  322. this._emitter.on(event, listener, context);
  323. }
  324. once<E extends keyof HlsListeners, Context = undefined>(
  325. event: E,
  326. listener: HlsListeners[E],
  327. context: Context = this as any,
  328. ) {
  329. this._emitter.once(event, listener, context);
  330. }
  331. removeAllListeners<E extends keyof HlsListeners>(event?: E | undefined) {
  332. this._emitter.removeAllListeners(event);
  333. }
  334. off<E extends keyof HlsListeners, Context = undefined>(
  335. event: E,
  336. listener?: HlsListeners[E] | undefined,
  337. context: Context = this as any,
  338. once?: boolean | undefined,
  339. ) {
  340. this._emitter.off(event, listener, context, once);
  341. }
  342. listeners<E extends keyof HlsListeners>(event: E): HlsListeners[E][] {
  343. return this._emitter.listeners(event);
  344. }
  345. emit<E extends keyof HlsListeners>(
  346. event: E,
  347. name: E,
  348. eventObject: Parameters<HlsListeners[E]>[1],
  349. ): boolean {
  350. return this._emitter.emit(event, name, eventObject);
  351. }
  352. trigger<E extends keyof HlsListeners>(
  353. event: E,
  354. eventObject: Parameters<HlsListeners[E]>[1],
  355. ): boolean {
  356. if (this.config.debug) {
  357. return this.emit(event, event, eventObject);
  358. } else {
  359. try {
  360. return this.emit(event, event, eventObject);
  361. } catch (error) {
  362. this.logger.error(
  363. 'An internal error happened while handling event ' +
  364. event +
  365. '. Error message: "' +
  366. error.message +
  367. '". Here is a stacktrace:',
  368. error,
  369. );
  370. // Prevent recursion in error event handlers that throw #5497
  371. if (!this.triggeringException) {
  372. this.triggeringException = true;
  373. const fatal = event === Events.ERROR;
  374. this.trigger(Events.ERROR, {
  375. type: ErrorTypes.OTHER_ERROR,
  376. details: ErrorDetails.INTERNAL_EXCEPTION,
  377. fatal,
  378. event,
  379. error,
  380. });
  381. this.triggeringException = false;
  382. }
  383. }
  384. }
  385. return false;
  386. }
  387. listenerCount<E extends keyof HlsListeners>(event: E): number {
  388. return this._emitter.listenerCount(event);
  389. }
  390. /**
  391. * Dispose of the instance
  392. */
  393. destroy() {
  394. this.logger.log('destroy');
  395. this.trigger(Events.DESTROYING, undefined);
  396. this.detachMedia();
  397. this.removeAllListeners();
  398. this._autoLevelCapping = -1;
  399. this._url = null;
  400. this.networkControllers.forEach((component) => component.destroy());
  401. this.networkControllers.length = 0;
  402. this.coreComponents.forEach((component) => component.destroy());
  403. this.coreComponents.length = 0;
  404. // Remove any references that could be held in config options or callbacks
  405. const config = this.config;
  406. config.xhrSetup = config.fetchSetup = undefined;
  407. // @ts-ignore
  408. this.userConfig = null;
  409. }
  410. /**
  411. * Attaches Hls.js to a media element
  412. */
  413. attachMedia(data: HTMLMediaElement | MediaAttachingData) {
  414. if (!data || ('media' in data && !data.media)) {
  415. const error = new Error(`attachMedia failed: invalid argument (${data})`);
  416. this.trigger(Events.ERROR, {
  417. type: ErrorTypes.OTHER_ERROR,
  418. details: ErrorDetails.ATTACH_MEDIA_ERROR,
  419. fatal: true,
  420. error,
  421. });
  422. return;
  423. }
  424. this.logger.log(`attachMedia`);
  425. if (this._media) {
  426. this.logger.warn(`media must be detached before attaching`);
  427. this.detachMedia();
  428. }
  429. const attachMediaSource = 'media' in data;
  430. const media = attachMediaSource ? data.media : data;
  431. const attachingData = attachMediaSource ? data : { media };
  432. this._media = media;
  433. this.trigger(Events.MEDIA_ATTACHING, attachingData);
  434. }
  435. /**
  436. * Detach Hls.js from the media
  437. */
  438. detachMedia() {
  439. this.logger.log('detachMedia');
  440. this.trigger(Events.MEDIA_DETACHING, {});
  441. this._media = null;
  442. }
  443. /**
  444. * Detach HTMLMediaElement, MediaSource, and SourceBuffers without reset, for attaching to another instance
  445. */
  446. transferMedia(): AttachMediaSourceData | null {
  447. this._media = null;
  448. const transferMedia = this.bufferController.transferMedia();
  449. this.trigger(Events.MEDIA_DETACHING, { transferMedia });
  450. return transferMedia;
  451. }
  452. /**
  453. * Set the source URL. Can be relative or absolute.
  454. */
  455. loadSource(url: string) {
  456. this.stopLoad();
  457. const media = this.media;
  458. const loadedSource = this._url;
  459. const loadingSource = (this._url = buildAbsoluteURL(
  460. self.location.href,
  461. url,
  462. {
  463. alwaysNormalize: true,
  464. },
  465. ));
  466. this._autoLevelCapping = -1;
  467. this._maxHdcpLevel = null;
  468. this.logger.log(`loadSource:${loadingSource}`);
  469. if (
  470. media &&
  471. loadedSource &&
  472. (loadedSource !== loadingSource || this.bufferController.hasSourceTypes())
  473. ) {
  474. // Remove and re-create MediaSource
  475. this.detachMedia();
  476. this.attachMedia(media);
  477. }
  478. // when attaching to a source URL, trigger a playlist load
  479. this.trigger(Events.MANIFEST_LOADING, { url: url });
  480. }
  481. /**
  482. * Gets the currently loaded URL
  483. */
  484. public get url(): string | null {
  485. return this._url;
  486. }
  487. /**
  488. * Whether or not enough has been buffered to seek to start position or use `media.currentTime` to determine next load position
  489. */
  490. get hasEnoughToStart(): boolean {
  491. return this.streamController.hasEnoughToStart;
  492. }
  493. /**
  494. * Get the startPosition set on startLoad(position) or on autostart with config.startPosition
  495. */
  496. get startPosition(): number {
  497. return this.streamController.startPositionValue;
  498. }
  499. /**
  500. * Start loading data from the stream source.
  501. * Depending on default config, client starts loading automatically when a source is set.
  502. *
  503. * @param startPosition - Set the start position to stream from.
  504. * Defaults to -1 (None: starts from earliest point)
  505. */
  506. startLoad(startPosition: number = -1, skipSeekToStartPosition?: boolean) {
  507. this.logger.log(
  508. `startLoad(${
  509. startPosition +
  510. (skipSeekToStartPosition ? ', <skip seek to start>' : '')
  511. })`,
  512. );
  513. this.started = true;
  514. this.resumeBuffering();
  515. for (let i = 0; i < this.networkControllers.length; i++) {
  516. this.networkControllers[i].startLoad(
  517. startPosition,
  518. skipSeekToStartPosition,
  519. );
  520. if (!this.started || !this.networkControllers) {
  521. break;
  522. }
  523. }
  524. }
  525. /**
  526. * Stop loading of any stream data.
  527. */
  528. stopLoad() {
  529. this.logger.log('stopLoad');
  530. this.started = false;
  531. for (let i = 0; i < this.networkControllers.length; i++) {
  532. this.networkControllers[i].stopLoad();
  533. if (this.started || !this.networkControllers) {
  534. break;
  535. }
  536. }
  537. }
  538. /**
  539. * Returns whether loading, toggled with `startLoad()` and `stopLoad()`, is active or not`.
  540. */
  541. get loadingEnabled(): boolean {
  542. return this.started;
  543. }
  544. /**
  545. * Returns state of fragment loading toggled by calling `pauseBuffering()` and `resumeBuffering()`.
  546. */
  547. get bufferingEnabled(): boolean {
  548. return this.streamController.bufferingEnabled;
  549. }
  550. /**
  551. * Resumes stream controller segment loading after `pauseBuffering` has been called.
  552. */
  553. resumeBuffering() {
  554. if (!this.bufferingEnabled) {
  555. this.logger.log(`resume buffering`);
  556. this.networkControllers.forEach((controller) => {
  557. if (controller.resumeBuffering) {
  558. controller.resumeBuffering();
  559. }
  560. });
  561. }
  562. }
  563. /**
  564. * Prevents stream controller from loading new segments until `resumeBuffering` is called.
  565. * This allows for media buffering to be paused without interupting playlist loading.
  566. */
  567. pauseBuffering() {
  568. if (this.bufferingEnabled) {
  569. this.logger.log(`pause buffering`);
  570. this.networkControllers.forEach((controller) => {
  571. if (controller.pauseBuffering) {
  572. controller.pauseBuffering();
  573. }
  574. });
  575. }
  576. }
  577. get inFlightFragments(): InFlightFragments {
  578. const inFlightData = {
  579. [PlaylistLevelType.MAIN]: this.streamController.inFlightFrag,
  580. };
  581. if (this.audioStreamController) {
  582. inFlightData[PlaylistLevelType.AUDIO] =
  583. this.audioStreamController.inFlightFrag;
  584. }
  585. if (this.subtititleStreamController) {
  586. inFlightData[PlaylistLevelType.SUBTITLE] =
  587. this.subtititleStreamController.inFlightFrag;
  588. }
  589. return inFlightData;
  590. }
  591. /**
  592. * Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1)
  593. */
  594. swapAudioCodec() {
  595. this.logger.log('swapAudioCodec');
  596. this.streamController.swapAudioCodec();
  597. }
  598. /**
  599. * When the media-element fails, this allows to detach and then re-attach it
  600. * as one call (convenience method).
  601. *
  602. * Automatic recovery of media-errors by this process is configurable.
  603. */
  604. recoverMediaError() {
  605. this.logger.log('recoverMediaError');
  606. const media = this._media;
  607. const time = media?.currentTime;
  608. this.detachMedia();
  609. if (media) {
  610. this.attachMedia(media);
  611. if (time) {
  612. this.startLoad(time);
  613. }
  614. }
  615. }
  616. removeLevel(levelIndex: number) {
  617. this.levelController.removeLevel(levelIndex);
  618. }
  619. /**
  620. * @returns a UUID for this player instance
  621. */
  622. get sessionId(): string {
  623. let _sessionId = this._sessionId;
  624. if (!_sessionId) {
  625. _sessionId = this._sessionId = uuid();
  626. }
  627. return _sessionId;
  628. }
  629. /**
  630. * @returns an array of levels (variants) sorted by HDCP-LEVEL, RESOLUTION (height), FRAME-RATE, CODECS, VIDEO-RANGE, and BANDWIDTH
  631. */
  632. get levels(): Level[] {
  633. const levels = this.levelController.levels;
  634. return levels ? levels : [];
  635. }
  636. /**
  637. * @returns LevelDetails of last loaded level (variant) or `null` prior to loading a media playlist.
  638. */
  639. get latestLevelDetails(): LevelDetails | null {
  640. return this.streamController.getLevelDetails() || null;
  641. }
  642. /**
  643. * @returns Level object of selected level (variant) or `null` prior to selecting a level or once the level is removed.
  644. */
  645. get loadLevelObj(): Level | null {
  646. return this.levelController.loadLevelObj;
  647. }
  648. /**
  649. * Index of quality level (variant) currently played
  650. */
  651. get currentLevel(): number {
  652. return this.streamController.currentLevel;
  653. }
  654. /**
  655. * Set quality level index immediately. This will flush the current buffer to replace the quality asap. That means playback will interrupt at least shortly to re-buffer and re-sync eventually. Set to -1 for automatic level selection.
  656. */
  657. set currentLevel(newLevel: number) {
  658. this.logger.log(`set currentLevel:${newLevel}`);
  659. this.levelController.manualLevel = newLevel;
  660. this.streamController.immediateLevelSwitch();
  661. }
  662. /**
  663. * Index of next quality level loaded as scheduled by stream controller.
  664. */
  665. get nextLevel(): number {
  666. return this.streamController.nextLevel;
  667. }
  668. /**
  669. * Set quality level index for next loaded data.
  670. * This will switch the video quality asap, without interrupting playback.
  671. * May abort current loading of data, and flush parts of buffer (outside currently played fragment region).
  672. * @param newLevel - Pass -1 for automatic level selection
  673. */
  674. set nextLevel(newLevel: number) {
  675. this.logger.log(`set nextLevel:${newLevel}`);
  676. this.levelController.manualLevel = newLevel;
  677. this.streamController.nextLevelSwitch();
  678. }
  679. /**
  680. * Return the quality level of the currently or last (of none is loaded currently) segment
  681. */
  682. get loadLevel(): number {
  683. return this.levelController.level;
  684. }
  685. /**
  686. * Set quality level index for next loaded data in a conservative way.
  687. * This will switch the quality without flushing, but interrupt current loading.
  688. * Thus the moment when the quality switch will appear in effect will only be after the already existing buffer.
  689. * @param newLevel - Pass -1 for automatic level selection
  690. */
  691. set loadLevel(newLevel: number) {
  692. this.logger.log(`set loadLevel:${newLevel}`);
  693. this.levelController.manualLevel = newLevel;
  694. }
  695. /**
  696. * get next quality level loaded
  697. */
  698. get nextLoadLevel(): number {
  699. return this.levelController.nextLoadLevel;
  700. }
  701. /**
  702. * Set quality level of next loaded segment in a fully "non-destructive" way.
  703. * Same as `loadLevel` but will wait for next switch (until current loading is done).
  704. */
  705. set nextLoadLevel(level: number) {
  706. this.levelController.nextLoadLevel = level;
  707. }
  708. /**
  709. * Return "first level": like a default level, if not set,
  710. * falls back to index of first level referenced in manifest
  711. */
  712. get firstLevel(): number {
  713. return Math.max(this.levelController.firstLevel, this.minAutoLevel);
  714. }
  715. /**
  716. * Sets "first-level", see getter.
  717. */
  718. set firstLevel(newLevel: number) {
  719. this.logger.log(`set firstLevel:${newLevel}`);
  720. this.levelController.firstLevel = newLevel;
  721. }
  722. /**
  723. * Return the desired start level for the first fragment that will be loaded.
  724. * The default value of -1 indicates automatic start level selection.
  725. * Setting hls.nextAutoLevel without setting a startLevel will result in
  726. * the nextAutoLevel value being used for one fragment load.
  727. */
  728. get startLevel(): number {
  729. const startLevel = this.levelController.startLevel;
  730. if (startLevel === -1 && this.abrController.forcedAutoLevel > -1) {
  731. return this.abrController.forcedAutoLevel;
  732. }
  733. return startLevel;
  734. }
  735. /**
  736. * set start level (level of first fragment that will be played back)
  737. * if not overrided by user, first level appearing in manifest will be used as start level
  738. * if -1 : automatic start level selection, playback will start from level matching download bandwidth
  739. * (determined from download of first segment)
  740. */
  741. set startLevel(newLevel: number) {
  742. this.logger.log(`set startLevel:${newLevel}`);
  743. // if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
  744. if (newLevel !== -1) {
  745. newLevel = Math.max(newLevel, this.minAutoLevel);
  746. }
  747. this.levelController.startLevel = newLevel;
  748. }
  749. /**
  750. * Whether level capping is enabled.
  751. * Default value is set via `config.capLevelToPlayerSize`.
  752. */
  753. get capLevelToPlayerSize(): boolean {
  754. return this.config.capLevelToPlayerSize;
  755. }
  756. /**
  757. * Enables or disables level capping. If disabled after previously enabled, `nextLevelSwitch` will be immediately called.
  758. */
  759. set capLevelToPlayerSize(shouldStartCapping: boolean) {
  760. const newCapLevelToPlayerSize = !!shouldStartCapping;
  761. if (newCapLevelToPlayerSize !== this.config.capLevelToPlayerSize) {
  762. if (newCapLevelToPlayerSize) {
  763. this.capLevelController.startCapping(); // If capping occurs, nextLevelSwitch will happen based on size.
  764. } else {
  765. this.capLevelController.stopCapping();
  766. this.autoLevelCapping = -1;
  767. this.streamController.nextLevelSwitch(); // Now we're uncapped, get the next level asap.
  768. }
  769. this.config.capLevelToPlayerSize = newCapLevelToPlayerSize;
  770. }
  771. }
  772. /**
  773. * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`)
  774. */
  775. get autoLevelCapping(): number {
  776. return this._autoLevelCapping;
  777. }
  778. /**
  779. * Returns the current bandwidth estimate in bits per second, when available. Otherwise, `NaN` is returned.
  780. */
  781. get bandwidthEstimate(): number {
  782. const { bwEstimator } = this.abrController;
  783. if (!bwEstimator) {
  784. return NaN;
  785. }
  786. return bwEstimator.getEstimate();
  787. }
  788. set bandwidthEstimate(abrEwmaDefaultEstimate: number) {
  789. this.abrController.resetEstimator(abrEwmaDefaultEstimate);
  790. }
  791. get abrEwmaDefaultEstimate(): number {
  792. const { bwEstimator } = this.abrController;
  793. if (!bwEstimator) {
  794. return NaN;
  795. }
  796. return bwEstimator.defaultEstimate;
  797. }
  798. /**
  799. * get time to first byte estimate
  800. * @type {number}
  801. */
  802. get ttfbEstimate(): number {
  803. const { bwEstimator } = this.abrController;
  804. if (!bwEstimator) {
  805. return NaN;
  806. }
  807. return bwEstimator.getEstimateTTFB();
  808. }
  809. /**
  810. * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`)
  811. */
  812. set autoLevelCapping(newLevel: number) {
  813. if (this._autoLevelCapping !== newLevel) {
  814. this.logger.log(`set autoLevelCapping:${newLevel}`);
  815. this._autoLevelCapping = newLevel;
  816. this.levelController.checkMaxAutoUpdated();
  817. }
  818. }
  819. get maxHdcpLevel(): HdcpLevel {
  820. return this._maxHdcpLevel;
  821. }
  822. set maxHdcpLevel(value: HdcpLevel) {
  823. if (isHdcpLevel(value) && this._maxHdcpLevel !== value) {
  824. this._maxHdcpLevel = value;
  825. this.levelController.checkMaxAutoUpdated();
  826. }
  827. }
  828. /**
  829. * True when automatic level selection enabled
  830. */
  831. get autoLevelEnabled(): boolean {
  832. return this.levelController.manualLevel === -1;
  833. }
  834. /**
  835. * Level set manually (if any)
  836. */
  837. get manualLevel(): number {
  838. return this.levelController.manualLevel;
  839. }
  840. /**
  841. * min level selectable in auto mode according to config.minAutoBitrate
  842. */
  843. get minAutoLevel(): number {
  844. const {
  845. levels,
  846. config: { minAutoBitrate },
  847. } = this;
  848. if (!levels) return 0;
  849. const len = levels.length;
  850. for (let i = 0; i < len; i++) {
  851. if (levels[i].maxBitrate >= minAutoBitrate) {
  852. return i;
  853. }
  854. }
  855. return 0;
  856. }
  857. /**
  858. * max level selectable in auto mode according to autoLevelCapping
  859. */
  860. get maxAutoLevel(): number {
  861. const { levels, autoLevelCapping, maxHdcpLevel } = this;
  862. let maxAutoLevel;
  863. if (autoLevelCapping === -1 && levels?.length) {
  864. maxAutoLevel = levels.length - 1;
  865. } else {
  866. maxAutoLevel = autoLevelCapping;
  867. }
  868. if (maxHdcpLevel) {
  869. for (let i = maxAutoLevel; i--; ) {
  870. const hdcpLevel = levels[i].attrs['HDCP-LEVEL'];
  871. if (hdcpLevel && hdcpLevel <= maxHdcpLevel) {
  872. return i;
  873. }
  874. }
  875. }
  876. return maxAutoLevel;
  877. }
  878. get firstAutoLevel(): number {
  879. return this.abrController.firstAutoLevel;
  880. }
  881. /**
  882. * next automatically selected quality level
  883. */
  884. get nextAutoLevel(): number {
  885. return this.abrController.nextAutoLevel;
  886. }
  887. /**
  888. * this setter is used to force next auto level.
  889. * this is useful to force a switch down in auto mode:
  890. * in case of load error on level N, hls.js can set nextAutoLevel to N-1 for example)
  891. * forced value is valid for one fragment. upon successful frag loading at forced level,
  892. * this value will be resetted to -1 by ABR controller.
  893. */
  894. set nextAutoLevel(nextLevel: number) {
  895. this.abrController.nextAutoLevel = nextLevel;
  896. }
  897. /**
  898. * get the datetime value relative to media.currentTime for the active level Program Date Time if present
  899. */
  900. public get playingDate(): Date | null {
  901. return this.streamController.currentProgramDateTime;
  902. }
  903. public get mainForwardBufferInfo(): BufferInfo | null {
  904. return this.streamController.getMainFwdBufferInfo();
  905. }
  906. public get maxBufferLength(): number {
  907. return this.streamController.maxBufferLength;
  908. }
  909. /**
  910. * Find and select the best matching audio track, making a level switch when a Group change is necessary.
  911. * Updates `hls.config.audioPreference`. Returns the selected track, or null when no matching track is found.
  912. */
  913. public setAudioOption(
  914. audioOption: MediaPlaylist | AudioSelectionOption | undefined,
  915. ): MediaPlaylist | null {
  916. return this.audioTrackController?.setAudioOption(audioOption) || null;
  917. }
  918. /**
  919. * Find and select the best matching subtitle track, making a level switch when a Group change is necessary.
  920. * Updates `hls.config.subtitlePreference`. Returns the selected track, or null when no matching track is found.
  921. */
  922. public setSubtitleOption(
  923. subtitleOption: MediaPlaylist | SubtitleSelectionOption | undefined,
  924. ): MediaPlaylist | null {
  925. return (
  926. this.subtitleTrackController?.setSubtitleOption(subtitleOption) || null
  927. );
  928. }
  929. /**
  930. * Get the complete list of audio tracks across all media groups
  931. */
  932. get allAudioTracks(): MediaPlaylist[] {
  933. const audioTrackController = this.audioTrackController;
  934. return audioTrackController ? audioTrackController.allAudioTracks : [];
  935. }
  936. /**
  937. * Get the list of selectable audio tracks
  938. */
  939. get audioTracks(): MediaPlaylist[] {
  940. const audioTrackController = this.audioTrackController;
  941. return audioTrackController ? audioTrackController.audioTracks : [];
  942. }
  943. /**
  944. * index of the selected audio track (index in audio track lists)
  945. */
  946. get audioTrack(): number {
  947. const audioTrackController = this.audioTrackController;
  948. return audioTrackController ? audioTrackController.audioTrack : -1;
  949. }
  950. /**
  951. * selects an audio track, based on its index in audio track lists
  952. */
  953. set audioTrack(audioTrackId: number) {
  954. const audioTrackController = this.audioTrackController;
  955. if (audioTrackController) {
  956. audioTrackController.audioTrack = audioTrackId;
  957. }
  958. }
  959. /**
  960. * get the complete list of subtitle tracks across all media groups
  961. */
  962. get allSubtitleTracks(): MediaPlaylist[] {
  963. const subtitleTrackController = this.subtitleTrackController;
  964. return subtitleTrackController
  965. ? subtitleTrackController.allSubtitleTracks
  966. : [];
  967. }
  968. /**
  969. * get alternate subtitle tracks list from playlist
  970. */
  971. get subtitleTracks(): MediaPlaylist[] {
  972. const subtitleTrackController = this.subtitleTrackController;
  973. return subtitleTrackController
  974. ? subtitleTrackController.subtitleTracks
  975. : [];
  976. }
  977. /**
  978. * index of the selected subtitle track (index in subtitle track lists)
  979. */
  980. get subtitleTrack(): number {
  981. const subtitleTrackController = this.subtitleTrackController;
  982. return subtitleTrackController ? subtitleTrackController.subtitleTrack : -1;
  983. }
  984. get media() {
  985. return this._media;
  986. }
  987. /**
  988. * select an subtitle track, based on its index in subtitle track lists
  989. */
  990. set subtitleTrack(subtitleTrackId: number) {
  991. const subtitleTrackController = this.subtitleTrackController;
  992. if (subtitleTrackController) {
  993. subtitleTrackController.subtitleTrack = subtitleTrackId;
  994. }
  995. }
  996. /**
  997. * Whether subtitle display is enabled or not
  998. */
  999. get subtitleDisplay(): boolean {
  1000. const subtitleTrackController = this.subtitleTrackController;
  1001. return subtitleTrackController
  1002. ? subtitleTrackController.subtitleDisplay
  1003. : false;
  1004. }
  1005. /**
  1006. * Enable/disable subtitle display rendering
  1007. */
  1008. set subtitleDisplay(value: boolean) {
  1009. const subtitleTrackController = this.subtitleTrackController;
  1010. if (subtitleTrackController) {
  1011. subtitleTrackController.subtitleDisplay = value;
  1012. }
  1013. }
  1014. /**
  1015. * get mode for Low-Latency HLS loading
  1016. */
  1017. get lowLatencyMode(): boolean {
  1018. return this.config.lowLatencyMode;
  1019. }
  1020. /**
  1021. * Enable/disable Low-Latency HLS part playlist and segment loading, and start live streams at playlist PART-HOLD-BACK rather than HOLD-BACK.
  1022. */
  1023. set lowLatencyMode(mode: boolean) {
  1024. this.config.lowLatencyMode = mode;
  1025. }
  1026. /**
  1027. * Position (in seconds) of live sync point (ie edge of live position minus safety delay defined by ```hls.config.liveSyncDuration```)
  1028. * @returns null prior to loading live Playlist
  1029. */
  1030. get liveSyncPosition(): number | null {
  1031. return this.latencyController.liveSyncPosition;
  1032. }
  1033. /**
  1034. * Estimated position (in seconds) of live edge (ie edge of live playlist plus time sync playlist advanced)
  1035. * @returns 0 before first playlist is loaded
  1036. */
  1037. get latency(): number {
  1038. return this.latencyController.latency;
  1039. }
  1040. /**
  1041. * maximum distance from the edge before the player seeks forward to ```hls.liveSyncPosition```
  1042. * configured using ```liveMaxLatencyDurationCount``` (multiple of target duration) or ```liveMaxLatencyDuration```
  1043. * @returns 0 before first playlist is loaded
  1044. */
  1045. get maxLatency(): number {
  1046. return this.latencyController.maxLatency;
  1047. }
  1048. /**
  1049. * target distance from the edge as calculated by the latency controller
  1050. */
  1051. get targetLatency(): number | null {
  1052. return this.latencyController.targetLatency;
  1053. }
  1054. set targetLatency(latency: number) {
  1055. this.latencyController.targetLatency = latency;
  1056. }
  1057. /**
  1058. * the rate at which the edge of the current live playlist is advancing or 1 if there is none
  1059. */
  1060. get drift(): number | null {
  1061. return this.latencyController.drift;
  1062. }
  1063. /**
  1064. * set to true when startLoad is called before MANIFEST_PARSED event
  1065. */
  1066. get forceStartLoad(): boolean {
  1067. return this.streamController.forceStartLoad;
  1068. }
  1069. /**
  1070. * ContentSteering pathways getter
  1071. */
  1072. get pathways(): string[] {
  1073. return this.levelController.pathways;
  1074. }
  1075. /**
  1076. * ContentSteering pathwayPriority getter/setter
  1077. */
  1078. get pathwayPriority(): string[] | null {
  1079. return this.levelController.pathwayPriority;
  1080. }
  1081. set pathwayPriority(pathwayPriority: string[]) {
  1082. this.levelController.pathwayPriority = pathwayPriority;
  1083. }
  1084. /**
  1085. * returns true when all SourceBuffers are buffered to the end
  1086. */
  1087. get bufferedToEnd(): boolean {
  1088. return !!this.bufferController?.bufferedToEnd;
  1089. }
  1090. /**
  1091. * returns Interstitials Program Manager
  1092. */
  1093. get interstitialsManager(): InterstitialsManager | null {
  1094. return this.interstitialsController?.interstitialsManager || null;
  1095. }
  1096. /**
  1097. * returns mediaCapabilities.decodingInfo for a variant/rendition
  1098. */
  1099. getMediaDecodingInfo(
  1100. level: Level,
  1101. audioTracks: MediaPlaylist[] = this.allAudioTracks,
  1102. ): Promise<MediaDecodingInfo> {
  1103. const audioTracksByGroup = getAudioTracksByGroup(audioTracks);
  1104. return getMediaDecodingInfoPromise(
  1105. level,
  1106. audioTracksByGroup,
  1107. navigator.mediaCapabilities,
  1108. );
  1109. }
  1110. }
  1111. export type InFlightFragments = {
  1112. [PlaylistLevelType.MAIN]: InFlightData;
  1113. [PlaylistLevelType.AUDIO]?: InFlightData;
  1114. [PlaylistLevelType.SUBTITLE]?: InFlightData;
  1115. };
  1116. export type {
  1117. AudioSelectionOption,
  1118. SubtitleSelectionOption,
  1119. VideoSelectionOption,
  1120. MediaPlaylist,
  1121. ErrorDetails,
  1122. ErrorTypes,
  1123. Events,
  1124. Level,
  1125. LevelDetails,
  1126. HlsListeners,
  1127. HlsEventEmitter,
  1128. HlsConfig,
  1129. BufferInfo,
  1130. BufferTimeRange,
  1131. HdcpLevel,
  1132. AbrController,
  1133. AudioStreamController,
  1134. AudioTrackController,
  1135. BasePlaylistController,
  1136. BaseStreamController,
  1137. BufferController,
  1138. CapLevelController,
  1139. CMCDController,
  1140. ContentSteeringController,
  1141. EMEController,
  1142. ErrorController,
  1143. FPSController,
  1144. InterstitialsController,
  1145. StreamController,
  1146. SubtitleStreamController,
  1147. SubtitleTrackController,
  1148. EwmaBandWidthEstimator,
  1149. InterstitialsManager,
  1150. Decrypter,
  1151. FragmentLoader,
  1152. KeyLoader,
  1153. TaskLoop,
  1154. TransmuxerInterface,
  1155. InFlightData,
  1156. State,
  1157. XhrLoader,
  1158. FetchLoader,
  1159. Cues,
  1160. M3U8Parser,
  1161. };
  1162. export type {
  1163. ABRControllerConfig,
  1164. BufferControllerConfig,
  1165. CapLevelControllerConfig,
  1166. CMCDControllerConfig,
  1167. EMEControllerConfig,
  1168. DRMSystemConfiguration,
  1169. DRMSystemsConfiguration,
  1170. DRMSystemOptions,
  1171. FPSControllerConfig,
  1172. FragmentLoaderConfig,
  1173. FragmentLoaderConstructor,
  1174. GapControllerConfig,
  1175. HlsLoadPolicies,
  1176. LevelControllerConfig,
  1177. LoaderConfig,
  1178. LoadPolicy,
  1179. MP4RemuxerConfig,
  1180. PlaylistLoaderConfig,
  1181. PlaylistLoaderConstructor,
  1182. RetryConfig,
  1183. SelectionPreferences,
  1184. StreamControllerConfig,
  1185. LatencyControllerConfig,
  1186. MetadataControllerConfig,
  1187. TimelineControllerConfig,
  1188. TSDemuxerConfig,
  1189. } from './config';
  1190. export type { MediaKeySessionContext } from './controller/eme-controller';
  1191. export type {
  1192. FragmentState,
  1193. FragmentTracker,
  1194. } from './controller/fragment-tracker';
  1195. export type {
  1196. PathwayClone,
  1197. SteeringManifest,
  1198. UriReplacement,
  1199. } from './controller/content-steering-controller';
  1200. export type {
  1201. NetworkErrorAction,
  1202. ErrorActionFlags,
  1203. IErrorAction,
  1204. } from './controller/error-controller';
  1205. export type {
  1206. HlsAssetPlayer,
  1207. HlsAssetPlayerConfig,
  1208. InterstitialPlayer,
  1209. } from './controller/interstitial-player';
  1210. export type { PlayheadTimes } from './controller/interstitials-controller';
  1211. export type {
  1212. InterstitialScheduleDurations,
  1213. InterstitialScheduleEventItem,
  1214. InterstitialScheduleItem,
  1215. InterstitialSchedulePrimaryItem,
  1216. } from './controller/interstitials-schedule';
  1217. export type { TimelineController } from './controller/timeline-controller';
  1218. export type { DecrypterAesMode } from './crypt/decrypter-aes-mode';
  1219. export type { DateRange, DateRangeCue } from './loader/date-range';
  1220. export type { LoadStats } from './loader/load-stats';
  1221. export type { LevelKey } from './loader/level-key';
  1222. export type {
  1223. BaseSegment,
  1224. Fragment,
  1225. MediaFragment,
  1226. Part,
  1227. ElementaryStreams,
  1228. ElementaryStreamTypes,
  1229. ElementaryStreamInfo,
  1230. } from './loader/fragment';
  1231. export type {
  1232. FragLoadFailResult,
  1233. FragmentLoadProgressCallback,
  1234. LoadError,
  1235. } from './loader/fragment-loader';
  1236. export type { KeyLoaderInfo } from './loader/key-loader';
  1237. export type { DecryptData } from './loader/level-key';
  1238. export type {
  1239. AssetListJSON,
  1240. BaseData,
  1241. InterstitialAssetId,
  1242. InterstitialAssetItem,
  1243. InterstitialEvent,
  1244. InterstitialEventWithAssetList,
  1245. InterstitialId,
  1246. PlaybackRestrictions,
  1247. SnapOptions,
  1248. TimelineOccupancy,
  1249. } from './loader/interstitial-event';
  1250. export type { ParsedMultivariantPlaylist } from './loader/m3u8-parser';
  1251. export type {
  1252. AttachMediaSourceData,
  1253. BaseTrack,
  1254. BaseTrackSet,
  1255. BufferCreatedTrack,
  1256. BufferCreatedTrackSet,
  1257. ExtendedSourceBuffer,
  1258. MediaOverrides,
  1259. ParsedTrack,
  1260. SourceBufferName,
  1261. SourceBufferListener,
  1262. SourceBufferTrack,
  1263. SourceBufferTrackSet,
  1264. } from './types/buffer';
  1265. export type {
  1266. ComponentAPI,
  1267. AbrComponentAPI,
  1268. NetworkComponentAPI,
  1269. } from './types/component-api';
  1270. export type {
  1271. TrackLoadingData,
  1272. TrackLoadedData,
  1273. AssetListLoadedData,
  1274. AssetListLoadingData,
  1275. AudioTrackLoadedData,
  1276. AudioTrackUpdatedData,
  1277. AudioTracksUpdatedData,
  1278. AudioTrackSwitchedData,
  1279. AudioTrackSwitchingData,
  1280. BackBufferData,
  1281. BufferAppendedData,
  1282. BufferAppendingData,
  1283. BufferCodecsData,
  1284. BufferCreatedData,
  1285. BufferEOSData,
  1286. BufferFlushedData,
  1287. BufferFlushingData,
  1288. CuesParsedData,
  1289. ErrorData,
  1290. FPSDropData,
  1291. FPSDropLevelCappingData,
  1292. FragBufferedData,
  1293. FragChangedData,
  1294. FragDecryptedData,
  1295. FragLoadedData,
  1296. FragLoadEmergencyAbortedData,
  1297. FragLoadingData,
  1298. FragParsedData,
  1299. FragParsingInitSegmentData,
  1300. FragParsingMetadataData,
  1301. FragParsingUserdataData,
  1302. InitPTSFoundData,
  1303. KeyLoadedData,
  1304. KeyLoadingData,
  1305. LevelLoadedData,
  1306. LevelLoadingData,
  1307. LevelPTSUpdatedData,
  1308. LevelsUpdatedData,
  1309. LevelSwitchedData,
  1310. LevelSwitchingData,
  1311. LevelUpdatedData,
  1312. LiveBackBufferData,
  1313. ContentSteeringOptions,
  1314. ManifestLoadedData,
  1315. ManifestLoadingData,
  1316. ManifestParsedData,
  1317. MaxAutoLevelUpdatedData,
  1318. MediaAttachedData,
  1319. MediaAttachingData,
  1320. MediaDetachedData,
  1321. MediaDetachingData,
  1322. MediaEndedData,
  1323. NonNativeTextTrack,
  1324. NonNativeTextTracksData,
  1325. PartsLoadedData,
  1326. SteeringManifestLoadedData,
  1327. SubtitleFragProcessedData,
  1328. SubtitleTrackLoadedData,
  1329. SubtitleTrackUpdatedData,
  1330. SubtitleTracksUpdatedData,
  1331. SubtitleTrackSwitchData,
  1332. InterstitialsUpdatedData,
  1333. InterstitialsBufferedToBoundaryData,
  1334. InterstitialAssetPlayerCreatedData,
  1335. InterstitialStartedData,
  1336. InterstitialEndedData,
  1337. InterstitialAssetStartedData,
  1338. InterstitialAssetEndedData,
  1339. InterstitialAssetErrorData,
  1340. InterstitialsPrimaryResumed,
  1341. } from './types/events';
  1342. export type {
  1343. MetadataSample,
  1344. MetadataSchema,
  1345. UserdataSample,
  1346. } from './types/demuxer';
  1347. export type {
  1348. InitSegmentData,
  1349. RemuxedMetadata,
  1350. RemuxedTrack,
  1351. RemuxedUserdata,
  1352. RemuxerResult,
  1353. } from './types/remuxer';
  1354. export type { AttrList } from './utils/attr-list';
  1355. export type { Bufferable } from './utils/buffer-helper';
  1356. export type { CaptionScreen } from './utils/cea-608-parser';
  1357. export type { CuesInterface } from './utils/cues';
  1358. export type {
  1359. CodecsParsed,
  1360. HdcpLevels,
  1361. HlsSkip,
  1362. HlsUrlParameters,
  1363. LevelAttributes,
  1364. LevelParsed,
  1365. VariableMap,
  1366. VideoRange,
  1367. VideoRangeValues,
  1368. } from './types/level';
  1369. export type {
  1370. PlaylistLevelType,
  1371. HlsChunkPerformanceTiming,
  1372. HlsPerformanceTiming,
  1373. HlsProgressivePerformanceTiming,
  1374. PlaylistContextType,
  1375. PlaylistLoaderContext,
  1376. FragmentLoaderContext,
  1377. KeyLoaderContext,
  1378. Loader,
  1379. LoaderStats,
  1380. LoaderContext,
  1381. LoaderResponse,
  1382. LoaderConfiguration,
  1383. LoaderCallbacks,
  1384. LoaderOnProgress,
  1385. LoaderOnAbort,
  1386. LoaderOnError,
  1387. LoaderOnSuccess,
  1388. LoaderOnTimeout,
  1389. } from './types/loader';
  1390. export type { ILogFunction, ILogger, Logger } from './utils/logger';
  1391. export type {
  1392. MediaAttributes,
  1393. MediaPlaylistType,
  1394. MainPlaylistType,
  1395. AudioPlaylistType,
  1396. SubtitlePlaylistType,
  1397. } from './types/media-playlist';
  1398. export type { Track, TrackSet } from './types/track';
  1399. export type { ChunkMetadata, TransmuxerResult } from './types/transmuxer';
  1400. export type { MediaDecodingInfo } from './utils/mediacapabilities-helper';
  1401. export type {
  1402. MediaKeyFunc,
  1403. KeySystems,
  1404. KeySystemFormats,
  1405. } from './utils/mediakeys-helper';
  1406. export type { RationalTimestamp } from './utils/timescale-conversion';