Source: lib/util/mime_utils.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.util.MimeUtils');
  7. goog.require('shaka.dependencies');
  8. goog.require('shaka.media.Transmuxer');
  9. /**
  10. * @summary A set of utility functions for dealing with MIME types.
  11. */
  12. shaka.util.MimeUtils = class {
  13. /**
  14. * Takes a MIME type and optional codecs string and produces the full MIME
  15. * type.
  16. *
  17. * @param {string} mimeType
  18. * @param {string=} codecs
  19. * @return {string}
  20. */
  21. static getFullType(mimeType, codecs) {
  22. let fullMimeType = mimeType;
  23. if (codecs) {
  24. fullMimeType += '; codecs="' + codecs + '"';
  25. }
  26. return fullMimeType;
  27. }
  28. /**
  29. * Takes a MIME type and a codecs string and produces the full MIME
  30. * type. If it's a transport stream, convert its codecs to MP4 codecs.
  31. *
  32. * @param {string} mimeType
  33. * @param {string} codecs
  34. * @param {string} contentType
  35. * @return {string}
  36. */
  37. static getFullOrConvertedType(mimeType, codecs, contentType) {
  38. const fullMimeType = shaka.util.MimeUtils.getFullType(mimeType, codecs);
  39. if (!shaka.dependencies.muxjs() ||
  40. !shaka.media.Transmuxer.isTsContainer(fullMimeType)) {
  41. return fullMimeType;
  42. }
  43. return shaka.media.Transmuxer.convertTsCodecs(contentType, fullMimeType);
  44. }
  45. /**
  46. * Takes a Stream object and produces an extended MIME type with information
  47. * beyond the container and codec type, when available.
  48. *
  49. * @param {shaka.extern.Stream} stream
  50. * @return {string}
  51. */
  52. static getExtendedType(stream) {
  53. const components = [stream.mimeType];
  54. const extendedMimeParams = shaka.util.MimeUtils.EXTENDED_MIME_PARAMETERS_;
  55. extendedMimeParams.forEach((mimeKey, streamKey) => {
  56. const value = stream[streamKey];
  57. if (value) {
  58. components.push(mimeKey + '="' + value + '"');
  59. }
  60. });
  61. if (stream.hdr == 'PQ') {
  62. components.push('eotf="smpte2084"');
  63. }
  64. return components.join(';');
  65. }
  66. /**
  67. * Takes a full MIME type (with codecs) or basic MIME type (without codecs)
  68. * and returns a container type string ("mp2t", "mp4", "webm", etc.)
  69. *
  70. * @param {string} mimeType
  71. * @return {string}
  72. */
  73. static getContainerType(mimeType) {
  74. return mimeType.split(';')[0].split('/')[1];
  75. }
  76. /**
  77. * Split a list of codecs encoded in a string into a list of codecs.
  78. * @param {string} codecs
  79. * @return {!Array.<string>}
  80. */
  81. static splitCodecs(codecs) {
  82. return codecs.split(',');
  83. }
  84. /**
  85. * Get the base codec from a codec string.
  86. *
  87. * @param {string} codecString
  88. * @return {string}
  89. */
  90. static getCodecBase(codecString) {
  91. const parts = shaka.util.MimeUtils.getCodecParts_(codecString);
  92. return parts[0];
  93. }
  94. /**
  95. * Get the base and profile of a codec string. Where [0] will be the codec
  96. * base and [1] will be the profile.
  97. * @param {string} codecString
  98. * @return {!Array.<string>}
  99. * @private
  100. */
  101. static getCodecParts_(codecString) {
  102. const parts = codecString.split('.');
  103. const base = parts[0];
  104. parts.pop();
  105. const profile = parts.join('.');
  106. // Make sure that we always return a "base" and "profile".
  107. return [base, profile];
  108. }
  109. };
  110. /**
  111. * A map from Stream object keys to MIME type parameters. These should be
  112. * ignored by platforms that do not recognize them.
  113. *
  114. * This initial set of parameters are all recognized by Chromecast.
  115. *
  116. * @const {!Map.<string, string>}
  117. * @private
  118. */
  119. shaka.util.MimeUtils.EXTENDED_MIME_PARAMETERS_ = new Map()
  120. .set('codecs', 'codecs')
  121. .set('frameRate', 'framerate') // Ours is camelCase, theirs is lowercase.
  122. .set('bandwidth', 'bitrate') // They are in the same units: bits/sec.
  123. .set('width', 'width')
  124. .set('height', 'height')
  125. .set('channelsCount', 'channels');
  126. /**
  127. * A mimetype created for CEA-608 closed captions.
  128. * @const {string}
  129. */
  130. shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE = 'application/cea-608';
  131. /**
  132. * A mimetype created for CEA-708 closed captions.
  133. * @const {string}
  134. */
  135. shaka.util.MimeUtils.CEA708_CLOSED_CAPTION_MIMETYPE = 'application/cea-708';