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',
  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[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. delete shaka.media.ManifestParser.parsersByMime[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 in ManifestParser.parsersByMime) {
  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[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[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. }
  112. /**
  113. * Determines whether or not the MIME type is supported by our own
  114. * manifest parsers on this platform. This takes into account whether or not
  115. * MediaSource is available, as well as which parsers are registered to the
  116. * system.
  117. *
  118. * @param {string} mimeType
  119. * @return {boolean}
  120. */
  121. static isSupported(mimeType) {
  122. // Without MediaSource, our own parsers are useless.
  123. if (!shaka.util.Platform.supportsMediaSource()) {
  124. return false;
  125. }
  126. if (mimeType in shaka.media.ManifestParser.parsersByMime) {
  127. return true;
  128. }
  129. return false;
  130. }
  131. };
  132. /**
  133. * @const {string}
  134. */
  135. shaka.media.ManifestParser.HLS = 'HLS';
  136. /**
  137. * @const {string}
  138. */
  139. shaka.media.ManifestParser.DASH = 'DASH';
  140. /**
  141. * @const {string}
  142. */
  143. shaka.media.ManifestParser.MSS = 'MSS';
  144. /**
  145. * @const {string}
  146. */
  147. shaka.media.ManifestParser.UNKNOWN = 'UNKNOWN';
  148. /**
  149. * @enum {string}
  150. * @export
  151. */
  152. shaka.media.ManifestParser.AccessibilityPurpose = {
  153. VISUALLY_IMPAIRED: 'visually impaired',
  154. HARD_OF_HEARING: 'hard of hearing',
  155. };
  156. /**
  157. * Contains the parser factory functions indexed by MIME type.
  158. *
  159. * @type {!Object.<string, shaka.extern.ManifestParser.Factory>}
  160. */
  161. shaka.media.ManifestParser.parsersByMime = {};