From 8a97c9b49d32d53c8bd6697ded5706b914b43573 Mon Sep 17 00:00:00 2001 From: John Bartos Date: Thu, 12 Sep 2019 11:53:39 -0400 Subject: [PATCH] Fix lint errors --- src/controller/abr-controller.ts | 6 +- src/controller/audio-stream-controller.ts | 98 ++++----- src/controller/buffer-controller.ts | 25 ++- src/controller/buffer-operation-queue.ts | 6 +- src/controller/fragment-tracker.ts | 4 +- src/controller/level-controller.ts | 2 +- src/controller/level-helper.ts | 2 +- src/controller/stream-controller.ts | 4 +- src/crypt/decrypter.ts | 7 +- src/demux/aacdemuxer.ts | 18 +- src/demux/chunk-cache.ts | 2 +- src/demux/mp3demuxer.ts | 8 +- src/demux/mp4demuxer.ts | 8 +- src/demux/transmuxer-interface.ts | 44 ++-- src/demux/transmuxer-worker.ts | 78 +++---- src/demux/transmuxer.ts | 24 +-- src/loader/fragment-loader.ts | 100 ++++----- src/loader/load-stats.ts | 1 - src/performance/performance-monitor.ts | 3 +- src/polyfills/runtime-polyfills.ts | 1 + src/remux/mp4-remuxer.ts | 9 +- src/remux/passthrough-remuxer.ts | 32 +-- src/task-loop.ts | 2 +- src/types/buffer.ts | 2 +- src/types/fragment-tracker.ts | 2 +- src/types/general.ts | 2 +- src/types/transmuxer.ts | 18 +- src/utils/chunker.ts | 2 +- src/utils/fetch-loader.ts | 26 +-- src/utils/mp4-tools.ts | 8 +- src/utils/xhr-loader.ts | 16 +- .../buffer-controller-operations.ts | 67 +++--- tests/unit/controller/buffer-controller.js | 192 +++++++++--------- .../unit/controller/buffer-operation-queue.ts | 28 +-- 34 files changed, 420 insertions(+), 427 deletions(-) diff --git a/src/controller/abr-controller.ts b/src/controller/abr-controller.ts index b20a943c097..51e855943ca 100644 --- a/src/controller/abr-controller.ts +++ b/src/controller/abr-controller.ts @@ -69,7 +69,7 @@ class AbrController extends EventHandler { } } - /* + /* This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load quickly enough to prevent underbuffering TODO: Can we enhance this method when progressively streaming? @@ -147,7 +147,7 @@ class AbrController extends EventHandler { if (Number.isFinite(bwEstimate)) { bwEstimate = (bwEstimate / 1024).toFixed(3); } else { - bwEstimate = 'Unknown' + bwEstimate = 'Unknown'; } logger.warn(`Fragment ${frag.sn} of level ${frag.level} is loading too slowly and will cause an underbuffer; aborting and switching to level ${nextLoadLevel} Current BW estimate: ${bwEstimate} Kb/s @@ -341,6 +341,4 @@ class AbrController extends EventHandler { } } - - export default AbrController; diff --git a/src/controller/audio-stream-controller.ts b/src/controller/audio-stream-controller.ts index d273c73d2f9..2a555f68e5b 100644 --- a/src/controller/audio-stream-controller.ts +++ b/src/controller/audio-stream-controller.ts @@ -90,52 +90,52 @@ class AudioStreamController extends BaseStreamController { const { media } = this; switch (this.state) { - case State.ERROR: - // don't do anything in error state to avoid breaking further ... - break; - case State.PAUSED: - // TODO: Remove useless PAUSED state - // don't do anything in paused state either ... - break; - case State.STARTING: - this.state = State.WAITING_TRACK; - this.loadedmetadata = false; - break; - case State.IDLE: - this.doTickIdle(); - break; - case State.WAITING_TRACK: { - const {levels, trackId} = this; - if (levels && levels[trackId] && levels[trackId].details) { - // check if playlist is already loaded - this.state = State.WAITING_INIT_PTS; - } - break; + case State.ERROR: + // don't do anything in error state to avoid breaking further ... + break; + case State.PAUSED: + // TODO: Remove useless PAUSED state + // don't do anything in paused state either ... + break; + case State.STARTING: + this.state = State.WAITING_TRACK; + this.loadedmetadata = false; + break; + case State.IDLE: + this.doTickIdle(); + break; + case State.WAITING_TRACK: { + const { levels, trackId } = this; + if (levels && levels[trackId] && levels[trackId].details) { + // check if playlist is already loaded + this.state = State.WAITING_INIT_PTS; } - case State.FRAG_LOADING_WAITING_RETRY: - const now = performance.now(); - const retryDate = this.retryDate; - const isSeeking = media && media.seeking; - // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading - if (!retryDate || (now >= retryDate) || isSeeking) { - this.log('RetryDate reached, switch back to IDLE state'); - this.state = State.IDLE; - } - break; - case State.WAITING_INIT_PTS: - const videoTrackCC = this.videoTrackCC; - if (Number.isFinite(this.initPTS[videoTrackCC])) { - this.state = State.IDLE; - } - break; - case State.STOPPED: - case State.FRAG_LOADING: - case State.PARSING: - case State.PARSED: - case State.ENDED: - break; - default: - break; + break; + } + case State.FRAG_LOADING_WAITING_RETRY: + const now = performance.now(); + const retryDate = this.retryDate; + const isSeeking = media && media.seeking; + // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading + if (!retryDate || (now >= retryDate) || isSeeking) { + this.log('RetryDate reached, switch back to IDLE state'); + this.state = State.IDLE; + } + break; + case State.WAITING_INIT_PTS: + const videoTrackCC = this.videoTrackCC; + if (Number.isFinite(this.initPTS[videoTrackCC])) { + this.state = State.IDLE; + } + break; + case State.STOPPED: + case State.FRAG_LOADING: + case State.PARSING: + case State.PARSED: + case State.ENDED: + break; + default: + break; } this.onTickEnd(); @@ -157,7 +157,7 @@ class AudioStreamController extends BaseStreamController { this.lastCurrentTime = media.currentTime; } - private doTickIdle() { + private doTickIdle () { const { hls, levels, media, trackId } = this; const config = hls.config; @@ -233,7 +233,7 @@ class AudioStreamController extends BaseStreamController { if (frag.encrypted) { this.log(`Loading key for ${frag.sn} of [${trackDetails.startSN} ,${trackDetails.endSN}],track ${trackId}`); this.state = State.KEY_LOADING; - hls.trigger(Event.KEY_LOADING, {frag: frag}); + hls.trigger(Event.KEY_LOADING, { frag: frag }); } else { this.log(`Loading ${frag.sn}, cc: ${frag.cc} of [${trackDetails.startSN} ,${trackDetails.endSN}],track ${trackId}, currentTime:${pos},bufferEnd:${bufferInfo.end.toFixed(3)}`); this.loadFragment(frag); @@ -282,7 +282,7 @@ class AudioStreamController extends BaseStreamController { const { fragCurrent, transmuxer } = this; if (fragCurrent && fragCurrent.loader) { - fragCurrent.loader.abort(); + fragCurrent.loader.abort(); } this.fragCurrent = null; // destroy useless transmuxer when switching audio to main @@ -309,7 +309,7 @@ class AudioStreamController extends BaseStreamController { onAudioTrackLoaded (data: { details: LevelDetails, id: number }) { const { levels } = this; - const { details: newDetails, id: trackId, } = data; + const { details: newDetails, id: trackId } = data; if (!levels) { this.warn(`Audio tracks were reset while loading level ${trackId}`); return; diff --git a/src/controller/buffer-controller.ts b/src/controller/buffer-controller.ts index fda400e786a..f15c807b7a7 100644 --- a/src/controller/buffer-controller.ts +++ b/src/controller/buffer-controller.ts @@ -7,11 +7,9 @@ import EventHandler from '../event-handler'; import { logger } from '../utils/logger'; import { ErrorDetails, ErrorTypes } from '../errors'; import { getMediaSource } from '../utils/mediasource-helper'; -import Fragment from '../loader/fragment'; - +import Fragment, { ElementaryStreamTypes } from '../loader/fragment'; import { TrackSet } from '../types/track'; import { BufferAppendingEventPayload } from '../types/bufferAppendingEventPayload'; -import { ElementaryStreamTypes } from '../loader/fragment'; import BufferOperationQueue from './buffer-operation-queue'; import { @@ -21,7 +19,6 @@ import { SourceBufferName, SourceBufferListener } from '../types/buffer'; -import { ChunkMetadata } from '../types/transmuxer'; const MediaSource = getMediaSource(); @@ -32,7 +29,7 @@ export default class BufferController extends EventHandler { // the target duration of the current media playlist private _levelTargetDuration: number | null = null; // current stream state: true - for live broadcast, false - for VoD content - private _live: boolean = false; + private _live: boolean = false; // cache the self generated object url to detect hijack of video tag private _objectUrl: string | null = null; // A queue of buffer operations which require the SourceBuffer to not be updating upon execution @@ -263,7 +260,9 @@ export default class BufferController extends EventHandler { onComplete: () => { this.hls.trigger(Events.BUFFER_FLUSHED); }, - onError: (e) => { logger.warn(`[buffer-controller]: Failed to remove from ${type} SourceBuffer`, e); } + onError: (e) => { + logger.warn(`[buffer-controller]: Failed to remove from ${type} SourceBuffer`, e); + } }); if (data.type) { @@ -286,7 +285,7 @@ export default class BufferController extends EventHandler { } console.assert(buffersAppendedTo.length, 'Fragments must have at least one ElementaryStreamType set', frag); - logger.log(`[buffer-controller]: All fragment chunks received, enqueueing operation to signal fragment buffered`); + logger.log('[buffer-controller]: All fragment chunks received, enqueueing operation to signal fragment buffered'); const onUnblocked = () => { frag.stats.buffering.end = window.performance.now(); this.hls.trigger(Events.FRAG_BUFFERED, { frag, stats: frag.stats, id: frag.type }); @@ -318,7 +317,7 @@ export default class BufferController extends EventHandler { // Allow this to throw and be caught by the enqueueing function mediaSource.endOfStream(); }; - logger.log(`[buffer-controller: End of stream signalled, enqueuing end of stream operation`); + logger.log('[buffer-controller: End of stream signalled, enqueuing end of stream operation'); this.blockBuffers(endStream); } @@ -330,7 +329,7 @@ export default class BufferController extends EventHandler { this._live = details.live; const levelDuration = details.totalduration + details.fragments[0].start; - logger.log(`[buffer-controller]: Duration update required; enqueueing duration change operation`); + logger.log('[buffer-controller]: Duration update required; enqueueing duration change operation'); if (this.getSourceBufferTypes().length) { this.blockBuffers(this.updateMediaElementDuration.bind(this, levelDuration)); } else { @@ -521,7 +520,7 @@ export default class BufferController extends EventHandler { operation.onComplete(); operationQueue.shiftAndExecuteNext(type); - }; + } private _onSBUpdateError (type: SourceBufferName, event: Event) { logger.error(`[buffer-controller]: ${type} SourceBuffer error`, event); @@ -596,7 +595,7 @@ export default class BufferController extends EventHandler { // upon completion, since we already do it here private blockBuffers (onUnblocked: Function, buffers: Array = this.getSourceBufferTypes()) { if (!buffers.length) { - logger.log(`[buffer-controller]: Blocking operation requested, but no SourceBuffers exist`); + logger.log('[buffer-controller]: Blocking operation requested, but no SourceBuffers exist'); onUnblocked(); return; } @@ -615,7 +614,7 @@ export default class BufferController extends EventHandler { if (!sb || !sb.updating) { operationQueue.shiftAndExecuteNext(type); } - }) + }); }); } @@ -639,7 +638,7 @@ export default class BufferController extends EventHandler { return; } this.listeners[type].forEach(l => { - buffer.removeEventListener(l.event, l.listener); + buffer.removeEventListener(l.event, l.listener); }); } } diff --git a/src/controller/buffer-operation-queue.ts b/src/controller/buffer-operation-queue.ts index c10dc609035..55009786772 100644 --- a/src/controller/buffer-operation-queue.ts +++ b/src/controller/buffer-operation-queue.ts @@ -24,7 +24,9 @@ export default class BufferOperationQueue { public appendBlocker (type: SourceBufferName) : Promise<{}> { let execute; - const promise: Promise<{}> = new Promise((resolve, reject) => { execute = resolve; }); + const promise: Promise<{}> = new Promise((resolve, reject) => { + execute = resolve; + }); const operation = { execute, onComplete: () => {}, @@ -48,7 +50,7 @@ export default class BufferOperationQueue { // which do not end with this event must call _onSBUpdateEnd manually operation.execute(); } catch (e) { - logger.warn(`[buffer-operation-queue]: Unhandled exception executing the current operation`); + logger.warn('[buffer-operation-queue]: Unhandled exception executing the current operation'); operation.onError(e); // Only shift the current operation off, otherwise the updateend handler will do this for us diff --git a/src/controller/fragment-tracker.ts b/src/controller/fragment-tracker.ts index 369d8462524..2d59f918b7d 100644 --- a/src/controller/fragment-tracker.ts +++ b/src/controller/fragment-tracker.ts @@ -208,7 +208,7 @@ export class FragmentTracker extends EventHandler { return state; } - isTimeBuffered (startPTS: number , endPTS: number , timeRange: TimeRanges): boolean { + isTimeBuffered (startPTS: number, endPTS: number, timeRange: TimeRanges): boolean { let startTime; let endTime; for (let i = 0; i < timeRange.length; i++) { @@ -299,4 +299,4 @@ function isPartial (fragmentEntity: FragmentEntity): boolean { function getFragmentKey (fragment: Fragment): string { return `${fragment.type}_${fragment.level}_${fragment.urlId}_${fragment.sn}`; -} \ No newline at end of file +} diff --git a/src/controller/level-controller.ts b/src/controller/level-controller.ts index aa0e01d3400..7b13e705fc3 100644 --- a/src/controller/level-controller.ts +++ b/src/controller/level-controller.ts @@ -91,7 +91,7 @@ export default class LevelController extends EventHandler { let audioCodecFound = false; // regroup redundant levels together - data.levels.forEach((levelParsed: LevelParsed) => { + data.levels.forEach((levelParsed: LevelParsed) => { const attributes = levelParsed.attrs; videoCodecFound = videoCodecFound || !!levelParsed.videoCodec; diff --git a/src/controller/level-helper.ts b/src/controller/level-helper.ts index 262ba35df5a..81c0b8bdcaf 100644 --- a/src/controller/level-helper.ts +++ b/src/controller/level-helper.ts @@ -268,7 +268,7 @@ export function getProgramDateTimeAtEndOfLastEncodedFragment (levelDetails: Leve const encodedFragments = levelDetails.fragments.filter((fragment) => !fragment.prefetch); const lastEncodedFrag = encodedFragments[encodedFragments.length - 1]; if (Number.isFinite(lastEncodedFrag.programDateTime)) { - return lastEncodedFrag.programDateTime + lastEncodedFrag.duration * 1000; + return lastEncodedFrag.programDateTime + lastEncodedFrag.duration * 1000; } } return null; diff --git a/src/controller/stream-controller.ts b/src/controller/stream-controller.ts index 30590343156..083562fc9e4 100644 --- a/src/controller/stream-controller.ts +++ b/src/controller/stream-controller.ts @@ -421,7 +421,7 @@ export default class StreamController extends BaseStreamController { media.removeEventListener('seeking', this.onvseeking); media.removeEventListener('seeked', this.onvseeked); media.removeEventListener('ended', this.onvended); - this.onvseeking = this.onvseeked = this.onvended = null + this.onvseeking = this.onvseeked = this.onvended = null; } this.media = this.mediaBuffer = null; this.loadedmetadata = false; @@ -643,7 +643,7 @@ export default class StreamController extends BaseStreamController { const media = this.mediaBuffer ? this.mediaBuffer : this.media; const stats = frag.stats; this.fragPrevious = frag; - this.fragLastKbps = Math.round(8 * stats.total / (stats.buffering.end- stats.loading.first)); + this.fragLastKbps = Math.round(8 * stats.total / (stats.buffering.end - stats.loading.first)); this.log(`Buffered fragment ${frag.sn} of level ${frag.level}. PTS:[${frag.startPTS},${frag.endPTS}],DTS:[${frag.startDTS}/${frag.endDTS}], Buffered: ${TimeRanges.toString(media.buffered)}`); this.state = State.IDLE; diff --git a/src/crypt/decrypter.ts b/src/crypt/decrypter.ts index e33af70aea0..263d5c22c4d 100644 --- a/src/crypt/decrypter.ts +++ b/src/crypt/decrypter.ts @@ -105,7 +105,7 @@ export default class Decrypter { return new Uint8Array(result); } - public webCryptoDecrypt (data: Uint8Array, key: ArrayBuffer, iv: ArrayBuffer): Promise { + public webCryptoDecrypt (data: Uint8Array, key: ArrayBuffer, iv: ArrayBuffer): Promise { const subtle = this.subtle; if (this.key !== key || !this.fastAesKey) { this.key = key; @@ -118,21 +118,20 @@ export default class Decrypter { return crypto.decrypt(data.buffer, aesKey) .catch((err) => { return this.onWebCryptoError(err, data, key, iv); - }) + }); }) .catch((err) => { return this.onWebCryptoError(err, data, key, iv); }); } - private onWebCryptoError (err, data, key, iv) { + private onWebCryptoError (err, data, key, iv) { logger.warn('[decrypter.ts]: WebCrypto Error, disable WebCrypto API:', err); this.config.enableSoftwareAES = true; this.logEnabled = true; return this.softwareDecrypt(data, key, iv); } - private getValidChunk (data: Uint8Array) : Uint8Array { let currentChunk = data; const splitPoint = data.length - (data.length % CHUNK_SIZE); diff --git a/src/demux/aacdemuxer.ts b/src/demux/aacdemuxer.ts index 85f1aae0d52..7527de1541d 100644 --- a/src/demux/aacdemuxer.ts +++ b/src/demux/aacdemuxer.ts @@ -4,7 +4,7 @@ import * as ADTS from './adts'; import { logger } from '../utils/logger'; import ID3 from '../demux/id3'; -import {DemuxerResult, Demuxer, DemuxedTrack} from '../types/demuxer'; +import { DemuxerResult, Demuxer, DemuxedTrack } from '../types/demuxer'; import { dummyTrack } from './dummy-demuxed-track'; import { appendUint8Array } from '../utils/mp4-tools'; @@ -17,7 +17,7 @@ class AACDemuxer implements Demuxer { private cachedData: Uint8Array = new Uint8Array(); private initPTS: number | null = null; static readonly minProbeByteLength: number = 9; - + constructor (observer, config) { this.observer = observer; this.config = config; @@ -82,13 +82,13 @@ class AACDemuxer implements Demuxer { if (this.initPTS === null) { this.initPTS = Number.isFinite(timestamp) ? timestamp * 90 : timeOffset * 90000; } - + if (id3Data.length) { id3Track.samples.push({ pts: this.initPTS, dts: this.initPTS, data: id3Data }); } - + pts = this.initPTS; - + // Iteratively parse data for ADTS Headers and ID3 headers while (offset < length) { // Only begin parsing if able. @@ -117,8 +117,8 @@ class AACDemuxer implements Demuxer { } // At end of fragment, if there is remaining data, append everything since last useable data to cache. if (offset === length && lastDataIndex !== length) { - let partialData = data.slice(lastDataIndex); - this.cachedData = appendUint8Array(this.cachedData, partialData); + let partialData = data.slice(lastDataIndex); + this.cachedData = appendUint8Array(this.cachedData, partialData); } } @@ -139,11 +139,11 @@ class AACDemuxer implements Demuxer { if (this.cachedData) { this.demux(this.cachedData, 0); } - + this.frameIndex = 0; this.cachedData = new Uint8Array(); this.initPTS = null; - + return { audioTrack: this._audioTrack, avcTrack: dummyTrack, diff --git a/src/demux/chunk-cache.ts b/src/demux/chunk-cache.ts index e1d682a6192..4f491a6b58a 100644 --- a/src/demux/chunk-cache.ts +++ b/src/demux/chunk-cache.ts @@ -36,4 +36,4 @@ function concatUint8Arrays (chunks: Array, dataLength: number) : Uin offset += chunk.length; } return result; -} \ No newline at end of file +} diff --git a/src/demux/mp3demuxer.ts b/src/demux/mp3demuxer.ts index 6d4fb13b8a5..beca7d2b8ff 100644 --- a/src/demux/mp3demuxer.ts +++ b/src/demux/mp3demuxer.ts @@ -4,7 +4,7 @@ import ID3 from '../demux/id3'; import { logger } from '../utils/logger'; import MpegAudio from './mpegaudio'; -import {DemuxerResult, Demuxer, DemuxedTrack} from '../types/demuxer'; +import { DemuxerResult, Demuxer, DemuxedTrack } from '../types/demuxer'; import { dummyTrack } from './dummy-demuxed-track'; import { appendUint8Array } from '../utils/mp4-tools'; @@ -68,7 +68,7 @@ class MP3Demuxer implements Demuxer { const id3Track = this._id3Track; const timestamp = ID3.getTimeStamp(id3Data); const length = data.length; - + if (this.initPTS === null) { this.initPTS = timestamp ? 90 * timestamp : timeOffset * 90000; } @@ -125,11 +125,11 @@ class MP3Demuxer implements Demuxer { if (this.cachedData) { this.demux(this.cachedData, 0); } - + this.frameIndex = 0; this.initPTS = null; this.cachedData = new Uint8Array(); - + return { audioTrack: this._audioTrack, avcTrack: dummyTrack, diff --git a/src/demux/mp4demuxer.ts b/src/demux/mp4demuxer.ts index 515917bcc4e..a4bc1f321dd 100644 --- a/src/demux/mp4demuxer.ts +++ b/src/demux/mp4demuxer.ts @@ -53,10 +53,10 @@ class MP4Demuxer implements Demuxer { this.remainderData = null; return { - audioTrack: dummyTrack, - avcTrack, - id3Track: dummyTrack, - textTrack: dummyTrack + audioTrack: dummyTrack, + avcTrack, + id3Track: dummyTrack, + textTrack: dummyTrack }; } diff --git a/src/demux/transmuxer-interface.ts b/src/demux/transmuxer-interface.ts index 043d0ced0a6..7261544f213 100644 --- a/src/demux/transmuxer-interface.ts +++ b/src/demux/transmuxer-interface.ts @@ -187,30 +187,30 @@ export default class TransmuxerInterface { const data = ev.data; const hls = this.hls; switch (data.event) { - case 'init': { - // revoke the Object URL that was used to create transmuxer worker, so as not to leak it - global.URL.revokeObjectURL(this.worker.objectURL); - break; - } + case 'init': { + // revoke the Object URL that was used to create transmuxer worker, so as not to leak it + global.URL.revokeObjectURL(this.worker.objectURL); + break; + } - case 'transmuxComplete': { - this.handleTransmuxComplete(data.data); - break; - } + case 'transmuxComplete': { + this.handleTransmuxComplete(data.data); + break; + } - case 'flush': { - this.onFlush(data.data); - break; - } + case 'flush': { + this.onFlush(data.data); + break; + } - /* falls through */ - default: { - data.data = data.data || {}; - data.data.frag = this.frag; - data.data.id = this.id; - hls.trigger(data.event, data.data); - break; - } + /* falls through */ + default: { + data.data = data.data || {}; + data.data.frag = this.frag; + data.data.id = this.id; + hls.trigger(data.event, data.data); + break; + } } } @@ -221,7 +221,7 @@ export default class TransmuxerInterface { cmd: 'configure', config, state - }) + }); } else if (transmuxer) { transmuxer.configure(config, state); } diff --git a/src/demux/transmuxer-worker.ts b/src/demux/transmuxer-worker.ts index ab3efb74a3b..145e9c3af84 100644 --- a/src/demux/transmuxer-worker.ts +++ b/src/demux/transmuxer-worker.ts @@ -28,49 +28,49 @@ export default function TransmuxerWorker (self) { self.addEventListener('message', (ev) => { const data = ev.data; switch (data.cmd) { - case 'init': { - const config = JSON.parse(data.config); - self.transmuxer = new Transmuxer(observer, data.typeSupported, config, data.vendor); - enableLogs(config.debug); - forwardMessage('init', null); - break; + case 'init': { + const config = JSON.parse(data.config); + self.transmuxer = new Transmuxer(observer, data.typeSupported, config, data.vendor); + enableLogs(config.debug); + forwardMessage('init', null); + break; + } + case 'configure': { + self.transmuxer.configure(data.config, data.state); + break; + } + case 'demux': { + const transmuxResult: TransmuxerResult = self.transmuxer.push(data.data, data.decryptdata, data.chunkMeta); + if (!transmuxResult) { + return; } - case 'configure': { - self.transmuxer.configure(data.config, data.state); - break; - } - case 'demux': { - const transmuxResult: TransmuxerResult = self.transmuxer.push(data.data, data.decryptdata, data.chunkMeta); - if (!transmuxResult) { - return; - } + // @ts-ignore + if (transmuxResult.then) { // @ts-ignore - if (transmuxResult.then) { - // @ts-ignore - transmuxResult.then(data => { - emitTransmuxComplete(self, data); - }); - } else { - emitTransmuxComplete(self, transmuxResult); - } - break; + transmuxResult.then(data => { + emitTransmuxComplete(self, data); + }); + } else { + emitTransmuxComplete(self, transmuxResult); } - case 'flush': { - const id = data.chunkMeta; - const transmuxResult = self.transmuxer.flush(id); - if (transmuxResult.then) { - // @ts-ignore - transmuxResult.then((results: Array) => { - handleFlushResult(self, results as Array, id); - }); - } else { - handleFlushResult(self, transmuxResult as Array, id); - } - break; - } - default: - break; + break; + } + case 'flush': { + const id = data.chunkMeta; + const transmuxResult = self.transmuxer.flush(id); + if (transmuxResult.then) { + // @ts-ignore + transmuxResult.then((results: Array) => { + handleFlushResult(self, results as Array, id); + }); + } else { + handleFlushResult(self, transmuxResult as Array, id); } + break; + } + default: + break; + } }); } diff --git a/src/demux/transmuxer.ts b/src/demux/transmuxer.ts index 53e468e0718..393604e566b 100644 --- a/src/demux/transmuxer.ts +++ b/src/demux/transmuxer.ts @@ -91,7 +91,7 @@ export default class Transmuxer { stats.executeEnd = now(); return emptyResult(chunkMeta); } - uintData = decryptedData; + uintData = decryptedData; } else { this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, decryptdata.key.buffer, decryptdata.iv.buffer) .then((decryptedData) : TransmuxerResult => { @@ -101,7 +101,7 @@ export default class Transmuxer { this.decryptionPromise = null; return result; }); - return this.decryptionPromise!; + return this.decryptionPromise!; } } @@ -247,20 +247,20 @@ export default class Transmuxer { } private transmuxUnencrypted (data: Uint8Array, timeOffset: number, accurateTimeOffset: boolean, chunkMeta: ChunkMetadata) { - const { audioTrack, avcTrack, id3Track, textTrack } = this.demuxer!.demux(data, timeOffset,false); + const { audioTrack, avcTrack, id3Track, textTrack } = this.demuxer!.demux(data, timeOffset, false); return { remuxResult: this.remuxer!.remux(audioTrack, avcTrack, id3Track, textTrack, timeOffset, accurateTimeOffset), chunkMeta - } + }; } // TODO: Handle flush with Sample-AES private transmuxSampleAes (data: Uint8Array, decryptData: any, timeOffset: number, accurateTimeOffset: boolean, chunkMeta: ChunkMetadata) : Promise { return this.demuxer!.demuxSampleAes(data, decryptData, timeOffset) .then(demuxResult => ({ - remuxResult: this.remuxer!.remux(demuxResult.audioTrack, demuxResult.avcTrack, demuxResult.id3Track, demuxResult.textTrack, timeOffset, accurateTimeOffset), - chunkMeta - }) + remuxResult: this.remuxer!.remux(demuxResult.audioTrack, demuxResult.avcTrack, demuxResult.id3Track, demuxResult.textTrack, timeOffset, accurateTimeOffset), + chunkMeta + }) ); } @@ -313,9 +313,9 @@ function getEncryptionType (data: Uint8Array, decryptData: any): string | null { } const emptyResult = (chunkMeta) : TransmuxerResult => ({ - remuxResult: {}, - chunkMeta - }); + remuxResult: {}, + chunkMeta +}); export class TransmuxConfig { public audioCodec: string; @@ -340,11 +340,11 @@ export class TransmuxState { public trackSwitch: boolean; public timeOffset: number; - constructor(discontinuity: boolean, contiguous: boolean, accurateTimeOffset: boolean, trackSwitch: boolean, timeOffset: number){ + constructor (discontinuity: boolean, contiguous: boolean, accurateTimeOffset: boolean, trackSwitch: boolean, timeOffset: number) { this.discontinuity = discontinuity; this.contiguous = contiguous; this.accurateTimeOffset = accurateTimeOffset; this.trackSwitch = trackSwitch; this.timeOffset = timeOffset; } -} \ No newline at end of file +} diff --git a/src/loader/fragment-loader.ts b/src/loader/fragment-loader.ts index 7112635a60f..adca0daf40f 100644 --- a/src/loader/fragment-loader.ts +++ b/src/loader/fragment-loader.ts @@ -2,11 +2,11 @@ import { ErrorTypes, ErrorDetails } from '../errors'; import { logger } from '../utils/logger'; import Fragment from './fragment'; import { - Loader, - LoaderConfiguration, - FragmentLoaderContext, - LoaderContext, - LoaderCallbacks + Loader, + LoaderConfiguration, + FragmentLoaderContext, + LoaderContext, + LoaderCallbacks } from '../types/loader'; const MIN_CHUNK_SIZE = Math.pow(2, 14); // 16kb @@ -65,52 +65,52 @@ export default class FragmentLoader { return; } const callbacks: LoaderCallbacks = { - onSuccess: (response, stats, context, networkDetails) => { - this._resetLoader(frag); - resolve({ - payload: response.data as ArrayBuffer, - networkDetails - }); - }, - onError: (response, context, networkDetails) => { - this._resetLoader(frag); - reject(new LoadError({ - type: ErrorTypes.NETWORK_ERROR, - details: ErrorDetails.FRAG_LOAD_ERROR, - fatal: false, - frag, - response, - networkDetails - })); - }, - onAbort: (stats, context, networkDetails) => { - this._resetLoader(frag); - reject(new LoadError({ - type: ErrorTypes.NETWORK_ERROR, - details: ErrorDetails.INTERNAL_ABORTED, - fatal: false, - frag, - networkDetails - })); - }, - onTimeout: (response, context, networkDetails) => { - this._resetLoader(frag); - reject(new LoadError({ - type: ErrorTypes.NETWORK_ERROR, - details: ErrorDetails.FRAG_LOAD_TIMEOUT, - fatal: false, - frag, - networkDetails - })); - }, - onProgress: (stats, context, data, networkDetails) => { - if (onProgress) { - onProgress({ - payload: data as ArrayBuffer, - networkDetails - }); - } + onSuccess: (response, stats, context, networkDetails) => { + this._resetLoader(frag); + resolve({ + payload: response.data as ArrayBuffer, + networkDetails + }); + }, + onError: (response, context, networkDetails) => { + this._resetLoader(frag); + reject(new LoadError({ + type: ErrorTypes.NETWORK_ERROR, + details: ErrorDetails.FRAG_LOAD_ERROR, + fatal: false, + frag, + response, + networkDetails + })); + }, + onAbort: (stats, context, networkDetails) => { + this._resetLoader(frag); + reject(new LoadError({ + type: ErrorTypes.NETWORK_ERROR, + details: ErrorDetails.INTERNAL_ABORTED, + fatal: false, + frag, + networkDetails + })); + }, + onTimeout: (response, context, networkDetails) => { + this._resetLoader(frag); + reject(new LoadError({ + type: ErrorTypes.NETWORK_ERROR, + details: ErrorDetails.FRAG_LOAD_TIMEOUT, + fatal: false, + frag, + networkDetails + })); + }, + onProgress: (stats, context, data, networkDetails) => { + if (onProgress) { + onProgress({ + payload: data as ArrayBuffer, + networkDetails + }); } + } }; // Assign frag stats to the loader's stats reference frag.stats = loader.stats; diff --git a/src/loader/load-stats.ts b/src/loader/load-stats.ts index e096984ecf4..278a4ed0359 100644 --- a/src/loader/load-stats.ts +++ b/src/loader/load-stats.ts @@ -11,4 +11,3 @@ export default class LoadStats implements LoaderStats { parsing: HlsPerformanceTiming = { start: 0, end: 0 }; buffering: HlsProgressivePerformanceTiming = { start: 0, first: 0, end: 0 }; } - diff --git a/src/performance/performance-monitor.ts b/src/performance/performance-monitor.ts index 421f3e23fa2..25092ac2524 100644 --- a/src/performance/performance-monitor.ts +++ b/src/performance/performance-monitor.ts @@ -23,7 +23,6 @@ function logFragStats (frag: Fragment) { const tParse = stats.parsing.end - stats.parsing.start; const tTotal = stats.buffering.end - stats.loading.start; - logger.log(`[performance-monitor]: Stats for fragment ${frag.sn} of level ${frag.level}: Size: ${((stats.total / 1024)).toFixed(3)} kB Chunk Count: ${stats.chunkCount} @@ -40,4 +39,4 @@ function logFragStats (frag: Fragment) { Parse Duration: ${(tParse).toFixed(3)} ms Buffer Duration: ${(tBuffer).toFixed(3)} ms End-To-End Duration: ${(tTotal).toFixed(3)} ms`); -} \ No newline at end of file +} diff --git a/src/polyfills/runtime-polyfills.ts b/src/polyfills/runtime-polyfills.ts index 9e360f05d3c..03ecd46b874 100644 --- a/src/polyfills/runtime-polyfills.ts +++ b/src/polyfills/runtime-polyfills.ts @@ -1,4 +1,5 @@ if (!Uint8Array.prototype.slice) { + // eslint-disable-next-line Object.defineProperty(Uint8Array.prototype, 'slice', { value: function (begin, end) { return new Uint8Array(Array.prototype.slice.call(this, begin, end)); diff --git a/src/remux/mp4-remuxer.ts b/src/remux/mp4-remuxer.ts index 2c64004985f..6c065a1b2cc 100644 --- a/src/remux/mp4-remuxer.ts +++ b/src/remux/mp4-remuxer.ts @@ -139,7 +139,7 @@ export default class MP4Remuxer implements Remuxer { } generateIS (audioTrack: DemuxedAudioTrack, videoTrack: DemuxedAvcTrack, timeOffset) : InitSegmentData | undefined { - logger.log(`[mp4-remuxer]: generateIS`, Object.assign({}, audioTrack), Object.assign({}, videoTrack), timeOffset); + logger.log('[mp4-remuxer]: generateIS', Object.assign({}, audioTrack), Object.assign({}, videoTrack), timeOffset); const audioSamples = audioTrack.samples; const videoSamples = videoTrack.samples; const typeSupported = this.typeSupported; @@ -593,7 +593,7 @@ export default class MP4Remuxer implements Remuxer { if (mdatSize > 0) { /* concatenate the audio data and construct the mdat in place (need 8 more bytes to fill length and mdat type) */ - mdatSize += offset; + mdatSize += offset; try { mdat = new Uint8Array(mdatSize); } catch (err) { @@ -790,7 +790,6 @@ function dropSamplesUntilKeyframe (track: DemuxedTrack) : number { return dropIndex; } - class Mp4Sample { public size: number; public duration: number; @@ -815,6 +814,6 @@ class Mp4SampleFlags { constructor (isKeyframe) { this.dependsOn = isKeyframe ? 2 : 1; - this.isNonSync = isKeyframe ? 0 : 1 + this.isNonSync = isKeyframe ? 0 : 1; } -} \ No newline at end of file +} diff --git a/src/remux/passthrough-remuxer.ts b/src/remux/passthrough-remuxer.ts index ab557b19012..c4685aad049 100644 --- a/src/remux/passthrough-remuxer.ts +++ b/src/remux/passthrough-remuxer.ts @@ -73,7 +73,7 @@ class PassThroughRemuxer implements Remuxer { // TODO: utilize accurateTimeOffset remux (audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset): RemuxerResult { let { initPTS, lastEndDTS } = this; - const result: RemuxerResult = { + const result: RemuxerResult = { audio: undefined, video: undefined, text: textTrack, @@ -98,8 +98,8 @@ class PassThroughRemuxer implements Remuxer { const initSegment: InitSegmentData = {}; let initData = this.initData; if (!initData || !initData.length) { - this.generateInitSegment(data); - initData = this.initData; + this.generateInitSegment(data); + initData = this.initData; } if (!initData.length) { // We can't remux if the initSegment could not be generated @@ -107,12 +107,12 @@ class PassThroughRemuxer implements Remuxer { return result; } if (this.emitInitSegment) { - initSegment.tracks = this.initTracks; - this.emitInitSegment = false; + initSegment.tracks = this.initTracks; + this.emitInitSegment = false; } if (!Number.isFinite(initPTS as number)) { - this.initPTS = initSegment.initPTS = initPTS = computeInitPTS(initData, data, timeOffset); + this.initPTS = initSegment.initPTS = initPTS = computeInitPTS(initData, data, timeOffset); } const duration = getDuration(data, initData); @@ -136,16 +136,16 @@ class PassThroughRemuxer implements Remuxer { } const track: RemuxedTrack = { - data1: data, - startPTS: startDTS, - startDTS, - endPTS: endDTS, - endDTS, - type, - hasAudio, - hasVideo, - nb: 1, - dropped: 0 + data1: data, + startPTS: startDTS, + startDTS, + endPTS: endDTS, + endDTS, + type, + hasAudio, + hasVideo, + nb: 1, + dropped: 0 }; result.audio = track.type === 'audio' ? track : undefined; diff --git a/src/task-loop.ts b/src/task-loop.ts index a254f771e9d..8a64fc4e941 100644 --- a/src/task-loop.ts +++ b/src/task-loop.ts @@ -125,4 +125,4 @@ export default class TaskLoop extends EventHandler { * @abstract */ protected doTick (): void {} -} \ No newline at end of file +} diff --git a/src/types/buffer.ts b/src/types/buffer.ts index b1a1dc28f56..31678fc0620 100644 --- a/src/types/buffer.ts +++ b/src/types/buffer.ts @@ -25,7 +25,7 @@ export interface SourceBufferListener { listener: EventListener } -export type BufferedUtilArray = Array<{ start: number, end: number }> +export type BufferedUtilArray = Array<{ start: number, end: number }>; export interface BufferUtilInfo { len: number, diff --git a/src/types/fragment-tracker.ts b/src/types/fragment-tracker.ts index 360b2f718ae..e612d63be1e 100644 --- a/src/types/fragment-tracker.ts +++ b/src/types/fragment-tracker.ts @@ -15,4 +15,4 @@ export interface FragmentTimeRange { export interface FragmentBufferedRange { time: Array partial: boolean -} \ No newline at end of file +} diff --git a/src/types/general.ts b/src/types/general.ts index 4ac3116ed59..cdf597843c0 100644 --- a/src/types/general.ts +++ b/src/types/general.ts @@ -1 +1 @@ -export interface GenericObjectType { [key: string]: any; }; +export interface GenericObjectType { [key: string]: any; } diff --git a/src/types/transmuxer.ts b/src/types/transmuxer.ts index 7c6b6fc83f3..61766186da7 100644 --- a/src/types/transmuxer.ts +++ b/src/types/transmuxer.ts @@ -14,16 +14,16 @@ export class ChunkMetadata { public size: number; public transmuxing: HlsChunkPerformanceTiming = { start: 0, executeStart: 0, executeEnd: 0, end: 0 }; - public buffering: { [key in SourceBufferName]: HlsChunkPerformanceTiming } = { - audio: { start: 0, executeStart: 0, executeEnd: 0, end: 0 }, - video: { start: 0, executeStart: 0, executeEnd: 0, end: 0 }, - audiovideo: { start: 0, executeStart: 0, executeEnd: 0, end: 0 } + public buffering: { [key in SourceBufferName]: HlsChunkPerformanceTiming } = { + audio: { start: 0, executeStart: 0, executeEnd: 0, end: 0 }, + video: { start: 0, executeStart: 0, executeEnd: 0, end: 0 }, + audiovideo: { start: 0, executeStart: 0, executeEnd: 0, end: 0 } }; constructor (level, sn, id, size = 0) { - this.level = level; - this.sn = sn; - this.id = id; - this.size = size; + this.level = level; + this.sn = sn; + this.id = id; + this.size = size; } -} \ No newline at end of file +} diff --git a/src/utils/chunker.ts b/src/utils/chunker.ts index 9e391e8d92c..c1426f6c673 100644 --- a/src/utils/chunker.ts +++ b/src/utils/chunker.ts @@ -38,4 +38,4 @@ export default class Chunker { return result; } -} \ No newline at end of file +} diff --git a/src/utils/fetch-loader.ts b/src/utils/fetch-loader.ts index b7d13c78398..09081bab740 100644 --- a/src/utils/fetch-loader.ts +++ b/src/utils/fetch-loader.ts @@ -12,13 +12,13 @@ import ChunkCache from '../demux/chunk-cache'; const { fetch, AbortController, ReadableStream, Request, Headers, performance } = window as any; export function fetchSupported () { - if (fetch && AbortController && ReadableStream && Request) { - try { - new ReadableStream({}); // eslint-disable-line no-new - return true; - } catch (e) { /* noop */ } - } - return false; + if (fetch && AbortController && ReadableStream && Request) { + try { + new ReadableStream({}); // eslint-disable-line no-new + return true; + } catch (e) { /* noop */ } + } + return false; } class @@ -44,8 +44,8 @@ FetchLoader implements Loader { } abortInternal (): void { - this.stats.aborted = true; - this.controller.abort(); + this.stats.aborted = true; + this.controller.abort(); } abort (): void { @@ -114,11 +114,11 @@ FetchLoader implements Loader { }); } - getResponseHeader(name: string): string | null { + getResponseHeader (name: string): string | null { if (this.response) { try { return this.response.headers.get(name); - } catch (error) {/* Could not get header */} + } catch (error) { /* Could not get header */ } } return null; } @@ -155,7 +155,7 @@ FetchLoader implements Loader { } } pump(); - }).catch(() => {/* aborted */}); + }).catch(() => { /* aborted */ }); }; pump(); @@ -167,7 +167,7 @@ function getRequestParameters (context: LoaderContext, signal): any { method: 'GET', mode: 'cors', credentials: 'same-origin', - signal, + signal }; if (context.rangeEnd) { diff --git a/src/utils/mp4-tools.ts b/src/utils/mp4-tools.ts index 597ed2f5335..80a1dafc55e 100644 --- a/src/utils/mp4-tools.ts +++ b/src/utils/mp4-tools.ts @@ -449,9 +449,9 @@ export interface SegmentedRange { } export function appendUint8Array (data1: Uint8Array, data2: Uint8Array) : Uint8Array { - const temp = new Uint8Array(data1.length + data2.length); - temp.set(data1); - temp.set(data2, data1.length); + const temp = new Uint8Array(data1.length + data2.length); + temp.set(data1); + temp.set(data2, data1.length); - return temp; + return temp; } diff --git a/src/utils/xhr-loader.ts b/src/utils/xhr-loader.ts index e3fa3bff01d..05022ca052f 100644 --- a/src/utils/xhr-loader.ts +++ b/src/utils/xhr-loader.ts @@ -30,7 +30,7 @@ class XhrLoader implements Loader { this.stats.aborted = true; let loader = this.loader; if (loader && loader.readyState !== 4) { - loader.abort(); + loader.abort(); } window.clearTimeout(this.requestTimeout); this.requestTimeout = -1; @@ -169,13 +169,13 @@ class XhrLoader implements Loader { this.callbacks.onTimeout(this.stats, this.context, this.loader); } - getResponseHeader(name: string): string | null { - if (this.loader) { - try { - return this.loader.getResponseHeader(name); - } catch (error) {/* Could not get headers */} - } - return null; + getResponseHeader (name: string): string | null { + if (this.loader) { + try { + return this.loader.getResponseHeader(name); + } catch (error) { /* Could not get headers */ } + } + return null; } } diff --git a/tests/unit/controller/buffer-controller-operations.ts b/tests/unit/controller/buffer-controller-operations.ts index aa9eebae865..4f5f9db8374 100644 --- a/tests/unit/controller/buffer-controller-operations.ts +++ b/tests/unit/controller/buffer-controller-operations.ts @@ -29,12 +29,11 @@ class MockSourceBuffer extends EventTarget { public appendBuffer = sandbox.stub(); public remove = sandbox.stub(); - - public buffered = { - start() { + public buffered = { + start () { return this._start; }, - end() { + end () { return this._end; }, length: 1, @@ -107,7 +106,7 @@ describe('BufferController SourceBuffer operation queueing', function () { currentQueue.push(currentOperation, nextOperation); bufferController.sourceBuffer[name].dispatchEvent(new Event('updateend')); expect(currentOnComplete, 'onComplete should have been called on the current operation').to.have.callCount(i + 1); - expect(shiftAndExecuteNextSpy, `The queue should have been cycled`).to.have.callCount(i + 1); + expect(shiftAndExecuteNextSpy, 'The queue should have been cycled').to.have.callCount(i + 1); }); }); @@ -128,7 +127,7 @@ describe('BufferController SourceBuffer operation queueing', function () { expect(onError, 'onError should be called with the error event').to.have.been.calledWith(errorEvent); expect(triggerSpy, 'ERROR should have been triggered in response to the SourceBuffer error') .to.have.been.calledWith(Events.ERROR, { type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.BUFFER_APPENDING_ERROR, fatal: false }); - expect(shiftAndExecuteNextSpy, `The queue should not have been cycled`).to.have.not.been.called; + expect(shiftAndExecuteNextSpy, 'The queue should not have been cycled').to.have.not.been.called; }); }); @@ -150,14 +149,14 @@ describe('BufferController SourceBuffer operation queueing', function () { }; bufferController.onBufferAppending(data); - expect(queueAppendSpy, `The append operation should have been enqueued`).to.have.callCount(i + 1); + expect(queueAppendSpy, 'The append operation should have been enqueued').to.have.callCount(i + 1); buffer.dispatchEvent(new Event('updateend')); expect(buffer.ended, `The ${name} buffer should not be marked as true if an append occurred`).to.be.false; - expect(buffer.appendBuffer, `appendBuffer should have been called with the remuxed data`).to.have.been.calledWith(segmentData); - expect(triggerSpy, `BUFFER_APPENDED should be triggered upon completion of the operation`) + expect(buffer.appendBuffer, 'appendBuffer should have been called with the remuxed data').to.have.been.calledWith(segmentData); + expect(triggerSpy, 'BUFFER_APPENDED should be triggered upon completion of the operation') .to.have.been.calledWith(Events.BUFFER_APPENDED, { parent: 'main', timeRanges: { audio: buffers['audio'].buffered, video: buffers['video'].buffered }, chunkMeta }); - expect(shiftAndExecuteNextSpy, `The queue should have been cycled`).to.have.callCount(i + 1); + expect(shiftAndExecuteNextSpy, 'The queue should have been cycled').to.have.callCount(i + 1); }); }); @@ -172,10 +171,10 @@ describe('BufferController SourceBuffer operation queueing', function () { chunkMeta: new ChunkMetadata(0, 0, 0, 0) }); - expect(queueAppendSpy, `The append operation should have been enqueued`).to.have.callCount(i + 1); - expect(shiftAndExecuteNextSpy, `The queue should have been cycled`).to.have.callCount(i + 1); + expect(queueAppendSpy, 'The append operation should have been enqueued').to.have.callCount(i + 1); + expect(shiftAndExecuteNextSpy, 'The queue should have been cycled').to.have.callCount(i + 1); }); - expect(triggerSpy, `No event should have been triggered`).to.have.not.been.called; + expect(triggerSpy, 'No event should have been triggered').to.have.not.been.called; }); }); @@ -202,16 +201,16 @@ describe('BufferController SourceBuffer operation queueing', function () { resolve(); }); }) - .then(() => { - expect(shiftAndExecuteNextSpy, `The queues should have been cycled`).to.have.been.calledTwice; - }); + .then(() => { + expect(shiftAndExecuteNextSpy, 'The queues should have been cycled').to.have.been.calledTwice; + }); }); }); describe('onBufferFlushing', function () { let queueAppendSpy; beforeEach(function () { - queueAppendSpy = sandbox.spy(operationQueue, 'append'); + queueAppendSpy = sandbox.spy(operationQueue, 'append'); queueNames.forEach(name => { const sb = bufferController.sourceBuffer[name]; sb.setBuffered(0, 10); @@ -224,16 +223,16 @@ describe('BufferController SourceBuffer operation queueing', function () { endOffset: 10 }); - expect(queueAppendSpy, `A remove operation should have been appended to each queue`).to.have.been.calledTwice; + expect(queueAppendSpy, 'A remove operation should have been appended to each queue').to.have.been.calledTwice; queueNames.forEach((name, i) => { const buffer = bufferController.sourceBuffer[name]; expect(buffer.remove, `Remove should have been called once on the ${name} SourceBuffer`).to.have.been.calledOnce; - expect(buffer.remove, `Remove should have been called with the expected range`).to.have.been.calledWith(0, 10); + expect(buffer.remove, 'Remove should have been called with the expected range').to.have.been.calledWith(0, 10); buffer.dispatchEvent(new Event('updateend')); - expect(triggerSpy, `The BUFFER_FLUSHED event should be called once per buffer`).to.have.callCount(i + 1); - expect(triggerSpy, `BUFFER_FLUSHED should be the only event fired`).to.have.been.calledWith(Events.BUFFER_FLUSHED); - expect(shiftAndExecuteNextSpy, `The queue should have been cycled`).to.have.callCount(i + 1); + expect(triggerSpy, 'The BUFFER_FLUSHED event should be called once per buffer').to.have.callCount(i + 1); + expect(triggerSpy, 'BUFFER_FLUSHED should be the only event fired').to.have.been.calledWith(Events.BUFFER_FLUSHED); + expect(shiftAndExecuteNextSpy, 'The queue should have been cycled').to.have.callCount(i + 1); }); }); @@ -244,8 +243,8 @@ describe('BufferController SourceBuffer operation queueing', function () { endOffset: Infinity }); - expect(queueAppendSpy, `Two remove operations should have been appended`).to.have.been.calledTwice; - expect(shiftAndExecuteNextSpy, `The queues should have been cycled`).to.have.callCount(2); + expect(queueAppendSpy, 'Two remove operations should have been appended').to.have.been.calledTwice; + expect(shiftAndExecuteNextSpy, 'The queues should have been cycled').to.have.callCount(2); }); it('dequeues the remove operation if the requested remove range is not valid', function () { @@ -255,13 +254,13 @@ describe('BufferController SourceBuffer operation queueing', function () { endOffset: 9000 }); - expect(queueAppendSpy, `Four remove operations should have been appended`).to.have.callCount(2); - expect(shiftAndExecuteNextSpy, `The queues should have been cycled`).to.have.callCount(2); + expect(queueAppendSpy, 'Four remove operations should have been appended').to.have.callCount(2); + expect(shiftAndExecuteNextSpy, 'The queues should have been cycled').to.have.callCount(2); queueNames.forEach(name => { const buffer = bufferController.sourceBuffer[name]; expect(buffer.remove, `Remove should not have been called on the ${name} buffer`).to.have.not.been.called; }); - expect(triggerSpy, `No event should have been triggered`).to.have.not.been.called; + expect(triggerSpy, 'No event should have been triggered').to.have.not.been.called; }); }); @@ -282,13 +281,13 @@ describe('BufferController SourceBuffer operation queueing', function () { it('exits early if no media is defined', function () { delete bufferController.media; bufferController.flushLiveBackBuffer(); - expect(bufferFlushingSpy, `onBufferFlushing should not have been called`).to.have.not.been.called; + expect(bufferFlushingSpy, 'onBufferFlushing should not have been called').to.have.not.been.called; }); it('exits early if the stream is not live', function () { bufferController._live = false; bufferController.flushLiveBackBuffer(); - expect(bufferFlushingSpy, `onBufferFlushing should not have been called`).to.have.not.been.called; + expect(bufferFlushingSpy, 'onBufferFlushing should not have been called').to.have.not.been.called; }); it('exits early if the liveBackBufferLength config is not a finite number, or less than 0', function () { @@ -299,7 +298,7 @@ describe('BufferController SourceBuffer operation queueing', function () { hls.config.liveBackBufferLength = Infinity; bufferController.flushLiveBackBuffer(); - expect(bufferFlushingSpy, `onBufferFlushing should not have been called`).to.have.not.been.called; + expect(bufferFlushingSpy, 'onBufferFlushing should not have been called').to.have.not.been.called; }); it('should execute a remove operation if flushing a valid backBuffer range', function () { @@ -326,10 +325,9 @@ describe('BufferController SourceBuffer operation queueing', function () { buffer.setBuffered(10, 30); }); bufferController.flushLiveBackBuffer(); - expect(bufferFlushingSpy, `onBufferFlushing should not have been called`).to.have.not.been.called; + expect(bufferFlushingSpy, 'onBufferFlushing should not have been called').to.have.not.been.called; }); - it('does not remove if the buffer does not exist', function () { queueNames.forEach(name => { const buffer = bufferController.sourceBuffer[name]; @@ -340,7 +338,7 @@ describe('BufferController SourceBuffer operation queueing', function () { bufferController.sourceBuffer = {}; bufferController.flushLiveBackBuffer(); - expect(bufferFlushingSpy, `onBufferFlushing should not have been called`).to.have.not.been.called; + expect(bufferFlushingSpy, 'onBufferFlushing should not have been called').to.have.not.been.called; }); }); @@ -368,7 +366,7 @@ describe('BufferController SourceBuffer operation queueing', function () { it('updates class properties based on level data', function () { bufferController.onLevelUpdated(data); expect(bufferController._levelTargetDuration, '_levelTargetDuration').to.equal(6); - expect(bufferController._live, `_live`).to.be.true; + expect(bufferController._live, '_live').to.be.true; // It prefers averagetargetduration, but falls back to targetduration delete data.details.averagetargetduration; @@ -411,4 +409,3 @@ describe('BufferController SourceBuffer operation queueing', function () { }); }); }); - diff --git a/tests/unit/controller/buffer-controller.js b/tests/unit/controller/buffer-controller.js index 882b0cdb56b..c5f3aca4e90 100644 --- a/tests/unit/controller/buffer-controller.js +++ b/tests/unit/controller/buffer-controller.js @@ -31,102 +31,102 @@ describe('BufferController tests', function () { }); }); - describe('Live back buffer enforcement', function () { - let mockMedia; - let mockSourceBuffer; - let bufStart; - - beforeEach(function () { - bufStart = 0; - bufferController._levelTargetDuration = 10; - bufferController.media = mockMedia = { - currentTime: 0 - }; - bufferController.sourceBuffer = mockSourceBuffer = { - video: { - buffered: { - start () { - return bufStart; - }, - length: 1 - } - } - }; - bufferController._live = true; - hls.config.liveBackBufferLength = 10; - }); - - it('exits early if not live', function () { - bufferController.flushLiveBackBuffer(); - expect(removeStub).to.not.have.been.called; - }); - - it('exits early if liveBackBufferLength is not a finite number, or is less than 0', function () { - hls.config.liveBackBufferLength = 'foo'; - bufferController.flushLiveBackBuffer(); - - hls.config.liveBackBufferLength = -1; - bufferController.flushLiveBackBuffer(); - - expect(removeStub).to.not.have.been.called; - }); - - it('does not flush if nothing is buffered', function () { - delete mockSourceBuffer.buffered; - bufferController.flushLiveBackBuffer(); - - mockSourceBuffer = null; - bufferController.flushLiveBackBuffer(); - - expect(removeStub).to.not.have.been.called; - }); - - it('does not flush if no buffered range intersects with back buffer limit', function () { - bufStart = 5; - mockMedia.currentTime = 10; - bufferController.flushLiveBackBuffer(); - expect(removeStub).to.not.have.been.called; - }); - - it('does not flush if the liveBackBufferLength is Infinity', function () { - hls.config.liveBackBufferLength = Infinity; - mockMedia.currentTime = 15; - bufferController.flushLiveBackBuffer(); - expect(removeStub).to.not.have.been.called; - }); - - it('flushes up to the back buffer limit if the buffer intersects with that point', function () { - mockMedia.currentTime = 15; - bufferController.flushLiveBackBuffer(); - expect(removeStub).to.have.been.calledOnce; - expect(bufferController.flushBufferCounter).to.equal(0); - expect(removeStub).to.have.been.calledWith('video', mockSourceBuffer.video, 0, 5); - }); - - it('flushes to a max of one targetDuration from currentTime, regardless of liveBackBufferLength', function () { - mockMedia.currentTime = 15; - bufferController._levelTargetDuration = 5; - hls.config.liveBackBufferLength = 0; - bufferController.flushLiveBackBuffer(); - expect(removeStub).to.have.been.calledWith('video', mockSourceBuffer.video, 0, 10); - }); - - it('should trigger clean back buffer when there are no pending appends', function () { - bufferController.parent = {}; - bufferController.segments = [{ parent: bufferController.parent }]; - - sandbox.stub(bufferController, 'doAppending'); - - bufferController._onSBUpdateEnd(); - - expect(flushSpy).to.not.have.been.called; - - bufferController.segments = []; - bufferController._onSBUpdateEnd(); - - expect(flushSpy).to.have.been.calledOnce; - }); - }); + // describe('Live back buffer enforcement', function () { + // let mockMedia; + // let mockSourceBuffer; + // let bufStart; + // + // beforeEach(function () { + // bufStart = 0; + // bufferController._levelTargetDuration = 10; + // bufferController.media = mockMedia = { + // currentTime: 0 + // }; + // bufferController.sourceBuffer = mockSourceBuffer = { + // video: { + // buffered: { + // start () { + // return bufStart; + // }, + // length: 1 + // } + // } + // }; + // bufferController._live = true; + // hls.config.liveBackBufferLength = 10; + // }); + // + // it('exits early if not live', function () { + // bufferController.flushLiveBackBuffer(); + // expect(removeStub).to.not.have.been.called; + // }); + // + // it('exits early if liveBackBufferLength is not a finite number, or is less than 0', function () { + // hls.config.liveBackBufferLength = 'foo'; + // bufferController.flushLiveBackBuffer(); + // + // hls.config.liveBackBufferLength = -1; + // bufferController.flushLiveBackBuffer(); + // + // expect(removeStub).to.not.have.been.called; + // }); + // + // it('does not flush if nothing is buffered', function () { + // delete mockSourceBuffer.buffered; + // bufferController.flushLiveBackBuffer(); + // + // mockSourceBuffer = null; + // bufferController.flushLiveBackBuffer(); + // + // expect(removeStub).to.not.have.been.called; + // }); + // + // it('does not flush if no buffered range intersects with back buffer limit', function () { + // bufStart = 5; + // mockMedia.currentTime = 10; + // bufferController.flushLiveBackBuffer(); + // expect(removeStub).to.not.have.been.called; + // }); + // + // it('does not flush if the liveBackBufferLength is Infinity', function () { + // hls.config.liveBackBufferLength = Infinity; + // mockMedia.currentTime = 15; + // bufferController.flushLiveBackBuffer(); + // expect(removeStub).to.not.have.been.called; + // }); + // + // it('flushes up to the back buffer limit if the buffer intersects with that point', function () { + // mockMedia.currentTime = 15; + // bufferController.flushLiveBackBuffer(); + // expect(removeStub).to.have.been.calledOnce; + // expect(bufferController.flushBufferCounter).to.equal(0); + // expect(removeStub).to.have.been.calledWith('video', mockSourceBuffer.video, 0, 5); + // }); + // + // it('flushes to a max of one targetDuration from currentTime, regardless of liveBackBufferLength', function () { + // mockMedia.currentTime = 15; + // bufferController._levelTargetDuration = 5; + // hls.config.liveBackBufferLength = 0; + // bufferController.flushLiveBackBuffer(); + // expect(removeStub).to.have.been.calledWith('video', mockSourceBuffer.video, 0, 10); + // }); + // + // it('should trigger clean back buffer when there are no pending appends', function () { + // bufferController.parent = {}; + // bufferController.segments = [{ parent: bufferController.parent }]; + // + // sandbox.stub(bufferController, 'doAppending'); + // + // bufferController._onSBUpdateEnd(); + // + // expect(flushSpy).to.not.have.been.called; + // + // bufferController.segments = []; + // bufferController._onSBUpdateEnd(); + // + // expect(flushSpy).to.have.been.calledOnce; + // }); + // }); describe('sourcebuffer creation', function () { let createSbStub; diff --git a/tests/unit/controller/buffer-operation-queue.ts b/tests/unit/controller/buffer-operation-queue.ts index 92d37dd3466..5a61ee931fe 100644 --- a/tests/unit/controller/buffer-operation-queue.ts +++ b/tests/unit/controller/buffer-operation-queue.ts @@ -35,21 +35,21 @@ describe('BufferOperationQueue tests', function () { }); describe('append', function () { - it('appends and executes if the queue is empty', function () { - const execute = sandbox.spy(); - const operation: BufferOperation = { - execute, - onComplete: () => {}, - onError: () => {} - }; + it('appends and executes if the queue is empty', function () { + const execute = sandbox.spy(); + const operation: BufferOperation = { + execute, + onComplete: () => {}, + onError: () => {} + }; - queueNames.forEach((name, i) => { - operationQueue.append(operation, name); - expect(execute, `The ${name} queue operation should have been executed`).to.have.callCount(i + 1); - expect(operationQueue.queues[name], `The ${name} queue should have a length of 1`).to.have.length(1); + queueNames.forEach((name, i) => { + operationQueue.append(operation, name); + expect(execute, `The ${name} queue operation should have been executed`).to.have.callCount(i + 1); + expect(operationQueue.queues[name], `The ${name} queue should have a length of 1`).to.have.length(1); + }); }); }); -}); it('appends but does not execute if the queue has at least one operation enqueued', function () { queueNames.forEach((name) => { @@ -93,7 +93,7 @@ describe('BufferOperationQueue tests', function () { it('should execute the onError callback and shift the operation if it throws an unhandled exception', function () { const onError = sandbox.spy(); - const error = new Error; + const error = new Error(); const operation: BufferOperation = { execute: () => { throw error; @@ -129,4 +129,4 @@ describe('BufferOperationQueue tests', function () { }); }); }); -}); \ No newline at end of file +});