containers.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.isLikelyFmp4MediaSegment = exports.detectContainerForBytes = exports.isLikely = void 0;
  6. var _byteHelpers = require("./byte-helpers.js");
  7. var _mp4Helpers = require("./mp4-helpers.js");
  8. var _ebmlHelpers = require("./ebml-helpers.js");
  9. var _id3Helpers = require("./id3-helpers.js");
  10. var _nalHelpers = require("./nal-helpers.js");
  11. var CONSTANTS = {
  12. // "webm" string literal in hex
  13. 'webm': (0, _byteHelpers.toUint8)([0x77, 0x65, 0x62, 0x6d]),
  14. // "matroska" string literal in hex
  15. 'matroska': (0, _byteHelpers.toUint8)([0x6d, 0x61, 0x74, 0x72, 0x6f, 0x73, 0x6b, 0x61]),
  16. // "fLaC" string literal in hex
  17. 'flac': (0, _byteHelpers.toUint8)([0x66, 0x4c, 0x61, 0x43]),
  18. // "OggS" string literal in hex
  19. 'ogg': (0, _byteHelpers.toUint8)([0x4f, 0x67, 0x67, 0x53]),
  20. // ac-3 sync byte, also works for ec-3 as that is simply a codec
  21. // of ac-3
  22. 'ac3': (0, _byteHelpers.toUint8)([0x0b, 0x77]),
  23. // "RIFF" string literal in hex used for wav and avi
  24. 'riff': (0, _byteHelpers.toUint8)([0x52, 0x49, 0x46, 0x46]),
  25. // "AVI" string literal in hex
  26. 'avi': (0, _byteHelpers.toUint8)([0x41, 0x56, 0x49]),
  27. // "WAVE" string literal in hex
  28. 'wav': (0, _byteHelpers.toUint8)([0x57, 0x41, 0x56, 0x45]),
  29. // "ftyp3g" string literal in hex
  30. '3gp': (0, _byteHelpers.toUint8)([0x66, 0x74, 0x79, 0x70, 0x33, 0x67]),
  31. // "ftyp" string literal in hex
  32. 'mp4': (0, _byteHelpers.toUint8)([0x66, 0x74, 0x79, 0x70]),
  33. // "styp" string literal in hex
  34. 'fmp4': (0, _byteHelpers.toUint8)([0x73, 0x74, 0x79, 0x70]),
  35. // "ftypqt" string literal in hex
  36. 'mov': (0, _byteHelpers.toUint8)([0x66, 0x74, 0x79, 0x70, 0x71, 0x74]),
  37. // moov string literal in hex
  38. 'moov': (0, _byteHelpers.toUint8)([0x6D, 0x6F, 0x6F, 0x76]),
  39. // moof string literal in hex
  40. 'moof': (0, _byteHelpers.toUint8)([0x6D, 0x6F, 0x6F, 0x66])
  41. };
  42. var _isLikely = {
  43. aac: function aac(bytes) {
  44. var offset = (0, _id3Helpers.getId3Offset)(bytes);
  45. return (0, _byteHelpers.bytesMatch)(bytes, [0xFF, 0x10], {
  46. offset: offset,
  47. mask: [0xFF, 0x16]
  48. });
  49. },
  50. mp3: function mp3(bytes) {
  51. var offset = (0, _id3Helpers.getId3Offset)(bytes);
  52. return (0, _byteHelpers.bytesMatch)(bytes, [0xFF, 0x02], {
  53. offset: offset,
  54. mask: [0xFF, 0x06]
  55. });
  56. },
  57. webm: function webm(bytes) {
  58. var docType = (0, _ebmlHelpers.findEbml)(bytes, [_ebmlHelpers.EBML_TAGS.EBML, _ebmlHelpers.EBML_TAGS.DocType])[0]; // check if DocType EBML tag is webm
  59. return (0, _byteHelpers.bytesMatch)(docType, CONSTANTS.webm);
  60. },
  61. mkv: function mkv(bytes) {
  62. var docType = (0, _ebmlHelpers.findEbml)(bytes, [_ebmlHelpers.EBML_TAGS.EBML, _ebmlHelpers.EBML_TAGS.DocType])[0]; // check if DocType EBML tag is matroska
  63. return (0, _byteHelpers.bytesMatch)(docType, CONSTANTS.matroska);
  64. },
  65. mp4: function mp4(bytes) {
  66. // if this file is another base media file format, it is not mp4
  67. if (_isLikely['3gp'](bytes) || _isLikely.mov(bytes)) {
  68. return false;
  69. } // if this file starts with a ftyp or styp box its mp4
  70. if ((0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.mp4, {
  71. offset: 4
  72. }) || (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.fmp4, {
  73. offset: 4
  74. })) {
  75. return true;
  76. } // if this file starts with a moof/moov box its mp4
  77. if ((0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.moof, {
  78. offset: 4
  79. }) || (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.moov, {
  80. offset: 4
  81. })) {
  82. return true;
  83. }
  84. },
  85. mov: function mov(bytes) {
  86. return (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.mov, {
  87. offset: 4
  88. });
  89. },
  90. '3gp': function gp(bytes) {
  91. return (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS['3gp'], {
  92. offset: 4
  93. });
  94. },
  95. ac3: function ac3(bytes) {
  96. var offset = (0, _id3Helpers.getId3Offset)(bytes);
  97. return (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.ac3, {
  98. offset: offset
  99. });
  100. },
  101. ts: function ts(bytes) {
  102. if (bytes.length < 189 && bytes.length >= 1) {
  103. return bytes[0] === 0x47;
  104. }
  105. var i = 0; // check the first 376 bytes for two matching sync bytes
  106. while (i + 188 < bytes.length && i < 188) {
  107. if (bytes[i] === 0x47 && bytes[i + 188] === 0x47) {
  108. return true;
  109. }
  110. i += 1;
  111. }
  112. return false;
  113. },
  114. flac: function flac(bytes) {
  115. var offset = (0, _id3Helpers.getId3Offset)(bytes);
  116. return (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.flac, {
  117. offset: offset
  118. });
  119. },
  120. ogg: function ogg(bytes) {
  121. return (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.ogg);
  122. },
  123. avi: function avi(bytes) {
  124. return (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.riff) && (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.avi, {
  125. offset: 8
  126. });
  127. },
  128. wav: function wav(bytes) {
  129. return (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.riff) && (0, _byteHelpers.bytesMatch)(bytes, CONSTANTS.wav, {
  130. offset: 8
  131. });
  132. },
  133. 'h264': function h264(bytes) {
  134. // find seq_parameter_set_rbsp
  135. return (0, _nalHelpers.findH264Nal)(bytes, 7, 3).length;
  136. },
  137. 'h265': function h265(bytes) {
  138. // find video_parameter_set_rbsp or seq_parameter_set_rbsp
  139. return (0, _nalHelpers.findH265Nal)(bytes, [32, 33], 3).length;
  140. }
  141. }; // get all the isLikely functions
  142. // but make sure 'ts' is above h264 and h265
  143. // but below everything else as it is the least specific
  144. var isLikelyTypes = Object.keys(_isLikely) // remove ts, h264, h265
  145. .filter(function (t) {
  146. return t !== 'ts' && t !== 'h264' && t !== 'h265';
  147. }) // add it back to the bottom
  148. .concat(['ts', 'h264', 'h265']); // make sure we are dealing with uint8 data.
  149. isLikelyTypes.forEach(function (type) {
  150. var isLikelyFn = _isLikely[type];
  151. _isLikely[type] = function (bytes) {
  152. return isLikelyFn((0, _byteHelpers.toUint8)(bytes));
  153. };
  154. }); // export after wrapping
  155. var isLikely = _isLikely; // A useful list of file signatures can be found here
  156. // https://en.wikipedia.org/wiki/List_of_file_signatures
  157. exports.isLikely = isLikely;
  158. var detectContainerForBytes = function detectContainerForBytes(bytes) {
  159. bytes = (0, _byteHelpers.toUint8)(bytes);
  160. for (var i = 0; i < isLikelyTypes.length; i++) {
  161. var type = isLikelyTypes[i];
  162. if (isLikely[type](bytes)) {
  163. return type;
  164. }
  165. }
  166. return '';
  167. }; // fmp4 is not a container
  168. exports.detectContainerForBytes = detectContainerForBytes;
  169. var isLikelyFmp4MediaSegment = function isLikelyFmp4MediaSegment(bytes) {
  170. return (0, _mp4Helpers.findBox)(bytes, ['moof']).length > 0;
  171. };
  172. exports.isLikelyFmp4MediaSegment = isLikelyFmp4MediaSegment;