index.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /**
  2. * mux.js
  3. *
  4. * Copyright (c) Brightcove
  5. * Licensed Apache-2.0 https://github.com/videojs/mux.js/blob/master/LICENSE
  6. *
  7. * A stream-based aac to mp4 converter. This utility can be used to
  8. * deliver mp4s to a SourceBuffer on platforms that support native
  9. * Media Source Extensions.
  10. */
  11. 'use strict';
  12. var Stream = require('../utils/stream.js');
  13. var aacUtils = require('./utils');
  14. // Constants
  15. var AacStream;
  16. /**
  17. * Splits an incoming stream of binary data into ADTS and ID3 Frames.
  18. */
  19. AacStream = function() {
  20. var
  21. everything = new Uint8Array(),
  22. timeStamp = 0;
  23. AacStream.prototype.init.call(this);
  24. this.setTimestamp = function(timestamp) {
  25. timeStamp = timestamp;
  26. };
  27. this.push = function(bytes) {
  28. var
  29. frameSize = 0,
  30. byteIndex = 0,
  31. bytesLeft,
  32. chunk,
  33. packet,
  34. tempLength;
  35. // If there are bytes remaining from the last segment, prepend them to the
  36. // bytes that were pushed in
  37. if (everything.length) {
  38. tempLength = everything.length;
  39. everything = new Uint8Array(bytes.byteLength + tempLength);
  40. everything.set(everything.subarray(0, tempLength));
  41. everything.set(bytes, tempLength);
  42. } else {
  43. everything = bytes;
  44. }
  45. while (everything.length - byteIndex >= 3) {
  46. if ((everything[byteIndex] === 'I'.charCodeAt(0)) &&
  47. (everything[byteIndex + 1] === 'D'.charCodeAt(0)) &&
  48. (everything[byteIndex + 2] === '3'.charCodeAt(0))) {
  49. // Exit early because we don't have enough to parse
  50. // the ID3 tag header
  51. if (everything.length - byteIndex < 10) {
  52. break;
  53. }
  54. // check framesize
  55. frameSize = aacUtils.parseId3TagSize(everything, byteIndex);
  56. // Exit early if we don't have enough in the buffer
  57. // to emit a full packet
  58. // Add to byteIndex to support multiple ID3 tags in sequence
  59. if (byteIndex + frameSize > everything.length) {
  60. break;
  61. }
  62. chunk = {
  63. type: 'timed-metadata',
  64. data: everything.subarray(byteIndex, byteIndex + frameSize)
  65. };
  66. this.trigger('data', chunk);
  67. byteIndex += frameSize;
  68. continue;
  69. } else if (((everything[byteIndex] & 0xff) === 0xff) &&
  70. ((everything[byteIndex + 1] & 0xf0) === 0xf0)) {
  71. // Exit early because we don't have enough to parse
  72. // the ADTS frame header
  73. if (everything.length - byteIndex < 7) {
  74. break;
  75. }
  76. frameSize = aacUtils.parseAdtsSize(everything, byteIndex);
  77. // Exit early if we don't have enough in the buffer
  78. // to emit a full packet
  79. if (byteIndex + frameSize > everything.length) {
  80. break;
  81. }
  82. packet = {
  83. type: 'audio',
  84. data: everything.subarray(byteIndex, byteIndex + frameSize),
  85. pts: timeStamp,
  86. dts: timeStamp
  87. };
  88. this.trigger('data', packet);
  89. byteIndex += frameSize;
  90. continue;
  91. }
  92. byteIndex++;
  93. }
  94. bytesLeft = everything.length - byteIndex;
  95. if (bytesLeft > 0) {
  96. everything = everything.subarray(byteIndex);
  97. } else {
  98. everything = new Uint8Array();
  99. }
  100. };
  101. this.reset = function() {
  102. everything = new Uint8Array();
  103. this.trigger('reset');
  104. };
  105. this.endTimeline = function() {
  106. everything = new Uint8Array();
  107. this.trigger('endedtimeline');
  108. };
  109. };
  110. AacStream.prototype = new Stream();
  111. module.exports = AacStream;