wfs.js 156 KB

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