jmuxer 2.0.2 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -27
- package/dist/jmuxer.js +346 -253
- package/dist/jmuxer.min.js +1 -1
- package/package.json +9 -8
- package/rollup.config.js +2 -1
- package/src/controller/buffer.js +24 -20
- package/src/controller/remux.js +7 -1
- package/src/jmuxer.js +87 -26
- package/src/parsers/aac.js +5 -9
- package/src/parsers/h264.js +31 -3
- package/src/remuxer/aac.js +4 -0
- package/src/remuxer/h264.js +4 -2
- package/src/util/exp-golomb.js +6 -0
- package/test/parser.js +4 -2
package/dist/jmuxer.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("stream")):"function"==typeof define&&define.amd?define(["stream"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).JMuxer=t(e.stream)}(this,(function(e){"use strict";function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function i(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&u(e,t)}function o(e){return(o=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){return(u=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function c(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function l(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?c(e):t}function f(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=o(e);if(t){var i=o(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}function h(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var n=[],r=!0,i=!1,a=void 0;try{for(var s,o=e[Symbol.iterator]();!(r=(s=o.next()).done)&&(n.push(s.value),!t||n.length!==t);r=!0);}catch(e){i=!0,a=e}finally{try{r||null==o.return||o.return()}finally{if(i)throw a}}return n}(e,t)||d(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e,t){if(e){if("string"==typeof e)return y(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?y(e,t):void 0}}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function p(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=d(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,o=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return s=e.done,e},e:function(e){o=!0,a=e},f:function(){try{s||null==n.return||n.return()}finally{if(o)throw a}}}}var v,m;function k(e){if(v){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];v.apply(void 0,[e].concat(n))}}function g(e){if(m){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];m.apply(void 0,[e].concat(n))}}var b=function(){function e(t){n(this,e),this.payload=t,this.nri=(96&this.payload[0])>>5,this.ntype=31&this.payload[0],this.isvcl=1==this.ntype||5==this.ntype,this.stype="",this.isfmb=!1}return i(e,null,[{key:"type",value:function(t){return t.ntype in e.TYPES?e.TYPES[t.ntype]:"UNKNOWN"}},{key:"NDR",get:function(){return 1}},{key:"IDR",get:function(){return 5}},{key:"SEI",get:function(){return 6}},{key:"SPS",get:function(){return 7}},{key:"PPS",get:function(){return 8}},{key:"AUD",get:function(){return 9}},{key:"TYPES",get:function(){var t;return a(t={},e.IDR,"IDR"),a(t,e.SEI,"SEI"),a(t,e.SPS,"SPS"),a(t,e.PPS,"PPS"),a(t,e.NDR,"NDR"),a(t,e.AUD,"AUD"),t}}]),i(e,[{key:"toString",value:function(){return"".concat(e.type(this),": NRI: ").concat(this.getNri())}},{key:"getNri",value:function(){return this.nri}},{key:"type",value:function(){return this.ntype}},{key:"isKeyframe",value:function(){return this.ntype===e.IDR}},{key:"getPayload",value:function(){return this.payload}},{key:"getPayloadSize",value:function(){return this.payload.byteLength}},{key:"getSize",value:function(){return 4+this.getPayloadSize()}},{key:"getData",value:function(){var e=new Uint8Array(this.getSize());return new DataView(e.buffer).setUint32(0,this.getSize()-4),e.set(this.getPayload(),4),e}}]),e}();function S(e,t){var n=new Uint8Array((0|e.byteLength)+(0|t.byteLength));return n.set(e,0),n.set(t,0|e.byteLength),n}var w,x=function(){function e(t){n(this,e),this.data=t,this.index=0,this.bitLength=8*t.byteLength}return i(e,[{key:"skipBits",value:function(e){if(this.bitsAvailable<e)return!1;this.index+=e}},{key:"readBits",value:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this.getBits(e,this.index,t);return n}},{key:"getBits",value:function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(this.bitsAvailable<e)return 0;var r=t%8,i=this.data[t/8|0]&255>>>r,a=8-r;if(a>=e)return n&&(this.index+=e),i>>a-e;n&&(this.index+=a);var s=e-a;return i<<s|this.getBits(s,t+a,n)}},{key:"skipLZ",value:function(){var e;for(e=0;e<this.bitLength-this.index;++e)if(0!==this.getBits(1,this.index+e,!1))return this.index+=e,e;return e}},{key:"skipUEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"skipEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"readUEG",value:function(){var e=this.skipLZ();return this.readBits(e+1)-1}},{key:"readEG",value:function(){var e=this.readUEG();return 1&e?1+e>>>1:-1*(e>>>1)}},{key:"readBoolean",value:function(){return 1===this.readBits(1)}},{key:"readUByte",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return this.readBits(8*e)}},{key:"readUShort",value:function(){return this.readBits(16)}},{key:"readUInt",value:function(){return this.readBits(32)}},{key:"bitsAvailable",get:function(){return this.bitLength-this.index}}]),e}(),U=function(){function e(t){n(this,e),this.remuxer=t,this.track=t.mp4track}return i(e,null,[{key:"extractNALu",value:function(e){for(var t,n,r=0,i=e.byteLength,a=0,s=[],o=0;r<i;)switch(t=e[r++],a){case 0:0===t&&(a=1);break;case 1:a=0===t?2:0;break;case 2:case 3:0===t?a=3:1===t&&r<i?(o!=r-a-1&&s.push(e.subarray(o,r-a-1)),o=r,a=0):a=0}return o<i&&(n=e.subarray(o,i)),[s,n]}},{key:"skipScalingList",value:function(e,t){for(var n=8,r=8,i=0;i<t;i++)0!==r&&(r=(n+e.readEG()+256)%256),n=0===r?n:r}},{key:"readSPS",value:function(t){var n,r,i,a,s,o,u=new x(t),c=0,l=0,f=0,h=0,d=1;if(u.readUByte(),n=u.readUByte(),u.readBits(5),u.skipBits(3),u.readUByte(),u.skipUEG(),100===n||110===n||122===n||244===n||44===n||83===n||86===n||118===n||128===n){var y=u.readUEG();if(3===y&&u.skipBits(1),u.skipUEG(),u.skipUEG(),u.skipBits(1),u.readBoolean()){o=3!==y?8:12;for(var p=0;p<o;++p)u.readBoolean()&&(p<6?e.skipScalingList(u,16):e.skipScalingList(u,64))}}u.skipUEG();var v=u.readUEG();if(0===v)u.readUEG();else if(1===v){u.skipBits(1),u.skipEG(),u.skipEG(),r=u.readUEG();for(var m=0;m<r;++m)u.skipEG()}if(u.skipUEG(),u.skipBits(1),i=u.readUEG(),a=u.readUEG(),0===(s=u.readBits(1))&&u.skipBits(1),u.skipBits(1),u.readBoolean()&&(c=u.readUEG(),l=u.readUEG(),f=u.readUEG(),h=u.readUEG()),u.readBoolean()){if(u.readBoolean()){var k;switch(u.readUByte()){case 1:k=[1,1];break;case 2:k=[12,11];break;case 3:k=[10,11];break;case 4:k=[16,11];break;case 5:k=[40,33];break;case 6:k=[24,11];break;case 7:k=[20,11];break;case 8:k=[32,11];break;case 9:k=[80,33];break;case 10:k=[18,11];break;case 11:k=[15,11];break;case 12:k=[64,33];break;case 13:k=[160,99];break;case 14:k=[4,3];break;case 15:k=[3,2];break;case 16:k=[2,1];break;case 255:k=[u.readUByte()<<8|u.readUByte(),u.readUByte()<<8|u.readUByte()]}k&&(d=k[0]/k[1])}if(u.readBoolean()&&u.skipBits(1),u.readBoolean()&&(u.skipBits(4),u.readBoolean()&&u.skipBits(24)),u.readBoolean()&&(u.skipUEG(),u.skipUEG()),u.readBoolean())u.readUInt(),u.readUInt(),u.readBoolean()}return{width:Math.ceil((16*(i+1)-2*c-2*l)*d),height:(2-s)*(a+1)*16-(s?2:4)*(f+h)}}},{key:"parseHeader",value:function(e){var t=new x(e.getPayload());t.readUByte(),e.isfmb=0===t.readUEG(),e.stype=t.readUEG()}}]),i(e,[{key:"parseSPS",value:function(t){var n=e.readSPS(new Uint8Array(t));this.track.width=n.width,this.track.height=n.height,this.track.sps=[new Uint8Array(t)],this.track.codec="avc1.";for(var r=new DataView(t.buffer,t.byteOffset+1,4),i=0;i<3;++i){var a=r.getUint8(i).toString(16);a.length<2&&(a="0"+a),this.track.codec+=a}}},{key:"parsePPS",value:function(e){this.track.pps=[new Uint8Array(e)]}},{key:"parseNAL",value:function(e){if(!e)return!1;var t=!1;switch(e.type()){case b.IDR:case b.NDR:t=!0;break;case b.PPS:this.track.pps||(this.parsePPS(e.getPayload()),!this.remuxer.readyToDecode&&this.track.pps&&this.track.sps&&(this.remuxer.readyToDecode=!0)),t=!0;break;case b.SPS:this.track.sps||(this.parseSPS(e.getPayload()),!this.remuxer.readyToDecode&&this.track.pps&&this.track.sps&&(this.remuxer.readyToDecode=!0)),t=!0;break;case b.AUD:k("AUD - ignoing");break;case b.SEI:k("SEI - ignoing")}return t}}]),e}(),A=function(){function e(t){n(this,e),this.remuxer=t,this.track=t.mp4track}return i(e,null,[{key:"getHeaderLength",value:function(e){return 1&e[1]?7:9}},{key:"getFrameLength",value:function(e){return(3&e[3])<<11|e[4]<<3|(224&e[5])>>>5}},{key:"isAACPattern",value:function(e){return 255===e[0]&&240==(240&e[1])&&0==(6&e[1])}},{key:"extractAAC",value:function(t){var n,r,i=0,a=t.byteLength,s=[];if(!e.isAACPattern(t))return g("Invalid ADTS audio format"),s;for(n=e.getHeaderLength(t),w||(w=t.subarray(0,n));i<a;)r=e.getFrameLength(t),s.push(t.subarray(n,r)),t=t.slice(r),i+=r;return s}},{key:"samplingRateMap",get:function(){return[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350]}},{key:"getAACHeaderData",get:function(){return w}}]),i(e,[{key:"setAACConfig",value:function(){var t,n,r,i=new Uint8Array(2),a=e.getAACHeaderData;a&&(t=1+((192&a[2])>>>6),n=(60&a[2])>>>2,r=(1&a[2])<<2,r|=(192&a[3])>>>6,i[0]=t<<3,i[0]|=(14&n)>>1,i[1]|=(1&n)<<7,i[1]|=r<<3,this.track.codec="mp4a.40."+t,this.track.channelCount=r,this.track.config=i,this.remuxer.readyToDecode=!0)}}]),e}(),C=function(){function e(t){n(this,e),this.listener={},this.type=""|t}return i(e,[{key:"on",value:function(e,t){return this.listener[e]||(this.listener[e]=[]),this.listener[e].push(t),!0}},{key:"off",value:function(e,t){if(this.listener[e]){var n=this.listener[e].indexOf(t);return n>-1&&this.listener[e].splice(n,1),!0}return!1}},{key:"offAll",value:function(){this.listener={}}},{key:"dispatch",value:function(e,t){return!!this.listener[e]&&(this.listener[e].map((function(e){e.apply(null,[t])})),!0)}}]),e}(),B=function(){function e(){n(this,e)}return i(e,null,[{key:"init",value:function(){var t;for(t in e.types={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],sdtp:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[],smhd:[]},e.types)e.types.hasOwnProperty(t)&&(e.types[t]=[t.charCodeAt(0),t.charCodeAt(1),t.charCodeAt(2),t.charCodeAt(3)]);var n=new Uint8Array([0,0,0,0,0,0,0,0,118,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,86,105,100,101,111,72,97,110,100,108,101,114,0]),r=new Uint8Array([0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,114,0]);e.HDLR_TYPES={video:n,audio:r};var i=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),a=new Uint8Array([0,0,0,0,0,0,0,0]);e.STTS=e.STSC=e.STCO=a,e.STSZ=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),e.VMHD=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0]),e.SMHD=new Uint8Array([0,0,0,0,0,0,0,0]),e.STSD=new Uint8Array([0,0,0,0,0,0,0,1]);var s=new Uint8Array([105,115,111,109]),o=new Uint8Array([97,118,99,49]),u=new Uint8Array([0,0,0,1]);e.FTYP=e.box(e.types.ftyp,s,u,s,o),e.DINF=e.box(e.types.dinf,e.box(e.types.dref,i))}},{key:"box",value:function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];for(var i,a=8,s=n.length,o=s;s--;)a+=n[s].byteLength;for((i=new Uint8Array(a))[0]=a>>24&255,i[1]=a>>16&255,i[2]=a>>8&255,i[3]=255&a,i.set(e,4),s=0,a=8;s<o;++s)i.set(n[s],a),a+=n[s].byteLength;return i}},{key:"hdlr",value:function(t){return e.box(e.types.hdlr,e.HDLR_TYPES[t])}},{key:"mdat",value:function(t){return e.box(e.types.mdat,t)}},{key:"mdhd",value:function(t,n){return e.box(e.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,t>>24&255,t>>16&255,t>>8&255,255&t,n>>24,n>>16&255,n>>8&255,255&n,85,196,0,0]))}},{key:"mdia",value:function(t){return e.box(e.types.mdia,e.mdhd(t.timescale,t.duration),e.hdlr(t.type),e.minf(t))}},{key:"mfhd",value:function(t){return e.box(e.types.mfhd,new Uint8Array([0,0,0,0,t>>24,t>>16&255,t>>8&255,255&t]))}},{key:"minf",value:function(t){return"audio"===t.type?e.box(e.types.minf,e.box(e.types.smhd,e.SMHD),e.DINF,e.stbl(t)):e.box(e.types.minf,e.box(e.types.vmhd,e.VMHD),e.DINF,e.stbl(t))}},{key:"moof",value:function(t,n,r){return e.box(e.types.moof,e.mfhd(t),e.traf(r,n))}},{key:"moov",value:function(t,n,r){for(var i=t.length,a=[];i--;)a[i]=e.trak(t[i]);return e.box.apply(null,[e.types.moov,e.mvhd(r,n)].concat(a).concat(e.mvex(t)))}},{key:"mvex",value:function(t){for(var n=t.length,r=[];n--;)r[n]=e.trex(t[n]);return e.box.apply(null,[e.types.mvex].concat(r))}},{key:"mvhd",value:function(t,n){var r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,t>>24&255,t>>16&255,t>>8&255,255&t,n>>24&255,n>>16&255,n>>8&255,255&n,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]);return e.box(e.types.mvhd,r)}},{key:"sdtp",value:function(t){var n,r,i=t.samples||[],a=new Uint8Array(4+i.length);for(r=0;r<i.length;r++)n=i[r].flags,a[r+4]=n.dependsOn<<4|n.isDependedOn<<2|n.hasRedundancy;return e.box(e.types.sdtp,a)}},{key:"stbl",value:function(t){return e.box(e.types.stbl,e.stsd(t),e.box(e.types.stts,e.STTS),e.box(e.types.stsc,e.STSC),e.box(e.types.stsz,e.STSZ),e.box(e.types.stco,e.STCO))}},{key:"avc1",value:function(t){var n,r,i,a=[],s=[];for(n=0;n<t.sps.length;n++)i=(r=t.sps[n]).byteLength,a.push(i>>>8&255),a.push(255&i),a=a.concat(Array.prototype.slice.call(r));for(n=0;n<t.pps.length;n++)i=(r=t.pps[n]).byteLength,s.push(i>>>8&255),s.push(255&i),s=s.concat(Array.prototype.slice.call(r));var o=e.box(e.types.avcC,new Uint8Array([1,a[3],a[4],a[5],255,224|t.sps.length].concat(a).concat([t.pps.length]).concat(s))),u=t.width,c=t.height;return e.box(e.types.avc1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,u>>8&255,255&u,c>>8&255,255&c,0,72,0,0,0,72,0,0,0,0,0,0,0,1,18,98,105,110,101,108,112,114,111,46,114,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),o,e.box(e.types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))}},{key:"esds",value:function(e){var t=e.config.byteLength,n=new Uint8Array(26+t+3);return n.set([0,0,0,0,3,23+t,0,1,0,4,15+t,64,21,0,0,0,0,0,0,0,0,0,0,0,5,t]),n.set(e.config,26),n.set([6,1,2],26+t),n}},{key:"mp4a",value:function(t){var n=t.audiosamplerate;return e.box(e.types.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,t.channelCount,0,16,0,0,0,0,n>>8&255,255&n,0,0]),e.box(e.types.esds,e.esds(t)))}},{key:"stsd",value:function(t){return"audio"===t.type?e.box(e.types.stsd,e.STSD,e.mp4a(t)):e.box(e.types.stsd,e.STSD,e.avc1(t))}},{key:"tkhd",value:function(t){var n=t.id,r=t.duration,i=t.width,a=t.height,s=t.volume;return e.box(e.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,n>>24&255,n>>16&255,n>>8&255,255&n,0,0,0,0,r>>24,r>>16&255,r>>8&255,255&r,0,0,0,0,0,0,0,0,0,0,0,0,s>>0&255,s%1*10>>0&255,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,i>>8&255,255&i,0,0,a>>8&255,255&a,0,0]))}},{key:"traf",value:function(t,n){var r=e.sdtp(t),i=t.id;return e.box(e.types.traf,e.box(e.types.tfhd,new Uint8Array([0,0,0,0,i>>24,i>>16&255,i>>8&255,255&i])),e.box(e.types.tfdt,new Uint8Array([0,0,0,0,n>>24,n>>16&255,n>>8&255,255&n])),e.trun(t,r.length+16+16+8+16+8+8),r)}},{key:"trak",value:function(t){return t.duration=t.duration||4294967295,e.box(e.types.trak,e.tkhd(t),e.mdia(t))}},{key:"trex",value:function(t){var n=t.id;return e.box(e.types.trex,new Uint8Array([0,0,0,0,n>>24,n>>16&255,n>>8&255,255&n,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]))}},{key:"trun",value:function(t,n){var r,i,a,s,o,u,c=t.samples||[],l=c.length,f=12+16*l,h=new Uint8Array(f);for(n+=8+f,h.set([0,0,15,1,l>>>24&255,l>>>16&255,l>>>8&255,255&l,n>>>24&255,n>>>16&255,n>>>8&255,255&n],0),r=0;r<l;r++)a=(i=c[r]).duration,s=i.size,o=i.flags,u=i.cts,h.set([a>>>24&255,a>>>16&255,a>>>8&255,255&a,s>>>24&255,s>>>16&255,s>>>8&255,255&s,o.isLeading<<2|o.dependsOn,o.isDependedOn<<6|o.hasRedundancy<<4|o.paddingValue<<1|o.isNonSync,61440&o.degradPrio,15&o.degradPrio,u>>>24&255,u>>>16&255,u>>>8&255,255&u],12+16*r);return e.box(e.types.trun,h)}},{key:"initSegment",value:function(t,n,r){e.types||e.init();var i,a=e.moov(t,n,r);return(i=new Uint8Array(e.FTYP.byteLength+a.byteLength)).set(e.FTYP),i.set(a,e.FTYP.byteLength),i}}]),e}(),D=1,E=function(){function e(){n(this,e)}return i(e,[{key:"flush",value:function(){this.mp4track.len=0,this.mp4track.samples=[]}},{key:"isReady",value:function(){return!(!this.readyToDecode||!this.samples.length)||null}}],[{key:"getTrackID",value:function(){return D++}}]),e}(),T=function(e){s(r,e);var t=f(r);function r(e){var i;return n(this,r),(i=t.call(this)).readyToDecode=!1,i.nextDts=0,i.dts=0,i.mp4track={id:E.getTrackID(),type:"audio",channelCount:0,len:0,fragmented:!0,timescale:e,duration:e,samples:[],config:"",codec:""},i.samples=[],i.aac=new A(c(i)),i}return i(r,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.codec="",this.mp4track.channelCount="",this.mp4track.config="",this.mp4track.timescale=this.timescale,this.nextDts=0,this.dts=0}},{key:"remux",value:function(e){if(e.length>0)for(var t=0;t<e.length;t++){var n=e[t],r=n.units,i=r.byteLength;this.samples.push({units:r,size:i,duration:n.duration}),this.mp4track.len+=i,this.readyToDecode||this.aac.setAACConfig()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var e,t,n=new Uint8Array(this.mp4track.len),r=0,i=this.mp4track.samples;for(this.dts=this.nextDts;this.samples.length;){var a=this.samples.shift();a.units;(t=a.duration)<=0?(k("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(t)),this.mp4track.len-=a.size):(this.nextDts+=t,e={size:a.size,duration:t,cts:0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,dependsOn:1}},n.set(a.units,r),r+=a.size,i.push(e))}return i.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}}]),r}(E),P=function(e){s(r,e);var t=f(r);function r(e){var i;return n(this,r),(i=t.call(this)).readyToDecode=!1,i.nextDts=0,i.dts=0,i.mp4track={id:E.getTrackID(),type:"video",len:0,fragmented:!0,sps:"",pps:"",width:0,height:0,timescale:e,duration:e,samples:[]},i.samples=[],i.h264=new U(c(i)),i}return i(r,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.sps="",this.mp4track.pps="",this.nextDts=0,this.dts=0}},{key:"remux",value:function(e){var t,n=p(e);try{for(n.s();!(t=n.n()).done;){var r,i=t.value,a=[],s=0,o=p(i.units);try{for(o.s();!(r=o.n()).done;){var u=r.value;this.h264.parseNAL(u)&&(a.push(u),s+=u.getSize())}}catch(e){o.e(e)}finally{o.f()}a.length>0&&this.readyToDecode&&(this.mp4track.len+=s,this.samples.push({units:a,size:s,keyFrame:i.keyFrame,duration:i.duration}))}}catch(e){n.e(e)}finally{n.f()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var e,t,n=new Uint8Array(this.mp4track.len),r=0,i=this.mp4track.samples;for(this.dts=this.nextDts;this.samples.length;){var a=this.samples.shift(),s=a.units;if((t=a.duration)<=0)k("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(t)),this.mp4track.len-=a.size;else{this.nextDts+=t,e={size:a.size,duration:t,cts:0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,isNonSync:a.keyFrame?0:1,dependsOn:a.keyFrame?2:1}};var o,u=p(s);try{for(u.s();!(o=u.n()).done;){var c=o.value;n.set(c.getData(),r),r+=c.getSize()}}catch(e){u.e(e)}finally{u.f()}i.push(e)}}return i.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}}]),r}(E),L=function(e){s(r,e);var t=f(r);function r(e){var i;return n(this,r),(i=t.call(this,"remuxer")).initialized=!1,i.trackTypes=[],i.tracks={},i.seq=1,i.env=e,i.timescale=1e3,i.mediaDuration=0,i}return i(r,[{key:"addTrack",value:function(e){"video"!==e&&"both"!==e||(this.tracks.video=new P(this.timescale),this.trackTypes.push("video")),"audio"!==e&&"both"!==e||(this.tracks.audio=new T(this.timescale),this.trackTypes.push("audio"))}},{key:"reset",value:function(){var e,t=p(this.trackTypes);try{for(t.s();!(e=t.n()).done;){var n=e.value;this.tracks[n].resetTrack()}}catch(e){t.e(e)}finally{t.f()}this.initialized=!1}},{key:"destroy",value:function(){this.tracks={},this.offAll()}},{key:"flush",value:function(){if(this.initialized){var e,t=p(this.trackTypes);try{for(t.s();!(e=t.n()).done;){var n=e.value,r=this.tracks[n],i=r.getPayload();if(i&&i.byteLength){var a={type:n,payload:S(B.moof(this.seq,r.dts,r.mp4track),B.mdat(i)),dts:r.dts};this.dispatch("buffer",a);var s=(o=r.dts/this.timescale,u=void 0,c=void 0,l=void 0,f=void 0,f="",u=Math.floor(o),(c=parseInt(u/3600,10)%24)>0&&(f+=(c<10?"0"+c:c)+":"),f+=((l=parseInt(u/60,10)%60)<10?"0"+l:l)+":"+((u=u<0?0:u%60)<10?"0"+u:u));k("put segment (".concat(n,"): dts: ").concat(r.dts," frames: ").concat(r.mp4track.samples.length," second: ").concat(s)),r.flush(),this.seq++}}}catch(e){t.e(e)}finally{t.f()}}else this.isReady()&&(this.dispatch("ready"),this.initSegment(),this.initialized=!0,this.flush());var o,u,c,l,f}},{key:"initSegment",value:function(){var e,t=[],n=p(this.trackTypes);try{for(n.s();!(e=n.n()).done;){var r=e.value,i=this.tracks[r];if("browser"==this.env){var a={type:r,payload:B.initSegment([i.mp4track],this.mediaDuration,this.timescale)};this.dispatch("buffer",a)}else t.push(i.mp4track)}}catch(e){n.e(e)}finally{n.f()}if("node"==this.env){var s={type:"all",payload:B.initSegment(t,this.mediaDuration,this.timescale)};this.dispatch("buffer",s)}k("Initial segment generated.")}},{key:"isReady",value:function(){var e,t=p(this.trackTypes);try{for(t.s();!(e=t.n()).done;){var n=e.value;if(!this.tracks[n].readyToDecode||!this.tracks[n].samples.length)return!1}}catch(e){t.e(e)}finally{t.f()}return!0}},{key:"remux",value:function(e){var t,n=p(this.trackTypes);try{for(n.s();!(t=n.n()).done;){var r=t.value,i=e[r];"audio"===r&&this.tracks.video&&!this.tracks.video.readyToDecode||i.length>0&&this.tracks[r].remux(i)}}catch(e){n.e(e)}finally{n.f()}this.flush()}}]),r}(C),R=function(e){s(r,e);var t=f(r);function r(e,i){var a;return n(this,r),(a=t.call(this,"buffer")).type=i,a.queue=new Uint8Array,a.cleaning=!1,a.pendingCleaning=0,a.cleanOffset=30,a.cleanRanges=[],a.sourceBuffer=e,a.sourceBuffer.addEventListener("updateend",(function(){a.pendingCleaning>0&&(a.initCleanup(a.pendingCleaning),a.pendingCleaning=0),a.cleaning=!1,a.cleanRanges.length&&a.doCleanup()})),a.sourceBuffer.addEventListener("error",(function(){a.dispatch("error",{type:a.type,name:"buffer",error:"buffer error"})})),a}return i(r,[{key:"destroy",value:function(){this.queue=null,this.sourceBuffer=null,this.offAll()}},{key:"doCleanup",value:function(){if(this.cleanRanges.length){var e=this.cleanRanges.shift();k("".concat(this.type," remove range [").concat(e[0]," - ").concat(e[1],")")),this.cleaning=!0,this.sourceBuffer.remove(e[0],e[1])}else this.cleaning=!1}},{key:"initCleanup",value:function(e){if(this.sourceBuffer.updating)this.pendingCleaning=e;else if(this.sourceBuffer.buffered&&this.sourceBuffer.buffered.length&&!this.cleaning){for(var t=0;t<this.sourceBuffer.buffered.length;++t){var n=this.sourceBuffer.buffered.start(t),r=this.sourceBuffer.buffered.end(t);e-n>this.cleanOffset&&n<(r=e-this.cleanOffset)&&this.cleanRanges.push([n,r])}this.doCleanup()}}},{key:"doAppend",value:function(){if(this.queue.length&&!this.sourceBuffer.updating)try{this.sourceBuffer.appendBuffer(this.queue),this.queue=new Uint8Array}catch(e){if("QuotaExceededError"===e.name)return k("".concat(this.type," buffer quota full")),void this.dispatch("error",{type:this.type,name:"QuotaExceeded",error:"buffer error"});g("Error occured while appending ".concat(this.type," buffer - ").concat(e.name,": ").concat(e.message)),this.dispatch("error",{type:this.type,name:"unexpectedError",error:"buffer error"})}}},{key:"feed",value:function(e){this.queue=S(this.queue,e)}}]),r}(C);return function(r){s(o,r);var a=f(o);function o(e){var r;n(this,o);return(r=a.call(this,"jmuxer")).options=Object.assign({},{node:"",mode:"both",flushingTime:1500,clearBuffer:!0,fps:30,debug:!1,onReady:function(){},onError:function(){}},e),r.env="object"===("undefined"==typeof process?"undefined":t(process))&&"undefined"==typeof window?"node":"browser",r.options.debug&&(v=console.log,m=console.error),r.options.fps||(r.options.fps=30),r.frameDuration=1e3/r.options.fps|0,r.remuxController=new L(r.env),r.remuxController.addTrack(r.options.mode),r.lastCleaningTime=Date.now(),r.kfPosition=[],r.kfCounter=0,r.pendingUnits={},r.remainingData=new Uint8Array,r.remuxController.on("buffer",r.onBuffer.bind(c(r))),"browser"==r.env&&(r.remuxController.on("ready",r.createBuffer.bind(c(r))),r.initBrowser()),r.startInterval(),r}return i(o,null,[{key:"isSupported",value:function(e){return window.MediaSource&&window.MediaSource.isTypeSupported(e)}}]),i(o,[{key:"initBrowser",value:function(){"string"==typeof this.options.node&&""==this.options.node&&g("no video element were found to render, provide a valid video element"),this.node="string"==typeof this.options.node?document.getElementById(this.options.node):this.options.node,this.mseReady=!1,this.setupMSE()}},{key:"createStream",value:function(){var t=this.feed.bind(this),n=this.destroy.bind(this);return this.stream=new e.Duplex({writableObjectMode:!0,read:function(e){},write:function(e,n,r){t(e),r()},final:function(e){n(),e()}}),this.stream}},{key:"setupMSE",value:function(){if(window.MediaSource=window.MediaSource||window.WebKitMediaSource,!window.MediaSource)throw"Oops! Browser does not support media source extension.";this.isMSESupported=!!window.MediaSource,this.mediaSource=new MediaSource,this.url=URL.createObjectURL(this.mediaSource),this.node.src=this.url,this.mseEnded=!1,this.mediaSource.addEventListener("sourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("sourceclose",this.onMSEClose.bind(this)),this.mediaSource.addEventListener("webkitsourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("webkitsourceclose",this.onMSEClose.bind(this))}},{key:"endMSE",value:function(){if(!this.mseEnded)try{this.mseEnded=!0,this.mediaSource.endOfStream()}catch(e){g("mediasource is not available to end")}}},{key:"feed",value:function(e){var t,n,r,i=!1,a={video:[],audio:[]};if(e&&this.remuxController){if(r=e.duration?parseInt(e.duration):0,e.video){e.video=S(this.remainingData,e.video);var s=h(U.extractNALu(e.video),2);t=s[0],n=s[1],t.length>0&&(a.video=this.getVideoFrames(t,r),i=!0),this.remainingData=n||new Uint8Array}e.audio&&(t=A.extractAAC(e.audio)).length>0&&(a.audio=this.getAudioFrames(t,r),i=!0),i?this.remuxController.remux(a):g("Input object must have video and/or audio property. Make sure it is a valid typed array")}}},{key:"getVideoFrames",value:function(e,t){var n,r=this,i=[],a=[],s=0,o=!1,u=!1;this.pendingUnits.units&&(i=this.pendingUnits.units,u=this.pendingUnits.vcl,o=this.pendingUnits.keyFrame,this.pendingUnits={});var c,l=p(e);try{for(l.s();!(c=l.n()).done;){var f=c.value,h=new b(f);h.type()!==b.IDR&&h.type()!==b.NDR||U.parseHeader(h),i.length&&u&&(h.isfmb||!h.isvcl)&&(a.push({units:i,keyFrame:o}),i=[],o=!1,u=!1),i.push(h),o=o||h.isKeyframe(),u=u||h.isvcl}}catch(e){l.e(e)}finally{l.f()}if(i.length)if(t)if(u)a.push({units:i,keyFrame:o});else{var d=a.length-1;a[d].units=a[d].units.concat(i)}else this.pendingUnits={units:i,keyFrame:o,vcl:u};return n=t?t/a.length|0:this.frameDuration,s=t?t-n*a.length:0,a.map((function(e){e.duration=n,s>0&&(e.duration++,s--),r.kfCounter++,e.keyFrame&&r.options.clearBuffer&&r.kfPosition.push(r.kfCounter*n/1e3)})),k("jmuxer: No. of frames of the last chunk: ".concat(a.length)),a}},{key:"getAudioFrames",value:function(e,t){var n,r,i=[],a=0,s=p(e);try{for(s.s();!(r=s.n()).done;){var o=r.value;i.push({units:o})}}catch(e){s.e(e)}finally{s.f()}return n=t?t/i.length|0:this.frameDuration,a=t?t-n*i.length:0,i.map((function(e){e.duration=n,a>0&&(e.duration++,a--)})),i}},{key:"destroy",value:function(){if(this.stopInterval(),this.stream&&(this.remuxController.flush(),this.stream.push(null),this.stream=null),this.remuxController&&(this.remuxController.destroy(),this.remuxController=null),this.bufferControllers){for(var e in this.bufferControllers)this.bufferControllers[e].destroy();this.bufferControllers=null,this.endMSE()}this.node=!1,this.mseReady=!1,this.videoStarted=!1,this.mediaSource=null}},{key:"reset",value:function(){if(this.node.pause(),this.remuxController&&this.remuxController.reset(),this.bufferControllers){for(var e in this.bufferControllers)this.bufferControllers[e].destroy();this.bufferControllers=null,this.endMSE()}"browser"==this.env&&this.initBrowser(),k("JMuxer was reset")}},{key:"createBuffer",value:function(){if(this.mseReady&&this.remuxController&&this.remuxController.isReady()&&!this.bufferControllers)for(var e in this.bufferControllers={},this.remuxController.tracks){var t=this.remuxController.tracks[e];if(!o.isSupported("".concat(e,'/mp4; codecs="').concat(t.mp4track.codec,'"')))return g("Browser does not support codec"),!1;var n=this.mediaSource.addSourceBuffer("".concat(e,'/mp4; codecs="').concat(t.mp4track.codec,'"'));this.bufferControllers[e]=new R(n,e),this.bufferControllers[e].on("error",this.onBufferError.bind(this))}}},{key:"startInterval",value:function(){var e=this;this.interval=setInterval((function(){e.bufferControllers&&(e.releaseBuffer(),e.clearBuffer())}),this.options.flushingTime)}},{key:"stopInterval",value:function(){this.interval&&clearInterval(this.interval)}},{key:"releaseBuffer",value:function(){for(var e in this.bufferControllers)this.bufferControllers[e].doAppend()}},{key:"getSafeClearOffsetOfBuffer",value:function(e){for(var t,n="audio"===this.options.mode&&e||0,r=0;r<this.kfPosition.length&&!(this.kfPosition[r]>=e);r++)t=this.kfPosition[r];return t&&(this.kfPosition=this.kfPosition.filter((function(e){return e<t&&(n=e),e>=t}))),n}},{key:"clearBuffer",value:function(){if(this.options.clearBuffer&&Date.now()-this.lastCleaningTime>1e4){for(var e in this.bufferControllers){var t=this.getSafeClearOffsetOfBuffer(this.node.currentTime);this.bufferControllers[e].initCleanup(t)}this.lastCleaningTime=Date.now()}}},{key:"onBuffer",value:function(e){"browser"==this.env?this.bufferControllers&&this.bufferControllers[e.type]&&this.bufferControllers[e.type].feed(e.payload):this.stream&&this.stream.push(e.payload)}},{key:"onMSEOpen",value:function(){this.mseReady=!0,"function"==typeof this.options.onReady&&this.options.onReady.call(null),URL.revokeObjectURL(this.url),this.createBuffer()}},{key:"onMSEClose",value:function(){this.mseReady=!1,this.videoStarted=!1}},{key:"onBufferError",value:function(e){"QuotaExceeded"!=e.name?(this.endMSE(),"function"==typeof this.options.onError&&this.options.onError.call(null,e)):this.bufferControllers[e.type].initCleanup(this.node.currentTime)}}]),o}(C)}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("stream")):"function"==typeof define&&define.amd?define(["stream"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).JMuxer=t(e.stream)}(this,(function(e){"use strict";function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t(e)}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function i(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&u(e,t)}function o(e){return o=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},o(e)}function u(e,t){return u=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},u(e,t)}function c(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function f(e,t){if(t&&("object"==typeof t||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return c(e)}function l(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=o(e);if(t){var i=o(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return f(this,n)}}function h(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var r,i,s=[],a=!0,o=!1;try{for(n=n.call(e);!(a=(r=n.next()).done)&&(s.push(r.value),!t||s.length!==t);a=!0);}catch(e){o=!0,i=e}finally{try{a||null==n.return||n.return()}finally{if(o)throw i}}return s}(e,t)||d(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e,t){if(e){if("string"==typeof e)return y(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?y(e,t):void 0}}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function p(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=d(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,a=!0,o=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){o=!0,s=e},f:function(){try{a||null==n.return||n.return()}finally{if(o)throw s}}}}var v,m;function k(e){if(v){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];v.apply(void 0,[e].concat(n))}}function g(e){if(m){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];m.apply(void 0,[e].concat(n))}}var b=function(){function e(t){n(this,e),this.payload=t,this.nri=(96&this.payload[0])>>5,this.ntype=31&this.payload[0],this.isvcl=1==this.ntype||5==this.ntype,this.stype="",this.isfmb=!1}return i(e,[{key:"toString",value:function(){return"".concat(e.type(this),": NRI: ").concat(this.getNri())}},{key:"getNri",value:function(){return this.nri}},{key:"type",value:function(){return this.ntype}},{key:"isKeyframe",value:function(){return this.ntype===e.IDR}},{key:"getPayload",value:function(){return this.payload}},{key:"getPayloadSize",value:function(){return this.payload.byteLength}},{key:"getSize",value:function(){return 4+this.getPayloadSize()}},{key:"getData",value:function(){var e=new Uint8Array(this.getSize());return new DataView(e.buffer).setUint32(0,this.getSize()-4),e.set(this.getPayload(),4),e}}],[{key:"NDR",get:function(){return 1}},{key:"IDR",get:function(){return 5}},{key:"SEI",get:function(){return 6}},{key:"SPS",get:function(){return 7}},{key:"PPS",get:function(){return 8}},{key:"AUD",get:function(){return 9}},{key:"TYPES",get:function(){var t;return s(t={},e.IDR,"IDR"),s(t,e.SEI,"SEI"),s(t,e.SPS,"SPS"),s(t,e.PPS,"PPS"),s(t,e.NDR,"NDR"),s(t,e.AUD,"AUD"),t}},{key:"type",value:function(t){return t.ntype in e.TYPES?e.TYPES[t.ntype]:"UNKNOWN"}}]),e}();function S(e,t){var n=new Uint8Array((0|e.byteLength)+(0|t.byteLength));return n.set(e,0),n.set(t,0|e.byteLength),n}var w=function(){function e(t){n(this,e),this.data=t,this.index=0,this.bitLength=8*t.byteLength}return i(e,[{key:"setData",value:function(e){this.data=e,this.index=0,this.bitLength=8*e.byteLength}},{key:"bitsAvailable",get:function(){return this.bitLength-this.index}},{key:"skipBits",value:function(e){if(this.bitsAvailable<e)return!1;this.index+=e}},{key:"readBits",value:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this.getBits(e,this.index,t);return n}},{key:"getBits",value:function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(this.bitsAvailable<e)return 0;var r=t%8,i=this.data[t/8|0]&255>>>r,s=8-r;if(s>=e)return n&&(this.index+=e),i>>s-e;n&&(this.index+=s);var a=e-s;return i<<a|this.getBits(a,t+s,n)}},{key:"skipLZ",value:function(){var e;for(e=0;e<this.bitLength-this.index;++e)if(0!==this.getBits(1,this.index+e,!1))return this.index+=e,e;return e}},{key:"skipUEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"skipEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"readUEG",value:function(){var e=this.skipLZ();return this.readBits(e+1)-1}},{key:"readEG",value:function(){var e=this.readUEG();return 1&e?1+e>>>1:-1*(e>>>1)}},{key:"readBoolean",value:function(){return 1===this.readBits(1)}},{key:"readUByte",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return this.readBits(8*e)}},{key:"readUShort",value:function(){return this.readBits(16)}},{key:"readUInt",value:function(){return this.readBits(32)}}]),e}(),x=function(){function e(t){n(this,e),this.remuxer=t,this.track=t.mp4track}return i(e,[{key:"parseSPS",value:function(t){var n=e.readSPS(new Uint8Array(t));this.track.fps=n.fps,this.track.width=n.width,this.track.height=n.height,this.track.sps=[new Uint8Array(t)],this.track.codec="avc1.";for(var r=new DataView(t.buffer,t.byteOffset+1,4),i=0;i<3;++i){var s=r.getUint8(i).toString(16);s.length<2&&(s="0"+s),this.track.codec+=s}}},{key:"parsePPS",value:function(e){this.track.pps=[new Uint8Array(e)]}},{key:"parseNAL",value:function(e){if(!e)return!1;var t=!1;switch(e.type()){case b.IDR:case b.NDR:t=!0;break;case b.PPS:this.track.pps||(this.parsePPS(e.getPayload()),!this.remuxer.readyToDecode&&this.track.pps&&this.track.sps&&(this.remuxer.readyToDecode=!0)),t=!0;break;case b.SPS:this.track.sps||(this.parseSPS(e.getPayload()),!this.remuxer.readyToDecode&&this.track.pps&&this.track.sps&&(this.remuxer.readyToDecode=!0)),t=!0;break;case b.AUD:k("AUD - ignoing");break;case b.SEI:k("SEI - ignoing")}return t}}],[{key:"extractNALu",value:function(e){for(var t,n,r=0,i=e.byteLength,s=0,a=[],o=0;r<i;)switch(t=e[r++],s){case 0:0===t&&(s=1);break;case 1:s=0===t?2:0;break;case 2:case 3:0===t?s=3:1===t&&r<i?(o!=r-s-1&&a.push(e.subarray(o,r-s-1)),o=r,s=0):s=0}return o<i&&(n=e.subarray(o,i)),[a,n]}},{key:"skipScalingList",value:function(e,t){for(var n=8,r=8,i=0;i<t;i++)0!==r&&(r=(n+e.readEG()+256)%256),n=0===r?n:r}},{key:"readSPS",value:function(t){var n,r,i,s,a,o,u=new w(t),c=0,f=0,l=0,h=0,d=1,y=0;u.readUByte();for(var p=[],v=t.byteLength,m=1;m<v;m++)m+2<v&&3===u.readBits(24,!1)?(p.push(u.readBits(8)),p.push(u.readBits(8)),m+=2,u.readBits(8)):p.push(u.readBits(8));if(u.setData(new Uint8Array(p)),n=u.readUByte(),u.readBits(5),u.skipBits(3),u.readUByte(),u.skipUEG(),100===n||110===n||122===n||244===n||44===n||83===n||86===n||118===n||128===n){var k=u.readUEG();if(3===k&&u.skipBits(1),u.skipUEG(),u.skipUEG(),u.skipBits(1),u.readBoolean()){o=3!==k?8:12;for(var g=0;g<o;++g)u.readBoolean()&&(g<6?e.skipScalingList(u,16):e.skipScalingList(u,64))}}u.skipUEG();var b=u.readUEG();if(0===b)u.readUEG();else if(1===b){u.skipBits(1),u.skipEG(),u.skipEG(),r=u.readUEG();for(var S=0;S<r;++S)u.skipEG()}if(u.skipUEG(),u.skipBits(1),i=u.readUEG(),s=u.readUEG(),0===(a=u.readBits(1))&&u.skipBits(1),u.skipBits(1),u.readBoolean()&&(c=u.readUEG(),f=u.readUEG(),l=u.readUEG(),h=u.readUEG()),u.readBoolean()){if(u.readBoolean()){var x;switch(u.readUByte()){case 1:x=[1,1];break;case 2:x=[12,11];break;case 3:x=[10,11];break;case 4:x=[16,11];break;case 5:x=[40,33];break;case 6:x=[24,11];break;case 7:x=[20,11];break;case 8:x=[32,11];break;case 9:x=[80,33];break;case 10:x=[18,11];break;case 11:x=[15,11];break;case 12:x=[64,33];break;case 13:x=[160,99];break;case 14:x=[4,3];break;case 15:x=[3,2];break;case 16:x=[2,1];break;case 255:x=[u.readUByte()<<8|u.readUByte(),u.readUByte()<<8|u.readUByte()]}x&&x[0]>0&&x[1]>0&&(d=x[0]/x[1])}if(u.readBoolean()&&u.skipBits(1),u.readBoolean()&&(u.skipBits(4),u.readBoolean()&&u.skipBits(24)),u.readBoolean()&&(u.skipUEG(),u.skipUEG()),u.readBoolean()){var A=u.readUInt(),U=u.readUInt();u.readBoolean()&&(y=U/(2*A))}}return{fps:y>0?y:void 0,width:Math.ceil((16*(i+1)-2*c-2*f)*d),height:(2-a)*(s+1)*16-(a?2:4)*(l+h)}}},{key:"parseHeader",value:function(e){var t=new w(e.getPayload());t.readUByte(),e.isfmb=0===t.readUEG(),e.stype=t.readUEG()}}]),e}(),A=function(){function e(t){n(this,e),this.remuxer=t,this.track=t.mp4track}return i(e,[{key:"extractAAC",value:function(t){var n,r,i=0,s=t.byteLength,a=[];if(!e.isAACPattern(t))return g("Invalid ADTS audio format"),a;for(n=e.getHeaderLength(t),this.aacHeader||(this.aacHeader=t.subarray(0,n));i<s;)r=e.getFrameLength(t),a.push(t.subarray(n,r)),t=t.slice(r),i+=r;return a}},{key:"setAACConfig",value:function(){var e,t,n,r=new Uint8Array(2),i=this.aacHeader;i&&(e=1+((192&i[2])>>>6),t=(60&i[2])>>>2,n=(1&i[2])<<2,n|=(192&i[3])>>>6,r[0]=e<<3,r[0]|=(14&t)>>1,r[1]|=(1&t)<<7,r[1]|=n<<3,this.track.codec="mp4a.40."+e,this.track.channelCount=n,this.track.config=r,this.remuxer.readyToDecode=!0)}}],[{key:"samplingRateMap",get:function(){return[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350]}},{key:"getHeaderLength",value:function(e){return 1&e[1]?7:9}},{key:"getFrameLength",value:function(e){return(3&e[3])<<11|e[4]<<3|(224&e[5])>>>5}},{key:"isAACPattern",value:function(e){return 255===e[0]&&240==(240&e[1])&&0==(6&e[1])}}]),e}(),U=function(){function e(t){n(this,e),this.listener={},this.type=""|t}return i(e,[{key:"on",value:function(e,t){return this.listener[e]||(this.listener[e]=[]),this.listener[e].push(t),!0}},{key:"off",value:function(e,t){if(this.listener[e]){var n=this.listener[e].indexOf(t);return n>-1&&this.listener[e].splice(n,1),!0}return!1}},{key:"offAll",value:function(){this.listener={}}},{key:"dispatch",value:function(e,t){return!!this.listener[e]&&(this.listener[e].map((function(e){e.apply(null,[t])})),!0)}}]),e}(),B=function(){function e(){n(this,e)}return i(e,null,[{key:"init",value:function(){var t;for(t in e.types={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],sdtp:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[],smhd:[]},e.types)e.types.hasOwnProperty(t)&&(e.types[t]=[t.charCodeAt(0),t.charCodeAt(1),t.charCodeAt(2),t.charCodeAt(3)]);var n=new Uint8Array([0,0,0,0,0,0,0,0,118,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,86,105,100,101,111,72,97,110,100,108,101,114,0]),r=new Uint8Array([0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,114,0]);e.HDLR_TYPES={video:n,audio:r};var i=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),s=new Uint8Array([0,0,0,0,0,0,0,0]);e.STTS=e.STSC=e.STCO=s,e.STSZ=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),e.VMHD=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0]),e.SMHD=new Uint8Array([0,0,0,0,0,0,0,0]),e.STSD=new Uint8Array([0,0,0,0,0,0,0,1]);var a=new Uint8Array([105,115,111,109]),o=new Uint8Array([97,118,99,49]),u=new Uint8Array([0,0,0,1]);e.FTYP=e.box(e.types.ftyp,a,u,a,o),e.DINF=e.box(e.types.dinf,e.box(e.types.dref,i))}},{key:"box",value:function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];for(var i,s=8,a=n.length,o=a;a--;)s+=n[a].byteLength;for((i=new Uint8Array(s))[0]=s>>24&255,i[1]=s>>16&255,i[2]=s>>8&255,i[3]=255&s,i.set(e,4),a=0,s=8;a<o;++a)i.set(n[a],s),s+=n[a].byteLength;return i}},{key:"hdlr",value:function(t){return e.box(e.types.hdlr,e.HDLR_TYPES[t])}},{key:"mdat",value:function(t){return e.box(e.types.mdat,t)}},{key:"mdhd",value:function(t,n){return e.box(e.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,t>>24&255,t>>16&255,t>>8&255,255&t,n>>24,n>>16&255,n>>8&255,255&n,85,196,0,0]))}},{key:"mdia",value:function(t){return e.box(e.types.mdia,e.mdhd(t.timescale,t.duration),e.hdlr(t.type),e.minf(t))}},{key:"mfhd",value:function(t){return e.box(e.types.mfhd,new Uint8Array([0,0,0,0,t>>24,t>>16&255,t>>8&255,255&t]))}},{key:"minf",value:function(t){return"audio"===t.type?e.box(e.types.minf,e.box(e.types.smhd,e.SMHD),e.DINF,e.stbl(t)):e.box(e.types.minf,e.box(e.types.vmhd,e.VMHD),e.DINF,e.stbl(t))}},{key:"moof",value:function(t,n,r){return e.box(e.types.moof,e.mfhd(t),e.traf(r,n))}},{key:"moov",value:function(t,n,r){for(var i=t.length,s=[];i--;)s[i]=e.trak(t[i]);return e.box.apply(null,[e.types.moov,e.mvhd(r,n)].concat(s).concat(e.mvex(t)))}},{key:"mvex",value:function(t){for(var n=t.length,r=[];n--;)r[n]=e.trex(t[n]);return e.box.apply(null,[e.types.mvex].concat(r))}},{key:"mvhd",value:function(t,n){var r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,t>>24&255,t>>16&255,t>>8&255,255&t,n>>24&255,n>>16&255,n>>8&255,255&n,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]);return e.box(e.types.mvhd,r)}},{key:"sdtp",value:function(t){var n,r,i=t.samples||[],s=new Uint8Array(4+i.length);for(r=0;r<i.length;r++)n=i[r].flags,s[r+4]=n.dependsOn<<4|n.isDependedOn<<2|n.hasRedundancy;return e.box(e.types.sdtp,s)}},{key:"stbl",value:function(t){return e.box(e.types.stbl,e.stsd(t),e.box(e.types.stts,e.STTS),e.box(e.types.stsc,e.STSC),e.box(e.types.stsz,e.STSZ),e.box(e.types.stco,e.STCO))}},{key:"avc1",value:function(t){var n,r,i,s=[],a=[];for(n=0;n<t.sps.length;n++)i=(r=t.sps[n]).byteLength,s.push(i>>>8&255),s.push(255&i),s=s.concat(Array.prototype.slice.call(r));for(n=0;n<t.pps.length;n++)i=(r=t.pps[n]).byteLength,a.push(i>>>8&255),a.push(255&i),a=a.concat(Array.prototype.slice.call(r));var o=e.box(e.types.avcC,new Uint8Array([1,s[3],s[4],s[5],255,224|t.sps.length].concat(s).concat([t.pps.length]).concat(a))),u=t.width,c=t.height;return e.box(e.types.avc1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,u>>8&255,255&u,c>>8&255,255&c,0,72,0,0,0,72,0,0,0,0,0,0,0,1,18,98,105,110,101,108,112,114,111,46,114,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),o,e.box(e.types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))}},{key:"esds",value:function(e){var t=e.config.byteLength,n=new Uint8Array(26+t+3);return n.set([0,0,0,0,3,23+t,0,1,0,4,15+t,64,21,0,0,0,0,0,0,0,0,0,0,0,5,t]),n.set(e.config,26),n.set([6,1,2],26+t),n}},{key:"mp4a",value:function(t){var n=t.audiosamplerate;return e.box(e.types.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,t.channelCount,0,16,0,0,0,0,n>>8&255,255&n,0,0]),e.box(e.types.esds,e.esds(t)))}},{key:"stsd",value:function(t){return"audio"===t.type?e.box(e.types.stsd,e.STSD,e.mp4a(t)):e.box(e.types.stsd,e.STSD,e.avc1(t))}},{key:"tkhd",value:function(t){var n=t.id,r=t.duration,i=t.width,s=t.height,a=t.volume;return e.box(e.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,n>>24&255,n>>16&255,n>>8&255,255&n,0,0,0,0,r>>24,r>>16&255,r>>8&255,255&r,0,0,0,0,0,0,0,0,0,0,0,0,a>>0&255,a%1*10>>0&255,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,i>>8&255,255&i,0,0,s>>8&255,255&s,0,0]))}},{key:"traf",value:function(t,n){var r=e.sdtp(t),i=t.id;return e.box(e.types.traf,e.box(e.types.tfhd,new Uint8Array([0,0,0,0,i>>24,i>>16&255,i>>8&255,255&i])),e.box(e.types.tfdt,new Uint8Array([0,0,0,0,n>>24,n>>16&255,n>>8&255,255&n])),e.trun(t,r.length+16+16+8+16+8+8),r)}},{key:"trak",value:function(t){return t.duration=t.duration||4294967295,e.box(e.types.trak,e.tkhd(t),e.mdia(t))}},{key:"trex",value:function(t){var n=t.id;return e.box(e.types.trex,new Uint8Array([0,0,0,0,n>>24,n>>16&255,n>>8&255,255&n,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]))}},{key:"trun",value:function(t,n){var r,i,s,a,o,u,c=t.samples||[],f=c.length,l=12+16*f,h=new Uint8Array(l);for(n+=8+l,h.set([0,0,15,1,f>>>24&255,f>>>16&255,f>>>8&255,255&f,n>>>24&255,n>>>16&255,n>>>8&255,255&n],0),r=0;r<f;r++)s=(i=c[r]).duration,a=i.size,o=i.flags,u=i.cts,h.set([s>>>24&255,s>>>16&255,s>>>8&255,255&s,a>>>24&255,a>>>16&255,a>>>8&255,255&a,o.isLeading<<2|o.dependsOn,o.isDependedOn<<6|o.hasRedundancy<<4|o.paddingValue<<1|o.isNonSync,61440&o.degradPrio,15&o.degradPrio,u>>>24&255,u>>>16&255,u>>>8&255,255&u],12+16*r);return e.box(e.types.trun,h)}},{key:"initSegment",value:function(t,n,r){e.types||e.init();var i,s=e.moov(t,n,r);return(i=new Uint8Array(e.FTYP.byteLength+s.byteLength)).set(e.FTYP),i.set(s,e.FTYP.byteLength),i}}]),e}(),D=1,C=function(){function e(){n(this,e)}return i(e,[{key:"flush",value:function(){this.mp4track.len=0,this.mp4track.samples=[]}},{key:"isReady",value:function(){return!(!this.readyToDecode||!this.samples.length)||null}}],[{key:"getTrackID",value:function(){return D++}}]),e}(),E=function(e){a(r,e);var t=l(r);function r(e){var i;return n(this,r),(i=t.call(this)).readyToDecode=!1,i.nextDts=0,i.dts=0,i.mp4track={id:C.getTrackID(),type:"audio",channelCount:0,len:0,fragmented:!0,timescale:e,duration:e,samples:[],config:"",codec:""},i.samples=[],i.aac=new A(c(i)),i}return i(r,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.codec="",this.mp4track.channelCount="",this.mp4track.config="",this.mp4track.timescale=this.timescale,this.nextDts=0,this.dts=0}},{key:"remux",value:function(e){if(e.length>0)for(var t=0;t<e.length;t++){var n=e[t],r=n.units,i=r.byteLength;this.samples.push({units:r,size:i,duration:n.duration}),this.mp4track.len+=i,this.readyToDecode||this.aac.setAACConfig()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var e,t,n=new Uint8Array(this.mp4track.len),r=0,i=this.mp4track.samples;for(this.dts=this.nextDts;this.samples.length;){var s=this.samples.shift();s.units,(t=s.duration)<=0?(k("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(t)),this.mp4track.len-=s.size):(this.nextDts+=t,e={size:s.size,duration:t,cts:0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,dependsOn:1}},n.set(s.units,r),r+=s.size,i.push(e))}return i.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}},{key:"getAacParser",value:function(){return this.aac}}]),r}(C),T=function(e){a(r,e);var t=l(r);function r(e){var i;return n(this,r),(i=t.call(this)).readyToDecode=!1,i.nextDts=0,i.dts=0,i.mp4track={id:C.getTrackID(),type:"video",len:0,fragmented:!0,sps:"",pps:"",fps:30,width:0,height:0,timescale:e,duration:e,samples:[]},i.samples=[],i.h264=new x(c(i)),i}return i(r,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.sps="",this.mp4track.pps="",this.nextDts=0,this.dts=0}},{key:"remux",value:function(e){var t,n=p(e);try{for(n.s();!(t=n.n()).done;){var r,i=t.value,s=[],a=0,o=p(i.units);try{for(o.s();!(r=o.n()).done;){var u=r.value;this.h264.parseNAL(u)&&(s.push(u),a+=u.getSize())}}catch(e){o.e(e)}finally{o.f()}s.length>0&&this.readyToDecode&&(this.mp4track.len+=a,this.samples.push({units:s,size:a,keyFrame:i.keyFrame,duration:i.duration,compositionTimeOffset:i.compositionTimeOffset}))}}catch(e){n.e(e)}finally{n.f()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var e,t,n=new Uint8Array(this.mp4track.len),r=0,i=this.mp4track.samples;for(this.dts=this.nextDts;this.samples.length;){var s=this.samples.shift(),a=s.units;if((t=s.duration)<=0)k("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(t)),this.mp4track.len-=s.size;else{this.nextDts+=t,e={size:s.size,duration:t,cts:s.compositionTimeOffset||0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,isNonSync:s.keyFrame?0:1,dependsOn:s.keyFrame?2:1}};var o,u=p(a);try{for(u.s();!(o=u.n()).done;){var c=o.value;n.set(c.getData(),r),r+=c.getSize()}}catch(e){u.e(e)}finally{u.f()}i.push(e)}}return i.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}}]),r}(C),P=function(e){a(r,e);var t=l(r);function r(e){var i;return n(this,r),(i=t.call(this,"remuxer")).initialized=!1,i.trackTypes=[],i.tracks={},i.seq=1,i.env=e,i.timescale=1e3,i.mediaDuration=0,i.aacParser=null,i}return i(r,[{key:"addTrack",value:function(e){if("video"!==e&&"both"!==e||(this.tracks.video=new T(this.timescale),this.trackTypes.push("video")),"audio"===e||"both"===e){var t=new E(this.timescale);this.aacParser=t.getAacParser(),this.tracks.audio=t,this.trackTypes.push("audio")}}},{key:"reset",value:function(){var e,t=p(this.trackTypes);try{for(t.s();!(e=t.n()).done;){var n=e.value;this.tracks[n].resetTrack()}}catch(e){t.e(e)}finally{t.f()}this.initialized=!1}},{key:"destroy",value:function(){this.tracks={},this.offAll()}},{key:"flush",value:function(){if(this.initialized){var e,t=p(this.trackTypes);try{for(t.s();!(e=t.n()).done;){var n=e.value,r=this.tracks[n],i=r.getPayload();if(i&&i.byteLength){var s={type:n,payload:S(B.moof(this.seq,r.dts,r.mp4track),B.mdat(i)),dts:r.dts};"video"===n&&(s.fps=r.mp4track.fps),this.dispatch("buffer",s);var a=(o=r.dts/this.timescale,u=void 0,c=void 0,f=void 0,l=void 0,l="",u=Math.floor(o),(c=parseInt(u/3600,10)%24)>0&&(l+=(c<10?"0"+c:c)+":"),l+=((f=parseInt(u/60,10)%60)<10?"0"+f:f)+":"+((u=u<0?0:u%60)<10?"0"+u:u));k("put segment (".concat(n,"): dts: ").concat(r.dts," frames: ").concat(r.mp4track.samples.length," second: ").concat(a)),r.flush(),this.seq++}}}catch(e){t.e(e)}finally{t.f()}}else this.isReady()&&(this.dispatch("ready"),this.initSegment(),this.initialized=!0,this.flush());var o,u,c,f,l}},{key:"initSegment",value:function(){var e,t=[],n=p(this.trackTypes);try{for(n.s();!(e=n.n()).done;){var r=e.value,i=this.tracks[r];if("browser"==this.env){var s={type:r,payload:B.initSegment([i.mp4track],this.mediaDuration,this.timescale)};this.dispatch("buffer",s)}else t.push(i.mp4track)}}catch(e){n.e(e)}finally{n.f()}if("node"==this.env){var a={type:"all",payload:B.initSegment(t,this.mediaDuration,this.timescale)};this.dispatch("buffer",a)}k("Initial segment generated.")}},{key:"isReady",value:function(){var e,t=p(this.trackTypes);try{for(t.s();!(e=t.n()).done;){var n=e.value;if(!this.tracks[n].readyToDecode||!this.tracks[n].samples.length)return!1}}catch(e){t.e(e)}finally{t.f()}return!0}},{key:"remux",value:function(e){var t,n=p(this.trackTypes);try{for(n.s();!(t=n.n()).done;){var r=t.value,i=e[r];"audio"===r&&this.tracks.video&&!this.tracks.video.readyToDecode||i.length>0&&this.tracks[r].remux(i)}}catch(e){n.e(e)}finally{n.f()}this.flush()}}]),r}(U),L=function(e){a(r,e);var t=l(r);function r(e,i){var s;return n(this,r),(s=t.call(this,"buffer")).type=i,s.queue=new Uint8Array,s.cleaning=!1,s.pendingCleaning=0,s.cleanOffset=30,s.cleanRanges=[],s.sourceBuffer=e,s.sourceBuffer.addEventListener("updateend",(function(){s.pendingCleaning>0&&(s.initCleanup(s.pendingCleaning),s.pendingCleaning=0),s.cleaning=!1,s.cleanRanges.length&&s.doCleanup()})),s.sourceBuffer.addEventListener("error",(function(){s.dispatch("error",{type:s.type,name:"buffer",error:"buffer error"})})),s}return i(r,[{key:"destroy",value:function(){this.queue=null,this.sourceBuffer=null,this.offAll()}},{key:"doCleanup",value:function(){if(this.cleanRanges.length){var e=this.cleanRanges.shift();k("".concat(this.type," remove range [").concat(e[0]," - ").concat(e[1],")")),this.cleaning=!0,this.sourceBuffer.remove(e[0],e[1])}else this.cleaning=!1}},{key:"initCleanup",value:function(e){try{if(this.sourceBuffer.updating)return void(this.pendingCleaning=e);if(this.sourceBuffer.buffered&&this.sourceBuffer.buffered.length&&!this.cleaning){for(var t=0;t<this.sourceBuffer.buffered.length;++t){var n=this.sourceBuffer.buffered.start(t),r=this.sourceBuffer.buffered.end(t);e-n>this.cleanOffset&&n<(r=e-this.cleanOffset)&&this.cleanRanges.push([n,r])}this.doCleanup()}}catch(e){g("Error occured while cleaning ".concat(this.type," buffer - ").concat(e.name,": ").concat(e.message))}}},{key:"doAppend",value:function(){if(this.queue.length&&this.sourceBuffer&&!this.sourceBuffer.updating)try{this.sourceBuffer.appendBuffer(this.queue),this.queue=new Uint8Array}catch(t){var e="unexpectedError";"QuotaExceededError"===t.name?(k("".concat(this.type," buffer quota full")),e="QuotaExceeded"):(g("Error occured while appending ".concat(this.type," buffer - ").concat(t.name,": ").concat(t.message)),e="InvalidStateError"),this.dispatch("error",{type:this.type,name:e,error:"buffer error"})}}},{key:"feed",value:function(e){this.queue=S(this.queue,e)}}]),r}(U);return function(r){a(o,r);var s=l(o);function o(e){var r;n(this,o),(r=s.call(this,"jmuxer")).isReset=!1;return r.options=Object.assign({},{node:"",mode:"both",flushingTime:500,maxDelay:500,clearBuffer:!0,fps:30,readFpsFromTrack:!1,debug:!1,onReady:function(){},onError:function(){},onMissingVideoFrames:function(){},onMissingAudioFrames:function(){}},e),r.env="object"===("undefined"==typeof process?"undefined":t(process))&&"undefined"==typeof window?"node":"browser",r.options.debug&&(v=console.log,m=console.error),r.options.fps||(r.options.fps=30),r.frameDuration=1e3/r.options.fps|0,r.remuxController=new P(r.env),r.remuxController.addTrack(r.options.mode),r.initData(),r.remuxController.on("buffer",r.onBuffer.bind(c(r))),"browser"==r.env&&(r.remuxController.on("ready",r.createBuffer.bind(c(r))),r.initBrowser()),r}return i(o,[{key:"initData",value:function(){this.lastCleaningTime=Date.now(),this.kfPosition=[],this.kfCounter=0,this.pendingUnits={},this.remainingData=new Uint8Array,this.startInterval()}},{key:"initBrowser",value:function(){"string"==typeof this.options.node&&""==this.options.node&&g("no video element were found to render, provide a valid video element"),this.node="string"==typeof this.options.node?document.getElementById(this.options.node):this.options.node,this.mseReady=!1,this.setupMSE()}},{key:"createStream",value:function(){var t=this.feed.bind(this),n=this.destroy.bind(this);return this.stream=new e.Duplex({writableObjectMode:!0,read:function(e){},write:function(e,n,r){t(e),r()},final:function(e){n(),e()}}),this.stream}},{key:"setupMSE",value:function(){if(window.MediaSource=window.MediaSource||window.WebKitMediaSource,!window.MediaSource)throw"Oops! Browser does not support media source extension.";this.isMSESupported=!!window.MediaSource,this.mediaSource=new MediaSource,this.url=URL.createObjectURL(this.mediaSource),this.node.src=this.url,this.mseEnded=!1,this.mediaSource.addEventListener("sourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("sourceclose",this.onMSEClose.bind(this)),this.mediaSource.addEventListener("webkitsourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("webkitsourceclose",this.onMSEClose.bind(this))}},{key:"endMSE",value:function(){if(!this.mseEnded)try{this.mseEnded=!0,this.mediaSource.endOfStream()}catch(e){g("mediasource is not available to end")}}},{key:"feed",value:function(e){var t,n,r,i=!1,s={video:[],audio:[]};if(e&&this.remuxController){if(r=e.duration?parseInt(e.duration):0,e.video){e.video=S(this.remainingData,e.video);var a=h(x.extractNALu(e.video),2);if(t=a[0],n=a[1],this.remainingData=n||new Uint8Array,!(t.length>0))return g("Failed to extract any NAL units from video data:",n),void("function"==typeof this.options.onMissingVideoFrames&&this.options.onMissingVideoFrames.call(null,e));s.video=this.getVideoFrames(t,r,e.compositionTimeOffset),i=!0}if(e.audio){if(!((t=this.remuxController.aacParser.extractAAC(e.audio)).length>0))return g("Failed to extract audio data from:",e.audio),void("function"==typeof this.options.onMissingAudioFrames&&this.options.onMissingAudioFrames.call(null,e));s.audio=this.getAudioFrames(t,r),i=!0}i?this.remuxController.remux(s):g("Input object must have video and/or audio property. Make sure it is a valid typed array")}}},{key:"getVideoFrames",value:function(e,t,n){var r,i=this,s=[],a=[],o=0,u=!1,c=!1;this.pendingUnits.units&&(s=this.pendingUnits.units,c=this.pendingUnits.vcl,u=this.pendingUnits.keyFrame,this.pendingUnits={});var f,l=p(e);try{for(l.s();!(f=l.n()).done;){var h=f.value,d=new b(h);d.type()!==b.IDR&&d.type()!==b.NDR||x.parseHeader(d),s.length&&c&&(d.isfmb||!d.isvcl)&&(a.push({units:s,keyFrame:u}),s=[],u=!1,c=!1),s.push(d),u=u||d.isKeyframe(),c=c||d.isvcl}}catch(e){l.e(e)}finally{l.f()}if(s.length)if(t)if(c)a.push({units:s,keyFrame:u});else{var y=a.length-1;y>=0&&(a[y].units=a[y].units.concat(s))}else this.pendingUnits={units:s,keyFrame:u,vcl:c};return r=t?t/a.length|0:this.frameDuration,o=t?t-r*a.length:0,a.map((function(e){e.duration=r,e.compositionTimeOffset=n,o>0&&(e.duration++,o--),i.kfCounter++,e.keyFrame&&i.options.clearBuffer&&i.kfPosition.push(i.kfCounter*r/1e3)})),k("jmuxer: No. of frames of the last chunk: ".concat(a.length)),a}},{key:"getAudioFrames",value:function(e,t){var n,r,i=[],s=0,a=p(e);try{for(a.s();!(r=a.n()).done;){var o=r.value;i.push({units:o})}}catch(e){a.e(e)}finally{a.f()}return n=t?t/i.length|0:this.frameDuration,s=t?t-n*i.length:0,i.map((function(e){e.duration=n,s>0&&(e.duration++,s--)})),i}},{key:"destroy",value:function(){if(this.stopInterval(),this.stream&&(this.remuxController.flush(),this.stream.push(null),this.stream=null),this.remuxController&&(this.remuxController.destroy(),this.remuxController=null),this.bufferControllers){for(var e in this.bufferControllers)this.bufferControllers[e].destroy();this.bufferControllers=null,this.endMSE()}this.node=!1,this.mseReady=!1,this.videoStarted=!1,this.mediaSource=null}},{key:"reset",value:function(){if(this.stopInterval(),this.isReset=!0,this.node.pause(),this.remuxController&&this.remuxController.reset(),this.bufferControllers){for(var e in this.bufferControllers)this.bufferControllers[e].destroy();this.bufferControllers=null,this.endMSE()}this.initData(),"browser"==this.env&&this.initBrowser(),k("JMuxer was reset")}},{key:"createBuffer",value:function(){if(this.mseReady&&this.remuxController&&this.remuxController.isReady()&&!this.bufferControllers)for(var e in this.bufferControllers={},this.remuxController.tracks){var t=this.remuxController.tracks[e];if(!o.isSupported("".concat(e,'/mp4; codecs="').concat(t.mp4track.codec,'"')))return g("Browser does not support codec"),!1;var n=this.mediaSource.addSourceBuffer("".concat(e,'/mp4; codecs="').concat(t.mp4track.codec,'"'));this.bufferControllers[e]=new L(n,e),this.bufferControllers[e].on("error",this.onBufferError.bind(this))}}},{key:"startInterval",value:function(){var e=this;this.interval=setInterval((function(){e.options.flushingTime?e.applyAndClearBuffer():e.bufferControllers&&e.cancelDelay()}),this.options.flushingTime||1e3)}},{key:"stopInterval",value:function(){this.interval&&clearInterval(this.interval)}},{key:"cancelDelay",value:function(){if(this.node.buffered&&this.node.buffered.length>0&&!this.node.seeking){var e=this.node.buffered.end(0);e-this.node.currentTime>this.options.maxDelay/1e3&&(console.log("delay"),this.node.currentTime=e-.001)}}},{key:"releaseBuffer",value:function(){for(var e in this.bufferControllers)this.bufferControllers[e].doAppend()}},{key:"applyAndClearBuffer",value:function(){this.bufferControllers&&(this.releaseBuffer(),this.clearBuffer())}},{key:"getSafeClearOffsetOfBuffer",value:function(e){for(var t,n="audio"===this.options.mode&&e||0,r=0;r<this.kfPosition.length&&!(this.kfPosition[r]>=e);r++)t=this.kfPosition[r];return t&&(this.kfPosition=this.kfPosition.filter((function(e){return e<t&&(n=e),e>=t}))),n}},{key:"clearBuffer",value:function(){if(this.options.clearBuffer&&Date.now()-this.lastCleaningTime>1e4){for(var e in this.bufferControllers){var t=this.getSafeClearOffsetOfBuffer(this.node.currentTime);this.bufferControllers[e].initCleanup(t)}this.lastCleaningTime=Date.now()}}},{key:"onBuffer",value:function(e){this.options.readFpsFromTrack&&void 0!==e.fps&&this.options.fps!=e.fps&&(this.options.fps=e.fps,this.frameDuration=Math.ceil(1e3/e.fps),k("JMuxer changed FPS to ".concat(e.fps," from track data"))),"browser"==this.env?this.bufferControllers&&this.bufferControllers[e.type]&&this.bufferControllers[e.type].feed(e.payload):this.stream&&this.stream.push(e.payload),0===this.options.flushingTime&&this.applyAndClearBuffer()}},{key:"onMSEOpen",value:function(){this.mseReady=!0,URL.revokeObjectURL(this.url),"function"==typeof this.options.onReady&&this.options.onReady.call(null,this.isReset)}},{key:"onMSEClose",value:function(){this.mseReady=!1,this.videoStarted=!1}},{key:"onBufferError",value:function(e){if("QuotaExceeded"==e.name)return k("JMuxer cleaning ".concat(e.type," buffer due to QuotaExceeded error")),void this.bufferControllers[e.type].initCleanup(this.node.currentTime);"InvalidStateError"==e.name?(k("JMuxer is reseting due to InvalidStateError"),this.reset()):this.endMSE(),"function"==typeof this.options.onError&&this.options.onError.call(null,e)}}],[{key:"isSupported",value:function(e){return window.MediaSource&&window.MediaSource.isTypeSupported(e)}}]),o}(U)}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jmuxer",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "jMuxer - a simple javascript mp4 muxer for non-standard streaming communications protocol",
|
|
5
5
|
"main": "dist/jmuxer.min.js",
|
|
6
6
|
"scripts": {
|
|
@@ -35,22 +35,23 @@
|
|
|
35
35
|
"@babel/preset-env": "^7.10.4",
|
|
36
36
|
"@rollup/plugin-babel": "^5.2.1",
|
|
37
37
|
"@rollup/plugin-buble": "^0.21.3",
|
|
38
|
-
"@rollup/plugin-
|
|
39
|
-
"@rollup/plugin-
|
|
38
|
+
"@rollup/plugin-eslint": "^8.0.1",
|
|
39
|
+
"@rollup/plugin-node-resolve": "^13.0.6",
|
|
40
|
+
"@rollup/plugin-replace": "^3.0.0",
|
|
40
41
|
"@rollup/pluginutils": "^4.0.0",
|
|
41
42
|
"caniuse-lite": "^1.0.30001223",
|
|
42
43
|
"chai": "^4.2.0",
|
|
43
|
-
"eslint": "^
|
|
44
|
+
"eslint": "^8.2.0",
|
|
44
45
|
"karma": "^6.3.2",
|
|
45
46
|
"karma-chai": "^0.1.0",
|
|
46
47
|
"karma-chrome-launcher": "^3.1.0",
|
|
47
48
|
"karma-mocha": "^2.0.1",
|
|
48
49
|
"karma-rollup-preprocessor": "^7.0.5",
|
|
49
|
-
"mocha": "^
|
|
50
|
+
"mocha": "^9.1.3",
|
|
51
|
+
"patch-package": "^6.4.7",
|
|
50
52
|
"path": "^0.12.7",
|
|
51
|
-
"rollup": "^2.
|
|
52
|
-
"rollup-plugin-eslint": "^7.0.0",
|
|
53
|
+
"rollup": "^2.59.0",
|
|
53
54
|
"rollup-plugin-terser": "^7.0.2",
|
|
54
|
-
"ws": "^
|
|
55
|
+
"ws": "^8.2.3"
|
|
55
56
|
}
|
|
56
57
|
}
|
package/rollup.config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Rollup plugins
|
|
2
2
|
import babel from '@rollup/plugin-babel';
|
|
3
|
-
import
|
|
3
|
+
import eslint from '@rollup/plugin-eslint';
|
|
4
4
|
import replace from '@rollup/plugin-replace';
|
|
5
5
|
import { terser } from 'rollup-plugin-terser';
|
|
6
6
|
export default {
|
|
@@ -41,6 +41,7 @@ export default {
|
|
|
41
41
|
}),
|
|
42
42
|
replace({
|
|
43
43
|
exclude: 'node_modules/**',
|
|
44
|
+
preventAssignment: true,
|
|
44
45
|
ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
|
|
45
46
|
}),
|
|
46
47
|
(process.env.NODE_ENV === 'production' && terser()),
|
package/src/controller/buffer.js
CHANGED
|
@@ -50,44 +50,48 @@ export default class BufferController extends Event {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
initCleanup(cleanMaxLimit) {
|
|
53
|
-
|
|
54
|
-
this.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
let
|
|
60
|
-
|
|
53
|
+
try {
|
|
54
|
+
if (this.sourceBuffer.updating) {
|
|
55
|
+
this.pendingCleaning = cleanMaxLimit;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (this.sourceBuffer.buffered && this.sourceBuffer.buffered.length && !this.cleaning) {
|
|
59
|
+
for (let i = 0; i < this.sourceBuffer.buffered.length; ++i) {
|
|
60
|
+
let start = this.sourceBuffer.buffered.start(i);
|
|
61
|
+
let end = this.sourceBuffer.buffered.end(i);
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
if ((cleanMaxLimit - start) > this.cleanOffset) {
|
|
64
|
+
end = cleanMaxLimit - this.cleanOffset;
|
|
65
|
+
if (start < end) {
|
|
66
|
+
this.cleanRanges.push([start, end]);
|
|
67
|
+
}
|
|
66
68
|
}
|
|
67
69
|
}
|
|
70
|
+
this.doCleanup();
|
|
68
71
|
}
|
|
69
|
-
|
|
72
|
+
} catch (e) {
|
|
73
|
+
debug.error(`Error occured while cleaning ${this.type} buffer - ${e.name}: ${e.message}`);
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
doAppend() {
|
|
74
78
|
if (!this.queue.length) return;
|
|
75
79
|
|
|
76
|
-
if (this.sourceBuffer.updating)
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
80
|
+
if (!this.sourceBuffer || this.sourceBuffer.updating) return;
|
|
79
81
|
|
|
80
82
|
try {
|
|
81
83
|
this.sourceBuffer.appendBuffer(this.queue);
|
|
82
84
|
this.queue = new Uint8Array();
|
|
83
85
|
} catch (e) {
|
|
86
|
+
let name = 'unexpectedError';
|
|
84
87
|
if (e.name === 'QuotaExceededError') {
|
|
85
88
|
debug.log(`${this.type} buffer quota full`);
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
name = 'QuotaExceeded';
|
|
90
|
+
} else {
|
|
91
|
+
debug.error(`Error occured while appending ${this.type} buffer - ${e.name}: ${e.message}`);
|
|
92
|
+
name = 'InvalidStateError';
|
|
88
93
|
}
|
|
89
|
-
|
|
90
|
-
this.dispatch('error', { type: this.type, name: 'unexpectedError', error: 'buffer error' });
|
|
94
|
+
this.dispatch('error', { type: this.type, name: name, error: 'buffer error' });
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
|
package/src/controller/remux.js
CHANGED
|
@@ -16,6 +16,7 @@ export default class RemuxController extends Event {
|
|
|
16
16
|
this.env = env;
|
|
17
17
|
this.timescale = 1000;
|
|
18
18
|
this.mediaDuration = 0;
|
|
19
|
+
this.aacParser = null;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
addTrack(type) {
|
|
@@ -24,7 +25,9 @@ export default class RemuxController extends Event {
|
|
|
24
25
|
this.trackTypes.push('video');
|
|
25
26
|
}
|
|
26
27
|
if (type === 'audio' || type === 'both') {
|
|
27
|
-
|
|
28
|
+
const aacRemuxer = new AACRemuxer(this.timescale);
|
|
29
|
+
this.aacParser = aacRemuxer.getAacParser();
|
|
30
|
+
this.tracks.audio = aacRemuxer;
|
|
28
31
|
this.trackTypes.push('audio');
|
|
29
32
|
}
|
|
30
33
|
}
|
|
@@ -62,6 +65,9 @@ export default class RemuxController extends Event {
|
|
|
62
65
|
payload: payload,
|
|
63
66
|
dts: track.dts
|
|
64
67
|
};
|
|
68
|
+
if (type === 'video') {
|
|
69
|
+
data.fps = track.mp4track.fps;
|
|
70
|
+
}
|
|
65
71
|
this.dispatch('buffer', data);
|
|
66
72
|
let duration = secToTime(track.dts / this.timescale);
|
|
67
73
|
debug.log(`put segment (${type}): dts: ${track.dts} frames: ${track.mp4track.samples.length} second: ${duration}`);
|
package/src/jmuxer.js
CHANGED
|
@@ -15,15 +15,20 @@ export default class JMuxer extends Event {
|
|
|
15
15
|
|
|
16
16
|
constructor(options) {
|
|
17
17
|
super('jmuxer');
|
|
18
|
+
this.isReset = false;
|
|
18
19
|
let defaults = {
|
|
19
20
|
node: '',
|
|
20
21
|
mode: 'both', // both, audio, video
|
|
21
|
-
flushingTime:
|
|
22
|
+
flushingTime: 500,
|
|
23
|
+
maxDelay: 500,
|
|
22
24
|
clearBuffer: true,
|
|
23
25
|
fps: 30,
|
|
26
|
+
readFpsFromTrack: false, // set true to fetch fps value from NALu
|
|
24
27
|
debug: false,
|
|
25
28
|
onReady: function() {}, // function called when MSE is ready to accept frames
|
|
26
|
-
onError: function() {}, // function called when jmuxer encounters any buffer related
|
|
29
|
+
onError: function() {}, // function called when jmuxer encounters any buffer related errors
|
|
30
|
+
onMissingVideoFrames: function () {}, // function called when jmuxer encounters any missing video frames
|
|
31
|
+
onMissingAudioFrames: function () {}, // function called when jmuxer encounters any missing audio frames
|
|
27
32
|
};
|
|
28
33
|
this.options = Object.assign({}, defaults, options);
|
|
29
34
|
this.env = typeof process === 'object' && typeof window === 'undefined' ? 'node' : 'browser';
|
|
@@ -37,11 +42,8 @@ export default class JMuxer extends Event {
|
|
|
37
42
|
this.frameDuration = (1000 / this.options.fps) | 0;
|
|
38
43
|
this.remuxController = new RemuxController(this.env);
|
|
39
44
|
this.remuxController.addTrack(this.options.mode);
|
|
40
|
-
|
|
41
|
-
this.
|
|
42
|
-
this.kfCounter = 0;
|
|
43
|
-
this.pendingUnits = {};
|
|
44
|
-
this.remainingData = new Uint8Array();
|
|
45
|
+
|
|
46
|
+
this.initData();
|
|
45
47
|
|
|
46
48
|
/* events callback */
|
|
47
49
|
this.remuxController.on('buffer', this.onBuffer.bind(this));
|
|
@@ -49,6 +51,14 @@ export default class JMuxer extends Event {
|
|
|
49
51
|
this.remuxController.on('ready', this.createBuffer.bind(this));
|
|
50
52
|
this.initBrowser();
|
|
51
53
|
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
initData() {
|
|
57
|
+
this.lastCleaningTime = Date.now();
|
|
58
|
+
this.kfPosition = [];
|
|
59
|
+
this.kfCounter = 0;
|
|
60
|
+
this.pendingUnits = {};
|
|
61
|
+
this.remainingData = new Uint8Array();
|
|
52
62
|
this.startInterval();
|
|
53
63
|
}
|
|
54
64
|
|
|
@@ -119,20 +129,34 @@ export default class JMuxer extends Event {
|
|
|
119
129
|
|
|
120
130
|
if (!data || !this.remuxController) return;
|
|
121
131
|
duration = data.duration ? parseInt(data.duration) : 0;
|
|
132
|
+
|
|
122
133
|
if (data.video) {
|
|
123
134
|
data.video = appendByteArray(this.remainingData, data.video);
|
|
124
135
|
[slices, left] = H264Parser.extractNALu(data.video);
|
|
136
|
+
this.remainingData = left || new Uint8Array();
|
|
137
|
+
|
|
125
138
|
if (slices.length > 0) {
|
|
126
|
-
chunks.video = this.getVideoFrames(slices, duration);
|
|
139
|
+
chunks.video = this.getVideoFrames(slices, duration, data.compositionTimeOffset);
|
|
127
140
|
remux = true;
|
|
141
|
+
} else {
|
|
142
|
+
debug.error('Failed to extract any NAL units from video data:', left);
|
|
143
|
+
if (typeof this.options.onMissingVideoFrames === 'function') {
|
|
144
|
+
this.options.onMissingVideoFrames.call(null, data);
|
|
145
|
+
}
|
|
146
|
+
return;
|
|
128
147
|
}
|
|
129
|
-
this.remainingData = left || new Uint8Array();
|
|
130
148
|
}
|
|
131
149
|
if (data.audio) {
|
|
132
|
-
slices =
|
|
150
|
+
slices = this.remuxController.aacParser.extractAAC(data.audio);
|
|
133
151
|
if (slices.length > 0) {
|
|
134
152
|
chunks.audio = this.getAudioFrames(slices, duration);
|
|
135
153
|
remux = true;
|
|
154
|
+
} else {
|
|
155
|
+
debug.error('Failed to extract audio data from:', data.audio);
|
|
156
|
+
if (typeof this.options.onMissingAudioFrames === 'function') {
|
|
157
|
+
this.options.onMissingAudioFrames.call(null, data);
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
136
160
|
}
|
|
137
161
|
}
|
|
138
162
|
if (!remux) {
|
|
@@ -142,7 +166,7 @@ export default class JMuxer extends Event {
|
|
|
142
166
|
this.remuxController.remux(chunks);
|
|
143
167
|
}
|
|
144
168
|
|
|
145
|
-
getVideoFrames(nalus, duration) {
|
|
169
|
+
getVideoFrames(nalus, duration, compositionTimeOffset) {
|
|
146
170
|
let units = [],
|
|
147
171
|
frames = [],
|
|
148
172
|
fd = 0,
|
|
@@ -150,9 +174,9 @@ export default class JMuxer extends Event {
|
|
|
150
174
|
keyFrame = false,
|
|
151
175
|
vcl = false;
|
|
152
176
|
if (this.pendingUnits.units) {
|
|
153
|
-
units
|
|
154
|
-
vcl
|
|
155
|
-
keyFrame
|
|
177
|
+
units = this.pendingUnits.units;
|
|
178
|
+
vcl = this.pendingUnits.vcl;
|
|
179
|
+
keyFrame = this.pendingUnits.keyFrame;
|
|
156
180
|
this.pendingUnits = {};
|
|
157
181
|
}
|
|
158
182
|
for (let nalu of nalus) {
|
|
@@ -189,7 +213,9 @@ export default class JMuxer extends Event {
|
|
|
189
213
|
});
|
|
190
214
|
} else {
|
|
191
215
|
let last = frames.length - 1;
|
|
192
|
-
|
|
216
|
+
if (last >= 0) {
|
|
217
|
+
frames[last].units = frames[last].units.concat(units);
|
|
218
|
+
}
|
|
193
219
|
}
|
|
194
220
|
}
|
|
195
221
|
fd = duration ? duration / frames.length | 0 : this.frameDuration;
|
|
@@ -197,6 +223,7 @@ export default class JMuxer extends Event {
|
|
|
197
223
|
|
|
198
224
|
frames.map((frame) => {
|
|
199
225
|
frame.duration = fd;
|
|
226
|
+
frame.compositionTimeOffset = compositionTimeOffset;
|
|
200
227
|
if (tt > 0) {
|
|
201
228
|
frame.duration++;
|
|
202
229
|
tt--;
|
|
@@ -216,7 +243,7 @@ export default class JMuxer extends Event {
|
|
|
216
243
|
tt = 0;
|
|
217
244
|
|
|
218
245
|
for (let units of aacFrames) {
|
|
219
|
-
frames.push({units});
|
|
246
|
+
frames.push({ units });
|
|
220
247
|
}
|
|
221
248
|
fd = duration ? duration / frames.length | 0 : this.frameDuration;
|
|
222
249
|
tt = duration ? (duration - (fd * frames.length)) : 0;
|
|
@@ -255,6 +282,8 @@ export default class JMuxer extends Event {
|
|
|
255
282
|
}
|
|
256
283
|
|
|
257
284
|
reset() {
|
|
285
|
+
this.stopInterval();
|
|
286
|
+
this.isReset = true;
|
|
258
287
|
this.node.pause();
|
|
259
288
|
if (this.remuxController) {
|
|
260
289
|
this.remuxController.reset();
|
|
@@ -266,6 +295,7 @@ export default class JMuxer extends Event {
|
|
|
266
295
|
this.bufferControllers = null;
|
|
267
296
|
this.endMSE();
|
|
268
297
|
}
|
|
298
|
+
this.initData();
|
|
269
299
|
if (this.env == 'browser') {
|
|
270
300
|
this.initBrowser();
|
|
271
301
|
}
|
|
@@ -288,12 +318,13 @@ export default class JMuxer extends Event {
|
|
|
288
318
|
}
|
|
289
319
|
|
|
290
320
|
startInterval() {
|
|
291
|
-
this.interval = setInterval(()=>{
|
|
292
|
-
if (this.
|
|
293
|
-
this.
|
|
294
|
-
|
|
321
|
+
this.interval = setInterval(() => {
|
|
322
|
+
if (this.options.flushingTime) {
|
|
323
|
+
this.applyAndClearBuffer();
|
|
324
|
+
} else if (this.bufferControllers) {
|
|
325
|
+
this.cancelDelay();
|
|
295
326
|
}
|
|
296
|
-
}, this.options.flushingTime);
|
|
327
|
+
}, this.options.flushingTime || 1000);
|
|
297
328
|
}
|
|
298
329
|
|
|
299
330
|
stopInterval() {
|
|
@@ -302,12 +333,29 @@ export default class JMuxer extends Event {
|
|
|
302
333
|
}
|
|
303
334
|
}
|
|
304
335
|
|
|
336
|
+
cancelDelay() {
|
|
337
|
+
if (this.node.buffered && this.node.buffered.length > 0 && !this.node.seeking) {
|
|
338
|
+
const end = this.node.buffered.end(0);
|
|
339
|
+
if (end - this.node.currentTime > (this.options.maxDelay / 1000)) {
|
|
340
|
+
console.log('delay');
|
|
341
|
+
this.node.currentTime = end - 0.001;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
305
346
|
releaseBuffer() {
|
|
306
347
|
for (let type in this.bufferControllers) {
|
|
307
348
|
this.bufferControllers[type].doAppend();
|
|
308
349
|
}
|
|
309
350
|
}
|
|
310
351
|
|
|
352
|
+
applyAndClearBuffer() {
|
|
353
|
+
if (this.bufferControllers) {
|
|
354
|
+
this.releaseBuffer();
|
|
355
|
+
this.clearBuffer();
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
311
359
|
getSafeClearOffsetOfBuffer(offset) {
|
|
312
360
|
let maxLimit = (this.options.mode === 'audio' && offset) || 0,
|
|
313
361
|
adjacentOffset;
|
|
@@ -318,7 +366,7 @@ export default class JMuxer extends Event {
|
|
|
318
366
|
adjacentOffset = this.kfPosition[i];
|
|
319
367
|
}
|
|
320
368
|
if (adjacentOffset) {
|
|
321
|
-
this.kfPosition = this.kfPosition.filter(
|
|
369
|
+
this.kfPosition = this.kfPosition.filter(kfDelimiter => {
|
|
322
370
|
if (kfDelimiter < adjacentOffset) {
|
|
323
371
|
maxLimit = kfDelimiter;
|
|
324
372
|
}
|
|
@@ -339,23 +387,31 @@ export default class JMuxer extends Event {
|
|
|
339
387
|
}
|
|
340
388
|
|
|
341
389
|
onBuffer(data) {
|
|
390
|
+
if (this.options.readFpsFromTrack && typeof data.fps !== 'undefined' && this.options.fps != data.fps) {
|
|
391
|
+
this.options.fps = data.fps;
|
|
392
|
+
this.frameDuration = Math.ceil(1000 / data.fps);
|
|
393
|
+
debug.log(`JMuxer changed FPS to ${data.fps} from track data`);
|
|
394
|
+
}
|
|
342
395
|
if (this.env == 'browser') {
|
|
343
396
|
if (this.bufferControllers && this.bufferControllers[data.type]) {
|
|
344
397
|
this.bufferControllers[data.type].feed(data.payload);
|
|
345
398
|
}
|
|
346
|
-
} else if(this.stream) {
|
|
399
|
+
} else if (this.stream) {
|
|
347
400
|
this.stream.push(data.payload);
|
|
348
401
|
}
|
|
402
|
+
if (this.options.flushingTime === 0) {
|
|
403
|
+
this.applyAndClearBuffer();
|
|
404
|
+
}
|
|
349
405
|
}
|
|
350
406
|
|
|
351
407
|
/* Events on MSE */
|
|
352
408
|
onMSEOpen() {
|
|
353
409
|
this.mseReady = true;
|
|
410
|
+
URL.revokeObjectURL(this.url);
|
|
411
|
+
// this.createBuffer();
|
|
354
412
|
if (typeof this.options.onReady === 'function') {
|
|
355
|
-
this.options.onReady.call(null);
|
|
413
|
+
this.options.onReady.call(null, this.isReset);
|
|
356
414
|
}
|
|
357
|
-
URL.revokeObjectURL(this.url);
|
|
358
|
-
this.createBuffer();
|
|
359
415
|
}
|
|
360
416
|
|
|
361
417
|
onMSEClose() {
|
|
@@ -365,9 +421,14 @@ export default class JMuxer extends Event {
|
|
|
365
421
|
|
|
366
422
|
onBufferError(data) {
|
|
367
423
|
if (data.name == 'QuotaExceeded') {
|
|
424
|
+
debug.log(`JMuxer cleaning ${data.type} buffer due to QuotaExceeded error`);
|
|
368
425
|
this.bufferControllers[data.type].initCleanup(this.node.currentTime);
|
|
369
426
|
return;
|
|
370
427
|
}
|
|
428
|
+
else if (data.name == 'InvalidStateError') {
|
|
429
|
+
debug.log('JMuxer is reseting due to InvalidStateError');
|
|
430
|
+
this.reset();
|
|
431
|
+
}
|
|
371
432
|
else {
|
|
372
433
|
this.endMSE();
|
|
373
434
|
}
|
package/src/parsers/aac.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import * as debug from '../util/debug';
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
export class AACParser {
|
|
4
4
|
static get samplingRateMap() {
|
|
5
5
|
return [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
static get getAACHeaderData() {
|
|
9
|
-
return aacHeader;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
8
|
static getHeaderLength(data) {
|
|
13
9
|
return (data[1] & 0x01 ? 7 : 9); // without CRC 7 and with CRC 9 Refs: https://wiki.multimedia.cx/index.php?title=ADTS
|
|
14
10
|
}
|
|
@@ -21,7 +17,7 @@ export class AACParser {
|
|
|
21
17
|
return data[0] === 0xff && (data[1] & 0xf0) === 0xf0 && (data[1] & 0x06) === 0x00;
|
|
22
18
|
}
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
extractAAC(buffer) {
|
|
25
21
|
let i = 0,
|
|
26
22
|
length = buffer.byteLength,
|
|
27
23
|
result = [],
|
|
@@ -33,8 +29,8 @@ export class AACParser {
|
|
|
33
29
|
return result;
|
|
34
30
|
}
|
|
35
31
|
headerLength = AACParser.getHeaderLength(buffer);
|
|
36
|
-
if (!aacHeader) {
|
|
37
|
-
aacHeader = buffer.subarray(0, headerLength);
|
|
32
|
+
if (!this.aacHeader) {
|
|
33
|
+
this.aacHeader = buffer.subarray(0, headerLength);
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
while (i < length) {
|
|
@@ -56,7 +52,7 @@ export class AACParser {
|
|
|
56
52
|
sampleIndex,
|
|
57
53
|
channelCount,
|
|
58
54
|
config = new Uint8Array(2),
|
|
59
|
-
headerData =
|
|
55
|
+
headerData = this.aacHeader;
|
|
60
56
|
|
|
61
57
|
if (!headerData) return;
|
|
62
58
|
|