Source: lib/offline/offline_manifest_parser.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.offline.OfflineManifestParser');
  7. goog.require('goog.asserts');
  8. goog.require('shaka.log');
  9. goog.require('shaka.media.ManifestParser');
  10. goog.require('shaka.offline.ManifestConverter');
  11. goog.require('shaka.offline.OfflineUri');
  12. goog.require('shaka.offline.StorageMuxer');
  13. goog.require('shaka.util.Error');
  14. /**
  15. * @summary Creates a new offline manifest parser.
  16. * @implements {shaka.extern.ManifestParser}
  17. */
  18. shaka.offline.OfflineManifestParser = class {
  19. /** */
  20. constructor() {
  21. /** @private {shaka.offline.OfflineUri} */
  22. this.uri_ = null;
  23. }
  24. /** @override */
  25. configure(config) {
  26. // No-op
  27. }
  28. /** @override */
  29. async start(uriString, playerInterface) {
  30. /** @type {shaka.offline.OfflineUri} */
  31. const uri = shaka.offline.OfflineUri.parse(uriString);
  32. this.uri_ = uri;
  33. if (uri == null || !uri.isManifest()) {
  34. throw new shaka.util.Error(
  35. shaka.util.Error.Severity.CRITICAL,
  36. shaka.util.Error.Category.NETWORK,
  37. shaka.util.Error.Code.MALFORMED_OFFLINE_URI,
  38. uriString);
  39. }
  40. /** @type {!shaka.offline.StorageMuxer} */
  41. const muxer = new shaka.offline.StorageMuxer();
  42. try {
  43. await muxer.init();
  44. const cell = await muxer.getCell(uri.mechanism(), uri.cell());
  45. const manifests = await cell.getManifests([uri.key()]);
  46. const manifest = manifests[0];
  47. const converter = new shaka.offline.ManifestConverter(
  48. uri.mechanism(), uri.cell());
  49. const finalManifest = converter.fromManifestDB(manifest);
  50. playerInterface.makeTextStreamsForClosedCaptions(finalManifest);
  51. return finalManifest;
  52. } finally {
  53. await muxer.destroy();
  54. }
  55. }
  56. /** @override */
  57. stop() {
  58. return Promise.resolve();
  59. }
  60. /** @override */
  61. update() {
  62. // No-op
  63. }
  64. /** @override */
  65. async onExpirationUpdated(sessionId, expiration) {
  66. goog.asserts.assert(
  67. this.uri_,
  68. 'Should not get update event before start has been called');
  69. /** @type {!shaka.offline.OfflineUri} */
  70. const uri = this.uri_;
  71. /** @type {!shaka.offline.StorageMuxer} */
  72. const muxer = new shaka.offline.StorageMuxer();
  73. try {
  74. await muxer.init();
  75. const cell = await muxer.getCell(uri.mechanism(), uri.cell());
  76. const manifests = await cell.getManifests([uri.key()]);
  77. const manifest = manifests[0];
  78. const foundSession = manifest.sessionIds.includes(sessionId);
  79. const newExpiration = manifest.expiration == undefined ||
  80. manifest.expiration > expiration;
  81. if (foundSession && newExpiration) {
  82. shaka.log.debug('Updating expiration for stored content');
  83. await cell.updateManifestExpiration(uri.key(), expiration);
  84. }
  85. } catch (e) {
  86. // Ignore errors with update.
  87. shaka.log.error('There was an error updating', uri, e);
  88. } finally {
  89. await muxer.destroy();
  90. }
  91. }
  92. /** @override */
  93. onInitialVariantChosen(variant) {
  94. // No-op
  95. }
  96. /** @override */
  97. banLocation(uri) {
  98. // No-op
  99. }
  100. /** @override */
  101. setMediaElement(mediaElement) {
  102. // No-op
  103. }
  104. };
  105. shaka.media.ManifestParser.registerParserByMime(
  106. 'application/x-offline-manifest',
  107. () => new shaka.offline.OfflineManifestParser());