Source: lib/text/mp4_ttml_parser.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.text.Mp4TtmlParser');
  7. goog.require('shaka.text.TextEngine');
  8. goog.require('shaka.text.TtmlTextParser');
  9. goog.require('shaka.util.Error');
  10. goog.require('shaka.util.Mp4Parser');
  11. /**
  12. * @implements {shaka.extern.TextParser}
  13. * @export
  14. */
  15. shaka.text.Mp4TtmlParser = class {
  16. /** */
  17. constructor() {
  18. /**
  19. * @type {!shaka.extern.TextParser}
  20. * @private
  21. */
  22. this.parser_ = new shaka.text.TtmlTextParser();
  23. }
  24. /**
  25. * @override
  26. * @export
  27. */
  28. parseInit(data) {
  29. const Mp4Parser = shaka.util.Mp4Parser;
  30. let sawSTPP = false;
  31. new Mp4Parser()
  32. .box('moov', Mp4Parser.children)
  33. .box('trak', Mp4Parser.children)
  34. .box('mdia', Mp4Parser.children)
  35. .box('minf', Mp4Parser.children)
  36. .box('stbl', Mp4Parser.children)
  37. .fullBox('stsd', Mp4Parser.sampleDescription)
  38. .box('stpp', (box) => {
  39. sawSTPP = true;
  40. box.parser.stop();
  41. }).parse(data);
  42. if (!sawSTPP) {
  43. throw new shaka.util.Error(
  44. shaka.util.Error.Severity.CRITICAL,
  45. shaka.util.Error.Category.TEXT,
  46. shaka.util.Error.Code.INVALID_MP4_TTML);
  47. }
  48. }
  49. /**
  50. * @override
  51. * @export
  52. */
  53. setSequenceMode(sequenceMode) {
  54. // Unused.
  55. }
  56. /**
  57. * @override
  58. * @export
  59. */
  60. setManifestType(manifestType) {
  61. // Unused.
  62. }
  63. /**
  64. * @override
  65. * @export
  66. */
  67. parseMedia(data, time, uri) {
  68. const Mp4Parser = shaka.util.Mp4Parser;
  69. let sawMDAT = false;
  70. let payload = [];
  71. const parser = new Mp4Parser()
  72. .box('mdat', Mp4Parser.allData((data) => {
  73. sawMDAT = true;
  74. // Join this to any previous payload, in case the mp4 has multiple
  75. // mdats.
  76. payload = payload.concat(this.parser_.parseMedia(data, time, uri));
  77. }));
  78. parser.parse(data, /* partialOkay= */ false);
  79. if (!sawMDAT) {
  80. throw new shaka.util.Error(
  81. shaka.util.Error.Severity.CRITICAL,
  82. shaka.util.Error.Category.TEXT,
  83. shaka.util.Error.Code.INVALID_MP4_TTML);
  84. }
  85. return payload;
  86. }
  87. };
  88. shaka.text.TextEngine.registerParser(
  89. 'application/mp4; codecs="stpp"', () => new shaka.text.Mp4TtmlParser());
  90. shaka.text.TextEngine.registerParser(
  91. 'application/mp4; codecs="stpp.ttml"',
  92. () => new shaka.text.Mp4TtmlParser());
  93. shaka.text.TextEngine.registerParser(
  94. 'application/mp4; codecs="stpp.ttml.im1t"',
  95. () => new shaka.text.Mp4TtmlParser());
  96. shaka.text.TextEngine.registerParser(
  97. 'application/mp4; codecs="stpp.ttml.im2t"',
  98. () => new shaka.text.Mp4TtmlParser());
  99. shaka.text.TextEngine.registerParser(
  100. 'application/mp4; codecs="stpp.ttml.etd1"',
  101. () => new shaka.text.Mp4TtmlParser());
  102. shaka.text.TextEngine.registerParser(
  103. 'application/mp4; codecs="stpp.ttml.etd1|im1t"',
  104. () => new shaka.text.Mp4TtmlParser());
  105. shaka.text.TextEngine.registerParser(
  106. 'application/mp4; codecs="stpp.ttml.im1t|etd1"',
  107. () => new shaka.text.Mp4TtmlParser());
  108. // Legacy codec string uses capital "TTML", i.e.: prior to HLS rfc8216bis:
  109. // Note that if a Variant Stream specifies one or more Renditions that
  110. // include IMSC subtitles, the CODECS attribute MUST indicate this with a
  111. // format identifier such as "stpp.ttml.im1t".
  112. // (https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-05#section-4.4.5.2)
  113. shaka.text.TextEngine.registerParser(
  114. 'application/mp4; codecs="stpp.TTML.im1t"',
  115. () => new shaka.text.Mp4TtmlParser());