shaka-player 4.7.11 → 4.7.12
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/README.md +2 -4
- package/dist/deps.js +3 -4
- package/dist/locales.js +31 -31
- package/dist/shaka-player.compiled.d.ts +12 -10
- package/dist/shaka-player.compiled.debug.d.ts +12 -10
- package/dist/shaka-player.compiled.debug.externs.js +78 -64
- package/dist/shaka-player.compiled.debug.js +168 -163
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +78 -64
- package/dist/shaka-player.compiled.js +1134 -1128
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +12 -10
- package/dist/shaka-player.ui.debug.d.ts +12 -10
- package/dist/shaka-player.ui.debug.externs.js +78 -64
- package/dist/shaka-player.ui.debug.js +178 -174
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +78 -64
- package/dist/shaka-player.ui.js +1264 -1258
- package/dist/shaka-player.ui.map +4 -4
- package/externs/shaka/player.js +32 -19
- package/lib/abr/simple_abr_manager.js +21 -26
- package/lib/cast/cast_proxy.js +1 -3
- package/lib/cast/cast_sender.js +8 -11
- package/lib/cea/cea608_memory.js +1 -1
- package/lib/cea/ts_cea_parser.js +10 -1
- package/lib/dash/dash_parser.js +3 -0
- package/lib/hls/hls_parser.js +18 -16
- package/lib/media/drm_engine.js +6 -3
- package/lib/media/media_source_engine.js +25 -12
- package/lib/media/presentation_timeline.js +23 -0
- package/lib/media/segment_utils.js +10 -1
- package/lib/player.js +15 -2
- package/lib/polyfill/media_capabilities.js +20 -1
- package/lib/polyfill/mediasource.js +37 -14
- package/lib/text/vtt_text_parser.js +51 -51
- package/lib/transmuxer/h264.js +3 -3
- package/lib/transmuxer/h265.js +3 -3
- package/lib/transmuxer/ts_transmuxer.js +42 -3
- package/lib/util/manifest_parser_utils.js +1 -0
- package/lib/util/mp4_parser.js +57 -0
- package/lib/util/platform.js +4 -0
- package/lib/util/ts_parser.js +99 -10
- package/package.json +1 -1
- package/lib/polyfill/storage_estimate.js +0 -57
package/externs/shaka/player.js
CHANGED
|
@@ -96,57 +96,70 @@ shaka.extern.StateChange;
|
|
|
96
96
|
* again.
|
|
97
97
|
*
|
|
98
98
|
* @property {number} width
|
|
99
|
-
* The width of the current video track.
|
|
99
|
+
* The width of the current video track. If nothing is loaded or the content
|
|
100
|
+
* is audio-only, NaN.
|
|
100
101
|
* @property {number} height
|
|
101
|
-
* The height of the current video track.
|
|
102
|
+
* The height of the current video track. If nothing is loaded or the content
|
|
103
|
+
* is audio-only, NaN.
|
|
102
104
|
* @property {number} streamBandwidth
|
|
103
105
|
* The bandwidth required for the current streams (total, in bit/sec).
|
|
104
|
-
* It takes into account the playbackrate.
|
|
106
|
+
* It takes into account the playbackrate. If nothing is loaded, NaN.
|
|
105
107
|
*
|
|
106
108
|
* @property {number} decodedFrames
|
|
107
|
-
* The total number of frames decoded by the Player.
|
|
108
|
-
*
|
|
109
|
+
* The total number of frames decoded by the Player. If not reported by the
|
|
110
|
+
* browser, NaN.
|
|
109
111
|
* @property {number} droppedFrames
|
|
110
|
-
* The total number of frames dropped by the Player.
|
|
111
|
-
*
|
|
112
|
+
* The total number of frames dropped by the Player. If not reported by the
|
|
113
|
+
* browser, NaN.
|
|
112
114
|
* @property {number} corruptedFrames
|
|
113
|
-
* The total number of corrupted frames dropped by the browser.
|
|
114
|
-
*
|
|
115
|
+
* The total number of corrupted frames dropped by the browser. If not
|
|
116
|
+
* reported by the browser, NaN.
|
|
115
117
|
* @property {number} estimatedBandwidth
|
|
116
|
-
* The current estimated network bandwidth (in bit/sec).
|
|
118
|
+
* The current estimated network bandwidth (in bit/sec). If no estimate
|
|
119
|
+
* available, NaN.
|
|
117
120
|
*
|
|
118
121
|
* @property {number} gapsJumped
|
|
119
122
|
* The total number of playback gaps jumped by the GapJumpingController.
|
|
123
|
+
* If nothing is loaded, NaN.
|
|
120
124
|
* @property {number} stallsDetected
|
|
121
125
|
* The total number of playback stalls detected by the StallDetector.
|
|
126
|
+
* If nothing is loaded, NaN.
|
|
122
127
|
*
|
|
123
128
|
* @property {number} completionPercent
|
|
124
129
|
* This is the greatest completion percent that the user has experienced in
|
|
125
|
-
* playback.
|
|
126
|
-
*
|
|
130
|
+
* playback. Also known as the "high water mark". If nothing is loaded, or
|
|
131
|
+
* the stream is live (and therefore indefinite), NaN.
|
|
127
132
|
* @property {number} loadLatency
|
|
128
133
|
* This is the number of seconds it took for the video element to have enough
|
|
129
134
|
* data to begin playback. This is measured from the time load() is called to
|
|
130
135
|
* the time the <code>'loadeddata'</code> event is fired by the media element.
|
|
136
|
+
* If nothing is loaded, NaN.
|
|
131
137
|
* @property {number} manifestTimeSeconds
|
|
132
138
|
* The amount of time it took to download and parse the manifest.
|
|
139
|
+
* If nothing is loaded, NaN.
|
|
133
140
|
* @property {number} drmTimeSeconds
|
|
134
141
|
* The amount of time it took to download the first drm key, and load that key
|
|
135
|
-
* into the drm system.
|
|
142
|
+
* into the drm system. If nothing is loaded or DRM is not in use, NaN.
|
|
136
143
|
* @property {number} playTime
|
|
137
|
-
* The total time spent in a playing state in seconds.
|
|
144
|
+
* The total time spent in a playing state in seconds. If nothing is loaded,
|
|
145
|
+
* NaN.
|
|
138
146
|
* @property {number} pauseTime
|
|
139
|
-
* The total time spent in a paused state in seconds.
|
|
147
|
+
* The total time spent in a paused state in seconds. If nothing is loaded,
|
|
148
|
+
* NaN.
|
|
140
149
|
* @property {number} bufferingTime
|
|
141
|
-
* The total time spent in a buffering state in seconds.
|
|
150
|
+
* The total time spent in a buffering state in seconds. If nothing is
|
|
151
|
+
* loaded, NaN.
|
|
142
152
|
* @property {number} licenseTime
|
|
143
|
-
* The time spent on license requests during this session in seconds
|
|
153
|
+
* The time spent on license requests during this session in seconds. If DRM
|
|
154
|
+
* is not in use, NaN.
|
|
144
155
|
* @property {number} liveLatency
|
|
145
156
|
* The time between the capturing of a frame and the end user having it
|
|
146
|
-
* displayed on their screen.
|
|
157
|
+
* displayed on their screen. If nothing is loaded or the content is VOD,
|
|
158
|
+
* NaN.
|
|
147
159
|
*
|
|
148
160
|
* @property {number} maxSegmentDuration
|
|
149
|
-
* The presentation's max segment duration in seconds
|
|
161
|
+
* The presentation's max segment duration in seconds. If nothing is loaded,
|
|
162
|
+
* NaN.
|
|
150
163
|
*
|
|
151
164
|
* @property {!Array.<shaka.extern.TrackChoice>} switchHistory
|
|
152
165
|
* A history of the stream changes.
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.abr.SimpleAbrManager');
|
|
8
8
|
|
|
9
|
-
goog.require('shaka.util.IReleasable');
|
|
10
9
|
goog.require('goog.asserts');
|
|
11
10
|
goog.require('shaka.abr.EwmaBandwidthEstimator');
|
|
12
11
|
goog.require('shaka.log');
|
|
12
|
+
goog.require('shaka.util.EventManager');
|
|
13
|
+
goog.require('shaka.util.IReleasable');
|
|
13
14
|
goog.require('shaka.util.StreamUtils');
|
|
14
15
|
goog.require('shaka.util.Timer');
|
|
15
16
|
|
|
@@ -50,30 +51,30 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
50
51
|
/** @private {shaka.abr.EwmaBandwidthEstimator} */
|
|
51
52
|
this.bandwidthEstimator_ = new shaka.abr.EwmaBandwidthEstimator();
|
|
52
53
|
|
|
53
|
-
/** @private {
|
|
54
|
-
this.
|
|
54
|
+
/** @private {!shaka.util.EventManager} */
|
|
55
|
+
this.eventManager_ = new shaka.util.EventManager();
|
|
55
56
|
|
|
56
57
|
// Some browsers implement the Network Information API, which allows
|
|
57
58
|
// retrieving information about a user's network connection. We listen
|
|
58
59
|
// to the change event to be able to make quick changes in case the type
|
|
59
60
|
// of connectivity changes.
|
|
60
61
|
if (navigator.connection && navigator.connection.addEventListener) {
|
|
61
|
-
this.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
62
|
+
this.eventManager_.listen(
|
|
63
|
+
/** @type {EventTarget} */(navigator.connection),
|
|
64
|
+
'change',
|
|
65
|
+
() => {
|
|
66
|
+
if (this.enabled_ && this.config_.useNetworkInformation) {
|
|
67
|
+
this.bandwidthEstimator_ = new shaka.abr.EwmaBandwidthEstimator();
|
|
68
|
+
if (this.config_) {
|
|
69
|
+
this.bandwidthEstimator_.configure(this.config_.advanced);
|
|
70
|
+
}
|
|
71
|
+
const chosenVariant = this.chooseVariant();
|
|
72
|
+
if (chosenVariant && navigator.onLine) {
|
|
73
|
+
this.switch_(chosenVariant, this.config_.clearBufferSwitch,
|
|
74
|
+
this.config_.safeMarginSwitch);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
/**
|
|
@@ -151,13 +152,7 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
151
152
|
*/
|
|
152
153
|
release() {
|
|
153
154
|
// stop() should already have been called for unload
|
|
154
|
-
|
|
155
|
-
if (navigator.connection && navigator.connection.removeEventListener) {
|
|
156
|
-
navigator.connection.removeEventListener(
|
|
157
|
-
'change', this.onNetworkInformationChange_);
|
|
158
|
-
this.onNetworkInformationChange_ = null;
|
|
159
|
-
}
|
|
160
|
-
|
|
155
|
+
this.eventManager_.release();
|
|
161
156
|
this.resizeObserverTimer_ = null;
|
|
162
157
|
}
|
|
163
158
|
|
package/lib/cast/cast_proxy.js
CHANGED
|
@@ -188,12 +188,10 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
|
|
|
188
188
|
* @export
|
|
189
189
|
*/
|
|
190
190
|
async cast() {
|
|
191
|
-
const initState = this.getInitState_();
|
|
192
|
-
|
|
193
191
|
// TODO: transfer manually-selected tracks?
|
|
194
192
|
// TODO: transfer side-loaded text tracks?
|
|
195
193
|
|
|
196
|
-
await this.sender_.cast(
|
|
194
|
+
await this.sender_.cast();
|
|
197
195
|
if (!this.localPlayer_) {
|
|
198
196
|
// We've already been destroyed.
|
|
199
197
|
return;
|
package/lib/cast/cast_sender.js
CHANGED
|
@@ -261,12 +261,10 @@ shaka.cast.CastSender = class {
|
|
|
261
261
|
|
|
262
262
|
|
|
263
263
|
/**
|
|
264
|
-
* @param {shaka.cast.CastUtils.InitStateType} initState Video and player
|
|
265
|
-
* state to be sent to the receiver.
|
|
266
264
|
* @return {!Promise} Resolved when connected to a receiver. Rejected if the
|
|
267
265
|
* connection fails or is canceled by the user.
|
|
268
266
|
*/
|
|
269
|
-
async cast(
|
|
267
|
+
async cast() {
|
|
270
268
|
if (!this.apiReady_) {
|
|
271
269
|
throw new shaka.util.Error(
|
|
272
270
|
shaka.util.Error.Severity.RECOVERABLE,
|
|
@@ -288,7 +286,7 @@ shaka.cast.CastSender = class {
|
|
|
288
286
|
|
|
289
287
|
this.castPromise_ = new shaka.util.PublicPromise();
|
|
290
288
|
chrome.cast.requestSession(
|
|
291
|
-
(session) => this.onSessionInitiated_(
|
|
289
|
+
(session) => this.onSessionInitiated_(session),
|
|
292
290
|
(error) => this.onConnectionError_(error));
|
|
293
291
|
await this.castPromise_;
|
|
294
292
|
}
|
|
@@ -303,10 +301,9 @@ shaka.cast.CastSender = class {
|
|
|
303
301
|
if (!this.isCasting_) {
|
|
304
302
|
return;
|
|
305
303
|
}
|
|
306
|
-
const initState = this.onInitStateRequired_();
|
|
307
304
|
|
|
308
305
|
chrome.cast.requestSession(
|
|
309
|
-
(session) => this.onSessionInitiated_(
|
|
306
|
+
(session) => this.onSessionInitiated_(session),
|
|
310
307
|
(error) => this.onConnectionError_(error));
|
|
311
308
|
}
|
|
312
309
|
|
|
@@ -401,12 +398,14 @@ shaka.cast.CastSender = class {
|
|
|
401
398
|
|
|
402
399
|
|
|
403
400
|
/**
|
|
404
|
-
* @param {shaka.cast.CastUtils.InitStateType} initState
|
|
405
401
|
* @param {chrome.cast.Session} session
|
|
406
402
|
* @private
|
|
407
403
|
*/
|
|
408
|
-
onSessionInitiated_(
|
|
404
|
+
onSessionInitiated_(session) {
|
|
409
405
|
shaka.log.debug('CastSender: onSessionInitiated');
|
|
406
|
+
|
|
407
|
+
const initState = this.onInitStateRequired_();
|
|
408
|
+
|
|
410
409
|
this.onSessionCreated_(session);
|
|
411
410
|
|
|
412
411
|
this.sendMessage_({
|
|
@@ -529,12 +528,10 @@ shaka.cast.CastSender = class {
|
|
|
529
528
|
onExistingSessionJoined_(session) {
|
|
530
529
|
shaka.log.debug('CastSender: onExistingSessionJoined');
|
|
531
530
|
|
|
532
|
-
const initState = this.onInitStateRequired_();
|
|
533
|
-
|
|
534
531
|
this.castPromise_ = new shaka.util.PublicPromise();
|
|
535
532
|
this.hasJoinedExistingSession_ = true;
|
|
536
533
|
|
|
537
|
-
this.onSessionInitiated_(
|
|
534
|
+
this.onSessionInitiated_(session);
|
|
538
535
|
}
|
|
539
536
|
|
|
540
537
|
|
package/lib/cea/cea608_memory.js
CHANGED
|
@@ -293,7 +293,7 @@ shaka.cea.Cea608Memory.CharSet.BasicNorthAmericanChars = new Map([
|
|
|
293
293
|
*/
|
|
294
294
|
shaka.cea.Cea608Memory.CharSet.SpecialNorthAmericanChars = new Map([
|
|
295
295
|
[0x30, '®'], [0x31, '°'], [0x32, '½'], [0x33, '¿'], [0x34, '™'], [0x35, '¢'],
|
|
296
|
-
[0x36, '£'], [0x37, '♪'], [0x38, 'à'], [0x39, '
|
|
296
|
+
[0x36, '£'], [0x37, '♪'], [0x38, 'à'], [0x39, ' '], [0x3a, 'è'], [0x3b, 'â'],
|
|
297
297
|
[0x3c, 'ê'], [0x3d, 'î'], [0x3e, 'ô'], [0x3f, 'û'],
|
|
298
298
|
]);
|
|
299
299
|
|
package/lib/cea/ts_cea_parser.js
CHANGED
|
@@ -26,6 +26,9 @@ shaka.cea.TsCeaParser = class {
|
|
|
26
26
|
* @const {!shaka.cea.SeiProcessor}
|
|
27
27
|
*/
|
|
28
28
|
this.seiProcessor_ = new shaka.cea.SeiProcessor();
|
|
29
|
+
|
|
30
|
+
/** @private {?shaka.util.TsParser} */
|
|
31
|
+
this.tsParser_ = null;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
/**
|
|
@@ -41,6 +44,12 @@ shaka.cea.TsCeaParser = class {
|
|
|
41
44
|
parse(mediaSegment) {
|
|
42
45
|
const CeaUtils = shaka.cea.CeaUtils;
|
|
43
46
|
|
|
47
|
+
if (!this.tsParser_) {
|
|
48
|
+
this.tsParser_ = new shaka.util.TsParser();
|
|
49
|
+
} else {
|
|
50
|
+
this.tsParser_.clearData();
|
|
51
|
+
}
|
|
52
|
+
|
|
44
53
|
/** @type {!Array<!shaka.extern.ICeaParser.CaptionPacket>} **/
|
|
45
54
|
const captionPackets = [];
|
|
46
55
|
|
|
@@ -48,7 +57,7 @@ shaka.cea.TsCeaParser = class {
|
|
|
48
57
|
if (!shaka.util.TsParser.probe(uint8ArrayData)) {
|
|
49
58
|
return captionPackets;
|
|
50
59
|
}
|
|
51
|
-
const tsParser =
|
|
60
|
+
const tsParser = this.tsParser_.parse(uint8ArrayData);
|
|
52
61
|
const codecs = tsParser.getCodecs();
|
|
53
62
|
const videoNalus = tsParser.getVideoNalus();
|
|
54
63
|
const validNaluTypes = [];
|
package/lib/dash/dash_parser.js
CHANGED
|
@@ -643,6 +643,9 @@ shaka.dash.DashParser = class {
|
|
|
643
643
|
// best latency
|
|
644
644
|
if (this.lowLatencyMode_) {
|
|
645
645
|
minBufferTime = 0;
|
|
646
|
+
const presentationDelay = suggestedPresentationDelay != null ?
|
|
647
|
+
suggestedPresentationDelay : this.config_.defaultPresentationDelay;
|
|
648
|
+
presentationTimeline.setDelay(presentationDelay);
|
|
646
649
|
}
|
|
647
650
|
|
|
648
651
|
// These steps are not done on manifest update.
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -552,7 +552,7 @@ shaka.hls.HlsParser = class {
|
|
|
552
552
|
if (goog.DEBUG) {
|
|
553
553
|
const firstSequenceStartTime =
|
|
554
554
|
mediaSequenceToStartTime.values().next().value;
|
|
555
|
-
|
|
555
|
+
shaka.log.warning(
|
|
556
556
|
firstSequenceStartTime == segment0.startTime,
|
|
557
557
|
'Sequence number map is not ordered as expected!');
|
|
558
558
|
}
|
|
@@ -586,16 +586,18 @@ shaka.hls.HlsParser = class {
|
|
|
586
586
|
// Drop any earlier references.
|
|
587
587
|
const numSegmentsToDrop =
|
|
588
588
|
this.minSequenceNumber_ - streamInfo.firstSequenceNumber;
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
589
|
+
if (numSegmentsToDrop > 0) {
|
|
590
|
+
segmentIndex.dropFirstReferences(numSegmentsToDrop);
|
|
591
|
+
|
|
592
|
+
// Now adjust timestamps back to begin at 0.
|
|
593
|
+
const segmentN = segmentIndex.earliestReference();
|
|
594
|
+
if (segmentN) {
|
|
595
|
+
const streamOffset = -segmentN.startTime;
|
|
596
|
+
// Modify all SegmentReferences equally.
|
|
597
|
+
streamInfo.stream.segmentIndex.offset(streamOffset);
|
|
598
|
+
// Update other parts of streamInfo the same way.
|
|
599
|
+
this.offsetStreamInfo_(streamInfo, streamOffset);
|
|
600
|
+
}
|
|
599
601
|
}
|
|
600
602
|
}
|
|
601
603
|
}
|
|
@@ -986,17 +988,17 @@ shaka.hls.HlsParser = class {
|
|
|
986
988
|
}
|
|
987
989
|
|
|
988
990
|
if (!this.presentationTimeline_.isStartTimeLocked()) {
|
|
989
|
-
const
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
991
|
+
for (const streamInfo of this.uriToStreamInfosMap_.values()) {
|
|
992
|
+
if (!streamInfo.stream.segmentIndex) {
|
|
993
|
+
continue; // Not active.
|
|
994
|
+
}
|
|
993
995
|
if (streamInfo.type != 'audio' && streamInfo.type != 'video') {
|
|
994
996
|
continue;
|
|
995
997
|
}
|
|
996
998
|
const firstReference = streamInfo.stream.segmentIndex.get(0);
|
|
997
999
|
if (firstReference && firstReference.syncTime) {
|
|
998
1000
|
const syncTime = firstReference.syncTime;
|
|
999
|
-
this.presentationTimeline_.
|
|
1001
|
+
this.presentationTimeline_.setInitialProgramDateTime(syncTime);
|
|
1000
1002
|
}
|
|
1001
1003
|
}
|
|
1002
1004
|
}
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -697,9 +697,12 @@ shaka.media.DrmEngine = class {
|
|
|
697
697
|
initDataOverride.initDataType, initDataOverride.initData);
|
|
698
698
|
}
|
|
699
699
|
|
|
700
|
-
// If
|
|
701
|
-
// it will never get resolved.
|
|
702
|
-
|
|
700
|
+
// If there were no sessions to load, we need to resolve the promise right
|
|
701
|
+
// now or else it will never get resolved.
|
|
702
|
+
// We determine this by checking areAllSessionsLoaded_, rather than checking
|
|
703
|
+
// the number of initDatas, since the newInitData method can reject init
|
|
704
|
+
// datas in some circumstances.
|
|
705
|
+
if (this.areAllSessionsLoaded_()) {
|
|
703
706
|
this.allSessionsLoaded_.resolve();
|
|
704
707
|
}
|
|
705
708
|
|
|
@@ -151,6 +151,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
151
151
|
|
|
152
152
|
/** @private {?number} */
|
|
153
153
|
this.lastDuration_ = null;
|
|
154
|
+
|
|
155
|
+
/** @private {?shaka.util.TsParser} */
|
|
156
|
+
this.tsParser_ = null;
|
|
154
157
|
}
|
|
155
158
|
|
|
156
159
|
/**
|
|
@@ -392,6 +395,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
392
395
|
|
|
393
396
|
// This object is owned by Player
|
|
394
397
|
this.lcevcDec_ = null;
|
|
398
|
+
|
|
399
|
+
this.tsParser_ = null;
|
|
395
400
|
}
|
|
396
401
|
|
|
397
402
|
/**
|
|
@@ -442,6 +447,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
442
447
|
this.manifestType_ == shaka.media.ManifestParser.HLS &&
|
|
443
448
|
!this.ignoreManifestTimestampsInSegmentsMode_;
|
|
444
449
|
|
|
450
|
+
this.tsParser_ = null;
|
|
451
|
+
|
|
445
452
|
for (const contentType of streamsByType.keys()) {
|
|
446
453
|
const stream = streamsByType.get(contentType);
|
|
447
454
|
this.initSourceBuffer_(contentType, stream, stream.codecs);
|
|
@@ -460,10 +467,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
460
467
|
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
461
468
|
* @param {shaka.extern.Stream} stream
|
|
462
469
|
* @param {string} codecs
|
|
463
|
-
* @param {boolean=} forceTransmux
|
|
464
470
|
* @private
|
|
465
471
|
*/
|
|
466
|
-
initSourceBuffer_(contentType, stream, codecs
|
|
472
|
+
initSourceBuffer_(contentType, stream, codecs) {
|
|
467
473
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
468
474
|
|
|
469
475
|
goog.asserts.assert(
|
|
@@ -475,7 +481,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
475
481
|
if (contentType == ContentType.TEXT) {
|
|
476
482
|
this.reinitText(mimeType, this.sequenceMode_, stream.external);
|
|
477
483
|
} else {
|
|
478
|
-
let needTransmux = this.config_.forceTransmux
|
|
484
|
+
let needTransmux = this.config_.forceTransmux;
|
|
479
485
|
if (!shaka.media.Capabilities.isTypeSupported(mimeType) ||
|
|
480
486
|
(!this.sequenceMode_ &&
|
|
481
487
|
shaka.util.MimeUtils.RAW_FORMATS.includes(mimeType))) {
|
|
@@ -492,10 +498,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
492
498
|
ContentType.VIDEO, (codecs || '').split(','));
|
|
493
499
|
if (audioCodec && videoCodec) {
|
|
494
500
|
this.needSplitMuxedContent_ = true;
|
|
495
|
-
this.initSourceBuffer_(
|
|
496
|
-
|
|
497
|
-
this.initSourceBuffer_(
|
|
498
|
-
ContentType.VIDEO, stream, videoCodec, /* forceTransmux= */ true);
|
|
501
|
+
this.initSourceBuffer_(ContentType.AUDIO, stream, audioCodec);
|
|
502
|
+
this.initSourceBuffer_(ContentType.VIDEO, stream, videoCodec);
|
|
499
503
|
return;
|
|
500
504
|
}
|
|
501
505
|
const transmuxerPlugin =
|
|
@@ -789,7 +793,12 @@ shaka.media.MediaSourceEngine = class {
|
|
|
789
793
|
}
|
|
790
794
|
} else if (!mimeType.includes('/mp4') && !mimeType.includes('/webm') &&
|
|
791
795
|
shaka.util.TsParser.probe(uint8ArrayData)) {
|
|
792
|
-
|
|
796
|
+
if (!this.tsParser_) {
|
|
797
|
+
this.tsParser_ = new shaka.util.TsParser();
|
|
798
|
+
} else {
|
|
799
|
+
this.tsParser_.clearData();
|
|
800
|
+
}
|
|
801
|
+
const tsParser = this.tsParser_.parse(uint8ArrayData);
|
|
793
802
|
const startTime = tsParser.getStartTime(contentType);
|
|
794
803
|
if (startTime != null) {
|
|
795
804
|
timestamp = startTime;
|
|
@@ -1177,6 +1186,12 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1177
1186
|
return;
|
|
1178
1187
|
}
|
|
1179
1188
|
|
|
1189
|
+
// Reset the promise in case the timestamp offset changed during
|
|
1190
|
+
// a period/discontinuity transition.
|
|
1191
|
+
if (contentType == ContentType.VIDEO) {
|
|
1192
|
+
this.textSequenceModeOffset_ = new shaka.util.PublicPromise();
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1180
1195
|
// Queue an abort() to help MSE splice together overlapping segments.
|
|
1181
1196
|
// We set appendWindowEnd when we change periods in DASH content, and the
|
|
1182
1197
|
// period transition may result in overlap.
|
|
@@ -1857,8 +1872,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1857
1872
|
let needTransmux = this.config_.forceTransmux;
|
|
1858
1873
|
if (!shaka.media.Capabilities.isTypeSupported(newMimeType) ||
|
|
1859
1874
|
(!this.sequenceMode_ &&
|
|
1860
|
-
shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType))
|
|
1861
|
-
codecs.includes(',')) {
|
|
1875
|
+
shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType))) {
|
|
1862
1876
|
needTransmux = true;
|
|
1863
1877
|
}
|
|
1864
1878
|
const TransmuxerEngine = shaka.transmuxer.TransmuxerEngine;
|
|
@@ -1939,8 +1953,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1939
1953
|
let needTransmux = this.config_.forceTransmux;
|
|
1940
1954
|
if (!shaka.media.Capabilities.isTypeSupported(newMimeType) ||
|
|
1941
1955
|
(!this.sequenceMode_ &&
|
|
1942
|
-
shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType))
|
|
1943
|
-
stream.codecs.includes(',')) {
|
|
1956
|
+
shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType))) {
|
|
1944
1957
|
needTransmux = true;
|
|
1945
1958
|
}
|
|
1946
1959
|
const newMimeTypeWithAllCodecs =
|
|
@@ -96,6 +96,9 @@ shaka.media.PresentationTimeline = class {
|
|
|
96
96
|
|
|
97
97
|
/** @private {boolean} */
|
|
98
98
|
this.startTimeLocked_ = false;
|
|
99
|
+
|
|
100
|
+
/** @private {?number} */
|
|
101
|
+
this.initialProgramDateTime_ = null;
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
|
|
@@ -339,6 +342,26 @@ shaka.media.PresentationTimeline = class {
|
|
|
339
342
|
}
|
|
340
343
|
|
|
341
344
|
|
|
345
|
+
/**
|
|
346
|
+
* Sets the initial program date time.
|
|
347
|
+
*
|
|
348
|
+
* @param {number} initialProgramDateTime
|
|
349
|
+
* @export
|
|
350
|
+
*/
|
|
351
|
+
setInitialProgramDateTime(initialProgramDateTime) {
|
|
352
|
+
this.initialProgramDateTime_ = initialProgramDateTime;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* @return {?number} The initial program date time in seconds.
|
|
358
|
+
* @export
|
|
359
|
+
*/
|
|
360
|
+
getInitialProgramDateTime() {
|
|
361
|
+
return this.initialProgramDateTime_;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
|
|
342
365
|
/**
|
|
343
366
|
* Gives PresentationTimeline a Stream's minimum segment start time.
|
|
344
367
|
*
|
|
@@ -55,6 +55,7 @@ shaka.media.SegmentUtils = class {
|
|
|
55
55
|
let hasVideo = false;
|
|
56
56
|
switch (tsCodecs.audio) {
|
|
57
57
|
case 'aac':
|
|
58
|
+
case 'aac-loas':
|
|
58
59
|
codecs.push('mp4a.40.2');
|
|
59
60
|
hasAudio = true;
|
|
60
61
|
break;
|
|
@@ -70,6 +71,10 @@ shaka.media.SegmentUtils = class {
|
|
|
70
71
|
codecs.push('ec-3');
|
|
71
72
|
hasAudio = true;
|
|
72
73
|
break;
|
|
74
|
+
case 'opus':
|
|
75
|
+
codecs.push('opus');
|
|
76
|
+
hasAudio = true;
|
|
77
|
+
break;
|
|
73
78
|
}
|
|
74
79
|
switch (tsCodecs.video) {
|
|
75
80
|
case 'avc':
|
|
@@ -88,6 +93,10 @@ shaka.media.SegmentUtils = class {
|
|
|
88
93
|
}
|
|
89
94
|
hasVideo = true;
|
|
90
95
|
break;
|
|
96
|
+
case 'av1':
|
|
97
|
+
codecs.push('av01.0.01M.08');
|
|
98
|
+
hasVideo = true;
|
|
99
|
+
break;
|
|
91
100
|
}
|
|
92
101
|
if (!codecs.length) {
|
|
93
102
|
return null;
|
|
@@ -256,7 +265,7 @@ shaka.media.SegmentUtils = class {
|
|
|
256
265
|
// This signals an encrypted sample, which we can go inside of to
|
|
257
266
|
// find the codec used.
|
|
258
267
|
// Note: If encrypted, you can only have audio or video, not both.
|
|
259
|
-
.box('enca', Mp4Parser.
|
|
268
|
+
.box('enca', Mp4Parser.audioSampleEntry)
|
|
260
269
|
.box('encv', Mp4Parser.visualSampleEntry)
|
|
261
270
|
.box('sinf', Mp4Parser.children)
|
|
262
271
|
.box('frma', (box) => {
|
package/lib/player.js
CHANGED
|
@@ -4494,7 +4494,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4494
4494
|
|
|
4495
4495
|
if (this.manifest_) {
|
|
4496
4496
|
const timeline = this.manifest_.presentationTimeline;
|
|
4497
|
-
const startTime = timeline.
|
|
4497
|
+
const startTime = timeline.getInitialProgramDateTime() ||
|
|
4498
|
+
timeline.getPresentationStartTime();
|
|
4498
4499
|
return new Date(/* ms= */ (startTime + presentationTime) * 1000);
|
|
4499
4500
|
} else if (this.video_ && this.video_.getStartDate) {
|
|
4500
4501
|
// Apple's native HLS gives us getStartDate(), which is only available if
|
|
@@ -6099,6 +6100,18 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6099
6100
|
// change.
|
|
6100
6101
|
if (this.playhead_) {
|
|
6101
6102
|
this.playhead_.notifyOfBufferingChange();
|
|
6103
|
+
// Skip the initial buffer gap
|
|
6104
|
+
const startTime = this.mediaSourceEngine_.bufferStart(contentType);
|
|
6105
|
+
if (
|
|
6106
|
+
!this.isLive() &&
|
|
6107
|
+
// If not paused then GapJumpingController will handle this gap.
|
|
6108
|
+
this.video_.paused &&
|
|
6109
|
+
startTime != null &&
|
|
6110
|
+
startTime > 0 &&
|
|
6111
|
+
this.playhead_.getTime() < startTime
|
|
6112
|
+
) {
|
|
6113
|
+
this.playhead_.setStartTime(startTime);
|
|
6114
|
+
}
|
|
6102
6115
|
}
|
|
6103
6116
|
this.pollBufferState_();
|
|
6104
6117
|
|
|
@@ -6934,7 +6947,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6934
6947
|
* @export
|
|
6935
6948
|
*/
|
|
6936
6949
|
// eslint-disable-next-line no-useless-concat
|
|
6937
|
-
shaka.Player.version = 'v4.7.
|
|
6950
|
+
shaka.Player.version = 'v4.7.12' + '-uncompiled'; // x-release-please-version
|
|
6938
6951
|
|
|
6939
6952
|
// Initialize the deprecation system using the version string we just set
|
|
6940
6953
|
// on the player.
|
|
@@ -300,7 +300,17 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
300
300
|
// this query is specifically for HDR.
|
|
301
301
|
displayType += '; eotf=smpte2084';
|
|
302
302
|
}
|
|
303
|
-
|
|
303
|
+
let result = false;
|
|
304
|
+
if (displayType in shaka.polyfill.MediaCapabilities
|
|
305
|
+
.memoizedCanDisplayTypeRequests_) {
|
|
306
|
+
result = shaka.polyfill.MediaCapabilities
|
|
307
|
+
.memoizedCanDisplayTypeRequests_[displayType];
|
|
308
|
+
} else {
|
|
309
|
+
result = cast.__platform__.canDisplayType(displayType);
|
|
310
|
+
shaka.polyfill.MediaCapabilities
|
|
311
|
+
.memoizedCanDisplayTypeRequests_[displayType] = result;
|
|
312
|
+
}
|
|
313
|
+
return result;
|
|
304
314
|
}
|
|
305
315
|
|
|
306
316
|
/**
|
|
@@ -337,6 +347,15 @@ shaka.polyfill.MediaCapabilities.originalMcap = null;
|
|
|
337
347
|
*/
|
|
338
348
|
shaka.polyfill.MediaCapabilities.memoizedMediaKeySystemAccessRequests_ = {};
|
|
339
349
|
|
|
350
|
+
/**
|
|
351
|
+
* A cache that stores the canDisplayType result of calling
|
|
352
|
+
* `cast.__platform__.canDisplayType`.
|
|
353
|
+
*
|
|
354
|
+
* @type {(Object<(!string), (!boolean)>)}
|
|
355
|
+
* @export
|
|
356
|
+
*/
|
|
357
|
+
shaka.polyfill.MediaCapabilities.memoizedCanDisplayTypeRequests_ = {};
|
|
358
|
+
|
|
340
359
|
// Install at a lower priority than MediaSource polyfill, so that we have
|
|
341
360
|
// MediaSource available first.
|
|
342
361
|
shaka.polyfill.register(shaka.polyfill.MediaCapabilities.install, -1);
|