wfs.js 140 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672
  1. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Wfs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
  2. // Copyright Joyent, Inc. and other Node contributors.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a
  5. // copy of this software and associated documentation files (the
  6. // "Software"), to deal in the Software without restriction, including
  7. // without limitation the rights to use, copy, modify, merge, publish,
  8. // distribute, sublicense, and/or sell copies of the Software, and to permit
  9. // persons to whom the Software is furnished to do so, subject to the
  10. // following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included
  13. // in all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  18. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  19. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. function EventEmitter() {
  23. this._events = this._events || {};
  24. this._maxListeners = this._maxListeners || undefined;
  25. }
  26. module.exports = EventEmitter;
  27. // Backwards-compat with node 0.10.x
  28. EventEmitter.EventEmitter = EventEmitter;
  29. EventEmitter.prototype._events = undefined;
  30. EventEmitter.prototype._maxListeners = undefined;
  31. // By default EventEmitters will print a warning if more than 10 listeners are
  32. // added to it. This is a useful default which helps finding memory leaks.
  33. EventEmitter.defaultMaxListeners = 10;
  34. // Obviously not all Emitters should be limited to 10. This function allows
  35. // that to be increased. Set to zero for unlimited.
  36. EventEmitter.prototype.setMaxListeners = function(n) {
  37. if (!isNumber(n) || n < 0 || isNaN(n))
  38. throw TypeError('n must be a positive number');
  39. this._maxListeners = n;
  40. return this;
  41. };
  42. EventEmitter.prototype.emit = function(type) {
  43. var er, handler, len, args, i, listeners;
  44. if (!this._events)
  45. this._events = {};
  46. // If there is no 'error' event listener then throw.
  47. if (type === 'error') {
  48. if (!this._events.error ||
  49. (isObject(this._events.error) && !this._events.error.length)) {
  50. er = arguments[1];
  51. if (er instanceof Error) {
  52. throw er; // Unhandled 'error' event
  53. } else {
  54. // At least give some kind of context to the user
  55. var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
  56. err.context = er;
  57. throw err;
  58. }
  59. }
  60. }
  61. handler = this._events[type];
  62. if (isUndefined(handler))
  63. return false;
  64. if (isFunction(handler)) {
  65. switch (arguments.length) {
  66. // fast cases
  67. case 1:
  68. handler.call(this);
  69. break;
  70. case 2:
  71. handler.call(this, arguments[1]);
  72. break;
  73. case 3:
  74. handler.call(this, arguments[1], arguments[2]);
  75. break;
  76. // slower
  77. default:
  78. args = Array.prototype.slice.call(arguments, 1);
  79. handler.apply(this, args);
  80. }
  81. } else if (isObject(handler)) {
  82. args = Array.prototype.slice.call(arguments, 1);
  83. listeners = handler.slice();
  84. len = listeners.length;
  85. for (i = 0; i < len; i++)
  86. listeners[i].apply(this, args);
  87. }
  88. return true;
  89. };
  90. EventEmitter.prototype.addListener = function(type, listener) {
  91. var m;
  92. if (!isFunction(listener))
  93. throw TypeError('listener must be a function');
  94. if (!this._events)
  95. this._events = {};
  96. // To avoid recursion in the case that type === "newListener"! Before
  97. // adding it to the listeners, first emit "newListener".
  98. if (this._events.newListener)
  99. this.emit('newListener', type,
  100. isFunction(listener.listener) ?
  101. listener.listener : listener);
  102. if (!this._events[type])
  103. // Optimize the case of one listener. Don't need the extra array object.
  104. this._events[type] = listener;
  105. else if (isObject(this._events[type]))
  106. // If we've already got an array, just append.
  107. this._events[type].push(listener);
  108. else
  109. // Adding the second element, need to change to array.
  110. this._events[type] = [this._events[type], listener];
  111. // Check for listener leak
  112. if (isObject(this._events[type]) && !this._events[type].warned) {
  113. if (!isUndefined(this._maxListeners)) {
  114. m = this._maxListeners;
  115. } else {
  116. m = EventEmitter.defaultMaxListeners;
  117. }
  118. if (m && m > 0 && this._events[type].length > m) {
  119. this._events[type].warned = true;
  120. console.error('(node) warning: possible EventEmitter memory ' +
  121. 'leak detected. %d listeners added. ' +
  122. 'Use emitter.setMaxListeners() to increase limit.',
  123. this._events[type].length);
  124. if (typeof console.trace === 'function') {
  125. // not supported in IE 10
  126. console.trace();
  127. }
  128. }
  129. }
  130. return this;
  131. };
  132. EventEmitter.prototype.on = EventEmitter.prototype.addListener;
  133. EventEmitter.prototype.once = function(type, listener) {
  134. if (!isFunction(listener))
  135. throw TypeError('listener must be a function');
  136. var fired = false;
  137. function g() {
  138. this.removeListener(type, g);
  139. if (!fired) {
  140. fired = true;
  141. listener.apply(this, arguments);
  142. }
  143. }
  144. g.listener = listener;
  145. this.on(type, g);
  146. return this;
  147. };
  148. // emits a 'removeListener' event iff the listener was removed
  149. EventEmitter.prototype.removeListener = function(type, listener) {
  150. var list, position, length, i;
  151. if (!isFunction(listener))
  152. throw TypeError('listener must be a function');
  153. if (!this._events || !this._events[type])
  154. return this;
  155. list = this._events[type];
  156. length = list.length;
  157. position = -1;
  158. if (list === listener ||
  159. (isFunction(list.listener) && list.listener === listener)) {
  160. delete this._events[type];
  161. if (this._events.removeListener)
  162. this.emit('removeListener', type, listener);
  163. } else if (isObject(list)) {
  164. for (i = length; i-- > 0;) {
  165. if (list[i] === listener ||
  166. (list[i].listener && list[i].listener === listener)) {
  167. position = i;
  168. break;
  169. }
  170. }
  171. if (position < 0)
  172. return this;
  173. if (list.length === 1) {
  174. list.length = 0;
  175. delete this._events[type];
  176. } else {
  177. list.splice(position, 1);
  178. }
  179. if (this._events.removeListener)
  180. this.emit('removeListener', type, listener);
  181. }
  182. return this;
  183. };
  184. EventEmitter.prototype.removeAllListeners = function(type) {
  185. var key, listeners;
  186. if (!this._events)
  187. return this;
  188. // not listening for removeListener, no need to emit
  189. if (!this._events.removeListener) {
  190. if (arguments.length === 0)
  191. this._events = {};
  192. else if (this._events[type])
  193. delete this._events[type];
  194. return this;
  195. }
  196. // emit removeListener for all listeners on all events
  197. if (arguments.length === 0) {
  198. for (key in this._events) {
  199. if (key === 'removeListener') continue;
  200. this.removeAllListeners(key);
  201. }
  202. this.removeAllListeners('removeListener');
  203. this._events = {};
  204. return this;
  205. }
  206. listeners = this._events[type];
  207. if (isFunction(listeners)) {
  208. this.removeListener(type, listeners);
  209. } else if (listeners) {
  210. // LIFO order
  211. while (listeners.length)
  212. this.removeListener(type, listeners[listeners.length - 1]);
  213. }
  214. delete this._events[type];
  215. return this;
  216. };
  217. EventEmitter.prototype.listeners = function(type) {
  218. var ret;
  219. if (!this._events || !this._events[type])
  220. ret = [];
  221. else if (isFunction(this._events[type]))
  222. ret = [this._events[type]];
  223. else
  224. ret = this._events[type].slice();
  225. return ret;
  226. };
  227. EventEmitter.prototype.listenerCount = function(type) {
  228. if (this._events) {
  229. var evlistener = this._events[type];
  230. if (isFunction(evlistener))
  231. return 1;
  232. else if (evlistener)
  233. return evlistener.length;
  234. }
  235. return 0;
  236. };
  237. EventEmitter.listenerCount = function(emitter, type) {
  238. return emitter.listenerCount(type);
  239. };
  240. function isFunction(arg) {
  241. return typeof arg === 'function';
  242. }
  243. function isNumber(arg) {
  244. return typeof arg === 'number';
  245. }
  246. function isObject(arg) {
  247. return typeof arg === 'object' && arg !== null;
  248. }
  249. function isUndefined(arg) {
  250. return arg === void 0;
  251. }
  252. },{}],2:[function(require,module,exports){
  253. 'use strict';
  254. Object.defineProperty(exports, "__esModule", {
  255. value: true
  256. });
  257. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  258. var _events = require('../events');
  259. var _events2 = _interopRequireDefault(_events);
  260. var _eventHandler = require('../event-handler');
  261. var _eventHandler2 = _interopRequireDefault(_eventHandler);
  262. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  263. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  264. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  265. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
  266. * Buffer Controller
  267. */
  268. var BufferController = function (_EventHandler) {
  269. _inherits(BufferController, _EventHandler);
  270. function BufferController(wfs) {
  271. _classCallCheck(this, BufferController);
  272. var _this = _possibleConstructorReturn(this, (BufferController.__proto__ || Object.getPrototypeOf(BufferController)).call(this, wfs, _events2.default.MEDIA_ATTACHING, _events2.default.BUFFER_APPENDING, _events2.default.BUFFER_RESET));
  273. _this.mediaSource = null;
  274. _this.media = null;
  275. _this.pendingTracks = {};
  276. _this.sourceBuffer = {};
  277. _this.segments = [];
  278. _this.appended = 0;
  279. _this._msDuration = null;
  280. // Source Buffer listeners
  281. _this.onsbue = _this.onSBUpdateEnd.bind(_this);
  282. _this.browserType = 0;
  283. if (navigator.userAgent.toLowerCase().indexOf('firefox') !== -1) {
  284. _this.browserType = 1;
  285. }
  286. _this.mediaType = 'H264Raw';
  287. _this.websocketName = undefined;
  288. _this.channelName = undefined;
  289. return _this;
  290. }
  291. _createClass(BufferController, [{
  292. key: 'destroy',
  293. value: function destroy() {
  294. _eventHandler2.default.prototype.destroy.call(this);
  295. }
  296. }, {
  297. key: 'onMediaAttaching',
  298. value: function onMediaAttaching(data) {
  299. var media = this.media = data.media;
  300. this.mediaType = data.mediaType;
  301. this.websocketName = data.websocketName;
  302. this.channelName = data.channelName;
  303. if (media) {
  304. // setup the media source
  305. var ms = this.mediaSource = new MediaSource();
  306. //Media Source listeners
  307. this.onmso = this.onMediaSourceOpen.bind(this);
  308. this.onmse = this.onMediaSourceEnded.bind(this);
  309. this.onmsc = this.onMediaSourceClose.bind(this);
  310. ms.addEventListener('sourceopen', this.onmso);
  311. ms.addEventListener('sourceended', this.onmse);
  312. ms.addEventListener('sourceclose', this.onmsc);
  313. // link video and media Source
  314. media.src = URL.createObjectURL(ms);
  315. }
  316. }
  317. }, {
  318. key: 'onMediaDetaching',
  319. value: function onMediaDetaching() {}
  320. }, {
  321. key: 'onBufferAppending',
  322. value: function onBufferAppending(data) {
  323. if (!this.segments) {
  324. this.segments = [data];
  325. } else {
  326. this.segments.push(data);
  327. }
  328. this.doAppending();
  329. }
  330. }, {
  331. key: 'onMediaSourceClose',
  332. value: function onMediaSourceClose() {
  333. console.log('media source closed');
  334. }
  335. }, {
  336. key: 'onMediaSourceEnded',
  337. value: function onMediaSourceEnded() {
  338. console.log('media source ended');
  339. }
  340. }, {
  341. key: 'onSBUpdateEnd',
  342. value: function onSBUpdateEnd(event) {
  343. // Firefox
  344. if (this.browserType === 1) {
  345. this.mediaSource.endOfStream();
  346. this.media.play();
  347. }
  348. this.appending = false;
  349. this.doAppending();
  350. this.updateMediaElementDuration();
  351. }
  352. }, {
  353. key: 'updateMediaElementDuration',
  354. value: function updateMediaElementDuration() {}
  355. }, {
  356. key: 'onMediaSourceOpen',
  357. value: function onMediaSourceOpen() {
  358. var mediaSource = this.mediaSource;
  359. if (mediaSource) {
  360. // once received, don't listen anymore to sourceopen event
  361. mediaSource.removeEventListener('sourceopen', this.onmso);
  362. }
  363. if (this.mediaType === 'FMp4') {
  364. this.checkPendingTracks();
  365. }
  366. this.wfs.trigger(_events2.default.MEDIA_ATTACHED, { media: this.media, channelName: this.channelName, mediaType: this.mediaType, websocketName: this.websocketName });
  367. }
  368. }, {
  369. key: 'checkPendingTracks',
  370. value: function checkPendingTracks() {
  371. this.createSourceBuffers({ tracks: 'video', mimeType: '' });
  372. this.pendingTracks = {};
  373. }
  374. }, {
  375. key: 'onBufferReset',
  376. value: function onBufferReset(data) {
  377. if (this.mediaType === 'H264Raw') {
  378. this.createSourceBuffers({ tracks: 'video', mimeType: data.mimeType });
  379. }
  380. }
  381. }, {
  382. key: 'createSourceBuffers',
  383. value: function createSourceBuffers(tracks) {
  384. var sourceBuffer = this.sourceBuffer,
  385. mediaSource = this.mediaSource;
  386. var mimeType = void 0;
  387. if (tracks.mimeType === '') {
  388. mimeType = 'video/mp4;codecs=avc1.420028'; // avc1.42c01f avc1.42801e avc1.640028 avc1.420028
  389. } else {
  390. mimeType = 'video/mp4;codecs=' + tracks.mimeType;
  391. }
  392. try {
  393. var sb = sourceBuffer['video'] = mediaSource.addSourceBuffer(mimeType);
  394. sb.addEventListener('updateend', this.onsbue);
  395. track.buffer = sb;
  396. } catch (err) {}
  397. this.wfs.trigger(_events2.default.BUFFER_CREATED, { tracks: tracks });
  398. this.media.play();
  399. }
  400. }, {
  401. key: 'doAppending',
  402. value: function doAppending() {
  403. var wfs = this.wfs,
  404. sourceBuffer = this.sourceBuffer,
  405. segments = this.segments;
  406. if (Object.keys(sourceBuffer).length) {
  407. if (this.media.error) {
  408. this.segments = [];
  409. console.log('trying to append although a media error occured, flush segment and abort');
  410. return;
  411. }
  412. if (this.appending) {
  413. return;
  414. }
  415. if (segments && segments.length) {
  416. var segment = segments.shift();
  417. try {
  418. if (sourceBuffer[segment.type]) {
  419. this.parent = segment.parent;
  420. sourceBuffer[segment.type].appendBuffer(segment.data);
  421. this.appendError = 0;
  422. this.appended++;
  423. this.appending = true;
  424. } else {}
  425. } catch (err) {
  426. // in case any error occured while appending, put back segment in segments table
  427. segments.unshift(segment);
  428. var event = { type: ErrorTypes.MEDIA_ERROR };
  429. if (err.code !== 22) {
  430. if (this.appendError) {
  431. this.appendError++;
  432. } else {
  433. this.appendError = 1;
  434. }
  435. event.details = ErrorDetails.BUFFER_APPEND_ERROR;
  436. event.frag = this.fragCurrent;
  437. if (this.appendError > wfs.config.appendErrorMaxRetry) {
  438. segments = [];
  439. event.fatal = true;
  440. return;
  441. } else {
  442. event.fatal = false;
  443. }
  444. } else {
  445. this.segments = [];
  446. event.details = ErrorDetails.BUFFER_FULL_ERROR;
  447. return;
  448. }
  449. }
  450. }
  451. }
  452. }
  453. }]);
  454. return BufferController;
  455. }(_eventHandler2.default);
  456. exports.default = BufferController;
  457. },{"../event-handler":7,"../events":8}],3:[function(require,module,exports){
  458. 'use strict';
  459. Object.defineProperty(exports, "__esModule", {
  460. value: true
  461. });
  462. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  463. var _events = require('../events');
  464. var _events2 = _interopRequireDefault(_events);
  465. var _eventHandler = require('../event-handler');
  466. var _eventHandler2 = _interopRequireDefault(_eventHandler);
  467. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  468. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  469. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  470. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
  471. * Flow Controller
  472. */
  473. var FlowController = function (_EventHandler) {
  474. _inherits(FlowController, _EventHandler);
  475. function FlowController(wfs) {
  476. _classCallCheck(this, FlowController);
  477. var _this = _possibleConstructorReturn(this, (FlowController.__proto__ || Object.getPrototypeOf(FlowController)).call(this, wfs, _events2.default.MEDIA_ATTACHED, _events2.default.BUFFER_CREATED, _events2.default.FILE_PARSING_DATA, _events2.default.FILE_HEAD_LOADED, _events2.default.FILE_DATA_LOADED, _events2.default.WEBSOCKET_ATTACHED, _events2.default.FRAG_PARSING_DATA, _events2.default.FRAG_PARSING_INIT_SEGMENT));
  478. _this.fileStart = 0;
  479. _this.fileEnd = 0;
  480. _this.pendingAppending = 0;
  481. _this.mediaType = undefined;
  482. channelName: _this.channelName;
  483. return _this;
  484. }
  485. _createClass(FlowController, [{
  486. key: 'destroy',
  487. value: function destroy() {
  488. _eventHandler2.default.prototype.destroy.call(this);
  489. }
  490. }, {
  491. key: 'onMediaAttached',
  492. value: function onMediaAttached(data) {
  493. if (data.websocketName != undefined) {
  494. // var client = new WebSocket('ws://' + window.location.host + '/' + data.websocketName);
  495. var client = new WebSocket('ws://192.168.11.66:9101');
  496. console.log("open",client);
  497. this.wfs.attachWebsocket(client, data.channelName);
  498. } else {
  499. console.log('websocketName ERROE!!!');
  500. }
  501. }
  502. }, {
  503. key: 'onBufferCreated',
  504. value: function onBufferCreated(data) {
  505. this.mediaType = data.mediaType;
  506. }
  507. }, {
  508. key: 'onFileHeadLoaded',
  509. value: function onFileHeadLoaded(data) {}
  510. }, {
  511. key: 'onFileDataLoaded',
  512. value: function onFileDataLoaded(data) {}
  513. }, {
  514. key: 'onFileParsingData',
  515. value: function onFileParsingData(data) {}
  516. }, {
  517. key: 'onWebsocketAttached',
  518. value: function onWebsocketAttached(data) {
  519. this.wfs.trigger(_events2.default.BUFFER_APPENDING, { type: 'video', data: data.payload, parent: 'main' });
  520. }
  521. }, {
  522. key: 'onFragParsingInitSegment',
  523. value: function onFragParsingInitSegment(data) {
  524. var tracks = data.tracks,
  525. trackName,
  526. track;
  527. track = tracks.video;
  528. if (track) {
  529. track.id = data.id;
  530. }
  531. for (trackName in tracks) {
  532. track = tracks[trackName];
  533. var initSegment = track.initSegment;
  534. if (initSegment) {
  535. this.pendingAppending++;
  536. this.wfs.trigger(_events2.default.BUFFER_APPENDING, { type: trackName, data: initSegment, parent: 'main' });
  537. }
  538. }
  539. }
  540. }, {
  541. key: 'onFragParsingData',
  542. value: function onFragParsingData(data) {
  543. var _this2 = this;
  544. if (data.type === 'video') {}
  545. [data.data1, data.data2].forEach(function (buffer) {
  546. if (buffer) {
  547. _this2.pendingAppending++;
  548. _this2.wfs.trigger(_events2.default.BUFFER_APPENDING, { type: data.type, data: buffer, parent: 'main' });
  549. }
  550. });
  551. }
  552. }]);
  553. return FlowController;
  554. }(_eventHandler2.default);
  555. exports.default = FlowController;
  556. },{"../event-handler":7,"../events":8}],4:[function(require,module,exports){
  557. 'use strict';
  558. Object.defineProperty(exports, "__esModule", {
  559. value: true
  560. });
  561. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
  562. * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.
  563. */
  564. var _logger = require('../utils/logger');
  565. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  566. var ExpGolomb = function () {
  567. function ExpGolomb(data) {
  568. _classCallCheck(this, ExpGolomb);
  569. this.data = data;
  570. // the number of bytes left to examine in this.data
  571. this.bytesAvailable = this.data.byteLength;
  572. // the current word being examined
  573. this.word = 0; // :uint
  574. // the number of bits left to examine in the current word
  575. this.bitsAvailable = 0; // :uint
  576. }
  577. // ():void
  578. _createClass(ExpGolomb, [{
  579. key: 'loadWord',
  580. value: function loadWord() {
  581. var position = this.data.byteLength - this.bytesAvailable,
  582. workingBytes = new Uint8Array(4),
  583. availableBytes = Math.min(4, this.bytesAvailable);
  584. if (availableBytes === 0) {
  585. throw new Error('no bytes available');
  586. }
  587. workingBytes.set(this.data.subarray(position, position + availableBytes));
  588. this.word = new DataView(workingBytes.buffer).getUint32(0);
  589. // track the amount of this.data that has been processed
  590. this.bitsAvailable = availableBytes * 8;
  591. this.bytesAvailable -= availableBytes;
  592. }
  593. // (count:int):void
  594. }, {
  595. key: 'skipBits',
  596. value: function skipBits(count) {
  597. var skipBytes; // :int
  598. if (this.bitsAvailable > count) {
  599. this.word <<= count;
  600. this.bitsAvailable -= count;
  601. } else {
  602. count -= this.bitsAvailable;
  603. skipBytes = count >> 3;
  604. count -= skipBytes >> 3;
  605. this.bytesAvailable -= skipBytes;
  606. this.loadWord();
  607. this.word <<= count;
  608. this.bitsAvailable -= count;
  609. }
  610. }
  611. // (size:int):uint
  612. }, {
  613. key: 'readBits',
  614. value: function readBits(size) {
  615. var bits = Math.min(this.bitsAvailable, size),
  616. // :uint
  617. valu = this.word >>> 32 - bits; // :uint
  618. if (size > 32) {
  619. _logger.logger.error('Cannot read more than 32 bits at a time');
  620. }
  621. this.bitsAvailable -= bits;
  622. if (this.bitsAvailable > 0) {
  623. this.word <<= bits;
  624. } else if (this.bytesAvailable > 0) {
  625. this.loadWord();
  626. }
  627. bits = size - bits;
  628. if (bits > 0) {
  629. return valu << bits | this.readBits(bits);
  630. } else {
  631. return valu;
  632. }
  633. }
  634. // ():uint
  635. }, {
  636. key: 'skipLZ',
  637. value: function skipLZ() {
  638. var leadingZeroCount; // :uint
  639. for (leadingZeroCount = 0; leadingZeroCount < this.bitsAvailable; ++leadingZeroCount) {
  640. if (0 !== (this.word & 0x80000000 >>> leadingZeroCount)) {
  641. // the first bit of working word is 1
  642. this.word <<= leadingZeroCount;
  643. this.bitsAvailable -= leadingZeroCount;
  644. return leadingZeroCount;
  645. }
  646. }
  647. // we exhausted word and still have not found a 1
  648. this.loadWord();
  649. return leadingZeroCount + this.skipLZ();
  650. }
  651. // ():void
  652. }, {
  653. key: 'skipUEG',
  654. value: function skipUEG() {
  655. this.skipBits(1 + this.skipLZ());
  656. }
  657. // ():void
  658. }, {
  659. key: 'skipEG',
  660. value: function skipEG() {
  661. this.skipBits(1 + this.skipLZ());
  662. }
  663. // ():uint
  664. }, {
  665. key: 'readUEG',
  666. value: function readUEG() {
  667. var clz = this.skipLZ(); // :uint
  668. return this.readBits(clz + 1) - 1;
  669. }
  670. // ():int
  671. }, {
  672. key: 'readEG',
  673. value: function readEG() {
  674. var valu = this.readUEG(); // :int
  675. if (0x01 & valu) {
  676. // the number is odd if the low order bit is set
  677. return 1 + valu >>> 1; // add 1 to make it even, and divide by 2
  678. } else {
  679. return -1 * (valu >>> 1); // divide by two then make it negative
  680. }
  681. }
  682. // Some convenience functions
  683. // :Boolean
  684. }, {
  685. key: 'readBoolean',
  686. value: function readBoolean() {
  687. return 1 === this.readBits(1);
  688. }
  689. // ():int
  690. }, {
  691. key: 'readUByte',
  692. value: function readUByte() {
  693. return this.readBits(8);
  694. }
  695. // ():int
  696. }, {
  697. key: 'readUShort',
  698. value: function readUShort() {
  699. return this.readBits(16);
  700. }
  701. // ():int
  702. }, {
  703. key: 'readUInt',
  704. value: function readUInt() {
  705. return this.readBits(32);
  706. }
  707. /**
  708. * Advance the ExpGolomb decoder past a scaling list. The scaling
  709. * list is optionally transmitted as part of a sequence parameter
  710. * set and is not relevant to transmuxing.
  711. * @param count {number} the number of entries in this scaling list
  712. * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
  713. */
  714. }, {
  715. key: 'skipScalingList',
  716. value: function skipScalingList(count) {
  717. var lastScale = 8,
  718. nextScale = 8,
  719. j,
  720. deltaScale;
  721. for (j = 0; j < count; j++) {
  722. if (nextScale !== 0) {
  723. deltaScale = this.readEG();
  724. nextScale = (lastScale + deltaScale + 256) % 256;
  725. }
  726. lastScale = nextScale === 0 ? lastScale : nextScale;
  727. }
  728. }
  729. /**
  730. * Read a sequence parameter set and return some interesting video
  731. * properties. A sequence parameter set is the H264 metadata that
  732. * describes the properties of upcoming video frames.
  733. * @param data {Uint8Array} the bytes of a sequence parameter set
  734. * @return {object} an object with configuration parsed from the
  735. * sequence parameter set, including the dimensions of the
  736. * associated video frames.
  737. */
  738. }, {
  739. key: 'readSPS',
  740. value: function readSPS() {
  741. var frameCropLeftOffset = 0,
  742. frameCropRightOffset = 0,
  743. frameCropTopOffset = 0,
  744. frameCropBottomOffset = 0,
  745. sarScale = 1,
  746. profileIdc,
  747. profileCompat,
  748. levelIdc,
  749. numRefFramesInPicOrderCntCycle,
  750. picWidthInMbsMinus1,
  751. picHeightInMapUnitsMinus1,
  752. frameMbsOnlyFlag,
  753. scalingListCount,
  754. i;
  755. this.readUByte();
  756. profileIdc = this.readUByte(); // profile_idc
  757. profileCompat = this.readBits(5); // constraint_set[0-4]_flag, u(5)
  758. this.skipBits(3); // reserved_zero_3bits u(3),
  759. levelIdc = this.readUByte(); //level_idc u(8)
  760. this.skipUEG(); // seq_parameter_set_id
  761. // some profiles have more optional data we don't need
  762. if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {
  763. var chromaFormatIdc = this.readUEG();
  764. if (chromaFormatIdc === 3) {
  765. this.skipBits(1); // separate_colour_plane_flag
  766. }
  767. this.skipUEG(); // bit_depth_luma_minus8
  768. this.skipUEG(); // bit_depth_chroma_minus8
  769. this.skipBits(1); // qpprime_y_zero_transform_bypass_flag
  770. if (this.readBoolean()) {
  771. // seq_scaling_matrix_present_flag
  772. scalingListCount = chromaFormatIdc !== 3 ? 8 : 12;
  773. for (i = 0; i < scalingListCount; i++) {
  774. if (this.readBoolean()) {
  775. // seq_scaling_list_present_flag[ i ]
  776. if (i < 6) {
  777. this.skipScalingList(16);
  778. } else {
  779. this.skipScalingList(64);
  780. }
  781. }
  782. }
  783. }
  784. }
  785. this.skipUEG(); // log2_max_frame_num_minus4
  786. var picOrderCntType = this.readUEG();
  787. if (picOrderCntType === 0) {
  788. this.readUEG(); //log2_max_pic_order_cnt_lsb_minus4
  789. } else if (picOrderCntType === 1) {
  790. this.skipBits(1); // delta_pic_order_always_zero_flag
  791. this.skipEG(); // offset_for_non_ref_pic
  792. this.skipEG(); // offset_for_top_to_bottom_field
  793. numRefFramesInPicOrderCntCycle = this.readUEG();
  794. for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) {
  795. this.skipEG(); // offset_for_ref_frame[ i ]
  796. }
  797. }
  798. this.skipUEG(); // max_num_ref_frames
  799. this.skipBits(1); // gaps_in_frame_num_value_allowed_flag
  800. picWidthInMbsMinus1 = this.readUEG();
  801. picHeightInMapUnitsMinus1 = this.readUEG();
  802. frameMbsOnlyFlag = this.readBits(1);
  803. if (frameMbsOnlyFlag === 0) {
  804. this.skipBits(1); // mb_adaptive_frame_field_flag
  805. }
  806. this.skipBits(1); // direct_8x8_inference_flag
  807. if (this.readBoolean()) {
  808. // frame_cropping_flag
  809. frameCropLeftOffset = this.readUEG();
  810. frameCropRightOffset = this.readUEG();
  811. frameCropTopOffset = this.readUEG();
  812. frameCropBottomOffset = this.readUEG();
  813. }
  814. if (this.readBoolean()) {
  815. // vui_parameters_present_flag
  816. if (this.readBoolean()) {
  817. // aspect_ratio_info_present_flag
  818. var sarRatio = void 0;
  819. var aspectRatioIdc = this.readUByte();
  820. switch (aspectRatioIdc) {
  821. case 1:
  822. sarRatio = [1, 1];break;
  823. case 2:
  824. sarRatio = [12, 11];break;
  825. case 3:
  826. sarRatio = [10, 11];break;
  827. case 4:
  828. sarRatio = [16, 11];break;
  829. case 5:
  830. sarRatio = [40, 33];break;
  831. case 6:
  832. sarRatio = [24, 11];break;
  833. case 7:
  834. sarRatio = [20, 11];break;
  835. case 8:
  836. sarRatio = [32, 11];break;
  837. case 9:
  838. sarRatio = [80, 33];break;
  839. case 10:
  840. sarRatio = [18, 11];break;
  841. case 11:
  842. sarRatio = [15, 11];break;
  843. case 12:
  844. sarRatio = [64, 33];break;
  845. case 13:
  846. sarRatio = [160, 99];break;
  847. case 14:
  848. sarRatio = [4, 3];break;
  849. case 15:
  850. sarRatio = [3, 2];break;
  851. case 16:
  852. sarRatio = [2, 1];break;
  853. case 255:
  854. {
  855. sarRatio = [this.readUByte() << 8 | this.readUByte(), this.readUByte() << 8 | this.readUByte()];
  856. break;
  857. }
  858. }
  859. if (sarRatio) {
  860. sarScale = sarRatio[0] / sarRatio[1];
  861. }
  862. }
  863. }
  864. return {
  865. width: Math.ceil(((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2) * sarScale),
  866. height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset)
  867. };
  868. }
  869. }, {
  870. key: 'readSliceType',
  871. value: function readSliceType() {
  872. // skip NALu type
  873. this.readUByte();
  874. // discard first_mb_in_slice
  875. this.readUEG();
  876. // return slice_type
  877. return this.readUEG();
  878. }
  879. }]);
  880. return ExpGolomb;
  881. }();
  882. exports.default = ExpGolomb;
  883. },{"../utils/logger":15}],5:[function(require,module,exports){
  884. 'use strict';
  885. Object.defineProperty(exports, "__esModule", {
  886. value: true
  887. });
  888. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  889. var _events = require('../events');
  890. var _events2 = _interopRequireDefault(_events);
  891. var _expGolomb = require('./exp-golomb');
  892. var _expGolomb2 = _interopRequireDefault(_expGolomb);
  893. var _eventHandler = require('../event-handler');
  894. var _eventHandler2 = _interopRequireDefault(_eventHandler);
  895. var _mp4Remuxer = require('../remux/mp4-remuxer');
  896. var _mp4Remuxer2 = _interopRequireDefault(_mp4Remuxer);
  897. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  898. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  899. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  900. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  901. */
  902. var h264Demuxer = function (_EventHandler) {
  903. _inherits(h264Demuxer, _EventHandler);
  904. function h264Demuxer(wfs) {
  905. var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  906. _classCallCheck(this, h264Demuxer);
  907. var _this = _possibleConstructorReturn(this, (h264Demuxer.__proto__ || Object.getPrototypeOf(h264Demuxer)).call(this, wfs, _events2.default.H264_DATA_PARSED));
  908. _this.config = _this.wfs.config || config;
  909. _this.wfs = wfs;
  910. _this.id = 'main';
  911. _this.remuxer = new _mp4Remuxer2.default(_this.wfs, _this.id, _this.config);
  912. _this.contiguous = true;
  913. _this.timeOffset = 1;
  914. _this.sn = 0;
  915. _this.TIMESCALE = 90000;
  916. _this.timestamp = 0;
  917. _this.scaleFactor = _this.TIMESCALE / 1000;
  918. _this.H264_TIMEBASE = 3000;
  919. _this._avcTrack = { container: 'video/mp2t', type: 'video', id: 1, sequenceNumber: 0,
  920. samples: [], len: 0, nbNalu: 0, dropped: 0, count: 0 };
  921. _this.browserType = 0;
  922. if (navigator.userAgent.toLowerCase().indexOf('firefox') !== -1) {
  923. _this.browserType = 1;
  924. }
  925. return _this;
  926. }
  927. _createClass(h264Demuxer, [{
  928. key: 'destroy',
  929. value: function destroy() {
  930. _eventHandler2.default.prototype.destroy.call(this);
  931. }
  932. }, {
  933. key: 'getTimestampM',
  934. value: function getTimestampM() {
  935. this.timestamp += this.H264_TIMEBASE;
  936. return this.timestamp;
  937. }
  938. }, {
  939. key: 'onH264DataParsed',
  940. value: function onH264DataParsed(event) {
  941. this._parseAVCTrack(event.data);
  942. if (this.browserType === 1 || this._avcTrack.samples.length >= 20) {
  943. // Firefox
  944. this.remuxer.pushVideo(0, this.sn, this._avcTrack, this.timeOffset, this.contiguous);
  945. this.sn += 1;
  946. }
  947. }
  948. }, {
  949. key: '_parseAVCTrack',
  950. value: function _parseAVCTrack(array) {
  951. var _this2 = this;
  952. var track = this._avcTrack,
  953. samples = track.samples,
  954. units = this._parseAVCNALu(array),
  955. units2 = [],
  956. debug = false,
  957. key = false,
  958. length = 0,
  959. expGolombDecoder,
  960. avcSample,
  961. push,
  962. i;
  963. var debugString = '';
  964. var pushAccesUnit = function () {
  965. if (units2.length) {
  966. if (!this.config.forceKeyFrameOnDiscontinuity || key === true || track.sps && (samples.length || this.contiguous)) {
  967. var tss = this.getTimestampM();
  968. avcSample = { units: { units: units2, length: length }, pts: tss, dts: tss, key: key };
  969. samples.push(avcSample);
  970. track.len += length;
  971. track.nbNalu += units2.length;
  972. } else {
  973. track.dropped++;
  974. }
  975. units2 = [];
  976. length = 0;
  977. }
  978. }.bind(this);
  979. units.forEach(function (unit) {
  980. switch (unit.type) {
  981. //NDR
  982. case 1:
  983. push = true;
  984. if (debug) {
  985. debugString += 'NDR ';
  986. }
  987. break;
  988. //IDR
  989. case 5:
  990. push = true;
  991. if (debug) {
  992. debugString += 'IDR ';
  993. }
  994. key = true;
  995. break;
  996. //SEI
  997. case 6:
  998. unit.data = _this2.discardEPB(unit.data);
  999. expGolombDecoder = new _expGolomb2.default(unit.data);
  1000. // skip frameType
  1001. expGolombDecoder.readUByte();
  1002. break;
  1003. //SPS
  1004. case 7:
  1005. push = false;
  1006. if (debug) {
  1007. debugString += 'SPS ';
  1008. }
  1009. if (!track.sps) {
  1010. expGolombDecoder = new _expGolomb2.default(unit.data);
  1011. var config = expGolombDecoder.readSPS();
  1012. track.width = config.width;
  1013. track.height = config.height;
  1014. track.sps = [unit.data];
  1015. track.duration = 0;
  1016. var codecarray = unit.data.subarray(1, 4);
  1017. var codecstring = 'avc1.';
  1018. for (i = 0; i < 3; i++) {
  1019. var h = codecarray[i].toString(16);
  1020. if (h.length < 2) {
  1021. h = '0' + h;
  1022. }
  1023. codecstring += h;
  1024. }
  1025. track.codec = codecstring;
  1026. _this2.wfs.trigger(_events2.default.BUFFER_RESET, { mimeType: track.codec });
  1027. push = true;
  1028. }
  1029. break;
  1030. //PPS
  1031. case 8:
  1032. push = false;
  1033. if (debug) {
  1034. debugString += 'PPS ';
  1035. }
  1036. if (!track.pps) {
  1037. track.pps = [unit.data];
  1038. push = true;
  1039. }
  1040. break;
  1041. case 9:
  1042. push = false;
  1043. if (debug) {
  1044. debugString += 'AUD ';
  1045. }
  1046. pushAccesUnit();
  1047. break;
  1048. default:
  1049. push = false;
  1050. debugString += 'unknown NAL ' + unit.type + ' ';
  1051. break;
  1052. }
  1053. if (push) {
  1054. units2.push(unit);
  1055. length += unit.data.byteLength;
  1056. }
  1057. });
  1058. if (debug || debugString.length) {
  1059. logger.log(debugString);
  1060. }
  1061. pushAccesUnit();
  1062. }
  1063. }, {
  1064. key: '_parseAVCNALu',
  1065. value: function _parseAVCNALu(array) {
  1066. var i = 0,
  1067. len = array.byteLength,
  1068. value,
  1069. overflow,
  1070. state = 0; //state = this.avcNaluState;
  1071. var units = [],
  1072. unit,
  1073. unitType,
  1074. lastUnitStart,
  1075. lastUnitType;
  1076. while (i < len) {
  1077. value = array[i++];
  1078. // finding 3 or 4-byte start codes (00 00 01 OR 00 00 00 01)
  1079. switch (state) {
  1080. case 0:
  1081. if (value === 0) {
  1082. state = 1;
  1083. }
  1084. break;
  1085. case 1:
  1086. if (value === 0) {
  1087. state = 2;
  1088. } else {
  1089. state = 0;
  1090. }
  1091. break;
  1092. case 2:
  1093. case 3:
  1094. if (value === 0) {
  1095. state = 3;
  1096. } else if (value === 1 && i < len) {
  1097. unitType = array[i] & 0x1f;
  1098. if (lastUnitStart) {
  1099. unit = { data: array.subarray(lastUnitStart, i - state - 1), type: lastUnitType };
  1100. units.push(unit);
  1101. } else {}
  1102. lastUnitStart = i;
  1103. lastUnitType = unitType;
  1104. state = 0;
  1105. } else {
  1106. state = 0;
  1107. }
  1108. break;
  1109. default:
  1110. break;
  1111. }
  1112. }
  1113. if (lastUnitStart) {
  1114. unit = { data: array.subarray(lastUnitStart, len), type: lastUnitType, state: state };
  1115. units.push(unit);
  1116. }
  1117. return units;
  1118. }
  1119. /**
  1120. * remove Emulation Prevention bytes from a RBSP
  1121. */
  1122. }, {
  1123. key: 'discardEPB',
  1124. value: function discardEPB(data) {
  1125. var length = data.byteLength,
  1126. EPBPositions = [],
  1127. i = 1,
  1128. newLength,
  1129. newData;
  1130. // Find all `Emulation Prevention Bytes`
  1131. while (i < length - 2) {
  1132. if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0x03) {
  1133. EPBPositions.push(i + 2);
  1134. i += 2;
  1135. } else {
  1136. i++;
  1137. }
  1138. }
  1139. // If no Emulation Prevention Bytes were found just return the original
  1140. // array
  1141. if (EPBPositions.length === 0) {
  1142. return data;
  1143. }
  1144. // Create a new array to hold the NAL unit data
  1145. newLength = length - EPBPositions.length;
  1146. newData = new Uint8Array(newLength);
  1147. var sourceIndex = 0;
  1148. for (i = 0; i < newLength; sourceIndex++, i++) {
  1149. if (sourceIndex === EPBPositions[0]) {
  1150. // Skip this byte
  1151. sourceIndex++;
  1152. // Remove this position index
  1153. EPBPositions.shift();
  1154. }
  1155. newData[i] = data[sourceIndex];
  1156. }
  1157. return newData;
  1158. }
  1159. }]);
  1160. return h264Demuxer;
  1161. }(_eventHandler2.default);
  1162. exports.default = h264Demuxer;
  1163. },{"../event-handler":7,"../events":8,"../remux/mp4-remuxer":13,"./exp-golomb":4}],6:[function(require,module,exports){
  1164. 'use strict';
  1165. Object.defineProperty(exports, "__esModule", {
  1166. value: true
  1167. });
  1168. var ErrorTypes = exports.ErrorTypes = {
  1169. // Identifier for a network error (loading error / timeout ...)
  1170. NETWORK_ERROR: 'networkError',
  1171. // Identifier for a media Error (video/parsing/mediasource error)
  1172. MEDIA_ERROR: 'mediaError',
  1173. // Identifier for all other errors
  1174. OTHER_ERROR: 'otherError'
  1175. };
  1176. var ErrorDetails = exports.ErrorDetails = {
  1177. // Identifier for a manifest load error - data: { url : faulty URL, response : { code: error code, text: error text }}
  1178. MANIFEST_LOAD_ERROR: 'manifestLoadError',
  1179. // Identifier for a manifest load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}
  1180. MANIFEST_LOAD_TIMEOUT: 'manifestLoadTimeOut',
  1181. // Identifier for a manifest parsing error - data: { url : faulty URL, reason : error reason}
  1182. MANIFEST_PARSING_ERROR: 'manifestParsingError',
  1183. // Identifier for a manifest with only incompatible codecs error - data: { url : faulty URL, reason : error reason}
  1184. MANIFEST_INCOMPATIBLE_CODECS_ERROR: 'manifestIncompatibleCodecsError',
  1185. // Identifier for a level load error - data: { url : faulty URL, response : { code: error code, text: error text }}
  1186. LEVEL_LOAD_ERROR: 'levelLoadError',
  1187. // Identifier for a level load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}
  1188. LEVEL_LOAD_TIMEOUT: 'levelLoadTimeOut',
  1189. // Identifier for a level switch error - data: { level : faulty level Id, event : error description}
  1190. LEVEL_SWITCH_ERROR: 'levelSwitchError',
  1191. // Identifier for an audio track load error - data: { url : faulty URL, response : { code: error code, text: error text }}
  1192. AUDIO_TRACK_LOAD_ERROR: 'audioTrackLoadError',
  1193. // Identifier for an audio track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}
  1194. AUDIO_TRACK_LOAD_TIMEOUT: 'audioTrackLoadTimeOut',
  1195. // Identifier for fragment load error - data: { frag : fragment object, response : { code: error code, text: error text }}
  1196. FRAG_LOAD_ERROR: 'fragLoadError',
  1197. // Identifier for fragment loop loading error - data: { frag : fragment object}
  1198. FRAG_LOOP_LOADING_ERROR: 'fragLoopLoadingError',
  1199. // Identifier for fragment load timeout error - data: { frag : fragment object}
  1200. FRAG_LOAD_TIMEOUT: 'fragLoadTimeOut',
  1201. // Identifier for a fragment decryption error event - data: parsing error description
  1202. FRAG_DECRYPT_ERROR: 'fragDecryptError',
  1203. // Identifier for a fragment parsing error event - data: parsing error description
  1204. FRAG_PARSING_ERROR: 'fragParsingError',
  1205. // Identifier for decrypt key load error - data: { frag : fragment object, response : { code: error code, text: error text }}
  1206. KEY_LOAD_ERROR: 'keyLoadError',
  1207. // Identifier for decrypt key load timeout error - data: { frag : fragment object}
  1208. KEY_LOAD_TIMEOUT: 'keyLoadTimeOut',
  1209. // Triggered when an exception occurs while adding a sourceBuffer to MediaSource - data : { err : exception , mimeType : mimeType }
  1210. BUFFER_ADD_CODEC_ERROR: 'bufferAddCodecError',
  1211. // Identifier for a buffer append error - data: append error description
  1212. BUFFER_APPEND_ERROR: 'bufferAppendError',
  1213. // Identifier for a buffer appending error event - data: appending error description
  1214. BUFFER_APPENDING_ERROR: 'bufferAppendingError',
  1215. // Identifier for a buffer stalled error event
  1216. BUFFER_STALLED_ERROR: 'bufferStalledError',
  1217. // Identifier for a buffer full event
  1218. BUFFER_FULL_ERROR: 'bufferFullError',
  1219. // Identifier for a buffer seek over hole event
  1220. BUFFER_SEEK_OVER_HOLE: 'bufferSeekOverHole',
  1221. // Identifier for an internal exception happening inside hls.js while handling an event
  1222. INTERNAL_EXCEPTION: 'internalException'
  1223. };
  1224. },{}],7:[function(require,module,exports){
  1225. 'use strict';
  1226. Object.defineProperty(exports, "__esModule", {
  1227. value: true
  1228. });
  1229. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  1230. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
  1231. *
  1232. * All objects in the event handling chain should inherit from this class
  1233. *
  1234. */
  1235. var _events = require('./events');
  1236. var _events2 = _interopRequireDefault(_events);
  1237. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  1238. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1239. var EventHandler = function () {
  1240. function EventHandler(wfs) {
  1241. _classCallCheck(this, EventHandler);
  1242. this.wfs = wfs;
  1243. this.onEvent = this.onEvent.bind(this);
  1244. for (var _len = arguments.length, events = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  1245. events[_key - 1] = arguments[_key];
  1246. }
  1247. this.handledEvents = events;
  1248. this.useGenericHandler = true;
  1249. this.registerListeners();
  1250. }
  1251. _createClass(EventHandler, [{
  1252. key: 'destroy',
  1253. value: function destroy() {
  1254. this.unregisterListeners();
  1255. }
  1256. }, {
  1257. key: 'isEventHandler',
  1258. value: function isEventHandler() {
  1259. return _typeof(this.handledEvents) === 'object' && this.handledEvents.length && typeof this.onEvent === 'function';
  1260. }
  1261. }, {
  1262. key: 'registerListeners',
  1263. value: function registerListeners() {
  1264. if (this.isEventHandler()) {
  1265. this.handledEvents.forEach(function (event) {
  1266. if (event === 'wfsEventGeneric') {
  1267. //throw new Error('Forbidden event name: ' + event);
  1268. }
  1269. this.wfs.on(event, this.onEvent);
  1270. }.bind(this));
  1271. }
  1272. }
  1273. }, {
  1274. key: 'unregisterListeners',
  1275. value: function unregisterListeners() {
  1276. if (this.isEventHandler()) {
  1277. this.handledEvents.forEach(function (event) {
  1278. this.wfs.off(event, this.onEvent);
  1279. }.bind(this));
  1280. }
  1281. }
  1282. /**
  1283. * arguments: event (string), data (any)
  1284. */
  1285. }, {
  1286. key: 'onEvent',
  1287. value: function onEvent(event, data) {
  1288. this.onEventGeneric(event, data);
  1289. }
  1290. }, {
  1291. key: 'onEventGeneric',
  1292. value: function onEventGeneric(event, data) {
  1293. var eventToFunction = function eventToFunction(event, data) {
  1294. var funcName = 'on' + event.replace('wfs', '');
  1295. if (typeof this[funcName] !== 'function') {
  1296. //throw new Error(`Event ${event} has no generic handler in this ${this.constructor.name} class (tried ${funcName})`);
  1297. }
  1298. return this[funcName].bind(this, data);
  1299. };
  1300. try {
  1301. eventToFunction.call(this, event, data).call();
  1302. } catch (err) {
  1303. console.log('internal error happened while processing ' + event + ':' + err.message);
  1304. // this.hls.trigger(Event.ERROR, {type: ErrorTypes.OTHER_ERROR, details: ErrorDetails.INTERNAL_EXCEPTION, fatal: false, event : event, err : err});
  1305. }
  1306. }
  1307. }]);
  1308. return EventHandler;
  1309. }();
  1310. exports.default = EventHandler;
  1311. },{"./events":8}],8:[function(require,module,exports){
  1312. 'use strict';
  1313. module.exports = {
  1314. MEDIA_ATTACHING: 'wfsMediaAttaching',
  1315. MEDIA_ATTACHED: 'wfsMediaAttached',
  1316. FRAG_LOADING: 'wfsFragLoading',
  1317. BUFFER_CREATED: 'wfsBufferCreated',
  1318. BUFFER_APPENDING: 'wfsBufferAppending',
  1319. BUFFER_RESET: 'wfsBufferReset',
  1320. FRAG_PARSING_DATA: 'wfsFragParsingData',
  1321. FRAG_PARSING_INIT_SEGMENT: 'wfsFragParsingInitSegment',
  1322. //------------------------------------------
  1323. H264_DATA_PARSING: 'wfsH264DataParsing',
  1324. H264_DATA_PARSED: 'wfsH264DataParsed',
  1325. //------------------------------------------
  1326. WEBSOCKET_ATTACHED: 'wfsWebsocketAttached',
  1327. WEBSOCKET_ATTACHING: 'wfsWebsocketAttaching',
  1328. WEBSOCKET_DATA_UPLOADING: 'wfsWebsocketDataUploading',
  1329. WEBSOCKET_MESSAGE_SENDING: 'wfsWebsocketMessageSending',
  1330. //------------------------------------------
  1331. FILE_HEAD_LOADING: 'wfsFileHeadLoading',
  1332. FILE_HEAD_LOADED: 'wfsFileHeadLoaded',
  1333. FILE_DATA_LOADING: 'wfsFileDataLoading',
  1334. FILE_DATA_LOADED: 'wfsFileDataLoaded',
  1335. FILE_PARSING_DATA: 'wfsFileParsingData'
  1336. //------------------------------------------
  1337. };
  1338. },{}],9:[function(require,module,exports){
  1339. "use strict";
  1340. Object.defineProperty(exports, "__esModule", {
  1341. value: true
  1342. });
  1343. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  1344. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1345. /**
  1346. * AAC helper
  1347. */
  1348. var AAC = function () {
  1349. function AAC() {
  1350. _classCallCheck(this, AAC);
  1351. }
  1352. _createClass(AAC, null, [{
  1353. key: "getSilentFrame",
  1354. value: function getSilentFrame(channelCount) {
  1355. if (channelCount === 1) {
  1356. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);
  1357. } else if (channelCount === 2) {
  1358. return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);
  1359. } else if (channelCount === 3) {
  1360. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);
  1361. } else if (channelCount === 4) {
  1362. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);
  1363. } else if (channelCount === 5) {
  1364. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);
  1365. } else if (channelCount === 6) {
  1366. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);
  1367. }
  1368. return null;
  1369. }
  1370. }]);
  1371. return AAC;
  1372. }();
  1373. exports.default = AAC;
  1374. },{}],10:[function(require,module,exports){
  1375. 'use strict';
  1376. // This is mostly for support of the es6 module export
  1377. // syntax with the babel compiler, it looks like it doesnt support
  1378. // function exports like we are used to in node/commonjs
  1379. module.exports = require('./wfs.js').default;
  1380. },{"./wfs.js":18}],11:[function(require,module,exports){
  1381. 'use strict';
  1382. Object.defineProperty(exports, "__esModule", {
  1383. value: true
  1384. });
  1385. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  1386. var _events = require('../events');
  1387. var _events2 = _interopRequireDefault(_events);
  1388. var _eventHandler = require('../event-handler');
  1389. var _eventHandler2 = _interopRequireDefault(_eventHandler);
  1390. var _h264NalSlicesreader = require('../utils/h264-nal-slicesreader.js');
  1391. var _h264NalSlicesreader2 = _interopRequireDefault(_h264NalSlicesreader);
  1392. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  1393. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1394. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  1395. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
  1396. * Websocket Loader
  1397. */
  1398. var WebsocketLoader = function (_EventHandler) {
  1399. _inherits(WebsocketLoader, _EventHandler);
  1400. function WebsocketLoader(wfs) {
  1401. _classCallCheck(this, WebsocketLoader);
  1402. var _this = _possibleConstructorReturn(this, (WebsocketLoader.__proto__ || Object.getPrototypeOf(WebsocketLoader)).call(this, wfs, _events2.default.WEBSOCKET_ATTACHING, _events2.default.WEBSOCKET_DATA_UPLOADING, _events2.default.WEBSOCKET_MESSAGE_SENDING));
  1403. _this.buf = null;
  1404. _this.slicesReader = new _h264NalSlicesreader2.default(wfs);
  1405. _this.mediaType = undefined;
  1406. _this.channelName = undefined;
  1407. return _this;
  1408. }
  1409. _createClass(WebsocketLoader, [{
  1410. key: 'destroy',
  1411. value: function destroy() {
  1412. !!this.client && this.client.close();
  1413. this.slicesReader.destroy();
  1414. _eventHandler2.default.prototype.destroy.call(this);
  1415. }
  1416. }, {
  1417. key: 'onWebsocketAttaching',
  1418. value: function onWebsocketAttaching(data) {
  1419. this.mediaType = data.mediaType;
  1420. this.channelName = data.channelName;
  1421. if (data.websocket instanceof WebSocket) {
  1422. this.client = data.websocket;
  1423. this.client.onopen = this.initSocketClient.bind(this);
  1424. this.client.onclose = function (e) {
  1425. console.log('Websocket Disconnected!');
  1426. };
  1427. }
  1428. }
  1429. }, {
  1430. key: 'initSocketClient',
  1431. value: function initSocketClient(client) {
  1432. this.client.binaryType = 'arraybuffer';
  1433. this.client.onmessage = this.receiveSocketMessage.bind(this);
  1434. this.wfs.trigger(_events2.default.WEBSOCKET_MESSAGE_SENDING, { commandType: "open", channelName: this.channelName, commandValue: "NA" });
  1435. console.log('Websocket Open!');
  1436. }
  1437. }, {
  1438. key: 'receiveSocketMessage',
  1439. value: function receiveSocketMessage(event) {
  1440. this.buf = new Uint8Array(event.data);
  1441. var copy = new Uint8Array(this.buf);
  1442. if (this.mediaType === 'FMp4') {
  1443. this.wfs.trigger(_events2.default.WEBSOCKET_ATTACHED, { payload: copy });
  1444. }
  1445. if (this.mediaType === 'H264Raw') {
  1446. this.wfs.trigger(_events2.default.H264_DATA_PARSING, { data: copy });
  1447. }
  1448. }
  1449. }, {
  1450. key: 'onWebsocketDataUploading',
  1451. value: function onWebsocketDataUploading(event) {
  1452. this.client.send(event.data);
  1453. }
  1454. }, {
  1455. key: 'onWebsocketMessageSending',
  1456. value: function onWebsocketMessageSending(event) {
  1457. this.client.send(JSON.stringify({ t: event.commandType, c: event.channelName, v: event.commandValue }));
  1458. }
  1459. }]);
  1460. return WebsocketLoader;
  1461. }(_eventHandler2.default);
  1462. exports.default = WebsocketLoader;
  1463. },{"../event-handler":7,"../events":8,"../utils/h264-nal-slicesreader.js":14}],12:[function(require,module,exports){
  1464. 'use strict';
  1465. Object.defineProperty(exports, "__esModule", {
  1466. value: true
  1467. });
  1468. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  1469. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1470. /**
  1471. * Generate MP4 Box
  1472. */
  1473. //import Hex from '../utils/hex';
  1474. var MP4 = function () {
  1475. function MP4() {
  1476. _classCallCheck(this, MP4);
  1477. }
  1478. _createClass(MP4, null, [{
  1479. key: 'init',
  1480. value: function init() {
  1481. MP4.types = {
  1482. avc1: [], // codingname
  1483. avcC: [],
  1484. btrt: [],
  1485. dinf: [],
  1486. dref: [],
  1487. esds: [],
  1488. ftyp: [],
  1489. hdlr: [],
  1490. mdat: [],
  1491. mdhd: [],
  1492. mdia: [],
  1493. mfhd: [],
  1494. minf: [],
  1495. moof: [],
  1496. moov: [],
  1497. mp4a: [],
  1498. mvex: [],
  1499. mvhd: [],
  1500. sdtp: [],
  1501. stbl: [],
  1502. stco: [],
  1503. stsc: [],
  1504. stsd: [],
  1505. stsz: [],
  1506. stts: [],
  1507. tfdt: [],
  1508. tfhd: [],
  1509. traf: [],
  1510. trak: [],
  1511. trun: [],
  1512. trex: [],
  1513. tkhd: [],
  1514. vmhd: [],
  1515. smhd: []
  1516. };
  1517. var i;
  1518. for (i in MP4.types) {
  1519. if (MP4.types.hasOwnProperty(i)) {
  1520. MP4.types[i] = [i.charCodeAt(0), i.charCodeAt(1), i.charCodeAt(2), i.charCodeAt(3)];
  1521. }
  1522. }
  1523. var videoHdlr = new Uint8Array([0x00, // version 0
  1524. 0x00, 0x00, 0x00, // flags
  1525. 0x00, 0x00, 0x00, 0x00, // pre_defined
  1526. 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'
  1527. 0x00, 0x00, 0x00, 0x00, // reserved
  1528. 0x00, 0x00, 0x00, 0x00, // reserved
  1529. 0x00, 0x00, 0x00, 0x00, // reserved
  1530. 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'VideoHandler'
  1531. ]);
  1532. var audioHdlr = new Uint8Array([0x00, // version 0
  1533. 0x00, 0x00, 0x00, // flags
  1534. 0x00, 0x00, 0x00, 0x00, // pre_defined
  1535. 0x73, 0x6f, 0x75, 0x6e, // handler_type: 'soun'
  1536. 0x00, 0x00, 0x00, 0x00, // reserved
  1537. 0x00, 0x00, 0x00, 0x00, // reserved
  1538. 0x00, 0x00, 0x00, 0x00, // reserved
  1539. 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'SoundHandler'
  1540. ]);
  1541. MP4.HDLR_TYPES = {
  1542. 'video': videoHdlr,
  1543. 'audio': audioHdlr
  1544. };
  1545. var dref = new Uint8Array([0x00, // version 0
  1546. 0x00, 0x00, 0x00, // flags
  1547. 0x00, 0x00, 0x00, 0x01, // entry_count
  1548. 0x00, 0x00, 0x00, 0x0c, // entry_size
  1549. 0x75, 0x72, 0x6c, 0x20, // 'url' type
  1550. 0x00, // version 0
  1551. 0x00, 0x00, 0x01 // entry_flags
  1552. ]);
  1553. var stco = new Uint8Array([0x00, // version
  1554. 0x00, 0x00, 0x00, // flags
  1555. 0x00, 0x00, 0x00, 0x00 // entry_count
  1556. ]);
  1557. MP4.STTS = MP4.STSC = MP4.STCO = stco;
  1558. MP4.STSZ = new Uint8Array([0x00, // version
  1559. 0x00, 0x00, 0x00, // flags
  1560. 0x00, 0x00, 0x00, 0x00, // sample_size
  1561. 0x00, 0x00, 0x00, 0x00]);
  1562. MP4.VMHD = new Uint8Array([0x00, // version
  1563. 0x00, 0x00, 0x01, // flags
  1564. 0x00, 0x00, // graphicsmode
  1565. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // opcolor
  1566. ]);
  1567. MP4.SMHD = new Uint8Array([0x00, // version
  1568. 0x00, 0x00, 0x00, // flags
  1569. 0x00, 0x00, // balance
  1570. 0x00, 0x00 // reserved
  1571. ]);
  1572. MP4.STSD = new Uint8Array([0x00, // version 0
  1573. 0x00, 0x00, 0x00, // flags
  1574. 0x00, 0x00, 0x00, 0x01]); // entry_count
  1575. var majorBrand = new Uint8Array([105, 115, 111, 109]); // isom
  1576. var avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1
  1577. var minorVersion = new Uint8Array([0, 0, 0, 1]);
  1578. MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand);
  1579. MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));
  1580. }
  1581. }, {
  1582. key: 'box',
  1583. value: function box(type) {
  1584. var payload = Array.prototype.slice.call(arguments, 1),
  1585. size = 8,
  1586. i = payload.length,
  1587. len = i,
  1588. result;
  1589. // calculate the total size we need to allocate
  1590. while (i--) {
  1591. size += payload[i].byteLength;
  1592. }
  1593. result = new Uint8Array(size);
  1594. result[0] = size >> 24 & 0xff;
  1595. result[1] = size >> 16 & 0xff;
  1596. result[2] = size >> 8 & 0xff;
  1597. result[3] = size & 0xff;
  1598. result.set(type, 4);
  1599. // copy the payload into the result
  1600. for (i = 0, size = 8; i < len; i++) {
  1601. // copy payload[i] array @ offset size
  1602. result.set(payload[i], size);
  1603. size += payload[i].byteLength;
  1604. }
  1605. return result;
  1606. }
  1607. }, {
  1608. key: 'hdlr',
  1609. value: function hdlr(type) {
  1610. return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);
  1611. }
  1612. }, {
  1613. key: 'mdat',
  1614. value: function mdat(data) {
  1615. // console.log( "mdat==> ",data.length );
  1616. return MP4.box(MP4.types.mdat, data);
  1617. }
  1618. }, {
  1619. key: 'mdhd',
  1620. value: function mdhd(timescale, duration) {
  1621. duration *= timescale;
  1622. return MP4.box(MP4.types.mdhd, new Uint8Array([0x00, // version 0
  1623. 0x00, 0x00, 0x00, // flags
  1624. 0x00, 0x00, 0x00, 0x02, // creation_time
  1625. 0x00, 0x00, 0x00, 0x03, // modification_time
  1626. timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale
  1627. duration >> 24, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
  1628. 0x55, 0xc4, // 'und' language (undetermined)
  1629. 0x00, 0x00]));
  1630. }
  1631. }, {
  1632. key: 'mdia',
  1633. value: function mdia(track) {
  1634. return MP4.box(MP4.types.mdia, MP4.mdhd(track.timescale, track.duration), MP4.hdlr(track.type), MP4.minf(track));
  1635. }
  1636. }, {
  1637. key: 'mfhd',
  1638. value: function mfhd(sequenceNumber) {
  1639. return MP4.box(MP4.types.mfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // flags
  1640. sequenceNumber >> 24, sequenceNumber >> 16 & 0xFF, sequenceNumber >> 8 & 0xFF, sequenceNumber & 0xFF]) // sequence_number
  1641. );
  1642. }
  1643. }, {
  1644. key: 'minf',
  1645. value: function minf(track) {
  1646. if (track.type === 'audio') {
  1647. return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track));
  1648. } else {
  1649. return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track));
  1650. }
  1651. }
  1652. }, {
  1653. key: 'moof',
  1654. value: function moof(sn, baseMediaDecodeTime, track) {
  1655. return MP4.box(MP4.types.moof, MP4.mfhd(sn), MP4.traf(track, baseMediaDecodeTime));
  1656. }
  1657. /**
  1658. * @param tracks... (optional) {array} the tracks associated with this movie
  1659. */
  1660. }, {
  1661. key: 'moov',
  1662. value: function moov(tracks) {
  1663. var i = tracks.length,
  1664. boxes = [];
  1665. while (i--) {
  1666. boxes[i] = MP4.trak(tracks[i]);
  1667. }
  1668. return MP4.box.apply(null, [MP4.types.moov, MP4.mvhd(tracks[0].timescale, tracks[0].duration)].concat(boxes).concat(MP4.mvex(tracks)));
  1669. }
  1670. }, {
  1671. key: 'mvex',
  1672. value: function mvex(tracks) {
  1673. var i = tracks.length,
  1674. boxes = [];
  1675. while (i--) {
  1676. boxes[i] = MP4.trex(tracks[i]);
  1677. }
  1678. return MP4.box.apply(null, [MP4.types.mvex].concat(boxes));
  1679. }
  1680. }, {
  1681. key: 'mvhd',
  1682. value: function mvhd(timescale, duration) {
  1683. duration *= timescale;
  1684. var bytes = new Uint8Array([0x00, // version 0
  1685. 0x00, 0x00, 0x00, // flags
  1686. 0x00, 0x00, 0x00, 0x01, // creation_time
  1687. 0x00, 0x00, 0x00, 0x02, // modification_time
  1688. timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale
  1689. duration >> 24 & 0xFF, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
  1690. 0x00, 0x01, 0x00, 0x00, // 1.0 rate
  1691. 0x01, 0x00, // 1.0 volume
  1692. 0x00, 0x00, // reserved
  1693. 0x00, 0x00, 0x00, 0x00, // reserved
  1694. 0x00, 0x00, 0x00, 0x00, // reserved
  1695. 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
  1696. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
  1697. 0xff, 0xff, 0xff, 0xff // next_track_ID
  1698. ]);
  1699. return MP4.box(MP4.types.mvhd, bytes);
  1700. }
  1701. }, {
  1702. key: 'sdtp',
  1703. value: function sdtp(track) {
  1704. var samples = track.samples || [],
  1705. bytes = new Uint8Array(4 + samples.length),
  1706. flags,
  1707. i;
  1708. // leave the full box header (4 bytes) all zero
  1709. // write the sample table
  1710. for (i = 0; i < samples.length; i++) {
  1711. flags = samples[i].flags;
  1712. bytes[i + 4] = flags.dependsOn << 4 | flags.isDependedOn << 2 | flags.hasRedundancy;
  1713. }
  1714. return MP4.box(MP4.types.sdtp, bytes);
  1715. }
  1716. }, {
  1717. key: 'stbl',
  1718. value: function stbl(track) {
  1719. return MP4.box(MP4.types.stbl, MP4.stsd(track), MP4.box(MP4.types.stts, MP4.STTS), MP4.box(MP4.types.stsc, MP4.STSC), MP4.box(MP4.types.stsz, MP4.STSZ), MP4.box(MP4.types.stco, MP4.STCO));
  1720. }
  1721. }, {
  1722. key: 'avc1',
  1723. value: function avc1(track) {
  1724. var sps = [],
  1725. pps = [],
  1726. i,
  1727. data,
  1728. len;
  1729. // assemble the SPSs
  1730. for (i = 0; i < track.sps.length; i++) {
  1731. data = track.sps[i];
  1732. len = data.byteLength;
  1733. sps.push(len >>> 8 & 0xFF);
  1734. sps.push(len & 0xFF);
  1735. sps = sps.concat(Array.prototype.slice.call(data)); // SPS
  1736. }
  1737. // assemble the PPSs
  1738. for (i = 0; i < track.pps.length; i++) {
  1739. data = track.pps[i];
  1740. len = data.byteLength;
  1741. pps.push(len >>> 8 & 0xFF);
  1742. pps.push(len & 0xFF);
  1743. pps = pps.concat(Array.prototype.slice.call(data));
  1744. }
  1745. var avcc = MP4.box(MP4.types.avcC, new Uint8Array([0x01, // version
  1746. sps[3], // profile
  1747. sps[4], // profile compat
  1748. sps[5], // level
  1749. 0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes
  1750. 0xE0 | track.sps.length // 3bit reserved (111) + numOfSequenceParameterSets
  1751. ].concat(sps).concat([track.pps.length // numOfPictureParameterSets
  1752. ]).concat(pps))),
  1753. // "PPS"
  1754. width = track.width,
  1755. height = track.height;
  1756. //console.log('avcc:' + Hex.hexDump(avcc));
  1757. return MP4.box(MP4.types.avc1, new Uint8Array([0x00, 0x00, 0x00, // reserved
  1758. 0x00, 0x00, 0x00, // reserved
  1759. 0x00, 0x01, // data_reference_index
  1760. 0x00, 0x00, // pre_defined
  1761. 0x00, 0x00, // reserved
  1762. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
  1763. width >> 8 & 0xFF, width & 0xff, // width
  1764. height >> 8 & 0xFF, height & 0xff, // height
  1765. 0x00, 0x48, 0x00, 0x00, // horizresolution
  1766. 0x00, 0x48, 0x00, 0x00, // vertresolution
  1767. 0x00, 0x00, 0x00, 0x00, // reserved
  1768. 0x00, 0x01, // frame_count
  1769. 0x12, 0x6a, 0x65, 0x66, 0x66, // wfs.js
  1770. 0x2d, 0x79, 0x61, 0x6e, 0x2f, 0x2f, 0x2f, 0x67, 0x77, 0x66, 0x73, 0x2E, 0x6A, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // compressorname
  1771. 0x00, 0x18, // depth = 24
  1772. 0x11, 0x11]), // pre_defined = -1
  1773. avcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80, // bufferSizeDB
  1774. 0x00, 0x2d, 0xc6, 0xc0, // maxBitrate
  1775. 0x00, 0x2d, 0xc6, 0xc0])) // avgBitrate
  1776. );
  1777. }
  1778. }, {
  1779. key: 'esds',
  1780. value: function esds(track) {
  1781. var configlen = track.config.length;
  1782. return new Uint8Array([0x00, // version 0
  1783. 0x00, 0x00, 0x00, // flags
  1784. 0x03, // descriptor_type
  1785. 0x17 + configlen, // length
  1786. 0x00, 0x01, //es_id
  1787. 0x00, // stream_priority
  1788. 0x04, // descriptor_type
  1789. 0x0f + configlen, // length
  1790. 0x40, //codec : mpeg4_audio
  1791. 0x15, // stream_type
  1792. 0x00, 0x00, 0x00, // buffer_size
  1793. 0x00, 0x00, 0x00, 0x00, // maxBitrate
  1794. 0x00, 0x00, 0x00, 0x00, // avgBitrate
  1795. 0x05 // descriptor_type
  1796. ].concat([configlen]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor
  1797. }
  1798. }, {
  1799. key: 'mp4a',
  1800. value: function mp4a(track) {
  1801. var audiosamplerate = track.audiosamplerate;
  1802. return MP4.box(MP4.types.mp4a, new Uint8Array([0x00, 0x00, 0x00, // reserved
  1803. 0x00, 0x00, 0x00, // reserved
  1804. 0x00, 0x01, // data_reference_index
  1805. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
  1806. 0x00, track.channelCount, // channelcount
  1807. 0x00, 0x10, // sampleSize:16bits
  1808. 0x00, 0x00, 0x00, 0x00, // reserved2
  1809. audiosamplerate >> 8 & 0xFF, audiosamplerate & 0xff, //
  1810. 0x00, 0x00]), MP4.box(MP4.types.esds, MP4.esds(track)));
  1811. }
  1812. }, {
  1813. key: 'stsd',
  1814. value: function stsd(track) {
  1815. if (track.type === 'audio') {
  1816. return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
  1817. } else {
  1818. return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
  1819. }
  1820. }
  1821. }, {
  1822. key: 'tkhd',
  1823. value: function tkhd(track) {
  1824. var id = track.id,
  1825. duration = track.duration * track.timescale,
  1826. width = track.width,
  1827. height = track.height;
  1828. // console.log( "tkhd==> ",track.id, track.duration, track.timescale, width,height );
  1829. return MP4.box(MP4.types.tkhd, new Uint8Array([0x00, // version 0
  1830. 0x00, 0x00, 0x07, // flags
  1831. 0x00, 0x00, 0x00, 0x00, // creation_time
  1832. 0x00, 0x00, 0x00, 0x00, // modification_time
  1833. id >> 24 & 0xFF, id >> 16 & 0xFF, id >> 8 & 0xFF, id & 0xFF, // track_ID
  1834. 0x00, 0x00, 0x00, 0x00, // reserved
  1835. duration >> 24, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
  1836. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
  1837. 0x00, 0x00, // layer
  1838. 0x00, 0x00, // alternate_group
  1839. 0x00, 0x00, // non-audio track volume
  1840. 0x00, 0x00, // reserved
  1841. 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
  1842. width >> 8 & 0xFF, width & 0xFF, 0x00, 0x00, // width
  1843. height >> 8 & 0xFF, height & 0xFF, 0x00, 0x00 // height
  1844. ]));
  1845. }
  1846. }, {
  1847. key: 'traf',
  1848. value: function traf(track, baseMediaDecodeTime) {
  1849. var sampleDependencyTable = MP4.sdtp(track),
  1850. id = track.id;
  1851. // console.log( "traf==> ",id ,baseMediaDecodeTime);
  1852. return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([0x00, // version 0
  1853. 0x00, 0x00, 0x00, // flags
  1854. id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF]) // track_ID
  1855. ), MP4.box(MP4.types.tfdt, new Uint8Array([0x00, // version 0
  1856. 0x00, 0x00, 0x00, // flags
  1857. baseMediaDecodeTime >> 24, baseMediaDecodeTime >> 16 & 0XFF, baseMediaDecodeTime >> 8 & 0XFF, baseMediaDecodeTime & 0xFF]) // baseMediaDecodeTime
  1858. ), MP4.trun(track, sampleDependencyTable.length + 16 + // tfhd
  1859. 16 + // tfdt
  1860. 8 + // traf header
  1861. 16 + // mfhd
  1862. 8 + // moof header
  1863. 8), // mdat header
  1864. sampleDependencyTable);
  1865. }
  1866. /**
  1867. * Generate a track box.
  1868. * @param track {object} a track definition
  1869. * @return {Uint8Array} the track box
  1870. */
  1871. }, {
  1872. key: 'trak',
  1873. value: function trak(track) {
  1874. track.duration = track.duration || 0xffffffff;
  1875. return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track));
  1876. }
  1877. }, {
  1878. key: 'trex',
  1879. value: function trex(track) {
  1880. var id = track.id;
  1881. return MP4.box(MP4.types.trex, new Uint8Array([0x00, // version 0
  1882. 0x00, 0x00, 0x00, // flags
  1883. id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF, // track_ID
  1884. 0x00, 0x00, 0x00, 0x01, // default_sample_description_index
  1885. 0x00, 0x00, 0x00, 0x00, // default_sample_duration
  1886. 0x00, 0x00, 0x00, 0x00, // default_sample_size
  1887. 0x00, 0x01, 0x00, 0x01 // default_sample_flags
  1888. ]));
  1889. }
  1890. }, {
  1891. key: 'trun',
  1892. value: function trun(track, offset) {
  1893. var samples = track.samples || [],
  1894. len = samples.length,
  1895. arraylen = 12 + 16 * len,
  1896. array = new Uint8Array(arraylen),
  1897. i,
  1898. sample,
  1899. duration,
  1900. size,
  1901. flags,
  1902. cts;
  1903. //sample = samples[0];
  1904. // console.log( "trun==> ",sample.duration, sample.cts ,sample.size,len );
  1905. offset += 8 + arraylen;
  1906. array.set([0x00, // version 0
  1907. 0x00, 0x0f, 0x01, // flags
  1908. len >>> 24 & 0xFF, len >>> 16 & 0xFF, len >>> 8 & 0xFF, len & 0xFF, // sample_count
  1909. offset >>> 24 & 0xFF, offset >>> 16 & 0xFF, offset >>> 8 & 0xFF, offset & 0xFF // data_offset
  1910. ], 0);
  1911. for (i = 0; i < len; i++) {
  1912. sample = samples[i];
  1913. duration = sample.duration;
  1914. size = sample.size;
  1915. flags = sample.flags;
  1916. cts = sample.cts;
  1917. array.set([duration >>> 24 & 0xFF, duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, // sample_duration
  1918. size >>> 24 & 0xFF, size >>> 16 & 0xFF, size >>> 8 & 0xFF, size & 0xFF, // sample_size
  1919. flags.isLeading << 2 | flags.dependsOn, flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.paddingValue << 1 | flags.isNonSync, flags.degradPrio & 0xF0 << 8, flags.degradPrio & 0x0F, // sample_flags
  1920. cts >>> 24 & 0xFF, cts >>> 16 & 0xFF, cts >>> 8 & 0xFF, cts & 0xFF // sample_composition_time_offset
  1921. ], 12 + 16 * i);
  1922. }
  1923. return MP4.box(MP4.types.trun, array);
  1924. }
  1925. }, {
  1926. key: 'initSegment',
  1927. value: function initSegment(tracks) {
  1928. if (!MP4.types) {
  1929. MP4.init();
  1930. }
  1931. var movie = MP4.moov(tracks),
  1932. result;
  1933. result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength);
  1934. result.set(MP4.FTYP);
  1935. result.set(movie, MP4.FTYP.byteLength);
  1936. return result;
  1937. }
  1938. }]);
  1939. return MP4;
  1940. }();
  1941. exports.default = MP4;
  1942. },{}],13:[function(require,module,exports){
  1943. 'use strict';
  1944. Object.defineProperty(exports, "__esModule", {
  1945. value: true
  1946. });
  1947. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
  1948. * fMP4 remuxer
  1949. */
  1950. var _aac = require('../helper/aac');
  1951. var _aac2 = _interopRequireDefault(_aac);
  1952. var _events = require('../events');
  1953. var _events2 = _interopRequireDefault(_events);
  1954. var _logger = require('../utils/logger');
  1955. var _mp4Generator = require('../remux/mp4-generator');
  1956. var _mp4Generator2 = _interopRequireDefault(_mp4Generator);
  1957. var _errors = require('../errors');
  1958. require('../utils/polyfill');
  1959. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  1960. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1961. var MP4Remuxer = function () {
  1962. function MP4Remuxer(observer, id, config) {
  1963. _classCallCheck(this, MP4Remuxer);
  1964. this.observer = observer;
  1965. this.id = id;
  1966. this.config = config;
  1967. this.ISGenerated = false;
  1968. this.PES2MP4SCALEFACTOR = 4;
  1969. this.PES_TIMESCALE = 90000;
  1970. this.MP4_TIMESCALE = this.PES_TIMESCALE / this.PES2MP4SCALEFACTOR;
  1971. this.nextAvcDts = 90300;
  1972. this.H264_TIMEBASE = 3000;
  1973. }
  1974. _createClass(MP4Remuxer, [{
  1975. key: 'destroy',
  1976. value: function destroy() {}
  1977. }, {
  1978. key: 'insertDiscontinuity',
  1979. value: function insertDiscontinuity() {
  1980. this._initPTS = this._initDTS = undefined;
  1981. }
  1982. }, {
  1983. key: 'switchLevel',
  1984. value: function switchLevel() {
  1985. this.ISGenerated = false;
  1986. }
  1987. }, {
  1988. key: 'pushVideo',
  1989. value: function pushVideo(level, sn, videoTrack, timeOffset, contiguous) {
  1990. this.level = level;
  1991. this.sn = sn;
  1992. var videoData = void 0;
  1993. // generate Init Segment if needed
  1994. if (!this.ISGenerated) {
  1995. this.generateVideoIS(videoTrack, timeOffset);
  1996. }
  1997. if (this.ISGenerated) {
  1998. if (videoTrack.samples.length) {
  1999. this.remuxVideo_2(videoTrack, timeOffset, contiguous);
  2000. }
  2001. }
  2002. }
  2003. }, {
  2004. key: 'remuxVideo_2',
  2005. value: function remuxVideo_2(track, timeOffset, contiguous, audioTrackLength) {
  2006. var offset = 8,
  2007. pesTimeScale = this.PES_TIMESCALE,
  2008. pes2mp4ScaleFactor = this.PES2MP4SCALEFACTOR,
  2009. mp4SampleDuration,
  2010. mdat,
  2011. moof,
  2012. firstPTS,
  2013. firstDTS,
  2014. nextDTS,
  2015. inputSamples = track.samples,
  2016. outputSamples = [];
  2017. /* concatenate the video data and construct the mdat in place
  2018. (need 8 more bytes to fill length and mpdat type) */
  2019. mdat = new Uint8Array(track.len + 4 * track.nbNalu + 8);
  2020. var view = new DataView(mdat.buffer);
  2021. view.setUint32(0, mdat.byteLength);
  2022. mdat.set(_mp4Generator2.default.types.mdat, 4);
  2023. var sampleDuration = 0;
  2024. var ptsnorm = void 0,
  2025. dtsnorm = void 0,
  2026. mp4Sample = void 0,
  2027. lastDTS = void 0;
  2028. for (var i = 0; i < inputSamples.length; i++) {
  2029. var avcSample = inputSamples[i],
  2030. mp4SampleLength = 0,
  2031. compositionTimeOffset = void 0;
  2032. // convert NALU bitstream to MP4 format (prepend NALU with size field)
  2033. while (avcSample.units.units.length) {
  2034. var unit = avcSample.units.units.shift();
  2035. view.setUint32(offset, unit.data.byteLength);
  2036. offset += 4;
  2037. mdat.set(unit.data, offset);
  2038. offset += unit.data.byteLength;
  2039. mp4SampleLength += 4 + unit.data.byteLength;
  2040. }
  2041. var pts = avcSample.pts - this._initPTS;
  2042. var dts = avcSample.dts - this._initDTS;
  2043. dts = Math.min(pts, dts);
  2044. if (lastDTS !== undefined) {
  2045. ptsnorm = this._PTSNormalize(pts, lastDTS);
  2046. dtsnorm = this._PTSNormalize(dts, lastDTS);
  2047. sampleDuration = dtsnorm - lastDTS;
  2048. if (sampleDuration <= 0) {
  2049. _logger.logger.log('invalid sample duration at PTS/DTS: ' + avcSample.pts + '/' + avcSample.dts + '|dts norm: ' + dtsnorm + '|lastDTS: ' + lastDTS + ':' + sampleDuration);
  2050. sampleDuration = 1;
  2051. }
  2052. } else {
  2053. var nextAvcDts = this.nextAvcDts,
  2054. delta;
  2055. ptsnorm = this._PTSNormalize(pts, nextAvcDts);
  2056. dtsnorm = this._PTSNormalize(dts, nextAvcDts);
  2057. if (nextAvcDts) {
  2058. delta = Math.round(dtsnorm - nextAvcDts);
  2059. if ( /*contiguous ||*/Math.abs(delta) < 600) {
  2060. if (delta) {
  2061. if (delta > 1) {
  2062. _logger.logger.log('AVC:' + delta + ' ms hole between fragments detected,filling it');
  2063. } else if (delta < -1) {
  2064. _logger.logger.log('AVC:' + -delta + ' ms overlapping between fragments detected');
  2065. }
  2066. dtsnorm = nextAvcDts;
  2067. ptsnorm = Math.max(ptsnorm - delta, dtsnorm);
  2068. _logger.logger.log('Video/PTS/DTS adjusted: ' + ptsnorm + '/' + dtsnorm + ',delta:' + delta);
  2069. }
  2070. }
  2071. }
  2072. this.firstPTS = Math.max(0, ptsnorm);
  2073. this.firstDTS = Math.max(0, dtsnorm);
  2074. sampleDuration = 0.03;
  2075. }
  2076. outputSamples.push({
  2077. size: mp4SampleLength,
  2078. duration: this.H264_TIMEBASE,
  2079. cts: 0,
  2080. flags: {
  2081. isLeading: 0,
  2082. isDependedOn: 0,
  2083. hasRedundancy: 0,
  2084. degradPrio: 0,
  2085. dependsOn: avcSample.key ? 2 : 1,
  2086. isNonSync: avcSample.key ? 0 : 1
  2087. }
  2088. });
  2089. lastDTS = dtsnorm;
  2090. }
  2091. var lastSampleDuration = 0;
  2092. if (outputSamples.length >= 2) {
  2093. lastSampleDuration = outputSamples[outputSamples.length - 2].duration;
  2094. outputSamples[0].duration = lastSampleDuration;
  2095. }
  2096. this.nextAvcDts = dtsnorm + lastSampleDuration;
  2097. var dropped = track.dropped;
  2098. track.len = 0;
  2099. track.nbNalu = 0;
  2100. track.dropped = 0;
  2101. if (outputSamples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
  2102. var flags = outputSamples[0].flags;
  2103. flags.dependsOn = 2;
  2104. flags.isNonSync = 0;
  2105. }
  2106. track.samples = outputSamples;
  2107. moof = _mp4Generator2.default.moof(track.sequenceNumber++, dtsnorm, track);
  2108. track.samples = [];
  2109. var data = {
  2110. id: this.id,
  2111. level: this.level,
  2112. sn: this.sn,
  2113. data1: moof,
  2114. data2: mdat,
  2115. startPTS: ptsnorm,
  2116. endPTS: ptsnorm,
  2117. startDTS: dtsnorm,
  2118. endDTS: dtsnorm,
  2119. type: 'video',
  2120. nb: outputSamples.length,
  2121. dropped: dropped
  2122. };
  2123. this.observer.trigger(_events2.default.FRAG_PARSING_DATA, data);
  2124. return data;
  2125. }
  2126. }, {
  2127. key: 'generateVideoIS',
  2128. value: function generateVideoIS(videoTrack, timeOffset) {
  2129. var observer = this.observer,
  2130. videoSamples = videoTrack.samples,
  2131. pesTimeScale = this.PES_TIMESCALE,
  2132. tracks = {},
  2133. data = { id: this.id, level: this.level, sn: this.sn, tracks: tracks, unique: false },
  2134. computePTSDTS = this._initPTS === undefined,
  2135. initPTS,
  2136. initDTS;
  2137. if (computePTSDTS) {
  2138. initPTS = initDTS = Infinity;
  2139. }
  2140. if (videoTrack.sps && videoTrack.pps && videoSamples.length) {
  2141. videoTrack.timescale = 90000; //this.MP4_TIMESCALE;
  2142. tracks.video = {
  2143. container: 'video/mp4',
  2144. codec: videoTrack.codec,
  2145. initSegment: _mp4Generator2.default.initSegment([videoTrack]),
  2146. metadata: {
  2147. width: videoTrack.width,
  2148. height: videoTrack.height
  2149. }
  2150. };
  2151. if (computePTSDTS) {
  2152. initPTS = Math.min(initPTS, videoSamples[0].pts - this.H264_TIMEBASE);
  2153. initDTS = Math.min(initDTS, videoSamples[0].dts - this.H264_TIMEBASE);
  2154. }
  2155. }
  2156. if (Object.keys(tracks).length) {
  2157. observer.trigger(_events2.default.FRAG_PARSING_INIT_SEGMENT, data);
  2158. this.ISGenerated = true;
  2159. if (computePTSDTS) {
  2160. this._initPTS = initPTS;
  2161. this._initDTS = initDTS;
  2162. }
  2163. } else {
  2164. console.log("generateVideoIS ERROR==> ", _errors.ErrorTypes.MEDIA_ERROR);
  2165. }
  2166. }
  2167. }, {
  2168. key: 'remux',
  2169. value: function remux(level, sn, audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous) {
  2170. this.level = level;
  2171. this.sn = sn;
  2172. // generate Init Segment if needed
  2173. if (!this.ISGenerated) {
  2174. this.generateIS(audioTrack, videoTrack, timeOffset);
  2175. }
  2176. if (this.ISGenerated) {
  2177. // Purposefully remuxing audio before video, so that remuxVideo can use nextAacPts, which is
  2178. // calculated in remuxAudio.
  2179. //logger.log('nb AAC samples:' + audioTrack.samples.length);
  2180. if (audioTrack.samples.length) {
  2181. var audioData = this.remuxAudio(audioTrack, timeOffset, contiguous);
  2182. //logger.log('nb AVC samples:' + videoTrack.samples.length);
  2183. if (videoTrack.samples.length) {
  2184. var audioTrackLength = void 0;
  2185. if (audioData) {
  2186. audioTrackLength = audioData.endPTS - audioData.startPTS;
  2187. }
  2188. this.remuxVideo(videoTrack, timeOffset, contiguous, audioTrackLength);
  2189. }
  2190. } else {
  2191. var videoData = void 0;
  2192. //logger.log('nb AVC samples:' + videoTrack.samples.length);
  2193. if (videoTrack.samples.length) {
  2194. videoData = this.remuxVideo(videoTrack, timeOffset, contiguous);
  2195. }
  2196. if (videoData && audioTrack.codec) {
  2197. this.remuxEmptyAudio(audioTrack, timeOffset, contiguous, videoData);
  2198. }
  2199. }
  2200. }
  2201. //logger.log('nb ID3 samples:' + audioTrack.samples.length);
  2202. if (id3Track.samples.length) {
  2203. this.remuxID3(id3Track, timeOffset);
  2204. }
  2205. //logger.log('nb ID3 samples:' + audioTrack.samples.length);
  2206. if (textTrack.samples.length) {
  2207. this.remuxText(textTrack, timeOffset);
  2208. }
  2209. //notify end of parsing
  2210. this.observer.trigger(_events2.default.FRAG_PARSED, { id: this.id, level: this.level, sn: this.sn });
  2211. }
  2212. }, {
  2213. key: 'generateIS',
  2214. value: function generateIS(audioTrack, videoTrack, timeOffset) {
  2215. var observer = this.observer,
  2216. audioSamples = audioTrack.samples,
  2217. videoSamples = videoTrack.samples,
  2218. pesTimeScale = this.PES_TIMESCALE,
  2219. tracks = {},
  2220. data = { id: this.id, level: this.level, sn: this.sn, tracks: tracks, unique: false },
  2221. computePTSDTS = this._initPTS === undefined,
  2222. initPTS,
  2223. initDTS;
  2224. if (computePTSDTS) {
  2225. initPTS = initDTS = Infinity;
  2226. }
  2227. if (audioTrack.config && audioSamples.length) {
  2228. audioTrack.timescale = audioTrack.audiosamplerate;
  2229. // MP4 duration (track duration in seconds multiplied by timescale) is coded on 32 bits
  2230. // we know that each AAC sample contains 1024 frames....
  2231. // in order to avoid overflowing the 32 bit counter for large duration, we use smaller timescale (timescale/gcd)
  2232. // we just need to ensure that AAC sample duration will still be an integer (will be 1024/gcd)
  2233. if (audioTrack.timescale * audioTrack.duration > Math.pow(2, 32)) {
  2234. var greatestCommonDivisor = function greatestCommonDivisor(a, b) {
  2235. if (!b) {
  2236. return a;
  2237. }
  2238. return greatestCommonDivisor(b, a % b);
  2239. };
  2240. audioTrack.timescale = audioTrack.audiosamplerate / greatestCommonDivisor(audioTrack.audiosamplerate, 1024);
  2241. }
  2242. _logger.logger.log('audio mp4 timescale :' + audioTrack.timescale);
  2243. tracks.audio = {
  2244. container: 'audio/mp4',
  2245. codec: audioTrack.codec,
  2246. initSegment: _mp4Generator2.default.initSegment([audioTrack]),
  2247. metadata: {
  2248. channelCount: audioTrack.channelCount
  2249. }
  2250. };
  2251. if (computePTSDTS) {
  2252. // remember first PTS of this demuxing context. for audio, PTS + DTS ...
  2253. initPTS = initDTS = audioSamples[0].pts - pesTimeScale * timeOffset;
  2254. }
  2255. }
  2256. if (videoTrack.sps && videoTrack.pps && videoSamples.length) {
  2257. videoTrack.timescale = this.MP4_TIMESCALE;
  2258. tracks.video = {
  2259. container: 'video/mp4',
  2260. codec: videoTrack.codec,
  2261. initSegment: _mp4Generator2.default.initSegment([videoTrack]),
  2262. metadata: {
  2263. width: videoTrack.width,
  2264. height: videoTrack.height
  2265. }
  2266. };
  2267. if (computePTSDTS) {
  2268. initPTS = Math.min(initPTS, videoSamples[0].pts - pesTimeScale * timeOffset);
  2269. initDTS = Math.min(initDTS, videoSamples[0].dts - pesTimeScale * timeOffset);
  2270. }
  2271. }
  2272. if (Object.keys(tracks).length) {
  2273. observer.trigger(_events2.default.FRAG_PARSING_INIT_SEGMENT, data);
  2274. this.ISGenerated = true;
  2275. if (computePTSDTS) {
  2276. this._initPTS = initPTS;
  2277. this._initDTS = initDTS;
  2278. }
  2279. } else {
  2280. observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, id: this.id, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: false, reason: 'no audio/video samples found' });
  2281. }
  2282. }
  2283. }, {
  2284. key: 'remuxVideo',
  2285. value: function remuxVideo(track, timeOffset, contiguous, audioTrackLength) {
  2286. var offset = 8,
  2287. pesTimeScale = this.PES_TIMESCALE,
  2288. pes2mp4ScaleFactor = this.PES2MP4SCALEFACTOR,
  2289. mp4SampleDuration,
  2290. mdat,
  2291. moof,
  2292. firstPTS,
  2293. firstDTS,
  2294. nextDTS,
  2295. lastPTS,
  2296. lastDTS,
  2297. inputSamples = track.samples,
  2298. outputSamples = [];
  2299. // PTS is coded on 33bits, and can loop from -2^32 to 2^32
  2300. // PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value
  2301. var nextAvcDts = void 0;
  2302. if (contiguous) {
  2303. // if parsed fragment is contiguous with last one, let's use last DTS value as reference
  2304. nextAvcDts = this.nextAvcDts;
  2305. } else {
  2306. // if not contiguous, let's use target timeOffset
  2307. nextAvcDts = timeOffset * pesTimeScale;
  2308. }
  2309. // compute first DTS and last DTS, normalize them against reference value
  2310. var sample = inputSamples[0];
  2311. firstDTS = Math.max(this._PTSNormalize(sample.dts, nextAvcDts) - this._initDTS, 0);
  2312. firstPTS = Math.max(this._PTSNormalize(sample.pts, nextAvcDts) - this._initDTS, 0);
  2313. // check timestamp continuity accross consecutive fragments (this is to remove inter-fragment gap/hole)
  2314. var delta = Math.round((firstDTS - nextAvcDts) / 90);
  2315. // if fragment are contiguous, detect hole/overlapping between fragments
  2316. if (contiguous) {
  2317. if (delta) {
  2318. if (delta > 1) {
  2319. _logger.logger.log('AVC:' + delta + ' ms hole between fragments detected,filling it');
  2320. } else if (delta < -1) {
  2321. _logger.logger.log('AVC:' + -delta + ' ms overlapping between fragments detected');
  2322. }
  2323. // remove hole/gap : set DTS to next expected DTS
  2324. firstDTS = nextAvcDts;
  2325. inputSamples[0].dts = firstDTS + this._initDTS;
  2326. // offset PTS as well, ensure that PTS is smaller or equal than new DTS
  2327. firstPTS = Math.max(firstPTS - delta, nextAvcDts);
  2328. inputSamples[0].pts = firstPTS + this._initDTS;
  2329. _logger.logger.log('Video/PTS/DTS adjusted: ' + firstPTS + '/' + firstDTS + ',delta:' + delta);
  2330. }
  2331. }
  2332. nextDTS = firstDTS;
  2333. // compute lastPTS/lastDTS
  2334. sample = inputSamples[inputSamples.length - 1];
  2335. lastDTS = Math.max(this._PTSNormalize(sample.dts, nextAvcDts) - this._initDTS, 0);
  2336. lastPTS = Math.max(this._PTSNormalize(sample.pts, nextAvcDts) - this._initDTS, 0);
  2337. lastPTS = Math.max(lastPTS, lastDTS);
  2338. var vendor = navigator.vendor,
  2339. userAgent = navigator.userAgent,
  2340. isSafari = vendor && vendor.indexOf('Apple') > -1 && userAgent && !userAgent.match('CriOS');
  2341. // on Safari let's signal the same sample duration for all samples
  2342. // sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS
  2343. // set this constant duration as being the avg delta between consecutive DTS.
  2344. if (isSafari) {
  2345. mp4SampleDuration = Math.round((lastDTS - firstDTS) / (pes2mp4ScaleFactor * (inputSamples.length - 1)));
  2346. }
  2347. // normalize all PTS/DTS now ...
  2348. for (var i = 0; i < inputSamples.length; i++) {
  2349. var _sample = inputSamples[i];
  2350. if (isSafari) {
  2351. // sample DTS is computed using a constant decoding offset (mp4SampleDuration) between samples
  2352. _sample.dts = firstDTS + i * pes2mp4ScaleFactor * mp4SampleDuration;
  2353. } else {
  2354. // ensure sample monotonic DTS
  2355. _sample.dts = Math.max(this._PTSNormalize(_sample.dts, nextAvcDts) - this._initDTS, firstDTS);
  2356. // ensure dts is a multiple of scale factor to avoid rounding issues
  2357. _sample.dts = Math.round(_sample.dts / pes2mp4ScaleFactor) * pes2mp4ScaleFactor;
  2358. }
  2359. // we normalize PTS against nextAvcDts, we also substract initDTS (some streams don't start @ PTS O)
  2360. // and we ensure that computed value is greater or equal than sample DTS
  2361. _sample.pts = Math.max(this._PTSNormalize(_sample.pts, nextAvcDts) - this._initDTS, _sample.dts);
  2362. // ensure pts is a multiple of scale factor to avoid rounding issues
  2363. _sample.pts = Math.round(_sample.pts / pes2mp4ScaleFactor) * pes2mp4ScaleFactor;
  2364. }
  2365. /* concatenate the video data and construct the mdat in place
  2366. (need 8 more bytes to fill length and mpdat type) */
  2367. mdat = new Uint8Array(track.len + 4 * track.nbNalu + 8);
  2368. var view = new DataView(mdat.buffer);
  2369. view.setUint32(0, mdat.byteLength);
  2370. mdat.set(_mp4Generator2.default.types.mdat, 4);
  2371. for (var _i = 0; _i < inputSamples.length; _i++) {
  2372. var avcSample = inputSamples[_i],
  2373. mp4SampleLength = 0,
  2374. compositionTimeOffset = void 0;
  2375. // convert NALU bitstream to MP4 format (prepend NALU with size field)
  2376. while (avcSample.units.units.length) {
  2377. var unit = avcSample.units.units.shift();
  2378. view.setUint32(offset, unit.data.byteLength);
  2379. offset += 4;
  2380. mdat.set(unit.data, offset);
  2381. offset += unit.data.byteLength;
  2382. mp4SampleLength += 4 + unit.data.byteLength;
  2383. }
  2384. if (!isSafari) {
  2385. // expected sample duration is the Decoding Timestamp diff of consecutive samples
  2386. if (_i < inputSamples.length - 1) {
  2387. mp4SampleDuration = inputSamples[_i + 1].dts - avcSample.dts;
  2388. } else {
  2389. var config = this.config,
  2390. lastFrameDuration = avcSample.dts - inputSamples[_i > 0 ? _i - 1 : _i].dts;
  2391. if (config.stretchShortVideoTrack) {
  2392. // In some cases, a segment's audio track duration may exceed the video track duration.
  2393. // Since we've already remuxed audio, and we know how long the audio track is, we look to
  2394. // see if the delta to the next segment is longer than the minimum of maxBufferHole and
  2395. // maxSeekHole. If so, playback would potentially get stuck, so we artificially inflate
  2396. // the duration of the last frame to minimize any potential gap between segments.
  2397. var maxBufferHole = config.maxBufferHole,
  2398. maxSeekHole = config.maxSeekHole,
  2399. gapTolerance = Math.floor(Math.min(maxBufferHole, maxSeekHole) * pesTimeScale),
  2400. deltaToFrameEnd = (audioTrackLength ? firstPTS + audioTrackLength * pesTimeScale : this.nextAacPts) - avcSample.pts;
  2401. if (deltaToFrameEnd > gapTolerance) {
  2402. // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video
  2403. // frame overlap. maxBufferHole/maxSeekHole should be >> lastFrameDuration anyway.
  2404. mp4SampleDuration = deltaToFrameEnd - lastFrameDuration;
  2405. if (mp4SampleDuration < 0) {
  2406. mp4SampleDuration = lastFrameDuration;
  2407. }
  2408. _logger.logger.log('It is approximately ' + deltaToFrameEnd / 90 + ' ms to the next segment; using duration ' + mp4SampleDuration / 90 + ' ms for the last video frame.');
  2409. } else {
  2410. mp4SampleDuration = lastFrameDuration;
  2411. }
  2412. } else {
  2413. mp4SampleDuration = lastFrameDuration;
  2414. }
  2415. }
  2416. mp4SampleDuration /= pes2mp4ScaleFactor;
  2417. compositionTimeOffset = Math.round((avcSample.pts - avcSample.dts) / pes2mp4ScaleFactor);
  2418. } else {
  2419. compositionTimeOffset = Math.max(0, mp4SampleDuration * Math.round((avcSample.pts - avcSample.dts) / (pes2mp4ScaleFactor * mp4SampleDuration)));
  2420. }
  2421. outputSamples.push({
  2422. size: mp4SampleLength,
  2423. // constant duration
  2424. duration: mp4SampleDuration,
  2425. cts: compositionTimeOffset,
  2426. flags: {
  2427. isLeading: 0,
  2428. isDependedOn: 0,
  2429. hasRedundancy: 0,
  2430. degradPrio: 0,
  2431. dependsOn: avcSample.key ? 2 : 1,
  2432. isNonSync: avcSample.key ? 0 : 1
  2433. }
  2434. });
  2435. }
  2436. // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
  2437. this.nextAvcDts = lastDTS + mp4SampleDuration * pes2mp4ScaleFactor;
  2438. var dropped = track.dropped;
  2439. track.len = 0;
  2440. track.nbNalu = 0;
  2441. track.dropped = 0;
  2442. if (outputSamples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
  2443. var flags = outputSamples[0].flags;
  2444. // chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue
  2445. // https://code.google.com/p/chromium/issues/detail?id=229412
  2446. flags.dependsOn = 2;
  2447. flags.isNonSync = 0;
  2448. }
  2449. track.samples = outputSamples;
  2450. moof = _mp4Generator2.default.moof(track.sequenceNumber++, firstDTS / pes2mp4ScaleFactor, track);
  2451. track.samples = [];
  2452. var data = {
  2453. id: this.id,
  2454. level: this.level,
  2455. sn: this.sn,
  2456. data1: moof,
  2457. data2: mdat,
  2458. startPTS: firstPTS / pesTimeScale,
  2459. endPTS: (lastPTS + pes2mp4ScaleFactor * mp4SampleDuration) / pesTimeScale,
  2460. startDTS: firstPTS / pesTimeScale,
  2461. endDTS: (lastPTS + pes2mp4ScaleFactor * mp4SampleDuration) / pesTimeScale,
  2462. // startDTS: firstDTS / pesTimeScale,
  2463. // endDTS: this.nextAvcDts / pesTimeScale,
  2464. type: 'video',
  2465. nb: outputSamples.length,
  2466. dropped: dropped
  2467. };
  2468. this.observer.trigger(_events2.default.FRAG_PARSING_DATA, data);
  2469. return data;
  2470. }
  2471. }, {
  2472. key: 'remuxAudio',
  2473. value: function remuxAudio(track, timeOffset, contiguous) {
  2474. var pesTimeScale = this.PES_TIMESCALE,
  2475. mp4timeScale = track.timescale,
  2476. pes2mp4ScaleFactor = pesTimeScale / mp4timeScale,
  2477. expectedSampleDuration = track.timescale * 1024 / track.audiosamplerate;
  2478. var view,
  2479. offset = 8,
  2480. aacSample,
  2481. mp4Sample,
  2482. unit,
  2483. mdat,
  2484. moof,
  2485. firstPTS,
  2486. firstDTS,
  2487. lastDTS,
  2488. pts,
  2489. dts,
  2490. ptsnorm,
  2491. dtsnorm,
  2492. samples = [],
  2493. samples0 = [];
  2494. track.samples.sort(function (a, b) {
  2495. return a.pts - b.pts;
  2496. });
  2497. samples0 = track.samples;
  2498. var nextAacPts = contiguous ? this.nextAacPts : timeOffset * pesTimeScale;
  2499. // If the audio track is missing samples, the frames seem to get "left-shifted" within the
  2500. // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.
  2501. // In an effort to prevent this from happening, we inject frames here where there are gaps.
  2502. // When possible, we inject a silent frame; when that's not possible, we duplicate the last
  2503. // frame.
  2504. var firstPtsNorm = this._PTSNormalize(samples0[0].pts - this._initPTS, nextAacPts),
  2505. pesFrameDuration = expectedSampleDuration * pes2mp4ScaleFactor;
  2506. var nextPtsNorm = firstPtsNorm + pesFrameDuration;
  2507. for (var i = 1; i < samples0.length;) {
  2508. // First, let's see how far off this frame is from where we expect it to be
  2509. var sample = samples0[i],
  2510. ptsNorm = this._PTSNormalize(sample.pts - this._initPTS, nextAacPts),
  2511. delta = ptsNorm - nextPtsNorm;
  2512. // If we're overlapping by more than half a duration, drop this sample
  2513. if (delta < -0.5 * pesFrameDuration) {
  2514. _logger.logger.log('Dropping frame due to ' + Math.abs(delta / 90) + ' ms overlap.');
  2515. samples0.splice(i, 1);
  2516. track.len -= sample.unit.length;
  2517. // Don't touch nextPtsNorm or i
  2518. }
  2519. // Otherwise, if we're more than half a frame away from where we should be, insert missing frames
  2520. else if (delta > 0.5 * pesFrameDuration) {
  2521. var missing = Math.round(delta / pesFrameDuration);
  2522. _logger.logger.log('Injecting ' + missing + ' frame' + (missing > 1 ? 's' : '') + ' of missing audio due to ' + Math.round(delta / 90) + ' ms gap.');
  2523. for (var j = 0; j < missing; j++) {
  2524. var newStamp = samples0[i - 1].pts + pesFrameDuration,
  2525. fillFrame = _aac2.default.getSilentFrame(track.channelCount);
  2526. if (!fillFrame) {
  2527. _logger.logger.log('Unable to get silent frame for given audio codec; duplicating last frame instead.');
  2528. fillFrame = sample.unit.slice(0);
  2529. }
  2530. samples0.splice(i, 0, { unit: fillFrame, pts: newStamp, dts: newStamp });
  2531. track.len += fillFrame.length;
  2532. i += 1;
  2533. }
  2534. // Adjust sample to next expected pts
  2535. nextPtsNorm += (missing + 1) * pesFrameDuration;
  2536. sample.pts = samples0[i - 1].pts + pesFrameDuration;
  2537. i += 1;
  2538. }
  2539. // Otherwise, we're within half a frame duration, so just adjust pts
  2540. else {
  2541. if (Math.abs(delta) > 0.1 * pesFrameDuration) {
  2542. _logger.logger.log('Invalid frame delta ' + (ptsNorm - nextPtsNorm + pesFrameDuration) + ' at PTS ' + Math.round(ptsNorm / 90) + ' (should be ' + pesFrameDuration + ').');
  2543. }
  2544. nextPtsNorm += pesFrameDuration;
  2545. sample.pts = samples0[i - 1].pts + pesFrameDuration;
  2546. i += 1;
  2547. }
  2548. }
  2549. while (samples0.length) {
  2550. aacSample = samples0.shift();
  2551. unit = aacSample.unit;
  2552. pts = aacSample.pts - this._initDTS;
  2553. dts = aacSample.dts - this._initDTS;
  2554. //logger.log(`Audio/PTS:${Math.round(pts/90)}`);
  2555. // if not first sample
  2556. if (lastDTS !== undefined) {
  2557. ptsnorm = this._PTSNormalize(pts, lastDTS);
  2558. dtsnorm = this._PTSNormalize(dts, lastDTS);
  2559. mp4Sample.duration = (dtsnorm - lastDTS) / pes2mp4ScaleFactor;
  2560. } else {
  2561. ptsnorm = this._PTSNormalize(pts, nextAacPts);
  2562. dtsnorm = this._PTSNormalize(dts, nextAacPts);
  2563. var _delta = Math.round(1000 * (ptsnorm - nextAacPts) / pesTimeScale);
  2564. // if fragment are contiguous, detect hole/overlapping between fragments
  2565. if (contiguous) {
  2566. // log delta
  2567. if (_delta) {
  2568. if (_delta > 0) {
  2569. _logger.logger.log(_delta + ' ms hole between AAC samples detected,filling it');
  2570. // if we have frame overlap, overlapping for more than half a frame duraion
  2571. } else if (_delta < -12) {
  2572. // drop overlapping audio frames... browser will deal with it
  2573. _logger.logger.log(-_delta + ' ms overlapping between AAC samples detected, drop frame');
  2574. track.len -= unit.byteLength;
  2575. continue;
  2576. }
  2577. // set PTS/DTS to expected PTS/DTS
  2578. ptsnorm = dtsnorm = nextAacPts;
  2579. }
  2580. }
  2581. // remember first PTS of our aacSamples, ensure value is positive
  2582. firstPTS = Math.max(0, ptsnorm);
  2583. firstDTS = Math.max(0, dtsnorm);
  2584. if (track.len > 0) {
  2585. /* concatenate the audio data and construct the mdat in place
  2586. (need 8 more bytes to fill length and mdat type) */
  2587. mdat = new Uint8Array(track.len + 8);
  2588. view = new DataView(mdat.buffer);
  2589. view.setUint32(0, mdat.byteLength);
  2590. mdat.set(_mp4Generator2.default.types.mdat, 4);
  2591. } else {
  2592. // no audio samples
  2593. return;
  2594. }
  2595. }
  2596. mdat.set(unit, offset);
  2597. offset += unit.byteLength;
  2598. //console.log('PTS/DTS/initDTS/normPTS/normDTS/relative PTS : ${aacSample.pts}/${aacSample.dts}/${this._initDTS}/${ptsnorm}/${dtsnorm}/${(aacSample.pts/4294967296).toFixed(3)}');
  2599. mp4Sample = {
  2600. size: unit.byteLength,
  2601. cts: 0,
  2602. duration: 0,
  2603. flags: {
  2604. isLeading: 0,
  2605. isDependedOn: 0,
  2606. hasRedundancy: 0,
  2607. degradPrio: 0,
  2608. dependsOn: 1
  2609. }
  2610. };
  2611. samples.push(mp4Sample);
  2612. lastDTS = dtsnorm;
  2613. }
  2614. var lastSampleDuration = 0;
  2615. var nbSamples = samples.length;
  2616. //set last sample duration as being identical to previous sample
  2617. if (nbSamples >= 2) {
  2618. lastSampleDuration = samples[nbSamples - 2].duration;
  2619. mp4Sample.duration = lastSampleDuration;
  2620. }
  2621. if (nbSamples) {
  2622. // next aac sample PTS should be equal to last sample PTS + duration
  2623. this.nextAacPts = ptsnorm + pes2mp4ScaleFactor * lastSampleDuration;
  2624. //logger.log('Audio/PTS/PTSend:' + aacSample.pts.toFixed(0) + '/' + this.nextAacDts.toFixed(0));
  2625. track.len = 0;
  2626. track.samples = samples;
  2627. moof = _mp4Generator2.default.moof(track.sequenceNumber++, firstDTS / pes2mp4ScaleFactor, track);
  2628. track.samples = [];
  2629. var audioData = {
  2630. id: this.id,
  2631. level: this.level,
  2632. sn: this.sn,
  2633. data1: moof,
  2634. data2: mdat,
  2635. startPTS: firstPTS / pesTimeScale,
  2636. endPTS: this.nextAacPts / pesTimeScale,
  2637. startDTS: firstDTS / pesTimeScale,
  2638. endDTS: (dtsnorm + pes2mp4ScaleFactor * lastSampleDuration) / pesTimeScale,
  2639. type: 'audio',
  2640. nb: nbSamples
  2641. };
  2642. this.observer.trigger(_events2.default.FRAG_PARSING_DATA, audioData);
  2643. return audioData;
  2644. }
  2645. return null;
  2646. }
  2647. }, {
  2648. key: 'remuxEmptyAudio',
  2649. value: function remuxEmptyAudio(track, timeOffset, contiguous, videoData) {
  2650. var pesTimeScale = this.PES_TIMESCALE,
  2651. mp4timeScale = track.timescale ? track.timescale : track.audiosamplerate,
  2652. pes2mp4ScaleFactor = pesTimeScale / mp4timeScale,
  2653. // sync with video's timestamp
  2654. startDTS = videoData.startDTS * pesTimeScale + this._initDTS,
  2655. endDTS = videoData.endDTS * pesTimeScale + this._initDTS,
  2656. // one sample's duration value
  2657. sampleDuration = 1024,
  2658. frameDuration = pes2mp4ScaleFactor * sampleDuration,
  2659. // samples count of this segment's duration
  2660. nbSamples = Math.ceil((endDTS - startDTS) / frameDuration),
  2661. // silent frame
  2662. silentFrame = _aac2.default.getSilentFrame(track.channelCount);
  2663. // Can't remux if we can't generate a silent frame...
  2664. if (!silentFrame) {
  2665. _logger.logger.trace('Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec!');
  2666. return;
  2667. }
  2668. var samples = [];
  2669. for (var i = 0; i < nbSamples; i++) {
  2670. var stamp = startDTS + i * frameDuration;
  2671. samples.push({ unit: silentFrame.slice(0), pts: stamp, dts: stamp });
  2672. track.len += silentFrame.length;
  2673. }
  2674. track.samples = samples;
  2675. this.remuxAudio(track, timeOffset, contiguous);
  2676. }
  2677. }, {
  2678. key: 'remuxID3',
  2679. value: function remuxID3(track, timeOffset) {
  2680. var length = track.samples.length,
  2681. sample;
  2682. // consume samples
  2683. if (length) {
  2684. for (var index = 0; index < length; index++) {
  2685. sample = track.samples[index];
  2686. // setting id3 pts, dts to relative time
  2687. // using this._initPTS and this._initDTS to calculate relative time
  2688. sample.pts = (sample.pts - this._initPTS) / this.PES_TIMESCALE;
  2689. sample.dts = (sample.dts - this._initDTS) / this.PES_TIMESCALE;
  2690. }
  2691. this.observer.trigger(_events2.default.FRAG_PARSING_METADATA, {
  2692. id: this.id,
  2693. level: this.level,
  2694. sn: this.sn,
  2695. samples: track.samples
  2696. });
  2697. }
  2698. track.samples = [];
  2699. timeOffset = timeOffset;
  2700. }
  2701. }, {
  2702. key: 'remuxText',
  2703. value: function remuxText(track, timeOffset) {
  2704. track.samples.sort(function (a, b) {
  2705. return a.pts - b.pts;
  2706. });
  2707. var length = track.samples.length,
  2708. sample;
  2709. // consume samples
  2710. if (length) {
  2711. for (var index = 0; index < length; index++) {
  2712. sample = track.samples[index];
  2713. // setting text pts, dts to relative time
  2714. // using this._initPTS and this._initDTS to calculate relative time
  2715. sample.pts = (sample.pts - this._initPTS) / this.PES_TIMESCALE;
  2716. }
  2717. this.observer.trigger(_events2.default.FRAG_PARSING_USERDATA, {
  2718. id: this.id,
  2719. level: this.level,
  2720. sn: this.sn,
  2721. samples: track.samples
  2722. });
  2723. }
  2724. track.samples = [];
  2725. timeOffset = timeOffset;
  2726. }
  2727. }, {
  2728. key: '_PTSNormalize',
  2729. value: function _PTSNormalize(value, reference) {
  2730. var offset;
  2731. if (reference === undefined) {
  2732. return value;
  2733. }
  2734. if (reference < value) {
  2735. // - 2^33
  2736. offset = -8589934592;
  2737. } else {
  2738. // + 2^33
  2739. offset = 8589934592;
  2740. }
  2741. /* PTS is 33bit (from 0 to 2^33 -1)
  2742. if diff between value and reference is bigger than half of the amplitude (2^32) then it means that
  2743. PTS looping occured. fill the gap */
  2744. while (Math.abs(value - reference) > 4294967296) {
  2745. value += offset;
  2746. }
  2747. return value;
  2748. }
  2749. }, {
  2750. key: 'passthrough',
  2751. get: function get() {
  2752. return false;
  2753. }
  2754. }]);
  2755. return MP4Remuxer;
  2756. }();
  2757. exports.default = MP4Remuxer;
  2758. },{"../errors":6,"../events":8,"../helper/aac":9,"../remux/mp4-generator":12,"../utils/logger":15,"../utils/polyfill":16}],14:[function(require,module,exports){
  2759. 'use strict';
  2760. Object.defineProperty(exports, "__esModule", {
  2761. value: true
  2762. });
  2763. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  2764. var _events = require('../events');
  2765. var _events2 = _interopRequireDefault(_events);
  2766. var _eventHandler = require('../event-handler');
  2767. var _eventHandler2 = _interopRequireDefault(_eventHandler);
  2768. var _h264Demuxer = require('../demux/h264-demuxer');
  2769. var _h264Demuxer2 = _interopRequireDefault(_h264Demuxer);
  2770. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  2771. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2772. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2773. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
  2774. * H264 NAL Slicer
  2775. */
  2776. var SlicesReader = function (_EventHandler) {
  2777. _inherits(SlicesReader, _EventHandler);
  2778. function SlicesReader(wfs) {
  2779. var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  2780. _classCallCheck(this, SlicesReader);
  2781. var _this = _possibleConstructorReturn(this, (SlicesReader.__proto__ || Object.getPrototypeOf(SlicesReader)).call(this, wfs, _events2.default.H264_DATA_PARSING));
  2782. _this.config = _this.wfs.config || config;
  2783. _this.h264Demuxer = new _h264Demuxer2.default(wfs);
  2784. _this.wfs = wfs;
  2785. _this.lastBuf = null;
  2786. _this.nals = [];
  2787. return _this;
  2788. }
  2789. _createClass(SlicesReader, [{
  2790. key: 'destroy',
  2791. value: function destroy() {
  2792. this.lastBuf = null;
  2793. this.nals = [];
  2794. _eventHandler2.default.prototype.destroy.call(this);
  2795. }
  2796. }, {
  2797. key: '_read',
  2798. value: function _read(buffer) {
  2799. var typedAr = null;
  2800. this.nals = [];
  2801. if (!buffer || buffer.byteLength < 1) return;
  2802. if (this.lastBuf) {
  2803. typedAr = new Uint8Array(buffer.byteLength + this.lastBuf.length);
  2804. typedAr.set(this.lastBuf);
  2805. typedAr.set(new Uint8Array(buffer), this.lastBuf.length);
  2806. } else {
  2807. typedAr = new Uint8Array(buffer);
  2808. }
  2809. var lastNalEndPos = 0;
  2810. var b1 = -1; // byte before one
  2811. var b2 = -2; // byte before two
  2812. var nalStartPos = new Array();
  2813. for (var i = 0; i < typedAr.length; i += 2) {
  2814. var b_0 = typedAr[i];
  2815. var b_1 = typedAr[i + 1];
  2816. if (b1 == 0 && b_0 == 0 && b_1 == 0) {
  2817. nalStartPos.push(i - 1);
  2818. } else if (b_1 == 1 && b_0 == 0 && b1 == 0 && b2 == 0) {
  2819. nalStartPos.push(i - 2);
  2820. }
  2821. b2 = b_0;
  2822. b1 = b_1;
  2823. }
  2824. if (nalStartPos.length > 1) {
  2825. for (var i = 0; i < nalStartPos.length - 1; ++i) {
  2826. this.nals.push(typedAr.subarray(nalStartPos[i], nalStartPos[i + 1] + 1));
  2827. lastNalEndPos = nalStartPos[i + 1];
  2828. }
  2829. } else {
  2830. lastNalEndPos = nalStartPos[0];
  2831. }
  2832. if (lastNalEndPos != 0 && lastNalEndPos < typedAr.length) {
  2833. this.lastBuf = typedAr.subarray(lastNalEndPos);
  2834. } else {
  2835. if (!!!this.lastBuf) {
  2836. this.lastBuf = typedAr;
  2837. }
  2838. var _newBuf = new Uint8Array(this.lastBuf.length + buffer.byteLength);
  2839. _newBuf.set(this.lastBuf);
  2840. _newBuf.set(new Uint8Array(buffer), this.lastBuf.length);
  2841. this.lastBuf = _newBuf;
  2842. }
  2843. }
  2844. }, {
  2845. key: 'onH264DataParsing',
  2846. value: function onH264DataParsing(event) {
  2847. this._read(event.data);
  2848. var $this = this;
  2849. this.nals.forEach(function (nal) {
  2850. $this.wfs.trigger(_events2.default.H264_DATA_PARSED, {
  2851. data: nal
  2852. });
  2853. });
  2854. }
  2855. }]);
  2856. return SlicesReader;
  2857. }(_eventHandler2.default);
  2858. exports.default = SlicesReader;
  2859. },{"../demux/h264-demuxer":5,"../event-handler":7,"../events":8}],15:[function(require,module,exports){
  2860. 'use strict';
  2861. Object.defineProperty(exports, "__esModule", {
  2862. value: true
  2863. });
  2864. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  2865. function noop() {}
  2866. var fakeLogger = {
  2867. trace: noop,
  2868. debug: noop,
  2869. log: noop,
  2870. warn: noop,
  2871. info: noop,
  2872. error: noop
  2873. };
  2874. var exportedLogger = fakeLogger;
  2875. //let lastCallTime;
  2876. // function formatMsgWithTimeInfo(type, msg) {
  2877. // const now = Date.now();
  2878. // const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';
  2879. // lastCallTime = now;
  2880. // msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )';
  2881. // return msg;
  2882. // }
  2883. function formatMsg(type, msg) {
  2884. msg = '[' + type + '] > ' + msg;
  2885. return msg;
  2886. }
  2887. function consolePrintFn(type) {
  2888. var func = window.console[type];
  2889. if (func) {
  2890. return function () {
  2891. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  2892. args[_key] = arguments[_key];
  2893. }
  2894. if (args[0]) {
  2895. args[0] = formatMsg(type, args[0]);
  2896. }
  2897. func.apply(window.console, args);
  2898. };
  2899. }
  2900. return noop;
  2901. }
  2902. function exportLoggerFunctions(debugConfig) {
  2903. for (var _len2 = arguments.length, functions = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  2904. functions[_key2 - 1] = arguments[_key2];
  2905. }
  2906. functions.forEach(function (type) {
  2907. exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);
  2908. });
  2909. }
  2910. var enableLogs = exports.enableLogs = function enableLogs(debugConfig) {
  2911. if (debugConfig === true || (typeof debugConfig === 'undefined' ? 'undefined' : _typeof(debugConfig)) === 'object') {
  2912. exportLoggerFunctions(debugConfig,
  2913. // Remove out from list here to hard-disable a log-level
  2914. //'trace',
  2915. 'debug', 'log', 'info', 'warn', 'error');
  2916. // Some browsers don't allow to use bind on console object anyway
  2917. // fallback to default if needed
  2918. try {
  2919. exportedLogger.log();
  2920. } catch (e) {
  2921. exportedLogger = fakeLogger;
  2922. }
  2923. } else {
  2924. exportedLogger = fakeLogger;
  2925. }
  2926. };
  2927. var logger = exports.logger = exportedLogger;
  2928. },{}],16:[function(require,module,exports){
  2929. 'use strict';
  2930. if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
  2931. ArrayBuffer.prototype.slice = function (start, end) {
  2932. var that = new Uint8Array(this);
  2933. if (end === undefined) {
  2934. end = that.length;
  2935. }
  2936. var result = new ArrayBuffer(end - start);
  2937. var resultArray = new Uint8Array(result);
  2938. for (var i = 0; i < resultArray.length; i++) {
  2939. resultArray[i] = that[i + start];
  2940. }
  2941. return result;
  2942. };
  2943. }
  2944. },{}],17:[function(require,module,exports){
  2945. 'use strict';
  2946. Object.defineProperty(exports, "__esModule", {
  2947. value: true
  2948. });
  2949. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  2950. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2951. /**
  2952. * XHR based logger
  2953. */
  2954. var XhrLoader = function () {
  2955. function XhrLoader(config) {
  2956. _classCallCheck(this, XhrLoader);
  2957. if (config && config.xhrSetup) {
  2958. this.xhrSetup = config.xhrSetup;
  2959. }
  2960. }
  2961. _createClass(XhrLoader, [{
  2962. key: 'destroy',
  2963. value: function destroy() {
  2964. this.abort();
  2965. this.loader = null;
  2966. }
  2967. }, {
  2968. key: 'abort',
  2969. value: function abort() {
  2970. var loader = this.loader;
  2971. if (loader && loader.readyState !== 4) {
  2972. this.stats.aborted = true;
  2973. loader.abort();
  2974. }
  2975. window.clearTimeout(this.requestTimeout);
  2976. this.requestTimeout = null;
  2977. window.clearTimeout(this.retryTimeout);
  2978. this.retryTimeout = null;
  2979. }
  2980. }, {
  2981. key: 'loadHead',
  2982. value: function loadHead(context, config, callbacks) {
  2983. this.context = context;
  2984. this.config = config;
  2985. this.callbacks = callbacks;
  2986. this.stats = { trequest: performance.now(), retry: 0 };
  2987. this.retryDelay = config.retryDelay;
  2988. var xhr = new XMLHttpRequest();
  2989. xhr.open('head', context.url);
  2990. xhr.onload = function () {
  2991. callbacks.onSuccess(xhr.getResponseHeader('content-length'));
  2992. };
  2993. xhr.send();
  2994. }
  2995. }, {
  2996. key: 'load',
  2997. value: function load(context, config, callbacks) {
  2998. this.context = context;
  2999. this.config = config;
  3000. this.callbacks = callbacks;
  3001. this.stats = { trequest: performance.now(), retry: 0 };
  3002. this.retryDelay = config.retryDelay;
  3003. this.loadInternal();
  3004. }
  3005. }, {
  3006. key: 'loadInternal',
  3007. value: function loadInternal() {
  3008. var xhr,
  3009. context = this.context;
  3010. if (typeof XDomainRequest !== 'undefined') {
  3011. xhr = this.loader = new XDomainRequest();
  3012. } else {
  3013. xhr = this.loader = new XMLHttpRequest();
  3014. }
  3015. xhr.onloadend = this.loadend.bind(this);
  3016. xhr.onprogress = this.loadprogress.bind(this);
  3017. xhr.open('GET', context.url, true);
  3018. if (context.rangeEnd) {
  3019. xhr.setRequestHeader('Range', 'bytes=' + context.rangeStart + '-' + (context.rangeEnd - 1));
  3020. }
  3021. xhr.responseType = context.responseType;
  3022. var stats = this.stats;
  3023. stats.tfirst = 0;
  3024. stats.loaded = 0;
  3025. if (this.xhrSetup) {
  3026. this.xhrSetup(xhr, context.url);
  3027. }
  3028. // setup timeout before we perform request
  3029. this.requestTimeout = window.setTimeout(this.loadtimeout.bind(this), this.config.timeout);
  3030. xhr.send();
  3031. }
  3032. }, {
  3033. key: 'loadend',
  3034. value: function loadend(event) {
  3035. var xhr = event.currentTarget,
  3036. status = xhr.status,
  3037. stats = this.stats,
  3038. context = this.context,
  3039. config = this.config;
  3040. // don't proceed if xhr has been aborted
  3041. if (stats.aborted) {
  3042. return;
  3043. }
  3044. // in any case clear the current xhrs timeout
  3045. window.clearTimeout(this.requestTimeout);
  3046. // http status between 200 to 299 are all successful
  3047. if (status >= 200 && status < 300) {
  3048. stats.tload = Math.max(stats.tfirst, performance.now());
  3049. var data = void 0,
  3050. len = void 0;
  3051. if (context.responseType === 'arraybuffer') {
  3052. data = xhr.response;
  3053. len = data.byteLength;
  3054. } else {
  3055. data = xhr.responseText;
  3056. len = data.length;
  3057. }
  3058. stats.loaded = stats.total = len;
  3059. var response = { url: xhr.responseURL, data: data };
  3060. this.callbacks.onSuccess(response, stats, context);
  3061. } else {
  3062. // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
  3063. if (stats.retry >= config.maxRetry || status >= 400 && status < 499) {
  3064. // logger.error(`${status} while loading ${context.url}` );
  3065. this.callbacks.onError({ code: status, text: xhr.statusText }, context);
  3066. } else {
  3067. // retry
  3068. // logger.warn(`${status} while loading ${context.url}, retrying in ${this.retryDelay}...`);
  3069. // aborts and resets internal state
  3070. this.destroy();
  3071. // schedule retry
  3072. this.retryTimeout = window.setTimeout(this.loadInternal.bind(this), this.retryDelay);
  3073. // set exponential backoff
  3074. this.retryDelay = Math.min(2 * this.retryDelay, config.maxRetryDelay);
  3075. stats.retry++;
  3076. }
  3077. }
  3078. }
  3079. }, {
  3080. key: 'loadtimeout',
  3081. value: function loadtimeout() {
  3082. // logger.warn(`timeout while loading ${this.context.url}` );
  3083. this.callbacks.onTimeout(this.stats, this.context);
  3084. }
  3085. }, {
  3086. key: 'loadprogress',
  3087. value: function loadprogress(event) {
  3088. var stats = this.stats;
  3089. if (stats.tfirst === 0) {
  3090. stats.tfirst = Math.max(performance.now(), stats.trequest);
  3091. }
  3092. stats.loaded = event.loaded;
  3093. if (event.lengthComputable) {
  3094. stats.total = event.total;
  3095. }
  3096. var onProgress = this.callbacks.onProgress;
  3097. if (onProgress) {
  3098. // last args is to provide on progress data
  3099. onProgress(stats, this.context, null);
  3100. }
  3101. }
  3102. }]);
  3103. return XhrLoader;
  3104. }();
  3105. exports.default = XhrLoader;
  3106. },{}],18:[function(require,module,exports){
  3107. /**
  3108. * WFS interface, Jeff Yang 2016.10
  3109. */
  3110. 'use strict';
  3111. Object.defineProperty(exports, "__esModule", {
  3112. value: true
  3113. });
  3114. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  3115. var _events = require('./events');
  3116. var _events2 = _interopRequireDefault(_events);
  3117. var _flowController = require('./controller/flow-controller');
  3118. var _flowController2 = _interopRequireDefault(_flowController);
  3119. var _bufferController = require('./controller/buffer-controller');
  3120. var _bufferController2 = _interopRequireDefault(_bufferController);
  3121. var _events3 = require('events');
  3122. var _events4 = _interopRequireDefault(_events3);
  3123. var _xhrLoader = require('./utils/xhr-loader');
  3124. var _xhrLoader2 = _interopRequireDefault(_xhrLoader);
  3125. var _websocketLoader = require('./loader/websocket-loader');
  3126. var _websocketLoader2 = _interopRequireDefault(_websocketLoader);
  3127. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  3128. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3129. var Wfs = function () {
  3130. _createClass(Wfs, null, [{
  3131. key: 'isSupported',
  3132. value: function isSupported() {
  3133. return window.MediaSource && typeof window.MediaSource.isTypeSupported === 'function' && window.MediaSource.isTypeSupported('video/mp4; codecs="avc1.42c01f,mp4a.40.2"');
  3134. }
  3135. }, {
  3136. key: 'version',
  3137. get: function get() {
  3138. // replaced with browserify-versionify transform
  3139. return '' + 'v.0.0.0.1';
  3140. }
  3141. }, {
  3142. key: 'Events',
  3143. get: function get() {
  3144. return _events2.default;
  3145. }
  3146. }, {
  3147. key: 'DefaultConfig',
  3148. get: function get() {
  3149. if (!Wfs.defaultConfig) {
  3150. Wfs.defaultConfig = {
  3151. autoStartLoad: true,
  3152. startPosition: -1,
  3153. debug: false,
  3154. fLoader: undefined,
  3155. loader: _xhrLoader2.default,
  3156. //loader: FetchLoader,
  3157. fmp4FileUrl: 'xxxx.mp4',
  3158. fragLoadingTimeOut: 20000,
  3159. fragLoadingMaxRetry: 6,
  3160. fragLoadingRetryDelay: 1000,
  3161. fragLoadingMaxRetryTimeout: 64000,
  3162. fragLoadingLoopThreshold: 3,
  3163. forceKeyFrameOnDiscontinuity: true,
  3164. appendErrorMaxRetry: 3
  3165. };
  3166. }
  3167. return Wfs.defaultConfig;
  3168. },
  3169. set: function set(defaultConfig) {
  3170. Wfs.defaultConfig = defaultConfig;
  3171. }
  3172. }]);
  3173. function Wfs() {
  3174. var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  3175. _classCallCheck(this, Wfs);
  3176. var defaultConfig = Wfs.DefaultConfig;
  3177. for (var prop in defaultConfig) {
  3178. if (prop in config) {
  3179. continue;
  3180. }
  3181. config[prop] = defaultConfig[prop];
  3182. }
  3183. this.config = config;
  3184. // observer setup
  3185. var observer = this.observer = new _events4.default();
  3186. observer.trigger = function trigger(event) {
  3187. for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  3188. data[_key - 1] = arguments[_key];
  3189. }
  3190. observer.emit.apply(observer, [event, event].concat(data));
  3191. };
  3192. observer.off = function off(event) {
  3193. for (var _len2 = arguments.length, data = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  3194. data[_key2 - 1] = arguments[_key2];
  3195. }
  3196. observer.removeListener.apply(observer, [event].concat(data));
  3197. };
  3198. this.on = observer.on.bind(observer);
  3199. this.off = observer.off.bind(observer);
  3200. this.trigger = observer.trigger.bind(observer);
  3201. this.flowController = new _flowController2.default(this);
  3202. this.bufferController = new _bufferController2.default(this);
  3203. // this.fileLoader = new FileLoader(this);
  3204. this.websocketLoader = new _websocketLoader2.default(this);
  3205. this.mediaType = undefined;
  3206. }
  3207. _createClass(Wfs, [{
  3208. key: 'destroy',
  3209. value: function destroy() {
  3210. this.flowController.destroy();
  3211. this.bufferController.destroy();
  3212. // this.fileLoader.destroy();
  3213. this.websocketLoader.destroy();
  3214. }
  3215. }, {
  3216. key: 'attachMedia',
  3217. value: function attachMedia(media) {
  3218. var channelName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'chX';
  3219. var mediaType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'H264Raw';
  3220. var websocketName = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'play2';
  3221. // 'H264Raw' 'FMp4'
  3222. this.mediaType = mediaType;
  3223. this.media = media;
  3224. this.trigger(_events2.default.MEDIA_ATTACHING, { media: media, channelName: channelName, mediaType: mediaType, websocketName: websocketName });
  3225. }
  3226. }, {
  3227. key: 'attachWebsocket',
  3228. value: function attachWebsocket(websocket, channelName) {
  3229. this.trigger(_events2.default.WEBSOCKET_ATTACHING, { websocket: websocket, mediaType: this.mediaType, channelName: channelName });
  3230. }
  3231. }]);
  3232. return Wfs;
  3233. }();
  3234. exports.default = Wfs;
  3235. },{"./controller/buffer-controller":2,"./controller/flow-controller":3,"./events":8,"./loader/websocket-loader":11,"./utils/xhr-loader":17,"events":1}]},{},[10])(10)
  3236. });
  3237. //# sourceMappingURL=wfs.js.map