Home Reference Source

src/demux/aacdemuxer.js

  1. /**
  2. * AAC demuxer
  3. */
  4. import * as ADTS from './adts';
  5. import { logger } from '../utils/logger';
  6. import ID3 from '../demux/id3';
  7.  
  8. class AACDemuxer {
  9. constructor (observer, remuxer, config) {
  10. this.observer = observer;
  11. this.config = config;
  12. this.remuxer = remuxer;
  13. }
  14.  
  15. resetInitSegment (initSegment, audioCodec, videoCodec, duration) {
  16. this._audioTrack = { container: 'audio/adts', type: 'audio', id: 0, sequenceNumber: 0, isAAC: true, samples: [], len: 0, manifestCodec: audioCodec, duration: duration, inputTimeScale: 90000 };
  17. }
  18.  
  19. resetTimeStamp () {
  20. }
  21.  
  22. static probe (data) {
  23. if (!data) {
  24. return false;
  25. }
  26.  
  27. // Check for the ADTS sync word
  28. // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1
  29. // Layer bits (position 14 and 15) in header should be always 0 for ADTS
  30. // More info https://wiki.multimedia.cx/index.php?title=ADTS
  31. const id3Data = ID3.getID3Data(data, 0) || [];
  32. let offset = id3Data.length;
  33.  
  34. for (let length = data.length; offset < length; offset++) {
  35. if (ADTS.probe(data, offset)) {
  36. logger.log('ADTS sync word found !');
  37. return true;
  38. }
  39. }
  40. return false;
  41. }
  42.  
  43. // feed incoming data to the front of the parsing pipeline
  44. append (data, timeOffset, contiguous, accurateTimeOffset) {
  45. let track = this._audioTrack;
  46. let id3Data = ID3.getID3Data(data, 0) || [];
  47. let timestamp = ID3.getTimeStamp(id3Data);
  48. let pts = Number.isFinite(timestamp) ? timestamp * 90 : timeOffset * 90000;
  49. let frameIndex = 0;
  50. let stamp = pts;
  51. let length = data.length;
  52. let offset = id3Data.length;
  53.  
  54. let id3Samples = [{ pts: stamp, dts: stamp, data: id3Data }];
  55.  
  56. while (offset < length - 1) {
  57. if (ADTS.isHeader(data, offset) && (offset + 5) < length) {
  58. ADTS.initTrackConfig(track, this.observer, data, offset, track.manifestCodec);
  59. let frame = ADTS.appendFrame(track, data, offset, pts, frameIndex);
  60. if (frame) {
  61. offset += frame.length;
  62. stamp = frame.sample.pts;
  63. frameIndex++;
  64. } else {
  65. logger.log('Unable to parse AAC frame');
  66. break;
  67. }
  68. } else if (ID3.isHeader(data, offset)) {
  69. id3Data = ID3.getID3Data(data, offset);
  70. id3Samples.push({ pts: stamp, dts: stamp, data: id3Data });
  71. offset += id3Data.length;
  72. } else {
  73. // nothing found, keep looking
  74. offset++;
  75. }
  76. }
  77.  
  78. this.remuxer.remux(track,
  79. { samples: [] },
  80. { samples: id3Samples, inputTimeScale: 90000 },
  81. { samples: [] },
  82. timeOffset,
  83. contiguous,
  84. accurateTimeOffset);
  85. }
  86.  
  87. destroy () {
  88. }
  89. }
  90.  
  91. export default AACDemuxer;