shaka-player 3.3.4 → 4.0.0
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/.github/workflows/build-and-test.yaml +0 -1
- package/.github/workflows/demo-version-index.yaml +8 -0
- package/.github/workflows/release-please.yaml +23 -2
- package/.github/workflows/selenium-lab-tests.yaml +0 -1
- package/.github/workflows/sync-labels.yaml +33 -0
- package/.github/workflows/update-issues.yaml +29 -0
- package/.github/workflows/validate-pr-title.yaml +35 -0
- package/AUTHORS +1 -0
- package/CHANGELOG.md +198 -32
- package/CONTRIBUTORS +1 -0
- package/README.md +10 -7
- package/app-engine/demo-version-index/README.md +3 -3
- package/app-engine/demo-version-index/app.yaml +27 -1
- package/app-engine/demo-version-index/generate.py +164 -0
- package/app-engine/demo-version-index/main.py +4 -155
- package/app-engine/demo-version-index/requirements.txt +0 -1
- package/build/README.md +2 -2
- package/build/compiler.py +1 -1
- package/build/generateTsDefs.py +0 -2
- package/build/shaka-lab.yaml +0 -2
- package/build/test.py +7 -1
- package/build/types/core +0 -1
- package/build/types/polyfill +0 -3
- package/demo/common/asset.js +17 -1
- package/demo/common/assets.js +29 -0
- package/demo/common/message_ids.js +6 -3
- package/demo/config.js +10 -11
- package/demo/custom.js +39 -0
- package/demo/demo_utils.js +0 -1
- package/demo/locales/en.json +6 -3
- package/demo/locales/source.json +22 -10
- package/demo/main.js +9 -6
- package/demo/search.js +2 -1
- package/dist/controls.css +1 -1
- package/dist/demo.compiled.debug.js +71 -64
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +71 -64
- package/dist/demo.compiled.map +3 -3
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +16 -20
- package/dist/locales.js +31 -29
- package/dist/receiver.compiled.debug.js +32 -28
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +32 -28
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +78 -83
- package/dist/shaka-player.compiled.debug.d.ts +78 -83
- package/dist/shaka-player.compiled.debug.externs.js +126 -126
- package/dist/shaka-player.compiled.debug.js +426 -483
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +126 -126
- package/dist/shaka-player.compiled.js +838 -856
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +80 -83
- package/dist/shaka-player.ui.debug.d.ts +80 -83
- package/dist/shaka-player.ui.debug.externs.js +134 -126
- package/dist/shaka-player.ui.debug.js +488 -543
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +134 -126
- package/dist/shaka-player.ui.js +980 -994
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/config.md +0 -2
- package/docs/tutorials/drm-config.md +5 -0
- package/docs/tutorials/fairplay.md +7 -22
- package/docs/tutorials/faq.md +0 -11
- package/docs/tutorials/index.json +2 -8
- package/docs/tutorials/plugins.md +1 -3
- package/docs/tutorials/upgrade.md +83 -11
- package/externs/polyfill.js +15 -0
- package/externs/shaka/manifest.js +5 -1
- package/externs/shaka/net.js +12 -0
- package/externs/shaka/offline.js +5 -1
- package/externs/shaka/player.js +39 -32
- package/externs/shaka/text.js +12 -12
- package/externs/sourcebuffer.js +15 -0
- package/lib/ads/client_side_ad.js +13 -2
- package/lib/ads/client_side_ad_manager.js +22 -4
- package/lib/cast/cast_utils.js +0 -1
- package/lib/dash/content_protection.js +85 -5
- package/lib/dash/dash_parser.js +1 -1
- package/lib/hls/hls_parser.js +378 -743
- package/lib/hls/manifest_text_parser.js +2 -3
- package/lib/media/drm_engine.js +102 -53
- package/lib/media/gap_jumping_controller.js +10 -45
- package/lib/media/media_source_engine.js +87 -15
- package/lib/media/playhead.js +2 -5
- package/lib/media/presentation_timeline.js +1 -2
- package/lib/media/segment_index.js +13 -46
- package/lib/media/segment_reference.js +47 -1
- package/lib/media/streaming_engine.js +29 -11
- package/lib/media/time_ranges_utils.js +4 -9
- package/lib/net/networking_engine.js +3 -0
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +1 -0
- package/lib/offline/storage.js +100 -132
- package/lib/player.js +17 -201
- package/lib/polyfill/media_capabilities.js +12 -6
- package/lib/polyfill/mediasource.js +0 -28
- package/lib/polyfill/patchedmediakeys_nop.js +2 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +2 -0
- package/lib/text/cue.js +0 -6
- package/lib/text/lrc_text_parser.js +8 -0
- package/lib/text/mp4_ttml_parser.js +8 -0
- package/lib/text/mp4_vtt_parser.js +8 -0
- package/lib/text/sbv_text_parser.js +8 -0
- package/lib/text/simple_text_displayer.js +1 -7
- package/lib/text/srt_text_parser.js +8 -0
- package/lib/text/ssa_text_parser.js +8 -0
- package/lib/text/text_engine.js +19 -3
- package/lib/text/ttml_text_parser.js +8 -0
- package/lib/text/ui_text_displayer.js +1 -7
- package/lib/text/vtt_text_parser.js +24 -2
- package/lib/text/web_vtt_generator.js +1 -7
- package/lib/util/error.js +9 -13
- package/lib/util/fairplay_utils.js +109 -0
- package/lib/util/functional.js +0 -42
- package/lib/util/mime_utils.js +2 -0
- package/lib/util/platform.js +45 -0
- package/lib/util/player_configuration.js +12 -6
- package/lib/util/pssh.js +23 -4
- package/lib/util/stream_utils.js +92 -22
- package/lib/util/uint8array_utils.js +0 -16
- package/lib/util/xml_utils.js +1 -1
- package/package.json +1 -1
- package/roadmap.md +19 -19
- package/shaka-player.uncompiled.js +0 -3
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/dash/dash_parser_content_protection_unit.js +44 -0
- package/test/dash/dash_parser_manifest_unit.js +0 -24
- package/test/dash/dash_parser_segment_template_unit.js +3 -4
- package/test/demo/demo_unit.js +2 -1
- package/test/hls/hls_live_unit.js +99 -220
- package/test/hls/hls_parser_unit.js +515 -432
- package/test/media/drm_engine_unit.js +86 -120
- package/test/media/media_source_engine_integration.js +26 -3
- package/test/media/media_source_engine_unit.js +7 -6
- package/test/media/playhead_unit.js +27 -191
- package/test/media/segment_index_unit.js +15 -25
- package/test/media/streaming_engine_integration.js +4 -39
- package/test/media/streaming_engine_unit.js +3 -2
- package/test/media/time_ranges_utils_unit.js +0 -5
- package/test/offline/manifest_convert_unit.js +34 -4
- package/test/offline/offline_manifest_parser_unit.js +1 -0
- package/test/offline/storage_integration.js +5 -4
- package/test/player_external.js +0 -6
- package/test/player_integration.js +16 -0
- package/test/player_unit.js +26 -0
- package/test/test/util/fake_media_source_engine.js +11 -4
- package/test/test/util/manifest_generator.js +3 -1
- package/test/test/util/manifest_parser_util.js +4 -1
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/streaming_engine_util.js +1 -0
- package/test/test/util/test_scheme.js +24 -1
- package/test/test/util/util.js +4 -4
- package/test/text/cue_integration.js +2 -2
- package/test/text/lrc_text_parser_unit.js +6 -7
- package/test/text/mp4_ttml_parser_unit.js +6 -4
- package/test/text/mp4_vtt_parser_unit.js +6 -5
- package/test/text/sbv_text_parser_unit.js +5 -6
- package/test/text/srt_text_parser_unit.js +5 -6
- package/test/text/ssa_text_parser_unit.js +17 -29
- package/test/text/text_engine_unit.js +45 -5
- package/test/text/ttml_text_parser_unit.js +77 -77
- package/test/text/vtt_text_parser_unit.js +55 -57
- package/test/ui/ui_integration.js +0 -16
- package/test/ui/ui_unit.js +27 -0
- package/test/util/cmcd_manager_unit.js +3 -0
- package/test/util/stream_utils_unit.js +23 -7
- package/ui/controls.js +65 -40
- package/ui/fullscreen_button.js +26 -6
- package/ui/less/containers.less +3 -3
- package/ui/locales/en.json +1 -0
- package/ui/locales/source.json +5 -0
- package/ui/resolution_selection.js +31 -33
- package/ui/ui.js +0 -17
- package/docs/tutorials/upgrade-v2-5.md +0 -441
- package/docs/tutorials/upgrade-v3.md +0 -38
- package/lib/polyfill/mathround.js +0 -49
- package/lib/polyfill/patchedmediakeys_apple.js +0 -744
- package/lib/polyfill/patchedmediakeys_ms.js +0 -698
- package/lib/util/mutex.js +0 -52
- package/test/util/functional_unit.js +0 -82
package/lib/offline/storage.js
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
goog.provide('shaka.offline.Storage');
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
|
-
goog.require('shaka.Deprecate');
|
|
11
10
|
goog.require('shaka.Player');
|
|
12
11
|
goog.require('shaka.log');
|
|
13
12
|
goog.require('shaka.media.DrmEngine');
|
|
@@ -25,11 +24,9 @@ goog.require('shaka.util.ArrayUtils');
|
|
|
25
24
|
goog.require('shaka.util.ConfigUtils');
|
|
26
25
|
goog.require('shaka.util.Destroyer');
|
|
27
26
|
goog.require('shaka.util.Error');
|
|
28
|
-
goog.require('shaka.util.Functional');
|
|
29
27
|
goog.require('shaka.util.IDestroyable');
|
|
30
28
|
goog.require('shaka.util.Iterables');
|
|
31
29
|
goog.require('shaka.util.MimeUtils');
|
|
32
|
-
goog.require('shaka.util.Mutex');
|
|
33
30
|
goog.require('shaka.util.Platform');
|
|
34
31
|
goog.require('shaka.util.PlayerConfiguration');
|
|
35
32
|
goog.require('shaka.util.StreamUtils');
|
|
@@ -195,22 +192,10 @@ shaka.offline.Storage = class {
|
|
|
195
192
|
if (arguments.length == 2 && typeof(config) == 'string') {
|
|
196
193
|
config = shaka.util.ConfigUtils.convertToConfigObject(config, value);
|
|
197
194
|
}
|
|
198
|
-
|
|
199
195
|
goog.asserts.assert(typeof(config) == 'object', 'Should be an object!');
|
|
200
196
|
|
|
201
|
-
// Deprecate 'manifest.dash.defaultPresentationDelay' configuration.
|
|
202
|
-
if (config['manifest'] && config['manifest']['dash'] &&
|
|
203
|
-
'defaultPresentationDelay' in config['manifest']['dash']) {
|
|
204
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
205
|
-
'manifest.dash.defaultPresentationDelay configuration',
|
|
206
|
-
'Please Use manifest.defaultPresentationDelay instead.');
|
|
207
|
-
config['manifest']['defaultPresentationDelay'] =
|
|
208
|
-
config['manifest']['dash']['defaultPresentationDelay'];
|
|
209
|
-
delete config['manifest']['dash']['defaultPresentationDelay'];
|
|
210
|
-
}
|
|
211
|
-
|
|
212
197
|
goog.asserts.assert(
|
|
213
|
-
this.config_, 'Cannot reconfigure
|
|
198
|
+
this.config_, 'Cannot reconfigure storage after calling destroy.');
|
|
214
199
|
return shaka.util.PlayerConfiguration.mergeConfigObjects(
|
|
215
200
|
/* destination= */ this.config_, /* updates= */ config );
|
|
216
201
|
}
|
|
@@ -292,7 +277,7 @@ shaka.offline.Storage = class {
|
|
|
292
277
|
config.manifest.retryParameters,
|
|
293
278
|
mimeType || null);
|
|
294
279
|
|
|
295
|
-
return
|
|
280
|
+
return factory();
|
|
296
281
|
};
|
|
297
282
|
|
|
298
283
|
/** @type {!shaka.offline.DownloadManager} */
|
|
@@ -309,33 +294,9 @@ shaka.offline.Storage = class {
|
|
|
309
294
|
shaka.util.ArrayUtils.remove(this.openDownloadManagers_, downloader);
|
|
310
295
|
});
|
|
311
296
|
|
|
312
|
-
// Provide a temporary shim for "then" for backward compatibility.
|
|
313
|
-
/** @type {!Object} */ (abortableStoreOp)['then'] = (onSuccess) => {
|
|
314
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
315
|
-
'shaka.offline.Storage.store.then',
|
|
316
|
-
'Storage operations now return a shaka.util.AbortableOperation, ' +
|
|
317
|
-
'rather than a promise. Please update to conform to this new API; ' +
|
|
318
|
-
'you can use the |chain| method instead.');
|
|
319
|
-
return abortableStoreOp.promise.then(onSuccess);
|
|
320
|
-
};
|
|
321
|
-
|
|
322
297
|
return this.startAbortableOperation_(abortableStoreOp);
|
|
323
298
|
}
|
|
324
299
|
|
|
325
|
-
/**
|
|
326
|
-
* Returns true if an asset is currently downloading.
|
|
327
|
-
*
|
|
328
|
-
* @return {boolean}
|
|
329
|
-
* @deprecated
|
|
330
|
-
* @export
|
|
331
|
-
*/
|
|
332
|
-
getStoreInProgress() {
|
|
333
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
334
|
-
'shaka.offline.Storage.getStoreInProgress',
|
|
335
|
-
'Multiple concurrent downloads are now supported.');
|
|
336
|
-
return false;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
300
|
/**
|
|
340
301
|
* See |shaka.offline.Storage.store| for details.
|
|
341
302
|
*
|
|
@@ -479,36 +440,34 @@ shaka.offline.Storage = class {
|
|
|
479
440
|
async downloadSegments_(
|
|
480
441
|
toDownload, manifestId, manifestDB, downloader, config, storage,
|
|
481
442
|
manifest, drmEngine) {
|
|
443
|
+
let pendingManifestUpdates = {};
|
|
444
|
+
let pendingDataSize = 0;
|
|
445
|
+
|
|
482
446
|
/**
|
|
483
447
|
* @param {!Array.<!shaka.offline.DownloadInfo>} toDownload
|
|
484
448
|
* @param {boolean} updateDRM
|
|
485
449
|
*/
|
|
486
450
|
const download = async (toDownload, updateDRM) => {
|
|
487
|
-
const throwIfAbortedFn = () => {
|
|
488
|
-
this.ensureNotDestroyed_();
|
|
489
|
-
};
|
|
490
451
|
for (const download of toDownload) {
|
|
491
|
-
/** @param {?BufferSource} data */
|
|
492
|
-
let data;
|
|
493
452
|
const request = download.makeSegmentRequest(config);
|
|
494
453
|
const estimateId = download.estimateId;
|
|
495
454
|
const isInitSegment = download.isInitSegment;
|
|
496
|
-
const onDownloaded = (d) => {
|
|
497
|
-
data = d;
|
|
498
|
-
return Promise.resolve();
|
|
499
|
-
};
|
|
500
|
-
downloader.queue(download.groupId,
|
|
501
|
-
request, estimateId, isInitSegment, onDownloaded);
|
|
502
|
-
downloader.queueWork(download.groupId, async () => {
|
|
503
|
-
goog.asserts.assert(data, 'We should have loaded data by now');
|
|
504
|
-
goog.asserts.assert(data instanceof ArrayBuffer,
|
|
505
|
-
'The data should be an ArrayBuffer');
|
|
506
455
|
|
|
456
|
+
const onDownloaded = async (data) => {
|
|
457
|
+
// Store the data.
|
|
458
|
+
const dataKeys = await storage.addSegments([{data}]);
|
|
459
|
+
this.ensureNotDestroyed_();
|
|
460
|
+
|
|
461
|
+
// Store the necessary update to the manifest, to be processed later.
|
|
507
462
|
const ref = /** @type {!shaka.media.SegmentReference} */ (
|
|
508
463
|
download.ref);
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
464
|
+
const id = shaka.offline.DownloadInfo.idForSegmentRef(ref);
|
|
465
|
+
pendingManifestUpdates[id] = dataKeys[0];
|
|
466
|
+
pendingDataSize += data.byteLength;
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
downloader.queue(download.groupId,
|
|
470
|
+
request, estimateId, isInitSegment, onDownloaded);
|
|
512
471
|
}
|
|
513
472
|
await downloader.waitToFinish();
|
|
514
473
|
|
|
@@ -516,8 +475,8 @@ shaka.offline.Storage = class {
|
|
|
516
475
|
// Re-store the manifest, to attach session IDs.
|
|
517
476
|
// These were (maybe) discovered inside the downloader; we can only add
|
|
518
477
|
// them now, at the end, since the manifestDB is in flux during the
|
|
519
|
-
// process of downloading and storing, and
|
|
520
|
-
// not know about the DRM engine.
|
|
478
|
+
// process of downloading and storing, and assignSegmentsToManifest
|
|
479
|
+
// does not know about the DRM engine.
|
|
521
480
|
this.ensureNotDestroyed_();
|
|
522
481
|
this.setManifestDrmFields_(manifest, manifestDB, drmEngine, config);
|
|
523
482
|
await storage.updateManifest(manifestId, manifestDB);
|
|
@@ -526,24 +485,54 @@ shaka.offline.Storage = class {
|
|
|
526
485
|
|
|
527
486
|
const usingBgFetch = false; // TODO: Get.
|
|
528
487
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
488
|
+
try {
|
|
489
|
+
if (this.getManifestIsEncrypted_(manifest) && usingBgFetch &&
|
|
490
|
+
!this.getManifestIncludesInitData_(manifest)) {
|
|
491
|
+
// Background fetch can't make DRM sessions, so if we have to get the
|
|
492
|
+
// init data from the init segments, download those first before
|
|
493
|
+
// anything else.
|
|
494
|
+
await download(toDownload.filter((info) => info.isInitSegment), true);
|
|
495
|
+
this.ensureNotDestroyed_();
|
|
496
|
+
toDownload = toDownload.filter((info) => !info.isInitSegment);
|
|
538
497
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
498
|
+
// Copy these and reset them now, before calling await.
|
|
499
|
+
const manifestUpdates = pendingManifestUpdates;
|
|
500
|
+
const dataSize = pendingDataSize;
|
|
501
|
+
pendingManifestUpdates = {};
|
|
502
|
+
pendingDataSize = 0;
|
|
542
503
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
504
|
+
await shaka.offline.Storage.assignSegmentsToManifest(
|
|
505
|
+
storage, manifestId, manifestDB, manifestUpdates, dataSize,
|
|
506
|
+
() => this.ensureNotDestroyed_());
|
|
507
|
+
this.ensureNotDestroyed_();
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (!usingBgFetch) {
|
|
511
|
+
await download(toDownload, false);
|
|
512
|
+
this.ensureNotDestroyed_();
|
|
513
|
+
|
|
514
|
+
// Copy these and reset them now, before calling await.
|
|
515
|
+
const manifestUpdates = pendingManifestUpdates;
|
|
516
|
+
const dataSize = pendingDataSize;
|
|
517
|
+
pendingManifestUpdates = {};
|
|
518
|
+
pendingDataSize = 0;
|
|
519
|
+
|
|
520
|
+
await shaka.offline.Storage.assignSegmentsToManifest(
|
|
521
|
+
storage, manifestId, manifestDB, manifestUpdates, dataSize,
|
|
522
|
+
() => this.ensureNotDestroyed_());
|
|
523
|
+
this.ensureNotDestroyed_();
|
|
524
|
+
|
|
525
|
+
goog.asserts.assert(
|
|
526
|
+
!manifestDB.isIncomplete, 'The manifest should be complete by now');
|
|
527
|
+
} else {
|
|
528
|
+
// TODO: Send the request to the service worker. Don't await the result.
|
|
529
|
+
}
|
|
530
|
+
} catch (error) {
|
|
531
|
+
const dataKeys = Object.values(pendingManifestUpdates);
|
|
532
|
+
// Remove these pending segments that are not yet linked to the manifest.
|
|
533
|
+
await storage.removeSegments(dataKeys, (key) => {});
|
|
534
|
+
|
|
535
|
+
throw error;
|
|
547
536
|
}
|
|
548
537
|
}
|
|
549
538
|
|
|
@@ -567,70 +556,50 @@ shaka.offline.Storage = class {
|
|
|
567
556
|
}
|
|
568
557
|
|
|
569
558
|
/**
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
* The parts of this function that modify the manifest are protected by a
|
|
573
|
-
* mutex, to prevent race conditions; specifically, it prevents two parallel
|
|
574
|
-
* instances of this method from both loading the manifest into memory at the
|
|
575
|
-
* same time, which would result in the slower/later call overwriting the
|
|
576
|
-
* changes of the other.
|
|
559
|
+
* Updates the given manifest, assigns database keys to segments, then stores
|
|
560
|
+
* the updated manifest.
|
|
577
561
|
*
|
|
562
|
+
* It is up to the caller to ensure that this method is not called
|
|
563
|
+
* concurrently on the same manifest.
|
|
564
|
+
*
|
|
565
|
+
* @param {shaka.extern.StorageCell} storage
|
|
578
566
|
* @param {number} manifestId
|
|
579
|
-
* @param {!shaka.
|
|
580
|
-
* @param {
|
|
567
|
+
* @param {!shaka.extern.ManifestDB} manifestDB
|
|
568
|
+
* @param {!Object.<string, number>} manifestUpdates
|
|
569
|
+
* @param {number} dataSizeUpdate
|
|
581
570
|
* @param {function()} throwIfAbortedFn A function that should throw if the
|
|
582
571
|
* download has been aborted.
|
|
583
|
-
* @return {!Promise
|
|
572
|
+
* @return {!Promise}
|
|
584
573
|
*/
|
|
585
|
-
static async
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const idForRef = shaka.offline.DownloadInfo.idForSegmentRef(ref);
|
|
574
|
+
static async assignSegmentsToManifest(
|
|
575
|
+
storage, manifestId, manifestDB, manifestUpdates, dataSizeUpdate,
|
|
576
|
+
throwIfAbortedFn) {
|
|
590
577
|
let manifestUpdated = false;
|
|
591
|
-
let dataKey;
|
|
592
|
-
let activeHandle;
|
|
593
|
-
/** @type {!shaka.extern.ManifestDB} */
|
|
594
|
-
let manifestDB;
|
|
595
|
-
|
|
596
|
-
let mutexId = 0;
|
|
597
578
|
|
|
598
579
|
try {
|
|
599
|
-
await muxer.init();
|
|
600
|
-
activeHandle = await muxer.getActive();
|
|
601
|
-
|
|
602
|
-
// Store the data.
|
|
603
|
-
const dataKeys = await activeHandle.cell.addSegments([data]);
|
|
604
|
-
dataKey = dataKeys[0];
|
|
605
|
-
throwIfAbortedFn();
|
|
606
|
-
|
|
607
|
-
// Acquire the mutex before accessing the manifest, since there could be
|
|
608
|
-
// multiple instances of this method running at once.
|
|
609
|
-
mutexId = await shaka.offline.Storage.mutex_.acquire();
|
|
610
|
-
throwIfAbortedFn();
|
|
611
|
-
|
|
612
|
-
// Load the manifest.
|
|
613
|
-
const manifests = await activeHandle.cell.getManifests([manifestId]);
|
|
614
|
-
throwIfAbortedFn();
|
|
615
|
-
manifestDB = manifests[0];
|
|
616
|
-
|
|
617
580
|
// Assign the stored data to the manifest.
|
|
618
581
|
let complete = true;
|
|
619
582
|
for (const stream of manifestDB.streams) {
|
|
620
583
|
for (const segment of stream.segments) {
|
|
621
|
-
|
|
584
|
+
let dataKey = segment.pendingSegmentRefId ?
|
|
585
|
+
manifestUpdates[segment.pendingSegmentRefId] : null;
|
|
586
|
+
if (dataKey != null) {
|
|
622
587
|
segment.dataKey = dataKey;
|
|
623
588
|
// Now that the segment has been associated with the appropriate
|
|
624
589
|
// dataKey, the pendingSegmentRefId is no longer necessary.
|
|
625
590
|
segment.pendingSegmentRefId = undefined;
|
|
626
591
|
}
|
|
627
|
-
|
|
592
|
+
|
|
593
|
+
dataKey = segment.pendingInitSegmentRefId ?
|
|
594
|
+
manifestUpdates[segment.pendingInitSegmentRefId] : null;
|
|
595
|
+
if (dataKey != null) {
|
|
628
596
|
segment.initSegmentKey = dataKey;
|
|
629
597
|
// Now that the init segment has been associated with the
|
|
630
598
|
// appropriate initSegmentKey, the pendingInitSegmentRefId is no
|
|
631
599
|
// longer necessary.
|
|
632
600
|
segment.pendingInitSegmentRefId = undefined;
|
|
633
601
|
}
|
|
602
|
+
|
|
634
603
|
if (segment.pendingSegmentRefId) {
|
|
635
604
|
complete = false;
|
|
636
605
|
}
|
|
@@ -641,33 +610,30 @@ shaka.offline.Storage = class {
|
|
|
641
610
|
}
|
|
642
611
|
|
|
643
612
|
// Update the size of the manifest.
|
|
644
|
-
manifestDB.size +=
|
|
613
|
+
manifestDB.size += dataSizeUpdate;
|
|
645
614
|
|
|
646
615
|
// Mark the manifest as complete, if all segments are downloaded.
|
|
647
616
|
if (complete) {
|
|
648
617
|
manifestDB.isIncomplete = false;
|
|
649
618
|
}
|
|
650
619
|
|
|
651
|
-
//
|
|
652
|
-
await
|
|
620
|
+
// Update the manifest.
|
|
621
|
+
await storage.updateManifest(manifestId, manifestDB);
|
|
653
622
|
manifestUpdated = true;
|
|
654
623
|
throwIfAbortedFn();
|
|
655
624
|
} catch (e) {
|
|
656
625
|
await shaka.offline.Storage.cleanStoredManifest(manifestId);
|
|
657
626
|
|
|
658
|
-
if (
|
|
627
|
+
if (!manifestUpdated) {
|
|
628
|
+
const dataKeys = Object.values(manifestUpdates);
|
|
659
629
|
// The cleanStoredManifest method will not "see" any segments that have
|
|
660
630
|
// been downloaded but not assigned to the manifest yet. So un-store
|
|
661
631
|
// them separately.
|
|
662
|
-
await
|
|
632
|
+
await storage.removeSegments(dataKeys, (key) => {});
|
|
663
633
|
}
|
|
664
634
|
|
|
665
635
|
throw e;
|
|
666
|
-
} finally {
|
|
667
|
-
await muxer.destroy();
|
|
668
|
-
shaka.offline.Storage.mutex_.release(mutexId);
|
|
669
636
|
}
|
|
670
|
-
return manifestDB;
|
|
671
637
|
}
|
|
672
638
|
|
|
673
639
|
/**
|
|
@@ -866,6 +832,7 @@ shaka.offline.Storage = class {
|
|
|
866
832
|
drmInfo,
|
|
867
833
|
appMetadata: metadata,
|
|
868
834
|
isIncomplete: true,
|
|
835
|
+
sequenceMode: manifest.sequenceMode,
|
|
869
836
|
};
|
|
870
837
|
|
|
871
838
|
return {manifestDB, toDownload};
|
|
@@ -1361,6 +1328,9 @@ shaka.offline.Storage = class {
|
|
|
1361
1328
|
const startTime =
|
|
1362
1329
|
manifest.presentationTimeline.getSegmentAvailabilityStart();
|
|
1363
1330
|
|
|
1331
|
+
const numberOfParallelDownloads = config.offline.numberOfParallelDownloads;
|
|
1332
|
+
let groupId = 0;
|
|
1333
|
+
|
|
1364
1334
|
shaka.offline.Storage.forEachSegment_(stream, startTime, (segment) => {
|
|
1365
1335
|
const pendingSegmentRefId =
|
|
1366
1336
|
shaka.offline.DownloadInfo.idForSegmentRef(segment);
|
|
@@ -1374,7 +1344,7 @@ shaka.offline.Storage = class {
|
|
|
1374
1344
|
const segmentDownload = new shaka.offline.DownloadInfo(
|
|
1375
1345
|
segment,
|
|
1376
1346
|
estimateId,
|
|
1377
|
-
|
|
1347
|
+
groupId,
|
|
1378
1348
|
/* isInitSegment= */ false);
|
|
1379
1349
|
toDownload.set(pendingSegmentRefId, segmentDownload);
|
|
1380
1350
|
}
|
|
@@ -1389,7 +1359,7 @@ shaka.offline.Storage = class {
|
|
|
1389
1359
|
const initDownload = new shaka.offline.DownloadInfo(
|
|
1390
1360
|
segment.initSegmentReference,
|
|
1391
1361
|
estimateId,
|
|
1392
|
-
|
|
1362
|
+
groupId,
|
|
1393
1363
|
/* isInitSegment= */ true);
|
|
1394
1364
|
toDownload.set(pendingInitSegmentRefId, initDownload);
|
|
1395
1365
|
}
|
|
@@ -1409,6 +1379,7 @@ shaka.offline.Storage = class {
|
|
|
1409
1379
|
dataKey: 0,
|
|
1410
1380
|
};
|
|
1411
1381
|
streamDb.segments.push(segmentDB);
|
|
1382
|
+
groupId = (groupId + 1) % numberOfParallelDownloads;
|
|
1412
1383
|
});
|
|
1413
1384
|
|
|
1414
1385
|
return streamDb;
|
|
@@ -1662,9 +1633,6 @@ shaka.offline.Storage = class {
|
|
|
1662
1633
|
}
|
|
1663
1634
|
};
|
|
1664
1635
|
|
|
1665
|
-
/** @private {!shaka.util.Mutex} */
|
|
1666
|
-
shaka.offline.Storage.mutex_ = new shaka.util.Mutex();
|
|
1667
|
-
|
|
1668
1636
|
shaka.offline.Storage.defaultSystemIds_ = new Map()
|
|
1669
1637
|
.set('org.w3.clearkey', '1077efecc0b24d02ace33c1e52e2fb4b')
|
|
1670
1638
|
.set('com.widevine.alpha', 'edef8ba979d64acea3c827dcd51d21ed')
|