shaka-player 4.6.12 → 4.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +14 -12
- package/demo/common/assets.js +3 -1
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +5 -5
- package/dist/demo.compiled.debug.map +1 -1
- package/dist/demo.compiled.js +5 -5
- package/dist/demo.compiled.map +1 -1
- package/dist/deps.js +1 -1
- package/dist/locales.js +31 -31
- package/dist/receiver.compiled.debug.js +5 -5
- package/dist/receiver.compiled.debug.map +1 -1
- package/dist/receiver.compiled.js +5 -5
- package/dist/receiver.compiled.map +1 -1
- package/dist/shaka-player.compiled.debug.js +11 -11
- package/dist/shaka-player.compiled.debug.map +2 -2
- package/dist/shaka-player.compiled.js +1013 -1011
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +1 -1
- package/dist/shaka-player.ui.debug.d.ts +1 -1
- package/dist/shaka-player.ui.debug.js +91 -101
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.js +1241 -1246
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/ui-customization.md +0 -13
- package/lib/dash/dash_parser.js +1 -1
- package/lib/media/content_workarounds.js +24 -0
- package/lib/player.js +11 -2
- package/package.json +1 -1
- package/test/dash/dash_parser_live_unit.js +19 -0
- package/test/player_integration.js +46 -40
- package/ui/externs/ui.js +1 -10
- package/ui/less/range_elements.less +0 -33
- package/ui/seek_bar.js +0 -212
- package/ui/ui.js +0 -2
|
@@ -188,19 +188,6 @@ const config = {
|
|
|
188
188
|
ui.configure(config);
|
|
189
189
|
```
|
|
190
190
|
|
|
191
|
-
If you've chosen to display chapters, you can specify the color for the chapter markers on
|
|
192
|
-
the timeline and the text color of the chapter titles that popup on hover:
|
|
193
|
-
```js
|
|
194
|
-
const config = {
|
|
195
|
-
displayChapters: true,
|
|
196
|
-
seekBarColors: {
|
|
197
|
-
chapterMarks: 'rgb(27, 27, 27)',
|
|
198
|
-
chapterLabels: 'rgb(255, 255, 255)'
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
ui.configure(config);
|
|
202
|
-
```
|
|
203
|
-
|
|
204
191
|
#### Configuring playback, fast forward and rewind rates
|
|
205
192
|
The rate in which the player can play, fast forward and rewind content can be configured using the `playbackRates`, `fastForwardRates` and `rewindRates` options.
|
|
206
193
|
|
package/lib/dash/dash_parser.js
CHANGED
|
@@ -1640,7 +1640,7 @@ shaka.dash.DashParser = class {
|
|
|
1640
1640
|
// An attribute which is present and set to 0 should still result in
|
|
1641
1641
|
// periodic updates. For more, see:
|
|
1642
1642
|
// https://github.com/Dash-Industry-Forum/Guidelines-TimingModel/issues/48
|
|
1643
|
-
if (this.updatePeriod_
|
|
1643
|
+
if (this.updatePeriod_ < 0) {
|
|
1644
1644
|
return;
|
|
1645
1645
|
}
|
|
1646
1646
|
|
|
@@ -69,6 +69,30 @@ shaka.media.ContentWorkarounds = class {
|
|
|
69
69
|
})
|
|
70
70
|
.fullBox('encv', onEncryptionMetadataBox)
|
|
71
71
|
.fullBox('enca', onEncryptionMetadataBox)
|
|
72
|
+
.fullBox('dvav', (box) => {
|
|
73
|
+
boxesToModify.push({
|
|
74
|
+
box,
|
|
75
|
+
newType: ContentWorkarounds.BOX_TYPE_ENCV_,
|
|
76
|
+
});
|
|
77
|
+
})
|
|
78
|
+
.fullBox('dva1', (box) => {
|
|
79
|
+
boxesToModify.push({
|
|
80
|
+
box,
|
|
81
|
+
newType: ContentWorkarounds.BOX_TYPE_ENCV_,
|
|
82
|
+
});
|
|
83
|
+
})
|
|
84
|
+
.fullBox('dvh1', (box) => {
|
|
85
|
+
boxesToModify.push({
|
|
86
|
+
box,
|
|
87
|
+
newType: ContentWorkarounds.BOX_TYPE_ENCV_,
|
|
88
|
+
});
|
|
89
|
+
})
|
|
90
|
+
.fullBox('dvhe', (box) => {
|
|
91
|
+
boxesToModify.push({
|
|
92
|
+
box,
|
|
93
|
+
newType: ContentWorkarounds.BOX_TYPE_ENCV_,
|
|
94
|
+
});
|
|
95
|
+
})
|
|
72
96
|
.fullBox('hev1', (box) => {
|
|
73
97
|
boxesToModify.push({
|
|
74
98
|
box,
|
package/lib/player.js
CHANGED
|
@@ -1779,8 +1779,17 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1779
1779
|
|
|
1780
1780
|
this.drmEngine_.configure(this.config_.drm);
|
|
1781
1781
|
|
|
1782
|
+
const tracksChanged = shaka.util.StreamUtils.applyRestrictions(
|
|
1783
|
+
this.manifest_.variants, this.config_.restrictions, this.maxHwRes_);
|
|
1784
|
+
if (tracksChanged && this.streamingEngine_) {
|
|
1785
|
+
this.onTracksChanged_();
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
const playableVariants = shaka.util.StreamUtils.getPlayableVariants(
|
|
1789
|
+
this.manifest_.variants);
|
|
1790
|
+
|
|
1782
1791
|
await this.drmEngine_.initForPlayback(
|
|
1783
|
-
|
|
1792
|
+
playableVariants,
|
|
1784
1793
|
this.manifest_.offlineSessionIds);
|
|
1785
1794
|
|
|
1786
1795
|
await this.drmEngine_.attach(this.video_);
|
|
@@ -6828,7 +6837,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6828
6837
|
* @export
|
|
6829
6838
|
*/
|
|
6830
6839
|
// eslint-disable-next-line no-useless-concat
|
|
6831
|
-
shaka.Player.version = 'v4.6.
|
|
6840
|
+
shaka.Player.version = 'v4.6.13' + '-uncompiled'; // x-release-please-version
|
|
6832
6841
|
|
|
6833
6842
|
// Initialize the deprecation system using the version string we just set
|
|
6834
6843
|
// on the player.
|
package/package.json
CHANGED
|
@@ -642,6 +642,25 @@ describe('DashParser Live', () => {
|
|
|
642
642
|
expect(updateTick).toHaveBeenCalledTimes(1);
|
|
643
643
|
});
|
|
644
644
|
|
|
645
|
+
it('still updates when @minimumUpdatePeriod is zero', async () => {
|
|
646
|
+
const lines = [
|
|
647
|
+
'<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
|
|
648
|
+
];
|
|
649
|
+
// updateTime parameter sets @minimumUpdatePeriod in the manifest.
|
|
650
|
+
const manifestText = makeSimpleLiveManifestText(lines, /* updateTime= */ 0);
|
|
651
|
+
|
|
652
|
+
/** @type {!jasmine.Spy} */
|
|
653
|
+
const tickAfter = updateTickSpy();
|
|
654
|
+
Date.now = () => 0;
|
|
655
|
+
|
|
656
|
+
fakeNetEngine.setResponseText('dummy://foo', manifestText);
|
|
657
|
+
await parser.start('dummy://foo', playerInterface);
|
|
658
|
+
|
|
659
|
+
expect(tickAfter).toHaveBeenCalledTimes(1);
|
|
660
|
+
const delay = tickAfter.calls.mostRecent().args[0];
|
|
661
|
+
expect(delay).toBe(0);
|
|
662
|
+
});
|
|
663
|
+
|
|
645
664
|
it('uses @minimumUpdatePeriod', async () => {
|
|
646
665
|
const lines = [
|
|
647
666
|
'<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
|
|
@@ -61,6 +61,46 @@ describe('Player', () => {
|
|
|
61
61
|
document.body.removeChild(video);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
+
describe('seek range', () => {
|
|
65
|
+
// Regression test for Issue #3675.
|
|
66
|
+
it('has a reasonable seek range after going from live to VOD', async () => {
|
|
67
|
+
const netEngine = player.getNetworkingEngine();
|
|
68
|
+
const startTime = Date.now();
|
|
69
|
+
netEngine.registerRequestFilter((type, request) => {
|
|
70
|
+
if (type != shaka.net.NetworkingEngine.RequestType.MANIFEST) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Simulate a live stream by providing different manifests over time.
|
|
74
|
+
const time = (Date.now() - startTime) / 1000;
|
|
75
|
+
const manifestNumber = Math.min(5, Math.floor(0.5 + time / 2));
|
|
76
|
+
request.uris = [
|
|
77
|
+
'/base/test/test/assets/3675/dash_' + manifestNumber + '.mpd',
|
|
78
|
+
];
|
|
79
|
+
console.log('getting manifest', request.uris);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Play the stream.
|
|
83
|
+
await player.load('/base/test/test/assets/3675/dash_0.mpd');
|
|
84
|
+
await video.play();
|
|
85
|
+
|
|
86
|
+
// Wait for the stream to be over.
|
|
87
|
+
eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy));
|
|
88
|
+
/** @type {shaka.test.Waiter} */
|
|
89
|
+
const waiter = new shaka.test.Waiter(eventManager)
|
|
90
|
+
.setPlayer(player)
|
|
91
|
+
.timeoutAfter(40)
|
|
92
|
+
.failOnTimeout(true);
|
|
93
|
+
await waiter.waitForEnd(video);
|
|
94
|
+
|
|
95
|
+
// The stream should have transitioned to VOD by now.
|
|
96
|
+
expect(player.isLive()).toBe(false);
|
|
97
|
+
|
|
98
|
+
// Check that the final seek range is as expected.
|
|
99
|
+
const seekRange = player.seekRange();
|
|
100
|
+
expect(seekRange.end).toBeCloseTo(14);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
64
104
|
describe('attach', () => {
|
|
65
105
|
beforeEach(async () => {
|
|
66
106
|
// To test attach, we want to construct a player without a video element
|
|
@@ -908,46 +948,6 @@ describe('Player', () => {
|
|
|
908
948
|
});
|
|
909
949
|
});
|
|
910
950
|
|
|
911
|
-
describe('seek range', () => {
|
|
912
|
-
// Regression test for Issue #3675.
|
|
913
|
-
it('has a reasonable seek range after going from live to VOD', async () => {
|
|
914
|
-
const netEngine = player.getNetworkingEngine();
|
|
915
|
-
const startTime = Date.now();
|
|
916
|
-
netEngine.registerRequestFilter((type, request) => {
|
|
917
|
-
if (type != shaka.net.NetworkingEngine.RequestType.MANIFEST) {
|
|
918
|
-
return;
|
|
919
|
-
}
|
|
920
|
-
// Simulate a live stream by providing different manifests over time.
|
|
921
|
-
const time = (Date.now() - startTime) / 1000;
|
|
922
|
-
const manifestNumber = Math.min(5, Math.floor(0.5 + time / 2));
|
|
923
|
-
request.uris = [
|
|
924
|
-
'/base/test/test/assets/3675/dash_' + manifestNumber + '.mpd',
|
|
925
|
-
];
|
|
926
|
-
console.log('getting manifest', request.uris);
|
|
927
|
-
});
|
|
928
|
-
|
|
929
|
-
// Play the stream.
|
|
930
|
-
await player.load('/base/test/test/assets/3675/dash_0.mpd');
|
|
931
|
-
await video.play();
|
|
932
|
-
|
|
933
|
-
// Wait for the stream to be over.
|
|
934
|
-
eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy));
|
|
935
|
-
/** @type {shaka.test.Waiter} */
|
|
936
|
-
const waiter = new shaka.test.Waiter(eventManager)
|
|
937
|
-
.setPlayer(player)
|
|
938
|
-
.timeoutAfter(40)
|
|
939
|
-
.failOnTimeout(true);
|
|
940
|
-
await waiter.waitForEnd(video);
|
|
941
|
-
|
|
942
|
-
// The stream should have transitioned to VOD by now.
|
|
943
|
-
expect(player.isLive()).toBe(false);
|
|
944
|
-
|
|
945
|
-
// Check that the final seek range is as expected.
|
|
946
|
-
const seekRange = player.seekRange();
|
|
947
|
-
expect(seekRange.end).toBeCloseTo(14);
|
|
948
|
-
});
|
|
949
|
-
});
|
|
950
|
-
|
|
951
951
|
describe('buffering', () => {
|
|
952
952
|
const startBuffering = jasmine.objectContaining({buffering: true});
|
|
953
953
|
const endBuffering = jasmine.objectContaining({buffering: false});
|
|
@@ -1012,6 +1012,9 @@ describe('Player', () => {
|
|
|
1012
1012
|
});
|
|
1013
1013
|
|
|
1014
1014
|
it('buffers ahead of the playhead', async () => {
|
|
1015
|
+
if (window.ManagedMediaSource) {
|
|
1016
|
+
pending('ManagedMediaSource has buffer control signals.');
|
|
1017
|
+
}
|
|
1015
1018
|
player.configure('streaming.bufferingGoal', 10);
|
|
1016
1019
|
|
|
1017
1020
|
await player.load('test:sintel_long_compiled');
|
|
@@ -1036,6 +1039,9 @@ describe('Player', () => {
|
|
|
1036
1039
|
});
|
|
1037
1040
|
|
|
1038
1041
|
it('clears buffer behind playhead', async () => {
|
|
1042
|
+
if (window.ManagedMediaSource) {
|
|
1043
|
+
pending('ManagedMediaSource has buffer control signals.');
|
|
1044
|
+
}
|
|
1039
1045
|
player.configure('streaming.bufferingGoal', 30);
|
|
1040
1046
|
player.configure('streaming.bufferBehind', 30);
|
|
1041
1047
|
|
package/ui/externs/ui.js
CHANGED
|
@@ -21,9 +21,7 @@ shaka.extern = {};
|
|
|
21
21
|
* base: string,
|
|
22
22
|
* buffered: string,
|
|
23
23
|
* played: string,
|
|
24
|
-
* adBreaks: string
|
|
25
|
-
* chapterMarks: string,
|
|
26
|
-
* chapterLabels: string
|
|
24
|
+
* adBreaks: string
|
|
27
25
|
* }}
|
|
28
26
|
*
|
|
29
27
|
* @property {string} base
|
|
@@ -38,13 +36,6 @@ shaka.extern = {};
|
|
|
38
36
|
* @property {string} adBreaks
|
|
39
37
|
* The CSS background color applied to the portion of the seek bar showing
|
|
40
38
|
* when the ad breaks are scheduled to occur on the timeline.
|
|
41
|
-
* @property {string} chapterMarks
|
|
42
|
-
* The CSS border color applied to sections of the seek bar showing
|
|
43
|
-
* when the chapters start and end on the timeline.
|
|
44
|
-
* Defaults to dark grey rgb(27, 27, 27).
|
|
45
|
-
* @property {string} chapterLabels
|
|
46
|
-
* The CSS text color applied to the chapter labels that appear above the
|
|
47
|
-
* seek bar on hover. Defaults to white rgb(255, 255, 255).
|
|
48
39
|
* @exportDoc
|
|
49
40
|
*/
|
|
50
41
|
shaka.extern.UISeekBarColors;
|
|
@@ -154,36 +154,3 @@
|
|
|
154
154
|
.shaka-ad-markers {
|
|
155
155
|
.overlay-child();
|
|
156
156
|
}
|
|
157
|
-
|
|
158
|
-
#shaka-player-ui-chapters-container {
|
|
159
|
-
width: 100%;
|
|
160
|
-
height: 100%;
|
|
161
|
-
display: flex;
|
|
162
|
-
flex-direction: row;
|
|
163
|
-
z-index: 0;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.shaka-chapter {
|
|
167
|
-
height: 100%;
|
|
168
|
-
position: relative;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.shaka-chapter-label {
|
|
172
|
-
position: relative;
|
|
173
|
-
top: -2.5em;
|
|
174
|
-
width: 100%;
|
|
175
|
-
text-align: center;
|
|
176
|
-
text-shadow: 1px 1px gray;
|
|
177
|
-
line-height: normal;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.shaka-chapter > div:first-child {
|
|
181
|
-
width: 100%;
|
|
182
|
-
height: 100%;
|
|
183
|
-
border-right: 1px solid;
|
|
184
|
-
position: absolute;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
.shaka-chapter:last-child > div:first-child {
|
|
188
|
-
border-right: none;
|
|
189
|
-
}
|
package/ui/seek_bar.js
CHANGED
|
@@ -16,7 +16,6 @@ goog.require('shaka.ui.RangeElement');
|
|
|
16
16
|
goog.require('shaka.ui.Utils');
|
|
17
17
|
goog.require('shaka.util.Dom');
|
|
18
18
|
goog.require('shaka.util.Error');
|
|
19
|
-
goog.require('shaka.util.EventManager');
|
|
20
19
|
goog.require('shaka.util.Mp4Parser');
|
|
21
20
|
goog.require('shaka.util.Networking');
|
|
22
21
|
goog.require('shaka.util.Timer');
|
|
@@ -84,18 +83,6 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
|
|
|
84
83
|
this.markAdBreaks_();
|
|
85
84
|
});
|
|
86
85
|
|
|
87
|
-
/**
|
|
88
|
-
* @private {shaka.util.EventManager}
|
|
89
|
-
*/
|
|
90
|
-
this.chaptersEventManager_ = new shaka.util.EventManager();
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/** @private {!HTMLElement} */
|
|
94
|
-
this.chaptersContainer_ = shaka.util.Dom.createHTMLElement('div');
|
|
95
|
-
this.chaptersContainer_.id = 'shaka-player-ui-chapters-container';
|
|
96
|
-
this.container.appendChild(this.chaptersContainer_);
|
|
97
|
-
|
|
98
|
-
this.setupChapters_();
|
|
99
86
|
|
|
100
87
|
/**
|
|
101
88
|
* When user is scrubbing the seek bar - we should pause the video - see
|
|
@@ -238,8 +225,6 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
|
|
|
238
225
|
this.adBreaksTimer_ = null;
|
|
239
226
|
}
|
|
240
227
|
|
|
241
|
-
this.chaptersEventManager_.release();
|
|
242
|
-
|
|
243
228
|
super.release();
|
|
244
229
|
}
|
|
245
230
|
|
|
@@ -693,203 +678,6 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
|
|
|
693
678
|
return minutes + ':' + seconds;
|
|
694
679
|
}
|
|
695
680
|
}
|
|
696
|
-
|
|
697
|
-
/**
|
|
698
|
-
* Sets up the chapter element creator and change handling.
|
|
699
|
-
* @private
|
|
700
|
-
*/
|
|
701
|
-
setupChapters_() {
|
|
702
|
-
let language = 'und';
|
|
703
|
-
/** @type {!Array<shaka.extern.Chapter>} */
|
|
704
|
-
let chapters = [];
|
|
705
|
-
|
|
706
|
-
/**
|
|
707
|
-
* Does a value compare on chapters.
|
|
708
|
-
* @param {shaka.extern.Chapter} a
|
|
709
|
-
* @param {shaka.extern.Chapter} b
|
|
710
|
-
* @return {boolean}
|
|
711
|
-
*/
|
|
712
|
-
const chaptersEqual = (a, b) => {
|
|
713
|
-
return (!a && !b) || (a.id === b.id && a.title === b.title &&
|
|
714
|
-
a.startTime === b.startTime && a.endTime === b.endTime);
|
|
715
|
-
};
|
|
716
|
-
|
|
717
|
-
/** @type {function(): void} */
|
|
718
|
-
const handleChapterTrackChange = () => {
|
|
719
|
-
let nextLanguage = 'und';
|
|
720
|
-
/** @type {!Array<shaka.extern.Chapter>} */
|
|
721
|
-
let nextChapters = [];
|
|
722
|
-
|
|
723
|
-
const currentLocales = this.localization.getCurrentLocales();
|
|
724
|
-
for (const locale of Array.from(currentLocales)) {
|
|
725
|
-
nextLanguage = locale;
|
|
726
|
-
nextChapters = this.player.getChapters(nextLanguage);
|
|
727
|
-
if (nextChapters.length) {
|
|
728
|
-
break;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
if (!nextChapters.length) {
|
|
732
|
-
nextLanguage = 'und';
|
|
733
|
-
nextChapters = this.player.getChapters(nextLanguage);
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
const languageChanged = nextLanguage !== language;
|
|
737
|
-
const chaptersChanged = chapters.length !== nextChapters.length ||
|
|
738
|
-
!chapters.some((c, idx) => {
|
|
739
|
-
const n = nextChapters.at(idx);
|
|
740
|
-
return chaptersEqual(c, n) ||
|
|
741
|
-
nextChapters.some((n) => chaptersEqual(c, n));
|
|
742
|
-
});
|
|
743
|
-
|
|
744
|
-
language = nextLanguage;
|
|
745
|
-
chapters = nextChapters;
|
|
746
|
-
if (!nextChapters.length) {
|
|
747
|
-
this.deletePreviousChapters_();
|
|
748
|
-
} else if (languageChanged || chaptersChanged) {
|
|
749
|
-
this.createChapterElements_(this.container, chapters);
|
|
750
|
-
}
|
|
751
|
-
};
|
|
752
|
-
|
|
753
|
-
handleChapterTrackChange();
|
|
754
|
-
|
|
755
|
-
this.eventManager.listen(
|
|
756
|
-
this.player, 'unloading', () => {
|
|
757
|
-
this.deletePreviousChapters_();
|
|
758
|
-
language = 'und';
|
|
759
|
-
chapters = [];
|
|
760
|
-
});
|
|
761
|
-
|
|
762
|
-
this.eventManager.listen(
|
|
763
|
-
this.player, 'trackschanged', handleChapterTrackChange);
|
|
764
|
-
|
|
765
|
-
this.eventManager.listen(
|
|
766
|
-
this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
|
|
767
|
-
handleChapterTrackChange();
|
|
768
|
-
});
|
|
769
|
-
|
|
770
|
-
this.eventManager.listen(
|
|
771
|
-
this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
|
|
772
|
-
handleChapterTrackChange();
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
/**
|
|
777
|
-
* Builds and inserts ChaptersElement into dom container.
|
|
778
|
-
* @param {!HTMLElement} container
|
|
779
|
-
* @param {!Array<shaka.extern.Chapter>} chapterTracks
|
|
780
|
-
* @private
|
|
781
|
-
*/
|
|
782
|
-
createChapterElements_(container, chapterTracks) {
|
|
783
|
-
this.deletePreviousChapters_();
|
|
784
|
-
|
|
785
|
-
const hiddenClass = 'shaka-hidden';
|
|
786
|
-
|
|
787
|
-
/** @type {{start: number, end: number}} */
|
|
788
|
-
const seekRange = this.player.seekRange();
|
|
789
|
-
|
|
790
|
-
/**
|
|
791
|
-
* @type {!Array<{
|
|
792
|
-
* start: number,
|
|
793
|
-
* end: number,
|
|
794
|
-
* size: number,
|
|
795
|
-
* title: string,
|
|
796
|
-
* id: string
|
|
797
|
-
* }>}
|
|
798
|
-
* */
|
|
799
|
-
const chapters = [];
|
|
800
|
-
|
|
801
|
-
for (const c of chapterTracks) {
|
|
802
|
-
if (c.startTime >= seekRange.end) {
|
|
803
|
-
continue;
|
|
804
|
-
}
|
|
805
|
-
const start = c.startTime > seekRange.start ?
|
|
806
|
-
c.startTime : seekRange.start;
|
|
807
|
-
const end = c.endTime < seekRange.end ?
|
|
808
|
-
c.endTime : seekRange.end;
|
|
809
|
-
const size = (end-start);
|
|
810
|
-
chapters.push({start, end, size, title: c.title, id: c.id});
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
if (chapters.length < 2) {
|
|
814
|
-
return;
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
const totalSize = chapters.reduce((t, c) => {
|
|
818
|
-
t += c.size;
|
|
819
|
-
return t;
|
|
820
|
-
}, 0);
|
|
821
|
-
|
|
822
|
-
/**
|
|
823
|
-
* @type {!Array<{
|
|
824
|
-
* start: number,
|
|
825
|
-
* end: number,
|
|
826
|
-
* el: HTMLElement
|
|
827
|
-
* }>}
|
|
828
|
-
* */
|
|
829
|
-
const chapterElMap = [];
|
|
830
|
-
|
|
831
|
-
for (const c of chapters) {
|
|
832
|
-
/** @type {!HTMLElement} */
|
|
833
|
-
const chapterEl = shaka.util.Dom.createHTMLElement('div');
|
|
834
|
-
chapterEl.classList.add('shaka-chapter');
|
|
835
|
-
chapterEl.style.width = `${c.size * 100 / totalSize}%`;
|
|
836
|
-
|
|
837
|
-
this.chaptersContainer_.appendChild(chapterEl);
|
|
838
|
-
|
|
839
|
-
/** @type {!HTMLElement} */
|
|
840
|
-
const chapterMarker = shaka.util.Dom.createHTMLElement('div');
|
|
841
|
-
chapterMarker.style.borderColor =
|
|
842
|
-
this.config_.seekBarColors.chapterMarks;
|
|
843
|
-
chapterEl.appendChild(chapterMarker);
|
|
844
|
-
|
|
845
|
-
/** @type {!HTMLElement} */
|
|
846
|
-
const chapterLabel = shaka.util.Dom.createHTMLElement('p');
|
|
847
|
-
chapterLabel.classList.add('shaka-chapter-label', hiddenClass);
|
|
848
|
-
chapterLabel.style.color =
|
|
849
|
-
this.config_.seekBarColors.chapterLabels;
|
|
850
|
-
chapterLabel.innerText = c.title;
|
|
851
|
-
chapterEl.appendChild(chapterLabel);
|
|
852
|
-
|
|
853
|
-
chapterElMap.push(
|
|
854
|
-
{start: c.start, end: c.end, el: chapterLabel});
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
// Add chapter event listeners
|
|
858
|
-
this.chaptersEventManager_.listen(this.bar, 'pointermove', (e) => {
|
|
859
|
-
if (!e.target) {
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
const target = /** @type {HTMLElement} */(e.target);
|
|
863
|
-
|
|
864
|
-
const screenXDiff = e.offsetX / target.clientWidth;
|
|
865
|
-
const rangeMax = parseInt(target.getAttribute('max'), 10);
|
|
866
|
-
const hoverVal = screenXDiff * rangeMax;
|
|
867
|
-
|
|
868
|
-
for (const c of chapterElMap) {
|
|
869
|
-
const hidden = c.el.classList.contains(hiddenClass);
|
|
870
|
-
const inChapter = c.start <= hoverVal && hoverVal < c.end;
|
|
871
|
-
if (inChapter === hidden) {
|
|
872
|
-
c.el.classList.toggle(hiddenClass);
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
}, {passive: true});
|
|
876
|
-
|
|
877
|
-
this.chaptersEventManager_.listen(this.bar, 'pointerout', () => {
|
|
878
|
-
for (const c of chapterElMap) {
|
|
879
|
-
if (!c.el.classList.contains(hiddenClass)) {
|
|
880
|
-
c.el.classList.add(hiddenClass);
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
}, {passive: true});
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
/**
|
|
887
|
-
* @private
|
|
888
|
-
*/
|
|
889
|
-
deletePreviousChapters_() {
|
|
890
|
-
this.chaptersEventManager_.removeAll();
|
|
891
|
-
shaka.util.Dom.removeAllChildren(this.chaptersContainer_);
|
|
892
|
-
}
|
|
893
681
|
};
|
|
894
682
|
|
|
895
683
|
|
package/ui/ui.js
CHANGED
|
@@ -229,8 +229,6 @@ shaka.ui.Overlay = class {
|
|
|
229
229
|
buffered: 'rgba(255, 255, 255, 0.54)',
|
|
230
230
|
played: 'rgb(255, 255, 255)',
|
|
231
231
|
adBreaks: 'rgb(255, 204, 0)',
|
|
232
|
-
chapterMarks: 'rgb(27, 27, 27)',
|
|
233
|
-
chapterLabels: 'rgb(255, 255, 255)',
|
|
234
232
|
},
|
|
235
233
|
volumeBarColors: {
|
|
236
234
|
base: 'rgba(255, 255, 255, 0.54)',
|