Source: lib/media/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.media.ManifestParser');
  7. goog.require('shaka.Deprecate');
  8. goog.require('shaka.log');
  9. goog.require('shaka.util.Error');
  10. goog.require('shaka.util.Platform');
  11. // TODO: revisit this when Closure Compiler supports partially-exported classes.
  12. /**
  13. * @summary An interface to register manifest parsers.
  14. * @export
  15. */
  16. shaka.media.ManifestParser = class {
  17. /**
  18. * Registers a manifest parser by file extension.
  19. *
  20. * @param {string} extension The file extension of the manifest.
  21. * @param {shaka.extern.ManifestParser.Factory} parserFactory The factory
  22. * used to create parser instances.
  23. * @export
  24. */
  25. static registerParserByExtension(extension, parserFactory) {
  26. shaka.Deprecate.deprecateFeature(5,
  27. 'ManifestParser.registerParserByExtension',
  28. 'Please use an ManifestParser with registerParserByMime function.');
  29. }
  30. /**
  31. * Registers a manifest parser by MIME type.
  32. *
  33. * @param {string} mimeType The MIME type of the manifest.
  34. * @param {shaka.extern.ManifestParser.Factory} parserFactory The factory
  35. * used to create parser instances.
  36. * @export
  37. */
  38. static registerParserByMime(mimeType, parserFactory) {
  39. shaka.media.ManifestParser.parsersByMime.set(mimeType, parserFactory);
  40. }
  41. /**
  42. * Unregisters a manifest parser by MIME type.
  43. *
  44. * @param {string} mimeType The MIME type of the manifest.
  45. * @export
  46. */
  47. static unregisterParserByMime(mimeType) {
  48. shaka.media.ManifestParser.parsersByMime.delete(mimeType);
  49. }
  50. /**
  51. * Returns a map of manifest support for well-known types.
  52. *
  53. * @return {!Object<string, boolean>}
  54. */
  55. static probeSupport() {
  56. const ManifestParser = shaka.media.ManifestParser;
  57. const support = {};
  58. // Make sure all registered parsers are shown, but only for MSE-enabled
  59. // platforms where our parsers matter.
  60. if (shaka.util.Platform.supportsMediaSource()) {
  61. for (const type of ManifestParser.parsersByMime.keys()) {
  62. support[type] = true;
  63. }
  64. }
  65. // Make sure all well-known types are tested as well, just to show an
  66. // explicit false for things people might be expecting.
  67. const testMimeTypes = [
  68. // DASH
  69. 'application/dash+xml',
  70. // HLS
  71. 'application/x-mpegurl',
  72. 'application/vnd.apple.mpegurl',
  73. // SmoothStreaming
  74. 'application/vnd.ms-sstr+xml',
  75. ];
  76. for (const type of testMimeTypes) {
  77. // Only query our parsers for MSE-enabled platforms. Otherwise, query a
  78. // temporary media element for native support for these types.
  79. if (shaka.util.Platform.supportsMediaSource()) {
  80. support[type] = ManifestParser.parsersByMime.has(type);
  81. } else {
  82. support[type] = shaka.util.Platform.supportsMediaType(type);
  83. }
  84. }
  85. return support;
  86. }
  87. /**
  88. * Get a factory that can create a manifest parser that should be able to
  89. * parse the manifest at |uri|.
  90. *
  91. * @param {string} uri
  92. * @param {?string} mimeType
  93. * @return {shaka.extern.ManifestParser.Factory}
  94. */
  95. static getFactory(uri, mimeType) {
  96. const ManifestParser = shaka.media.ManifestParser;
  97. // Try using the MIME type we were given.
  98. if (mimeType) {
  99. const factory = ManifestParser.parsersByMime.get(mimeType.toLowerCase());
  100. if (factory) {
  101. return factory;
  102. }
  103. shaka.log.warning(
  104. 'Could not determine manifest type using MIME type ', mimeType);
  105. }
  106. throw new shaka.util.Error(
  107. shaka.util.Error.Severity.CRITICAL,
  108. shaka.util.Error.Category.MANIFEST,
  109. shaka.util.Error.Code.UNABLE_TO_GUESS_MANIFEST_TYPE,
  110. uri,
  111. mimeType);
  112. }
  113. /**
  114. * Determines whether or not the MIME type is supported by our own
  115. * manifest parsers on this platform. This takes into account whether or not
  116. * MediaSource is available, as well as which parsers are registered to the
  117. * system.
  118. *
  119. * @param {string} mimeType
  120. * @return {boolean}
  121. */
  122. static isSupported(mimeType) {
  123. // Without MediaSource, our own parsers are useless.
  124. if (!shaka.util.Platform.supportsMediaSource()) {
  125. return false;
  126. }
  127. return shaka.media.ManifestParser.parsersByMime.has(mimeType);
  128. }
  129. };
  130. /**
  131. * @const {string}
  132. */
  133. shaka.media.ManifestParser.HLS = 'HLS';
  134. /**
  135. * @const {string}
  136. */
  137. shaka.media.ManifestParser.DASH = 'DASH';
  138. /**
  139. * @const {string}
  140. */
  141. shaka.media.ManifestParser.MSS = 'MSS';
  142. /**
  143. * @const {string}
  144. */
  145. shaka.media.ManifestParser.UNKNOWN = 'UNKNOWN';
  146. /**
  147. * @enum {string}
  148. * @export
  149. */
  150. shaka.media.ManifestParser.AccessibilityPurpose = {
  151. VISUALLY_IMPAIRED: 'visually impaired',
  152. HARD_OF_HEARING: 'hard of hearing',
  153. };
  154. /**
  155. * Contains the parser factory functions indexed by MIME type.
  156. *
  157. * @type {!Map<string, shaka.extern.ManifestParser.Factory>}
  158. */
  159. shaka.media.ManifestParser.parsersByMime = new Map();