wfs.js 140 KB

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