shaka-player 4.9.32 → 4.9.34
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/dist/deps.js +6 -5
- package/dist/locales.js +36 -36
- package/dist/shaka-player.compiled.d.ts +11 -3
- package/dist/shaka-player.compiled.debug.d.ts +11 -3
- package/dist/shaka-player.compiled.debug.externs.js +8 -5
- package/dist/shaka-player.compiled.debug.js +453 -440
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +8 -5
- package/dist/shaka-player.compiled.js +1281 -1271
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +11 -3
- package/dist/shaka-player.ui.debug.d.ts +11 -3
- package/dist/shaka-player.ui.debug.externs.js +8 -5
- package/dist/shaka-player.ui.debug.js +483 -470
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +8 -5
- package/dist/shaka-player.ui.js +1478 -1468
- package/dist/shaka-player.ui.map +4 -4
- package/externs/managedmediasource.js +6 -0
- package/externs/shaka/codecs.js +21 -0
- package/externs/shaka/offline.js +4 -0
- package/lib/cast/cast_utils.js +1 -0
- package/lib/hls/hls_parser.js +26 -5
- package/lib/media/drm_engine.js +78 -18
- package/lib/media/media_source_capabilities.js +3 -2
- package/lib/media/media_source_engine.js +117 -36
- package/lib/media/segment_utils.js +57 -47
- package/lib/offline/download_info.js +5 -0
- package/lib/offline/download_manager.js +54 -0
- package/lib/offline/manifest_converter.js +1 -0
- package/lib/offline/storage.js +11 -2
- package/lib/player.js +89 -53
- package/lib/polyfill/media_capabilities.js +1 -1
- package/lib/text/simple_text_displayer.js +9 -1
- package/lib/text/ui_text_displayer.js +2 -14
- package/lib/text/vtt_text_parser.js +9 -4
- package/lib/transmuxer/aac_transmuxer.js +11 -3
- package/lib/transmuxer/ac3_transmuxer.js +11 -3
- package/lib/transmuxer/ec3_transmuxer.js +11 -3
- package/lib/transmuxer/h264.js +143 -70
- package/lib/transmuxer/mp3_transmuxer.js +11 -3
- package/lib/transmuxer/ts_transmuxer.js +68 -28
- package/lib/util/abortable_operation.js +3 -0
- package/lib/util/drm_utils.js +20 -0
- package/lib/util/functional.js +27 -0
- package/lib/util/mime_utils.js +2 -0
- package/lib/util/number_utils.js +37 -0
- package/lib/util/object_utils.js +83 -0
- package/lib/util/platform.js +48 -40
- package/lib/util/stream_utils.js +27 -106
- package/lib/util/ts_parser.js +111 -85
- package/package.json +2 -2
- package/ui/controls.js +4 -0
- package/ui/fast_forward_button.js +7 -0
- package/ui/play_button.js +1 -1
- package/ui/rewind_button.js +7 -0
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
goog.provide('shaka.offline.DownloadInfo');
|
|
8
8
|
|
|
9
9
|
goog.require('shaka.util.Networking');
|
|
10
|
+
goog.require('shaka.util.Uint8ArrayUtils');
|
|
10
11
|
goog.requireType('shaka.media.InitSegmentReference');
|
|
11
12
|
goog.requireType('shaka.media.SegmentReference');
|
|
12
13
|
|
|
@@ -43,6 +44,10 @@ shaka.offline.DownloadInfo = class {
|
|
|
43
44
|
* @return {string}
|
|
44
45
|
*/
|
|
45
46
|
static idForSegmentRef(ref) {
|
|
47
|
+
const segmentData = ref.getSegmentData();
|
|
48
|
+
if (segmentData) {
|
|
49
|
+
return shaka.util.Uint8ArrayUtils.toBase64(segmentData);
|
|
50
|
+
}
|
|
46
51
|
// Escape the URIs using encodeURI, to make sure that a weirdly formed URI
|
|
47
52
|
// cannot cause two unrelated refs to be considered equivalent.
|
|
48
53
|
return ref.getUris().map((uri) => '{' + encodeURI(uri) + '}').join('') +
|
|
@@ -168,6 +168,60 @@ shaka.offline.DownloadManager = class {
|
|
|
168
168
|
return newPromise;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Add already-downloaded data to a group.
|
|
173
|
+
*
|
|
174
|
+
* @param {number} groupId
|
|
175
|
+
* The group to add this segment to. If the group does not exist, a new
|
|
176
|
+
* group will be created.
|
|
177
|
+
* @param {!BufferSource} queueData
|
|
178
|
+
* @param {number} estimateId
|
|
179
|
+
* @param {boolean} isInitSegment
|
|
180
|
+
* @param {function(BufferSource):!Promise} onDownloaded
|
|
181
|
+
* The callback for when this request has been downloaded. Downloading for
|
|
182
|
+
* |group| will pause until the promise returned by |onDownloaded| resolves.
|
|
183
|
+
* @return {!Promise} Resolved when this request is complete.
|
|
184
|
+
*/
|
|
185
|
+
queueData(groupId, queueData, estimateId, isInitSegment, onDownloaded) {
|
|
186
|
+
this.destroyer_.ensureNotDestroyed();
|
|
187
|
+
|
|
188
|
+
const group = this.groups_.get(groupId) || Promise.resolve();
|
|
189
|
+
|
|
190
|
+
// Add another download to the group.
|
|
191
|
+
const newPromise = group.then(() => {
|
|
192
|
+
// Make sure we stop downloading if we have been destroyed.
|
|
193
|
+
if (this.destroyer_.destroyed()) {
|
|
194
|
+
throw new shaka.util.Error(
|
|
195
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
196
|
+
shaka.util.Error.Category.STORAGE,
|
|
197
|
+
shaka.util.Error.Code.OPERATION_ABORTED);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Update initData
|
|
201
|
+
if (isInitSegment) {
|
|
202
|
+
const segmentBytes = shaka.util.BufferUtils.toUint8(queueData);
|
|
203
|
+
const pssh = new shaka.util.Pssh(segmentBytes);
|
|
204
|
+
for (const key in pssh.data) {
|
|
205
|
+
const index = Number(key);
|
|
206
|
+
const data = pssh.data[index];
|
|
207
|
+
const systemId = pssh.systemIds[index];
|
|
208
|
+
this.onInitData_(data, systemId);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Update all our internal stats.
|
|
213
|
+
this.estimator_.close(estimateId, queueData.byteLength);
|
|
214
|
+
this.onProgress_(
|
|
215
|
+
this.estimator_.getEstimatedProgress(),
|
|
216
|
+
this.estimator_.getTotalDownloaded());
|
|
217
|
+
|
|
218
|
+
return onDownloaded(queueData);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
this.groups_.set(groupId, newPromise);
|
|
222
|
+
return newPromise;
|
|
223
|
+
}
|
|
224
|
+
|
|
171
225
|
/**
|
|
172
226
|
* Add additional async work to the group work queue.
|
|
173
227
|
*
|
|
@@ -212,6 +212,7 @@ shaka.offline.ManifestConverter = class {
|
|
|
212
212
|
spatialAudio: streamDB.spatialAudio,
|
|
213
213
|
closedCaptions: streamDB.closedCaptions,
|
|
214
214
|
tilesLayout: streamDB.tilesLayout,
|
|
215
|
+
mssPrivateData: streamDB.mssPrivateData,
|
|
215
216
|
accessibilityPurpose: null,
|
|
216
217
|
external: streamDB.external,
|
|
217
218
|
fastSwitching: streamDB.fastSwitching,
|
package/lib/offline/storage.js
CHANGED
|
@@ -474,8 +474,16 @@ shaka.offline.Storage = class {
|
|
|
474
474
|
pendingDataSize += data.byteLength;
|
|
475
475
|
};
|
|
476
476
|
|
|
477
|
-
|
|
478
|
-
|
|
477
|
+
const ref = /** @type {!shaka.media.SegmentReference} */ (
|
|
478
|
+
download.ref);
|
|
479
|
+
const segmentData = ref.getSegmentData();
|
|
480
|
+
if (segmentData) {
|
|
481
|
+
downloader.queueData(download.groupId,
|
|
482
|
+
segmentData, estimateId, isInitSegment, onDownloaded);
|
|
483
|
+
} else {
|
|
484
|
+
downloader.queue(download.groupId,
|
|
485
|
+
request, estimateId, isInitSegment, onDownloaded);
|
|
486
|
+
}
|
|
479
487
|
}
|
|
480
488
|
await downloader.waitToFinish();
|
|
481
489
|
|
|
@@ -1335,6 +1343,7 @@ shaka.offline.Storage = class {
|
|
|
1335
1343
|
spatialAudio: stream.spatialAudio,
|
|
1336
1344
|
closedCaptions: stream.closedCaptions,
|
|
1337
1345
|
tilesLayout: stream.tilesLayout,
|
|
1346
|
+
mssPrivateData: stream.mssPrivateData,
|
|
1338
1347
|
external: stream.external,
|
|
1339
1348
|
fastSwitching: stream.fastSwitching,
|
|
1340
1349
|
};
|
package/lib/player.js
CHANGED
|
@@ -56,6 +56,7 @@ goog.require('shaka.util.ManifestParserUtils');
|
|
|
56
56
|
goog.require('shaka.util.MediaReadyState');
|
|
57
57
|
goog.require('shaka.util.MimeUtils');
|
|
58
58
|
goog.require('shaka.util.Mutex');
|
|
59
|
+
goog.require('shaka.util.NumberUtils');
|
|
59
60
|
goog.require('shaka.util.ObjectUtils');
|
|
60
61
|
goog.require('shaka.util.Platform');
|
|
61
62
|
goog.require('shaka.util.PlayerConfiguration');
|
|
@@ -705,7 +706,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
705
706
|
this.externalSrcEqualsThumbnailsStreams_ = [];
|
|
706
707
|
|
|
707
708
|
/** @private {number} */
|
|
708
|
-
this.completionPercent_ =
|
|
709
|
+
this.completionPercent_ = -1;
|
|
709
710
|
|
|
710
711
|
/** @private {?shaka.extern.PlayerConfiguration} */
|
|
711
712
|
this.config_ = this.defaultConfig_();
|
|
@@ -1446,7 +1447,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1446
1447
|
// after several playbacks, and they are not able anymore to properly
|
|
1447
1448
|
// create MediaKeys objects. To prevent it, clear the cache after
|
|
1448
1449
|
// each playback.
|
|
1449
|
-
if (this.config_.streaming.clearDecodingCache) {
|
|
1450
|
+
if (this.config_ && this.config_.streaming.clearDecodingCache) {
|
|
1450
1451
|
shaka.util.StreamUtils.clearDecodingConfigCache();
|
|
1451
1452
|
shaka.util.DrmUtils.clearMediaKeySystemAccessMap();
|
|
1452
1453
|
}
|
|
@@ -1457,7 +1458,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1457
1458
|
|
|
1458
1459
|
this.externalSrcEqualsThumbnailsStreams_ = [];
|
|
1459
1460
|
|
|
1460
|
-
this.completionPercent_ =
|
|
1461
|
+
this.completionPercent_ = -1;
|
|
1461
1462
|
|
|
1462
1463
|
// Make sure that the app knows of the new buffering state.
|
|
1463
1464
|
this.updateBufferState_();
|
|
@@ -2524,7 +2525,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2524
2525
|
if (this.manifest_.nextUrl) {
|
|
2525
2526
|
if (this.config_.streaming.preloadNextUrlWindow > 0) {
|
|
2526
2527
|
const onTimeUpdate = async () => {
|
|
2527
|
-
const timeToEnd = this.
|
|
2528
|
+
const timeToEnd = this.seekRange().end - this.video_.currentTime;
|
|
2528
2529
|
if (!isNaN(timeToEnd)) {
|
|
2529
2530
|
if (timeToEnd <= this.config_.streaming.preloadNextUrlWindow) {
|
|
2530
2531
|
this.loadEventManager_.unlisten(
|
|
@@ -4059,10 +4060,16 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4059
4060
|
// seekable range. This covers both plain mp4s and native HLS playbacks.
|
|
4060
4061
|
if (this.video_ && this.video_.src) {
|
|
4061
4062
|
const seekable = this.video_.seekable;
|
|
4062
|
-
if (seekable.length) {
|
|
4063
|
+
if (seekable && seekable.length) {
|
|
4064
|
+
const playRangeStart =
|
|
4065
|
+
this.config_ ? this.config_.playRangeStart : 0;
|
|
4066
|
+
const start = Math.max(seekable.start(0), playRangeStart);
|
|
4067
|
+
const playRangeEnd =
|
|
4068
|
+
this.config_ ? this.config_.playRangeEnd : Infinity;
|
|
4069
|
+
const end = Math.min(seekable.end(seekable.length - 1), playRangeEnd);
|
|
4063
4070
|
return {
|
|
4064
|
-
'start':
|
|
4065
|
-
'end':
|
|
4071
|
+
'start': start,
|
|
4072
|
+
'end': end,
|
|
4066
4073
|
};
|
|
4067
4074
|
}
|
|
4068
4075
|
}
|
|
@@ -4220,12 +4227,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4220
4227
|
}
|
|
4221
4228
|
this.trickPlayEventManager_.removeAll();
|
|
4222
4229
|
|
|
4223
|
-
if (this.video_.paused) {
|
|
4224
|
-
// Our fast forward is implemented with playbackRate and needs the video
|
|
4225
|
-
// to be playing (to not be paused) to take immediate effect.
|
|
4226
|
-
// If the video is paused, "unpause" it.
|
|
4227
|
-
this.video_.play();
|
|
4228
|
-
}
|
|
4229
4230
|
this.playRateController_.set(rate);
|
|
4230
4231
|
|
|
4231
4232
|
if (this.loadMode_ == shaka.Player.LoadMode.MEDIA_SOURCE) {
|
|
@@ -5389,7 +5390,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5389
5390
|
|
|
5390
5391
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
5391
5392
|
|
|
5392
|
-
|
|
5393
|
+
const seekRange = this.seekRange();
|
|
5394
|
+
let duration = seekRange.end - seekRange.start;
|
|
5393
5395
|
if (this.manifest_) {
|
|
5394
5396
|
duration = this.manifest_.presentationTimeline.getDuration();
|
|
5395
5397
|
}
|
|
@@ -5502,7 +5504,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5502
5504
|
}
|
|
5503
5505
|
|
|
5504
5506
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
5505
|
-
|
|
5507
|
+
const seekRange = this.seekRange();
|
|
5508
|
+
let duration = seekRange.end - seekRange.start;
|
|
5506
5509
|
if (this.manifest_) {
|
|
5507
5510
|
duration = this.manifest_.presentationTimeline.getDuration();
|
|
5508
5511
|
}
|
|
@@ -5928,9 +5931,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5928
5931
|
const Platform = shaka.util.Platform;
|
|
5929
5932
|
if (this.videoContainer_ &&
|
|
5930
5933
|
(!Platform.safariVersion() || document.fullscreenEnabled)) {
|
|
5931
|
-
const latestConfig = this.getConfiguration();
|
|
5932
5934
|
return new shaka.text.UITextDisplayer(
|
|
5933
|
-
this.video_, this.videoContainer_
|
|
5935
|
+
this.video_, this.videoContainer_);
|
|
5934
5936
|
} else {
|
|
5935
5937
|
// eslint-disable-next-line no-restricted-syntax
|
|
5936
5938
|
if (HTMLMediaElement.prototype.addTextTrack) {
|
|
@@ -6198,7 +6200,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6198
6200
|
let updateState = 'playing';
|
|
6199
6201
|
if (this.bufferObserver_.getState() == State.STARVING) {
|
|
6200
6202
|
updateState = 'buffering';
|
|
6201
|
-
} else if (this.
|
|
6203
|
+
} else if (this.isEnded()) {
|
|
6202
6204
|
updateState = 'ended';
|
|
6203
6205
|
} else if (this.video_.paused) {
|
|
6204
6206
|
updateState = 'paused';
|
|
@@ -6370,41 +6372,62 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6370
6372
|
if (!this.video_) {
|
|
6371
6373
|
return;
|
|
6372
6374
|
}
|
|
6373
|
-
|
|
6374
|
-
const
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
if (
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6375
|
+
|
|
6376
|
+
const isQuartile = (quartilePercent, currentPercent) => {
|
|
6377
|
+
const NumberUtils = shaka.util.NumberUtils;
|
|
6378
|
+
|
|
6379
|
+
if ((NumberUtils.isFloatEqual(quartilePercent, currentPercent) ||
|
|
6380
|
+
currentPercent > quartilePercent) &&
|
|
6381
|
+
this.completionPercent_ < quartilePercent) {
|
|
6382
|
+
this.completionPercent_ = quartilePercent;
|
|
6383
|
+
return true;
|
|
6384
|
+
}
|
|
6385
|
+
return false;
|
|
6386
|
+
};
|
|
6387
|
+
|
|
6388
|
+
const checkEnded = () => {
|
|
6389
|
+
if (this.config_ && this.config_.playRangeEnd != Infinity) {
|
|
6390
|
+
// Make sure the video stops when we reach the end.
|
|
6391
|
+
// This is required when there is a custom playRangeEnd specified.
|
|
6392
|
+
if (this.isEnded()) {
|
|
6393
|
+
this.video_.pause();
|
|
6385
6394
|
}
|
|
6386
6395
|
}
|
|
6396
|
+
};
|
|
6397
|
+
|
|
6398
|
+
const seekRange = this.seekRange();
|
|
6399
|
+
const duration = seekRange.end - seekRange.start;
|
|
6400
|
+
const completionRatio =
|
|
6401
|
+
duration > 0 ? this.video_.currentTime / duration : 0;
|
|
6402
|
+
|
|
6403
|
+
if (isNaN(completionRatio)) {
|
|
6404
|
+
return;
|
|
6387
6405
|
}
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6406
|
+
|
|
6407
|
+
const percent = completionRatio * 100;
|
|
6408
|
+
|
|
6409
|
+
let event;
|
|
6410
|
+
if (isQuartile(0, percent)) {
|
|
6411
|
+
event = shaka.Player.makeEvent_(shaka.util.FakeEvent.EventName.Started);
|
|
6412
|
+
} else if (isQuartile(25, percent)) {
|
|
6413
|
+
event = shaka.Player.makeEvent_(
|
|
6414
|
+
shaka.util.FakeEvent.EventName.FirstQuartile);
|
|
6415
|
+
} else if (isQuartile(50, percent)) {
|
|
6416
|
+
event = shaka.Player.makeEvent_(
|
|
6417
|
+
shaka.util.FakeEvent.EventName.Midpoint);
|
|
6418
|
+
} else if (isQuartile(75, percent)) {
|
|
6419
|
+
event = shaka.Player.makeEvent_(
|
|
6420
|
+
shaka.util.FakeEvent.EventName.ThirdQuartile);
|
|
6421
|
+
} else if (isQuartile(100, percent)) {
|
|
6422
|
+
event = shaka.Player.makeEvent_(
|
|
6423
|
+
shaka.util.FakeEvent.EventName.Complete);
|
|
6424
|
+
checkEnded();
|
|
6425
|
+
} else {
|
|
6426
|
+
checkEnded();
|
|
6427
|
+
}
|
|
6428
|
+
|
|
6429
|
+
if (event) {
|
|
6430
|
+
this.dispatchEvent(event);
|
|
6408
6431
|
}
|
|
6409
6432
|
}
|
|
6410
6433
|
|
|
@@ -7440,7 +7463,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
7440
7463
|
|
|
7441
7464
|
// This is a strong guarantee that we are buffered to the end, because it
|
|
7442
7465
|
// means the playhead is already at that end.
|
|
7443
|
-
if (this.
|
|
7466
|
+
if (this.isEnded()) {
|
|
7444
7467
|
return true;
|
|
7445
7468
|
}
|
|
7446
7469
|
|
|
@@ -7480,7 +7503,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
7480
7503
|
|
|
7481
7504
|
// This is a strong guarantee that we are buffered to the end, because it
|
|
7482
7505
|
// means the playhead is already at that end.
|
|
7483
|
-
if (this.
|
|
7506
|
+
if (this.isEnded()) {
|
|
7484
7507
|
return true;
|
|
7485
7508
|
}
|
|
7486
7509
|
|
|
@@ -7508,6 +7531,19 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
7508
7531
|
shaka.util.Error.Category.PLAYER,
|
|
7509
7532
|
shaka.util.Error.Code.LOAD_INTERRUPTED);
|
|
7510
7533
|
}
|
|
7534
|
+
|
|
7535
|
+
/**
|
|
7536
|
+
* Indicate if the video has ended.
|
|
7537
|
+
*
|
|
7538
|
+
* @return {boolean}
|
|
7539
|
+
* @export
|
|
7540
|
+
*/
|
|
7541
|
+
isEnded() {
|
|
7542
|
+
if (!this.video_ || this.video_.ended) {
|
|
7543
|
+
return true;
|
|
7544
|
+
}
|
|
7545
|
+
return this.video_.currentTime >= this.seekRange().end;
|
|
7546
|
+
}
|
|
7511
7547
|
};
|
|
7512
7548
|
|
|
7513
7549
|
/**
|
|
@@ -7549,7 +7585,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
7549
7585
|
* @export
|
|
7550
7586
|
*/
|
|
7551
7587
|
// eslint-disable-next-line no-useless-concat, max-len
|
|
7552
|
-
shaka.Player.version = 'v4.9.
|
|
7588
|
+
shaka.Player.version = 'v4.9.34' + '-uncompiled'; // x-release-please-version
|
|
7553
7589
|
|
|
7554
7590
|
// Initialize the deprecation system using the version string we just set
|
|
7555
7591
|
// on the player.
|
|
@@ -328,7 +328,7 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
328
328
|
let displayType = videoConfig.contentType;
|
|
329
329
|
if (videoConfig.width && videoConfig.height) {
|
|
330
330
|
// All Chromecast can support 720p videos
|
|
331
|
-
if (videoConfig.width > 1280
|
|
331
|
+
if (videoConfig.width > 1280 && videoConfig.height > 720) {
|
|
332
332
|
displayType +=
|
|
333
333
|
`; width=${videoConfig.width}; height=${videoConfig.height}`;
|
|
334
334
|
}
|
|
@@ -91,6 +91,9 @@ shaka.text.SimpleTextDisplayer = class {
|
|
|
91
91
|
* @export
|
|
92
92
|
*/
|
|
93
93
|
append(cues) {
|
|
94
|
+
if (!this.textTrack_) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
94
97
|
const flattenedCues = shaka.text.Utils.getCuesToFlatten(cues);
|
|
95
98
|
|
|
96
99
|
// Convert cues.
|
|
@@ -178,6 +181,9 @@ shaka.text.SimpleTextDisplayer = class {
|
|
|
178
181
|
* @export
|
|
179
182
|
*/
|
|
180
183
|
isTextVisible() {
|
|
184
|
+
if (!this.textTrack_) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
181
187
|
return this.textTrack_.mode == 'showing';
|
|
182
188
|
}
|
|
183
189
|
|
|
@@ -186,7 +192,9 @@ shaka.text.SimpleTextDisplayer = class {
|
|
|
186
192
|
* @export
|
|
187
193
|
*/
|
|
188
194
|
setTextVisibility(on) {
|
|
189
|
-
this.textTrack_
|
|
195
|
+
if (this.textTrack_) {
|
|
196
|
+
this.textTrack_.mode = on ? 'showing' : 'hidden';
|
|
197
|
+
}
|
|
190
198
|
}
|
|
191
199
|
|
|
192
200
|
/**
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
goog.provide('shaka.text.UITextDisplayer');
|
|
9
9
|
|
|
10
10
|
goog.require('goog.asserts');
|
|
11
|
-
goog.require('shaka.Deprecate');
|
|
12
11
|
goog.require('shaka.log');
|
|
13
12
|
goog.require('shaka.text.Cue');
|
|
14
13
|
goog.require('shaka.text.CueRegion');
|
|
@@ -31,9 +30,8 @@ shaka.text.UITextDisplayer = class {
|
|
|
31
30
|
* Constructor.
|
|
32
31
|
* @param {HTMLMediaElement} video
|
|
33
32
|
* @param {HTMLElement} videoContainer
|
|
34
|
-
* @param {shaka.extern.TextDisplayerConfiguration} config
|
|
35
33
|
*/
|
|
36
|
-
constructor(video, videoContainer
|
|
34
|
+
constructor(video, videoContainer) {
|
|
37
35
|
goog.asserts.assert(videoContainer, 'videoContainer should be valid.');
|
|
38
36
|
|
|
39
37
|
if (!document.fullscreenEnabled) {
|
|
@@ -74,22 +72,12 @@ shaka.text.UITextDisplayer = class {
|
|
|
74
72
|
|
|
75
73
|
this.videoContainer_.appendChild(this.textContainer_);
|
|
76
74
|
|
|
77
|
-
if (!config || !config.captionsUpdatePeriod) {
|
|
78
|
-
shaka.Deprecate.deprecateFeature(5,
|
|
79
|
-
'UITextDisplayer w/ config',
|
|
80
|
-
'Please migrate to initializing UITextDisplayer with a config.');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** @private {number} */
|
|
84
|
-
const updatePeriod = (config && config.captionsUpdatePeriod) ?
|
|
85
|
-
config.captionsUpdatePeriod : 0.25;
|
|
86
|
-
|
|
87
75
|
/** @private {shaka.util.Timer} */
|
|
88
76
|
this.captionsTimer_ = new shaka.util.Timer(() => {
|
|
89
77
|
if (!this.video_.paused) {
|
|
90
78
|
this.updateCaptions_();
|
|
91
79
|
}
|
|
92
|
-
}).tickEvery(
|
|
80
|
+
}).tickEvery(/* seconds= */ 0.25);
|
|
93
81
|
|
|
94
82
|
/**
|
|
95
83
|
* Maps cues to cue elements. Specifically points out the wrapper element of
|
|
@@ -84,10 +84,15 @@ shaka.text.VttTextParser = class {
|
|
|
84
84
|
// HLS content, which should use X-TIMESTAMP-MAP and periodStart instead.
|
|
85
85
|
let offset = time.vttOffset;
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
if (this.manifestType_ == shaka.media.ManifestParser.HLS) {
|
|
88
|
+
// Only use 'X-TIMESTAMP-MAP' with HLS.
|
|
89
|
+
if (blocks[0].includes('X-TIMESTAMP-MAP')) {
|
|
90
|
+
offset = this.computeHlsOffset_(blocks[0], time);
|
|
91
|
+
} else if (time.periodStart && time.vttOffset == time.periodStart) {
|
|
92
|
+
// In the case where X-TIMESTAMP-MAP is not used and it is HLS, we
|
|
93
|
+
// should not use offset unless segment-relative times are used.
|
|
94
|
+
offset = 0;
|
|
95
|
+
}
|
|
91
96
|
}
|
|
92
97
|
|
|
93
98
|
// Parse VTT regions.
|
|
@@ -35,6 +35,9 @@ shaka.transmuxer.AacTransmuxer = class {
|
|
|
35
35
|
|
|
36
36
|
/** @private {!Map.<string, !Uint8Array>} */
|
|
37
37
|
this.initSegments = new Map();
|
|
38
|
+
|
|
39
|
+
/** @private {?Uint8Array} */
|
|
40
|
+
this.lastInitSegment_ = null;
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
|
|
@@ -215,11 +218,16 @@ shaka.transmuxer.AacTransmuxer = class {
|
|
|
215
218
|
} else {
|
|
216
219
|
initSegment = this.initSegments.get(initSegmentKey);
|
|
217
220
|
}
|
|
221
|
+
const appendInitSegment = this.lastInitSegment_ !== initSegment;
|
|
218
222
|
const segmentData = mp4Generator.segmentData();
|
|
219
|
-
|
|
223
|
+
this.lastInitSegment_ = initSegment;
|
|
220
224
|
this.frameIndex_++;
|
|
221
|
-
|
|
222
|
-
|
|
225
|
+
if (appendInitSegment) {
|
|
226
|
+
const transmuxData = Uint8ArrayUtils.concat(initSegment, segmentData);
|
|
227
|
+
return Promise.resolve(transmuxData);
|
|
228
|
+
} else {
|
|
229
|
+
return Promise.resolve(segmentData);
|
|
230
|
+
}
|
|
223
231
|
}
|
|
224
232
|
};
|
|
225
233
|
|
|
@@ -34,6 +34,9 @@ shaka.transmuxer.Ac3Transmuxer = class {
|
|
|
34
34
|
|
|
35
35
|
/** @private {!Map.<string, !Uint8Array>} */
|
|
36
36
|
this.initSegments = new Map();
|
|
37
|
+
|
|
38
|
+
/** @private {?Uint8Array} */
|
|
39
|
+
this.lastInitSegment_ = null;
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
|
|
@@ -203,11 +206,16 @@ shaka.transmuxer.Ac3Transmuxer = class {
|
|
|
203
206
|
} else {
|
|
204
207
|
initSegment = this.initSegments.get(initSegmentKey);
|
|
205
208
|
}
|
|
209
|
+
const appendInitSegment = this.lastInitSegment_ !== initSegment;
|
|
206
210
|
const segmentData = mp4Generator.segmentData();
|
|
207
|
-
|
|
211
|
+
this.lastInitSegment_ = initSegment;
|
|
208
212
|
this.frameIndex_++;
|
|
209
|
-
|
|
210
|
-
|
|
213
|
+
if (appendInitSegment) {
|
|
214
|
+
const transmuxData = Uint8ArrayUtils.concat(initSegment, segmentData);
|
|
215
|
+
return Promise.resolve(transmuxData);
|
|
216
|
+
} else {
|
|
217
|
+
return Promise.resolve(segmentData);
|
|
218
|
+
}
|
|
211
219
|
}
|
|
212
220
|
};
|
|
213
221
|
|
|
@@ -34,6 +34,9 @@ shaka.transmuxer.Ec3Transmuxer = class {
|
|
|
34
34
|
|
|
35
35
|
/** @private {!Map.<string, !Uint8Array>} */
|
|
36
36
|
this.initSegments = new Map();
|
|
37
|
+
|
|
38
|
+
/** @private {?Uint8Array} */
|
|
39
|
+
this.lastInitSegment_ = null;
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
|
|
@@ -203,11 +206,16 @@ shaka.transmuxer.Ec3Transmuxer = class {
|
|
|
203
206
|
} else {
|
|
204
207
|
initSegment = this.initSegments.get(initSegmentKey);
|
|
205
208
|
}
|
|
209
|
+
const appendInitSegment = this.lastInitSegment_ !== initSegment;
|
|
206
210
|
const segmentData = mp4Generator.segmentData();
|
|
207
|
-
|
|
211
|
+
this.lastInitSegment_ = initSegment;
|
|
208
212
|
this.frameIndex_++;
|
|
209
|
-
|
|
210
|
-
|
|
213
|
+
if (appendInitSegment) {
|
|
214
|
+
const transmuxData = Uint8ArrayUtils.concat(initSegment, segmentData);
|
|
215
|
+
return Promise.resolve(transmuxData);
|
|
216
|
+
} else {
|
|
217
|
+
return Promise.resolve(segmentData);
|
|
218
|
+
}
|
|
211
219
|
}
|
|
212
220
|
};
|
|
213
221
|
|