Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
221 commits
Select commit Hold shift + click to select a range
03bc302
Alternative palyer POC
sebastianpiq Nov 5, 2024
0c9aed2
try to keep buffers on alternative change
JoaquinBCh Nov 6, 2024
5f340c1
restore bytes to original mediasource
N1Knight Nov 12, 2024
b7b4827
AlternativeMpd: Two video tag approach
mhargain Dec 5, 2024
75c6f94
@AlternativeMpd: modes, returnOffset and mixin added
mhargain Dec 18, 2024
0d56009
@AlternativeMpd: added manifest highlight for demo page
mhargain Dec 19, 2024
bba9de5
updated demo url
mhargain Dec 30, 2024
85808ee
Revert "restore bytes to original mediasource"
mhargain Dec 30, 2024
7820963
Update alternative mpd syntaxis
sebastianpiq Jan 14, 2025
ddaec16
Fix worng uri alternative mpd value
sebastianpiq Jan 14, 2025
a3a5119
Add logger to the alternative mpd controller
sebastianpiq Jan 14, 2025
3beeeee
Update default clip value
sebastianpiq Jan 14, 2025
c45dcdd
Change console errors to error logs
sebastianpiq Jan 14, 2025
2f61209
Delete unnecesary comments
sebastianpiq Jan 14, 2025
d808066
Improve alternative mpd envents schedule logic
sebastianpiq Jan 14, 2025
d182bf9
Update alternative mpd events off
sebastianpiq Jan 14, 2025
f0f2642
Fix wrong alternative event url and duration
sebastianpiq Jan 14, 2025
af6a99c
Implement max duration
sebastianpiq Jan 14, 2025
c82d22b
Implement clip for alternative
sebastianpiq Jan 14, 2025
e629efc
Implement alternative start at playhead
sebastianpiq Jan 14, 2025
5f189cd
Remove unused console logs
sebastianpiq Jan 15, 2025
aedbeb4
Change duration to maxDuration as reference to switch back
sebastianpiq Jan 15, 2025
80d481b
Update alternative mpd controller constants
sebastianpiq Jan 15, 2025
7ccdd36
Merge pull request #41 from qualabs/alternative/update-syntaxis
emilsas Jan 16, 2025
241a9aa
Fix alterantive end stream switch back and clip default value
sebastianpiq Jan 16, 2025
e86f774
Fix multiperiod bug
sebastianpiq Jan 16, 2025
254bfde
Merge branch 'alternative/max-duration' into current branch
Jan 16, 2025
5fefe26
Implement return offset
sebastianpiq Jan 16, 2025
971110b
Fix edge case with multiperiods
sebastianpiq Jan 16, 2025
e3684ee
Improve should switch back readability
sebastianpiq Jan 16, 2025
14e2ac2
Implement alternative return offset
sebastianpiq Jan 17, 2025
8324638
Fix clip and maxDurations bugs
sebastianpiq Jan 17, 2025
c302d53
Change alternative watched value to completed
sebastianpiq Jan 17, 2025
90d3c83
Merge pull request #43 from qualabs/alternative/max-duration
sebastianpiq Jan 17, 2025
5c3995c
Merge pull request #46 from qualabs/alternative/return-offset
sebastianpiq Jan 17, 2025
a8ffdab
merge alternative-media-presentations
sebastianpiq Jan 17, 2025
5581320
Merge pull request #44 from qualabs/alternative/start-at-playhead
sebastianpiq Jan 17, 2025
74bdd09
Fix clip+startAtPlayhead and maxDurations bugs
sebastianpiq Jan 20, 2025
8ba35db
Fix alternative player don't return
sebastianpiq Jan 20, 2025
3552c63
Fix alternative event earliestResolutionTimeOffset attribute
sebastianpiq Jan 20, 2025
0de5b4d
Merge branch 'alternative/add-logger' into demo-bug-fixes
sebastianpiq Jan 21, 2025
b3c4a46
Merge branch 'alternative/update-constants' into demo-bug-fixes
sebastianpiq Jan 21, 2025
d244a49
Fix merge logger and constants bugs
sebastianpiq Jan 21, 2025
e089428
Remove parse alternative mpd event unnecesary if conditions
sebastianpiq Jan 21, 2025
13970c7
Only Alternative MPD replace events can be used used for dynamic MPD
tatiana-perera Jan 21, 2025
da5bfd5
Fix alternative events not triggered without event duration
sebastianpiq Jan 21, 2025
1ca952f
Fix wrong clip and startAtPlayhead return time
sebastianpiq Jan 23, 2025
d799b98
Include t anchor with startAtPlayhead
tatiana-perera Jan 23, 2025
a238d42
Changed doble quotes to single ones
tatiana-perera Jan 23, 2025
87482a2
Merged demo-bug-fixes into current branch
tatiana-perera Jan 23, 2025
e3d03fa
Now, the t anchor is obtained with a regEx
tatiana-perera Jan 23, 2025
f7bb729
Merge pull request #48 from qualabs/feature/alternative-startAtPlayHe…
tatiana-perera Jan 23, 2025
5a05014
Now the alternative duration is the minimum of max duration and the a…
tatiana-perera Jan 24, 2025
22d412d
Fix bug multi alternative events
sebastianpiq Jan 24, 2025
3c7c1fe
Merge pull request #47 from qualabs/demo-bug-fixes
tatiana-perera Jan 24, 2025
6b7b8ae
Add default (60 seconds) to the erliestResolutionTimeOffset
sebastianpiq Feb 3, 2025
238352d
Add constant for the deafaul earliest resolution time offset
sebastianpiq Feb 28, 2025
779ef4b
Merge pull request #52 from qualabs/alternative/earliestResolutionTim…
sebastianpiq Feb 28, 2025
5fa9745
Merge branch 'development' into feature/alternative-media-presentations
emilsas Apr 30, 2025
53661d7
Rename 'startAtPlayhead' to 'startWithOffset' in AlternativeMpd and r…
sebastianpiq May 28, 2025
5eaeece
Merge pull request #102 from qualabs/alternative-mpd/update-startWith…
cotid-qualabs Jun 4, 2025
4c67920
WIP executeOnce
cotid-qualabs Jun 5, 2025
3b7cd8f
WIP
cotid-qualabs Jun 9, 2025
5d29012
task/cml-segement-template-util (#4711)
littlespex May 3, 2025
a6668f7
TypeScript fixes for MediaSettings (#4761)
stschr May 3, 2025
3015cd7
Fix errors in JSDoc
dsilhavy May 9, 2025
360b691
Stschr/20250424 role main (#4760)
stschr May 10, 2025
b886c86
Fix build error in network sample (#4767)
dsilhavy May 10, 2025
5d9298b
Increase version number to 5.1.0
dsilhavy May 14, 2025
ca5b06e
fix: fix: allow large ints to be passed in as time values for process…
littlespex May 18, 2025
1adf9ee
Change next version number to 5.0.3
dsilhavy May 21, 2025
1bfcc77
[VTTParser] Support for lineAlign and positionAlign (#4773)
eduter May 21, 2025
47efab3
[TextTracks] Improve performance of addCaptions and fix duplicate che…
eduter May 21, 2025
2dfa4f3
add check for schemeIdUri in getIsMain() (#4779)
stschr May 21, 2025
103b9c6
Upgrade CML version in network interceptor sample
dsilhavy May 21, 2025
4906ee5
Fix regression when setting size of VTT cue (#4780)
dsilhavy May 21, 2025
fb1661a
fix: Handle falsy values in DescriptorType value property (#4784)
stephanterning May 22, 2025
6ffda88
Merge branch 'development' into feature/alternative-media-presentations
sebastianpiq Jun 9, 2025
13d17a9
task/cml-segement-template-util (#4711)
littlespex May 3, 2025
2b0c0ae
Fix build error in network sample (#4767)
dsilhavy May 10, 2025
3254903
Increase version number to 5.1.0
dsilhavy May 14, 2025
02370b0
Change next version number to 5.0.3
dsilhavy May 21, 2025
00148c9
Upgrade CML version in network interceptor sample
dsilhavy May 21, 2025
b9aaeda
Increase version number to 5.1.0
dsilhavy Jun 2, 2025
7f1f596
feature: implement no jump alternative event attribute
sebastianpiq Jun 12, 2025
c82f1cf
Merge pull request #106 from qualabs/alternative-media-presentation/n…
cotid-qualabs Jun 12, 2025
75271ae
Remove unnecessary code and comments
sebastianpiq Jun 19, 2025
bf62c90
Remove unnecesary white space
sebastianpiq Jun 20, 2025
ef3f338
refactor: remove unused resetAlt functions from Stream and StreamCont…
sebastianpiq Jun 20, 2025
b35d5eb
Merge branch 'feature/alternative-media-presentations' into alternati…
sebastianpiq Jun 20, 2025
7d9cc16
feat: add executeOnce property to AlternativeMpd and update related l…
sebastianpiq Jun 20, 2025
82a582a
refactor: remove executeOnce property from alternativeMpd in DashMani…
sebastianpiq Jun 20, 2025
50a898d
refactor: improve readability by adding comments to skip logic in eve…
sebastianpiq Jun 20, 2025
759a251
Merge pull request #105 from qualabs/alternative-media-presentation/e…
cotid-qualabs Jun 23, 2025
a76affe
feature: add no jump attributes and refactor event handling logic
sebastianpiq Jun 25, 2025
e801b16
refactor: update no jump attributes and clean up event handling logic
sebastianpiq Jun 25, 2025
94d2412
refactor: update noJump condition to use constant for better readability
sebastianpiq Jun 25, 2025
8346e30
Merge pull request #109 from qualabs/alternative-media-presentations/…
cotid-qualabs Jun 25, 2025
5b2adbd
feature: add STATUS repeat and update
sebastianpiq Jun 27, 2025
de365a2
Merge branch 'feature/alternative-media-presentations' into alternati…
sebastianpiq Jun 30, 2025
96b93f7
refactor: simplify condition checks for scheduled events in Alternati…
sebastianpiq Jun 30, 2025
2cde079
Merge pull request #111 from qualabs/alternative-media-presentations/…
cotid-qualabs Jul 10, 2025
72e93be
Move parse event logic from the event recived to the player time updated
sebastianpiq Aug 18, 2025
d24d68a
Refactor eventController to handle earliestResolutionTimeOffset and r…
sebastianpiq Aug 18, 2025
0ec11d4
Remove unnecessary console log from _onAlternativeEventTriggered func…
sebastianpiq Aug 18, 2025
7a3a542
refactor: remove prebufferedEvents and streamline prebuffering logic
sebastianpiq Aug 18, 2025
41e4274
fix: ensure video elements are inserted into the DOM only if parentNo…
sebastianpiq Aug 18, 2025
161ea40
fix: include event object in EVENT_READY_TO_RESOLVE trigger and adjus…
sebastianpiq Aug 19, 2025
323b32d
fix: include event object in EVENT_READY_TO_RESOLVE trigger and adjus…
sebastianpiq Aug 19, 2025
a5dac1c
feat: implement noJump event handling and refactor event triggering l…
sebastianpiq Aug 22, 2025
08050a4
feat: enhance noJump event handling and refactor related logic
sebastianpiq Aug 22, 2025
051acf9
fix: reorder conditions in _canEventRetrigger to improve clarity and …
sebastianpiq Aug 22, 2025
74be18f
feat: add playback seeking event handling to prevent false event trig…
sebastianpiq Aug 22, 2025
27168b2
feat: implement logic to determine the first event in a sequence for …
sebapique Aug 22, 2025
46aee3a
feat: add executeOnce handling
sebapique Aug 22, 2025
f3561f9
refactor: remove unused constants and clean up event handling logic
sebapique Aug 23, 2025
d821539
tests
sebapique Aug 26, 2025
fc12b2a
refactor: remove unnecessary tests
sebastianpiq Aug 26, 2025
e5333fd
refactor: remove unnecessary tests
sebastianpiq Aug 26, 2025
70ca4cd
Implement alternativeMpdController unit tests
sebastianpiq Sep 2, 2025
46eb407
feat: add mock utilities for AlternativeMpdController testing
sebastianpiq Sep 2, 2025
e51d9e2
Fix event resolution time offset
sebastianpiq Sep 4, 2025
268add0
refactor: remove debug log for resolution time calculation
sebastianpiq Sep 4, 2025
701fe33
refactor: Implement media manager
sebastianpiq Sep 8, 2025
2902846
Add sample page
sebastianpiq Sep 9, 2025
3743525
Implement alternative preload
sebastianpiq Sep 9, 2025
74f8aac
refactor: Clean up MediaManager prebuffered content handling
sebastianpiq Sep 9, 2025
dc3bb19
fix: adapt switch back logic for live to live
sebastianpiq Sep 11, 2025
15f49a0
refactor: Event controller supports alternative events (#126)
sebastianpiq Sep 11, 2025
3adb4e8
add alternative content start and end events
cotid-qualabs Sep 11, 2025
c0679f5
add vod to vod insert and replace functional tests
cotid-qualabs Sep 11, 2025
8a32cc4
insert manifest fix
cotid-qualabs Sep 11, 2025
ca3338f
Merge branch 'feature/alternative-media-presentations' of github.com:…
cotid-qualabs Sep 11, 2025
a33627a
refactor: Rename realMaxDuration to calculatedMaxDuration and encapsu…
sebastianpiq Sep 11, 2025
d8f509c
Merge branch 'feature/alternative-media-presentations' into alternati…
sebastianpiq Sep 11, 2025
5a2673f
add live to vod replace functional test
cotid-qualabs Sep 11, 2025
654bc94
add vod to live
cotid-qualabs Sep 11, 2025
45d6047
add vod to live
cotid-qualabs Sep 11, 2025
ff5a6b6
add complete alterantive duration verification
cotid-qualabs Sep 11, 2025
b8c7c41
add insert vod to live
cotid-qualabs Sep 11, 2025
8cfcf2f
alternative replace vod manifest cleanup
cotid-qualabs Sep 11, 2025
feb415d
add complete alterantive duration to live to vod
cotid-qualabs Sep 11, 2025
d913269
variable rename
cotid-qualabs Sep 11, 2025
92578b4
file renames
cotid-qualabs Sep 11, 2025
4ffe120
vector name update
cotid-qualabs Sep 11, 2025
6b2d78c
add live to live
cotid-qualabs Sep 11, 2025
060e165
executeOnce functional test case
cotid-qualabs Sep 12, 2025
9a6c2d4
refactor: Move event handling logic in the MediaManager into the Alte…
sebapique Sep 12, 2025
c5ebb05
test case rename
cotid-qualabs Sep 12, 2025
e2f791d
simplify replace live test case
cotid-qualabs Sep 12, 2025
3852a27
Implemented live content with alternative live content playback (#129)
sebastianpiq Sep 12, 2025
16c0ef7
Merge branch 'feature/alternative-media-presentations' of github.com:…
cotid-qualabs Sep 12, 2025
22d9045
extend tolerance for live content
cotid-qualabs Sep 12, 2025
b276809
test: Add unit tests for AlternativeMediaController with MediaManager…
sebapique Sep 15, 2025
e7bf699
refactor: Replace console logging with logger in AlternativeMediaCont…
sebapique Sep 15, 2025
f5d1de1
test: crete unit test for switchBackToMainContent logic
sebapique Sep 15, 2025
5d4ca6f
refactor: Enhance MediaManagerMock with improved event handling and r…
sebapique Sep 15, 2025
4c7ead2
Merge branch 'feature/alternative-media-presentations' into alternati…
sebapique Sep 15, 2025
8069607
remove unnecssary changes
sebapique Sep 15, 2025
13a2cc9
Merge pull request #130 from qualabs/alternative-media-presentations/…
cotid-qualabs Sep 16, 2025
6b4c916
Merge pull request #128 from qualabs/alternative-media-presentations/…
cotid-qualabs Sep 16, 2025
7d2029b
Fix mediaManager don't set the configs property
sebastianpiq Sep 16, 2025
6211d8d
fix: modify _onAlternativePlaybackTimeUpdated to use a cloned event o…
sebapique Sep 16, 2025
339ce3a
feat: add setAlternativeVideoElement method to manage alternative vid…
sebastianpiq Sep 18, 2025
302d324
feat: add logging for prebuffering start in MediaManager
sebastianpiq Sep 18, 2025
20e3d8a
executeOnce bugfix (#132)
cotid-qualabs Sep 18, 2025
8eb7f7d
refactor: remove redundant config setting for alternative video element
sebastianpiq Sep 18, 2025
17a6e4a
refactor: remove redundant config setting for alternative video element
sebastianpiq Sep 18, 2025
8e27e27
feat: implement alternative video element support and update related …
sebastianpiq Sep 18, 2025
29bddb2
fix: rename test case
cotid-qualabs Sep 19, 2025
b1e1deb
replace functional test use getCurrentTime
cotid-qualabs Sep 19, 2025
a5ef275
Merge pull request #133 from qualabs/alternative-media-presentations/…
cotid-qualabs Sep 19, 2025
be466f2
add init for alternative media method into the functional tests dash …
sebastianpiq Sep 22, 2025
852a74b
Merge pull request #134 from qualabs/alternative-media-presentations/…
cotid-qualabs Sep 22, 2025
991f292
feat: add setAlternativeVideoElement unit test
sebastianpiq Sep 22, 2025
1e0048e
fix debug import in the MediaManager
sebastianpiq Sep 22, 2025
40dd8f9
refactor: streamline MediaManager instance creation in tests
sebastianpiq Sep 22, 2025
c270d1c
feat: add context variable to MediaManager constructor
sebastianpiq Sep 22, 2025
dd2cf07
fix: ensure MediaManager is initialized in beforeEach
sebastianpiq Sep 22, 2025
1884d4c
test: add getAlternativePlayer test for the MediaManager and fix swit…
sebastianpiq Sep 22, 2025
1fe5d55
fix: update expectation in getAlternativePlayer test to check for und…
sebastianpiq Sep 22, 2025
079e650
test: remove 'only' from getAlternativePlayer tests to ensure all tes…
sebastianpiq Sep 22, 2025
ed82fa9
refactor: clean up comments in getAlternativePlayer test for clarity
sebastianpiq Sep 22, 2025
da35d11
test: add unit test for switchToAlternativeContent and prebufferAlter…
sebastianpiq Sep 22, 2025
686e271
test: implement switch back to main content unit test
sebastianpiq Sep 22, 2025
8fdbd8d
test: Improve MediaManager unit test and add switchBackToMain contet …
sebastianpiq Sep 22, 2025
3224608
add presentation time validation to replace vod
cotid-qualabs Sep 23, 2025
7bf503c
add presentation time validation to insert vod
cotid-qualabs Sep 23, 2025
e8256ce
Merge pull request #136 from qualabs/media-manager-unit-test/set-alte…
cotid-qualabs Sep 23, 2025
90541aa
Merge branch 'alternative-media-presentations/media-manager-unit-test…
sebastianpiq Sep 23, 2025
04f67e0
Revert "Merge branch 'alternative-media-presentations/media-manager-u…
sebastianpiq Sep 23, 2025
9de7d08
Merge pull request #137 from qualabs/media-manager-unit-test/prebuffe…
cotid-qualabs Sep 23, 2025
34ec73d
Merge branch 'alternative-media-presentations/media-manager-unit-test…
sebastianpiq Sep 23, 2025
caac29e
Merge pull request #138 from qualabs/media-manager-unit-test/switch-b…
cotid-qualabs Sep 23, 2025
d093ed8
Merge branch 'feature/alternative-media-presentations' into alternati…
sebastianpiq Sep 23, 2025
80ff9ee
Fix formatting of alternative video element in index.html
sebastianpiq Sep 23, 2025
d6b27f6
Merge pull request #135 from qualabs/alternative-media-presentations/…
cotid-qualabs Sep 23, 2025
456e20c
feat: Implement live to live switch back
sebastianpiq Sep 23, 2025
a909d2f
fix: Correct variable name typo in EventController and remove console…
sebastianpiq Sep 25, 2025
c871f7f
Merge pull request #139 from qualabs/alternative-media-presentations/…
cotid-qualabs Sep 25, 2025
6594b70
Alternative media presentations/clip functional test (#140)
cotid-qualabs Sep 26, 2025
16416f2
feat: Add EVENT_UPDATED constant and implement event update handling …
sebastianpiq Oct 2, 2025
70e0ebe
Fix max duration calculation on update event
sebastianpiq Oct 6, 2025
57adcc2
Merge pull request #143 from qualabs/alternative-media-presentations/…
cotid-qualabs Oct 8, 2025
b68b73f
Alternative MPD live to live sample page (#144)
cotid-qualabs Oct 8, 2025
465f9a2
[Alternative media presentations] Playback ended event (#141)
cotid-qualabs Oct 9, 2025
bf31094
Feature MPD update on validity expiration (#68)
cotid-qualabs Oct 9, 2025
7095cc9
add returnOffset functional test (#142)
cotid-qualabs Oct 9, 2025
e4fdc71
Revert "Feature MPD update on validity expiration (#68)"
sebastianpiq Oct 9, 2025
db74be1
Merge pull request #146 from qualabs/revert-68-feature/mpd-update-on-…
cotid-qualabs Oct 9, 2025
1d8f5fd
Add alternative live to live status update functional test (#145)
cotid-qualabs Oct 10, 2025
d758cf3
Add Listen Mode sample and update samples.json with new entry
sebastianpiq Oct 10, 2025
8e42370
Merge branch 'Dash-Industry-Forum:development' into development
cotid-qualabs Oct 14, 2025
f3931c8
Add setAlternativeVideoElement as optional and fix issue restarting t…
sebastianpiq Oct 15, 2025
735ab95
remove unnecessary parameter in addManifestResponseInterceptor
sebastianpiq Oct 15, 2025
36d6359
Merge pull request #147 from qualabs/alternative-media-presentations/…
cotid-qualabs Oct 15, 2025
942efd1
Update alternative media presentations sample and remove obsolete man…
sebastianpiq Oct 15, 2025
8355665
Modify alternative media presentations sample HTML file
sebastianpiq Oct 15, 2025
8a496ea
Merge branch 'Dash-Industry-Forum:development' into development
sebastianpiq Oct 16, 2025
80f2acb
Update href for Alternative Media Presentations sample to point to th…
sebastianpiq Oct 16, 2025
1ef1b90
Merge branch 'development' into feature/alternative-media-presentations
sebastianpiq Oct 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
433 changes: 433 additions & 0 deletions samples/alternative/alternative-media-presentations.html

Large diffs are not rendered by default.

372 changes: 372 additions & 0 deletions samples/alternative/listen-mode.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,372 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Listen Mode - Alternative Media Presentations</title>

<script src="../../dist/modern/umd/dash.all.debug.js"></script>

<!-- Bootstrap core CSS -->
<link href="../lib/bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="../lib/main.css" rel="stylesheet">

<style>
video {
width: 640px;
height: 360px;
}

#alternative-video-element {
display: none;
}

#manifestViewer {
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
background: #1e1e1e;
color: #dcdcdc;
padding: 1em;
white-space: pre;
overflow: auto;
border: 1px solid #444;
font-size: 10px;
border-radius: 4px;
max-height: 400px;
}
#manifestViewer .token\.tag { color: #569CD6; }
#manifestViewer .token\.attr-name { color: #9CDCFE; }
#manifestViewer .token\.attr-value { color: #CE9178; }
#manifestViewer .token\.text { color: #D4D4D4; }
#manifestViewer .token\.altmpd { color: #06ff06; }
#manifestViewer .token\.altmpd-bg { background-color: rgb(36, 179, 36); }

.event-config {
background-color: #f8f9fa;
padding: 15px;
border-radius: 5px;
margin-bottom: 15px;
border: 1px solid #dee2e6;
}

.form-label {
font-weight: bold;
margin-bottom: 5px;
}

#statusMessage {
margin-top: 15px;
font-weight: bold;
}
</style>
</head>
<body>

<main>
<div class="container py-4">
<header class="pb-3 mb-4 border-bottom">
<img class=""
src="../lib/img/dashjs-logo.png"
width="200">
</header>
<div class="row">
<div class="col-md-6">
<div class="h-100 p-5 bg-light border rounded-3">
<h3>Listen Mode - Alternative Media Presentations</h3>
<p>A sample demonstrating listen mode where an alternative content can be replaced without maxDuration, and then a status update can add maxDuration to return to original content.</p>

<div class="event-config">
<h5>Stream Configuration</h5>
<div class="mb-3">
<label class="form-label">Main Live Stream URL:</label>
<input type="text" id="manifestUrl" class="form-control" value="https://livesim.dashif.org/livesim/testpic_2s/Manifest.mpd" />
</div>

<div class="mb-3">
<label class="form-label">Alternative Live Stream URL:</label>
<input type="text" id="alternativeUrl" class="form-control" value="https://d10gktn8v7end7.cloudfront.net/out/v1/6ee19df3afa24fe190a8ae16c2c88560/index.mpd" />
</div>

<div class="mb-3">
<label class="form-label">Time Offset (seconds):</label>
<input type="number" id="timeOffset" class="form-control" value="10" min="5" max="300" />
<small class="text-muted">Time from now to trigger replace event</small>
</div>

<div class="mt-3">
<button id="loadPlayer" class="btn btn-success">Load Player</button>
<button id="returnButton" class="btn btn-warning ms-2" disabled>End Alternative</button>
</div>

<div id="statusMessage" class="alert alert-info mt-3" style="display: none;"></div>
</div>
</div>
</div>
<div class="col-md-6">
<video id="video-element" controls="true"></video>
<video id="alternative-video-element" controls="true"></video>

<div class="mt-3">
<h6>Generated Manifest Events:</h6>
<div id="manifestViewer">No events configured yet...</div>
</div>
</div>
</div>
<footer class="pt-3 mt-4 text-muted border-top">
&copy; DASH-IF
</footer>
</div>
</main>

<script class="code">
let player;
let replaceEvent = null;
let eventId = 0;
const DEFAULT_DURATION = 10000; // 10 seconds
const DEFAULT_RETURN_OFFSET = 10000; // 10 seconds
const DEFAULT_EARLIEST_RESOLUTION_TIME_OFFSET = 3000; // 3 seconds

function init() {
setupEventListeners();
}

function setupEventListeners() {
const returnBtn = document.getElementById('returnButton');
const loadPlayerBtn = document.getElementById('loadPlayer');

returnBtn.addEventListener('click', returnToOriginal);
loadPlayerBtn.addEventListener('click', loadPlayer);
}

function showStatus(message, type = 'info') {
const statusDiv = document.getElementById('statusMessage');
statusDiv.textContent = message;
statusDiv.className = `alert alert-${type} mt-3`;
statusDiv.style.display = 'block';
}

function updateManifestViewer() {
const viewer = document.getElementById('manifestViewer');

if (!replaceEvent) {
viewer.textContent = 'No events configured yet...';
return;
}

let statusAttr = replaceEvent.hasMaxDuration ? ' status="update"' : '';
let maxDurationAttr = replaceEvent.hasMaxDuration ? `\n maxDuration="0"` : '';

let manifestXml = `
<EventStream schemeIdUri="urn:mpeg:dash:event:alternativeMPD:replace:2025" timescale="1000">
<Event presentationTime="${replaceEvent.presentationTime}" duration="${DEFAULT_DURATION}" id="${replaceEvent.id}"${statusAttr}>
<ReplacePresentation
url="${replaceEvent.alternativeUrl}"
earliestResolutionTimeOffset="${DEFAULT_EARLIEST_RESOLUTION_TIME_OFFSET}"
returnOffset="${DEFAULT_RETURN_OFFSET}"${maxDurationAttr}
clip="false"
startAtPlayhead="true" />
</Event>
</EventStream>`;

// Format and highlight the XML
let highlighted = manifestXml
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/(&lt;\/?)(\w+)(.*?)(\/?&gt;)/g, (match, open, tagName, attrs, close) => {
let isAltMpd = (tagName === "ReplacePresentation");
let coloredTag = `<span class="token.tag${isAltMpd ? ' token.altmpd' : ''}">${open}${tagName}</span>`;
if (attrs.trim().length > 0) {
attrs = attrs.replace(/(\w+)="(.*?)"/g, `<span class="token.attr-name">$1</span>="<span class="token.attr-value">$2</span>"`);
coloredTag += attrs;
}
coloredTag += `<span class="token.tag${isAltMpd ? ' token.altmpd' : ''}">${close}</span>`;
return coloredTag;
});

viewer.innerHTML = highlighted;
}


function returnToOriginal() {
if (!player) {
showStatus('Please load the player first', 'danger');
return;
}

if (!replaceEvent) {
showStatus('No replace event to update', 'danger');
return;
}

// Apply the maxDuration status update
applyMaxDurationUpdate(replaceEvent);

// Disable return button
document.getElementById('returnButton').disabled = true;
}

function applyMaxDurationUpdate(eventToUpdate) {
// Mark the event as having maxDuration in our tracking object
// The response interceptor will include this in subsequent manifest requests
eventToUpdate.hasMaxDuration = true;
updateManifestViewer();

showStatus(`Status update sent. Main content will return soon.`, 'warning');
}

function addManifestResponseInterceptor() {
const interceptor = (response) => {
// Only intercept MPD manifest requests
if (response.request?.customData?.request?.type === 'MPD' && replaceEvent) {
try {
let xmlString = response.data;
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');

// Get the Period element
const period = xmlDoc.querySelector('Period');
if (!period) {
return Promise.resolve(response);
}

// Remove existing alternative MPD event streams
const existingEventStreams = period.querySelectorAll('EventStream[schemeIdUri="urn:mpeg:dash:event:alternativeMPD:replace:2025"]');
existingEventStreams.forEach(es => es.remove());

// Create the EventStream element
const eventStream = xmlDoc.createElement('EventStream');
eventStream.setAttribute('schemeIdUri', 'urn:mpeg:dash:event:alternativeMPD:replace:2025');
eventStream.setAttribute('timescale', '1000');

// Create the Event element
const event = xmlDoc.createElement('Event');
event.setAttribute('id', replaceEvent.id);
event.setAttribute('presentationTime', replaceEvent.presentationTime);
event.setAttribute('duration', DEFAULT_DURATION);

// Add status if maxDuration is set
if (replaceEvent.hasMaxDuration) {
event.setAttribute('status', 'update');
}

// Create the ReplacePresentation element
const replacePresentation = xmlDoc.createElement('ReplacePresentation');
replacePresentation.setAttribute('url', replaceEvent.alternativeUrl);
replacePresentation.setAttribute('earliestResolutionTimeOffset', DEFAULT_EARLIEST_RESOLUTION_TIME_OFFSET);
replacePresentation.setAttribute('returnOffset', DEFAULT_RETURN_OFFSET);
replacePresentation.setAttribute('clip', 'false');
replacePresentation.setAttribute('startAtPlayhead', 'true');

// Add maxDuration if the event has been updated
if (replaceEvent.hasMaxDuration) {
replacePresentation.setAttribute('maxDuration', '0');
}

// Assemble the elements
event.appendChild(replacePresentation);
eventStream.appendChild(event);
period.appendChild(eventStream);

// Serialize back to XML string
const serializer = new XMLSerializer();
response.data = serializer.serializeToString(xmlDoc);

} catch (error) {
console.error('Error modifying manifest:', error);
}
}

return Promise.resolve(response);
};

player.addResponseInterceptor(interceptor);
}

function loadPlayer() {
const manifestUrl = document.getElementById('manifestUrl').value;
const alternativeUrl = document.getElementById('alternativeUrl').value;
const timeOffset = parseInt(document.getElementById('timeOffset').value);
const video = document.getElementById('video-element');
const alternativeVideo = document.getElementById('alternative-video-element');
const returnButton = document.getElementById('returnButton');
const loadButton = document.getElementById('loadPlayer');

// Clean up existing player
if (player) {
player.reset();
}

// Reset button states during load
returnButton.disabled = true;

// Create the replace event automatically
const presentationTime = Date.now() + (timeOffset * 1000);

replaceEvent = {
id: eventId,
presentationTime: presentationTime,
alternativeUrl: alternativeUrl,
hasMaxDuration: false,
timeOffset: timeOffset
};

updateManifestViewer();

// Set video attributes
video.setAttribute('controls', 'true');
video.setAttribute('autoplay', '');
video.setAttribute('muted', '');

// Create new player following the correct sequence
player = dashjs.MediaPlayer().create();
window.player = player;

// Initialize first (without parameters)
player.initialize();

// Set alternative video element
player.setAlternativeVideoElement(alternativeVideo);

// Attach the main video view
player.attachView(video);

// Configure settings
player.updateSettings({
streaming: {
text: {
dispatchForManualRendering: true
}
}
});

// Add response interceptor to modify manifest dynamically
addManifestResponseInterceptor(manifestUrl);

// Set up event listeners
player.on('alternativeMpdContentStart', (data) => {
showStatus('Alternative content started!', 'info');
});

player.on('alternativeMpdContentEnd', (data) => {
showStatus('Returned to original content', 'success');
});

player.on('error', (e) => {
showStatus(`Player error: ${e.error}`, 'danger');
});

// Attach source directly with URL
player.attachSource(manifestUrl);

// Enable End Alternative button after player is loaded
returnButton.disabled = false;
loadButton.textContent = 'Reload Player';
showStatus(`Player loaded. Replace event will trigger in ${timeOffset} seconds (no maxDuration).`, 'success');
}

document.addEventListener('DOMContentLoaded', function () {
init();
});
</script>
<script src="../highlighter.js"></script>
</body>
</html>
Loading