m2ts-helpers.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { bytesMatch, toUint8 } from './byte-helpers.js';
  2. var SYNC_BYTE = 0x47; // use of maxPes is deprecated as we should always look at
  3. // all pes packets to prevent being caught off guard by changes
  4. // in that stream that happen after the pes specified
  5. export var parseTs = function parseTs(bytes, maxPes) {
  6. if (maxPes === void 0) {
  7. maxPes = Infinity;
  8. }
  9. bytes = toUint8(bytes);
  10. var startIndex = 0;
  11. var endIndex = 188;
  12. var pmt = {};
  13. var pesCount = 0;
  14. while (endIndex < bytes.byteLength && pesCount < maxPes) {
  15. if (bytes[startIndex] !== SYNC_BYTE && bytes[endIndex] !== SYNC_BYTE) {
  16. endIndex += 1;
  17. startIndex += 1;
  18. continue;
  19. }
  20. var packet = bytes.subarray(startIndex, endIndex);
  21. var pid = (packet[1] & 0x1f) << 8 | packet[2];
  22. var hasPusi = !!(packet[1] & 0x40);
  23. var hasAdaptationHeader = (packet[3] & 0x30) >>> 4 > 0x01;
  24. var payloadOffset = 4 + (hasAdaptationHeader ? packet[4] + 1 : 0);
  25. if (hasPusi) {
  26. payloadOffset += packet[payloadOffset] + 1;
  27. }
  28. if (pid === 0 && !pmt.pid) {
  29. pmt.pid = (packet[payloadOffset + 10] & 0x1f) << 8 | packet[payloadOffset + 11];
  30. } else if (pmt.pid && pid === pmt.pid) {
  31. var isNotForward = packet[payloadOffset + 5] & 0x01; // ignore forward pmt delarations
  32. if (!isNotForward) {
  33. continue;
  34. }
  35. pmt.streams = pmt.streams || {};
  36. var sectionLength = (packet[payloadOffset + 1] & 0x0f) << 8 | packet[payloadOffset + 2];
  37. var tableEnd = 3 + sectionLength - 4;
  38. var programInfoLength = (packet[payloadOffset + 10] & 0x0f) << 8 | packet[payloadOffset + 11];
  39. var offset = 12 + programInfoLength;
  40. while (offset < tableEnd) {
  41. // add an entry that maps the elementary_pid to the stream_type
  42. var i = payloadOffset + offset;
  43. var type = packet[i];
  44. var esPid = (packet[i + 1] & 0x1F) << 8 | packet[i + 2];
  45. var esLength = (packet[i + 3] & 0x0f) << 8 | packet[i + 4];
  46. var esInfo = packet.subarray(i + 5, i + 5 + esLength);
  47. var stream = pmt.streams[esPid] = {
  48. esInfo: esInfo,
  49. typeNumber: type,
  50. packets: [],
  51. type: '',
  52. codec: ''
  53. };
  54. if (type === 0x06 && bytesMatch(esInfo, [0x4F, 0x70, 0x75, 0x73], {
  55. offset: 2
  56. })) {
  57. stream.type = 'audio';
  58. stream.codec = 'opus';
  59. } else if (type === 0x1B || type === 0x20) {
  60. stream.type = 'video';
  61. stream.codec = 'avc1';
  62. } else if (type === 0x24) {
  63. stream.type = 'video';
  64. stream.codec = 'hev1';
  65. } else if (type === 0x10) {
  66. stream.type = 'video';
  67. stream.codec = 'mp4v.20';
  68. } else if (type === 0x0F) {
  69. stream.type = 'audio';
  70. stream.codec = 'aac';
  71. } else if (type === 0x81) {
  72. stream.type = 'audio';
  73. stream.codec = 'ac-3';
  74. } else if (type === 0x87) {
  75. stream.type = 'audio';
  76. stream.codec = 'ec-3';
  77. } else if (type === 0x03 || type === 0x04) {
  78. stream.type = 'audio';
  79. stream.codec = 'mp3';
  80. }
  81. offset += esLength + 5;
  82. }
  83. } else if (pmt.pid && pmt.streams) {
  84. pmt.streams[pid].packets.push(packet.subarray(payloadOffset));
  85. pesCount++;
  86. }
  87. startIndex += 188;
  88. endIndex += 188;
  89. }
  90. if (!pmt.streams) {
  91. pmt.streams = {};
  92. }
  93. return pmt;
  94. };