shaka-player 4.7.8 → 4.7.10
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/AUTHORS +1 -0
- package/CONTRIBUTORS +1 -0
- package/README.md +14 -12
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +1 -1
- package/dist/locales.js +31 -31
- package/dist/shaka-player.compiled.debug.js +84 -84
- package/dist/shaka-player.compiled.debug.map +2 -2
- package/dist/shaka-player.compiled.js +1036 -1035
- 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 +109 -118
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.js +1251 -1257
- package/dist/shaka-player.ui.map +4 -4
- package/lib/dash/dash_parser.js +1 -1
- package/lib/dash/segment_template.js +18 -13
- package/lib/hls/hls_parser.js +2 -2
- package/lib/media/content_workarounds.js +24 -0
- package/lib/media/segment_reference.js +4 -1
- package/lib/media/streaming_engine.js +2 -2
- package/lib/player.js +11 -2
- package/lib/util/cmcd_manager.js +3 -13
- package/lib/util/periods.js +23 -1
- package/lib/util/stream_utils.js +1 -1
- package/package.json +2 -2
- 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
package/lib/dash/dash_parser.js
CHANGED
|
@@ -1685,7 +1685,7 @@ shaka.dash.DashParser = class {
|
|
|
1685
1685
|
// An attribute which is present and set to 0 should still result in
|
|
1686
1686
|
// periodic updates. For more, see:
|
|
1687
1687
|
// https://github.com/Dash-Industry-Forum/Guidelines-TimingModel/issues/48
|
|
1688
|
-
if (this.updatePeriod_
|
|
1688
|
+
if (this.updatePeriod_ < 0) {
|
|
1689
1689
|
return;
|
|
1690
1690
|
}
|
|
1691
1691
|
|
|
@@ -755,16 +755,10 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
755
755
|
|
|
756
756
|
this.evict(this.periodStart_);
|
|
757
757
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
if (this.periodEnd_ !== Infinity) {
|
|
763
|
-
// Adjust the last timeline entry to match the period end
|
|
764
|
-
const lastTimePeriod = timeline[timeline.length - 1];
|
|
765
|
-
// NOTE: end should be relative to period start
|
|
766
|
-
lastTimePeriod.end = this.periodEnd_ - this.periodStart_;
|
|
767
|
-
}
|
|
758
|
+
// Do NOT adjust last range to match period end! With high precision
|
|
759
|
+
// timestamps several recalculations may give wrong results on less precise
|
|
760
|
+
// platforms. To mitigate that, we're using cached |periodEnd_| value in
|
|
761
|
+
// find/get() methods whenever possible.
|
|
768
762
|
}
|
|
769
763
|
|
|
770
764
|
/**
|
|
@@ -784,7 +778,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
784
778
|
const timeline = this.templateInfo_.timeline;
|
|
785
779
|
|
|
786
780
|
// Early exit if the time isn't within this period
|
|
787
|
-
if (time < this.periodStart_ || time
|
|
781
|
+
if (time < this.periodStart_ || time >= this.periodEnd_) {
|
|
788
782
|
return null;
|
|
789
783
|
}
|
|
790
784
|
|
|
@@ -797,10 +791,14 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
797
791
|
// the references by a fraction of a second. To account for this, we use
|
|
798
792
|
// the start of the next segment as /end/, unless this is the last
|
|
799
793
|
// reference, in which case we use the period end as the /end/
|
|
800
|
-
let end
|
|
794
|
+
let end;
|
|
801
795
|
|
|
802
796
|
if (i < lastIndex) {
|
|
803
797
|
end = timeline[i + 1].start + this.periodStart_;
|
|
798
|
+
} else if (this.periodEnd_ === Infinity) {
|
|
799
|
+
end = range.end + this.periodStart_;
|
|
800
|
+
} else {
|
|
801
|
+
end = this.periodEnd_;
|
|
804
802
|
}
|
|
805
803
|
|
|
806
804
|
if ((time >= start) && (time < end)) {
|
|
@@ -831,6 +829,12 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
831
829
|
.unscaledPresentationTimeOffset + range.unscaledStart;
|
|
832
830
|
const timestampOffset = this.periodStart_ -
|
|
833
831
|
this.templateInfo_.scaledPresentationTimeOffset;
|
|
832
|
+
const trueSegmentEnd = this.periodStart_ + range.end;
|
|
833
|
+
let segmentEnd = trueSegmentEnd;
|
|
834
|
+
if (correctedPosition === this.getNumReferences() - 1 &&
|
|
835
|
+
this.periodEnd_ !== Infinity) {
|
|
836
|
+
segmentEnd = this.periodEnd_;
|
|
837
|
+
}
|
|
834
838
|
|
|
835
839
|
const partialSegmentRefs = [];
|
|
836
840
|
|
|
@@ -901,7 +905,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
901
905
|
|
|
902
906
|
ref = new shaka.media.SegmentReference(
|
|
903
907
|
this.periodStart_ + range.start,
|
|
904
|
-
|
|
908
|
+
segmentEnd,
|
|
905
909
|
createUrisCb,
|
|
906
910
|
/* startByte= */ 0,
|
|
907
911
|
/* endByte= */ null,
|
|
@@ -916,6 +920,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
916
920
|
shaka.media.SegmentReference.Status.AVAILABLE,
|
|
917
921
|
this.aes128Key_,
|
|
918
922
|
/* allPartialSegments= */ range.partialSegments > 0);
|
|
923
|
+
ref.trueEndTime = trueSegmentEnd;
|
|
919
924
|
this.references[correctedPosition] = ref;
|
|
920
925
|
}
|
|
921
926
|
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -2839,12 +2839,12 @@ shaka.hls.HlsParser = class {
|
|
|
2839
2839
|
// Don't download the key object until the segment is parsed, to avoid a
|
|
2840
2840
|
// startup delay for long manifests with lots of keys.
|
|
2841
2841
|
keyInfo.fetchKey = async () => {
|
|
2842
|
-
const
|
|
2842
|
+
const keyUris = shaka.hls.Utils.constructSegmentUris(
|
|
2843
2843
|
getUris(), drmTag.getRequiredAttrValue('URI'), variables);
|
|
2844
2844
|
|
|
2845
2845
|
const requestType = shaka.net.NetworkingEngine.RequestType.KEY;
|
|
2846
2846
|
const request = shaka.net.NetworkingEngine.makeRequest(
|
|
2847
|
-
|
|
2847
|
+
keyUris, this.config_.retryParameters);
|
|
2848
2848
|
const keyResponse = await this.makeNetworkRequest_(request, requestType);
|
|
2849
2849
|
|
|
2850
2850
|
// keyResponse.status is undefined when URI is "data:text/plain;base64,"
|
|
@@ -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,
|
|
@@ -129,7 +129,10 @@ shaka.media.InitSegmentReference = class {
|
|
|
129
129
|
static equal(reference1, reference2) {
|
|
130
130
|
const ArrayUtils = shaka.util.ArrayUtils;
|
|
131
131
|
const BufferUtils = shaka.util.BufferUtils;
|
|
132
|
-
|
|
132
|
+
|
|
133
|
+
if (reference1 === reference2) {
|
|
134
|
+
return true;
|
|
135
|
+
} else if (!reference1 || !reference2) {
|
|
133
136
|
return reference1 == reference2;
|
|
134
137
|
} else {
|
|
135
138
|
return reference1.getStartByte() == reference2.getStartByte() &&
|
|
@@ -2163,8 +2163,8 @@ shaka.media.StreamingEngine = class {
|
|
|
2163
2163
|
const bufferedBehind = presentationTime - startTime;
|
|
2164
2164
|
|
|
2165
2165
|
const overflow = bufferedBehind - bufferBehind;
|
|
2166
|
-
// See: https://github.com/shaka-project/shaka-player/issues/
|
|
2167
|
-
if (overflow <=
|
|
2166
|
+
// See: https://github.com/shaka-project/shaka-player/issues/6240
|
|
2167
|
+
if (overflow <= 1) {
|
|
2168
2168
|
shaka.log.v2(logPrefix,
|
|
2169
2169
|
'buffer behind okay:',
|
|
2170
2170
|
'presentationTime=' + presentationTime,
|
package/lib/player.js
CHANGED
|
@@ -1795,8 +1795,17 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1795
1795
|
|
|
1796
1796
|
this.drmEngine_.configure(this.config_.drm);
|
|
1797
1797
|
|
|
1798
|
+
const tracksChanged = shaka.util.StreamUtils.applyRestrictions(
|
|
1799
|
+
this.manifest_.variants, this.config_.restrictions, this.maxHwRes_);
|
|
1800
|
+
if (tracksChanged && this.streamingEngine_) {
|
|
1801
|
+
this.onTracksChanged_();
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
const playableVariants = shaka.util.StreamUtils.getPlayableVariants(
|
|
1805
|
+
this.manifest_.variants);
|
|
1806
|
+
|
|
1798
1807
|
await this.drmEngine_.initForPlayback(
|
|
1799
|
-
|
|
1808
|
+
playableVariants,
|
|
1800
1809
|
this.manifest_.offlineSessionIds);
|
|
1801
1810
|
|
|
1802
1811
|
await this.drmEngine_.attach(this.video_);
|
|
@@ -6925,7 +6934,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6925
6934
|
* @export
|
|
6926
6935
|
*/
|
|
6927
6936
|
// eslint-disable-next-line no-useless-concat
|
|
6928
|
-
shaka.Player.version = 'v4.7.
|
|
6937
|
+
shaka.Player.version = 'v4.7.10' + '-uncompiled'; // x-release-please-version
|
|
6929
6938
|
|
|
6930
6939
|
// Initialize the deprecation system using the version string we just set
|
|
6931
6940
|
// on the player.
|
package/lib/util/cmcd_manager.js
CHANGED
|
@@ -27,13 +27,6 @@ shaka.util.CmcdManager = class {
|
|
|
27
27
|
/** @private {?shaka.extern.CmcdConfiguration} */
|
|
28
28
|
this.config_ = config;
|
|
29
29
|
|
|
30
|
-
/**
|
|
31
|
-
* Session ID
|
|
32
|
-
*
|
|
33
|
-
* @private {string}
|
|
34
|
-
*/
|
|
35
|
-
this.sid_ = '';
|
|
36
|
-
|
|
37
30
|
/**
|
|
38
31
|
* Streaming format
|
|
39
32
|
*
|
|
@@ -65,9 +58,6 @@ shaka.util.CmcdManager = class {
|
|
|
65
58
|
*/
|
|
66
59
|
configure(config) {
|
|
67
60
|
this.config_ = config;
|
|
68
|
-
if (this.config_.sessionId && this.config_.sessionId != this.sid_) {
|
|
69
|
-
this.sid_ = '';
|
|
70
|
-
}
|
|
71
61
|
}
|
|
72
62
|
|
|
73
63
|
/**
|
|
@@ -295,13 +285,13 @@ shaka.util.CmcdManager = class {
|
|
|
295
285
|
* @private
|
|
296
286
|
*/
|
|
297
287
|
createData_() {
|
|
298
|
-
if (!this.
|
|
299
|
-
this.
|
|
288
|
+
if (!this.config_.sessionId) {
|
|
289
|
+
this.config_.sessionId = window.crypto.randomUUID();
|
|
300
290
|
}
|
|
301
291
|
return {
|
|
302
292
|
v: shaka.util.CmcdManager.Version,
|
|
303
293
|
sf: this.sf_,
|
|
304
|
-
sid: this.
|
|
294
|
+
sid: this.config_.sessionId,
|
|
305
295
|
cid: this.config_.contentId,
|
|
306
296
|
mtp: this.playerInterface_.getBandwidthEstimate() / 1000,
|
|
307
297
|
};
|
package/lib/util/periods.js
CHANGED
|
@@ -1215,7 +1215,18 @@ shaka.util.PeriodCombiner = class {
|
|
|
1215
1215
|
return false;
|
|
1216
1216
|
}
|
|
1217
1217
|
|
|
1218
|
-
// If language-based differences haven't decided this, look at
|
|
1218
|
+
// If language-based differences haven't decided this, look at labels.
|
|
1219
|
+
// If available options differ, look does any matches with output stream.
|
|
1220
|
+
if (best.label !== candidate.label) {
|
|
1221
|
+
if (outputStream.label === best.label) {
|
|
1222
|
+
return false;
|
|
1223
|
+
}
|
|
1224
|
+
if (outputStream.label === candidate.label) {
|
|
1225
|
+
return true;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
// If label-based differences haven't decided this, look at roles. If
|
|
1219
1230
|
// the candidate has more roles in common with the output, upgrade to the
|
|
1220
1231
|
// candidate.
|
|
1221
1232
|
if (outputStream.roles.length) {
|
|
@@ -1410,6 +1421,17 @@ shaka.util.PeriodCombiner = class {
|
|
|
1410
1421
|
return false;
|
|
1411
1422
|
}
|
|
1412
1423
|
|
|
1424
|
+
// If language-based differences haven't decided this, look at labels.
|
|
1425
|
+
// If available options differ, look does any matches with output stream.
|
|
1426
|
+
if (best.label !== candidate.label) {
|
|
1427
|
+
if (outputStream.label === best.label) {
|
|
1428
|
+
return false;
|
|
1429
|
+
}
|
|
1430
|
+
if (outputStream.label === candidate.label) {
|
|
1431
|
+
return true;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1413
1435
|
// If the candidate has more roles in common with the output, upgrade to the
|
|
1414
1436
|
// candidate.
|
|
1415
1437
|
if (outputStream.roles.length) {
|
package/lib/util/stream_utils.js
CHANGED
|
@@ -908,7 +908,7 @@ shaka.util.StreamUtils = class {
|
|
|
908
908
|
// currently don't support 'fLaC', while 'flac' is supported by most
|
|
909
909
|
// major browsers.
|
|
910
910
|
// See https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
|
|
911
|
-
if (codecs === 'fLaC') {
|
|
911
|
+
if (codecs === 'fLaC' && !shaka.util.Platform.isSafari()) {
|
|
912
912
|
return 'flac';
|
|
913
913
|
}
|
|
914
914
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shaka-player",
|
|
3
3
|
"description": "DASH/EME video player library",
|
|
4
|
-
"version": "4.7.
|
|
4
|
+
"version": "4.7.10",
|
|
5
5
|
"homepage": "https://github.com/shaka-project/shaka-player",
|
|
6
6
|
"author": "Google",
|
|
7
7
|
"maintainers": [
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"karma-coverage": "^2.2.0",
|
|
44
44
|
"karma-jasmine": "^4.0.1",
|
|
45
45
|
"karma-jasmine-ajax": "^0.1.13",
|
|
46
|
-
"karma-local-wd-launcher": "^1.6.
|
|
46
|
+
"karma-local-wd-launcher": "^1.6.7",
|
|
47
47
|
"karma-opera-launcher": "^1.0.0",
|
|
48
48
|
"karma-sourcemap-loader": "^0.3.8",
|
|
49
49
|
"karma-spec-reporter": "^0.0.34",
|
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)',
|