MP4Remux.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. let _dtsBase;
  2. let _types = [];
  3. let datas = {};
  4. _types = {
  5. avc1: [], avcC: [], btrt: [], dinf: [],
  6. dref: [], esds: [], ftyp: [], hdlr: [],
  7. mdat: [], mdhd: [], mdia: [], mfhd: [],
  8. minf: [], moof: [], moov: [], mp4a: [],
  9. mvex: [], mvhd: [], sdtp: [], stbl: [],
  10. stco: [], stsc: [], stsd: [], stsz: [],
  11. stts: [], tfdt: [], tfhd: [], traf: [],
  12. trak: [], trun: [], trex: [], tkhd: [],
  13. vmhd: [], smhd: []
  14. };
  15. class MP4Remux {
  16. constructor() {
  17. }
  18. init() {
  19. for (let name in _types) {
  20. _types[name] = [
  21. name.charCodeAt(0),
  22. name.charCodeAt(1),
  23. name.charCodeAt(2),
  24. name.charCodeAt(3)
  25. ];
  26. }
  27. _dtsBase = 0;
  28. datas.FTYP = new Uint8Array([
  29. 0x69, 0x73, 0x6F, 0x6D, // major_brand: isom
  30. 0x0, 0x0, 0x0, 0x1, // minor_version: 0x01
  31. 0x69, 0x73, 0x6F, 0x6D, // isom
  32. 0x61, 0x76, 0x63, 0x31 // avc1
  33. ]);
  34. datas.STSD_PREFIX = new Uint8Array([
  35. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  36. 0x00, 0x00, 0x00, 0x01 // entry_count
  37. ]);
  38. datas.STTS = new Uint8Array([
  39. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  40. 0x00, 0x00, 0x00, 0x00 // entry_count
  41. ]);
  42. datas.STSC = datas.STCO = datas.STTS;
  43. datas.STSZ = new Uint8Array([
  44. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  45. 0x00, 0x00, 0x00, 0x00, // sample_size
  46. 0x00, 0x00, 0x00, 0x00 // sample_count
  47. ]);
  48. datas.HDLR_VIDEO = new Uint8Array([
  49. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  50. 0x00, 0x00, 0x00, 0x00, // pre_defined
  51. 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'
  52. 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes
  53. 0x00, 0x00, 0x00, 0x00,
  54. 0x00, 0x00, 0x00, 0x00,
  55. 0x56, 0x69, 0x64, 0x65,
  56. 0x6F, 0x48, 0x61, 0x6E,
  57. 0x64, 0x6C, 0x65, 0x72, 0x00 // name: VideoHandler
  58. ]);
  59. datas.HDLR_AUDIO = new Uint8Array([
  60. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  61. 0x00, 0x00, 0x00, 0x00, // pre_defined
  62. 0x73, 0x6F, 0x75, 0x6E, // handler_type: 'soun'
  63. 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes
  64. 0x00, 0x00, 0x00, 0x00,
  65. 0x00, 0x00, 0x00, 0x00,
  66. 0x53, 0x6F, 0x75, 0x6E,
  67. 0x64, 0x48, 0x61, 0x6E,
  68. 0x64, 0x6C, 0x65, 0x72, 0x00 // name: SoundHandler
  69. ]);
  70. datas.DREF = new Uint8Array([
  71. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  72. 0x00, 0x00, 0x00, 0x01, // entry_count
  73. 0x00, 0x00, 0x00, 0x0C, // entry_size
  74. 0x75, 0x72, 0x6C, 0x20, // type 'url '
  75. 0x00, 0x00, 0x00, 0x01 // version(0) + flags
  76. ]);
  77. // Sound media header
  78. datas.SMHD = new Uint8Array([
  79. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  80. 0x00, 0x00, 0x00, 0x00 // balance(2) + reserved(2)
  81. ]);
  82. // video media header
  83. datas.VMHD = new Uint8Array([
  84. 0x00, 0x00, 0x00, 0x01, // version(0) + flags
  85. 0x00, 0x00, // graphicsmode: 2 bytes
  86. 0x00, 0x00, 0x00, 0x00, // opcolor: 3 * 2 bytes
  87. 0x00, 0x00
  88. ]);
  89. }
  90. initSegment(meta) {
  91. let ftyp = box(_types.ftyp, datas.FTYP);
  92. let moov = Moov(meta);
  93. let seg = new Uint8Array(ftyp.byteLength + moov.byteLength);
  94. seg.set(ftyp, 0);
  95. seg.set(moov, ftyp.byteLength);
  96. return seg;
  97. }
  98. mediaSegment(sequenceNumber, track, data) {
  99. let moof = Moof(sequenceNumber, track);
  100. let frameData = mdat(data);
  101. let seg = new Uint8Array(moof.byteLength + frameData.byteLength);
  102. seg.set(moof, 0);
  103. seg.set(frameData, moof.byteLength);
  104. return seg
  105. }
  106. }
  107. //组装initSegment
  108. function Moov(meta) {
  109. let mvhd = Mvhd(meta.timescale, meta.duration);
  110. let trak = Trak(meta);
  111. let mvex = Mvex(meta);
  112. return box(_types.moov, mvhd, trak, mvex);
  113. }
  114. //组装moov
  115. function Mvhd(timescale, duration) {
  116. return box(_types.mvhd, new Uint8Array([
  117. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  118. 0x00, 0x00, 0x00, 0x00, // creation_time
  119. 0x00, 0x00, 0x00, 0x00, // modification_time
  120. (timescale >>> 24) & 0xFF, // timescale: 4 bytes
  121. (timescale >>> 16) & 0xFF,
  122. (timescale >>> 8) & 0xFF,
  123. (timescale) & 0xFF,
  124. (duration >>> 24) & 0xFF, // duration: 4 bytes
  125. (duration >>> 16) & 0xFF,
  126. (duration >>> 8) & 0xFF,
  127. (duration) & 0xFF,
  128. 0x00, 0x01, 0x00, 0x00, // Preferred rate: 1.0
  129. 0x01, 0x00, 0x00, 0x00, // PreferredVolume(1.0, 2bytes) + reserved(2bytes)
  130. 0x00, 0x00, 0x00, 0x00, // reserved: 4 + 4 bytes
  131. 0x00, 0x00, 0x00, 0x00,
  132. 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----
  133. 0x00, 0x00, 0x00, 0x00,
  134. 0x00, 0x00, 0x00, 0x00,
  135. 0x00, 0x00, 0x00, 0x00,
  136. 0x00, 0x01, 0x00, 0x00,
  137. 0x00, 0x00, 0x00, 0x00,
  138. 0x00, 0x00, 0x00, 0x00,
  139. 0x00, 0x00, 0x00, 0x00,
  140. 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----
  141. 0x00, 0x00, 0x00, 0x00, // ----begin pre_defined 6 * 4 bytes----
  142. 0x00, 0x00, 0x00, 0x00,
  143. 0x00, 0x00, 0x00, 0x00,
  144. 0x00, 0x00, 0x00, 0x00,
  145. 0x00, 0x00, 0x00, 0x00,
  146. 0x00, 0x00, 0x00, 0x00, // ----end pre_defined 6 * 4 bytes----
  147. 0xFF, 0xFF, 0xFF, 0xFF // next_track_ID
  148. ]));
  149. }
  150. function Trak(meta) {
  151. return box(_types.trak, Tkhd(meta), Mdia(meta));
  152. }
  153. function Mvex(meta) {
  154. return box(_types.mvex, trex(meta));
  155. }
  156. //组装trak
  157. function Tkhd(meta) {
  158. let trackId = meta.id;
  159. let duration = meta.duration;
  160. let width = meta.width;
  161. let height = meta.height;
  162. return box(_types.tkhd, new Uint8Array([
  163. 0x00, 0x00, 0x00, 0x07, // version(0) + flags
  164. 0x00, 0x00, 0x00, 0x00, // creation_time
  165. 0x00, 0x00, 0x00, 0x00, // modification_time
  166. (trackId >>> 24) & 0xFF, // track_ID: 4 bytes
  167. (trackId >>> 16) & 0xFF,
  168. (trackId >>> 8) & 0xFF,
  169. (trackId) & 0xFF,
  170. 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes
  171. (duration >>> 24) & 0xFF, // duration: 4 bytes
  172. (duration >>> 16) & 0xFF,
  173. (duration >>> 8) & 0xFF,
  174. (duration) & 0xFF,
  175. 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes
  176. 0x00, 0x00, 0x00, 0x00,
  177. 0x00, 0x00, 0x00, 0x00, // layer(2bytes) + alternate_group(2bytes)
  178. 0x00, 0x00, 0x00, 0x00, // volume(2bytes) + reserved(2bytes)
  179. 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----
  180. 0x00, 0x00, 0x00, 0x00,
  181. 0x00, 0x00, 0x00, 0x00,
  182. 0x00, 0x00, 0x00, 0x00,
  183. 0x00, 0x01, 0x00, 0x00,
  184. 0x00, 0x00, 0x00, 0x00,
  185. 0x00, 0x00, 0x00, 0x00,
  186. 0x00, 0x00, 0x00, 0x00,
  187. 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----
  188. (width >>> 8) & 0xFF, // width and height
  189. (width) & 0xFF,
  190. 0x00, 0x00,
  191. (height >>> 8) & 0xFF,
  192. (height) & 0xFF,
  193. 0x00, 0x00
  194. ]));
  195. }
  196. function Mdia(meta) {
  197. return box(_types.mdia, mdhd(meta), hdlr(meta), minf(meta));
  198. }
  199. //组装mdia
  200. function mdhd(meta) {
  201. let timescale = meta.timescale;
  202. let duration = meta.duration;
  203. return box(_types.mdhd, new Uint8Array([
  204. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  205. 0x00, 0x00, 0x00, 0x00, // creation_time
  206. 0x00, 0x00, 0x00, 0x00, // modification_time
  207. (timescale >>> 24) & 0xFF, // timescale: 4 bytes
  208. (timescale >>> 16) & 0xFF,
  209. (timescale >>> 8) & 0xFF,
  210. (timescale) & 0xFF,
  211. (duration >>> 24) & 0xFF, // duration: 4 bytes
  212. (duration >>> 16) & 0xFF,
  213. (duration >>> 8) & 0xFF,
  214. (duration) & 0xFF,
  215. 0x55, 0xC4, // language: und (undetermined)
  216. 0x00, 0x00 // pre_defined = 0
  217. ]));
  218. }
  219. function hdlr(meta) {
  220. let data = null;
  221. if (meta.type === 'audio') {
  222. data = datas.HDLR_AUDIO;
  223. } else {
  224. data = datas.HDLR_VIDEO;
  225. }
  226. return box(_types.hdlr, data);
  227. }
  228. function minf(meta) {
  229. let xmhd = null;
  230. if (meta.type === 'audio') {
  231. xmhd = box(_types.smhd, datas.SMHD);
  232. } else {
  233. xmhd = box(_types.vmhd, datas.VMHD);
  234. }
  235. return box(_types.minf, xmhd, dinf(), stbl(meta));
  236. }
  237. //组装minf
  238. function dinf() {
  239. return box(_types.dinf, box(_types.dref, datas.DREF));
  240. }
  241. function stbl(meta) {
  242. let result = box(_types.stbl, // type: stbl
  243. stsd(meta), // Sample Description Table
  244. box(_types.stts, datas.STTS), // Time-To-Sample
  245. box(_types.stsc, datas.STSC), // Sample-To-Chunk
  246. box(_types.stsz, datas.STSZ), // Sample size
  247. box(_types.stco, datas.STCO) // Chunk offset
  248. );
  249. return result;
  250. }
  251. //组装stbl
  252. function stsd(meta) {
  253. if (meta.type === 'audio') {
  254. return box(_types.stsd, datas.STSD_PREFIX, mp4a(meta));
  255. } else {
  256. return box(_types.stsd, datas.STSD_PREFIX, avc1(meta));
  257. }
  258. }
  259. //组装stsd
  260. function mp4a(meta) {
  261. let channelCount = meta.channelCount;
  262. let sampleRate = meta.audioSampleRate;
  263. let data = new Uint8Array([
  264. 0x00, 0x00, 0x00, 0x00, // reserved(4)
  265. 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)
  266. 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes
  267. 0x00, 0x00, 0x00, 0x00,
  268. 0x00, channelCount, // channelCount(2)
  269. 0x00, 0x10, // sampleSize(2)
  270. 0x00, 0x00, 0x00, 0x00, // reserved(4)
  271. (sampleRate >>> 8) & 0xFF, // Audio sample rate
  272. (sampleRate) & 0xFF,
  273. 0x00, 0x00
  274. ]);
  275. return box(_types.mp4a, data, esds(meta));
  276. }
  277. function avc1(meta) {
  278. let width = meta.width;
  279. let height = meta.height;
  280. let sps = meta.sps || [], pps = meta.pps || [], sequenceParameterSets = [], pictureParameterSets = [];
  281. for (let i = 0; i < sps.length; i++) {
  282. sequenceParameterSets.push((sps[i].byteLength & 65280) >>> 8);
  283. sequenceParameterSets.push(sps[i].byteLength & 255);
  284. sequenceParameterSets = sequenceParameterSets.concat(Array.prototype.slice.call(sps[i]))
  285. }
  286. for (let i = 0; i < pps.length; i++) {
  287. pictureParameterSets.push((pps[i].byteLength & 65280) >>> 8);
  288. pictureParameterSets.push(pps[i].byteLength & 255);
  289. pictureParameterSets = pictureParameterSets.concat(Array.prototype.slice.call(pps[i]))
  290. }
  291. //Todo: 待测,如果视频有问题,修改这里
  292. // let data = new Uint8Array([
  293. // 0x00, 0x00, 0x00, 0x00, // reserved(4)
  294. // 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)
  295. // 0x00, 0x00, 0x00, 0x00, // pre_defined(2) + reserved(2)
  296. // 0x00, 0x00, 0x00, 0x00, // pre_defined: 3 * 4 bytes
  297. // 0x00, 0x00, 0x00, 0x00,
  298. // 0x00, 0x00, 0x00, 0x00,
  299. // (width >>> 8) & 0xFF, // width: 2 bytes
  300. // (width) & 0xFF,
  301. // (height >>> 8) & 0xFF, // height: 2 bytes
  302. // (height) & 0xFF,
  303. // 0x00, 0x48, 0x00, 0x00, // horizresolution: 4 bytes
  304. // 0x00, 0x48, 0x00, 0x00, // vertresolution: 4 bytes
  305. // 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes
  306. // 0x00, 0x01, // frame_count
  307. // 0x0A, // strlen
  308. // 0x78, 0x71, 0x71, 0x2F, // compressorname: 32 bytes
  309. // 0x66, 0x6C, 0x76, 0x2E,
  310. // 0x6A, 0x73, 0x00, 0x00,
  311. // 0x00, 0x00, 0x00, 0x00,
  312. // 0x00, 0x00, 0x00, 0x00,
  313. // 0x00, 0x00, 0x00, 0x00,
  314. // 0x00, 0x00, 0x00, 0x00,
  315. // 0x00, 0x00, 0x00,
  316. // 0x00, 0x18, // depth
  317. // 0xFF, 0xFF // pre_defined = -1
  318. // ]);
  319. let data = new Uint8Array(
  320. [0, 0, 0, 0,
  321. 0, 0, 0, 1,
  322. 0, 0, 0, 0,
  323. 0, 0, 0, 0,
  324. 0, 0, 0, 0,
  325. 0, 0, 0, 0,
  326. (65280 & width) >> 8,
  327. 255 & width,
  328. (65280 & height) >> 8,
  329. 255 & height,
  330. 0, 72, 0, 0,
  331. 0, 72, 0, 0,
  332. 0, 0, 0, 0,
  333. 0, 1, 19, 0,
  334. 0, 0, 0, 0,
  335. 0, 0, 0, 0,
  336. 0, 0, 0, 0,
  337. 0, 0, 0, 0,
  338. 0, 0, 0, 0,
  339. 0, 0, 0, 0,
  340. 0, 0, 0, 0,
  341. 0, 0, 0, 24, 17, 17]);
  342. return box(_types.avc1, data, box(_types.avcC, new Uint8Array([1, meta.profileIdc, meta.profileCompatibility, meta.levelIdc, 255].concat([sps.length]).concat(sequenceParameterSets).concat([pps.length]).concat(pictureParameterSets))));
  343. }
  344. //组装mp4a
  345. function esds(meta) {
  346. let config = meta.config;
  347. let configSize = config.length;
  348. let data = new Uint8Array([
  349. 0x00, 0x00, 0x00, 0x00, // version 0 + flags
  350. 0x03, // descriptor_type
  351. 0x17 + configSize, // length3
  352. 0x00, 0x01, // es_id
  353. 0x00, // stream_priority
  354. 0x04, // descriptor_type
  355. 0x0F + configSize, // length
  356. 0x40, // codec: mpeg4_audio
  357. 0x15, // stream_type: Audio
  358. 0x00, 0x00, 0x00, // buffer_size
  359. 0x00, 0x00, 0x00, 0x00, // maxBitrate
  360. 0x00, 0x00, 0x00, 0x00, // avgBitrate
  361. 0x05 // descriptor_type
  362. ].concat(
  363. [configSize]
  364. ).concat(
  365. config
  366. ).concat(
  367. [0x06, 0x01, 0x02] // GASpecificConfig
  368. ));
  369. return box(_types.esds, data);
  370. }
  371. //组装mvex
  372. function trex(meta) {
  373. var trackId = meta.id;
  374. var data = new Uint8Array([
  375. 0x00, 0x00, 0x00, 0x00, // version(0) + flags
  376. (trackId >>> 24) & 0xFF, // track_ID
  377. (trackId >>> 16) & 0xFF,
  378. (trackId >>> 8) & 0xFF,
  379. (trackId) & 0xFF,
  380. 0x00, 0x00, 0x00, 0x01, // default_sample_description_index
  381. 0x00, 0x00, 0x00, 0x00, // default_sample_duration
  382. 0x00, 0x00, 0x00, 0x00, // default_sample_size
  383. 0x00, 0x01, 0x00, 0x01 // default_sample_flags
  384. ]);
  385. return box(_types.trex, data);
  386. }
  387. //组装mediaSegment
  388. function Moof(sequenceNumber, track) {
  389. return box(_types.moof, mfhd(sequenceNumber), traf(track));
  390. }
  391. function mdat(data) {
  392. return box(_types.mdat, data);
  393. }
  394. //组装moof
  395. function mfhd(sequenceNumber) {
  396. var data = new Uint8Array([
  397. 0x00, 0x00, 0x00, 0x00,
  398. (sequenceNumber >>> 24) & 0xFF, // sequence_number: int32
  399. (sequenceNumber >>> 16) & 0xFF,
  400. (sequenceNumber >>> 8) & 0xFF,
  401. (sequenceNumber) & 0xFF
  402. ]);
  403. return box(_types.mfhd, data);
  404. }
  405. function traf(track) {
  406. //console.log(track)
  407. var trackFragmentHeader = null, trackFragmentDecodeTime = null, trackFragmentRun = null, dataOffset = null;
  408. trackFragmentHeader = box(_types.tfhd, new Uint8Array([0, 2, 0, 0, 0, 0, 0, 1]));
  409. trackFragmentDecodeTime = box(_types.tfdt,
  410. new Uint8Array([
  411. 0, 0, 0, 0,
  412. track.baseMediaDecodeTime >>> 24 & 255,
  413. track.baseMediaDecodeTime >>> 16 & 255,
  414. track.baseMediaDecodeTime >>> 8 & 255,
  415. track.baseMediaDecodeTime & 255
  416. ]));
  417. dataOffset = 16 + 16 + 8 + 16 + 8 + 8;
  418. trackFragmentRun = trun(track, dataOffset);
  419. return box(_types.traf, trackFragmentHeader, trackFragmentDecodeTime, trackFragmentRun)
  420. }
  421. //组装traf
  422. function trun(track, offset) {
  423. if (track.type === "audio") {
  424. return audioTrun(track, offset)
  425. }
  426. return videoTrun(track, offset)
  427. }
  428. //组装trun
  429. function videoTrun(track, _offset) {
  430. var bytes = null, samples = null, sample = null, i = 0;
  431. var offset = _offset;
  432. samples = track.samples || [];
  433. if (samples[0].frameDuration === null) {
  434. offset += 8 + 12 + 4 + 4 * samples.length;
  435. bytes = trunHeader(samples, offset);
  436. for (i = 0; i < samples.length; i++) {
  437. sample = samples[i];
  438. bytes = bytes.concat([(sample.size & 4278190080) >>> 24, (sample.size & 16711680) >>> 16, (sample.size & 65280) >>> 8, sample.size & 255])
  439. }
  440. } else {
  441. offset += 8 + 12 + 4 + 4 * samples.length + 4 * samples.length;
  442. bytes = trunHeader1(samples, offset);
  443. for (i = 0; i < samples.length; i++) {
  444. sample = samples[i];
  445. bytes = bytes.concat([(sample.frameDuration & 4278190080) >>> 24, (sample.frameDuration & 16711680) >>> 16, (sample.frameDuration & 65280) >>> 8, sample.frameDuration & 255, (sample.size & 4278190080) >>> 24, (sample.size & 16711680) >>> 16, (sample.size & 65280) >>> 8, sample.size & 255])
  446. }
  447. }
  448. return box(_types.trun, new Uint8Array(bytes))
  449. }
  450. function audioTrun(track, _offset) {
  451. var bytes = null, samples = null, sample = null, i = 0;
  452. var offset = _offset;
  453. samples = track.samples || [];
  454. offset += 8 + 12 + 8 * samples.length;
  455. bytes = trunHeader(samples, offset);
  456. for (i = 0; i < samples.length; i++) {
  457. sample = samples[i];
  458. bytes = bytes.concat([(sample.duration & 4278190080) >>> 24, (sample.duration & 16711680) >>> 16, (sample.duration & 65280) >>> 8, sample.duration & 255, (sample.size & 4278190080) >>> 24, (sample.size & 16711680) >>> 16, (sample.size & 65280) >>> 8, sample.size & 255])
  459. }
  460. return box(_types.trun, new Uint8Array(bytes))
  461. }
  462. //组装videoTurn
  463. function trunHeader(samples, offset) {
  464. return [0, 0, 2, 5, (samples.length & 4278190080) >>> 24, (samples.length & 16711680) >>> 16, (samples.length & 65280) >>> 8, samples.length & 255, (offset & 4278190080) >>> 24, (offset & 16711680) >>> 16, (offset & 65280) >>> 8, offset & 255, 0, 0, 0, 0]
  465. }
  466. function trunHeader1(samples, offset) {
  467. return [0, 0, 3, 5, (samples.length & 4278190080) >>> 24, (samples.length & 16711680) >>> 16, (samples.length & 65280) >>> 8, samples.length & 255, (offset & 4278190080) >>> 24, (offset & 16711680) >>> 16, (offset & 65280) >>> 8, offset & 255, 0, 0, 0, 0]
  468. }
  469. /**
  470. *
  471. * @param type
  472. * @returns {Uint8Array}
  473. */
  474. function box(type, ...items) {
  475. let size = 8;
  476. //Todo: 测试一下这里
  477. //let arrs = Array.prototype.slice.call(arguments, 1);
  478. let arrs = [];
  479. arrs.push(...items);
  480. for (let i = 0; i < arrs.length; i++) {
  481. size += arrs[i].byteLength;
  482. }
  483. let data = new Uint8Array(size);
  484. let pos = 0;
  485. // set size
  486. data[pos++] = size >>> 24 & 0xFF;
  487. data[pos++] = size >>> 16 & 0xFF;
  488. data[pos++] = size >>> 8 & 0xFF;
  489. data[pos++] = size & 0xFF;
  490. // set type
  491. data.set(type, pos);
  492. pos += 4;
  493. // set data
  494. for (let i = 0; i < arrs.length; i++) {
  495. data.set(arrs[i], pos);
  496. pos += arrs[i].byteLength;
  497. }
  498. return data;
  499. }
  500. // let mp4Remux = new MP4Remux();
  501. // mp4Remux.init();
  502. export default MP4Remux;