From a03bb8a7217e86e819f8d665981b7feae83d3617 Mon Sep 17 00:00:00 2001 From: Daniel Silhavy Date: Mon, 12 Aug 2024 14:18:36 +0200 Subject: [PATCH] Fix/#4212 (#4544) * WiP: Use previous bitrate for multiperiod transitions * Use the bitrate of the previous period for preloading the new period * Add bitrate selection logic based on previous Representation for cases in which the upcoming periods are not preloaded * Add flag to disable search engine selection popup in Chrome for functional tests * Rename variable in index.d.ts --- index.d.ts | 15 ++- src/streaming/Stream.js | 60 +++++----- src/streaming/StreamProcessor.js | 104 +++++++++++------- src/streaming/controllers/AbrController.js | 6 +- src/streaming/controllers/StreamController.js | 65 ++++++----- src/streaming/models/CmcdModel.js | 2 +- .../config/test-configurations/local.json | 3 +- test/unit/mocks/StreamMock.js | 2 +- test/unit/test/streaming/streaming.Stream.js | 4 +- 9 files changed, 156 insertions(+), 105 deletions(-) diff --git a/index.d.ts b/index.d.ts index e56083fb48..7b3857eabf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,4 +1,9 @@ -import { CommonMediaRequest, CommonMediaResponse, RequestInterceptor, ResponseInterceptor } from '@svta/common-media-library/request' +import { + CommonMediaRequest, + CommonMediaResponse, + RequestInterceptor, + ResponseInterceptor +} from '@svta/common-media-library/request' export = dashjs; export as namespace dashjs; @@ -4562,7 +4567,7 @@ declare namespace dashjs { getHasVideoTrack(): boolean; - startPreloading(mediaSource: MediaSource, previousBuffers: any[]): void; + startPreloading(mediaSource: MediaSource, previousBuffers: any[], representationsFromPreviousPeriod: Representation[]): void; getThumbnailController(): object; @@ -4570,7 +4575,7 @@ declare namespace dashjs { reset(): void; - getProcessors(): any[]; + getStreamProcessors(): any[]; setMediaSource(mediaSource: MediaSource): void; @@ -4588,8 +4593,6 @@ declare namespace dashjs { getHasFinishedBuffering(): boolean - setPreloaded(value: boolean): void - startScheduleControllers(): void prepareTrackChange(e: object): void @@ -4626,7 +4629,7 @@ declare namespace dashjs { getStreamInfo(): StreamInfo; - selectMediaInfo(newMediaInfo: MediaInfo): Promise; + selectMediaInfo(selectionInput: object): Promise; clearMediaInfoArray(): void; diff --git a/src/streaming/Stream.js b/src/streaming/Stream.js index aa0232e721..dddeb9165d 100644 --- a/src/streaming/Stream.js +++ b/src/streaming/Stream.js @@ -189,9 +189,10 @@ function Stream(config) { * Activates Stream by re-initializing some of its components * @param {MediaSource} mediaSource * @param {array} previousBufferSinks + * @param representationsFromPreviousPeriod * @memberof Stream# */ - function activate(mediaSource, previousBufferSinks) { + function activate(mediaSource, previousBufferSinks, representationsFromPreviousPeriod = []) { return new Promise((resolve, reject) => { if (isActive) { resolve(previousBufferSinks); @@ -208,7 +209,7 @@ function Stream(config) { } - _initializeMedia(mediaSource, previousBufferSinks) + _initializeMedia(mediaSource, previousBufferSinks, representationsFromPreviousPeriod) .then((bufferSinks) => { isActive = true; eventBus.trigger(Events.STREAM_ACTIVATED, { @@ -222,7 +223,7 @@ function Stream(config) { }); } - function startPreloading(mediaSource, previousBuffers) { + function startPreloading(mediaSource, previousBuffers, representationsFromPreviousPeriod = []) { return new Promise((resolve, reject) => { if (getPreloaded()) { @@ -231,9 +232,9 @@ function Stream(config) { } logger.info(`[startPreloading] Preloading next stream with id ${getId()}`); - setPreloaded(true); + _setPreloaded(true); - _commonMediaInitialization(mediaSource, previousBuffers) + _commonMediaInitialization(mediaSource, previousBuffers, representationsFromPreviousPeriod) .then(() => { for (let i = 0; i < streamProcessors.length && streamProcessors[i]; i++) { streamProcessors[i].setExplicitBufferingTime(getStartTime()); @@ -242,7 +243,7 @@ function Stream(config) { resolve(); }) .catch(() => { - setPreloaded(false); + _setPreloaded(false); reject(); }); }); @@ -252,11 +253,12 @@ function Stream(config) { * * @param {object} mediaSource * @param {array} previousBufferSinks + * @param representationsFromPreviousPeriod * @return {Promise} * @private */ - function _initializeMedia(mediaSource, previousBufferSinks) { - return _commonMediaInitialization(mediaSource, previousBufferSinks); + function _initializeMedia(mediaSource, previousBufferSinks, representationsFromPreviousPeriod = []) { + return _commonMediaInitialization(mediaSource, previousBufferSinks, representationsFromPreviousPeriod); } /** @@ -266,7 +268,7 @@ function Stream(config) { * @return {Promise} * @private */ - function _commonMediaInitialization(mediaSource, previousBufferSinks) { + function _commonMediaInitialization(mediaSource, previousBufferSinks, representationsFromPreviousPeriod) { return new Promise((resolve, reject) => { checkConfig(); @@ -278,7 +280,10 @@ function Stream(config) { MEDIA_TYPES.forEach((mediaType) => { // If we are preloading without a video element we can not start texttrack handling. if (!(mediaType === Constants.TEXT && !mediaSource) && (mediaType !== Constants.VIDEO || (!element || (element && (/^VIDEO$/i).test(element.nodeName))))) { - promises.push(_initializeMediaForType(mediaType, mediaSource)); + const representationFromPreviousPeriod = representationsFromPreviousPeriod.find((representation) => { + return representation.mediaInfo.type === mediaType + }) + promises.push(_initializeMediaForType(mediaType, mediaSource, representationFromPreviousPeriod)); } }); @@ -315,7 +320,7 @@ function Stream(config) { */ function initializeForTextWithMediaSource(mediaSource) { return new Promise((resolve, reject) => { - _initializeMediaForType(Constants.TEXT, mediaSource) + _initializeMediaForType(Constants.TEXT, mediaSource, null) .then(() => { return createBufferSinkForText() }) @@ -335,7 +340,7 @@ function Stream(config) { * @param {object} mediaSource * @private */ - function _initializeMediaForType(type, mediaSource) { + function _initializeMediaForType(type, mediaSource, representationFromPreviousPeriod) { let allMediaForType = adapter.getAllMediaInfoForType(streamInfo, type); let embeddedMediaInfos = []; @@ -410,7 +415,11 @@ function Stream(config) { if (initialMediaInfo) { // In case of mixed fragmented and embedded text tracks, check if initial selected text track is not an embedded track - return streamProcessor.selectMediaInfo((type !== Constants.TEXT || !initialMediaInfo.isEmbedded) ? initialMediaInfo : allMediaForType[0]); + const newMediaInfo = type !== Constants.TEXT || !initialMediaInfo.isEmbedded ? initialMediaInfo : allMediaForType[0]; + return streamProcessor.selectMediaInfo({ + newMediaInfo, + previouslySelectedRepresentation: representationFromPreviousPeriod + }); } return Promise.resolve(); @@ -544,7 +553,7 @@ function Stream(config) { streamProcessors = []; isActive = false; hasFinishedBuffering = false; - setPreloaded(false); + _setPreloaded(false); setIsEndedEventSignaled(false); eventBus.trigger(Events.STREAM_DEACTIVATED, { streamInfo }); } @@ -749,10 +758,10 @@ function Stream(config) { hasFinishedBuffering = false; - let mediaInfo = e.newMediaInfo; + let newMediaInfo = e.newMediaInfo; let manifest = manifestModel.getValue(); - let processor = getProcessorForMediaInfo(mediaInfo); + let processor = getProcessorForMediaInfo(newMediaInfo); if (!processor) { return; } @@ -768,7 +777,7 @@ function Stream(config) { manifestUpdater.refreshManifest(); } } else { - processor.selectMediaInfo(mediaInfo) + processor.selectMediaInfo({ newMediaInfo }) .then(() => { processor.prepareTrackSwitch(); }); @@ -807,7 +816,7 @@ function Stream(config) { } function onBufferingCompleted() { - let processors = getProcessors(); + let processors = getStreamProcessors(); const ln = processors.length; if (ln === 0) { @@ -848,14 +857,14 @@ function Stream(config) { return null; } - let processors = getProcessors(); + let processors = getStreamProcessors(); return processors.filter(function (processor) { return (processor.getType() === type); })[0]; } - function getProcessors() { + function getStreamProcessors() { let arr = []; let type, @@ -905,7 +914,7 @@ function Stream(config) { if (allMediaForType) { for (let j = 0; j < allMediaForType.length; j++) { if (adapter.areMediaInfosEqual(currentMediaInfo, allMediaForType[j])) { - promises.push(streamProcessor.selectMediaInfo(allMediaForType[j])) + promises.push(streamProcessor.selectMediaInfo({ newMediaInfo: allMediaForType[j] })) } } } @@ -918,13 +927,13 @@ function Stream(config) { // Only relevant for MSS while (trackChangedEvents.length > 0) { let trackChangedEvent = trackChangedEvents.pop(); - let mediaInfo = trackChangedEvent.newMediaInfo; + let newMediaInfo = trackChangedEvent.newMediaInfo; let processor = getProcessorForMediaInfo(trackChangedEvent.oldMediaInfo); if (!processor) { return; } promises.push(processor.prepareTrackSwitch()); - promises.push(processor.selectMediaInfo(mediaInfo)); + promises.push(processor.selectMediaInfo({ newMediaInfo })); } return Promise.all(promises) @@ -973,7 +982,7 @@ function Stream(config) { } } - function setPreloaded(value) { + function _setPreloaded(value) { preloaded = value; } @@ -1023,13 +1032,13 @@ function Stream(config) { getIsActive, getIsEndedEventSignaled, getPreloaded, - getProcessors, getRepresentationForTypeById, getRepresentationForTypeByIndex, getRepresentationsByType, getStartTime, getStreamId, getStreamInfo, + getStreamProcessors, getThumbnailController, initialize, initializeForTextWithMediaSource, @@ -1038,7 +1047,6 @@ function Stream(config) { reset, setIsEndedEventSignaled, setMediaSource, - setPreloaded, startPreloading, startScheduleControllers, updateData, diff --git a/src/streaming/StreamProcessor.js b/src/streaming/StreamProcessor.js index 9749f315cb..b6c86c98fb 100644 --- a/src/streaming/StreamProcessor.js +++ b/src/streaming/StreamProcessor.js @@ -634,49 +634,79 @@ function StreamProcessor(config) { /** * Called once the StreamProcessor is initialized and when the track is switched. We only have one StreamProcessor per media type. So we need to adjust the mediaInfo once we switch/select a track. - * @param {object} newMediaInfo - * @param targetRepresentation + * @param {object} selectionInput */ - function selectMediaInfo(newMediaInfo, targetRepresentation = null) { + function selectMediaInfo(selectionInput) { return new Promise((resolve) => { - if (representationController) { + if (!representationController) { + return Promise.resolve(); + } - // Switching to a new AdaptationSet as part of a quality switch - if (targetRepresentation) { - currentMediaInfo = newMediaInfo; - } + let selectedValues = null; - // Switching to a new AS - else if ((currentMediaInfo === null || (!adapter.areMediaInfosEqual(currentMediaInfo, newMediaInfo)))) { - currentMediaInfo = newMediaInfo; - const bitrate = abrController.getInitialBitrateFor(type); - targetRepresentation = abrController.getOptimalRepresentationForBitrate(currentMediaInfo, bitrate, false); - } + // Switching to a new AdaptationSet as part of a quality switch + if (selectionInput.newRepresentation) { + selectedValues = _handleAdaptationSetQualitySwitch(selectionInput); + } - // MPD update quality remains the same - else { - currentMediaInfo = newMediaInfo; - targetRepresentation = representationController.getCurrentRepresentation() - } + // Switching to a new AS + else if ((currentMediaInfo === null || (!adapter.areMediaInfosEqual(currentMediaInfo, selectionInput.newMediaInfo)))) { + selectedValues = _handleAdaptationSetSwitch(selectionInput); + } - // Update Representation Controller with the new data. Note we do not filter any Representations here as the filter values might change over time. - const voRepresentations = abrController.getPossibleVoRepresentations(currentMediaInfo, false); - const representationId = targetRepresentation.id; - return representationController.updateData(voRepresentations, currentMediaInfo.isFragmented, representationId) - .then(() => { - _onDataUpdateCompleted() - resolve(); - }) - .catch((e) => { - logger.error(e); - resolve() - }) - } else { - return Promise.resolve(); + // MPD update quality remains the same + else { + selectedValues = _handleMpdUpdate(selectionInput); } + + currentMediaInfo = selectedValues.currentMediaInfo; + + // Update Representation Controller with the new data. Note we do not filter any Representations here as the filter values might change over time. + const voRepresentations = abrController.getPossibleVoRepresentations(currentMediaInfo, false); + return representationController.updateData(voRepresentations, currentMediaInfo.isFragmented, selectedValues.selectedRepresentation.id) + .then(() => { + _onDataUpdateCompleted() + resolve(); + }) + .catch((e) => { + logger.error(e); + resolve() + }) + }) } + function _handleAdaptationSetQualitySwitch(selectionInput) { + return { + selectedRepresentation: selectionInput.newRepresentation, + currentMediaInfo: selectionInput.newMediaInfo, + } + } + + function _handleAdaptationSetSwitch(selectionInput) { + let bitrateInKbit = NaN; + + // In case ABR was disabled and we got a selected Representation from the previous period we use a bitrate that is close to the one from the previous period + if (!settings.get().streaming.abr.autoSwitchBitrate[selectionInput.newMediaInfo.type] && selectionInput.previouslySelectedRepresentation) { + bitrateInKbit = selectionInput.previouslySelectedRepresentation.bitrateInKbit + } else { + bitrateInKbit = abrController.getInitialBitrateFor(type); + } + + const selectedRepresentation = abrController.getOptimalRepresentationForBitrate(selectionInput.newMediaInfo, bitrateInKbit, false); + return { + selectedRepresentation, + currentMediaInfo: selectionInput.newMediaInfo + } + } + + function _handleMpdUpdate(selectionInput) { + return { + currentMediaInfo: selectionInput.newMediaInfo, + selectedRepresentation: representationController.getCurrentRepresentation() + } + } + /** * The quality has changed which means we have switched to a different representation. * If we want to aggressively replace existing parts in the buffer we need to make sure that the new quality is higher than the already buffered one. @@ -728,7 +758,7 @@ function StreamProcessor(config) { const newMediaInfo = newRepresentation.mediaInfo; currentMediaInfo = newMediaInfo; - selectMediaInfo(newMediaInfo, newRepresentation) + selectMediaInfo({ newMediaInfo, newRepresentation }) .then(() => { _handleDifferentSwitchTypes(e, newRepresentation); }) @@ -965,12 +995,12 @@ function StreamProcessor(config) { return; } - const mInfo = mediaInfoArr.find((info) => { + const newMediaInfo = mediaInfoArr.find((info) => { return info.index === currentTrackInfo.index && info.lang === currentTrackInfo.lang; }); - if (mInfo) { - selectMediaInfo(mInfo) + if (newMediaInfo) { + selectMediaInfo({ newMediaInfo }) .then(() => { bufferController.setIsBufferingCompleted(false); setExplicitBufferingTime(playbackController.getTime()); diff --git a/src/streaming/controllers/AbrController.js b/src/streaming/controllers/AbrController.js index b9503e749f..f21f6e18f4 100644 --- a/src/streaming/controllers/AbrController.js +++ b/src/streaming/controllers/AbrController.js @@ -217,7 +217,7 @@ function AbrController() { } } - function getOptimalRepresentationForBitrate(mediaInfo, bitrate, includeCompatibleMediaInfos = true) { + function getOptimalRepresentationForBitrate(mediaInfo, bitrateInKbit, includeCompatibleMediaInfos = true) { const possibleVoRepresentations = getPossibleVoRepresentationsFilteredBySettings(mediaInfo, includeCompatibleMediaInfos); if (!possibleVoRepresentations || possibleVoRepresentations.length === 0) { @@ -228,13 +228,13 @@ function AbrController() { const smallestRepresentation = possibleVoRepresentations.reduce((a, b) => { return a.bandwidth < b.bandwidth ? a : b; }) - if (bitrate <= 0) { + if (bitrateInKbit <= 0) { return smallestRepresentation } // Get all Representations that have lower or equal bitrate than our target bitrate const targetRepresentations = possibleVoRepresentations.filter((rep) => { - return rep.bitrateInKbit <= bitrate + return rep.bitrateInKbit <= bitrateInKbit }); if (!targetRepresentations || targetRepresentations.length === 0) { diff --git a/src/streaming/controllers/StreamController.js b/src/streaming/controllers/StreamController.js index 03a73493d6..1f17814248 100644 --- a/src/streaming/controllers/StreamController.js +++ b/src/streaming/controllers/StreamController.js @@ -419,10 +419,12 @@ function StreamController() { }); let keepBuffers = false; + let representationsFromPreviousPeriod = []; activeStream = stream; if (previousStream) { keepBuffers = _canSourceBuffersBeReused(stream, previousStream); + representationsFromPreviousPeriod = _getRepresentationsFromPreviousPeriod(previousStream); previousStream.deactivate(keepBuffers); } @@ -439,9 +441,9 @@ function StreamController() { // If we have a video element we are not preloading into a virtual buffer if (videoModel.getElement()) { - _openMediaSource(seekTime, keepBuffers, false); + _openMediaSource({ seekTime, keepBuffers, streamActivated: false, representationsFromPreviousPeriod }); } else { - _activateStream(seekTime, keepBuffers); + _activateStream({ seekTime, keepBuffers }); } } catch (e) { isStreamSwitchingInProgress = false; @@ -450,12 +452,10 @@ function StreamController() { /** * Setup the Media Source. Open MSE and attach event listeners - * @param {number} seekTime - * @param {boolean} keepBuffers - * @param {boolean} streamActivated * @private + * @param inputParameters */ - function _openMediaSource(seekTime, keepBuffers, streamActivated = false) { + function _openMediaSource(inputParameters) { let sourceUrl; function _onMediaSourceOpen() { @@ -472,9 +472,9 @@ function StreamController() { _setMediaDuration(); const dvrInfo = dashMetrics.getCurrentDVRInfo(); mediaSourceController.setSeekable(dvrInfo.range.start, dvrInfo.range.end); - if (streamActivated) { - if (!isNaN(seekTime)) { - playbackController.seek(seekTime, true, true); + if (inputParameters.streamActivated) { + if (!isNaN(inputParameters.seekTime)) { + playbackController.seek(inputParameters.seekTime, true, true); } // Set the media source for all StreamProcessors activeStream.setMediaSource(mediaSource) @@ -483,7 +483,7 @@ function StreamController() { activeStream.initializeForTextWithMediaSource(mediaSource); }) } else { - _activateStream(seekTime, keepBuffers); + _activateStream(inputParameters); } } @@ -498,8 +498,8 @@ function StreamController() { mediaSource = mediaSourceController.createMediaSource(); _open(); } else { - if (keepBuffers) { - _activateStream(seekTime, keepBuffers); + if (inputParameters.keepBuffers) { + _activateStream(inputParameters); } else { mediaSourceController.detachMediaSource(videoModel); _open(); @@ -512,8 +512,9 @@ function StreamController() { * @param {number} seekTime * @param {boolean} keepBuffers */ - function _activateStream(seekTime, keepBuffers) { - activeStream.activate(mediaSource, keepBuffers ? bufferSinks : undefined, seekTime) + function _activateStream(inputParameters) { + const representationsFromPreviousPeriod = inputParameters.representationsFromPreviousPeriod || []; + activeStream.activate(mediaSource, inputParameters.keepBuffers ? bufferSinks : undefined, representationsFromPreviousPeriod) .then((sinks) => { // check if change type is supported by the browser if (sinks) { @@ -525,9 +526,9 @@ function StreamController() { } // Set the initial time for this stream in the StreamProcessor - if (!isNaN(seekTime)) { - eventBus.trigger(Events.SEEK_TARGET, { time: seekTime }, { streamId: activeStream.getId() }); - playbackController.seek(seekTime, false, true); + if (!isNaN(inputParameters.seekTime)) { + eventBus.trigger(Events.SEEK_TARGET, { time: inputParameters.seekTime }, { streamId: activeStream.getId() }); + playbackController.seek(inputParameters.seekTime, false, true); activeStream.startScheduleControllers(); } @@ -536,6 +537,13 @@ function StreamController() { }); } + function _getRepresentationsFromPreviousPeriod(previousStream) { + const previousStreamProcessors = previousStream ? previousStream.getStreamProcessors() : []; + return previousStreamProcessors.map((streamProcessor) => { + return streamProcessor.getRepresentation(); + }) + } + /** * A playback seeking event was triggered. We need to disable the preloading streams and call the respective seeking handler. * We distinguish between inner period seeks and outer period seeks @@ -594,7 +602,7 @@ function StreamController() { * @private */ function _handleInnerPeriodSeek(e) { - const streamProcessors = activeStream.getProcessors(); + const streamProcessors = activeStream.getStreamProcessors(); streamProcessors.forEach((sp) => { return sp.prepareInnerPeriodPlaybackSeeking(e); @@ -612,7 +620,7 @@ function StreamController() { function _handleOuterPeriodSeek(e, seekToStream) { // Stop segment requests const seekTime = e && !isNaN(e.seekTime) ? e.seekTime : NaN; - const streamProcessors = activeStream.getProcessors(); + const streamProcessors = activeStream.getStreamProcessors(); const promises = streamProcessors.map((sp) => { // Cancel everything in case the active stream is still buffering @@ -634,7 +642,7 @@ function StreamController() { * @private */ function _onCurrentTrackChanged(e) { - // Track was changed in non active stream. No need to do anything, this only happens when a stream starts preloading + // Track was changed in non-active stream. No need to do anything, this only happens when a stream starts preloading if (e.newMediaInfo.streamInfo.id !== activeStream.getId()) { return; } @@ -643,9 +651,9 @@ function StreamController() { _deactivateAllPreloadingStreams(); if (settings.get().streaming.buffer.resetSourceBuffersForTrackSwitch && e.oldMediaInfo && e.oldMediaInfo.codec !== e.newMediaInfo.codec) { - const time = playbackController.getTime(); + const seekTime = playbackController.getTime(); activeStream.deactivate(false); - _openMediaSource(time, false, false); + _openMediaSource({ seekTime, keepBuffers: false, streamActivated: false }); return; } @@ -684,7 +692,8 @@ function StreamController() { let seamlessPeriodSwitch = _canSourceBuffersBeReused(nextStream, previousStream); if (seamlessPeriodSwitch) { - nextStream.startPreloading(mediaSource, bufferSinks) + const representationsFromPreviousPeriod = _getRepresentationsFromPreviousPeriod(previousStream); + nextStream.startPreloading(mediaSource, bufferSinks, representationsFromPreviousPeriod) .then(() => { preloadingStreams.push(nextStream); }); @@ -957,7 +966,7 @@ function StreamController() { * @return {array} */ function getActiveStreamProcessors() { - return activeStream ? activeStream.getProcessors() : []; + return activeStream ? activeStream.getStreamProcessors() : []; } /** @@ -1302,7 +1311,7 @@ function StreamController() { function switchToVideoElement(seekTime) { if (activeStream) { playbackController.initialize(getActiveStreamInfo()); - _openMediaSource(seekTime, false, true); + _openMediaSource({ seekTime, keepBuffers: false, streamActivated: true }); } } @@ -1378,13 +1387,13 @@ function StreamController() { */ function _handleMediaErrorDecode() { logger.warn('A MEDIA_ERR_DECODE occured: Resetting the MediaSource'); - const time = playbackController.getTime(); + const seekTime = playbackController.getTime(); // Deactivate the current stream. activeStream.deactivate(false); // Reset MSE - logger.warn(`MediaSource has been resetted. Resuming playback from time ${time}`); - _openMediaSource(time, false, false); + logger.warn(`MediaSource has been resetted. Resuming playback from time ${seekTime}`); + _openMediaSource({ seekTime, keepBuffers: false, streamActivated: false }); } function getActiveStreamInfo() { diff --git a/src/streaming/models/CmcdModel.js b/src/streaming/models/CmcdModel.js index 32dc69648b..c689097671 100644 --- a/src/streaming/models/CmcdModel.js +++ b/src/streaming/models/CmcdModel.js @@ -146,7 +146,7 @@ function CmcdModel() { if (!activeStream) { return; } - streamProcessors = activeStream.getProcessors(); + streamProcessors = activeStream.getStreamProcessors(); } function getQueryParameter(request) { diff --git a/test/functional/config/test-configurations/local.json b/test/functional/config/test-configurations/local.json index 3a4aefa74b..14be284d59 100644 --- a/test/functional/config/test-configurations/local.json +++ b/test/functional/config/test-configurations/local.json @@ -12,7 +12,8 @@ "flags": [ "--disable-web-security", "--autoplay-policy=no-user-gesture-required", - "--disable-popup-blocking" + "--disable-popup-blocking", + "--disable-search-engine-choice-screen" ] }, "firefox_custom": { diff --git a/test/unit/mocks/StreamMock.js b/test/unit/mocks/StreamMock.js index 55f1fa6972..a727ec9aa2 100644 --- a/test/unit/mocks/StreamMock.js +++ b/test/unit/mocks/StreamMock.js @@ -48,7 +48,7 @@ StreamMock.prototype.setRepresentation = function (representation) { this.dashAdapter.setRepresentation(representation); }; -StreamMock.prototype.getProcessors = function () { +StreamMock.prototype.getStreamProcessors = function () { return this.streamProcessors; }; diff --git a/test/unit/test/streaming/streaming.Stream.js b/test/unit/test/streaming/streaming.Stream.js index 0e7a06eacc..6e5862bef2 100644 --- a/test/unit/test/streaming/streaming.Stream.js +++ b/test/unit/test/streaming/streaming.Stream.js @@ -83,8 +83,8 @@ describe('Stream', function () { expect(isActive).to.be.false; // jshint ignore:line }); - it('should return an empty array when getProcessors is called but streamProcessors attribute is an empty array', () => { - const processors = stream.getProcessors(); + it('should return an empty array when getStreamProcessors is called but streamProcessors attribute is an empty array', () => { + const processors = stream.getStreamProcessors(); expect(processors).to.be.instanceOf(Array); // jshint ignore:line expect(processors).to.be.empty; // jshint ignore:line