From 8fd30f3b739a22faf45d5a37c7aa3693cde9577a Mon Sep 17 00:00:00 2001 From: Constanza Dibueno Date: Mon, 22 Sep 2025 11:05:33 -0300 Subject: [PATCH 01/11] alternative clip functional test vod to vod --- .../alternative-mpd/alternative-mpd-clip.mpd | 22 +++++ .../alternative/alternative-mpd-clip-vod.js | 96 +++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 test/functional/content/alternative-mpd/alternative-mpd-clip.mpd create mode 100644 test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js diff --git a/test/functional/content/alternative-mpd/alternative-mpd-clip.mpd b/test/functional/content/alternative-mpd/alternative-mpd-clip.mpd new file mode 100644 index 0000000000..de2069352c --- /dev/null +++ b/test/functional/content/alternative-mpd/alternative-mpd-clip.mpd @@ -0,0 +1,22 @@ + +https://dash.akamaized.net/akamai/bbb_30fps/ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js b/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js new file mode 100644 index 0000000000..5483171af3 --- /dev/null +++ b/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js @@ -0,0 +1,96 @@ +import Constants from '../../../../../src/streaming/constants/Constants.js'; +import Utils from '../../../src/Utils.js'; +import { initializeDashJsAdapterForAlternativMedia } from '../../common/common.js'; +import { expect } from 'chai'; + +Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-clip-vod').forEach((item) => { + const name = item.name; + const url = item.url; + + describe(`Alternative MPD Clip functionality tests for VOD-to-VOD: ${name}`, () => { + + let player; + + before(() => { + player = initializeDashJsAdapterForAlternativMedia(item, url); + }); + + after(() => { + if (player) { + player.destroy(); + } + }); + + it('should play VOD content, seek forward to simulate delay, then test clip behavior with alternative VOD content', (done) => { + let alternativeContentDetected = false; + let backToOriginalDetected = false; + let eventTriggered = false; + let alternativeEndTime = 0; + let expectedMaxDuration = 0; + let expectedPresentationTime = 0; + let seekPerformed = false; + + const timeout = setTimeout(() => { + done(new Error('Test timed out - alternative MPD replace clip event not completed within 30 seconds')); + }, 30000); + + // Listen for alternative MPD REPLACE events + player.registerEvent(Constants.ALTERNATIVE_MPD.URIS.REPLACE, () => { + eventTriggered = true; + }); + + // Listen for alternative content start event + player.registerEvent(Constants.ALTERNATIVE_MPD.CONTENT_START, (data) => { + if (data.event.mode === 'replace') { + alternativeContentDetected = true; + expectedMaxDuration = data.event.maxDuration; + expectedPresentationTime = data.event.presentationTime; + + expect(data.event.clip).to.be.true; + } + }); + + // Listen for alternative content end event + player.registerEvent(Constants.ALTERNATIVE_MPD.CONTENT_END, (data) => { + if (data.event.mode === 'replace') { + alternativeEndTime = player.getCurrentTime(); // Get playback time when alternative ends + backToOriginalDetected = true; + clearTimeout(timeout); + + // Wait to ensure stability + setTimeout(() => { + expect(eventTriggered).to.be.true; + expect(alternativeContentDetected).to.be.true; + expect(backToOriginalDetected).to.be.true; + + // With clip="true", alternative should terminate at PRT + maxDuration + const expectedTerminationTime = expectedPresentationTime + expectedMaxDuration; + expect(alternativeEndTime).equals(expectedTerminationTime); + done(); + }, 1000); // Wait for VOD content stability + } + }); + + // Perform seek forward to simulate delay after player starts + player.registerEvent('playbackStarted', () => { + if (!seekPerformed) { + seekPerformed = true; + + // Wait a moment for stable playback, then seek forward + setTimeout(() => { + const seekTime = 7; // Seek to 7 seconds - event should have started at 5s + player.seek(seekTime); + }, 2000); + } + }); + + // Handle errors + player.registerEvent('error', (e) => { + clearTimeout(timeout); + done(new Error(`Player error: ${JSON.stringify(e)}`)); + }); + + }, 35000); + + }); +}); \ No newline at end of file From 22b91fc636fb0e9ffb0c9843a89640f8e33044e6 Mon Sep 17 00:00:00 2001 From: Constanza Dibueno Date: Tue, 23 Sep 2025 13:40:26 -0300 Subject: [PATCH 02/11] small refacotr alternative replace live functional test --- .../alternative-mpd-replace-live.js | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-replace-live.js b/test/functional/test/feature-support/alternative/alternative-mpd-replace-live.js index 206eb28c2c..dcf63528f6 100644 --- a/test/functional/test/feature-support/alternative/alternative-mpd-replace-live.js +++ b/test/functional/test/feature-support/alternative/alternative-mpd-replace-live.js @@ -7,7 +7,7 @@ import { expect } from 'chai'; * Utility function to modify a live manifest by injecting Alternative MPD events * This simulates the functionality from the demo.html tool for live to VOD and live to live scenarios */ -function injectAlternativeMpdEvents(player, originalManifestUrl, alternativeManifestUrl, callback) { +function injectAlternativeMpdEvents(player, originalManifestUrl, alternativeManifestUrl, presentationTime, callback) { // Access the underlying MediaPlayer instance const mediaPlayer = player.player; @@ -20,10 +20,7 @@ function injectAlternativeMpdEvents(player, originalManifestUrl, alternativeMani manifest.Period[0].EventStream = []; } - // Calculate presentation time for live content - // For live streams, use current time + offset to ensure the event is in the future - const currentPresentationTime = Date.now(); - const presentationTime = currentPresentationTime + 4000; // 4 seconds from now + // Use the provided presentation time const duration = 9000; const earliestResolutionTimeOffset = 5000; const maxDuration = 9000; @@ -65,13 +62,19 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-rep describe(`Alternative MPD Replace Live functionality tests for: ${name}`, () => { let player; + let presentationTime; before((done) => { // Initialize the player without attaching source immediately player = initializeDashJsAdapterForAlternativMedia(item, null); - + + // Calculate presentation time for live content + // For live streams, use current time + offset to ensure the event is in the future + const currentPresentationTime = Date.now(); + presentationTime = currentPresentationTime + 4000; // 4 seconds from now + // Use the utility function to inject Alternative MPD events - injectAlternativeMpdEvents(player, originalUrl, alternativeUrl, () => { + injectAlternativeMpdEvents(player, originalUrl, alternativeUrl, presentationTime, () => { done(); }); }); @@ -108,6 +111,11 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-rep alternativeContentDetected = true; alternativeStartTime = Date.now(); expectedAlternativeDuration = data.event.duration; + const latency = player.getCurrentLiveLatency(); + if (!isNaN(latency)){ //prevents execution if player is not loaded yet + let expectedStartTimeWithLatency = presentationTime + (latency * 1000); + expect(alternativeStartTime).to.be.closeTo(expectedStartTimeWithLatency, 1000); // Allow tolerance + } } }); @@ -127,14 +135,12 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-rep // Verify that alternative content played for its full duration const actualAlternativeDuration = (alternativeEndTime - alternativeStartTime) / 1000; // Convert to seconds - expect(actualAlternativeDuration).to.be.at.least(expectedAlternativeDuration - 1); // Allow 1 second tolerance - expect(actualAlternativeDuration).to.be.at.most(expectedAlternativeDuration + 1.5); // Allow 1 second tolerance + expect(actualAlternativeDuration).to.be.closeTo(expectedAlternativeDuration, 1.5); // Allow 1 second tolerance // For REPLACE mode from live to VOD, verify timing behavior // The expected behavior is to return at presentationTime + duration or returnOffset const expectedMinTime = data.event.presentationTime + data.event.duration; - expect(timeAfterSwitch).to.be.at.least(expectedMinTime - 1); // Allow 1 second tolerance - expect(timeAfterSwitch).to.be.at.most(expectedMinTime + 2); // Allow 2 seconds tolerance for live content + expect(timeAfterSwitch).to.be.closeTo(expectedMinTime, 2); // Allow 2 seconds tolerance for live content done(); }, 2000); } From 4a8c2064e89551eb4650e16b450897284fc42342 Mon Sep 17 00:00:00 2001 From: Constanza Dibueno Date: Thu, 25 Sep 2025 14:21:20 -0300 Subject: [PATCH 03/11] add clip live to live test case --- .../streams/alternative-mpd.json | 21 ++- .../alternative/alternative-mpd-clip-live.js | 156 ++++++++++++++++++ 2 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js diff --git a/test/functional/config/test-configurations/streams/alternative-mpd.json b/test/functional/config/test-configurations/streams/alternative-mpd.json index a93f9cb083..196349de65 100644 --- a/test/functional/config/test-configurations/streams/alternative-mpd.json +++ b/test/functional/config/test-configurations/streams/alternative-mpd.json @@ -17,7 +17,9 @@ "feature-support/alternative/alternative-mpd-replace-vod", "feature-support/alternative/alternative-mpd-insert-vod", "feature-support/alternative/alternative-mpd-replace-live", - "feature-support/alternative/alternative-mpd-executeOnce" + "feature-support/alternative/alternative-mpd-executeOnce", + "feature-support/alternative/alternative-mpd-clip-vod", + "feature-support/alternative/alternative-mpd-clip-live" ], "excluded": [] }, @@ -79,6 +81,23 @@ "includedTestfiles": [ "feature-support/alternative/alternative-mpd-executeOnce" ] + }, + { + "name": "Alternative MPD Clip - VOD to VOD Test", + "type": "vod", + "url": "/base/test/functional/content/alternative-mpd/alternative-mpd-clip.mpd", + "includedTestfiles": [ + "feature-support/alternative/alternative-mpd-clip-vod" + ] + }, + { + "name": "Alternative MPD Clip - Live to Live Test", + "type": "live", + "originalUrl": "https://livesim2.dashif.org/livesim2/testpic_2s/Manifest.mpd", + "alternativeUrl": "https://livesim2.dashif.org/livesim2/testpic_2s/Manifest.mpd", + "includedTestfiles": [ + "feature-support/alternative/alternative-mpd-clip-live" + ] } ] } \ No newline at end of file diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js b/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js new file mode 100644 index 0000000000..7843cd7fc6 --- /dev/null +++ b/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js @@ -0,0 +1,156 @@ +import Constants from '../../../../../src/streaming/constants/Constants.js'; +import Utils from '../../../src/Utils.js'; +import { initializeDashJsAdapterForAlternativMedia } from '../../common/common.js'; +import { expect } from 'chai'; + +/** + * Utility function to modify a live manifest by injecting Alternative MPD events with clip functionality + * This tests the clip feature scenarios where only a portion of the alternative live content is played + */ +function injectAlternativeMpdClipEvents(player, originalManifestUrl, alternativeManifestUrl, presentationTime, maxDuration, callback) { + // Access the underlying MediaPlayer instance + const mediaPlayer = player.player; + + mediaPlayer.retrieveManifest(originalManifestUrl, (manifest) => { + // Initialize EventStream if it doesn't exist + if (!manifest.Period[0].EventStream) { + manifest.Period[0].EventStream = []; + } else { + // Clear existing EventStreams + manifest.Period[0].EventStream = []; + } + + const duration = 8000; + const earliestResolutionTimeOffset = 3000; + + // Create the replace event with clip functionality for live-to-live scenario + const replaceClipEvent = { + schemeIdUri: 'urn:mpeg:dash:event:alternativeMPD:replace:2025', + timescale: 1000, + Event: [{ + id: 1, + presentationTime: presentationTime, + duration: duration, + ReplacePresentation: { + url: alternativeManifestUrl, + earliestResolutionTimeOffset: earliestResolutionTimeOffset, + maxDuration: maxDuration, + clip: 'true', + } + }] + }; + + // Add the event to the manifest + manifest.Period[0].EventStream.push(replaceClipEvent); + + // Attach the modified manifest using the MediaPlayer directly + mediaPlayer.attachSource(manifest); + + if (callback) { + callback(); + } + }); +} + +Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-clip-live').forEach((item) => { + const name = item.name; + const originalUrl = item.originalUrl; + const alternativeUrl = item.alternativeUrl; + + describe(`Alternative MPD Replace with Clip functionality tests for Live-to-Live: ${name}`, () => { + + let player; + let presentationTime; + let maxDuration; + let presentationTimeOffset; + + before((done) => { + // Calculate presentation time for the test + const currentPresentationTime = Date.now(); + presentationTimeOffset = 10000 //includes potential latency + presentationTime = currentPresentationTime - presentationTimeOffset; //alternative content already started + maxDuration = 10000; + + // Initialize the player without attaching source immediately + player = initializeDashJsAdapterForAlternativMedia(item, null); + + // Use the utility function to inject Alternative MPD events with clip for live-to-live + injectAlternativeMpdClipEvents(player, originalUrl, alternativeUrl, presentationTime, maxDuration, () => { + done(); + }); + }); + + after(() => { + if (player) { + player.destroy(); + } + }); + + it('should play live content, switch to clipped alternative live content, then back to original live content', (done) => { + let alternativeContentDetected = false; + let backToOriginalDetected = false; + let eventTriggered = false; + let alternativeEndTime = 0; + let alternativeStartTime = 0; + let expectedMaxDuration = 0; + let expectedPresentationTime = 0; + + // Timeout disabled for debugging + const timeout = setTimeout(() => { + done(new Error('Test timed out - alternative MPD replace clip event not completed within 35 seconds')); + }, 35000); + + // Listen for alternative MPD REPLACE events + player.registerEvent(Constants.ALTERNATIVE_MPD.URIS.REPLACE, () => { + eventTriggered = true; + }); + + // Listen for alternative content start event + player.registerEvent(Constants.ALTERNATIVE_MPD.CONTENT_START, (data) => { + if (data.event.mode === 'replace') { + alternativeContentDetected = true; + alternativeStartTime = Date.now() / 1000; + expectedMaxDuration = data.event.maxDuration; + expectedPresentationTime = data.event.presentationTime; + expect(data.event.clip).to.be.true; + } + }); + + // Listen for alternative content end event + player.registerEvent(Constants.ALTERNATIVE_MPD.CONTENT_END, (data) => { + if (data.event.mode === 'replace') { + backToOriginalDetected = true; + alternativeEndTime = Date.now() / 1000; + const actualTerminationTime = player.player.timeAsUTC(); + const expectedTerminationTime = (expectedPresentationTime + expectedMaxDuration); + clearTimeout(timeout); + + // Wait to ensure stability + setTimeout(() => { + expect(eventTriggered).to.be.true; + expect(alternativeContentDetected).to.be.true; + expect(backToOriginalDetected).to.be.true; + + // Verify that the actual duration of alternative content is less than maxDuration + const actualAlternativeDuration = (alternativeEndTime - alternativeStartTime); + expect(actualAlternativeDuration).to.be.lessThan(expectedMaxDuration); + + // The alternative content should terminate at approximately PRT + APDmax + // Allow tolerance for live content timing variations + expect(actualTerminationTime).to.be.at.closeTo(expectedTerminationTime, 2); + + done(); + }, 2000); // Longer wait for live content stability + } + }); + + // Handle errors + player.registerEvent('error', (e) => { + clearTimeout(timeout); + done(new Error(`Player error: ${JSON.stringify(e)}`)); + }); + + }, 45000); + + }); +}); \ No newline at end of file From 64560410bb3456c8187a92d5a17c0a55ac8529b2 Mon Sep 17 00:00:00 2001 From: Constanza Dibueno Date: Thu, 25 Sep 2025 14:24:03 -0300 Subject: [PATCH 04/11] fix clip for live to live --- .../controllers/AlternativeMediaController.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/streaming/controllers/AlternativeMediaController.js b/src/streaming/controllers/AlternativeMediaController.js index 8d9840c16d..171a11d239 100644 --- a/src/streaming/controllers/AlternativeMediaController.js +++ b/src/streaming/controllers/AlternativeMediaController.js @@ -292,16 +292,18 @@ function AlternativeMediaController() { const altPlayer = mediaManager.getAlternativePlayer(); const deltaTime = e.time - timeToSwitch; - if (!alternativeSwitched) { + if (!alternativeSwitched && deltaTime > 0) { alternativeSwitched = true; calculatedMaxDuration = altPlayer.isDynamic() ? deltaTime + maxDuration : maxDuration; } const shouldSwitchBack = - // Check if the alternative content has finished playing - (Math.round(altPlayer.duration() - e.time) === 0) || - // Check if the alternative content reached the max duration - (clip && actualEventPresentationTime + deltaTime >= presentationTime + calculatedMaxDuration) || - (calculatedMaxDuration && calculatedMaxDuration <= e.time); + calculatedMaxDuration > 0 && ( + // Check if the alternative content has finished playing (only for non-dynamic content) + (!altPlayer.isDynamic() && Math.round(altPlayer.duration() - e.time) === 0) || + // Check if the alternative content reached the max duration + (clip && actualEventPresentationTime + deltaTime >= presentationTime + calculatedMaxDuration) || + (calculatedMaxDuration && calculatedMaxDuration <= e.time) + ); if (shouldSwitchBack) { const seekTime = _calculateSeekTime(event, altPlayer); mediaManager.switchBackToMainContent(seekTime); From 3dbfe6d14042f0c81384c01c1470c072fdb94d34 Mon Sep 17 00:00:00 2001 From: Constanza Dibueno <121617928+cotid-qualabs@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:56:22 -0300 Subject: [PATCH 05/11] Update test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../feature-support/alternative/alternative-mpd-clip-vod.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js b/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js index 5483171af3..b47648ece3 100644 --- a/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js +++ b/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js @@ -65,7 +65,7 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-cli // With clip="true", alternative should terminate at PRT + maxDuration const expectedTerminationTime = expectedPresentationTime + expectedMaxDuration; - expect(alternativeEndTime).equals(expectedTerminationTime); + expect(alternativeEndTime).to.be.closeTo(expectedTerminationTime, 0.5); done(); }, 1000); // Wait for VOD content stability } From 0651fae188baef2ff07b528b444e4209b083b3da Mon Sep 17 00:00:00 2001 From: Constanza Dibueno Date: Fri, 26 Sep 2025 11:57:00 -0300 Subject: [PATCH 06/11] remove comment --- .../feature-support/alternative/alternative-mpd-clip-live.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js b/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js index 7843cd7fc6..833ea7a131 100644 --- a/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js +++ b/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js @@ -95,7 +95,6 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-cli let expectedMaxDuration = 0; let expectedPresentationTime = 0; - // Timeout disabled for debugging const timeout = setTimeout(() => { done(new Error('Test timed out - alternative MPD replace clip event not completed within 35 seconds')); }, 35000); From 5a90d52bcd004e4a81187705d428dc9974743c2c Mon Sep 17 00:00:00 2001 From: Constanza Dibueno <121617928+cotid-qualabs@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:59:35 -0300 Subject: [PATCH 07/11] Update src/streaming/controllers/AlternativeMediaController.js Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- src/streaming/controllers/AlternativeMediaController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/streaming/controllers/AlternativeMediaController.js b/src/streaming/controllers/AlternativeMediaController.js index cc32a81153..50bc1a01c0 100644 --- a/src/streaming/controllers/AlternativeMediaController.js +++ b/src/streaming/controllers/AlternativeMediaController.js @@ -279,7 +279,7 @@ function AlternativeMediaController() { (!altPlayer.isDynamic() && Math.round(altPlayer.duration() - e.time) === 0) || // Check if the alternative content reached the max duration (clip && actualEventPresentationTime + deltaTime >= presentationTime + calculatedMaxDuration) || - (calculatedMaxDuration && calculatedMaxDuration <= e.time) + (calculatedMaxDuration && calculatedMaxDuration <= deltaTime) ); if (shouldSwitchBack) { const seekTime = _calculateSeekTime(event, altPlayer); From f0af032679ac9522fcf3dd3e31c5b3de38bdba74 Mon Sep 17 00:00:00 2001 From: Constanza Dibueno Date: Fri, 26 Sep 2025 12:11:56 -0300 Subject: [PATCH 08/11] rename deltaTime --- .../controllers/AlternativeMediaController.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/streaming/controllers/AlternativeMediaController.js b/src/streaming/controllers/AlternativeMediaController.js index 50bc1a01c0..c8d62c6a25 100644 --- a/src/streaming/controllers/AlternativeMediaController.js +++ b/src/streaming/controllers/AlternativeMediaController.js @@ -268,18 +268,18 @@ function AlternativeMediaController() { const altPlayer = mediaManager.getAlternativePlayer(); - const deltaTime = e.time - timeToSwitch; - if (!alternativeSwitched && deltaTime > 0) { + const adjustedTime = e.time - timeToSwitch; + if (!alternativeSwitched && adjustedTime > 0) { alternativeSwitched = true; - calculatedMaxDuration = altPlayer.isDynamic() ? deltaTime + maxDuration : maxDuration; + calculatedMaxDuration = altPlayer.isDynamic() ? adjustedTime + maxDuration : maxDuration; } const shouldSwitchBack = calculatedMaxDuration > 0 && ( // Check if the alternative content has finished playing (only for non-dynamic content) (!altPlayer.isDynamic() && Math.round(altPlayer.duration() - e.time) === 0) || // Check if the alternative content reached the max duration - (clip && actualEventPresentationTime + deltaTime >= presentationTime + calculatedMaxDuration) || - (calculatedMaxDuration && calculatedMaxDuration <= deltaTime) + (clip && actualEventPresentationTime + adjustedTime >= presentationTime + calculatedMaxDuration) || + (calculatedMaxDuration && calculatedMaxDuration <= adjustedTime) ); if (shouldSwitchBack) { const seekTime = _calculateSeekTime(event, altPlayer); From d85a4c77e3ba6af72deef6a464af3a6aeea0d267 Mon Sep 17 00:00:00 2001 From: Constanza Dibueno Date: Fri, 26 Sep 2025 12:35:22 -0300 Subject: [PATCH 09/11] remove comments --- .../alternative/alternative-mpd-clip-live.js | 11 ----------- .../alternative/alternative-mpd-clip-vod.js | 5 +---- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js b/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js index 833ea7a131..f911db5487 100644 --- a/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js +++ b/test/functional/test/feature-support/alternative/alternative-mpd-clip-live.js @@ -8,22 +8,18 @@ import { expect } from 'chai'; * This tests the clip feature scenarios where only a portion of the alternative live content is played */ function injectAlternativeMpdClipEvents(player, originalManifestUrl, alternativeManifestUrl, presentationTime, maxDuration, callback) { - // Access the underlying MediaPlayer instance const mediaPlayer = player.player; mediaPlayer.retrieveManifest(originalManifestUrl, (manifest) => { - // Initialize EventStream if it doesn't exist if (!manifest.Period[0].EventStream) { manifest.Period[0].EventStream = []; } else { - // Clear existing EventStreams manifest.Period[0].EventStream = []; } const duration = 8000; const earliestResolutionTimeOffset = 3000; - // Create the replace event with clip functionality for live-to-live scenario const replaceClipEvent = { schemeIdUri: 'urn:mpeg:dash:event:alternativeMPD:replace:2025', timescale: 1000, @@ -40,10 +36,7 @@ function injectAlternativeMpdClipEvents(player, originalManifestUrl, alternative }] }; - // Add the event to the manifest manifest.Period[0].EventStream.push(replaceClipEvent); - - // Attach the modified manifest using the MediaPlayer directly mediaPlayer.attachSource(manifest); if (callback) { @@ -65,7 +58,6 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-cli let presentationTimeOffset; before((done) => { - // Calculate presentation time for the test const currentPresentationTime = Date.now(); presentationTimeOffset = 10000 //includes potential latency presentationTime = currentPresentationTime - presentationTimeOffset; //alternative content already started @@ -99,12 +91,10 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-cli done(new Error('Test timed out - alternative MPD replace clip event not completed within 35 seconds')); }, 35000); - // Listen for alternative MPD REPLACE events player.registerEvent(Constants.ALTERNATIVE_MPD.URIS.REPLACE, () => { eventTriggered = true; }); - // Listen for alternative content start event player.registerEvent(Constants.ALTERNATIVE_MPD.CONTENT_START, (data) => { if (data.event.mode === 'replace') { alternativeContentDetected = true; @@ -115,7 +105,6 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-cli } }); - // Listen for alternative content end event player.registerEvent(Constants.ALTERNATIVE_MPD.CONTENT_END, (data) => { if (data.event.mode === 'replace') { backToOriginalDetected = true; diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js b/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js index b47648ece3..27b9146bcb 100644 --- a/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js +++ b/test/functional/test/feature-support/alternative/alternative-mpd-clip-vod.js @@ -34,12 +34,10 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-cli done(new Error('Test timed out - alternative MPD replace clip event not completed within 30 seconds')); }, 30000); - // Listen for alternative MPD REPLACE events player.registerEvent(Constants.ALTERNATIVE_MPD.URIS.REPLACE, () => { eventTriggered = true; }); - // Listen for alternative content start event player.registerEvent(Constants.ALTERNATIVE_MPD.CONTENT_START, (data) => { if (data.event.mode === 'replace') { alternativeContentDetected = true; @@ -50,10 +48,9 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-cli } }); - // Listen for alternative content end event player.registerEvent(Constants.ALTERNATIVE_MPD.CONTENT_END, (data) => { if (data.event.mode === 'replace') { - alternativeEndTime = player.getCurrentTime(); // Get playback time when alternative ends + alternativeEndTime = player.getCurrentTime(); backToOriginalDetected = true; clearTimeout(timeout); From a96cba665a87eeaea881f9353200ed9aadc6f0b1 Mon Sep 17 00:00:00 2001 From: Constanza Dibueno Date: Fri, 26 Sep 2025 12:36:15 -0300 Subject: [PATCH 10/11] add missing clear timeouts --- .../feature-support/alternative/alternative-mpd-insert-vod.js | 1 + .../feature-support/alternative/alternative-mpd-replace-vod.js | 1 + 2 files changed, 2 insertions(+) diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-insert-vod.js b/test/functional/test/feature-support/alternative/alternative-mpd-insert-vod.js index a6c3918497..21c804cf1f 100644 --- a/test/functional/test/feature-support/alternative/alternative-mpd-insert-vod.js +++ b/test/functional/test/feature-support/alternative/alternative-mpd-insert-vod.js @@ -86,6 +86,7 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-ins // Handle errors player.registerEvent('error', (e) => { + clearTimeout(timeout); console.error('Player error:', e); }); diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-replace-vod.js b/test/functional/test/feature-support/alternative/alternative-mpd-replace-vod.js index 29db30ed53..4d8124e47b 100644 --- a/test/functional/test/feature-support/alternative/alternative-mpd-replace-vod.js +++ b/test/functional/test/feature-support/alternative/alternative-mpd-replace-vod.js @@ -84,6 +84,7 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-rep // Handle errors player.registerEvent('error', (e) => { + clearTimeout(timeout); console.error('Player error:', e); }); From e892eb7231e0d7f99de17cd598beb26e76780c7e Mon Sep 17 00:00:00 2001 From: Constanza Dibueno Date: Fri, 26 Sep 2025 12:37:56 -0300 Subject: [PATCH 11/11] add missing done --- .../feature-support/alternative/alternative-mpd-insert-vod.js | 2 +- .../feature-support/alternative/alternative-mpd-replace-vod.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-insert-vod.js b/test/functional/test/feature-support/alternative/alternative-mpd-insert-vod.js index 21c804cf1f..cced906e26 100644 --- a/test/functional/test/feature-support/alternative/alternative-mpd-insert-vod.js +++ b/test/functional/test/feature-support/alternative/alternative-mpd-insert-vod.js @@ -87,7 +87,7 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-ins // Handle errors player.registerEvent('error', (e) => { clearTimeout(timeout); - console.error('Player error:', e); + done(new Error(`Player error: ${JSON.stringify(e)}`)); }); }, 35000); diff --git a/test/functional/test/feature-support/alternative/alternative-mpd-replace-vod.js b/test/functional/test/feature-support/alternative/alternative-mpd-replace-vod.js index 4d8124e47b..2a58e1037f 100644 --- a/test/functional/test/feature-support/alternative/alternative-mpd-replace-vod.js +++ b/test/functional/test/feature-support/alternative/alternative-mpd-replace-vod.js @@ -85,7 +85,7 @@ Utils.getTestvectorsForTestcase('feature-support/alternative/alternative-mpd-rep // Handle errors player.registerEvent('error', (e) => { clearTimeout(timeout); - console.error('Player error:', e); + done(new Error(`Player error: ${JSON.stringify(e)}`)); }); }, 30000);