vendor: 4,300 bytes, lines 1-129
1(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ 2/* $Date: 2007-06-12 18:02:31 $ */ 3 4// from: http://bannister.us/weblog/2007/06/09/simple-base64-encodedecode-javascript/ 5// Handles encode/decode of ASCII and Unicode strings. 6 7'use strict'; 8 9var UTF8 = {}; 10UTF8.encode = function (s) { 11 var u = []; 12 for (var i = 0; i < s.length; ++i) { 13 var c = s.charCodeAt(i); 14 if (c < 0x80) { 15 u.push(c); 16 } else if (c < 0x800) { 17 u.push(0xC0 | c >> 6); 18 u.push(0x80 | 63 & c); 19 } else if (c < 0x10000) { 20 u.push(0xE0 | c >> 12); 21 u.push(0x80 | 63 & c >> 6); 22 u.push(0x80 | 63 & c); 23 } else { 24 u.push(0xF0 | c >> 18); 25 u.push(0x80 | 63 & c >> 12); 26 u.push(0x80 | 63 & c >> 6); 27 u.push(0x80 | 63 & c); 28 } 29 } 30 return u; 31}; 32UTF8.decode = function (u) { 33 var a = []; 34 var i = 0; 35 while (i < u.length) { 36 var v = u[i++]; 37 if (v < 0x80) { 38 // no need to mask byte 39 } else if (v < 0xE0) { 40 v = (31 & v) << 6; 41 v |= 63 & u[i++]; 42 } else if (v < 0xF0) { 43 v = (15 & v) << 12; 44 v |= (63 & u[i++]) << 6; 45 v |= 63 & u[i++]; 46 } else { 47 v = (7 & v) << 18; 48 v |= (63 & u[i++]) << 12; 49 v |= (63 & u[i++]) << 6; 50 v |= 63 & u[i++]; 51 } 52 a.push(String.fromCharCode(v)); 53 } 54 return a.join(''); 55}; 56 57var BASE64 = {}; 58(function (T) { 59 var encodeArray = function encodeArray(u) { 60 var i = 0; 61 var a = []; 62 var n = 0 | u.length / 3; 63 while (0 < n--) { 64 var v = (u[i] << 16) + (u[i + 1] << 8) + u[i + 2]; 65 i += 3; 66 a.push(T.charAt(63 & v >> 18)); 67 a.push(T.charAt(63 & v >> 12)); 68 a.push(T.charAt(63 & v >> 6)); 69 a.push(T.charAt(63 & v)); 70 } 71 if (2 == u.length - i) { 72 var v = (u[i] << 16) + (u[i + 1] << 8); 73 a.push(T.charAt(63 & v >> 18)); 74 a.push(T.charAt(63 & v >> 12)); 75 a.push(T.charAt(63 & v >> 6)); 76 a.push('='); 77 } else if (1 == u.length - i) { 78 var v = u[i] << 16; 79 a.push(T.charAt(63 & v >> 18)); 80 a.push(T.charAt(63 & v >> 12)); 81 a.push('=='); 82 } 83 return a.join(''); 84 }; 85 var R = (function () { 86 var a = []; 87 for (var i = 0; i < T.length; ++i) { 88 a[T.charCodeAt(i)] = i; 89 } 90 a['='.charCodeAt(0)] = 0; 91 return a; 92 })(); 93 var decodeArray = function decodeArray(s) { 94 var i = 0; 95 var u = []; 96 var n = 0 | s.length / 4; 97 while (0 < n--) { 98 var v = (R[s.charCodeAt(i)] << 18) + (R[s.charCodeAt(i + 1)] << 12) + (R[s.charCodeAt(i + 2)] << 6) + R[s.charCodeAt(i + 3)]; 99 u.push(255 & v >> 16); 100 u.push(255 & v >> 8); 101 u.push(255 & v); 102 i += 4; 103 } 104 if (u) { 105 if ('=' == s.charAt(i - 2)) { 106 u.pop(); 107 u.pop(); 108 } else if ('=' == s.charAt(i - 1)) { 109 u.pop(); 110 } 111 } 112 return u; 113 }; 114 var ASCII = {}; 115 ASCII.encode = function (s) { 116 var u = []; 117 for (var i = 0; i < s.length; ++i) { 118 u.push(s.charCodeAt(i)); 119 } 120 return u; 121 }; 122 ASCII.decode = function (u) { 123 for (var i = 0; i < s.length; ++i) { 124 a[i] = String.fromCharCode(a[i]); 125 } 126 return a.join(''); 127 }; 128 BASE64.decodeArray = function (s) { 129 var u = decodeArray(s);
130 return new Uint8Array(u); 131 }; 132 BASE64.encodeASCII = function (s) { 133 var u = ASCII.encode(s); 134 return encodeArray(u); 135 }; 136 BASE64.decodeASCII = function (s) { 137 var a = decodeArray(s); 138 return ASCII.decode(a); 139 }; 140 BASE64.encode = function (s) { 141 var u = UTF8.encode(s); 142 return encodeArray(u); 143 }; 144 BASE64.decode = function (s) { 145 var u = decodeArray(s); 146 return UTF8.decode(u); 147 }; 148})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); 149 150/*The following polyfills are not used in dash.js but have caused multiplayer integration issues. 151 Therefore commenting them out. 152if (undefined === btoa) { 153 var btoa = BASE64.encode; 154} 155if (undefined === atob) { 156 var atob = BASE64.decode; 157} 158*/ 159 160if (typeof exports !== 'undefined') { 161 exports.decode = BASE64.decode; 162 exports.decodeArray = BASE64.decodeArray; 163} 164 165},{}],2:[function(_dereq_,module,exports){ 166/** 167 * The copyright in this software is being made available under the BSD License, 168 * included below. This software may be subject to other third party and contributor 169 * rights, including patent rights, and no such rights are granted under this license. 170 * 171 * Copyright (c) 2015-2016, DASH Industry Forum. 172 * All rights reserved. 173 * 174 * Redistribution and use in source and binary forms, with or without modification, 175 * are permitted provided that the following conditions are met: 176 * 1. Redistributions of source code must retain the above copyright notice, this 177 * list of conditions and the following disclaimer. 178 * * Redistributions in binary form must reproduce the above copyright notice, 179 * this list of conditions and the following disclaimer in the documentation and/or 180 * other materials provided with the distribution. 181 * 2. Neither the name of Dash Industry Forum nor the names of its 182 * contributors may be used to endorse or promote products derived from this software 183 * without specific prior written permission. 184 * 185 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 186 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 187 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 188 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 189 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 190 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 191 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 192 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 193 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 194 * POSSIBILITY OF SUCH DAMAGE. 195 */ 196'use strict'; 197 198(function (exports) { 199 200 "use strict"; 201 202 /** 203 * Exceptions from regular ASCII. CodePoints are mapped to UTF-16 codes 204 */ 205 206 var specialCea608CharsCodes = { 207 0x2a: 0xe1, // lowercase a, acute accent 208 0x5c: 0xe9, // lowercase e, acute accent 209 0x5e: 0xed, // lowercase i, acute accent 210 0x5f: 0xf3, // lowercase o, acute accent 211 0x60: 0xfa, // lowercase u, acute accent 212 0x7b: 0xe7, // lowercase c with cedilla 213 0x7c: 0xf7, // division symbol 214 0x7d: 0xd1, // uppercase N tilde 215 0x7e: 0xf1, // lowercase n tilde 216 0x7f: 0x2588, // Full block 217 // THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS 218 // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F 219 // THIS MEANS THAT \x50 MUST BE ADDED TO THE VALUES 220 0x80: 0xae, // Registered symbol (R) 221 0x81: 0xb0, // degree sign 222 0x82: 0xbd, // 1/2 symbol 223 0x83: 0xbf, // Inverted (open) question mark 224 0x84: 0x2122, // Trademark symbol (TM) 225 0x85: 0xa2, // Cents symbol 226 0x86: 0xa3, // Pounds sterling 227 0x87: 0x266a, // Music 8'th note 228 0x88: 0xe0, // lowercase a, grave accent 229 0x89: 0x20, // transparent space (regular) 230 0x8a: 0xe8, // lowercase e, grave accent 231 0x8b: 0xe2, // lowercase a, circumflex accent 232 0x8c: 0xea, // lowercase e, circumflex accent 233 0x8d: 0xee, // lowercase i, circumflex accent 234 0x8e: 0xf4, // lowercase o, circumflex accent 235 0x8f: 0xfb, // lowercase u, circumflex accent 236 // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS 237 // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F 238 0x90: 0xc1, // capital letter A with acute
239 0x91: 0xc9, // capital letter E with acute 240 0x92: 0xd3, // capital letter O with acute 241 0x93: 0xda, // capital letter U with acute 242 0x94: 0xdc, // capital letter U with diaresis 243 0x95: 0xfc, // lowercase letter U with diaeresis 244 0x96: 0x2018, // opening single quote 245 0x97: 0xa1, // inverted exclamation mark 246 0x98: 0x2a, // asterisk 247 0x99: 0x2019, // closing single quote 248 0x9a: 0x2501, // box drawings heavy horizontal 249 0x9b: 0xa9, // copyright sign 250 0x9c: 0x2120, // Service mark 251 0x9d: 0x2022, // (round) bullet 252 0x9e: 0x201c, // Left double quotation mark 253 0x9f: 0x201d, // Right double quotation mark 254 0xa0: 0xc0, // uppercase A, grave accent 255 0xa1: 0xc2, // uppercase A, circumflex 256 0xa2: 0xc7, // uppercase C with cedilla 257 0xa3: 0xc8, // uppercase E, grave accent 258 0xa4: 0xca, // uppercase E, circumflex 259 0xa5: 0xcb, // capital letter E with diaresis 260 0xa6: 0xeb, // lowercase letter e with diaresis 261 0xa7: 0xce, // uppercase I, circumflex 262 0xa8: 0xcf, // uppercase I, with diaresis 263 0xa9: 0xef, // lowercase i, with diaresis 264 0xaa: 0xd4, // uppercase O, circumflex 265 0xab: 0xd9, // uppercase U, grave accent 266 0xac: 0xf9, // lowercase u, grave accent 267 0xad: 0xdb, // uppercase U, circumflex 268 0xae: 0xab, // left-pointing double angle quotation mark 269 0xaf: 0xbb, // right-pointing double angle quotation mark 270 // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS 271 // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F 272 0xb0: 0xc3, // Uppercase A, tilde 273 0xb1: 0xe3, // Lowercase a, tilde 274 0xb2: 0xcd, // Uppercase I, acute accent 275 0xb3: 0xcc, // Uppercase I, grave accent 276 0xb4: 0xec, // Lowercase i, grave accent 277 0xb5: 0xd2, // Uppercase O, grave accent 278 0xb6: 0xf2, // Lowercase o, grave accent 279 0xb7: 0xd5, // Uppercase O, tilde 280 0xb8: 0xf5, // Lowercase o, tilde 281 0xb9: 0x7b, // Open curly brace 282 0xba: 0x7d, // Closing curly brace 283 0xbb: 0x5c, // Backslash 284 0xbc: 0x5e, // Caret 285 0xbd: 0x5f, // Underscore 286 0xbe: 0x7c, // Pipe (vertical line) 287 0xbf: 0x223c, // Tilde operator 288 0xc0: 0xc4, // Uppercase A, umlaut 289 0xc1: 0xe4, // Lowercase A, umlaut 290 0xc2: 0xd6, // Uppercase O, umlaut 291 0xc3: 0xf6, // Lowercase o, umlaut 292 0xc4: 0xdf, // Esszett (sharp S) 293 0xc5: 0xa5, // Yen symbol 294 0xc6: 0xa4, // Generic currency sign 295 0xc7: 0x2503, // Box drawings heavy vertical 296 0xc8: 0xc5, // Uppercase A, ring 297 0xc9: 0xe5, // Lowercase A, ring 298 0xca: 0xd8, // Uppercase O, stroke 299 0xcb: 0xf8, // Lowercase o, strok 300 0xcc: 0x250f, // Box drawings heavy down and right 301 0xcd: 0x2513, // Box drawings heavy down and left 302 0xce: 0x2517, // Box drawings heavy up and right 303 0xcf: 0x251b // Box drawings heavy up and left 304 }; 305 306 /** 307 * Get Unicode Character from CEA-608 byte code 308 */ 309 var getCharForByte = function getCharForByte(byte) { 310 var charCode = byte; 311 if (specialCea608CharsCodes.hasOwnProperty(byte)) { 312 charCode = specialCea608CharsCodes[byte]; 313 } 314 return String.fromCharCode(charCode); 315 }; 316 317 var NR_ROWS = 15, 318 NR_COLS = 32; 319 // Tables to look up row from PAC data 320 var rowsLowCh1 = { 0x11: 1, 0x12: 3, 0x15: 5, 0x16: 7, 0x17: 9, 0x10: 11, 0x13: 12, 0x14: 14 }; 321 var rowsHighCh1 = { 0x11: 2, 0x12: 4, 0x15: 6, 0x16: 8, 0x17: 10, 0x13
vendor: 22,304 bytes, lines 321-951
321: 13, 0x14: 15 }; 322 var rowsLowCh2 = { 0x19: 1, 0x1A: 3, 0x1D: 5, 0x1E: 7, 0x1F: 9, 0x18: 11, 0x1B: 12, 0x1C: 14 }; 323 var rowsHighCh2 = { 0x19: 2, 0x1A: 4, 0x1D: 6, 0x1E: 8, 0x1F: 10, 0x1B: 13, 0x1C: 15 }; 324 325 var backgroundColors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'black', 'transparent']; 326 327 /** 328 * Simple logger class to be able to write with time-stamps and filter on level. 329 */ 330 var logger = { 331 verboseFilter: { 'DATA': 3, 'DEBUG': 3, 'INFO': 2, 'WARNING': 2, 'TEXT': 1, 'ERROR': 0 }, 332 time: null, 333 verboseLevel: 0, // Only write errors 334 setTime: function setTime(newTime) { 335 this.time = newTime; 336 }, 337 log: function log(severity, msg) { 338 var minLevel = this.verboseFilter[severity]; 339 if (this.verboseLevel >= minLevel) { 340 console.log(this.time + " [" + severity + "] " + msg); 341 } 342 } 343 }; 344 345 var numArrayToHexArray = function numArrayToHexArray(numArray) { 346 var hexArray = []; 347 for (var j = 0; j < numArray.length; j++) { 348 hexArray.push(numArray[j].toString(16)); 349 } 350 return hexArray; 351 }; 352 353 /** 354 * State of CEA-608 pen or character 355 * @constructor 356 */ 357 var PenState = function PenState(foreground, underline, italics, background, flash) { 358 this.foreground = foreground || "white"; 359 this.underline = underline || false; 360 this.italics = italics || false; 361 this.background = background || "black"; 362 this.flash = flash || false; 363 }; 364 365 PenState.prototype = { 366 367 reset: function reset() { 368 this.foreground = "white"; 369 this.underline = false; 370 this.italics = false; 371 this.background = "black"; 372 this.flash = false; 373 }, 374 375 setStyles: function setStyles(styles) { 376 var attribs = ["foreground", "underline", "italics", "background", "flash"]; 377 for (var i = 0; i < attribs.length; i++) { 378 var style = attribs[i]; 379 if (styles.hasOwnProperty(style)) { 380 this[style] = styles[style]; 381 } 382 } 383 }, 384 385 isDefault: function isDefault() { 386 return this.foreground === "white" && !this.underline && !this.italics && this.background === "black" && !this.flash; 387 }, 388 389 equals: function equals(other) { 390 return this.foreground === other.foreground && this.underline === other.underline && this.italics === other.italics && this.background === other.background && this.flash === other.flash; 391 }, 392 393 copy: function copy(newPenState) { 394 this.foreground = newPenState.foreground; 395 this.underline = newPenState.underline; 396 this.italics = newPenState.italics; 397 this.background = newPenState.background; 398 this.flash = newPenState.flash; 399 }, 400 401 toString: function toString() { 402 return "color=" + this.foreground + ", underline=" + this.underline + ", italics=" + this.italics + ", background=" + this.background + ", flash=" + this.flash; 403 } 404 }; 405 406 /** 407 * Unicode character with styling and background. 408 * @constructor 409 */ 410 var StyledUnicodeChar = function StyledUnicodeChar(uchar, foreground, underline, italics, background, flash) { 411 this.uchar = uchar || ' '; // unicode character 412 this.penState = new PenState(foreground, underline, italics, background, flash); 413 }; 414 415 StyledUnicodeChar.prototype = { 416 417 reset: function reset() { 418 this.uchar = ' '; 419 this.penState.reset(); 420 }, 421 422 setChar: function setChar(uchar, newPenState) { 423 this.uchar = uchar; 424 this.penState.copy(newPenState); 425 }, 426 427 setPenState: function setPenState(newPenState) { 428 this.penState.copy(newPenState); 429 }, 430 431 equals: function equals(other) { 432 return this.uchar === other.uchar && this.penState.equals(other.penState); 433 }, 434 435 copy: function copy(newChar) { 436 this.uchar = newChar.uchar; 437 this.penState.copy(newChar.penState); 438 }, 439 440 isEmpty: function isEmpty() { 441 return this.uchar === ' ' && this.penState.isDefault(); 442 } 443 }; 444 445 /** 446 * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar. 447 * @constructor 448 */ 449 var Row = function Row() { 450 this.chars = []; 451 for (var i = 0; i < NR_COLS; i++) { 452 this.chars.push(new StyledUnicodeChar()); 453 } 454 this.pos = 0; 455 this.currPenState = new PenState(); 456 }; 457 458 Row.prototype = { 459 460 equals: function equals(other) { 461 var equal = true; 462 for (var i = 0; i < NR_COLS; i++) { 463 if (!this.chars[i].equals(other.chars[i])) { 464 equal = false; 465 break; 466 } 467 } 468 return equal; 469 }, 470 471 copy: function copy(other) { 472 for (var i = 0; i < NR_COLS; i++) { 473 this.chars[i].copy(other.chars[i]); 474 } 475 }, 476 477 isEmpty: function isEmpty() { 478 var empty = true; 479 for (var i = 0; i < NR_COLS; i++) { 480 if (!this.chars[i].isEmpty()) { 481 empty = false; 482 break; 483 } 484 } 485 return empty; 486 }, 487 488 /** 489 * Set the cursor to a valid column. 490 */ 491 setCursor: function setCursor(absPos) { 492 if (this.pos !== absPos) { 493 this.pos = absPos; 494 } 495 if (this.pos < 0) { 496 logger.log("ERROR", "Negative cursor position " + this.pos); 497 this.pos = 0; 498 } else if (this.pos > NR_COLS) { 499 logger.log("ERROR", "Too large cursor position " + this.pos); 500 this.pos = NR_COLS; 501 } 502 }, 503 504 /** 505 * Move the cursor relative to current position. 506 */ 507 moveCursor: function moveCursor(relPos) { 508 var newPos = this.pos + relPos; 509 if (relPos > 1) { 510 for (var i = this.pos + 1; i < newPos + 1; i++) { 511 this.chars[i].setPenState(this.currPenState); 512 } 513 } 514 this.setCursor(newPos); 515 }, 516 517 /** 518 * Backspace, move one step back and clear character. 519 */ 520 backSpace: function backSpace() { 521 this.moveCursor(-1); 522 this.chars[this.pos].setChar(' ', this.currPenState); 523 }, 524 525 insertChar: function insertChar(byte) { 526 if (byte >= 0x90) { 527 //Extended char 528 this.backSpace(); 529 } 530 var char = getCharForByte(byte); 531 if (this.pos >= NR_COLS) { 532 logger.log("ERROR", "Cannot insert " + byte.toString(16) + " (" + char + ") at position " + this.pos + ". Skipping it!"); 533 return; 534 } 535 this.chars[this.pos].setChar(char, this.currPenState); 536 this.moveCursor(1); 537 }, 538 539 clearFromPos: function clearFromPos(startPos) { 540 var i; 541 for (i = startPos; i < NR_COLS; i++) { 542 this.chars[i].reset(); 543 } 544 }, 545 546 clear: function clear() { 547 this.clearFromPos(0); 548 this.pos = 0; 549 this.currPenState.reset(); 550 }, 551 552 clearToEndOfRow: function clearToEndOfRow() { 553 this.clearFromPos(this.pos); 554 }, 555 556 getTextString: function getTextString() { 557 var chars = []; 558 var empty = true; 559 for (var i = 0; i < NR_COLS; i++) { 560 var char = this.chars[i].uchar; 561 if (char !== " ") { 562 empty = false; 563 } 564 chars.push(char); 565 } 566 if (empty) { 567 return ""; 568 } else { 569 return chars.join(""); 570 } 571 }, 572 573 setPenStyles: function setPenStyles(styles) { 574 this.currPenState.setStyles(styles); 575 var currChar = this.chars[this.pos]; 576 currChar.setPenState(this.currPenState); 577 } 578 }; 579 580 /** 581 * Keep a CEA-608 screen of 32x15 styled characters 582 * @constructor 583 */ 584 var CaptionScreen = function CaptionScreen() { 585 586 this.rows = []; 587 for (var i = 0; i < NR_ROWS; i++) { 588 this.rows.push(new Row()); // Note that we use zero-based numbering (0-14) 589 } 590 this.currRow = NR_ROWS - 1; 591 this.nrRollUpRows = null; 592 this.reset(); 593 }; 594 595 CaptionScreen.prototype = { 596 597 reset: function reset() { 598 for (var i = 0; i < NR_ROWS; i++) { 599 this.rows[i].clear(); 600 } 601 this.currRow = NR_ROWS - 1; 602 }, 603 604 equals: function equals(other) { 605 var equal = true; 606 for (var i = 0; i < NR_ROWS; i++) { 607 if (!this.rows[i].equals(other.rows[i])) { 608 equal = false; 609 break; 610 } 611 } 612 return equal; 613 }, 614 615 copy: function copy(other) { 616 for (var i = 0; i < NR_ROWS; i++) { 617 this.rows[i].copy(other.rows[i]); 618 } 619 }, 620 621 isEmpty: function isEmpty() { 622 var empty = true; 623 for (var i = 0; i < NR_ROWS; i++) { 624 if (!this.rows[i].isEmpty()) { 625 empty = false; 626 break; 627 } 628 } 629 return empty; 630 }, 631 632 backSpace: function backSpace() { 633 var row = this.rows[this.currRow]; 634 row.backSpace(); 635 }, 636 637 clearToEndOfRow: function clearToEndOfRow() { 638 var row = this.rows[this.currRow]; 639 row.clearToEndOfRow(); 640 }, 641 642 /** 643 * Insert a character (without styling) in the current row. 644 */ 645 insertChar: function insertChar(char) { 646 var row = this.rows[this.currRow]; 647 row.insertChar(char); 648 }, 649 650 setPen: function setPen(styles) { 651 var row = this.rows[this.currRow]; 652 row.setPenStyles(styles); 653 }, 654 655 moveCursor: function moveCursor(relPos) { 656 var row = this.rows[this.currRow]; 657 row.moveCursor(relPos); 658 }, 659 660 setCursor: function setCursor(absPos) { 661 logger.log("INFO", "setCursor: " + absPos); 662 var row = this.rows[this.currRow]; 663 row.setCursor(absPos); 664 }, 665 666 setPAC: function setPAC(pacData) { 667 logger.log("INFO", "pacData = " + JSON.stringify(pacData)); 668 var newRow = pacData.row - 1; 669 if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) { 670 newRow = this.nrRollUpRows - 1; 671 } 672 this.currRow = newRow; 673 var row = this.rows[this.currRow]; 674 if (pacData.indent !== null) { 675 var indent = pacData.indent; 676 var prevPos = Math.max(indent - 1, 0); 677 row.setCursor(pacData.indent); 678 pacData.color = row.chars[prevPos].penState.foreground; 679 } 680 var styles = { foreground: pacData.color, underline: pacData.underline, italics: pacData.italics, background: 'black', flash: false }; 681 this.setPen(styles); 682 }, 683 684 /** 685 * Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility). 686 */ 687 setBkgData: function setBkgData(bkgData) { 688 689 logger.log("INFO", "bkgData = " + JSON.stringify(bkgData)); 690 this.backSpace(); 691 this.setPen(bkgData); 692 this.insertChar(0x20); //Space 693 }, 694 695 setRollUpRows: function setRollUpRows(nrRows) { 696 this.nrRollUpRows = nrRows; 697 }, 698 699 rollUp: function rollUp() { 700 if (this.nrRollUpRows === null) { 701 logger.log("DEBUG", "roll_up but nrRollUpRows not set yet"); 702 return; //Not properly setup 703 } 704 logger.log("TEXT", this.getDisplayText()); 705 var topRowIndex = this.currRow + 1 - this.nrRollUpRows; 706 var topRow = this.rows.splice(topRowIndex, 1)[0]; 707 topRow.clear(); 708 this.rows.splice(this.currRow, 0, topRow); 709 logger.log("INFO", "Rolling up"); 710 //logger.log("TEXT", this.get_display_text()) 711 }, 712 713 /** 714 * Get all non-empty rows with as unicode text. 715 */ 716 getDisplayText: function getDisplayText(asOneRow) { 717 asOneRow = asOneRow || false; 718 var displayText = []; 719 var text = ""; 720 var rowNr = -1; 721 for (var i = 0; i < NR_ROWS; i++) { 722 var rowText = this.rows[i].getTextString(); 723 if (rowText) { 724 rowNr = i + 1; 725 if (asOneRow) { 726 displayText.push("Row " + rowNr + ': "' + rowText + '"'); 727 } else { 728 displayText.push(rowText.trim()); 729 } 730 } 731 } 732 if (displayText.length > 0) { 733 if (asOneRow) { 734 text = "[" + displayText.join(" | ") + "]"; 735 } else { 736 text = displayText.join("\n"); 737 } 738 } 739 return text; 740 }, 741 742 getTextAndFormat: function getTextAndFormat() { 743 return this.rows; 744 } 745 }; 746 747 /** 748 * Handle a CEA-608 channel and send decoded data to outputFilter 749 * @constructor 750 * @param {Number} channelNumber (1 or 2) 751 * @param {CueHandler} outputFilter Output from channel1 newCue(startTime, endTime, captionScreen) 752 */ 753 var Cea608Channel = function Cea608Channel(channelNumber, outputFilter) { 754 755 this.chNr = channelNumber; 756 this.outputFilter = outputFilter; 757 this.mode = null; 758 this.verbose = 0; 759 this.displayedMemory = new CaptionScreen(); 760 this.nonDisplayedMemory = new CaptionScreen(); 761 this.lastOutputScreen = new CaptionScreen(); 762 this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1]; 763 this.writeScreen = this.displayedMemory; 764 this.mode = null; 765 this.cueStartTime = null; // Keeps track of where a cue started. 766 }; 767 768 Cea608Channel.prototype = { 769 770 modes: ["MODE_ROLL-UP", "MODE_POP-ON", "MODE_PAINT-ON", "MODE_TEXT"], 771 772 reset: function reset() { 773 this.mode = null; 774 this.displayedMemory.reset(); 775 this.nonDisplayedMemory.reset(); 776 this.lastOutputScreen.reset(); 777 this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1]; 778 this.writeScreen = this.displayedMemory; 779 this.mode = null; 780 this.cueStartTime = null; 781 this.lastCueEndTime = null; 782 }, 783 784 getHandler: function getHandler() { 785 return this.outputFilter; 786 }, 787 788 setHandler: function setHandler(newHandler) { 789 this.outputFilter = newHandler; 790 }, 791 792 setPAC: function setPAC(pacData) { 793 this.writeScreen.setPAC(pacData); 794 }, 795 796 setBkgData: function setBkgData(bkgData) { 797 this.writeScreen.setBkgData(bkgData); 798 }, 799 800 setMode: function setMode(newMode) { 801 if (newMode === this.mode) { 802 return; 803 } 804 this.mode = newMode; 805 logger.log("INFO", "MODE=" + newMode); 806 if (this.mode == "MODE_POP-ON") { 807 this.writeScreen = this.nonDisplayedMemory; 808 } else { 809 this.writeScreen = this.displayedMemory; 810 this.writeScreen.reset(); 811 } 812 if (this.mode !== "MODE_ROLL-UP") { 813 this.displayedMemory.nrRollUpRows = null; 814 this.nonDisplayedMemory.nrRollUpRows = null; 815 } 816 this.mode = newMode; 817 }, 818 819 insertChars: function insertChars(chars) { 820 for (var i = 0; i < chars.length; i++) { 821 this.writeScreen.insertChar(chars[i]); 822 } 823 var screen = this.writeScreen === this.displayedMemory ? "DISP" : "NON_DISP"; 824 logger.log("INFO", screen + ": " + this.writeScreen.getDisplayText(true)); 825 if (this.mode === "MODE_PAINT-ON" || this.mode === "MODE_ROLL-UP") { 826 logger.log("TEXT", "DISPLAYED: " + this.displayedMemory.getDisplayText(true)); 827 this.outputDataUpdate(); 828 } 829 }, 830 831 cc_RCL: function cc_RCL() { 832 // Resume Caption Loading (switch mode to Pop On) 833 logger.log("INFO", "RCL - Resume Caption Loading"); 834 this.setMode("MODE_POP-ON"); 835 }, 836 cc_BS: function cc_BS() { 837 // BackSpace 838 logger.log("INFO", "BS - BackSpace"); 839 if (this.mode === "MODE_TEXT") { 840 return; 841 } 842 this.writeScreen.backSpace(); 843 if (this.writeScreen === this.displayedMemory) { 844 this.outputDataUpdate(); 845 } 846 }, 847 cc_AOF: function cc_AOF() { 848 // Reserved (formerly Alarm Off) 849 return; 850 }, 851 cc_AON: function cc_AON() { 852 // Reserved (formerly Alarm On) 853 return; 854 }, 855 cc_DER: function cc_DER() { 856 // Delete to End of Row 857 logger.log("INFO", "DER- Delete to End of Row"); 858 this.writeScreen.clearToEndOfRow(); 859 this.outputDataUpdate(); 860 }, 861 cc_RU: function cc_RU(nrRows) { 862 //Roll-Up Captions-2,3,or 4 Rows 863 logger.log("INFO", "RU(" + nrRows + ") - Roll Up"); 864 this.writeScreen = this.displayedMemory; 865 this.setMode("MODE_ROLL-UP"); 866 this.writeScreen.setRollUpRows(nrRows); 867 }, 868 cc_FON: function cc_FON() { 869 //Flash On 870 logger.log("INFO", "FON - Flash On"); 871 this.writeScreen.setPen({ flash: true }); 872 }, 873 cc_RDC: function cc_RDC() { 874 // Resume Direct Captioning (switch mode to PaintOn) 875 logger.log("INFO", "RDC - Resume Direct Captioning"); 876 this.setMode("MODE_PAINT-ON"); 877 }, 878 cc_TR: function cc_TR() { 879 // Text Restart in text mode (not supported, however) 880 logger.log("INFO", "TR"); 881 this.setMode("MODE_TEXT"); 882 }, 883 cc_RTD: function cc_RTD() { 884 // Resume Text Display in Text mode (not supported, however) 885 logger.log("INFO", "RTD"); 886 this.setMode("MODE_TEXT"); 887 }, 888 cc_EDM: function cc_EDM() { 889 // Erase Displayed Memory 890 logger.log("INFO", "EDM - Erase Displayed Memory"); 891 this.displayedMemory.reset(); 892 this.outputDataUpdate(); 893 }, 894 cc_CR: function cc_CR() { 895 // Carriage Return 896 logger.log("CR - Carriage Return"); 897 this.writeScreen.rollUp(); 898 this.outputDataUpdate(); 899 }, 900 cc_ENM: function cc_ENM() { 901 //Erase Non-Displayed Memory 902 logger.log("INFO", "ENM - Erase Non-displayed Memory"); 903 this.nonDisplayedMemory.reset(); 904 }, 905 cc_EOC: function cc_EOC() { 906 //End of Caption (Flip Memories) 907 logger.log("INFO", "EOC - End Of Caption"); 908 if (this.mode === "MODE_POP-ON") { 909 var tmp = this.displayedMemory; 910 this.displayedMemory = this.nonDisplayedMemory; 911 this.nonDisplayedMemory = tmp; 912 this.writeScreen = this.nonDisplayedMemory; 913 logger.log("TEXT", "DISP: " + this.displayedMemory.getDisplayText()); 914 } 915 this.outputDataUpdate(); 916 }, 917 cc_TO: function cc_TO(nrCols) { 918 // Tab Offset 1,2, or 3 columns 919 logger.log("INFO", "TO(" + nrCols + ") - Tab Offset"); 920 this.writeScreen.moveCursor(nrCols); 921 }, 922 cc_MIDROW: function cc_MIDROW(secondByte) { 923 // Parse MIDROW command 924 var styles = { flash: false }; 925 styles.underline = secondByte % 2 === 1; 926 styles.italics = secondByte >= 0x2e; 927 if (!styles.italics) { 928 var colorIndex = Math.floor(secondByte / 2) - 0x10; 929 var colors = ["white", "green", "blue", "cyan", "red", "yellow", "magenta"]; 930 styles.foreground = colors[colorIndex]; 931 } else { 932 styles.foreground = "white"; 933 } 934 logger.log("INFO", "MIDROW: " + JSON.stringify(styles)); 935 this.writeScreen.setPen(styles); 936 }, 937 938 outputDataUpdate: function outputDataUpdate() { 939 var t = logger.time; 940 if (t === null) { 941 return; 942 } 943 if (this.outputFilter) { 944 if (this.outputFilter.updateData) { 945 this.outputFilter.updateData(t, this.displayedMemory); 946 } 947 if (this.cueStartTime === null && !this.displayedMemory.isEmpty()) { 948 // Start of a new cue 949 this.cueStartTime = t; 950 } else { 951 if (!this.displayedMemory.equals(this.lastOutputScreen)
vendor: 6,140 bytes, lines 951-1104
951) { 952 if (this.outputFilter.newCue) { 953 this.outputFilter.newCue(this.cueStartTime, t, this.lastOutputScreen); 954 } 955 this.cueStartTime = this.displayedMemory.isEmpty() ? null : t; 956 } 957 } 958 this.lastOutputScreen.copy(this.displayedMemory); 959 } 960 }, 961 962 cueSplitAtTime: function cueSplitAtTime(t) { 963 if (this.outputFilter) { 964 if (!this.displayedMemory.isEmpty()) { 965 if (this.outputFilter.newCue) { 966 this.outputFilter.newCue(this.cueStartTime, t, this.displayedMemory); 967 } 968 this.cueStartTime = t; 969 } 970 } 971 } 972 }; 973 974 /** 975 * Parse CEA-608 data and send decoded data to out1 and out2. 976 * @constructor 977 * @param {Number} field CEA-608 field (1 or 2) 978 * @param {CueHandler} out1 Output from channel1 newCue(startTime, endTime, captionScreen) 979 * @param {CueHandler} out2 Output from channel2 newCue(startTime, endTime, captionScreen) 980 */ 981 var Cea608Parser = function Cea608Parser(field, out1, out2) { 982 this.field = field || 1; 983 this.outputs = [out1, out2]; 984 this.channels = [new Cea608Channel(1, out1), new Cea608Channel(2, out2)]; 985 this.currChNr = -1; // Will be 1 or 2 986 this.lastCmdA = null; // First byte of last command 987 this.lastCmdB = null; // Second byte of last command 988 this.bufferedData = []; 989 this.startTime = null; 990 this.lastTime = null; 991 this.dataCounters = { 'padding': 0, 'char': 0, 'cmd': 0, 'other': 0 }; 992 }; 993 994 Cea608Parser.prototype = { 995 996 getHandler: function getHandler(index) { 997 return this.channels[index].getHandler(); 998 }, 999 1000 setHandler: function setHandler(index, newHandler) { 1001 this.channels[index].setHandler(newHandler); 1002 }, 1003 1004 /** 1005 * Add data for time t in forms of list of bytes (unsigned ints). The bytes are treated as pairs. 1006 */ 1007 addData: function addData(t, byteList) { 1008 var cmdFound, 1009 a, 1010 b, 1011 charsFound = false; 1012 1013 this.lastTime = t; 1014 logger.setTime(t); 1015 1016 for (var i = 0; i < byteList.length; i += 2) { 1017 a = byteList[i] & 0x7f; 1018 b = byteList[i + 1] & 0x7f; 1019 1020 if (a >= 0x10 && a <= 0x1f && a === this.lastCmdA && b === this.lastCmdB) { 1021 this.lastCmdA = null; 1022 this.lastCmdB = null; 1023 logger.log("DEBUG", "Repeated command (" + numArrayToHexArray([a, b]) + ") is dropped"); 1024 continue; // Repeated commands are dropped (once) 1025 } 1026 1027 if (a === 0 && b === 0) { 1028 this.dataCounters.padding += 2; 1029 continue; 1030 } else { 1031 logger.log("DATA", "[" + numArrayToHexArray([byteList[i], byteList[i + 1]]) + "] -> (" + numArrayToHexArray([a, b]) + ")"); 1032 } 1033 cmdFound = this.parseCmd(a, b); 1034 if (!cmdFound) { 1035 cmdFound = this.parseMidrow(a, b); 1036 } 1037 if (!cmdFound) { 1038 cmdFound = this.parsePAC(a, b); 1039 } 1040 if (!cmdFound) { 1041 cmdFound = this.parseBackgroundAttributes(a, b); 1042 } 1043 if (!cmdFound) { 1044 charsFound = this.parseChars(a, b); 1045 if (charsFound) { 1046 if (this.currChNr && this.currChNr >= 0) { 1047 var channel = this.channels[this.currChNr - 1]; 1048 channel.insertChars(charsFound); 1049 } else { 1050 logger.log("WARNING", "No channel found yet. TEXT-MODE?"); 1051 } 1052 } 1053 } 1054 if (cmdFound) { 1055 this.dataCounters.cmd += 2; 1056 } else if (charsFound) { 1057 this.dataCounters.char += 2; 1058 } else { 1059 this.dataCounters.other += 2; 1060 logger.log("WARNING", "Couldn't parse cleaned data " + numArrayToHexArray([a, b]) + " orig: " + numArrayToHexArray([byteList[i], byteList[i + 1]])); 1061 } 1062 } 1063 }, 1064 1065 /** 1066 * Parse Command. 1067 * @returns {Boolean} Tells if a command was found 1068 */ 1069 parseCmd: function parseCmd(a, b) { 1070 var chNr = null; 1071 1072 var cond1 = (a === 0x14 || a === 0x15 || a === 0x1C || a === 0x1D) && 0x20 <= b && b <= 0x2F; 1073 var cond2 = (a === 0x17 || a === 0x1F) && 0x21 <= b && b <= 0x23; 1074 if (!(cond1 || cond2)) { 1075 return false; 1076 } 1077 1078 if (a === 0x14 || a === 0x15 || a === 0x17) { 1079 chNr = 1; 1080 } else { 1081 chNr = 2; // (a === 0x1C || a === 0x1D || a=== 0x1f) 1082 } 1083 1084 var channel = this.channels[chNr - 1]; 1085 1086 if (a === 0x14 || a === 0x15 || a === 0x1C || a === 0x1D) { 1087 if (b === 0x20) { 1088 channel.cc_RCL(); 1089 } else if (b === 0x21) { 1090 channel.cc_BS(); 1091 } else if (b === 0x22) { 1092 channel.cc_AOF(); 1093 } else if (b === 0x23) { 1094 channel.cc_AON(); 1095 } else if (b === 0x24) { 1096 channel.cc_DER(); 1097 } else if (b === 0x25) { 1098 channel.cc_RU(2); 1099 } else if (b === 0x26) { 1100 channel.cc_RU(3); 1101 } else if (b === 0x27) { 1102 channel.cc_RU(4); 1103 } else if (b === 0x28) { 1104 channel.cc_FON();
vendor: 8,978 bytes, lines 1105-1345
1105 } else if (b === 0x29) { 1106 channel.cc_RDC(); 1107 } else if (b === 0x2A) { 1108 channel.cc_TR(); 1109 } else if (b === 0x2B) { 1110 channel.cc_RTD(); 1111 } else if (b === 0x2C) { 1112 channel.cc_EDM(); 1113 } else if (b === 0x2D) { 1114 channel.cc_CR(); 1115 } else if (b === 0x2E) { 1116 channel.cc_ENM(); 1117 } else if (b === 0x2F) { 1118 channel.cc_EOC(); 1119 } 1120 } else { 1121 //a == 0x17 || a == 0x1F 1122 channel.cc_TO(b - 0x20); 1123 } 1124 this.lastCmdA = a; 1125 this.lastCmdB = b; 1126 this.currChNr = chNr; 1127 return true; 1128 }, 1129 1130 /** 1131 * Parse midrow styling command 1132 * @returns {Boolean} 1133 */ 1134 parseMidrow: function parseMidrow(a, b) { 1135 var chNr = null; 1136 1137 if ((a === 0x11 || a === 0x19) && 0x20 <= b && b <= 0x2f) { 1138 if (a === 0x11) { 1139 chNr = 1; 1140 } else { 1141 chNr = 2; 1142 } 1143 if (chNr !== this.currChNr) { 1144 logger.log("ERROR", "Mismatch channel in midrow parsing"); 1145 return false; 1146 } 1147 var channel = this.channels[chNr - 1]; 1148 // cea608 spec says midrow codes should inject a space 1149 channel.insertChars([0x20]); 1150 channel.cc_MIDROW(b); 1151 logger.log("DEBUG", "MIDROW (" + numArrayToHexArray([a, b]) + ")"); 1152 this.lastCmdA = a; 1153 this.lastCmdB = b; 1154 return true; 1155 } 1156 return false; 1157 }, 1158 /** 1159 * Parse Preable Access Codes (Table 53). 1160 * @returns {Boolean} Tells if PAC found 1161 */ 1162 parsePAC: function parsePAC(a, b) { 1163 1164 var chNr = null; 1165 var row = null; 1166 1167 var case1 = (0x11 <= a && a <= 0x17 || 0x19 <= a && a <= 0x1F) && 0x40 <= b && b <= 0x7F; 1168 var case2 = (a === 0x10 || a === 0x18) && 0x40 <= b && b <= 0x5F; 1169 if (!(case1 || case2)) { 1170 return false; 1171 } 1172 1173 chNr = a <= 0x17 ? 1 : 2; 1174 1175 if (0x40 <= b && b <= 0x5F) { 1176 row = chNr === 1 ? rowsLowCh1[a] : rowsLowCh2[a]; 1177 } else { 1178 // 0x60 <= b <= 0x7F 1179 row = chNr === 1 ? rowsHighCh1[a] : rowsHighCh2[a]; 1180 } 1181 var pacData = this.interpretPAC(row, b); 1182 var channel = this.channels[chNr - 1]; 1183 channel.setPAC(pacData); 1184 this.lastCmdA = a; 1185 this.lastCmdB = b; 1186 this.currChNr = chNr; 1187 return true; 1188 }, 1189 1190 /** 1191 * Interpret the second byte of the pac, and return the information. 1192 * @returns {Object} pacData with style parameters. 1193 */ 1194 interpretPAC: function interpretPAC(row, byte) { 1195 var pacIndex = byte; 1196 var pacData = { color: null, italics: false, indent: null, underline: false, row: row }; 1197 1198 if (byte > 0x5F) { 1199 pacIndex = byte - 0x60; 1200 } else { 1201 pacIndex = byte - 0x40; 1202 } 1203 pacData.underline = (pacIndex & 1) === 1; 1204 if (pacIndex <= 0xd) { 1205 pacData.color = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'white'][Math.floor(pacIndex / 2)]; 1206 } else if (pacIndex <= 0xf) { 1207 pacData.italics = true; 1208 pacData.color = 'white'; 1209 } else { 1210 pacData.indent = Math.floor((pacIndex - 0x10) / 2) * 4; 1211 } 1212 return pacData; // Note that row has zero offset. The spec uses 1. 1213 }, 1214 1215 /** 1216 * Parse characters. 1217 * @returns An array with 1 to 2 codes corresponding to chars, if found. null otherwise. 1218 */ 1219 parseChars: function parseChars(a, b) { 1220 1221 var channelNr = null, 1222 charCodes = null, 1223 charCode1 = null, 1224 charCode2 = null; 1225 1226 if (a >= 0x19) { 1227 channelNr = 2; 1228 charCode1 = a - 8; 1229 } else { 1230 channelNr = 1; 1231 charCode1 = a; 1232 } 1233 if (0x11 <= charCode1 && charCode1 <= 0x13) { 1234 // Special character 1235 var oneCode = b; 1236 if (charCode1 === 0x11) { 1237 oneCode = b + 0x50; 1238 } else if (charCode1 === 0x12) { 1239 oneCode = b + 0x70; 1240 } else { 1241 oneCode = b + 0x90; 1242 } 1243 logger.log("INFO", "Special char '" + getCharForByte(oneCode) + "' in channel " + channelNr); 1244 charCodes = [oneCode]; 1245 this.lastCmdA = a; 1246 this.lastCmdB = b; 1247 } else if (0x20 <= a && a <= 0x7f) { 1248 charCodes = b === 0 ? [a] : [a, b]; 1249 this.lastCmdA = null; 1250 this.lastCmdB = null; 1251 } 1252 if (charCodes) { 1253 var hexCodes = numArrayToHexArray(charCodes); 1254 logger.log("DEBUG", "Char codes = " + hexCodes.join(",")); 1255 } 1256 return charCodes; 1257 }, 1258 1259 /** 1260 * Parse extended background attributes as well as new foreground color black. 1261 * @returns{Boolean} Tells if background attributes are found 1262 */ 1263 parseBackgroundAttributes: function parseBackgroundAttributes(a, b) { 1264 var bkgData, index, chNr, channel; 1265 1266 var case1 = (a === 0x10 || a === 0x18) && 0x20 <= b && b <= 0x2f; 1267 var case2 = (a === 0x17 || a === 0x1f) && 0x2d <= b && b <= 0x2f; 1268 if (!(case1 || case2)) { 1269 return false; 1270 } 1271 bkgData = {}; 1272 if (a === 0x10 || a === 0x18) { 1273 index = Math.floor((b - 0x20) / 2); 1274 bkgData.background = backgroundColors[index]; 1275 if (b % 2 === 1) { 1276 bkgData.background = bkgData.background + "_semi"; 1277 } 1278 } else if (b === 0x2d) { 1279 bkgData.background = "transparent"; 1280 } else { 1281 bkgData.foreground = "black"; 1282 if (b === 0x2f) { 1283 bkgData.underline = true; 1284 } 1285 } 1286 chNr = a < 0x18 ? 1 : 2; 1287 channel = this.channels[chNr - 1]; 1288 channel.setBkgData(bkgData); 1289 this.lastCmdA = a; 1290 this.lastCmdB = b; 1291 return true; 1292 }, 1293 1294 /** 1295 * Reset state of parser and its channels. 1296 */ 1297 reset: function reset() { 1298 for (var i = 0; i < this.channels.length; i++) { 1299 if (this.channels[i]) { 1300 this.channels[i].reset(); 1301 } 1302 } 1303 this.lastCmdA = null; 1304 this.lastCmdB = null; 1305 }, 1306 1307 /** 1308 * Trigger the generation of a cue, and the start of a new one if displayScreens are not empty. 1309 */ 1310 cueSplitAtTime: function cueSplitAtTime(t) { 1311 for (var i = 0; i < this.channels.length; i++) { 1312 if (this.channels[i]) { 1313 this.channels[i].cueSplitAtTime(t); 1314 } 1315 } 1316 } 1317 }; 1318 1319 /** 1320 * Find ranges corresponding to SEA CEA-608 NALUS in sizeprepended NALU array. 1321 * @param {raw} dataView of binary data 1322 * @param {startPos} start position in raw 1323 * @param {size} total size of data in raw to consider 1324 * @returns 1325 */ 1326 var findCea608Nalus = function findCea608Nalus(raw, startPos, size) { 1327 var nalSize = 0, 1328 cursor = startPos, 1329 nalType = 0, 1330 cea608NaluRanges = [], 1331 1332 // Check SEI data according to ANSI-SCTE 128 1333 isCEA608SEI = function isCEA608SEI(payloadType, payloadSize, raw, pos) { 1334 if (payloadType !== 4 || payloadSize < 8) { 1335 return null; 1336 } 1337 var countryCode = raw.getUint8(pos); 1338 var providerCode = raw.getUint16(pos + 1); 1339 var userIdentifier = raw.getUint32(pos + 3); 1340 var userDataTypeCode = raw.getUint8(pos + 7); 1341 return countryCode == 0xB5 && providerCode == 0x31 && userIdentifier == 0x47413934 && userDataTypeCode == 0x3; 1342 }; 1343 while (cursor < startPos + size) { 1344 nalSize = raw.getUint32(cursor); 1345 nalType = raw.getUint8(cursor + 4) & 0x1F;
vendor: 4,442 bytes, lines 1346-1476
1346 //console.log(time + " NAL " + nalType); 1347 if (nalType === 6) { 1348 // SEI NAL Unit. The NAL header is the first byte 1349 //console.log("SEI NALU of size " + nalSize + " at time " + time); 1350 var pos = cursor + 5; 1351 var payloadType = -1; 1352 while (pos < cursor + 4 + nalSize - 1) { 1353 // The last byte should be rbsp_trailing_bits 1354 payloadType = 0; 1355 var b = 0xFF; 1356 while (b === 0xFF) { 1357 b = raw.getUint8(pos); 1358 payloadType += b; 1359 pos++; 1360 } 1361 var payloadSize = 0; 1362 b = 0xFF; 1363 while (b === 0xFF) { 1364 b = raw.getUint8(pos); 1365 payloadSize += b; 1366 pos++; 1367 } 1368 if (isCEA608SEI(payloadType, payloadSize, raw, pos)) { 1369 //console.log("CEA608 SEI " + time + " " + payloadSize); 1370 cea608NaluRanges.push([pos, payloadSize]); 1371 } 1372 pos += payloadSize; 1373 } 1374 } 1375 cursor += nalSize + 4; 1376 } 1377 return cea608NaluRanges; 1378 }; 1379 1380 var extractCea608DataFromRange = function extractCea608DataFromRange(raw, cea608Range) { 1381 var pos = cea608Range[0]; 1382 var fieldData = [[], []]; 1383 1384 pos += 8; // Skip the identifier up to userDataTypeCode 1385 var ccCount = raw.getUint8(pos) & 0x1f; 1386 pos += 2; // Advance 1 and skip reserved byte 1387 1388 for (var i = 0; i < ccCount; i++) { 1389 var byte = raw.getUint8(pos); 1390 var ccValid = byte & 0x4; 1391 var ccType = byte & 0x3; 1392 pos++; 1393 var ccData1 = raw.getUint8(pos); // Keep parity bit 1394 pos++; 1395 var ccData2 = raw.getUint8(pos); // Keep parity bit 1396 pos++; 1397 if (ccValid && (ccData1 & 0x7f) + (ccData2 & 0x7f) !== 0) { 1398 //Check validity and non-empty data 1399 if (ccType === 0) { 1400 fieldData[0].push(ccData1); 1401 fieldData[0].push(ccData2); 1402 } else if (ccType === 1) { 1403 fieldData[1].push(ccData1); 1404 fieldData[1].push(ccData2); 1405 } 1406 } 1407 } 1408 return fieldData; 1409 }; 1410 1411 exports.logger = logger; 1412 exports.PenState = PenState; 1413 exports.CaptionScreen = CaptionScreen; 1414 exports.Cea608Parser = Cea608Parser; 1415 exports.findCea608Nalus = findCea608Nalus; 1416 exports.extractCea608DataFromRange = extractCea608DataFromRange; 1417})(typeof exports === 'undefined' ? undefined.cea608parser = {} : exports); 1418 1419},{}],3:[function(_dereq_,module,exports){ 1420/* 1421 * 1422 * Licensed under the Apache License, Version 2.0 (the "License"); 1423 * you may not use this file except in compliance with the License. 1424 * You may obtain a copy of the License at 1425 * 1426 * http://www.apache.org/licenses/LICENSE-2.0 1427 * 1428 * Unless required by applicable law or agreed to in writing, software 1429 * distributed under the License is distributed on an "AS IS" BASIS, 1430 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1431 * See the License for the specific language governing permissions and 1432 * limitations under the License. 1433 * 1434 * author Digital Primates 1435 * copyright dash-if 2012 1436 */ 1437 1438/* 1439 * var parent, 1440 * child, 1441 * properties = [ 1442 { 1443 name: 'profiles', 1444 merge: false 1445 } 1446 ]; 1447 * 1448 * parent = {}; 1449 * parent.name = "ParentNode"; 1450 * parent.isRoor = false; 1451 * parent.isArray = false; 1452 * parent.children = []; 1453 * parent.properties = properties; 1454 * 1455 * child = {}; 1456 * child.name = "ChildNode"; 1457 * child.isRoor = false; 1458 * child.isArray = true; 1459 * child.children = null; 1460 * child.properties = properties; 1461 * parent.children.push(child); 1462 * 1463 */ 1464 1465'use strict'; 1466 1467Object.defineProperty(exports, '__esModule', { 1468 value: true 1469}); 1470function ObjectIron(map) { 1471 1472 var lookup, len, i; 1473 1474 // create a list of top level items to search for 1475 lookup = []; 1476 for (i = 0, len = map.length; i < len; i += 1) {
1477 if (map[i].isRoot) { 1478 lookup.push("root"); 1479 } else { 1480 lookup.push(map[i].name); 1481 } 1482 } 1483 1484 var mergeValues = function mergeValues(parentItem, childItem) { 1485 var name, parentValue, childValue; 1486 1487 if (parentItem === null || childItem === null) { 1488 return; 1489 } 1490 1491 for (name in parentItem) { 1492 if (parentItem.hasOwnProperty(name)) { 1493 if (!childItem.hasOwnProperty(name)) { 1494 childItem[name] = parentItem[name]; 1495 } 1496 } 1497 } 1498 }, 1499 mapProperties = function mapProperties(properties, parent, child) { 1500 var i, len, property, parentValue, childValue; 1501 1502 if (properties === null || properties.length === 0) { 1503 return; 1504 } 1505 1506 for (i = 0, len = properties.length; i < len; i += 1) { 1507 property = properties[i]; 1508 1509 if (parent.hasOwnProperty(property.name)) { 1510 if (child.hasOwnProperty(property.name)) { 1511 // check to see if we should merge 1512 if (property.merge) { 1513 parentValue = parent[property.name]; 1514 childValue = child[property.name]; 1515 1516 // complex objects; merge properties 1517 if (typeof parentValue === 'object' && typeof childValue === 'object') { 1518 mergeValues(parentValue, childValue); 1519 } 1520 // simple objects; merge them together 1521 else { 1522 if (property.mergeFunction != null) { 1523 child[property.name] = property.mergeFunction(parentValue, childValue); 1524 } else { 1525 child[property.name] = parentValue + childValue; 1526 } 1527 } 1528 } 1529 } else { 1530 // just add the property 1531 child[property.name] = parent[property.name]; 1532 } 1533 } 1534 } 1535 }, 1536 mapItem = function mapItem(obj, node) { 1537 var item = obj, 1538 i, 1539 len, 1540 v, 1541 len2, 1542 array, 1543 childItem, 1544 childNode, 1545 property; 1546 1547 if (item.children === null || item.children.length === 0) { 1548 return; 1549 } 1550 1551 for (i = 0, len = item.children.length; i < len; i += 1) { 1552 childItem = item.children[i]; 1553 1554 if (node.hasOwnProperty(childItem.name)) { 1555 if (childItem.isArray) { 1556 array = node[childItem.name + "_asArray"]; 1557 for (v = 0, len2 = array.length; v < len2; v += 1) { 1558 childNode = array[v]; 1559 mapProperties(item.properties, node, childNode); 1560 mapItem(childItem, childNode); 1561 } 1562 } else { 1563 childNode = node[childItem.name]; 1564 mapProperties(item.properties, node, childNode); 1565 mapItem(childItem, childNode); 1566 } 1567 } 1568 } 1569 }, 1570 performMapping = function performMapping(source) { 1571 var i, len, pi, pp, item, node, array; 1572 1573 if (source === null) { 1574 return source; 1575 } 1576 1577 if (typeof source !== 'object') { 1578 return source; 1579 } 1580 1581 // first look to see if anything cares about the root node 1582 for (i = 0, len = lookup.length; i < len; i += 1) { 1583 if (lookup[i] === "root") { 1584 item = map[i]; 1585 node = source; 1586 mapItem(item, node); 1587 } 1588 } 1589 1590 // iterate over the objects and look for any of the items we care about 1591 for (pp in source) { 1592 if (source.hasOwnProperty(pp) && pp != "__children") { 1593 pi = lookup.indexOf(pp); 1594 if (pi !== -1) { 1595 item = map[pi]; 1596 1597 if (item.isArray) { 1598 array = source[pp + "_asArray"]; 1599 for (i = 0, len = array.length; i < len; i += 1) { 1600 node = array[i]; 1601 mapItem(item, node); 1602 } 1603 } else { 1604 node = source[pp]; 1605 mapItem(item, node); 1606 } 1607 } 1608 // now check this to see if he has any of the properties we care about 1609 performMapping(source[pp]); 1610 } 1611 } 1612 1613 return source; 1614 }; 1615 1616 return { 1617 run: performMapping 1618 }; 1619} 1620 1621exports['default'] = ObjectIron; 1622module.exports = exports['default']; 1623 1624},{}],4:[function(_dereq_,module,exports){ 1625/* 1626 Copyright 2011-2013 Abdulla Abdurakhmanov 1627 Original sources are available at https://code.google.com/p/x2js/ 1628 1629 Licensed under the Apache License, Version 2.0 (the "License");
vendor: 10,993 bytes, lines 1630-1905
1630 you may not use this file except in compliance with the License. 1631 You may obtain a copy of the License at 1632 1633 http://www.apache.org/licenses/LICENSE-2.0 1634 1635 Unless required by applicable law or agreed to in writing, software 1636 distributed under the License is distributed on an "AS IS" BASIS, 1637 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1638 See the License for the specific language governing permissions and 1639 limitations under the License. 1640 */ 1641 1642/* 1643 Further modified for dashjs to: 1644 - keep track of children nodes in order in attribute __children. 1645 - add type conversion matchers 1646 - re-add ignoreRoot 1647 - allow zero-length attributePrefix 1648 - don't add white-space text nodes 1649 - remove explicit RequireJS support 1650*/ 1651 1652"use strict"; 1653 1654Object.defineProperty(exports, "__esModule", { 1655 value: true 1656}); 1657function X2JS(config) { 1658 'use strict'; 1659 1660 var VERSION = "1.2.0"; 1661 1662 config = config || {}; 1663 initConfigDefaults(); 1664 initRequiredPolyfills(); 1665 1666 function initConfigDefaults() { 1667 if (config.escapeMode === undefined) { 1668 config.escapeMode = true; 1669 } 1670 1671 if (config.attributePrefix === undefined) { 1672 config.attributePrefix = "_"; 1673 } 1674 1675 config.arrayAccessForm = config.arrayAccessForm || "none"; 1676 config.emptyNodeForm = config.emptyNodeForm || "text"; 1677 1678 if (config.enableToStringFunc === undefined) { 1679 config.enableToStringFunc = true; 1680 } 1681 config.arrayAccessFormPaths = config.arrayAccessFormPaths || []; 1682 if (config.skipEmptyTextNodesForObj === undefined) { 1683 config.skipEmptyTextNodesForObj = true; 1684 } 1685 if (config.stripWhitespaces === undefined) { 1686 config.stripWhitespaces = true; 1687 } 1688 config.datetimeAccessFormPaths = config.datetimeAccessFormPaths || []; 1689 1690 if (config.useDoubleQuotes === undefined) { 1691 config.useDoubleQuotes = false; 1692 } 1693 1694 config.xmlElementsFilter = config.xmlElementsFilter || []; 1695 config.jsonPropertiesFilter = config.jsonPropertiesFilter || []; 1696 1697 if (config.keepCData === undefined) { 1698 config.keepCData = false; 1699 } 1700 1701 if (config.ignoreRoot === undefined) { 1702 config.ignoreRoot = false; 1703 } 1704 } 1705 1706 var DOMNodeTypes = { 1707 ELEMENT_NODE: 1, 1708 TEXT_NODE: 3, 1709 CDATA_SECTION_NODE: 4, 1710 COMMENT_NODE: 8, 1711 DOCUMENT_NODE: 9 1712 }; 1713 1714 function initRequiredPolyfills() {} 1715 1716 function getNodeLocalName(node) { 1717 var nodeLocalName = node.localName; 1718 if (nodeLocalName == null) // Yeah, this is IE!! 1719 nodeLocalName = node.baseName; 1720 if (nodeLocalName == null || nodeLocalName == "") // =="" is IE too 1721 nodeLocalName = node.nodeName; 1722 return nodeLocalName; 1723 } 1724 1725 function getNodePrefix(node) { 1726 return node.prefix; 1727 } 1728 1729 function escapeXmlChars(str) { 1730 if (typeof str == "string") return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');else return str; 1731 } 1732 1733 function unescapeXmlChars(str) { 1734 return str.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, '&'); 1735 } 1736 1737 function checkInStdFiltersArrayForm(stdFiltersArrayForm, obj, name, path) { 1738 var idx = 0; 1739 for (; idx < stdFiltersArrayForm.length; idx++) { 1740 var filterPath = stdFiltersArrayForm[idx]; 1741 if (typeof filterPath === "string") { 1742 if (filterPath == path) break; 1743 } else if (filterPath instanceof RegExp) { 1744 if (filterPath.test(path)) break; 1745 } else if (typeof filterPath === "function") { 1746 if (filterPath(obj, name, path)) break; 1747 } 1748 } 1749 return idx != stdFiltersArrayForm.length; 1750 } 1751 1752 function toArrayAccessForm(obj, childName, path) { 1753 switch (config.arrayAccessForm) { 1754 case "property": 1755 if (!(obj[childName] instanceof Array)) obj[childName + "_asArray"] = [obj[childName]];else obj[childName + "_asArray"] = obj[childName]; 1756 break; 1757 /*case "none": 1758 break;*/ 1759 } 1760 1761 if (!(obj[childName] instanceof Array) && config.arrayAccessFormPaths.length > 0) { 1762 if (checkInStdFiltersArrayForm(config.arrayAccessFormPaths, obj, childName, path)) { 1763 obj[childName] = [obj[childName]]; 1764 } 1765 } 1766 } 1767 1768 function fromXmlDateTime(prop) { 1769 // Implementation based up on http://stackoverflow.com/questions/8178598/xml-datetime-to-javascript-date-object 1770 // Improved to support full spec and optional parts 1771 var bits = prop.split(/[-T:+Z]/g); 1772 1773 var d = new Date(bits[0], bits[1] - 1, bits[2]); 1774 var secondBits = bits[5].split("\."); 1775 d.setHours(bits[3], bits[4], secondBits[0]); 1776 if (secondBits.length > 1) d.setMilliseconds(secondBits[1]); 1777 1778 // Get supplied time zone offset in minutes 1779 if (bits[6] && bits[7]) { 1780 var offsetMinutes = bits[6] * 60 + Number(bits[7]); 1781 var sign = /\d\d-\d\d:\d\d$/.test(prop) ? '-' : '+'; 1782 1783 // Apply the sign 1784 offsetMinutes = 0 + (sign == '-' ? -1 * offsetMinutes : offsetMinutes); 1785 1786 // Apply offset and local timezone 1787 d.setMinutes(d.getMinutes() - offsetMinutes - d.getTimezoneOffset()); 1788 } else if (prop.indexOf("Z", prop.length - 1) !== -1) { 1789 d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds())); 1790 } 1791 1792 // d is now a local time equivalent to the supplied time 1793 return d; 1794 } 1795 1796 function checkFromXmlDateTimePaths(value, childName, fullPath) { 1797 if (config.datetimeAccessFormPaths.length > 0) { 1798 var path = fullPath.split("\.#")[0]; 1799 if (checkInStdFiltersArrayForm(config.datetimeAccessFormPaths, value, childName, path)) { 1800 return fromXmlDateTime(value); 1801 } else return value; 1802 } else return value; 1803 } 1804 1805 function checkXmlElementsFilter(obj, childType, childName, childPath) { 1806 if (childType == DOMNodeTypes.ELEMENT_NODE && config.xmlElementsFilter.length > 0) { 1807 return checkInStdFiltersArrayForm(config.xmlElementsFilter, obj, childName, childPath); 1808 } else return true; 1809 } 1810 1811 function parseDOMChildren(node, path) { 1812 if (node.nodeType == DOMNodeTypes.DOCUMENT_NODE) { 1813 var result = new Object(); 1814 var nodeChildren = node.childNodes; 1815 // Alternative for firstElementChild which is not supported in some environments 1816 for (var cidx = 0; cidx < nodeChildren.length; cidx++) { 1817 var child = nodeChildren[cidx]; 1818 if (child.nodeType == DOMNodeTypes.ELEMENT_NODE) { 1819 if (config.ignoreRoot) { 1820 result = parseDOMChildren(child); 1821 } else { 1822 result = {}; 1823 var childName = getNodeLocalName(child); 1824 result[childName] = parseDOMChildren(child); 1825 } 1826 } 1827 } 1828 return result; 1829 } else if (node.nodeType == DOMNodeTypes.ELEMENT_NODE) { 1830 var result = new Object(); 1831 result.__cnt = 0; 1832 1833 var children = []; 1834 var nodeChildren = node.childNodes; 1835 1836 // Children nodes 1837 for (var cidx = 0; cidx < nodeChildren.length; cidx++) { 1838 var child = nodeChildren[cidx]; 1839 var childName = getNodeLocalName(child); 1840 1841 if (child.nodeType != DOMNodeTypes.COMMENT_NODE) { 1842 var childPath = path + "." + childName; 1843 if (checkXmlElementsFilter(result, child.nodeType, childName, childPath)) { 1844 result.__cnt++; 1845 if (result[childName] == null) { 1846 var c = parseDOMChildren(child, childPath); 1847 if (childName != "#text" || /[^\s]/.test(c)) { 1848 var o = {}; 1849 o[childName] = c; 1850 children.push(o); 1851 } 1852 result[childName] = c; 1853 toArrayAccessForm(result, childName, childPath); 1854 } else { 1855 if (result[childName] != null) { 1856 if (!(result[childName] instanceof Array)) { 1857 result[childName] = [result[childName]]; 1858 toArrayAccessForm(result, childName, childPath); 1859 } 1860 } 1861 1862 var c = parseDOMChildren(child, childPath); 1863 if (childName != "#text" || /[^\s]/.test(c)) { 1864 // Don't add white-space text nodes 1865 var o = {}; 1866 o[childName] = c; 1867 children.push(o); 1868 } 1869 result[childName][result[childName].length] = c; 1870 } 1871 } 1872 } 1873 } 1874 1875 result.__children = children; 1876 1877 // Attributes 1878 var nodeLocalName = getNodeLocalName(node); 1879 for (var aidx = 0; aidx < node.attributes.length; aidx++) { 1880 var attr = node.attributes[aidx]; 1881 result.__cnt++; 1882 1883 var value2 = attr.value; 1884 for (var m = 0, ml = config.matchers.length; m < ml; m++) { 1885 var matchobj = config.matchers[m]; 1886 if (matchobj.test(attr, nodeLocalName)) value2 = matchobj.converter(attr.value); 1887 } 1888 1889 result[config.attributePrefix + attr.name] = value2; 1890 } 1891 1892 // Node namespace prefix 1893 var nodePrefix = getNodePrefix(node); 1894 if (nodePrefix != null && nodePrefix != "") { 1895 result.__cnt++; 1896 result.__prefix = nodePrefix; 1897 } 1898 1899 if (result["#text"] != null) { 1900 result.__text = result["#text"]; 1901 if (result.__text instanceof Array) { 1902 result.__text = result.__text.join("\n"); 1903 } 1904 //if(config.escapeMode) 1905 // result.__text = unescapeXmlChars(result.__text);
vendor: 11,966 bytes, lines 1906-2189
1906 if (config.stripWhitespaces) result.__text = result.__text.trim(); 1907 delete result["#text"]; 1908 if (config.arrayAccessForm == "property") delete result["#text_asArray"]; 1909 result.__text = checkFromXmlDateTimePaths(result.__text, childName, path + "." + childName); 1910 } 1911 if (result["#cdata-section"] != null) { 1912 result.__cdata = result["#cdata-section"]; 1913 delete result["#cdata-section"]; 1914 if (config.arrayAccessForm == "property") delete result["#cdata-section_asArray"]; 1915 } 1916 1917 if (result.__cnt == 0 && config.emptyNodeForm == "text") { 1918 result = ''; 1919 } else if (result.__cnt == 1 && result.__text != null) { 1920 result = result.__text; 1921 } else if (result.__cnt == 1 && result.__cdata != null && !config.keepCData) { 1922 result = result.__cdata; 1923 } else if (result.__cnt > 1 && result.__text != null && config.skipEmptyTextNodesForObj) { 1924 if (config.stripWhitespaces && result.__text == "" || result.__text.trim() == "") { 1925 delete result.__text; 1926 } 1927 } 1928 delete result.__cnt; 1929 1930 if (config.enableToStringFunc && (result.__text != null || result.__cdata != null)) { 1931 result.toString = function () { 1932 return (this.__text != null ? this.__text : '') + (this.__cdata != null ? this.__cdata : ''); 1933 }; 1934 } 1935 1936 return result; 1937 } else if (node.nodeType == DOMNodeTypes.TEXT_NODE || node.nodeType == DOMNodeTypes.CDATA_SECTION_NODE) { 1938 return node.nodeValue; 1939 } 1940 } 1941 1942 function startTag(jsonObj, element, attrList, closed) { 1943 var resultStr = "<" + (jsonObj != null && jsonObj.__prefix != null ? jsonObj.__prefix + ":" : "") + element; 1944 if (attrList != null) { 1945 for (var aidx = 0; aidx < attrList.length; aidx++) { 1946 var attrName = attrList[aidx]; 1947 var attrVal = jsonObj[attrName]; 1948 if (config.escapeMode) attrVal = escapeXmlChars(attrVal); 1949 resultStr += " " + attrName.substr(config.attributePrefix.length) + "="; 1950 if (config.useDoubleQuotes) resultStr += '"' + attrVal + '"';else resultStr += "'" + attrVal + "'"; 1951 } 1952 } 1953 if (!closed) resultStr += ">";else resultStr += "/>"; 1954 return resultStr; 1955 } 1956 1957 function endTag(jsonObj, elementName) { 1958 return "</" + (jsonObj.__prefix != null ? jsonObj.__prefix + ":" : "") + elementName + ">"; 1959 } 1960 1961 function endsWith(str, suffix) { 1962 return str.indexOf(suffix, str.length - suffix.length) !== -1; 1963 } 1964 1965 function jsonXmlSpecialElem(jsonObj, jsonObjField) { 1966 if (config.arrayAccessForm == "property" && endsWith(jsonObjField.toString(), "_asArray") || jsonObjField.toString().indexOf(config.attributePrefix) == 0 || jsonObjField.toString().indexOf("__") == 0 || jsonObj[jsonObjField] instanceof Function) return true;else return false; 1967 } 1968 1969 function jsonXmlElemCount(jsonObj) { 1970 var elementsCnt = 0; 1971 if (jsonObj instanceof Object) { 1972 for (var it in jsonObj) { 1973 if (jsonXmlSpecialElem(jsonObj, it)) continue; 1974 elementsCnt++; 1975 } 1976 } 1977 return elementsCnt; 1978 } 1979 1980 function checkJsonObjPropertiesFilter(jsonObj, propertyName, jsonObjPath) { 1981 return config.jsonPropertiesFilter.length == 0 || jsonObjPath == "" || checkInStdFiltersArrayForm(config.jsonPropertiesFilter, jsonObj, propertyName, jsonObjPath); 1982 } 1983 1984 function parseJSONAttributes(jsonObj) { 1985 var attrList = []; 1986 if (jsonObj instanceof Object) { 1987 for (var ait in jsonObj) { 1988 if (ait.toString().indexOf("__") == -1 && ait.toString().indexOf(config.attributePrefix) == 0) { 1989 attrList.push(ait); 1990 } 1991 } 1992 } 1993 return attrList; 1994 } 1995 1996 function parseJSONTextAttrs(jsonTxtObj) { 1997 var result = ""; 1998 1999 if (jsonTxtObj.__cdata != null) { 2000 result += "<![CDATA[" + jsonTxtObj.__cdata + "]]>"; 2001 } 2002 2003 if (jsonTxtObj.__text != null) { 2004 if (config.escapeMode) result += escapeXmlChars(jsonTxtObj.__text);else result += jsonTxtObj.__text; 2005 } 2006 return result; 2007 } 2008 2009 function parseJSONTextObject(jsonTxtObj) { 2010 var result = ""; 2011 2012 if (jsonTxtObj instanceof Object) { 2013 result += parseJSONTextAttrs(jsonTxtObj); 2014 } else if (jsonTxtObj != null) { 2015 if (config.escapeMode) result += escapeXmlChars(jsonTxtObj);else result += jsonTxtObj; 2016 } 2017 2018 return result; 2019 } 2020 2021 function getJsonPropertyPath(jsonObjPath, jsonPropName) { 2022 if (jsonObjPath === "") { 2023 return jsonPropName; 2024 } else return jsonObjPath + "." + jsonPropName; 2025 } 2026 2027 function parseJSONArray(jsonArrRoot, jsonArrObj, attrList, jsonObjPath) { 2028 var result = ""; 2029 if (jsonArrRoot.length == 0) { 2030 result += startTag(jsonArrRoot, jsonArrObj, attrList, true); 2031 } else { 2032 for (var arIdx = 0; arIdx < jsonArrRoot.length; arIdx++) { 2033 result += startTag(jsonArrRoot[arIdx], jsonArrObj, parseJSONAttributes(jsonArrRoot[arIdx]), false); 2034 result += parseJSONObject(jsonArrRoot[arIdx], getJsonPropertyPath(jsonObjPath, jsonArrObj)); 2035 result += endTag(jsonArrRoot[arIdx], jsonArrObj); 2036 } 2037 } 2038 return result; 2039 } 2040 2041 function parseJSONObject(jsonObj, jsonObjPath) { 2042 var result = ""; 2043 2044 var elementsCnt = jsonXmlElemCount(jsonObj); 2045 2046 if (elementsCnt > 0) { 2047 for (var it in jsonObj) { 2048 2049 if (jsonXmlSpecialElem(jsonObj, it) || jsonObjPath != "" && !checkJsonObjPropertiesFilter(jsonObj, it, getJsonPropertyPath(jsonObjPath, it))) continue; 2050 2051 var subObj = jsonObj[it]; 2052 2053 var attrList = parseJSONAttributes(subObj); 2054 2055 if (subObj == null || subObj == undefined) { 2056 result += startTag(subObj, it, attrList, true); 2057 } else if (subObj instanceof Object) { 2058 2059 if (subObj instanceof Array) { 2060 result += parseJSONArray(subObj, it, attrList, jsonObjPath); 2061 } else if (subObj instanceof Date) { 2062 result += startTag(subObj, it, attrList, false); 2063 result += subObj.toISOString(); 2064 result += endTag(subObj, it); 2065 } else { 2066 var subObjElementsCnt = jsonXmlElemCount(subObj); 2067 if (subObjElementsCnt > 0 || subObj.__text != null || subObj.__cdata != null) { 2068 result += startTag(subObj, it, attrList, false); 2069 result += parseJSONObject(subObj, getJsonPropertyPath(jsonObjPath, it)); 2070 result += endTag(subObj, it); 2071 } else { 2072 result += startTag(subObj, it, attrList, true); 2073 } 2074 } 2075 } else { 2076 result += startTag(subObj, it, attrList, false); 2077 result += parseJSONTextObject(subObj); 2078 result += endTag(subObj, it); 2079 } 2080 } 2081 } 2082 result += parseJSONTextObject(jsonObj); 2083 2084 return result; 2085 } 2086 2087 this.parseXmlString = function (xmlDocStr) { 2088 var isIEParser = window.ActiveXObject || "ActiveXObject" in window; 2089 if (xmlDocStr === undefined) { 2090 return null; 2091 } 2092 var xmlDoc; 2093 if (window.DOMParser) { 2094 var parser = new window.DOMParser(); 2095 var parsererrorNS = null; 2096 // IE9+ now is here 2097 if (!isIEParser) { 2098 try { 2099 parsererrorNS = parser.parseFromString("INVALID", "text/xml").getElementsByTagName("parsererror")[0].namespaceURI; 2100 } catch (err) { 2101 parsererrorNS = null; 2102 } 2103 } 2104 try { 2105 xmlDoc = parser.parseFromString(xmlDocStr, "text/xml"); 2106 if (parsererrorNS != null && xmlDoc.getElementsByTagNameNS(parsererrorNS, "parsererror").length > 0) { 2107 //throw new Error('Error parsing XML: '+xmlDocStr); 2108 xmlDoc = null; 2109 } 2110 } catch (err) { 2111 xmlDoc = null; 2112 } 2113 } else { 2114 // IE :( 2115 if (xmlDocStr.indexOf("<?") == 0) { 2116 xmlDocStr = xmlDocStr.substr(xmlDocStr.indexOf("?>") + 2); 2117 } 2118 xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 2119 xmlDoc.async = "false"; 2120 xmlDoc.loadXML(xmlDocStr); 2121 } 2122 return xmlDoc; 2123 }; 2124 2125 this.asArray = function (prop) { 2126 if (prop === undefined || prop == null) return [];else if (prop instanceof Array) return prop;else return [prop]; 2127 }; 2128 2129 this.toXmlDateTime = function (dt) { 2130 if (dt instanceof Date) return dt.toISOString();else if (typeof dt === 'number') return new Date(dt).toISOString();else return null; 2131 }; 2132 2133 this.asDateTime = function (prop) { 2134 if (typeof prop == "string") { 2135 return fromXmlDateTime(prop); 2136 } else return prop; 2137 }; 2138 2139 this.xml2json = function (xmlDoc) { 2140 return parseDOMChildren(xmlDoc); 2141 }; 2142 2143 this.xml_str2json = function (xmlDocStr) { 2144 var xmlDoc = this.parseXmlString(xmlDocStr); 2145 if (xmlDoc != null) return this.xml2json(xmlDoc);else return null; 2146 }; 2147 2148 this.json2xml_str = function (jsonObj) { 2149 return parseJSONObject(jsonObj, ""); 2150 }; 2151 2152 this.json2xml = function (jsonObj) { 2153 var xmlDocStr = this.json2xml_str(jsonObj); 2154 return this.parseXmlString(xmlDocStr); 2155 }; 2156 2157 this.getVersion = function () { 2158 return VERSION; 2159 }; 2160} 2161 2162exports["default"] = X2JS; 2163module.exports = exports["default"]; 2164 2165},{}],5:[function(_dereq_,module,exports){ 2166/** 2167 * The copyright in this software is being made available under the BSD License, 2168 * included below. This software may be subject to other third party and contributor 2169 * rights, including patent rights, and no such rights are granted under this license. 2170 * 2171 * Copyright (c) 2013, Dash Industry Forum. 2172 * All rights reserved. 2173 * 2174 * Redistribution and use in source and binary forms, with or without modification, 2175 * are permitted provided that the following conditions are met: 2176 * * Redistributions of source code must retain the above copyright notice, this 2177 * list of conditions and the following disclaimer. 2178 * * Redistributions in binary form must reproduce the above copyright notice, 2179 * this list of conditions and the following disclaimer in the documentation and/or 2180 * other materials provided with the distribution. 2181 * * Neither the name of Dash Industry Forum nor the names of its 2182 * contributors may be used to endorse or promote products derived from this software 2183 * without specific prior written permission. 2184 * 2185 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 2186 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 2187 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2188 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 2189 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
2189INCLUDING, BUT 2190 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2191 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2192 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2193 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2194 * POSSIBILITY OF SUCH DAMAGE. 2195 */ 2196 2197'use strict'; 2198 2199Object.defineProperty(exports, '__esModule', { 2200 value: true 2201}); 2202 2203function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2204 2205_dereq_(6); 2206 2207var _srcStreamingMetricsMetricsReporting = _dereq_(116); 2208 2209var _srcStreamingMetricsMetricsReporting2 = _interopRequireDefault(_srcStreamingMetricsMetricsReporting); 2210 2211var _srcStreamingProtectionProtection = _dereq_(147); 2212 2213var _srcStreamingProtectionProtection2 = _interopRequireDefault(_srcStreamingProtectionProtection); 2214 2215var _srcStreamingMediaPlayerFactory = _dereq_(95); 2216 2217var _srcStreamingMediaPlayerFactory2 = _interopRequireDefault(_srcStreamingMediaPlayerFactory); 2218 2219dashjs.Protection = _srcStreamingProtectionProtection2['default']; 2220dashjs.MetricsReporting = _srcStreamingMetricsMetricsReporting2['default']; 2221dashjs.MediaPlayerFactory = _srcStreamingMediaPlayerFactory2['default']; 2222 2223exports['default'] = dashjs; 2224exports.Protection = _srcStreamingProtectionProtection2['default']; 2225exports.MetricsReporting = _srcStreamingMetricsMetricsReporting2['default']; 2226exports.MediaPlayerFactory = _srcStreamingMediaPlayerFactory2['default']; 2227 2228},{"116":116,"147":147,"6":6,"95":95}],6:[function(_dereq_,module,exports){ 2229(function (global){ 2230/** 2231 * The copyright in this software is being made available under the BSD License, 2232 * included below. This software may be subject to other third party and contributor 2233 * rights, including patent rights, and no such rights are granted under this license. 2234 * 2235 * Copyright (c) 2013, Dash Industry Forum. 2236 * All rights reserved. 2237 * 2238 * Redistribution and use in source and binary forms, with or without modification, 2239 * are permitted provided that the following conditions are met: 2240 * * Redistributions of source code must retain the above copyright notice, this 2241 * list of conditions and the following disclaimer. 2242 * * Redistributions in binary form must reproduce the above copyright notice, 2243 * this list of conditions and the following disclaimer in the documentation and/or 2244 * other materials provided with the distribution. 2245 * * Neither the name of Dash Industry Forum nor the names of its 2246 * contributors may be used to endorse or promote products derived from this software 2247 * without specific prior written permission. 2248 * 2249 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 2250 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 2251 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2252 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 2253 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2254 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2255 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2256 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2257 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2258 * POSSIBILITY OF SUCH DAMAGE. 2259 */ 2260 2261'use strict'; 2262 2263Object.defineProperty(exports, '__esModule', { 2264 value: true 2265}); 2266 2267function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2268 2269var _srcStreamingMediaPlayer = _dereq_(93); 2270 2271var _srcStreamingMediaPlayer2 = _interopRequireDefault(_srcStreamingMediaPlayer); 2272 2273var _srcCoreFactoryMaker = _dereq_(51); 2274 2275var _srcCoreFactoryMaker2 = _interopRequireDefault(_srcCoreFactoryMaker); 2276 2277var _srcCoreVersion = _dereq_(52); 2278 2279// Shove both of these into the global scope 2280var context = typeof window !== 'undefined' && window || global; 2281 2282var dashjs = context.dashjs; 2283if (!dashjs) { 2284 dashjs = context.dashjs = {}; 2285} 2286 2287dashjs.MediaPlayer = _srcStreamingMediaPlayer2['default']; 2288dashjs.FactoryMaker = _srcCoreFactoryMaker2['default']; 2289dashjs.Version = (0, _srcCoreVersion.getVersionString)(); 2290 2291exports['default'] = dashjs; 2292exports.MediaPlayer = _srcStreamingMediaPlayer2['default']; 2293exports.FactoryMaker = _srcCoreFactoryMaker2['default']; 2294 2295}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 2296 2297},{"51":51,"52":52,"93":93}],7:[function(_dereq_,module,exports){ 2298var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
2298+/'; 2299 2300;(function (exports) { 2301 'use strict'; 2302 2303 var Arr = (typeof Uint8Array !== 'undefined') 2304 ? Uint8Array 2305 : Array 2306 2307 var PLUS = '+'.charCodeAt(0) 2308 var SLASH = '/'.charCodeAt(0) 2309 var NUMBER = '0'.charCodeAt(0) 2310 var LOWER = 'a'.charCodeAt(0) 2311 var UPPER = 'A'.charCodeAt(0) 2312 var PLUS_URL_SAFE = '-'.charCodeAt(0) 2313 var SLASH_URL_SAFE = '_'.charCodeAt(0) 2314 2315 function decode (elt) { 2316 var code = elt.charCodeAt(0) 2317 if (code === PLUS || 2318 code === PLUS_URL_SAFE) 2319 return 62 // '+' 2320 if (code === SLASH || 2321 code === SLASH_URL_SAFE) 2322 return 63 // '/' 2323 if (code < NUMBER) 2324 return -1 //no match 2325 if (code < NUMBER + 10) 2326 return code - NUMBER + 26 + 26 2327 if (code < UPPER + 26) 2328 return code - UPPER 2329 if (code < LOWER + 26) 2330 return code - LOWER + 26 2331 } 2332 2333 function b64ToByteArray (b64) { 2334 var i, j, l, tmp, placeHolders, arr 2335 2336 if (b64.length % 4 > 0) { 2337 throw new Error('Invalid string. Length must be a multiple of 4') 2338 } 2339 2340 // the number of equal signs (place holders) 2341 // if there are two placeholders, than the two characters before it 2342 // represent one byte 2343 // if there is only one, then the three characters before it represent 2 bytes 2344 // this is just a cheap hack to not do indexOf twice 2345 var len = b64.length 2346 placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 2347 2348 // base64 is 4/3 + up to two characters of the original data 2349 arr = new Arr(b64.length * 3 / 4 - placeHolders) 2350 2351 // if there are placeholders, only get up to the last complete 4 chars 2352 l = placeHolders > 0 ? b64.length - 4 : b64.length 2353 2354 var L = 0 2355 2356 function push (v) { 2357 arr[L++] = v 2358 } 2359 2360 for (i = 0, j = 0; i < l; i += 4, j += 3) { 2361 tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) 2362 push((tmp & 0xFF0000) >> 16) 2363 push((tmp & 0xFF00) >> 8) 2364 push(tmp & 0xFF) 2365 } 2366 2367 if (placeHolders === 2) { 2368 tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) 2369 push(tmp & 0xFF) 2370 } else if (placeHolders === 1) { 2371 tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) 2372 push((tmp >> 8) & 0xFF) 2373 push(tmp & 0xFF) 2374 } 2375 2376 return arr 2377 } 2378 2379 function uint8ToBase64 (uint8) { 2380 var i, 2381 extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes 2382 output = "", 2383 temp, length 2384 2385 function encode (num) { 2386 return lookup.charAt(num) 2387 } 2388 2389 function tripletToBase64 (num) { 2390 return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) 2391 } 2392 2393 // go through the array every three bytes, we'll deal with trailing stuff later 2394 for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { 2395 temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) 2396 output += tripletToBase64(temp) 2397 } 2398 2399 // pad the end with zeros, but make sure to not forget the extra bytes 2400 switch (extraBytes) { 2401 case 1: 2402 temp = uint8[uint8.length - 1] 2403 output += encode(temp >> 2) 2404 output += encode((temp << 4) & 0x3F) 2405 output += '==' 2406 break 2407 case 2: 2408 temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) 2409 output += encode(temp >> 10) 2410 output += encode((temp >> 4) & 0x3F) 2411 output += encode((temp << 2) & 0x3F) 2412 output += '=' 2413 break 2414 } 2415 2416 return output 2417 } 2418 2419 exports.toByteArray = b64ToByteArray 2420 exports.fromByteArray = uint8ToBase64 2421}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) 2422 2423},{}],8:[function(_dereq_,module,exports){ 2424 2425},{}],9:[function(_dereq_,module,exports){ 2426// Copyright Joyent, Inc. and other Node contributors. 2427// 2428// Permission is hereby granted, free of charge, to any person obtaining a 2429// copy of this software and associated documentation files (the 2430// "Software"), to deal in the Software without restriction, including 2431// without limitation the rights to use, copy, modify, merge, publish, 2432// distribute, sublicense, and/or sell copies of the Software, and to permit 2433// persons to whom the Software is furnished to do so, subject to the 2434// following conditions: 2435// 2436// The above copyright notice and this permission notice shall be included 2437// in all copies or substantial portions of the Software. 2438// 2439// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2440// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2441// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 2442// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 2443// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2444// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2445// USE OR OTHER DEALINGS IN THE SOFTWARE. 2446 2447var Buffer = _dereq_(10).Buffer; 2448 2449var isBufferEncoding = Buffer.isEncoding 2450 || function(encoding) { 2451 switch (encoding && encoding.toLowerCase()) { 2452 case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; 2453 default: return false; 2454 } 2455 } 2456 2457 2458function assertEncoding(encoding) { 2459 if (encoding && !isBufferEncoding(encoding)) { 2460 throw new Error('Unknown encoding: ' + encoding); 2461 } 2462} 2463 2464// StringDecoder provides an interface for efficiently splitting a series of 2465// buffers into a series of JS strings without breaking apart multi-byte 2466// characters. CESU-8 is handled as part of the UTF-8 encoding. 2467// 2468// @TODO Handling all encodings inside a single object makes it very difficult 2469// to reason about this code, so it should be split up in the future. 2470// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code 2471// points as used by CESU-8. 2472var StringDecoder = exports.StringDecoder = function(encoding) { 2473 this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); 2474 assertEncoding(encoding); 2475 switch (this.encoding) { 2476 case 'utf8': 2477 // CESU-8 represents each of Surrogate Pair by 3-bytes 2478 this.surrogateSize = 3; 2479 break; 2480 case 'ucs2': 2481 case 'utf16le': 2482 // UTF-16 represents each of Surrogate Pair by 2-bytes 2483 this.surrogateSize = 2; 2484 this.detectIncompleteChar = utf16DetectIncompleteChar; 2485 break; 2486 case 'base64': 2487 // Base-64 stores 3 bytes in 4 chars, and pads the remainder. 2488 this.surrogateSize = 3; 2489 this.detectIncompleteChar = base64DetectIncompleteChar; 2490 break; 2491 default: 2492 this.write = passThroughWrite; 2493 return; 2494 } 2495 2496 // Enough space to store all bytes of a single character. UTF-8 needs 4 2497 // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). 2498 this.charBuffer = new Buffer(6); 2499 // Number of bytes received for the current incomplete multi-byte character. 2500 this.charReceived = 0; 2501 // Number of bytes expected for the current incomplete multi-byte character. 2502 this.charLength = 0; 2503}; 2504 2505 2506// write decodes the given buffer and returns it as JS string that is 2507// guaranteed to not contain any partial multi-byte characters. Any partial
vendor: 5,462 bytes, lines 2508-2683
2508// character found at the end of the buffer is buffered up, and will be 2509// returned when calling write again with the remaining bytes. 2510// 2511// Note: Converting a Buffer containing an orphan surrogate to a String 2512// currently works, but converting a String to a Buffer (via `new Buffer`, or 2513// Buffer#write) will replace incomplete surrogates with the unicode 2514// replacement character. See https://codereview.chromium.org/121173009/ . 2515StringDecoder.prototype.write = function(buffer) { 2516 var charStr = ''; 2517 // if our last write ended with an incomplete multibyte character 2518 while (this.charLength) { 2519 // determine how many remaining bytes this buffer has to offer for this char 2520 var available = (buffer.length >= this.charLength - this.charReceived) ? 2521 this.charLength - this.charReceived : 2522 buffer.length; 2523 2524 // add the new bytes to the char buffer 2525 buffer.copy(this.charBuffer, this.charReceived, 0, available); 2526 this.charReceived += available; 2527 2528 if (this.charReceived < this.charLength) { 2529 // still not enough chars in this buffer? wait for more ... 2530 return ''; 2531 } 2532 2533 // remove bytes belonging to the current character from the buffer 2534 buffer = buffer.slice(available, buffer.length); 2535 2536 // get the character that was split 2537 charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); 2538 2539 // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character 2540 var charCode = charStr.charCodeAt(charStr.length - 1); 2541 if (charCode >= 0xD800 && charCode <= 0xDBFF) { 2542 this.charLength += this.surrogateSize; 2543 charStr = ''; 2544 continue; 2545 } 2546 this.charReceived = this.charLength = 0; 2547 2548 // if there are no more bytes in this buffer, just emit our char 2549 if (buffer.length === 0) { 2550 return charStr; 2551 } 2552 break; 2553 } 2554 2555 // determine and set charLength / charReceived 2556 this.detectIncompleteChar(buffer); 2557 2558 var end = buffer.length; 2559 if (this.charLength) { 2560 // buffer the incomplete character bytes we got 2561 buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); 2562 end -= this.charReceived; 2563 } 2564 2565 charStr += buffer.toString(this.encoding, 0, end); 2566 2567 var end = charStr.length - 1; 2568 var charCode = charStr.charCodeAt(end); 2569 // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character 2570 if (charCode >= 0xD800 && charCode <= 0xDBFF) { 2571 var size = this.surrogateSize; 2572 this.charLength += size; 2573 this.charReceived += size; 2574 this.charBuffer.copy(this.charBuffer, size, 0, size); 2575 buffer.copy(this.charBuffer, 0, 0, size); 2576 return charStr.substring(0, end); 2577 } 2578 2579 // or just emit the charStr 2580 return charStr; 2581}; 2582 2583// detectIncompleteChar determines if there is an incomplete UTF-8 character at 2584// the end of the given buffer. If so, it sets this.charLength to the byte 2585// length that character, and sets this.charReceived to the number of bytes 2586// that are available for this character. 2587StringDecoder.prototype.detectIncompleteChar = function(buffer) { 2588 // determine how many bytes we have to check at the end of this buffer 2589 var i = (buffer.length >= 3) ? 3 : buffer.length; 2590 2591 // Figure out if one of the last i bytes of our buffer announces an 2592 // incomplete char. 2593 for (; i > 0; i--) { 2594 var c = buffer[buffer.length - i]; 2595 2596 // See http://en.wikipedia.org/wiki/UTF-8#Description 2597 2598 // 110XXXXX 2599 if (i == 1 && c >> 5 == 0x06) { 2600 this.charLength = 2; 2601 break; 2602 } 2603 2604 // 1110XXXX 2605 if (i <= 2 && c >> 4 == 0x0E) { 2606 this.charLength = 3; 2607 break; 2608 } 2609 2610 // 11110XXX 2611 if (i <= 3 && c >> 3 == 0x1E) { 2612 this.charLength = 4; 2613 break; 2614 } 2615 } 2616 this.charReceived = i; 2617}; 2618 2619StringDecoder.prototype.end = function(buffer) { 2620 var res = ''; 2621 if (buffer && buffer.length) 2622 res = this.write(buffer); 2623 2624 if (this.charReceived) { 2625 var cr = this.charReceived; 2626 var buf = this.charBuffer; 2627 var enc = this.encoding; 2628 res += buf.slice(0, cr).toString(enc); 2629 } 2630 2631 return res; 2632}; 2633 2634function passThroughWrite(buffer) { 2635 return buffer.toString(this.encoding); 2636} 2637 2638function utf16DetectIncompleteChar(buffer) { 2639 this.charReceived = buffer.length % 2; 2640 this.charLength = this.charReceived ? 2 : 0; 2641} 2642 2643function base64DetectIncompleteChar(buffer) { 2644 this.charReceived = buffer.length % 3; 2645 this.charLength = this.charReceived ? 3 : 0; 2646} 2647 2648},{"10":10}],10:[function(_dereq_,module,exports){ 2649(function (global){ 2650/*! 2651 * The buffer module from node.js, for the browser. 2652 * 2653 * @author Feross Aboukhadijeh <[email protected]> <http://feross.org> 2654 * @license MIT 2655 */ 2656/* eslint-disable no-proto */ 2657 2658'use strict' 2659 2660var base64 = _dereq_(7) 2661var ieee754 = _dereq_(17) 2662var isArray = _dereq_(27) 2663 2664exports.Buffer = Buffer 2665exports.SlowBuffer = SlowBuffer 2666exports.INSPECT_MAX_BYTES = 50 2667Buffer.poolSize = 8192 // not used by this implementation 2668 2669var rootParent = {} 2670 2671/** 2672 * If `Buffer.TYPED_ARRAY_SUPPORT`: 2673 * === true Use Uint8Array implementation (fastest) 2674 * === false Use Object implementation (most compatible, even IE6) 2675 * 2676 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, 2677 * Opera 11.6+, iOS 4.2+. 2678 * 2679 * Due to various browser bugs, sometimes the Object implementation will be used even 2680 * when the browser supports typed arrays. 2681 * 2682 * Note: 2683 *
2684 * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, 2685 * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. 2686 * 2687 * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property 2688 * on objects. 2689 * 2690 * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. 2691 * 2692 * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of 2693 * incorrect length in some situations. 2694 2695 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they 2696 * get the Object implementation, which is slower but behaves correctly. 2697 */ 2698Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined 2699 ? global.TYPED_ARRAY_SUPPORT 2700 : typedArraySupport() 2701 2702function typedArraySupport () { 2703 function Bar () {} 2704 try { 2705 var arr = new Uint8Array(1) 2706 arr.foo = function () { return 42 } 2707 arr.constructor = Bar 2708 return arr.foo() === 42 && // typed array instances can be augmented 2709 arr.constructor === Bar && // constructor can be set 2710 typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` 2711 arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` 2712 } catch (e) { 2713 return false 2714 } 2715} 2716 2717function kMaxLength () { 2718 return Buffer.TYPED_ARRAY_SUPPORT 2719 ? 0x7fffffff 2720 : 0x3fffffff 2721} 2722 2723/** 2724 * Class: Buffer 2725 * ============= 2726 * 2727 * The Buffer constructor returns instances of `Uint8Array` that are augmented 2728 * with function properties for all the node `Buffer` API functions. We use 2729 * `Uint8Array` so that square bracket notation works as expected -- it returns 2730 * a single octet. 2731 * 2732 * By augmenting the instances, we can avoid modifying the `Uint8Array` 2733 * prototype. 2734 */ 2735function Buffer (arg) { 2736 if (!(this instanceof Buffer)) { 2737 // Avoid going through an ArgumentsAdaptorTrampoline in the common case. 2738 if (arguments.length > 1) return new Buffer(arg, arguments[1]) 2739 return new Buffer(arg) 2740 } 2741 2742 if (!Buffer.TYPED_ARRAY_SUPPORT) { 2743 this.length = 0 2744 this.parent = undefined 2745 } 2746 2747 // Common case. 2748 if (typeof arg === 'number') { 2749 return fromNumber(this, arg) 2750 } 2751 2752 // Slightly less common case. 2753 if (typeof arg === 'string') { 2754 return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') 2755 } 2756 2757 // Unusual. 2758 return fromObject(this, arg) 2759} 2760 2761function fromNumber (that, length) { 2762 that = allocate(that, length < 0 ? 0 : checked(length) | 0) 2763 if (!Buffer.TYPED_ARRAY_SUPPORT) { 2764 for (var i = 0; i < length; i++) { 2765 that[i] = 0 2766 } 2767 } 2768 return that 2769} 2770 2771function fromString (that, string, encoding) { 2772 if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' 2773 2774 // Assumption: byteLength() return value is always < kMaxLength. 2775 var length = byteLength(string, encoding) | 0 2776 that = allocate(that, length) 2777 2778 that.write(string, encoding) 2779 return that 2780} 2781 2782function fromObject (that, object) { 2783 if (Buffer.isBuffer(object)) return fromBuffer(that, object) 2784 2785 if (isArray(object)) return fromArray(that, object) 2786 2787 if (object == null) { 2788 throw new TypeError('must start with number, buffer, array or string') 2789 } 2790 2791 if (typeof ArrayBuffer !== 'undefined') { 2792 if (object.buffer instanceof ArrayBuffer) { 2793 return fromTypedArray(that, object) 2794 } 2795 if (object instanceof ArrayBuffer) { 2796 return fromArrayBuffer(that, object) 2797 } 2798 } 2799 2800 if (object.length) return fromArrayLike(that, object) 2801 2802 return fromJsonObject(that, object) 2803} 2804 2805function fromBuffer (that, buffer) { 2806 var length = checked(buffer.length) | 0 2807 that = allocate(that, length) 2808 buffer.copy(that, 0, 0, length) 2809 return that 2810} 2811 2812function fromArray (that, array) { 2813 var length = checked(array.length) | 0 2814 that = allocate(that, length) 2815 for (var i = 0; i < length; i += 1) { 2816 that[i] = array[i] & 255 2817 } 2818 return that 2819} 2820 2821// Duplicate of fromArray() to keep fromArray() monomorphic. 2822function fromTypedArray (that, array) { 2823 var length = checked(array.length) | 0 2824 that = allocate(that, length) 2825 // Truncating the elements is probably not what people expect from typed 2826 // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior 2827 // of the old Buffer constructor. 2828 for (var i = 0; i < length; i += 1) { 2829 that[i] = array[i] & 255 2830 } 2831 return that 2832} 2833 2834function fromArrayBuffer (that, array) { 2835 if (Buffer.TYPED_ARRAY_SUPPORT) { 2836 // Return an augmented `Uint8Array` instance, for best performance 2837 array.byteLength
2838 that = Buffer._augment(new Uint8Array(array)) 2839 } else { 2840 // Fallback: Return an object instance of the Buffer class 2841 that = fromTypedArray(that, new Uint8Array(array)) 2842 } 2843 return that 2844} 2845 2846function fromArrayLike (that, array) { 2847 var length = checked(array.length) | 0 2848 that = allocate(that, length) 2849 for (var i = 0; i < length; i += 1) { 2850 that[i] = array[i] & 255 2851 } 2852 return that 2853} 2854 2855// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. 2856// Returns a zero-length buffer for inputs that don't conform to the spec. 2857function fromJsonObject (that, object) { 2858 var array 2859 var length = 0 2860 2861 if (object.type === 'Buffer' && isArray(object.data)) { 2862 array = object.data 2863 length = checked(array.length) | 0 2864 } 2865 that = allocate(that, length) 2866 2867 for (var i = 0; i < length; i += 1) { 2868 that[i] = array[i] & 255 2869 } 2870 return that 2871} 2872 2873if (Buffer.TYPED_ARRAY_SUPPORT) { 2874 Buffer.prototype.__proto__ = Uint8Array.prototype 2875 Buffer.__proto__ = Uint8Array 2876} else { 2877 // pre-set for values that may exist in the future 2878 Buffer.prototype.length = undefined 2879 Buffer.prototype.parent = undefined 2880} 2881 2882function allocate (that, length) { 2883 if (Buffer.TYPED_ARRAY_SUPPORT) { 2884 // Return an augmented `Uint8Array` instance, for best performance 2885 that = Buffer._augment(new Uint8Array(length)) 2886 that.__proto__ = Buffer.prototype 2887 } else { 2888 // Fallback: Return an object instance of the Buffer class 2889 that.length = length 2890 that._isBuffer = true 2891 } 2892 2893 var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 2894 if (fromPool) that.parent = rootParent 2895 2896 return that 2897} 2898 2899function checked (length) { 2900 // Note: cannot use `length < kMaxLength` here because that fails when 2901 // length is NaN (which is otherwise coerced to zero.) 2902 if (length >= kMaxLength()) { 2903 throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 2904 'size: 0x' + kMaxLength().toString(16) + ' bytes') 2905 } 2906 return length | 0 2907} 2908 2909function SlowBuffer (subject, encoding) { 2910 if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) 2911 2912 var buf = new Buffer(subject, encoding) 2913 delete buf.parent 2914 return buf 2915} 2916 2917Buffer.isBuffer = function isBuffer (b) { 2918 return !!(b != null && b._isBuffer) 2919} 2920 2921Buffer.compare = function compare (a, b) { 2922 if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { 2923 throw new TypeError('Arguments must be Buffers') 2924 } 2925 2926 if (a === b) return 0 2927 2928 var x = a.length 2929 var y = b.length 2930 2931 var i = 0 2932 var len = Math.min(x, y) 2933 while (i < len) { 2934 if (a[i] !== b[i]) break 2935 2936 ++i 2937 } 2938 2939 if (i !== len) { 2940 x = a[i] 2941 y = b[i] 2942 } 2943 2944 if (x < y) return -1 2945 if (y < x) return 1 2946 return 0 2947} 2948 2949Buffer.isEncoding = function isEncoding (encoding) { 2950 switch (String(encoding).toLowerCase()) { 2951 case 'hex': 2952 case 'utf8': 2953 case 'utf-8': 2954 case 'ascii': 2955 case 'binary': 2956 case 'base64': 2957 case 'raw': 2958 case 'ucs2': 2959 case 'ucs-2': 2960 case 'utf16le': 2961 case 'utf-16le': 2962 return true 2963 default: 2964 return false 2965 } 2966} 2967 2968Buffer.concat = function concat (list, length) { 2969 if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') 2970 2971 if (list.length === 0) { 2972 return new Buffer(0) 2973 } 2974 2975 var i 2976 if (length === undefined) { 2977 length = 0 2978 for (i = 0; i < list.length; i++) { 2979 length += list[i].length 2980 } 2981 } 2982 2983 var buf = new Buffer(length) 2984 var pos = 0 2985 for (i = 0; i < list.length; i++) { 2986 var item = list[i] 2987 item.copy(buf, pos) 2988 pos += item.length 2989 } 2990 return buf 2991} 2992 2993function byteLength (string, encoding) { 2994 if (typeof string !== 'string') string = '' + string 2995 2996 var len = string.length 2997 if (len === 0) return 0 2998 2999 // Use a for loop to avoid recursion 3000 var loweredCase = false 3001 for (;;) { 3002 switch (encoding) { 3003 case 'ascii': 3004 case 'binary': 3005 // Deprecated 3006 case 'raw': 3007 case 'raws': 3008 return len 3009 case 'utf8': 3010 case 'utf-8': 3011 return utf8ToBytes(string).length 3012 case 'ucs2': 3013 case 'ucs-2': 3014 case 'utf16le': 3015 case 'utf-16le': 3016 return len * 2 3017 case 'hex': 3018 return len >>> 1 3019 case 'base64': 3020 return base64ToBytes(string).length 3021 default: 3022 if (loweredCase) return utf8ToBytes(string).length // assume utf8 3023 encoding = ('' + encoding).toLowerCase() 3024 loweredCase = true 3025 } 3026 } 3027} 3028Buffer.byteLength = byteLength 3029 3030function slowToString (encoding, start, end) { 3031 var loweredCase = false 3032 3033 start = start | 0 3034 end = end === undefined || end === Infinity ? this.length : end | 0 3035 3036 if (!encoding) encoding = 'utf8' 3037 if (start < 0) start = 0 3038 if (end > this.length) end = this.length 3039 if (end <= start) return '' 3040 3041 while (true) { 3042 switch (encoding) { 3043 case 'hex': 3044 return hexSlice(this, start, end) 3045 3046 case 'utf8': 3047 case 'utf-8': 3048 return utf8Slice(this, start, end) 3049 3050 case 'ascii': 3051 return asciiSlice(this, start, end) 3052 3053 case 'binary': 3054 return binarySlice(this, start, end) 3055 3056 case 'base64': 3057 return base64Slice(this, start, end) 3058 3059 case 'ucs2': 3060 case 'ucs-2': 3061 case 'utf16le': 3062 case 'utf-16le': 3063 return utf16leSlice(this, start, end) 3064 3065 default: 3066 if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) 3067 encoding = (encoding + '').toLowerCase() 3068 loweredCase = true 3069 } 3070 } 3071} 3072 3073Buffer.prototype.toString = function toString () { 3074 var length = this.length | 0 3075 if (length === 0) return '' 3076 if (arguments.length === 0) return utf8Slice(this, 0, length) 3077 return slowToString.apply(this, arguments) 3078} 3079 3080Buffer.prototype.equals = function equals (b) { 3081 if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') 3082 if (this === b) return true 3083 return Buffer.compare(this, b) === 0 3084} 3085 3086Buffer.prototype.inspect = function inspect () { 3087 var str = ''
3088 var max = exports.INSPECT_MAX_BYTES 3089 if (this.length > 0) { 3090 str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') 3091 if (this.length > max) str += ' ... ' 3092 } 3093 return '<Buffer ' + str + '>' 3094} 3095 3096Buffer.prototype.compare = function compare (b) { 3097 if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') 3098 if (this === b) return 0 3099 return Buffer.compare(this, b) 3100} 3101 3102Buffer.prototype.indexOf = function indexOf (val, byteOffset) { 3103 if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff 3104 else if (byteOffset < -0x80000000) byteOffset = -0x80000000 3105 byteOffset >>= 0 3106 3107 if (this.length === 0) return -1 3108 if (byteOffset >= this.length) return -1 3109 3110 // Negative offsets start from the end of the buffer 3111 if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) 3112 3113 if (typeof val === 'string') { 3114 if (val.length === 0) return -1 // special case: looking for empty string always fails 3115 return String.prototype.indexOf.call(this, val, byteOffset) 3116 } 3117 if (Buffer.isBuffer(val)) { 3118 return arrayIndexOf(this, val, byteOffset) 3119 } 3120 if (typeof val === 'number') { 3121 if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { 3122 return Uint8Array.prototype.indexOf.call(this, val, byteOffset) 3123 } 3124 return arrayIndexOf(this, [ val ], byteOffset) 3125 } 3126 3127 function arrayIndexOf (arr, val, byteOffset) { 3128 var foundIndex = -1 3129 for (var i = 0; byteOffset + i < arr.length; i++) { 3130 if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { 3131 if (foundIndex === -1) foundIndex = i 3132 if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex 3133 } else { 3134 foundIndex = -1 3135 } 3136 } 3137 return -1 3138 } 3139 3140 throw new TypeError('val must be string, number or Buffer') 3141} 3142 3143// `get` is deprecated 3144Buffer.prototype.get = function get (offset) { 3145 console.log('.get() is deprecated. Access using array indexes instead.') 3146 return this.readUInt8(offset) 3147} 3148 3149// `set` is deprecated 3150Buffer.prototype.set = function set (v, offset) { 3151 console.log('.set() is deprecated. Access using array indexes instead.') 3152 return this.writeUInt8(v, offset) 3153} 3154 3155function hexWrite (buf, string, offset, length) { 3156 offset = Number(offset) || 0 3157 var remaining = buf.length - offset 3158 if (!length) { 3159 length = remaining 3160 } else { 3161 length = Number(length) 3162 if (length > remaining) { 3163 length = remaining 3164 } 3165 } 3166 3167 // must be an even number of digits 3168 var strLen = string.length 3169 if (strLen % 2 !== 0) throw new Error('Invalid hex string') 3170 3171 if (length > strLen / 2) { 3172 length = strLen / 2 3173 } 3174 for (var i = 0; i < length; i++) { 3175 var parsed = parseInt(string.substr(i * 2, 2), 16) 3176 if (isNaN(parsed)) throw new Error('Invalid hex string') 3177 buf[offset + i] = parsed 3178 } 3179 return i 3180} 3181 3182function utf8Write (buf, string, offset, length) { 3183 return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) 3184} 3185 3186function asciiWrite (buf, string, offset, length) { 3187 return blitBuffer(asciiToBytes(string), buf, offset, length) 3188} 3189 3190function binaryWrite (buf, string, offset, length) { 3191 return asciiWrite(buf, string, offset, length) 3192} 3193 3194function base64Write (buf, string, offset, length) { 3195 return blitBuffer(base64ToBytes(string), buf, offset, length) 3196} 3197 3198function ucs2Write (buf, string, offset, length) { 3199 return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) 3200} 3201 3202Buffer.prototype.write = function write (string, offset, length, encoding) { 3203 // Buffer#write(string) 3204 if (offset === undefined) { 3205 encoding = 'utf8' 3206 length = this.length 3207 offset = 0 3208 // Buffer#write(string, encoding) 3209 } else if (length === undefined && typeof offset === 'string') { 3210 encoding = offset 3211 length = this.length 3212 offset = 0 3213 // Buffer#write(string, offset[, length][, encoding]) 3214 } else if (isFinite(offset)) { 3215 offset = offset | 0 3216 if (isFinite(length)) { 3217 length = length | 0 3218 if (encoding === undefined) encoding = 'utf8' 3219 } else { 3220 encoding = length 3221 length = undefined 3222 } 3223 // legacy write(string, encoding, offset, length) - remove in v0.13 3224 } else { 3225 var swap = encoding 3226 encoding = offset 3227 offset = length | 0 3228 length = swap 3229 } 3230 3231 var remaining = this.length - offset 3232 if (length === undefined || length > remaining) length = remaining 3233 3234 if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { 3235 throw new RangeError('attempt to write outside buffer bounds') 3236 } 3237 3238 if (!encoding) encoding = 'utf8' 3239 3240 var loweredCase = false 3241 for (;;) { 3242 switch (encoding) { 3243 case 'hex': 3244 return hexWrite(this, string, offset, length) 3245 3246 case 'utf8': 3247 case 'utf-8': 3248 return utf8Write(this, string, offset, length) 3249 3250 case 'ascii': 3251 return asciiWrite(this, string, offset, length) 3252 3253 case 'binary': 3254 return binaryWrite(this, string, offset, length) 3255 3256 case 'base64': 3257 // Warning: maxLength not taken into account in base64Write 3258 return base64Write(this, string, offset, length) 3259 3260 case 'ucs2': 3261 case 'ucs-2': 3262 case 'utf16le': 3263 case 'utf-16le': 3264 return ucs2Write(this, string, offset, length) 3265 3266 default: 3267 if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) 3268 encoding = ('' + encoding).toLowerCase() 3269 loweredCase = true 3270 } 3271 } 3272} 3273 3274Buffer.prototype.toJSON = function toJSON () { 3275 return { 3276 type: 'Buffer', 3277 data: Array.prototype.slice.call(this._arr || this, 0) 3278 } 3279} 3280 3281function base64Slice (buf, start, end) { 3282 if (start === 0 && end === buf.length) { 3283 return base64.fromByteArray(buf) 3284 } else { 3285 return base64.fromByteArray(buf.slice(start, end)) 3286 } 3287} 3288 3289function utf8Slice (buf, start, end) { 3290 end = Math.min(buf.length, end) 3291 var res = [] 3292 3293 var i = start 3294 while (i < end) { 3295 var firstByte = buf[i] 3296 var codePoint = null 3297 var bytesPerSequence = (firstByte > 0xEF) ? 4 3298 : (firstByte > 0xDF) ? 3 3299 : (firstByte > 0xBF) ? 2 3300 : 1 3301 3302 if (i + bytesPerSequence <= end) { 3303 var secondByte, thirdByte, fourthByte, tempCodePoint 3304 3305 switch (bytesPerSequence) { 3306 case 1: 3307 if (firstByte < 0x80) { 3308 codePoint = firstByte 3309 } 3310 break 3311 case 2: 3312 secondByte = buf[i + 1] 3313 if ((secondByte & 0xC0) === 0x80) { 3314 tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) 3315 if (tempCodePoint > 0x7F) { 3316 codePoint = tempCodePoint 3317 } 3318 } 3319 break 3320 case 3: 3321 secondByte = buf[i + 1] 3322 thirdByte = buf[i + 2] 3323 if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { 3324 tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) 3325 if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { 3326 codePoint = tempCodePoint 3327 } 3328 } 3329 break 3330 case 4: 3331 secondByte = buf[i + 1] 3332 thirdByte = buf[i + 2] 3333 fourthByte = buf[i + 3] 3334 if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { 3335 tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) 3336 if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { 3337 codePoint = tempCodePoint 3338 } 3339 } 3340 } 3341 } 3342 3343 if (codePoint === null) { 3344 // we did not generate a valid codePoint so insert a 3345 // replacement char (U+FFFD) and advance only 1 byte 3346 codePoint = 0xFFFD 3347 bytesPerSequence = 1 3348 } else if (codePoint > 0xFFFF) { 3349 // encode to utf16 (surrogate pair dance) 3350 codePoint -= 0x10000 3351 res.push(codePoint >>>
vendor: 2,580 bytes, lines 3351-3466
3351 10 & 0x3FF | 0xD800) 3352 codePoint = 0xDC00 | codePoint & 0x3FF 3353 } 3354 3355 res.push(codePoint) 3356 i += bytesPerSequence 3357 } 3358 3359 return decodeCodePointsArray(res) 3360} 3361 3362// Based on http://stackoverflow.com/a/22747272/680742, the browser with 3363// the lowest limit is Chrome, with 0x10000 args. 3364// We go 1 magnitude less, for safety 3365var MAX_ARGUMENTS_LENGTH = 0x1000 3366 3367function decodeCodePointsArray (codePoints) { 3368 var len = codePoints.length 3369 if (len <= MAX_ARGUMENTS_LENGTH) { 3370 return String.fromCharCode.apply(String, codePoints) // avoid extra slice() 3371 } 3372 3373 // Decode in chunks to avoid "call stack size exceeded". 3374 var res = '' 3375 var i = 0 3376 while (i < len) { 3377 res += String.fromCharCode.apply( 3378 String, 3379 codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) 3380 ) 3381 } 3382 return res 3383} 3384 3385function asciiSlice (buf, start, end) { 3386 var ret = '' 3387 end = Math.min(buf.length, end) 3388 3389 for (var i = start; i < end; i++) { 3390 ret += String.fromCharCode(buf[i] & 0x7F) 3391 } 3392 return ret 3393} 3394 3395function binarySlice (buf, start, end) { 3396 var ret = '' 3397 end = Math.min(buf.length, end) 3398 3399 for (var i = start; i < end; i++) { 3400 ret += String.fromCharCode(buf[i]) 3401 } 3402 return ret 3403} 3404 3405function hexSlice (buf, start, end) { 3406 var len = buf.length 3407 3408 if (!start || start < 0) start = 0 3409 if (!end || end < 0 || end > len) end = len 3410 3411 var out = '' 3412 for (var i = start; i < end; i++) { 3413 out += toHex(buf[i]) 3414 } 3415 return out 3416} 3417 3418function utf16leSlice (buf, start, end) { 3419 var bytes = buf.slice(start, end) 3420 var res = '' 3421 for (var i = 0; i < bytes.length; i += 2) { 3422 res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) 3423 } 3424 return res 3425} 3426 3427Buffer.prototype.slice = function slice (start, end) { 3428 var len = this.length 3429 start = ~~start 3430 end = end === undefined ? len : ~~end 3431 3432 if (start < 0) { 3433 start += len 3434 if (start < 0) start = 0 3435 } else if (start > len) { 3436 start = len 3437 } 3438 3439 if (end < 0) { 3440 end += len 3441 if (end < 0) end = 0 3442 } else if (end > len) { 3443 end = len 3444 } 3445 3446 if (end < start) end = start 3447 3448 var newBuf 3449 if (Buffer.TYPED_ARRAY_SUPPORT) { 3450 newBuf = Buffer._augment(this.subarray(start, end)) 3451 } else { 3452 var sliceLen = end - start 3453 newBuf = new Buffer(sliceLen, undefined) 3454 for (var i = 0; i < sliceLen; i++) { 3455 newBuf[i] = this[i + start] 3456 } 3457 } 3458 3459 if (newBuf.length) newBuf.parent = this.parent || this 3460 3461 return newBuf 3462} 3463 3464/* 3465 * Need to make sure that buffer isn't trying to write out of bounds. 3466 */
vendor: 10,066 bytes, lines 3467-3795
3467function checkOffset (offset, ext, length) { 3468 if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') 3469 if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') 3470} 3471 3472Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { 3473 offset = offset | 0 3474 byteLength = byteLength | 0 3475 if (!noAssert) checkOffset(offset, byteLength, this.length) 3476 3477 var val = this[offset] 3478 var mul = 1 3479 var i = 0 3480 while (++i < byteLength && (mul *= 0x100)) { 3481 val += this[offset + i] * mul 3482 } 3483 3484 return val 3485} 3486 3487Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { 3488 offset = offset | 0 3489 byteLength = byteLength | 0 3490 if (!noAssert) { 3491 checkOffset(offset, byteLength, this.length) 3492 } 3493 3494 var val = this[offset + --byteLength] 3495 var mul = 1 3496 while (byteLength > 0 && (mul *= 0x100)) { 3497 val += this[offset + --byteLength] * mul 3498 } 3499 3500 return val 3501} 3502 3503Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { 3504 if (!noAssert) checkOffset(offset, 1, this.length) 3505 return this[offset] 3506} 3507 3508Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { 3509 if (!noAssert) checkOffset(offset, 2, this.length) 3510 return this[offset] | (this[offset + 1] << 8) 3511} 3512 3513Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { 3514 if (!noAssert) checkOffset(offset, 2, this.length) 3515 return (this[offset] << 8) | this[offset + 1] 3516} 3517 3518Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { 3519 if (!noAssert) checkOffset(offset, 4, this.length) 3520 3521 return ((this[offset]) | 3522 (this[offset + 1] << 8) | 3523 (this[offset + 2] << 16)) + 3524 (this[offset + 3] * 0x1000000) 3525} 3526 3527Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { 3528 if (!noAssert) checkOffset(offset, 4, this.length) 3529 3530 return (this[offset] * 0x1000000) + 3531 ((this[offset + 1] << 16) | 3532 (this[offset + 2] << 8) | 3533 this[offset + 3]) 3534} 3535 3536Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { 3537 offset = offset | 0 3538 byteLength = byteLength | 0 3539 if (!noAssert) checkOffset(offset, byteLength, this.length) 3540 3541 var val = this[offset] 3542 var mul = 1 3543 var i = 0 3544 while (++i < byteLength && (mul *= 0x100)) { 3545 val += this[offset + i] * mul 3546 } 3547 mul *= 0x80 3548 3549 if (val >= mul) val -= Math.pow(2, 8 * byteLength) 3550 3551 return val 3552} 3553 3554Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { 3555 offset = offset | 0 3556 byteLength = byteLength | 0 3557 if (!noAssert) checkOffset(offset, byteLength, this.length) 3558 3559 var i = byteLength 3560 var mul = 1 3561 var val = this[offset + --i] 3562 while (i > 0 && (mul *= 0x100)) { 3563 val += this[offset + --i] * mul 3564 } 3565 mul *= 0x80 3566 3567 if (val >= mul) val -= Math.pow(2, 8 * byteLength) 3568 3569 return val 3570} 3571 3572Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { 3573 if (!noAssert) checkOffset(offset, 1, this.length) 3574 if (!(this[offset] & 0x80)) return (this[offset]) 3575 return ((0xff - this[offset] + 1) * -1) 3576} 3577 3578Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { 3579 if (!noAssert) checkOffset(offset, 2, this.length) 3580 var val = this[offset] | (this[offset + 1] << 8) 3581 return (val & 0x8000) ? val | 0xFFFF0000 : val 3582} 3583 3584Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { 3585 if (!noAssert) checkOffset(offset, 2, this.length) 3586 var val = this[offset + 1] | (this[offset] << 8) 3587 return (val & 0x8000) ? val | 0xFFFF0000 : val 3588} 3589 3590Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { 3591 if (!noAssert) checkOffset(offset, 4, this.length) 3592 3593 return (this[offset]) | 3594 (this[offset + 1] << 8) | 3595 (this[offset + 2] << 16) | 3596 (this[offset + 3] << 24) 3597} 3598 3599Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { 3600 if (!noAssert) checkOffset(offset, 4, this.length) 3601 3602 return (this[offset] << 24) | 3603 (this[offset + 1] << 16) | 3604 (this[offset + 2] << 8) | 3605 (this[offset + 3]) 3606} 3607 3608Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { 3609 if (!noAssert) checkOffset(offset, 4, this.length) 3610 return ieee754.read(this, offset, true, 23, 4) 3611} 3612 3613Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { 3614 if (!noAssert) checkOffset(offset, 4, this.length) 3615 return ieee754.read(this, offset, false, 23, 4) 3616} 3617 3618Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { 3619 if (!noAssert) checkOffset(offset, 8, this.length) 3620 return ieee754.read(this, offset, true, 52, 8) 3621} 3622 3623Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { 3624 if (!noAssert) checkOffset(offset, 8, this.length) 3625 return ieee754.read(this, offset, false, 52, 8) 3626} 3627 3628function checkInt (buf, value, offset, ext, max, min) { 3629 if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') 3630 if (value > max || value < min) throw new RangeError('value is out of bounds') 3631 if (offset + ext > buf.length) throw new RangeError('index out of range') 3632} 3633 3634Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { 3635 value = +value 3636 offset = offset | 0 3637 byteLength = byteLength | 0 3638 if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) 3639 3640 var mul = 1 3641 var i = 0 3642 this[offset] = value & 0xFF 3643 while (++i < byteLength && (mul *= 0x100)) { 3644 this[offset + i] = (value / mul) & 0xFF 3645 } 3646 3647 return offset + byteLength 3648} 3649 3650Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { 3651 value = +value 3652 offset = offset | 0 3653 byteLength = byteLength | 0 3654 if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) 3655 3656 var i = byteLength - 1 3657 var mul = 1 3658 this[offset + i] = value & 0xFF 3659 while (--i >= 0 && (mul *= 0x100)) { 3660 this[offset + i] = (value / mul) & 0xFF 3661 } 3662 3663 return offset + byteLength 3664} 3665 3666Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { 3667 value = +value 3668 offset = offset | 0 3669 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) 3670 if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 3671 this[offset] = (value & 0xff) 3672 return offset + 1 3673} 3674 3675function objectWriteUInt16 (buf, value, offset, littleEndian) { 3676 if (value < 0) value = 0xffff + value + 1 3677 for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { 3678 buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> 3679 (littleEndian ? i : 1 - i) * 8 3680 } 3681} 3682 3683Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { 3684 value = +value 3685 offset = offset | 0 3686 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) 3687 if (Buffer.TYPED_ARRAY_SUPPORT) { 3688 this[offset] = (value & 0xff) 3689 this[offset + 1] = (value >>> 8) 3690 } else { 3691 objectWriteUInt16(this, value, offset, true) 3692 } 3693 return offset + 2 3694} 3695 3696Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { 3697 value = +value 3698 offset = offset | 0 3699 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) 3700 if (Buffer.TYPED_ARRAY_SUPPORT) { 3701 this[offset] = (value >>> 8) 3702 this[offset + 1] = (value & 0xff) 3703 } else { 3704 objectWriteUInt16(this, value, offset, false) 3705 } 3706 return offset + 2 3707} 3708 3709function objectWriteUInt32 (buf, value, offset, littleEndian) { 3710 if (value < 0) value = 0xffffffff + value + 1 3711 for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { 3712 buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff 3713 } 3714} 3715 3716Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { 3717 value = +value 3718 offset = offset | 0 3719 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) 3720 if (Buffer.TYPED_ARRAY_SUPPORT) { 3721 this[offset + 3] = (value >>> 24) 3722 this[offset + 2] = (value >>> 16) 3723 this[offset + 1] = (value >>> 8) 3724 this[offset] = (value & 0xff) 3725 } else { 3726 objectWriteUInt32(this, value, offset, true) 3727 } 3728 return offset + 4 3729} 3730 3731Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { 3732 value = +value 3733 offset = offset | 0 3734 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) 3735 if (Buffer.TYPED_ARRAY_SUPPORT) { 3736 this[offset] = (value >>> 24) 3737 this[offset + 1] = (value >>> 16) 3738 this[offset + 2] = (value >>> 8) 3739 this[offset + 3] = (value & 0xff) 3740 } else { 3741 objectWriteUInt32(this, value, offset, false) 3742 } 3743 return offset + 4 3744} 3745 3746Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { 3747 value = +value 3748 offset = offset | 0 3749 if (!noAssert) { 3750 var limit = Math.pow(2, 8 * byteLength - 1) 3751 3752 checkInt(this, value, offset, byteLength, limit - 1, -limit) 3753 } 3754 3755 var i = 0 3756 var mul = 1 3757 var sub = value < 0 ? 1 : 0 3758 this[offset] = value & 0xFF 3759 while (++i < byteLength && (mul *= 0x100)) { 3760 this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 3761 } 3762 3763 return offset + byteLength 3764} 3765 3766Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { 3767 value = +value 3768 offset = offset | 0 3769 if (!noAssert) { 3770 var limit = Math.pow(2, 8 * byteLength - 1) 3771 3772 checkInt(this, value, offset, byteLength, limit - 1, -limit) 3773 } 3774 3775 var i = byteLength - 1 3776 var mul = 1 3777 var sub = value < 0 ? 1 : 0 3778 this[offset + i] = value & 0xFF 3779 while (--i >= 0 && (mul *= 0x100)) { 3780 this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 3781 } 3782 3783 return offset + byteLength 3784} 3785 3786Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { 3787 value = +value 3788 offset = offset | 0 3789 if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) 3790 if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 3791 if (value < 0) value = 0xff + value + 1 3792 this[offset] = (value & 0xff) 3793 return offset + 1 3794} 3795
vendor: 4,257 bytes, lines 3796-3919
3796Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { 3797 value = +value 3798 offset = offset | 0 3799 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) 3800 if (Buffer.TYPED_ARRAY_SUPPORT) { 3801 this[offset] = (value & 0xff) 3802 this[offset + 1] = (value >>> 8) 3803 } else { 3804 objectWriteUInt16(this, value, offset, true) 3805 } 3806 return offset + 2 3807} 3808 3809Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { 3810 value = +value 3811 offset = offset | 0 3812 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) 3813 if (Buffer.TYPED_ARRAY_SUPPORT) { 3814 this[offset] = (value >>> 8) 3815 this[offset + 1] = (value & 0xff) 3816 } else { 3817 objectWriteUInt16(this, value, offset, false) 3818 } 3819 return offset + 2 3820} 3821 3822Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { 3823 value = +value 3824 offset = offset | 0 3825 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 3826 if (Buffer.TYPED_ARRAY_SUPPORT) { 3827 this[offset] = (value & 0xff) 3828 this[offset + 1] = (value >>> 8) 3829 this[offset + 2] = (value >>> 16) 3830 this[offset + 3] = (value >>> 24) 3831 } else { 3832 objectWriteUInt32(this, value, offset, true) 3833 } 3834 return offset + 4 3835} 3836 3837Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { 3838 value = +value 3839 offset = offset | 0 3840 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 3841 if (value < 0) value = 0xffffffff + value + 1 3842 if (Buffer.TYPED_ARRAY_SUPPORT) { 3843 this[offset] = (value >>> 24) 3844 this[offset + 1] = (value >>> 16) 3845 this[offset + 2] = (value >>> 8) 3846 this[offset + 3] = (value & 0xff) 3847 } else { 3848 objectWriteUInt32(this, value, offset, false) 3849 } 3850 return offset + 4 3851} 3852 3853function checkIEEE754 (buf, value, offset, ext, max, min) { 3854 if (value > max || value < min) throw new RangeError('value is out of bounds') 3855 if (offset + ext > buf.length) throw new RangeError('index out of range') 3856 if (offset < 0) throw new RangeError('index out of range') 3857} 3858 3859function writeFloat (buf, value, offset, littleEndian, noAssert) { 3860 if (!noAssert) { 3861 checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) 3862 } 3863 ieee754.write(buf, value, offset, littleEndian, 23, 4) 3864 return offset + 4 3865} 3866 3867Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { 3868 return writeFloat(this, value, offset, true, noAssert) 3869} 3870 3871Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { 3872 return writeFloat(this, value, offset, false, noAssert) 3873} 3874 3875function writeDouble (buf, value, offset, littleEndian, noAssert) { 3876 if (!noAssert) { 3877 checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) 3878 } 3879 ieee754.write(buf, value, offset, littleEndian, 52, 8) 3880 return offset + 8 3881} 3882 3883Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { 3884 return writeDouble(this, value, offset, true, noAssert) 3885} 3886 3887Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { 3888 return writeDouble(this, value, offset, false, noAssert) 3889} 3890 3891// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) 3892Buffer.prototype.copy = function copy (target, targetStart, start, end) { 3893 if (!start) start = 0 3894 if (!end && end !== 0) end = this.length 3895 if (targetStart >= target.length) targetStart = target.length 3896 if (!targetStart) targetStart = 0 3897 if (end > 0 && end < start) end = start 3898 3899 // Copy 0 bytes; we're done 3900 if (end === start) return 0 3901 if (target.length === 0 || this.length === 0) return 0 3902 3903 // Fatal error conditions 3904 if (targetStart < 0) { 3905 throw new RangeError('targetStart out of bounds') 3906 } 3907 if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') 3908 if (end < 0) throw new RangeError('sourceEnd out of bounds') 3909 3910 // Are we oob? 3911 if (end > this.length) end = this.length 3912 if (target.length - targetStart < end - start) { 3913 end = target.length - targetStart + start 3914 } 3915 3916 var len = end - start 3917 var i 3918 3919 if (this === target && start < targetStart && targetStart < end) {
3920 // descending copy from end 3921 for (i = len - 1; i >= 0; i--) { 3922 target[i + targetStart] = this[i + start] 3923 } 3924 } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { 3925 // ascending copy from start 3926 for (i = 0; i < len; i++) { 3927 target[i + targetStart] = this[i + start] 3928 } 3929 } else { 3930 target._set(this.subarray(start, start + len), targetStart) 3931 } 3932 3933 return len 3934} 3935 3936// fill(value, start=0, end=buffer.length) 3937Buffer.prototype.fill = function fill (value, start, end) { 3938 if (!value) value = 0 3939 if (!start) start = 0 3940 if (!end) end = this.length 3941 3942 if (end < start) throw new RangeError('end < start') 3943 3944 // Fill 0 bytes; we're done 3945 if (end === start) return 3946 if (this.length === 0) return 3947 3948 if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') 3949 if (end < 0 || end > this.length) throw new RangeError('end out of bounds') 3950 3951 var i 3952 if (typeof value === 'number') { 3953 for (i = start; i < end; i++) { 3954 this[i] = value 3955 } 3956 } else { 3957 var bytes = utf8ToBytes(value.toString()) 3958 var len = bytes.length 3959 for (i = start; i < end; i++) { 3960 this[i] = bytes[i % len] 3961 } 3962 } 3963 3964 return this 3965} 3966 3967/** 3968 * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. 3969 * Added in Node 0.12. Only available in browsers that support ArrayBuffer. 3970 */ 3971Buffer.prototype.toArrayBuffer = function toArrayBuffer () { 3972 if (typeof Uint8Array !== 'undefined') { 3973 if (Buffer.TYPED_ARRAY_SUPPORT) { 3974 return (new Buffer(this)).buffer 3975 } else { 3976 var buf = new Uint8Array(this.length) 3977 for (var i = 0, len = buf.length; i < len; i += 1) { 3978 buf[i] = this[i] 3979 } 3980 return buf.buffer 3981 } 3982 } else { 3983 throw new TypeError('Buffer.toArrayBuffer not supported in this browser') 3984 } 3985} 3986 3987// HELPER FUNCTIONS 3988// ================ 3989 3990var BP = Buffer.prototype 3991 3992/** 3993 * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods 3994 */ 3995Buffer._augment = function _augment (arr) { 3996 arr.constructor = Buffer 3997 arr._isBuffer = true 3998 3999 // save reference to original Uint8Array set method before overwriting 4000 arr._set = arr.set 4001 4002 // deprecated 4003 arr.get = BP.get 4004 arr.set = BP.set 4005 4006 arr.write = BP.write 4007 arr.toString = BP.toString 4008 arr.toLocaleString = BP.toString 4009 arr.toJSON = BP.toJSON 4010 arr.equals = BP.equals 4011 arr.compare = BP.compare 4012 arr.indexOf = BP.indexOf 4013 arr.copy = BP.copy 4014 arr.slice = BP.slice 4015 arr.readUIntLE = BP.readUIntLE 4016 arr.readUIntBE = BP.readUIntBE 4017 arr.readUInt8 = BP.readUInt8 4018 arr.readUInt16LE = BP.readUInt16LE 4019 arr.readUInt16BE = BP.readUInt16BE 4020 arr.readUInt32LE = BP.readUInt32LE 4021 arr.readUInt32BE = BP.readUInt32BE 4022 arr.readIntLE = BP.readIntLE 4023 arr.readIntBE = BP.readIntBE 4024 arr.readInt8 = BP.readInt8 4025 arr.readInt16LE = BP.readInt16LE 4026 arr.readInt16BE = BP.readInt16BE 4027 arr.readInt32LE = BP.readInt32LE 4028 arr.readInt32BE = BP.readInt32BE 4029 arr.readFloatLE = BP.readFloatLE 4030 arr.readFloatBE = BP.readFloatBE 4031 arr.readDoubleLE = BP.readDoubleLE 4032 arr.readDoubleBE = BP.readDoubleBE 4033 arr.writeUInt8 = BP.writeUInt8 4034 arr.writeUIntLE = BP.writeUIntLE 4035 arr.writeUIntBE = BP.writeUIntBE 4036 arr.writeUInt16LE = BP.writeUInt16LE 4037 arr.writeUInt16BE = BP.writeUInt16BE 4038 arr.writeUInt32LE = BP.writeUInt32LE 4039 arr.writeUInt32BE = BP.writeUInt32BE 4040 arr.writeIntLE = BP.writeIntLE 4041 arr.writeIntBE = BP.writeIntBE 4042 arr.writeInt8 = BP.writeInt8 4043 arr.writeInt16LE = BP.writeInt16LE 4044 arr.writeInt16BE = BP.writeInt16BE 4045 arr.writeInt32LE = BP.writeInt32LE 4046 arr.writeInt32BE = BP.writeInt32BE 4047 arr.writeFloatLE = BP.writeFloatLE 4048 arr.writeFloatBE = BP.writeFloatBE 4049 arr.writeDoubleLE = BP.writeDoubleLE 4050 arr.writeDoubleBE = BP.writeDoubleBE 4051 arr.fill = BP.fill 4052 arr.inspect = BP.inspect 4053 arr.toArrayBuffer = BP.toArrayBuffer 4054 4055 return arr 4056} 4057 4058var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g 4059 4060function base64clean (str) { 4061 // Node strips out invalid characters like \n and \t from the string, base64-js does not 4062 str = stringtrim(str).replace(INVALID_BASE64_RE, '') 4063 // Node converts strings with length < 2 to '' 4064 if (str.length < 2) return '' 4065 // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not 4066 while (str.length % 4 !== 0) { 4067 str = str + '=' 4068 } 4069 return str 4070} 4071 4072function stringtrim (str) { 4073 if (str.trim) return str.trim() 4074 return str.replace(/^\s+|\s+$/g, '') 4075} 4076 4077function toHex (n) { 4078 if (n < 16) return '0' + n.toString(16) 4079 return n.toString(16) 4080} 4081 4082function utf8ToBytes (string, units) { 4083 units = units || Infinity 4084 var codePoint 4085 var length = string.length 4086 var leadSurrogate = null 4087 var bytes = [] 4088 4089 for (var i = 0; i < length; i++) { 4090 codePoint = string.charCodeAt(i) 4091 4092 // is surrogate component 4093 if (codePoint > 0xD7FF && codePoint < 0xE000) { 4094 // last char was a lead 4095 if (!leadSurrogate) { 4096 // no lead yet 4097 if (codePoint > 0xDBFF) { 4098 // unexpected trail 4099 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4100 continue 4101 } else if (i + 1 === length) { 4102 // unpaired lead 4103 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4104 continue 4105 } 4106 4107 // valid lead 4108 leadSurrogate = codePoint 4109 4110 continue 4111 } 4112 4113 // 2 leads in a row 4114 if (codePoint < 0xDC00) { 4115 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4116 leadSurrogate = codePoint 4117 continue 4118 } 4119 4120 // valid surrogate pair 4121 codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 4122 } else if (leadSurrogate) { 4123 // valid bmp char, but last char was a lead 4124 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4125 } 4126 4127 leadSurrogate = null 4128 4129 // encode utf8 4130 if (codePoint < 0x80) { 4131 if ((units -= 1) < 0) break 4132 bytes.push(codePoint) 4133 } else if (codePoint < 0x800) { 4134 if ((units -= 2) < 0) break 4135 bytes.push( 4136 codePoint >> 0x6 | 0xC0, 4137 codePoint & 0x3F | 0x80 4138 ) 4139 } else if (codePoint < 0x10000) { 4140 if ((units -= 3) < 0) break 4141 bytes.push( 4142 codePoint >> 0xC | 0xE0, 4143 codePoint >> 0x6 & 0x3F | 0x80, 4144 codePoint & 0x3F | 0x80 4145 ) 4146 } else if (codePoint < 0x110000) { 4147 if ((units -= 4) < 0) break 4148 bytes.push( 4149 codePoint >> 0x12 | 0xF0, 4150 codePoint >> 0xC & 0x3F | 0x80, 4151 codePoint >> 0x6 & 0x3F | 0x80, 4152 codePoint & 0x3F | 0x80 4153 ) 4154 } else { 4155 throw new Error('Invalid code point') 4156 } 4157 } 4158 4159 return bytes 4160} 4161 4162function asciiToBytes (str) { 4163 var byteArray = [] 4164 for (var i = 0; i < str.length; i++) { 4165 // Node's code seems to be doing this and not & 0x7F..
vendor: 5,825 bytes, lines 4166-4368
4166 byteArray.push(str.charCodeAt(i) & 0xFF) 4167 } 4168 return byteArray 4169} 4170 4171function utf16leToBytes (str, units) { 4172 var c, hi, lo 4173 var byteArray = [] 4174 for (var i = 0; i < str.length; i++) { 4175 if ((units -= 2) < 0) break 4176 4177 c = str.charCodeAt(i) 4178 hi = c >> 8 4179 lo = c % 256 4180 byteArray.push(lo) 4181 byteArray.push(hi) 4182 } 4183 4184 return byteArray 4185} 4186 4187function base64ToBytes (str) { 4188 return base64.toByteArray(base64clean(str)) 4189} 4190 4191function blitBuffer (src, dst, offset, length) { 4192 for (var i = 0; i < length; i++) { 4193 if ((i + offset >= dst.length) || (i >= src.length)) break 4194 dst[i + offset] = src[i] 4195 } 4196 return i 4197} 4198 4199}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 4200 4201},{"17":17,"27":27,"7":7}],11:[function(_dereq_,module,exports){ 4202/*! codem-isoboxer v0.3.4 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */ 4203var ISOBoxer = {}; 4204 4205ISOBoxer.parseBuffer = function(arrayBuffer) { 4206 return new ISOFile(arrayBuffer).parse(); 4207}; 4208 4209ISOBoxer.addBoxProcessor = function(type, parser) { 4210 if (typeof type !== 'string' || typeof parser !== 'function') { 4211 return; 4212 } 4213 ISOBox.prototype._boxProcessors[type] = parser; 4214}; 4215 4216ISOBoxer.createFile = function() { 4217 return new ISOFile(); 4218}; 4219 4220// See ISOBoxer.append() for 'pos' parameter syntax 4221ISOBoxer.createBox = function(type, parent, pos) { 4222 var newBox = ISOBox.create(type); 4223 if (parent) { 4224 parent.append(newBox, pos); 4225 } 4226 return newBox; 4227}; 4228 4229// See ISOBoxer.append() for 'pos' parameter syntax 4230ISOBoxer.createFullBox = function(type, parent, pos) { 4231 var newBox = ISOBoxer.createBox(type, parent, pos); 4232 newBox.version = 0; 4233 newBox.flags = 0; 4234 return newBox; 4235}; 4236 4237ISOBoxer.Utils = {}; 4238ISOBoxer.Utils.dataViewToString = function(dataView, encoding) { 4239 var impliedEncoding = encoding || 'utf-8'; 4240 if (typeof TextDecoder !== 'undefined') { 4241 return new TextDecoder(impliedEncoding).decode(dataView); 4242 } 4243 var a = []; 4244 var i = 0; 4245 4246 if (impliedEncoding === 'utf-8') { 4247 /* The following algorithm is essentially a rewrite of the UTF8.decode at 4248 http://bannister.us/weblog/2007/simple-base64-encodedecode-javascript/ 4249 */ 4250 4251 while (i < dataView.byteLength) { 4252 var c = dataView.getUint8(i++); 4253 if (c < 0x80) { 4254 // 1-byte character (7 bits) 4255 } else if (c < 0xe0) { 4256 // 2-byte character (11 bits) 4257 c = (c & 0x1f) << 6; 4258 c |= (dataView.getUint8(i++) & 0x3f); 4259 } else if (c < 0xf0) { 4260 // 3-byte character (16 bits) 4261 c = (c & 0xf) << 12; 4262 c |= (dataView.getUint8(i++) & 0x3f) << 6; 4263 c |= (dataView.getUint8(i++) & 0x3f); 4264 } else { 4265 // 4-byte character (21 bits) 4266 c = (c & 0x7) << 18; 4267 c |= (dataView.getUint8(i++) & 0x3f) << 12; 4268 c |= (dataView.getUint8(i++) & 0x3f) << 6; 4269 c |= (dataView.getUint8(i++) & 0x3f); 4270 } 4271 a.push(String.fromCharCode(c)); 4272 } 4273 } else { // Just map byte-by-byte (probably wrong) 4274 while (i < dataView.byteLength) { 4275 a.push(String.fromCharCode(dataView.getUint8(i++))); 4276 } 4277 } 4278 return a.join(''); 4279}; 4280 4281ISOBoxer.Utils.utf8ToByteArray = function(string) { 4282 // Only UTF-8 encoding is supported by TextEncoder 4283 var u, i; 4284 if (typeof TextEncoder !== 'undefined') { 4285 u = new TextEncoder().encode(string); 4286 } else { 4287 u = []; 4288 for (i = 0; i < string.length; ++i) { 4289 var c = string.charCodeAt(i); 4290 if (c < 0x80) { 4291 u.push(c); 4292 } else if (c < 0x800) { 4293 u.push(0xC0 | (c >> 6)); 4294 u.push(0x80 | (63 & c)); 4295 } else if (c < 0x10000) { 4296 u.push(0xE0 | (c >> 12)); 4297 u.push(0x80 | (63 & (c >> 6))); 4298 u.push(0x80 | (63 & c)); 4299 } else { 4300 u.push(0xF0 | (c >> 18)); 4301 u.push(0x80 | (63 & (c >> 12))); 4302 u.push(0x80 | (63 & (c >> 6))); 4303 u.push(0x80 | (63 & c)); 4304 } 4305 } 4306 } 4307 return u; 4308}; 4309 4310// Method to append a box in the list of child boxes 4311// The 'pos' parameter can be either: 4312// - (number) a position index at which to insert the new box 4313// - (string) the type of the box after which to insert the new box 4314// - (object) the box after which to insert the new box 4315ISOBoxer.Utils.appendBox = function(parent, box, pos) { 4316 box._offset = parent._cursor.offset; 4317 box._root = (parent._root ? parent._root : parent); 4318 box._raw = parent._raw; 4319 box._parent = parent; 4320 4321 if (pos === -1) { 4322 // The new box is a sub-box of the parent but not added in boxes array, 4323 // for example when the new box is set as an entry (see dref and stsd for example) 4324 return; 4325 } 4326 4327 if (pos === undefined || pos === null) { 4328 parent.boxes.push(box); 4329 return; 4330 } 4331 4332 var index = -1, 4333 type; 4334 4335 if (typeof pos === "number") { 4336 index = pos; 4337 } else { 4338 if (typeof pos === "string") { 4339 type = pos; 4340 } else if (typeof pos === "object" && pos.type) { 4341 type = pos.type; 4342 } else { 4343 parent.boxes.push(box); 4344 return; 4345 } 4346 4347 for (var i = 0; i < parent.boxes.length; i++) { 4348 if (type === parent.boxes[i].type) { 4349 index = i + 1; 4350 break; 4351 } 4352 } 4353 } 4354 parent.boxes.splice(index, 0, box); 4355}; 4356 4357if (typeof exports !== 'undefined') { 4358 exports.parseBuffer = ISOBoxer.parseBuffer; 4359 exports.addBoxProcessor = ISOBoxer.addBoxProcessor; 4360 exports.createFile = ISOBoxer.createFile; 4361 exports.createBox = ISOBoxer.createBox; 4362 exports.createFullBox = ISOBoxer.createFullBox; 4363 exports.Utils = ISOBoxer.Utils; 4364} 4365 4366ISOBoxer.Cursor = function(initialOffset) { 4367 this.offset = (typeof initialOffset == 'undefined' ? 0 : initialOffset); 4368};
vendor: 32,838 bytes, lines 4369-5329
4369 4370var ISOFile = function(arrayBuffer) { 4371 this._cursor = new ISOBoxer.Cursor(); 4372 this.boxes = []; 4373 if (arrayBuffer) { 4374 this._raw = new DataView(arrayBuffer); 4375 } 4376}; 4377 4378ISOFile.prototype.fetch = function(type) { 4379 var result = this.fetchAll(type, true); 4380 return (result.length ? result[0] : null); 4381}; 4382 4383ISOFile.prototype.fetchAll = function(type, returnEarly) { 4384 var result = []; 4385 ISOFile._sweep.call(this, type, result, returnEarly); 4386 return result; 4387}; 4388 4389ISOFile.prototype.parse = function() { 4390 this._cursor.offset = 0; 4391 this.boxes = []; 4392 while (this._cursor.offset < this._raw.byteLength) { 4393 var box = ISOBox.parse(this); 4394 4395 // Box could not be parsed 4396 if (typeof box.type === 'undefined') break; 4397 4398 this.boxes.push(box); 4399 } 4400 return this; 4401}; 4402 4403ISOFile._sweep = function(type, result, returnEarly) { 4404 if (this.type && this.type == type) result.push(this); 4405 for (var box in this.boxes) { 4406 if (result.length && returnEarly) return; 4407 ISOFile._sweep.call(this.boxes[box], type, result, returnEarly); 4408 } 4409}; 4410 4411ISOFile.prototype.write = function() { 4412 4413 var length = 0, 4414 i; 4415 4416 for (i = 0; i < this.boxes.length; i++) { 4417 length += this.boxes[i].getLength(false); 4418 } 4419 4420 var bytes = new Uint8Array(length); 4421 this._rawo = new DataView(bytes.buffer); 4422 this.bytes = bytes; 4423 this._cursor.offset = 0; 4424 4425 for (i = 0; i < this.boxes.length; i++) { 4426 this.boxes[i].write(); 4427 } 4428 4429 return bytes.buffer; 4430}; 4431 4432ISOFile.prototype.append = function(box, pos) { 4433 ISOBoxer.Utils.appendBox(this, box, pos); 4434}; 4435var ISOBox = function() { 4436 this._cursor = new ISOBoxer.Cursor(); 4437}; 4438 4439ISOBox.parse = function(parent) { 4440 var newBox = new ISOBox(); 4441 newBox._offset = parent._cursor.offset; 4442 newBox._root = (parent._root ? parent._root : parent); 4443 newBox._raw = parent._raw; 4444 newBox._parent = parent; 4445 newBox._parseBox(); 4446 parent._cursor.offset = newBox._raw.byteOffset + newBox._raw.byteLength; 4447 return newBox; 4448}; 4449 4450ISOBox.create = function(type) { 4451 var newBox = new ISOBox(); 4452 newBox.type = type; 4453 newBox.boxes = []; 4454 return newBox; 4455}; 4456 4457ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc', 'sinf', 'schi', 'encv', 'enca']; 4458 4459ISOBox.prototype._boxProcessors = {}; 4460 4461/////////////////////////////////////////////////////////////////////////////////////////////////// 4462// Generic read/write functions 4463 4464ISOBox.prototype._procField = function (name, type, size) { 4465 if (this._parsing) { 4466 this[name] = this._readField(type, size); 4467 } 4468 else { 4469 this._writeField(type, size, this[name]); 4470 } 4471}; 4472 4473ISOBox.prototype._procFieldArray = function (name, length, type, size) { 4474 var i; 4475 if (this._parsing) { 4476 this[name] = []; 4477 for (i = 0; i < length; i++) { 4478 this[name][i] = this._readField(type, size); 4479 } 4480 } 4481 else { 4482 for (i = 0; i < this[name].length; i++) { 4483 this._writeField(type, size, this[name][i]); 4484 } 4485 } 4486}; 4487 4488ISOBox.prototype._procFullBox = function() { 4489 this._procField('version', 'uint', 8); 4490 this._procField('flags', 'uint', 24); 4491}; 4492 4493ISOBox.prototype._procEntries = function(name, length, fn) { 4494 var i; 4495 if (this._parsing) { 4496 this[name] = []; 4497 for (i = 0; i < length; i++) { 4498 this[name].push({}); 4499 fn.call(this, this[name][i]); 4500 } 4501 } 4502 else { 4503 for (i = 0; i < length; i++) { 4504 fn.call(this, this[name][i]); 4505 } 4506 } 4507}; 4508 4509ISOBox.prototype._procSubEntries = function(entry, name, length, fn) { 4510 var i; 4511 if (this._parsing) { 4512 entry[name] = []; 4513 for (i = 0; i < length; i++) { 4514 entry[name].push({}); 4515 fn.call(this, entry[name][i]); 4516 } 4517 } 4518 else { 4519 for (i = 0; i < length; i++) { 4520 fn.call(this, entry[name][i]); 4521 } 4522 } 4523}; 4524 4525ISOBox.prototype._procEntryField = function (entry, name, type, size) { 4526 if (this._parsing) { 4527 entry[name] = this._readField(type, size); 4528 } 4529 else { 4530 this._writeField(type, size, entry[name]); 4531 } 4532}; 4533 4534ISOBox.prototype._procSubBoxes = function(name, length) { 4535 var i; 4536 if (this._parsing) { 4537 this[name] = []; 4538 for (i = 0; i < length; i++) { 4539 this[name].push(ISOBox.parse(this)); 4540 } 4541 } 4542 else { 4543 for (i = 0; i < length; i++) { 4544 if (this._rawo) { 4545 this[name][i].write(); 4546 } else { 4547 this.size += this[name][i].getLength(); 4548 } 4549 } 4550 } 4551}; 4552 4553/////////////////////////////////////////////////////////////////////////////////////////////////// 4554// Read/parse functions 4555 4556ISOBox.prototype._readField = function(type, size) { 4557 switch (type) { 4558 case 'uint': 4559 return this._readUint(size); 4560 case 'int': 4561 return this._readInt(size); 4562 case 'template': 4563 return this._readTemplate(size); 4564 case 'string': 4565 return (size === -1) ? this._readTerminatedString() : this._readString(size); 4566 case 'data': 4567 return this._readData(size); 4568 case 'utf8': 4569 return this._readUTF8String(); 4570 default: 4571 return -1; 4572 } 4573}; 4574 4575ISOBox.prototype._readInt = function(size) { 4576 var result = null, 4577 offset = this._cursor.offset - this._raw.byteOffset; 4578 switch(size) { 4579 case 8: 4580 result = this._raw.getInt8(offset); 4581 break; 4582 case 16: 4583 result = this._raw.getInt16(offset); 4584 break; 4585 case 32: 4586 result = this._raw.getInt32(offset); 4587 break; 4588 case 64: 4589 // Warning: JavaScript cannot handle 64-bit integers natively. 4590 // This will give unexpected results for integers >= 2^53 4591 var s1 = this._raw.getInt32(offset); 4592 var s2 = this._raw.getInt32(offset + 4); 4593 result = (s1 * Math.pow(2,32)) + s2; 4594 break; 4595 } 4596 this._cursor.offset += (size >> 3); 4597 return result; 4598}; 4599 4600ISOBox.prototype._readUint = function(size) { 4601 var result = null, 4602 offset = this._cursor.offset - this._raw.byteOffset, 4603 s1, s2; 4604 switch(size) { 4605 case 8: 4606 result = this._raw.getUint8(offset); 4607 break; 4608 case 16: 4609 result = this._raw.getUint16(offset); 4610 break; 4611 case 24: 4612 s1 = this._raw.getUint16(offset); 4613 s2 = this._raw.getUint8(offset + 2); 4614 result = (s1 << 8) + s2; 4615 break; 4616 case 32: 4617 result = this._raw.getUint32(offset); 4618 break; 4619 case 64: 4620 // Warning: JavaScript cannot handle 64-bit integers natively. 4621 // This will give unexpected results for integers >= 2^53 4622 s1 = this._raw.getUint32(offset); 4623 s2 = this._raw.getUint32(offset + 4); 4624 result = (s1 * Math.pow(2,32)) + s2; 4625 break; 4626 } 4627 this._cursor.offset += (size >> 3); 4628 return result; 4629}; 4630 4631ISOBox.prototype._readString = function(length) { 4632 var str = ''; 4633 for (var c = 0; c < length; c++) { 4634 var char = this._readUint(8); 4635 str += String.fromCharCode(char); 4636 } 4637 return str; 4638}; 4639 4640ISOBox.prototype._readTemplate = function(size) { 4641 var pre = this._readUint(size / 2); 4642 var post = this._readUint(size / 2); 4643 return pre + (post / Math.pow(2, size / 2)); 4644}; 4645 4646ISOBox.prototype._readTerminatedString = function() { 4647 var str = ''; 4648 while (this._cursor.offset - this._offset < this._raw.byteLength) { 4649 var char = this._readUint(8); 4650 if (char === 0) break; 4651 str += String.fromCharCode(char); 4652 } 4653 return str; 4654}; 4655 4656ISOBox.prototype._readData = function(size) { 4657 var length = (size > 0) ? size : (this._raw.byteLength - (this._cursor.offset - this._offset)); 4658 var data = new DataView(this._raw.buffer, this._cursor.offset, length); 4659 this._cursor.offset += length; 4660 return data; 4661}; 4662 4663ISOBox.prototype._readUTF8String = function() { 4664 var data = this._readData(); 4665 return ISOBoxer.Utils.dataViewToString(data); 4666}; 4667 4668ISOBox.prototype._parseBox = function() { 4669 this._parsing = true; 4670 this._cursor.offset = this._offset; 4671 4672 // return immediately if there are not enough bytes to read the header 4673 if (this._offset + 8 > this._raw.buffer.byteLength) { 4674 this._root._incomplete = true; 4675 return; 4676 } 4677 4678 this._procField('size', 'uint', 32); 4679 this._procField('type', 'string', 4); 4680 4681 if (this.size === 1) { this._procField('largesize', 'uint', 64); } 4682 if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); } 4683 4684 switch(this.size) { 4685 case 0: 4686 this._raw = new DataView(this._raw.buffer, this._offset, (this._raw.byteLength - this._cursor.offset + 8)); 4687 break; 4688 case 1: 4689 if (this._offset + this.size > this._raw.buffer.byteLength) { 4690 this._incomplete = true; 4691 this._root._incomplete = true; 4692 } else { 4693 this._raw = new DataView(this._raw.buffer, this._offset, this.largesize); 4694 } 4695 break; 4696 default: 4697 if (this._offset + this.size > this._raw.buffer.byteLength) { 4698 this._incomplete = true; 4699 this._root._incomplete = true; 4700 } else { 4701 this._raw = new DataView(this._raw.buffer, this._offset, this.size); 4702 } 4703 } 4704 4705 // additional parsing 4706 if (!this._incomplete) { 4707 if (this._boxProcessors[this.type]) { 4708 this._boxProcessors[this.type].call(this); 4709 } 4710 if (this._boxContainers.indexOf(this.type) !== -1) { 4711 this._parseContainerBox(); 4712 } else{ 4713 // Unknown box => read and store box content 4714 this._data = this._readData(); 4715 } 4716 } 4717}; 4718 4719ISOBox.prototype._parseFullBox = function() { 4720 this.version = this._readUint(8); 4721 this.flags = this._readUint(24); 4722}; 4723 4724ISOBox.prototype._parseContainerBox = function() { 4725 this.boxes = []; 4726 while (this._cursor.offset - this._raw.byteOffset < this._raw.byteLength) { 4727 this.boxes.push(ISOBox.parse(this)); 4728 } 4729}; 4730 4731/////////////////////////////////////////////////////////////////////////////////////////////////// 4732// Write functions 4733 4734ISOBox.prototype.append = function(box, pos) { 4735 ISOBoxer.Utils.appendBox(this, box, pos); 4736}; 4737 4738ISOBox.prototype.getLength = function() { 4739 this._parsing = false; 4740 this._rawo = null; 4741 4742 this.size = 0; 4743 this._procField('size', 'uint', 32); 4744 this._procField('type', 'string', 4); 4745 4746 if (this.size === 1) { this._procField('largesize', 'uint', 64); } 4747 if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); } 4748 4749 if (this._boxProcessors[this.type]) { 4750 this._boxProcessors[this.type].call(this); 4751 } 4752 4753 if (this._boxContainers.indexOf(this.type) !== -1) { 4754 for (var i = 0; i < this.boxes.length; i++) { 4755 this.size += this.boxes[i].getLength(); 4756 } 4757 } 4758 4759 if (this._data) { 4760 this._writeData(this._data); 4761 } 4762 4763 return this.size; 4764}; 4765 4766ISOBox.prototype.write = function() { 4767 this._parsing = false; 4768 this._cursor.offset = this._parent._cursor.offset; 4769 4770 switch(this.size) { 4771 case 0: 4772 this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, (this.parent._rawo.byteLength - this._cursor.offset)); 4773 break; 4774 case 1: 4775 this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.largesize); 4776 break; 4777 default: 4778 this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.size); 4779 } 4780 4781 this._procField('size', 'uint', 32); 4782 this._procField('type', 'string', 4); 4783 4784 if (this.size === 1) { this._procField('largesize', 'uint', 64); } 4785 if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); } 4786 4787 if (this._boxProcessors[this.type]) { 4788 this._boxProcessors[this.type].call(this); 4789 } 4790 4791 if (this._boxContainers.indexOf(this.type) !== -1) { 4792 for (var i = 0; i < this.boxes.length; i++) { 4793 this.boxes[i].write(); 4794 } 4795 } 4796 4797 if (this._data) { 4798 this._writeData(this._data); 4799 } 4800 4801 this._parent._cursor.offset += this.size; 4802 4803 return this.size; 4804}; 4805 4806ISOBox.prototype._writeInt = function(size, value) { 4807 if (this._rawo) { 4808 var offset = this._cursor.offset - this._rawo.byteOffset; 4809 switch(size) { 4810 case 8: 4811 this._rawo.setInt8(offset, value); 4812 break; 4813 case 16: 4814 this._rawo.setInt16(offset, value); 4815 break; 4816 case 32: 4817 this._rawo.setInt32(offset, value); 4818 break; 4819 case 64: 4820 // Warning: JavaScript cannot handle 64-bit integers natively. 4821 // This will give unexpected results for integers >= 2^53 4822 var s1 = Math.floor(value / Math.pow(2,32)); 4823 var s2 = value - (s1 * Math.pow(2,32)); 4824 this._rawo.setUint32(offset, s1); 4825 this._rawo.setUint32(offset + 4, s2); 4826 break; 4827 } 4828 this._cursor.offset += (size >> 3); 4829 } else { 4830 this.size += (size >> 3); 4831 } 4832}; 4833 4834ISOBox.prototype._writeUint = function(size, value) { 4835 4836 if (this._rawo) { 4837 var offset = this._cursor.offset - this._rawo.byteOffset, 4838 s1, s2; 4839 switch(size) { 4840 case 8: 4841 this._rawo.setUint8(offset, value); 4842 break; 4843 case 16: 4844 this._rawo.setUint16(offset, value); 4845 break; 4846 case 24: 4847 s1 = (value & 0xFFFF00) >> 8; 4848 s2 = (value & 0x0000FF); 4849 this._rawo.setUint16(offset, s1); 4850 this._rawo.setUint8(offset + 2, s2); 4851 break; 4852 case 32: 4853 this._rawo.setUint32(offset, value); 4854 break; 4855 case 64: 4856 // Warning: JavaScript cannot handle 64-bit integers natively. 4857 // This will give unexpected results for integers >= 2^53 4858 s1 = Math.floor(value / Math.pow(2,32)); 4859 s2 = value - (s1 * Math.pow(2,32)); 4860 this._rawo.setUint32(offset, s1); 4861 this._rawo.setUint32(offset + 4, s2); 4862 break; 4863 } 4864 this._cursor.offset += (size >> 3); 4865 } else { 4866 this.size += (size >> 3); 4867 } 4868}; 4869 4870ISOBox.prototype._writeString = function(size, str) { 4871 for (var c = 0; c < size; c++) { 4872 this._writeUint(8, str.charCodeAt(c)); 4873 } 4874}; 4875 4876ISOBox.prototype._writeTerminatedString = function(str) { 4877 if (str.length === 0) { 4878 return; 4879 } 4880 for (var c = 0; c < str.length; c++) { 4881 this._writeUint(8, str.charCodeAt(c)); 4882 } 4883 this._writeUint(8, 0); 4884}; 4885 4886ISOBox.prototype._writeTemplate = function(size, value) { 4887 var pre = Math.floor(value); 4888 var post = (value - pre) * Math.pow(2, size / 2); 4889 this._writeUint(size / 2, pre); 4890 this._writeUint(size / 2, post); 4891}; 4892 4893ISOBox.prototype._writeData = function(data) { 4894 var i; 4895 if (data instanceof Array) { 4896 if (!Uint8Array.from) { 4897 var typedArray = new Uint8Array(data.length); 4898 for (i = 0; i < data.length; i++) { 4899 typedArray[i] = data[i]; 4900 } 4901 data = new DataView(typedArray.buffer); 4902 } else { 4903 data = new DataView(Uint8Array.from(data).buffer); 4904 } 4905 } 4906 if (data instanceof Uint8Array) { 4907 data = new DataView(data.buffer); 4908 } 4909 if (this._rawo) { 4910 var offset = this._cursor.offset - this._rawo.byteOffset; 4911 for (i = 0; i < data.byteLength; i++) { 4912 this._rawo.setUint8(offset + i, data.getUint8(i)); 4913 } 4914 this._cursor.offset += data.byteLength; 4915 } else { 4916 this.size += data.byteLength; 4917 } 4918}; 4919 4920ISOBox.prototype._writeUTF8String = function(string) { 4921 var u = ISOBoxer.Utils.utf8ToByteArray(string); 4922 if (this._rawo) { 4923 var dataView = new DataView(this._rawo.buffer, this._cursor.offset, u.length); 4924 for (var i = 0; i < u.length; i++) { 4925 dataView.setUint8(i, u[i]); 4926 } 4927 } else { 4928 this.size += u.length; 4929 } 4930}; 4931 4932ISOBox.prototype._writeField = function(type, size, value) { 4933 switch (type) { 4934 case 'uint': 4935 this._writeUint(size, value); 4936 break; 4937 case 'int': 4938 this._writeInt(size, value); 4939 break; 4940 case 'template': 4941 this._writeTemplate(size, value); 4942 break; 4943 case 'string': 4944 if (size == -1) { 4945 this._writeTerminatedString(value); 4946 } else { 4947 this._writeString(size, value); 4948 } 4949 break; 4950 case 'data': 4951 this._writeData(value); 4952 break; 4953 case 'utf8': 4954 this._writeUTF8String(value); 4955 break; 4956 default: 4957 break; 4958 } 4959}; 4960 4961// ISO/IEC 14496-15:2014 - avc1 box 4962ISOBox.prototype._boxProcessors['avc1'] = ISOBox.prototype._boxProcessors['encv'] = function() { 4963 // SampleEntry fields 4964 this._procFieldArray('reserved1', 6, 'uint', 8); 4965 this._procField('data_reference_index', 'uint', 16); 4966 // VisualSampleEntry fields 4967 this._procField('pre_defined1', 'uint', 16); 4968 this._procField('reserved2', 'uint', 16); 4969 this._procFieldArray('pre_defined2', 3, 'uint', 32); 4970 this._procField('width', 'uint', 16); 4971 this._procField('height', 'uint', 16); 4972 this._procField('horizresolution', 'template', 32); 4973 this._procField('vertresolution', 'template', 32); 4974 this._procField('reserved3', 'uint', 32); 4975 this._procField('frame_count', 'uint', 16); 4976 this._procFieldArray('compressorname', 32,'uint', 8); 4977 this._procField('depth', 'uint', 16); 4978 this._procField('pre_defined3', 'int', 16); 4979 // AVCSampleEntry fields 4980 this._procField('config', 'data', -1); 4981}; 4982 4983// ISO/IEC 14496-12:2012 - 8.7.2 Data Reference Box 4984ISOBox.prototype._boxProcessors['dref'] = function() { 4985 this._procFullBox(); 4986 this._procField('entry_count', 'uint', 32); 4987 this._procSubBoxes('entries', this.entry_count); 4988}; 4989 4990// ISO/IEC 14496-12:2012 - 8.6.6 Edit List Box 4991ISOBox.prototype._boxProcessors['elst'] = function() { 4992 this._procFullBox(); 4993 this._procField('entry_count', 'uint', 32); 4994 this._procEntries('entries', this.entry_count, function(entry) { 4995 this._procEntryField(entry, 'segment_duration', 'uint', (this.version === 1) ? 64 : 32); 4996 this._procEntryField(entry, 'media_time', 'int', (this.version === 1) ? 64 : 32); 4997 this._procEntryField(entry, 'media_rate_integer', 'int', 16); 4998 this._procEntryField(entry, 'media_rate_fraction', 'int', 16); 4999 }); 5000}; 5001 5002// ISO/IEC 23009-1:2014 - 5.10.3.3 Event Message Box 5003ISOBox.prototype._boxProcessors['emsg'] = function() { 5004 this._procFullBox(); 5005 this._procField('scheme_id_uri', 'string', -1); 5006 this._procField('value', 'string', -1); 5007 this._procField('timescale', 'uint', 32); 5008 this._procField('presentation_time_delta', 'uint', 32); 5009 this._procField('event_duration', 'uint', 32); 5010 this._procField('id', 'uint', 32); 5011 this._procField('message_data', 'data', -1); 5012}; 5013 5014// ISO/IEC 14496-12:2012 - 8.1.2 Free Space Box 5015ISOBox.prototype._boxProcessors['free'] = ISOBox.prototype._boxProcessors['skip'] = function() { 5016 this._procField('data', 'data', -1); 5017}; 5018 5019// ISO/IEC 14496-12:2012 - 8.12.2 Original Format Box 5020ISOBox.prototype._boxProcessors['frma'] = function() { 5021 this._procField('data_format', 'uint', 32); 5022}; 5023// ISO/IEC 14496-12:2012 - 4.3 File Type Box / 8.16.2 Segment Type Box 5024ISOBox.prototype._boxProcessors['ftyp'] = 5025ISOBox.prototype._boxProcessors['styp'] = function() { 5026 this._procField('major_brand', 'string', 4); 5027 this._procField('minor_version', 'uint', 32); 5028 var nbCompatibleBrands = -1; 5029 if (this._parsing) { 5030 nbCompatibleBrands = (this._raw.byteLength - (this._cursor.offset - this._raw.byteOffset)) / 4; 5031 } 5032 this._procFieldArray('compatible_brands', nbCompatibleBrands, 'string', 4); 5033}; 5034 5035// ISO/IEC 14496-12:2012 - 8.4.3 Handler Reference Box 5036ISOBox.prototype._boxProcessors['hdlr'] = function() { 5037 this._procFullBox(); 5038 this._procField('pre_defined', 'uint', 32); 5039 this._procField('handler_type', 'string', 4); 5040 this._procFieldArray('reserved', 3, 'uint', 32); 5041 this._procField('name', 'string', -1); 5042}; 5043 5044// ISO/IEC 14496-12:2012 - 8.1.1 Media Data Box 5045ISOBox.prototype._boxProcessors['mdat'] = function() { 5046 this._procField('data', 'data', -1); 5047}; 5048 5049// ISO/IEC 14496-12:2012 - 8.4.2 Media Header Box 5050ISOBox.prototype._boxProcessors['mdhd'] = function() { 5051 this._procFullBox(); 5052 this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32); 5053 this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32); 5054 this._procField('timescale', 'uint', 32); 5055 this._procField('duration', 'uint', (this.version == 1) ? 64 : 32); 5056 if (!this._parsing && typeof this.language === 'string') { 5057 // In case of writing and language has been set as a string, then convert it into char codes array 5058 this.language = ((this.language.charCodeAt(0) - 0x60) << 10) | 5059 ((this.language.charCodeAt(1) - 0x60) << 5) | 5060 ((this.language.charCodeAt(2) - 0x60)); 5061 } 5062 this._procField('language', 'uint', 16); 5063 if (this._parsing) { 5064 this.language = String.fromCharCode(((this.language >> 10) & 0x1F) + 0x60, 5065 ((this.language >> 5) & 0x1F) + 0x60, 5066 (this.language & 0x1F) + 0x60); 5067 } 5068 this._procField('pre_defined', 'uint', 16); 5069}; 5070 5071// ISO/IEC 14496-12:2012 - 8.8.2 Movie Extends Header Box 5072ISOBox.prototype._boxProcessors['mehd'] = function() { 5073 this._procFullBox(); 5074 this._procField('fragment_duration', 'uint', (this.version == 1) ? 64 : 32); 5075}; 5076 5077// ISO/IEC 14496-12:2012 - 8.8.5 Movie Fragment Header Box 5078ISOBox.prototype._boxProcessors['mfhd'] = function() { 5079 this._procFullBox(); 5080 this._procField('sequence_number', 'uint', 32); 5081}; 5082 5083// ISO/IEC 14496-12:2012 - 8.8.11 Movie Fragment Random Access Box 5084ISOBox.prototype._boxProcessors['mfro'] = function() { 5085 this._procFullBox(); 5086 this._procField('mfra_size', 'uint', 32); // Called mfra_size to distinguish from the normal "size" attribute of a box 5087}; 5088 5089 5090// ISO/IEC 14496-12:2012 - 8.5.2.2 mp4a box (use AudioSampleEntry definition and naming) 5091ISOBox.prototype._boxProcessors['mp4a'] = ISOBox.prototype._boxProcessors['enca'] = function() { 5092 // SampleEntry fields 5093 this._procFieldArray('reserved1', 6, 'uint', 8); 5094 this._procField('data_reference_index', 'uint', 16); 5095 // AudioSampleEntry fields 5096 this._procFieldArray('reserved2', 2, 'uint', 32); 5097 this._procField('channelcount', 'uint', 16); 5098 this._procField('samplesize', 'uint', 16); 5099 this._procField('pre_defined', 'uint', 16); 5100 this._procField('reserved3', 'uint', 16); 5101 this._procField('samplerate', 'template', 32); 5102 // ESDescriptor fields 5103 this._procField('esds', 'data', -1); 5104}; 5105 5106// ISO/IEC 14496-12:2012 - 8.2.2 Movie Header Box 5107ISOBox.prototype._boxProcessors['mvhd'] = function() { 5108 this._procFullBox(); 5109 this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32); 5110 this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32); 5111 this._procField('timescale', 'uint', 32); 5112 this._procField('duration', 'uint', (this.version == 1) ? 64 : 32); 5113 this._procField('rate', 'template', 32); 5114 this._procField('volume', 'template', 16); 5115 this._procField('reserved1', 'uint', 16); 5116 this._procFieldArray('reserved2', 2, 'uint', 32); 5117 this._procFieldArray('matrix', 9, 'template', 32); 5118 this._procFieldArray('pre_defined', 6,'uint', 32); 5119 this._procField('next_track_ID', 'uint', 32); 5120}; 5121 5122// ISO/IEC 14496-30:2014 - WebVTT Cue Payload Box. 5123ISOBox.prototype._boxProcessors['payl'] = function() { 5124 this._procField('cue_text', 'utf8'); 5125}; 5126 5127//ISO/IEC 23001-7:2011 - 8.1 Protection System Specific Header Box 5128ISOBox.prototype._boxProcessors['pssh'] = function() { 5129 this._procFullBox(); 5130 5131 this._procFieldArray('SystemID', 16, 'uint', 8); 5132 this._procField('DataSize', 'uint', 32); 5133 this._procFieldArray('Data', this.DataSize, 'uint', 8); 5134}; 5135// ISO/IEC 14496-12:2012 - 8.12.5 Scheme Type Box 5136ISOBox.prototype._boxProcessors['schm'] = function() { 5137 this._procFullBox(); 5138 5139 this._procField('scheme_type', 'uint', 32); 5140 this._procField('scheme_version', 'uint', 32); 5141 5142 if (this.flags & 0x000001) { 5143 this._procField('scheme_uri', 'string', -1); 5144 } 5145}; 5146// ISO/IEC 14496-12:2012 - 8.6.4.1 sdtp box 5147ISOBox.prototype._boxProcessors['sdtp'] = function() { 5148 this._procFullBox(); 5149 5150 var sample_count = -1; 5151 if (this._parsing) { 5152 sample_count = (this._raw.byteLength - (this._cursor.offset - this._raw.byteOffset)); 5153 } 5154 5155 this._procFieldArray('sample_dependency_table', sample_count, 'uint', 8); 5156}; 5157 5158// ISO/IEC 14496-12:2012 - 8.16.3 Segment Index Box 5159ISOBox.prototype._boxProcessors['sidx'] = function() { 5160 this._procFullBox(); 5161 this._procField('reference_ID', 'uint', 32); 5162 this._procField('timescale', 'uint', 32); 5163 this._procField('earliest_presentation_time', 'uint', (this.version == 1) ? 64 : 32); 5164 this._procField('first_offset', 'uint', (this.version == 1) ? 64 : 32); 5165 this._procField('reserved', 'uint', 16); 5166 this._procField('reference_count', 'uint', 16); 5167 this._procEntries('references', this.reference_count, function(entry) { 5168 if (!this._parsing) { 5169 entry.reference = (entry.reference_type & 0x00000001) << 31; 5170 entry.reference |= (entry.referenced_size & 0x7FFFFFFF); 5171 entry.sap = (entry.starts_with_SAP & 0x00000001) << 31; 5172 entry.sap |= (entry.SAP_type & 0x00000003) << 28; 5173 entry.sap |= (entry.SAP_delta_time & 0x0FFFFFFF); 5174 } 5175 this._procEntryField(entry, 'reference', 'uint', 32); 5176 this._procEntryField(entry, 'subsegment_duration', 'uint', 32); 5177 this._procEntryField(entry, 'sap', 'uint', 32); 5178 if (this._parsing) { 5179 entry.reference_type = (entry.reference >> 31) & 0x00000001; 5180 entry.referenced_size = entry.reference & 0x7FFFFFFF; 5181 entry.starts_with_SAP = (entry.sap >> 31) & 0x00000001; 5182 entry.SAP_type = (entry.sap >> 28) & 0x00000007; 5183 entry.SAP_delta_time = (entry.sap & 0x0FFFFFFF); 5184 } 5185 }); 5186}; 5187 5188// ISO/IEC 14496-12:2012 - 8.4.5.3 Sound Media Header Box 5189ISOBox.prototype._boxProcessors['smhd'] = function() { 5190 this._procFullBox(); 5191 this._procField('balance', 'uint', 16); 5192 this._procField('reserved', 'uint', 16); 5193}; 5194 5195// ISO/IEC 14496-12:2012 - 8.16.4 Subsegment Index Box 5196ISOBox.prototype._boxProcessors['ssix'] = function() { 5197 this._procFullBox(); 5198 this._procField('subsegment_count', 'uint', 32); 5199 this._procEntries('subsegments', this.subsegment_count, function(subsegment) { 5200 this._procEntryField(subsegment, 'ranges_count', 'uint', 32); 5201 this._procSubEntries(subsegment, 'ranges', subsegment.ranges_count, function(range) { 5202 this._procEntryField(range, 'level', 'uint', 8); 5203 this._procEntryField(range, 'range_size', 'uint', 24); 5204 }); 5205 }); 5206}; 5207 5208// ISO/IEC 14496-12:2012 - 8.5.2 Sample Description Box 5209ISOBox.prototype._boxProcessors['stsd'] = function() { 5210 this._procFullBox(); 5211 this._procField('entry_count', 'uint', 32); 5212 this._procSubBoxes('entries', this.entry_count); 5213}; 5214 5215// ISO/IEC 14496-12:2015 - 8.7.7 Sub-Sample Information Box 5216ISOBox.prototype._boxProcessors['subs'] = function () { 5217 this._procFullBox(); 5218 this._procField('entry_count', 'uint', 32); 5219 this._procEntries('entries', this.entry_count, function(entry) { 5220 this._procEntryField(entry, 'sample_delta', 'uint', 32); 5221 this._procEntryField(entry, 'subsample_count', 'uint', 16); 5222 this._procSubEntries(entry, 'subsamples', entry.subsample_count, function(subsample) { 5223 this._procEntryField(subsample, 'subsample_size', 'uint', (this.version === 1) ? 32 : 16); 5224 this._procEntryField(subsample, 'subsample_priority', 'uint', 8); 5225 this._procEntryField(subsample, 'discardable', 'uint', 8); 5226 this._procEntryField(subsample, 'codec_specific_parameters', 'uint', 32); 5227 }); 5228 }); 5229}; 5230 5231//ISO/IEC 23001-7:2011 - 8.2 Track Encryption Box 5232ISOBox.prototype._boxProcessors['tenc'] = function() { 5233 this._procFullBox(); 5234 5235 this._procField('default_IsEncrypted', 'uint', 24); 5236 this._procField('default_IV_size', 'uint', 8); 5237 this._procFieldArray('default_KID', 16, 'uint', 8); 5238 }; 5239 5240// ISO/IEC 14496-12:2012 - 8.8.12 Track Fragmnent Decode Time 5241ISOBox.prototype._boxProcessors['tfdt'] = function() { 5242 this._procFullBox(); 5243 this._procField('baseMediaDecodeTime', 'uint', (this.version == 1) ? 64 : 32); 5244}; 5245 5246// ISO/IEC 14496-12:2012 - 8.8.7 Track Fragment Header Box 5247ISOBox.prototype._boxProcessors['tfhd'] = function() { 5248 this._procFullBox(); 5249 this._procField('track_ID', 'uint', 32); 5250 if (this.flags & 0x01) this._procField('base_data_offset', 'uint', 64); 5251 if (this.flags & 0x02) this._procField('sample_description_offset', 'uint', 32); 5252 if (this.flags & 0x08) this._procField('default_sample_duration', 'uint', 32); 5253 if (this.flags & 0x10) this._procField('default_sample_size', 'uint', 32); 5254 if (this.flags & 0x20) this._procField('default_sample_flags', 'uint', 32); 5255}; 5256 5257// ISO/IEC 14496-12:2012 - 8.8.10 Track Fragment Random Access Box 5258ISOBox.prototype._boxProcessors['tfra'] = function() { 5259 this._procFullBox(); 5260 this._procField('track_ID', 'uint', 32); 5261 if (!this._parsing) { 5262 this.reserved = 0; 5263 this.reserved |= (this.length_size_of_traf_num & 0x00000030) << 4; 5264 this.reserved |= (this.length_size_of_trun_num & 0x0000000C) << 2; 5265 this.reserved |= (this.length_size_of_sample_num & 0x00000003); 5266 } 5267 this._procField('reserved', 'uint', 32); 5268 if (this._parsing) { 5269 this.length_size_of_traf_num = (this.reserved & 0x00000030) >> 4; 5270 this.length_size_of_trun_num = (this.reserved & 0x0000000C) >> 2; 5271 this.length_size_of_sample_num = (this.reserved & 0x00000003); 5272 } 5273 this._procField('number_of_entry', 'uint', 32); 5274 this._procEntries('entries', this.number_of_entry, function(entry) { 5275 this._procEntryField(entry, 'time', 'uint', (this.version === 1) ? 64 : 32); 5276 this._procEntryField(entry, 'moof_offset', 'uint', (this.version === 1) ? 64 : 32); 5277 this._procEntryField(entry, 'traf_number', 'uint', (this.length_size_of_traf_num + 1) * 8); 5278 this._procEntryField(entry, 'trun_number', 'uint', (this.length_size_of_trun_num + 1) * 8); 5279 this._procEntryField(entry, 'sample_number', 'uint', (this.length_size_of_sample_num + 1) * 8); 5280 }); 5281}; 5282 5283// ISO/IEC 14496-12:2012 - 8.3.2 Track Header Box 5284ISOBox.prototype._boxProcessors['tkhd'] = function() { 5285 this._procFullBox(); 5286 this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32); 5287 this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32); 5288 this._procField('track_ID', 'uint', 32); 5289 this._procField('reserved1', 'uint', 32); 5290 this._procField('duration', 'uint', (this.version == 1) ? 64 : 32); 5291 this._procFieldArray('reserved2', 2, 'uint', 32); 5292 this._procField('layer', 'uint', 16); 5293 this._procField('alternate_group', 'uint', 16); 5294 this._procField('volume', 'template', 16); 5295 this._procField('reserved3', 'uint', 16); 5296 this._procFieldArray('matrix', 9, 'template', 32); 5297 this._procField('width', 'template', 32); 5298 this._procField('height', 'template', 32); 5299}; 5300 5301// ISO/IEC 14496-12:2012 - 8.8.3 Track Extends Box 5302ISOBox.prototype._boxProcessors['trex'] = function() { 5303 this._procFullBox(); 5304 this._procField('track_ID', 'uint', 32); 5305 this._procField('default_sample_description_index', 'uint', 32); 5306 this._procField('default_sample_duration', 'uint', 32); 5307 this._procField('default_sample_size', 'uint', 32); 5308 this._procField('default_sample_flags', 'uint', 32); 5309}; 5310 5311// ISO/IEC 14496-12:2012 - 8.8.8 Track Run Box 5312// Note: the 'trun' box has a direct relation to the 'tfhd' box for defaults. 5313// These defaults are not set explicitly here, but are left to resolve for the user. 5314ISOBox.prototype._boxProcessors['trun'] = function() { 5315 this._procFullBox(); 5316 this._procField('sample_count', 'uint', 32); 5317 if (this.flags & 0x1) this._procField('data_offset', 'int', 32); 5318 if (this.flags & 0x4) this._procField('first_sample_flags', 'uint', 32); 5319 this._procEntries('samples', this.sample_count, function(sample) { 5320 if (this.flags & 0x100) this._procEntryField(sample, 'sample_duration', 'uint', 32); 5321 if (this.flags & 0x200) this._procEntryField(sample, 'sample_size', 'uint', 32); 5322 if (this.flags & 0x400) this._procEntryField(sample, 'sample_flags', 'uint', 32); 5323 if (this.flags & 0x800) this._procEntryField(sample, 'sample_composition_time_offset', (this.version === 1) ? 'int' : 'uint', 32); 5324 }); 5325}; 5326 5327// ISO/IEC 14496-12:2012 - 8.7.2 Data Reference Box 5328ISOBox.prototype._boxProcessors['url '] = ISOBox.prototype._boxProcessors['urn '] = function() { 5329 this._procFullBox();
5330 if (this.type === 'urn ') { 5331 this._procField('name', 'string', -1); 5332 } 5333 this._procField('location', 'string', -1); 5334}; 5335 5336// ISO/IEC 14496-30:2014 - WebVTT Source Label Box 5337ISOBox.prototype._boxProcessors['vlab'] = function() { 5338 this._procField('source_label', 'utf8'); 5339}; 5340 5341// ISO/IEC 14496-12:2012 - 8.4.5.2 Video Media Header Box 5342ISOBox.prototype._boxProcessors['vmhd'] = function() { 5343 this._procFullBox(); 5344 this._procField('graphicsmode', 'uint', 16); 5345 this._procFieldArray('opcolor', 3, 'uint', 16); 5346}; 5347 5348// ISO/IEC 14496-30:2014 - WebVTT Configuration Box 5349ISOBox.prototype._boxProcessors['vttC'] = function() { 5350 this._procField('config', 'utf8'); 5351}; 5352 5353// ISO/IEC 14496-30:2014 - WebVTT Empty Sample Box 5354ISOBox.prototype._boxProcessors['vtte'] = function() { 5355 // Nothing should happen here. 5356}; 5357 5358},{}],12:[function(_dereq_,module,exports){ 5359(function (Buffer){ 5360// Copyright Joyent, Inc. and other Node contributors. 5361// 5362// Permission is hereby granted, free of charge, to any person obtaining a 5363// copy of this software and associated documentation files (the 5364// "Software"), to deal in the Software without restriction, including 5365// without limitation the rights to use, copy, modify, merge, publish, 5366// distribute, sublicense, and/or sell copies of the Software, and to permit 5367// persons to whom the Software is furnished to do so, subject to the 5368// following conditions: 5369// 5370// The above copyright notice and this permission notice shall be included 5371// in all copies or substantial portions of the Software. 5372// 5373// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 5374// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 5375// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 5376// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 5377// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 5378// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 5379// USE OR OTHER DEALINGS IN THE SOFTWARE. 5380 5381// NOTE: These type checking functions intentionally don't use `instanceof` 5382// because it is fragile and can be easily faked with `Object.create()`. 5383 5384function isArray(arg) { 5385 if (Array.isArray) { 5386 return Array.isArray(arg); 5387 } 5388 return objectToString(arg) === '[object Array]'; 5389} 5390exports.isArray = isArray; 5391 5392function isBoolean(arg) { 5393 return typeof arg === 'boolean'; 5394} 5395exports.isBoolean = isBoolean; 5396 5397function isNull(arg) { 5398 return arg === null; 5399} 5400exports.isNull = isNull; 5401 5402function isNullOrUndefined(arg) { 5403 return arg == null; 5404} 5405exports.isNullOrUndefined = isNullOrUndefined; 5406 5407function isNumber(arg) { 5408 return typeof arg === 'number'; 5409} 5410exports.isNumber = isNumber; 5411 5412function isString(arg) { 5413 return typeof arg === 'string'; 5414} 5415exports.isString = isString; 5416 5417function isSymbol(arg) { 5418 return typeof arg === 'symbol'; 5419} 5420exports.isSymbol = isSymbol; 5421 5422function isUndefined(arg) { 5423 return arg === void 0; 5424} 5425exports.isUndefined = isUndefined; 5426 5427function isRegExp(re) { 5428 return objectToString(re) === '[object RegExp]'; 5429} 5430exports.isRegExp = isRegExp; 5431 5432function isObject(arg) { 5433 return typeof arg === 'object' && arg !== null; 5434} 5435exports.isObject = isObject; 5436 5437function isDate(d) { 5438 return objectToString(d) === '[object Date]'; 5439} 5440exports.isDate = isDate; 5441 5442function isError(e) { 5443 return (objectToString(e) === '[object Error]' || e instanceof Error); 5444} 5445exports.isError = isError; 5446 5447function isFunction(arg) { 5448 return typeof arg === 'function'; 5449} 5450exports.isFunction = isFunction; 5451 5452function isPrimitive(arg) { 5453 return arg === null || 5454 typeof arg === 'boolean' || 5455 typeof arg === 'number' || 5456 typeof arg === 'string' || 5457 typeof arg === 'symbol' || // ES6 symbol 5458 typeof arg === 'undefined'; 5459} 5460exports.isPrimitive = isPrimitive; 5461 5462exports.isBuffer = Buffer.isBuffer; 5463 5464function objectToString(o) { 5465 return Object.prototype.toString.call(o); 5466} 5467 5468}).call(this,{"isBuffer":_dereq_(26)}) 5469 5470},{"26":26}],13:[function(_dereq_,module,exports){ 5471var pSlice = Array.prototype.slice; 5472var objectKeys = _dereq_(15); 5473var isArguments = _dereq_(14); 5474 5475var deepEqual = module.exports = function (actual, expected, opts) { 5476 if (!opts) opts = {}; 5477 // 7.1. All identical values are equivalent, as determined by ===. 5478 if (actual === expected) { 5479 return true; 5480 5481 } else if (actual instanceof Date && expected instanceof Date) { 5482 return actual.getTime() === expected.getTime(); 5483 5484 // 7.3. Other pairs that do not both pass typeof value == 'object', 5485 // equivalence is determined by ==. 5486 } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') { 5487 return opts.strict ? actual === expected : actual == expected; 5488 5489 // 7.4. For all other Object pairs, including Array objects, equivalence is 5490 // determined by having the same number of owned properties (as verified 5491 // with Object.prototype.hasOwnProperty.call), the same set of keys 5492 // (although not necessarily the same order), equivalent values for every 5493 // corresponding key, and an identical 'prototype' property. Note: this 5494 // accounts for both named and indexed properties on Arrays. 5495 } else { 5496 return objEquiv(actual, expected, opts); 5497 } 5498} 5499 5500function isUndefinedOrNull(value) { 5501 return value === null || value === undefined; 5502} 5503 5504function isBuffer (x) { 5505 if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false; 5506 if (typeof x.copy !== 'function' || typeof x.slice !== 'function') { 5507 return false; 5508 } 5509 if (x.length > 0 && typeof x[0] !== 'number') return false; 5510 return true; 5511} 5512 5513function objEquiv(a, b, opts) { 5514 var i, key;
5515 if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) 5516 return false; 5517 // an identical 'prototype' property. 5518 if (a.prototype !== b.prototype) return false; 5519 //~~~I've managed to break Object.keys through screwy arguments passing. 5520 // Converting to array solves the problem. 5521 if (isArguments(a)) { 5522 if (!isArguments(b)) { 5523 return false; 5524 } 5525 a = pSlice.call(a); 5526 b = pSlice.call(b); 5527 return deepEqual(a, b, opts); 5528 } 5529 if (isBuffer(a)) { 5530 if (!isBuffer(b)) { 5531 return false; 5532 } 5533 if (a.length !== b.length) return false; 5534 for (i = 0; i < a.length; i++) { 5535 if (a[i] !== b[i]) return false; 5536 } 5537 return true; 5538 } 5539 try { 5540 var ka = objectKeys(a), 5541 kb = objectKeys(b); 5542 } catch (e) {//happens when one is a string literal and the other isn't 5543 return false; 5544 } 5545 // having the same number of owned properties (keys incorporates 5546 // hasOwnProperty) 5547 if (ka.length != kb.length) 5548 return false; 5549 //the same set of keys (although not necessarily the same order), 5550 ka.sort(); 5551 kb.sort(); 5552 //~~~cheap key test 5553 for (i = ka.length - 1; i >= 0; i--) { 5554 if (ka[i] != kb[i]) 5555 return false; 5556 } 5557 //equivalent values for every corresponding key, and 5558 //~~~possibly expensive deep test 5559 for (i = ka.length - 1; i >= 0; i--) { 5560 key = ka[i]; 5561 if (!deepEqual(a[key], b[key], opts)) return false; 5562 } 5563 return typeof a === typeof b; 5564} 5565 5566},{"14":14,"15":15}],14:[function(_dereq_,module,exports){ 5567var supportsArgumentsClass = (function(){ 5568 return Object.prototype.toString.call(arguments) 5569})() == '[object Arguments]'; 5570 5571exports = module.exports = supportsArgumentsClass ? supported : unsupported; 5572 5573exports.supported = supported; 5574function supported(object) { 5575 return Object.prototype.toString.call(object) == '[object Arguments]'; 5576}; 5577 5578exports.unsupported = unsupported; 5579function unsupported(object){ 5580 return object && 5581 typeof object == 'object' && 5582 typeof object.length == 'number' && 5583 Object.prototype.hasOwnProperty.call(object, 'callee') && 5584 !Object.prototype.propertyIsEnumerable.call(object, 'callee') || 5585 false; 5586}; 5587 5588},{}],15:[function(_dereq_,module,exports){ 5589exports = module.exports = typeof Object.keys === 'function' 5590 ? Object.keys : shim; 5591 5592exports.shim = shim; 5593function shim (obj) { 5594 var keys = []; 5595 for (var key in obj) keys.push(key); 5596 return keys; 5597} 5598 5599},{}],16:[function(_dereq_,module,exports){ 5600// Copyright Joyent, Inc. and other Node contributors. 5601// 5602// Permission is hereby granted, free of charge, to any person obtaining a 5603// copy of this software and associated documentation files (the 5604// "Software"), to deal in the Software without restriction, including 5605// without limitation the rights to use, copy, modify, merge, publish, 5606// distribute, sublicense, and/or sell copies of the Software, and to permit 5607// persons to whom the Software is furnished to do so, subject to the 5608// following conditions: 5609// 5610// The above copyright notice and this permission notice shall be included 5611// in all copies or substantial portions of the Software. 5612// 5613// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 5614// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 5615// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 5616// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 5617// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 5618// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 5619// USE OR OTHER DEALINGS IN THE SOFTWARE. 5620 5621function EventEmitter() { 5622 this._events = this._events || {}; 5623 this._maxListeners = this._maxListeners || undefined; 5624} 5625module.exports = EventEmitter; 5626 5627// Backwards-compat with node 0.10.x 5628EventEmitter.EventEmitter = EventEmitter; 5629 5630EventEmitter.prototype._events = undefined; 5631EventEmitter.prototype._maxListeners = undefined; 5632 5633// By default EventEmitters will print a warning if more than 10 listeners are 5634// added to it. This is a useful default which helps finding memory leaks. 5635EventEmitter.defaultMaxListeners = 10; 5636 5637// Obviously not all Emitters should be limited to 10. This function allows 5638// that to be increased. Set to zero for unlimited. 5639EventEmitter.prototype.setMaxListeners = function(n) { 5640 if (!isNumber(n) || n < 0 || isNaN(n)) 5641 throw TypeError('n must be a positive number'); 5642 this._maxListeners = n; 5643 return this; 5644};
vendor: 4,148 bytes, lines 5645-5795
5645 5646EventEmitter.prototype.emit = function(type) { 5647 var er, handler, len, args, i, listeners; 5648 5649 if (!this._events) 5650 this._events = {}; 5651 5652 // If there is no 'error' event listener then throw. 5653 if (type === 'error') { 5654 if (!this._events.error || 5655 (isObject(this._events.error) && !this._events.error.length)) { 5656 er = arguments[1]; 5657 if (er instanceof Error) { 5658 throw er; // Unhandled 'error' event 5659 } 5660 throw TypeError('Uncaught, unspecified "error" event.'); 5661 } 5662 } 5663 5664 handler = this._events[type]; 5665 5666 if (isUndefined(handler)) 5667 return false; 5668 5669 if (isFunction(handler)) { 5670 switch (arguments.length) { 5671 // fast cases 5672 case 1: 5673 handler.call(this); 5674 break; 5675 case 2: 5676 handler.call(this, arguments[1]); 5677 break; 5678 case 3: 5679 handler.call(this, arguments[1], arguments[2]); 5680 break; 5681 // slower 5682 default: 5683 len = arguments.length; 5684 args = new Array(len - 1); 5685 for (i = 1; i < len; i++) 5686 args[i - 1] = arguments[i]; 5687 handler.apply(this, args); 5688 } 5689 } else if (isObject(handler)) { 5690 len = arguments.length; 5691 args = new Array(len - 1); 5692 for (i = 1; i < len; i++) 5693 args[i - 1] = arguments[i]; 5694 5695 listeners = handler.slice(); 5696 len = listeners.length; 5697 for (i = 0; i < len; i++) 5698 listeners[i].apply(this, args); 5699 } 5700 5701 return true; 5702}; 5703 5704EventEmitter.prototype.addListener = function(type, listener) { 5705 var m; 5706 5707 if (!isFunction(listener)) 5708 throw TypeError('listener must be a function'); 5709 5710 if (!this._events) 5711 this._events = {}; 5712 5713 // To avoid recursion in the case that type === "newListener"! Before 5714 // adding it to the listeners, first emit "newListener". 5715 if (this._events.newListener) 5716 this.emit('newListener', type, 5717 isFunction(listener.listener) ? 5718 listener.listener : listener); 5719 5720 if (!this._events[type]) 5721 // Optimize the case of one listener. Don't need the extra array object. 5722 this._events[type] = listener; 5723 else if (isObject(this._events[type])) 5724 // If we've already got an array, just append. 5725 this._events[type].push(listener); 5726 else 5727 // Adding the second element, need to change to array. 5728 this._events[type] = [this._events[type], listener]; 5729 5730 // Check for listener leak 5731 if (isObject(this._events[type]) && !this._events[type].warned) { 5732 var m; 5733 if (!isUndefined(this._maxListeners)) { 5734 m = this._maxListeners; 5735 } else { 5736 m = EventEmitter.defaultMaxListeners; 5737 } 5738 5739 if (m && m > 0 && this._events[type].length > m) { 5740 this._events[type].warned = true; 5741 console.error('(node) warning: possible EventEmitter memory ' + 5742 'leak detected. %d listeners added. ' + 5743 'Use emitter.setMaxListeners() to increase limit.', 5744 this._events[type].length); 5745 if (typeof console.trace === 'function') { 5746 // not supported in IE 10 5747 console.trace(); 5748 } 5749 } 5750 } 5751 5752 return this; 5753}; 5754 5755EventEmitter.prototype.on = EventEmitter.prototype.addListener; 5756 5757EventEmitter.prototype.once = function(type, listener) { 5758 if (!isFunction(listener)) 5759 throw TypeError('listener must be a function'); 5760 5761 var fired = false; 5762 5763 function g() { 5764 this.removeListener(type, g); 5765 5766 if (!fired) { 5767 fired = true; 5768 listener.apply(this, arguments); 5769 } 5770 } 5771 5772 g.listener = listener; 5773 this.on(type, g); 5774 5775 return this; 5776}; 5777 5778// emits a 'removeListener' event iff the listener was removed 5779EventEmitter.prototype.removeListener = function(type, listener) { 5780 var list, position, length, i; 5781 5782 if (!isFunction(listener)) 5783 throw TypeError('listener must be a function'); 5784 5785 if (!this._events || !this._events[type]) 5786 return this; 5787 5788 list = this._events[type]; 5789 length = list.length; 5790 position = -1; 5791 5792 if (list === listener || 5793 (isFunction(list.listener) && list.listener === listener)) { 5794 delete this._events[type]; 5795 if (this._events.removeListener)
vendor: 4,461 bytes, lines 5796-5983
5796 this.emit('removeListener', type, listener); 5797 5798 } else if (isObject(list)) { 5799 for (i = length; i-- > 0;) { 5800 if (list[i] === listener || 5801 (list[i].listener && list[i].listener === listener)) { 5802 position = i; 5803 break; 5804 } 5805 } 5806 5807 if (position < 0) 5808 return this; 5809 5810 if (list.length === 1) { 5811 list.length = 0; 5812 delete this._events[type]; 5813 } else { 5814 list.splice(position, 1); 5815 } 5816 5817 if (this._events.removeListener) 5818 this.emit('removeListener', type, listener); 5819 } 5820 5821 return this; 5822}; 5823 5824EventEmitter.prototype.removeAllListeners = function(type) { 5825 var key, listeners; 5826 5827 if (!this._events) 5828 return this; 5829 5830 // not listening for removeListener, no need to emit 5831 if (!this._events.removeListener) { 5832 if (arguments.length === 0) 5833 this._events = {}; 5834 else if (this._events[type]) 5835 delete this._events[type]; 5836 return this; 5837 } 5838 5839 // emit removeListener for all listeners on all events 5840 if (arguments.length === 0) { 5841 for (key in this._events) { 5842 if (key === 'removeListener') continue; 5843 this.removeAllListeners(key); 5844 } 5845 this.removeAllListeners('removeListener'); 5846 this._events = {}; 5847 return this; 5848 } 5849 5850 listeners = this._events[type]; 5851 5852 if (isFunction(listeners)) { 5853 this.removeListener(type, listeners); 5854 } else { 5855 // LIFO order 5856 while (listeners.length) 5857 this.removeListener(type, listeners[listeners.length - 1]); 5858 } 5859 delete this._events[type]; 5860 5861 return this; 5862}; 5863 5864EventEmitter.prototype.listeners = function(type) { 5865 var ret; 5866 if (!this._events || !this._events[type]) 5867 ret = []; 5868 else if (isFunction(this._events[type])) 5869 ret = [this._events[type]]; 5870 else 5871 ret = this._events[type].slice(); 5872 return ret; 5873}; 5874 5875EventEmitter.listenerCount = function(emitter, type) { 5876 var ret; 5877 if (!emitter._events || !emitter._events[type]) 5878 ret = 0; 5879 else if (isFunction(emitter._events[type])) 5880 ret = 1; 5881 else 5882 ret = emitter._events[type].length; 5883 return ret; 5884}; 5885 5886function isFunction(arg) { 5887 return typeof arg === 'function'; 5888} 5889 5890function isNumber(arg) { 5891 return typeof arg === 'number'; 5892} 5893 5894function isObject(arg) { 5895 return typeof arg === 'object' && arg !== null; 5896} 5897 5898function isUndefined(arg) { 5899 return arg === void 0; 5900} 5901 5902},{}],17:[function(_dereq_,module,exports){ 5903exports.read = function (buffer, offset, isLE, mLen, nBytes) { 5904 var e, m 5905 var eLen = nBytes * 8 - mLen - 1 5906 var eMax = (1 << eLen) - 1 5907 var eBias = eMax >> 1 5908 var nBits = -7 5909 var i = isLE ? (nBytes - 1) : 0 5910 var d = isLE ? -1 : 1 5911 var s = buffer[offset + i] 5912 5913 i += d 5914 5915 e = s & ((1 << (-nBits)) - 1) 5916 s >>= (-nBits) 5917 nBits += eLen 5918 for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} 5919 5920 m = e & ((1 << (-nBits)) - 1) 5921 e >>= (-nBits) 5922 nBits += mLen 5923 for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} 5924 5925 if (e === 0) { 5926 e = 1 - eBias 5927 } else if (e === eMax) { 5928 return m ? NaN : ((s ? -1 : 1) * Infinity) 5929 } else { 5930 m = m + Math.pow(2, mLen) 5931 e = e - eBias 5932 } 5933 return (s ? -1 : 1) * m * Math.pow(2, e - mLen) 5934} 5935 5936exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { 5937 var e, m, c 5938 var eLen = nBytes * 8 - mLen - 1 5939 var eMax = (1 << eLen) - 1 5940 var eBias = eMax >> 1 5941 var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) 5942 var i = isLE ? 0 : (nBytes - 1) 5943 var d = isLE ? 1 : -1 5944 var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 5945 5946 value = Math.abs(value) 5947 5948 if (isNaN(value) || value === Infinity) { 5949 m = isNaN(value) ? 1 : 0 5950 e = eMax 5951 } else { 5952 e = Math.floor(Math.log(value) / Math.LN2) 5953 if (value * (c = Math.pow(2, -e)) < 1) { 5954 e-- 5955 c *= 2 5956 } 5957 if (e + eBias >= 1) { 5958 value += rt / c 5959 } else { 5960 value += rt * Math.pow(2, 1 - eBias) 5961 } 5962 if (value * c >= 2) { 5963 e++ 5964 c /= 2 5965 } 5966 5967 if (e + eBias >= eMax) { 5968 m = 0 5969 e = eMax 5970 } else if (e + eBias >= 1) { 5971 m = (value * c - 1) * Math.pow(2, mLen) 5972 e = e + eBias 5973 } else { 5974 m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) 5975 e = 0 5976 } 5977 } 5978 5979 for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} 5980 5981 e = (e << mLen) | m 5982 eLen += mLen 5983 for (; eLen > 0;
vendor: 11,395 bytes, lines 5983-6348
5983 buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} 5984 5985 buffer[offset + i - d] |= s * 128 5986} 5987 5988},{}],18:[function(_dereq_,module,exports){ 5989/* 5990 * Copyright (c) 2016, Pierre-Anthony Lemieux <[email protected]> 5991 * All rights reserved. 5992 * 5993 * Redistribution and use in source and binary forms, with or without 5994 * modification, are permitted provided that the following conditions are met: 5995 * 5996 * * Redistributions of source code must retain the above copyright notice, this 5997 * list of conditions and the following disclaimer. 5998 * * Redistributions in binary form must reproduce the above copyright notice, 5999 * this list of conditions and the following disclaimer in the documentation 6000 * and/or other materials provided with the distribution. 6001 * 6002 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 6003 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 6004 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 6005 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 6006 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 6007 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 6008 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 6009 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 6010 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 6011 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 6012 * POSSIBILITY OF SUCH DAMAGE. 6013 */ 6014 6015/** 6016 * @module imscDoc 6017 */ 6018 6019; 6020(function (imscDoc, sax, imscNames, imscStyles, imscUtils) { 6021 6022 6023 /** 6024 * Allows a client to provide callbacks to handle children of the <metadata> element 6025 * @typedef {Object} MetadataHandler 6026 * @property {?OpenTagCallBack} onOpenTag 6027 * @property {?CloseTagCallBack} onCloseTag 6028 * @property {?TextCallBack} onText 6029 */ 6030 6031 /** 6032 * Called when the opening tag of an element node is encountered. 6033 * @callback OpenTagCallBack 6034 * @param {string} ns Namespace URI of the element 6035 * @param {string} name Local name of the element 6036 * @param {Object[]} attributes List of attributes, each consisting of a 6037 * `uri`, `name` and `value` 6038 */ 6039 6040 /** 6041 * Called when the closing tag of an element node is encountered. 6042 * @callback CloseTagCallBack 6043 */ 6044 6045 /** 6046 * Called when a text node is encountered. 6047 * @callback TextCallBack 6048 * @param {string} contents Contents of the text node 6049 */ 6050 6051 /** 6052 * Parses an IMSC1 document into an opaque in-memory representation that exposes 6053 * a single method <pre>getMediaTimeEvents()</pre> that returns a list of time 6054 * offsets (in seconds) of the ISD, i.e. the points in time where the visual 6055 * representation of the document change. `metadataHandler` allows the caller to 6056 * be called back when nodes are present in <metadata> elements. 6057 * 6058 * @param {string} xmlstring XML document 6059 * @param {?module:imscUtils.ErrorHandler} errorHandler Error callback 6060 * @param {?MetadataHandler} metadataHandler Callback for <Metadata> elements 6061 * @returns {Object} Opaque in-memory representation of an IMSC1 document 6062 */ 6063 6064 imscDoc.fromXML = function (xmlstring, errorHandler, metadataHandler) { 6065 var p = sax.parser(true, {xmlns: true}); 6066 var estack = []; 6067 var xmllangstack = []; 6068 var xmlspacestack = []; 6069 var metadata_depth = 0; 6070 var doc = null; 6071 6072 p.onclosetag = function (node) { 6073 6074 if (estack[0] instanceof Styling) { 6075 6076 /* flatten chained referential styling */ 6077 6078 for (var sid in estack[0].styles) { 6079 6080 mergeChainedStyles(estack[0], estack[0].styles[sid], errorHandler); 6081 6082 } 6083 6084 } else if (estack[0] instanceof P || estack[0] instanceof Span) { 6085 6086 /* merge anonymous spans */ 6087 6088 if (estack[0].contents.length > 1) { 6089 6090 var cs = [estack[0].contents[0]]; 6091 6092 var c; 6093 6094 for (c = 1; c < estack[0].contents.length; c++) { 6095 6096 if (estack[0].contents[c] instanceof AnonymousSpan && 6097 cs[cs.length - 1] instanceof AnonymousSpan) { 6098 6099 cs[cs.length - 1].text += estack[0].contents[c].text; 6100 6101 } else { 6102 6103 cs.push(estack[0].contents[c]); 6104 6105 } 6106 6107 } 6108 6109 estack[0].contents = cs; 6110 6111 } 6112 6113 // remove redundant nested anonymous spans (9.3.3(1)(c)) 6114 6115 if (estack[0] instanceof Span && 6116 estack[0].contents.length === 1 && 6117 estack[0].contents[0] instanceof AnonymousSpan && 6118 estack[0].text === null) { 6119 6120 estack[0].text = estack[0].contents[0].text; 6121 delete estack[0].contents; 6122 6123 } 6124 6125 } else if (estack[0] instanceof ForeignElement) { 6126 6127 if (estack[0].node.uri === imscNames.ns_tt && 6128 estack[0].node.local === 'metadata') { 6129 6130 /* leave the metadata element */ 6131 6132 metadata_depth--; 6133 6134 } else if (metadata_depth > 0 && 6135 metadataHandler && 6136 'onCloseTag' in metadataHandler) { 6137 6138 /* end of child of metadata element */ 6139 6140 metadataHandler.onCloseTag(); 6141 6142 } 6143 6144 } 6145 6146 // TODO: delete stylerefs? 6147 6148 // maintain the xml:space stack 6149 6150 xmlspacestack.shift(); 6151 6152 // maintain the xml:lang stack 6153 6154 xmllangstack.shift(); 6155 6156 // prepare for the next element 6157 6158 estack.shift(); 6159 }; 6160 6161 p.ontext = function (str) { 6162 6163 if (estack[0] === undefined) { 6164 6165 /* ignoring text outside of elements */ 6166 6167 } else if (estack[0] instanceof Span || estack[0] instanceof P) { 6168 6169 /* create an anonymous span */ 6170 6171 var s = new AnonymousSpan(); 6172 6173 s.initFromText(doc, estack[0], str, xmlspacestack[0], errorHandler); 6174 6175 estack[0].contents.push(s); 6176 6177 } else if (estack[0] instanceof ForeignElement && 6178 metadata_depth > 0 && 6179 metadataHandler && 6180 'onText' in metadataHandler) { 6181 6182 /* text node within a child of metadata element */ 6183 6184 metadataHandler.onText(str); 6185 6186 } 6187 6188 }; 6189 6190 6191 p.onopentag = function (node) { 6192 6193 // maintain the xml:space stack 6194 6195 var xmlspace = node.attributes["xml:space"]; 6196 6197 if (xmlspace) { 6198 6199 xmlspacestack.unshift(xmlspace.value); 6200 6201 } else { 6202 6203 if (xmlspacestack.length === 0) { 6204 6205 xmlspacestack.unshift("default"); 6206 6207 } else { 6208 6209 xmlspacestack.unshift(xmlspacestack[0]); 6210 6211 } 6212 6213 } 6214 6215 /* maintain the xml:lang stack */ 6216 6217 6218 var xmllang = node.attributes["xml:lang"]; 6219 6220 if (xmllang) { 6221 6222 xmllangstack.unshift(xmllang.value); 6223 6224 } else { 6225 6226 if (xmllangstack.length === 0) { 6227 6228 xmllangstack.unshift(""); 6229 6230 } else { 6231 6232 xmllangstack.unshift(xmllangstack[0]); 6233 6234 } 6235 6236 } 6237 6238 6239 /* process the element */ 6240 6241 if (node.uri === imscNames.ns_tt) { 6242 6243 if (node.local === 'tt') { 6244 6245 if (doc !== null) { 6246 6247 reportFatal("Two <tt> elements at (" + this.line + "," + this.column + ")"); 6248 6249 } 6250 6251 doc = new TT(); 6252 6253 doc.initFromNode(node, errorHandler); 6254 6255 estack.unshift(doc); 6256 6257 } else if (node.local === 'head') { 6258 6259 if (!(estack[0] instanceof TT)) { 6260 reportFatal("Parent of <head> element is not <tt> at (" + this.line + "," + this.column + ")"); 6261 } 6262 6263 if (doc.head !== null) { 6264 reportFatal("Second <head> element at (" + this.line + "," + this.column + ")"); 6265 } 6266 6267 doc.head = new Head(); 6268 6269 estack.unshift(doc.head); 6270 6271 } else if (node.local === 'styling') { 6272 6273 if (!(estack[0] instanceof Head)) { 6274 reportFatal("Parent of <styling> element is not <head> at (" + this.line + "," + this.column + ")"); 6275 } 6276 6277 if (doc.head.styling !== null) { 6278 reportFatal("Second <styling> element at (" + this.line + "," + this.column + ")"); 6279 } 6280 6281 doc.head.styling = new Styling(); 6282 6283 estack.unshift(doc.head.styling); 6284 6285 } else if (node.local === 'style') { 6286 6287 var s; 6288 6289 if (estack[0] instanceof Styling) { 6290 6291 s = new Style(); 6292 6293 s.initFromNode(node, errorHandler); 6294 6295 /* ignore <style> element missing @id */ 6296 6297 if (!s.id) { 6298 6299 reportError("<style> element missing @id attribute"); 6300 6301 } else { 6302 6303 doc.head.styling.styles[s.id] = s; 6304 6305 } 6306 6307 estack.unshift(s); 6308 6309 } else if (estack[0] instanceof Region) { 6310 6311 /* nested styles can be merged with specified styles 6312 * immediately, with lower priority 6313 * (see 8.4.4.2(3) at TTML1 ) 6314 */ 6315 6316 s = new Style(); 6317 6318 s.initFromNode(node, errorHandler); 6319 6320 mergeStylesIfNotPresent(s.styleAttrs, estack[0].styleAttrs); 6321 6322 estack.unshift(s); 6323 6324 } else { 6325 6326 reportFatal(errorHandler, "Parent of <style> element is not <styling> or <region> at (" + this.line + "," + this.column + ")"); 6327 6328 } 6329 6330 } else if (node.local === 'layout') { 6331 6332 if (!(estack[0] instanceof Head)) { 6333 6334 reportFatal(errorHandler, "Parent of <layout> element is not <head> at " + this.line + "," + this.column + ")"); 6335 6336 } 6337 6338 if (doc.head.layout !== null) { 6339 6340 reportFatal(errorHandler, "Second <layout> element at " + this.line + "," + this.column + ")"); 6341 6342 } 6343 6344 doc.head.layout = new Layout(); 6345 6346 estack.unshift(doc.head.layout); 6347 6348 }
vendor: 4,193 bytes, lines 6348-6477
6348 else if (node.local === 'region') { 6349 6350 if (!(estack[0] instanceof Layout)) { 6351 reportFatal(errorHandler, "Parent of <region> element is not <layout> at " + this.line + "," + this.column + ")"); 6352 } 6353 6354 var r = new Region(); 6355 6356 r.initFromNode(doc, node, errorHandler); 6357 6358 if (!r.id || r.id in doc.head.layout.regions) { 6359 6360 reportError(errorHandler, "Ignoring <region> with duplicate or missing @id at " + this.line + "," + this.column + ")"); 6361 6362 } else { 6363 6364 doc.head.layout.regions[r.id] = r; 6365 6366 doc._registerEvent(r); 6367 6368 } 6369 6370 estack.unshift(r); 6371 6372 } else if (node.local === 'body') { 6373 6374 if (!(estack[0] instanceof TT)) { 6375 6376 reportFatal(errorHandler, "Parent of <body> element is not <tt> at " + this.line + "," + this.column + ")"); 6377 6378 } 6379 6380 if (doc.body !== null) { 6381 6382 reportFatal(errorHandler, "Second <body> element at " + this.line + "," + this.column + ")"); 6383 6384 } 6385 6386 var b = new Body(); 6387 6388 b.initFromNode(doc, node, errorHandler); 6389 6390 doc._registerEvent(b); 6391 6392 doc.body = b; 6393 6394 estack.unshift(b); 6395 6396 } else if (node.local === 'div') { 6397 6398 if (!(estack[0] instanceof Div || estack[0] instanceof Body)) { 6399 6400 reportFatal(errorHandler, "Parent of <div> element is not <body> or <div> at " + this.line + "," + this.column + ")"); 6401 6402 } 6403 6404 var d = new Div(); 6405 6406 d.initFromNode(doc, estack[0], node, errorHandler); 6407 6408 doc._registerEvent(d); 6409 6410 estack[0].contents.push(d); 6411 6412 estack.unshift(d); 6413 6414 } else if (node.local === 'p') { 6415 6416 if (!(estack[0] instanceof Div)) { 6417 6418 reportFatal(errorHandler, "Parent of <p> element is not <div> at " + this.line + "," + this.column + ")"); 6419 6420 } 6421 6422 var p = new P(); 6423 6424 p.initFromNode(doc, estack[0], node, errorHandler); 6425 6426 doc._registerEvent(p); 6427 6428 estack[0].contents.push(p); 6429 6430 estack.unshift(p); 6431 6432 } else if (node.local === 'span') { 6433 6434 if (!(estack[0] instanceof Span || estack[0] instanceof P)) { 6435 6436 reportFatal(errorHandler, "Parent of <span> element is not <span> or <p> at " + this.line + "," + this.column + ")"); 6437 6438 } 6439 6440 var ns = new Span(); 6441 6442 ns.initFromNode(doc, estack[0], node, xmlspacestack[0], errorHandler); 6443 6444 doc._registerEvent(ns); 6445 6446 estack[0].contents.push(ns); 6447 6448 estack.unshift(ns); 6449 6450 } else if (node.local === 'br') { 6451 6452 if (!(estack[0] instanceof Span || estack[0] instanceof P)) { 6453 6454 reportFatal(errorHandler, "Parent of <br> element is not <span> or <p> at " + this.line + "," + this.column + ")"); 6455 6456 } 6457 6458 var nb = new Br(); 6459 6460 nb.initFromNode(doc, estack[0], node, errorHandler); 6461 6462 doc._registerEvent(nb); 6463 6464 estack[0].contents.push(nb); 6465 6466 estack.unshift(nb); 6467 6468 } else if (node.local === 'set') { 6469 6470 if (!(estack[0] instanceof Span || 6471 estack[0] instanceof P || 6472 estack[0] instanceof Div || 6473 estack[0] instanceof Body || 6474 estack[0] instanceof Region || 6475 estack[0] instanceof Br)) { 6476 6477 reportFatal(errorHandler, "Parent of <set>
vendor: 14,375 bytes, lines 6477-7063
6477 element is not a content element or a region at " + this.line + "," + this.column + ")"); 6478 6479 } 6480 6481 var st = new Set(); 6482 6483 st.initFromNode(doc, estack[0], node, errorHandler); 6484 6485 doc._registerEvent(st); 6486 6487 estack[0].sets.push(st); 6488 6489 estack.unshift(st); 6490 6491 } else { 6492 6493 /* element in the TT namespace, but not a content element */ 6494 6495 estack.unshift(new ForeignElement(node)); 6496 } 6497 6498 } else { 6499 6500 /* ignore elements not in the TTML namespace unless in metadata element */ 6501 6502 estack.unshift(new ForeignElement(node)); 6503 6504 } 6505 6506 /* handle metadata callbacks */ 6507 6508 if (estack[0] instanceof ForeignElement) { 6509 6510 if (node.uri === imscNames.ns_tt && 6511 node.local === 'metadata') { 6512 6513 /* enter the metadata element */ 6514 6515 metadata_depth++; 6516 6517 } else if ( 6518 metadata_depth > 0 && 6519 metadataHandler && 6520 'onOpenTag' in metadataHandler 6521 ) { 6522 6523 /* start of child of metadata element */ 6524 6525 var attrs = []; 6526 6527 for (var a in node.attributes) { 6528 attrs[node.attributes[a].uri + " " + node.attributes[a].local] = 6529 { 6530 uri: node.attributes[a].uri, 6531 local: node.attributes[a].local, 6532 value: node.attributes[a].value 6533 }; 6534 } 6535 6536 metadataHandler.onOpenTag(node.uri, node.local, attrs); 6537 6538 } 6539 6540 } 6541 6542 }; 6543 6544 // parse the document 6545 6546 p.write(xmlstring).close(); 6547 6548 // all referential styling has been flatten, so delete the styling elements if there is a head 6549 // otherwise create an empty head 6550 6551 if (doc.head !== null) { 6552 delete doc.head.styling; 6553 } else { 6554 doc.head = new Head(); 6555 } 6556 6557 // create default region if no regions specified 6558 6559 if (doc.head.layout === null) { 6560 6561 doc.head.layout = new Layout(); 6562 6563 } 6564 6565 var hasRegions = false; 6566 6567 /* AFAIK the only way to determine whether an object has members */ 6568 6569 for (var i in doc.head.layout.regions) { 6570 6571 hasRegions = true; 6572 6573 break; 6574 6575 } 6576 6577 if (!hasRegions) { 6578 6579 var dr = Region.createDefaultRegion(); 6580 6581 doc.head.layout.regions[dr.id] = dr; 6582 6583 } 6584 6585 return doc; 6586 }; 6587 6588 function ForeignElement(node) { 6589 this.node = node; 6590 } 6591 6592 function TT() { 6593 this.events = []; 6594 this.head = null; 6595 this.body = null; 6596 } 6597 6598 TT.prototype.initFromNode = function (node, errorHandler) { 6599 6600 /* compute cell resolution */ 6601 6602 this.cellResolution = extractCellResolution(node, errorHandler); 6603 6604 /* extract frame rate and tick rate */ 6605 6606 var frtr = extractFrameAndTickRate(node, errorHandler); 6607 6608 this.effectiveFrameRate = frtr.effectiveFrameRate; 6609 6610 this.tickRate = frtr.tickRate; 6611 6612 /* extract aspect ratio */ 6613 6614 this.aspectRatio = extractAspectRatio(node, errorHandler); 6615 6616 /* check timebase */ 6617 6618 var attr = findAttribute(node, imscNames.ns_ttp, "timeBase"); 6619 6620 if (attr !== null && attr !== "media") { 6621 6622 reportFatal(errorHandler, "Unsupported time base"); 6623 6624 } 6625 6626 /* retrieve extent */ 6627 6628 var e = extractExtent(node, errorHandler); 6629 6630 if (e === null) { 6631 6632 /* TODO: remove once unit tests are ready */ 6633 6634 this.pxDimensions = {'h': 480, 'w': 640}; 6635 6636 } else { 6637 6638 if (e.h.unit !== "px" || e.w.unit !== "px") { 6639 reportFatal(errorHandler, "Extent on TT must be in px or absent"); 6640 } 6641 6642 this.pxDimensions = {'h': e.h.value, 'w': e.w.value}; 6643 } 6644 6645 }; 6646 6647 /* register a temporal events */ 6648 TT.prototype._registerEvent = function (elem) { 6649 6650 /* skip if begin is not < then end */ 6651 6652 if (elem.end <= elem.begin) return; 6653 6654 /* index the begin time of the event */ 6655 6656 var b_i = indexOf(this.events, elem.begin); 6657 6658 if (!b_i.found) { 6659 this.events.splice(b_i.index, 0, elem.begin); 6660 } 6661 6662 /* index the end time of the event */ 6663 6664 if (elem.end !== Number.POSITIVE_INFINITY) { 6665 6666 var e_i = indexOf(this.events, elem.end); 6667 6668 if (!e_i.found) { 6669 this.events.splice(e_i.index, 0, elem.end); 6670 } 6671 6672 } 6673 6674 }; 6675 6676 6677 /* 6678 * Retrieves the range of ISD times covered by the document 6679 * 6680 * @returns {Array} Array of two elements: min_begin_time and max_begin_time 6681 * 6682 */ 6683 TT.prototype.getMediaTimeRange = function () { 6684 6685 return [this.events[0], this.events[this.events.length - 1]]; 6686 }; 6687 6688 /* 6689 * Returns list of ISD begin times 6690 * 6691 * @returns {Array} 6692 */ 6693 TT.prototype.getMediaTimeEvents = function () { 6694 6695 return this.events; 6696 }; 6697 6698 /* 6699 * Represents a TTML Head element 6700 */ 6701 6702 function Head() { 6703 this.styling = null; 6704 this.layout = null; 6705 } 6706 6707 /* 6708 * Represents a TTML Styling element 6709 */ 6710 6711 function Styling() { 6712 this.styles = {}; 6713 } 6714 6715 /* 6716 * Represents a TTML Style element 6717 */ 6718 6719 function Style() { 6720 this.id = null; 6721 this.styleAttrs = null; 6722 this.styleRefs = null; 6723 } 6724 6725 Style.prototype.initFromNode = function (node, errorHandler) { 6726 this.id = elementGetXMLID(node); 6727 this.styleAttrs = elementGetStyles(node, errorHandler); 6728 this.styleRefs = elementGetStyleRefs(node); 6729 }; 6730 6731 /* 6732 * Represents a TTML Layout element 6733 * 6734 */ 6735 6736 function Layout() { 6737 this.regions = {}; 6738 } 6739 6740 /* 6741 * Represents a TTML Content element 6742 * 6743 */ 6744 6745 function ContentElement(kind) { 6746 this.kind = kind; 6747 this.begin = null; 6748 this.end = null; 6749 this.styleAttrs = null; 6750 this.regionID = null; 6751 this.sets = null; 6752 this.timeContainer = null; 6753 } 6754 6755 ContentElement.prototype.initFromNode = function (doc, parent, node, errorHandler) { 6756 6757 var t = processTiming(doc, parent, node, errorHandler); 6758 this.begin = t.begin; 6759 this.end = t.end; 6760 6761 this.styleAttrs = elementGetStyles(node, errorHandler); 6762 6763 if (doc.head !== null && doc.head.styling !== null) { 6764 mergeReferencedStyles(doc.head.styling, elementGetStyleRefs(node), this.styleAttrs, errorHandler); 6765 } 6766 6767 this.regionID = elementGetRegionID(node); 6768 6769 this.sets = []; 6770 6771 this.timeContainer = elementGetTimeContainer(node, errorHandler); 6772 6773 }; 6774 6775 /* 6776 * Represents a TTML body element 6777 */ 6778 6779 function Body() { 6780 ContentElement.call(this, 'body'); 6781 } 6782 6783 Body.prototype.initFromNode = function (doc, node, errorHandler) { 6784 ContentElement.prototype.initFromNode.call(this, doc, null, node, errorHandler); 6785 this.contents = []; 6786 }; 6787 6788 /* 6789 * Represents a TTML div element 6790 */ 6791 6792 function Div() { 6793 ContentElement.call(this, 'div'); 6794 } 6795 6796 Div.prototype.initFromNode = function (doc, parent, node, errorHandler) { 6797 ContentElement.prototype.initFromNode.call(this, doc, parent, node, errorHandler); 6798 this.contents = []; 6799 }; 6800 6801 /* 6802 * Represents a TTML p element 6803 */ 6804 6805 function P() { 6806 ContentElement.call(this, 'p'); 6807 } 6808 6809 P.prototype.initFromNode = function (doc, parent, node, errorHandler) { 6810 ContentElement.prototype.initFromNode.call(this, doc, parent, node, errorHandler); 6811 this.contents = []; 6812 }; 6813 6814 /* 6815 * Represents a TTML span element 6816 */ 6817 6818 function Span() { 6819 ContentElement.call(this, 'span'); 6820 this.space = null; 6821 } 6822 6823 Span.prototype.initFromNode = function (doc, parent, node, xmlspace, errorHandler) { 6824 ContentElement.prototype.initFromNode.call(this, doc, parent, node, errorHandler); 6825 this.space = xmlspace; 6826 this.contents = []; 6827 }; 6828 6829 /* 6830 * Represents a TTML anonymous span element 6831 */ 6832 6833 function AnonymousSpan() { 6834 ContentElement.call(this, 'span'); 6835 this.space = null; 6836 this.text = null; 6837 } 6838 6839 AnonymousSpan.prototype.initFromText = function (doc, parent, text, xmlspace, errorHandler) { 6840 ContentElement.prototype.initFromNode.call(this, doc, parent, null, errorHandler); 6841 this.text = text; 6842 this.space = xmlspace; 6843 }; 6844 6845 /* 6846 * Represents a TTML br element 6847 */ 6848 6849 function Br() { 6850 ContentElement.call(this, 'br'); 6851 } 6852 6853 Br.prototype.initFromNode = function (doc, parent, node, errorHandler) { 6854 ContentElement.prototype.initFromNode.call(this, doc, parent, node, errorHandler); 6855 }; 6856 6857 /* 6858 * Represents a TTML Region element 6859 * 6860 */ 6861 6862 function Region() { 6863 this.id = null; 6864 this.begin = null; 6865 this.end = null; 6866 this.styleAttrs = null; 6867 this.sets = null; 6868 } 6869 6870 Region.createDefaultRegion = function () { 6871 var r = new Region(); 6872 6873 r.id = ''; 6874 r.begin = 0; 6875 r.end = Number.POSITIVE_INFINITY; 6876 r.styleAttrs = {}; 6877 r.sets = []; 6878 6879 return r; 6880 }; 6881 6882 Region.prototype.initFromNode = function (doc, node, errorHandler) { 6883 6884 this.id = elementGetXMLID(node); 6885 6886 var t = processTiming(doc, null, node, errorHandler); 6887 this.begin = t.begin; 6888 this.end = t.end; 6889 6890 this.styleAttrs = elementGetStyles(node, errorHandler); 6891 6892 this.sets = []; 6893 6894 /* immediately merge referenced styles */ 6895 6896 if (doc.head !== null && doc.head.styling !== null) { 6897 mergeReferencedStyles(doc.head.styling, elementGetStyleRefs(node), this.styleAttrs, errorHandler); 6898 } 6899 6900 }; 6901 6902 /* 6903 * Represents a TTML Set element 6904 * 6905 */ 6906 6907 function Set() { 6908 this.begin = null; 6909 this.end = null; 6910 this.qname = null; 6911 this.value = null; 6912 } 6913 6914 Set.prototype.initFromNode = function (doc, parent, node, errorHandler) { 6915 6916 var t = processTiming(doc, parent, node, errorHandler); 6917 6918 this.begin = t.begin; 6919 this.end = t.end; 6920 6921 var styles = elementGetStyles(node, errorHandler); 6922 6923 for (var qname in styles) { 6924 6925 if (this.qname) { 6926 6927 reportError(errorHandler, "More than one style specified on set"); 6928 break; 6929 6930 } 6931 6932 this.qname = qname; 6933 this.value = styles[qname]; 6934 6935 } 6936 6937 }; 6938 6939 /* 6940 * Utility functions 6941 * 6942 */ 6943 6944 6945 function elementGetXMLID(node) { 6946 return node && 'xml:id' in node.attributes ? node.attributes['xml:id'].value || null : null; 6947 } 6948 6949 function elementGetRegionID(node) { 6950 return node && 'region' in node.attributes ? node.attributes.region.value : ''; 6951 } 6952 6953 function elementGetTimeContainer(node, errorHandler) { 6954 6955 var tc = node && 'timeContainer' in node.attributes ? node.attributes.timeContainer.value : null; 6956 6957 if ((!tc) || tc === "par") { 6958 6959 return "par"; 6960 6961 } else if (tc === "seq") { 6962 6963 return "seq"; 6964 6965 } else { 6966 6967 reportError(errorHandler, "Illegal value of timeContainer (assuming 'par')"); 6968 6969 return "par"; 6970 6971 } 6972 6973 } 6974 6975 function elementGetStyleRefs(node) { 6976 6977 return node && 'style' in node.attributes ? node.attributes.style.value.split(" ") : []; 6978 6979 } 6980 6981 function elementGetStyles(node, errorHandler) { 6982 6983 var s = {}; 6984 6985 if (node !== null) { 6986 6987 for (var i in node.attributes) { 6988 6989 var qname = node.attributes[i].uri + " " + node.attributes[i].local; 6990 6991 var sa = imscStyles.byQName[qname]; 6992 6993 if (sa !== undefined) { 6994 6995 var val = sa.parse(node.attributes[i].value); 6996 6997 if (val !== null) { 6998 6999 s[qname] = val; 7000 7001 /* TODO: consider refactoring errorHandler into parse and compute routines */ 7002 7003 if (sa === imscStyles.byName.zIndex) { 7004 reportWarning(errorHandler, "zIndex attribute present but not used by IMSC1 since regions do not overlap"); 7005 } 7006 7007 } else { 7008 7009 reportError(errorHandler, "Cannot parse styling attribute " + qname + " --> " + node.attributes[i].value); 7010 7011 } 7012 7013 } 7014 7015 } 7016 7017 } 7018 7019 return s; 7020 } 7021 7022 function findAttribute(node, ns, name) { 7023 for (var i in node.attributes) { 7024 7025 if (node.attributes[i].uri === ns && 7026 node.attributes[i].local === name) { 7027 7028 return node.attributes[i].value; 7029 } 7030 } 7031 7032 return null; 7033 } 7034 7035 function extractAspectRatio(node, errorHandler) { 7036 7037 var ar = findAttribute(node, imscNames.ns_ittp, "aspectRatio"); 7038 7039 var rslt = null; 7040 7041 if (ar !== null) { 7042 7043 var ASPECT_RATIO_RE = /(\d+) (\d+)/; 7044 7045 var m = ASPECT_RATIO_RE.exec(ar); 7046 7047 if (m !== null) { 7048 7049 var w = parseInt(m[1]); 7050 7051 var h = parseInt(m[2]); 7052 7053 if (w !== 0 && h !== 0) { 7054 7055 rslt = w / h; 7056 7057 } else { 7058 7059 reportError(errorHandler, "Illegal aspectRatio values (ignoring)"); 7060 } 7061 7062 } else { 7063
vendor: 3,724 bytes, lines 7064-7235
7064 reportError(errorHandler, "Malformed aspectRatio attribute (ignoring)"); 7065 } 7066 7067 } 7068 7069 return rslt; 7070 7071 } 7072 7073 /* 7074 * Returns the cellResolution attribute from a node 7075 * 7076 */ 7077 function extractCellResolution(node, errorHandler) { 7078 7079 var cr = findAttribute(node, imscNames.ns_ttp, "cellResolution"); 7080 7081 // initial value 7082 7083 var h = 15; 7084 var w = 32; 7085 7086 if (cr !== null) { 7087 7088 var CELL_RESOLUTION_RE = /(\d+) (\d+)/; 7089 7090 var m = CELL_RESOLUTION_RE.exec(cr); 7091 7092 if (m !== null) { 7093 7094 w = parseInt(m[1]); 7095 7096 h = parseInt(m[2]); 7097 7098 } else { 7099 7100 reportWarning(errorHandler, "Malformed cellResolution value (using initial value instead)"); 7101 7102 } 7103 7104 } 7105 7106 return {'w': w, 'h': h}; 7107 7108 } 7109 7110 7111 function extractFrameAndTickRate(node, errorHandler) { 7112 7113 // subFrameRate is ignored per IMSC1 specification 7114 7115 // extract frame rate 7116 7117 var fps_attr = findAttribute(node, imscNames.ns_ttp, "frameRate"); 7118 7119 // initial value 7120 7121 var fps = 30; 7122 7123 // match variable 7124 7125 var m; 7126 7127 if (fps_attr !== null) { 7128 7129 var FRAME_RATE_RE = /(\d+)/; 7130 7131 m = FRAME_RATE_RE.exec(fps_attr); 7132 7133 if (m !== null) { 7134 7135 fps = parseInt(m[1]); 7136 7137 } else { 7138 7139 reportWarning(errorHandler, "Malformed frame rate attribute (using initial value instead)"); 7140 } 7141 7142 } 7143 7144 // extract frame rate multiplier 7145 7146 var frm_attr = findAttribute(node, imscNames.ns_ttp, "frameRateMultiplier"); 7147 7148 // initial value 7149 7150 var frm = 1; 7151 7152 if (frm_attr !== null) { 7153 7154 var FRAME_RATE_MULT_RE = /(\d+) (\d+)/; 7155 7156 m = FRAME_RATE_MULT_RE.exec(frm_attr); 7157 7158 if (m !== null) { 7159 7160 frm = parseInt(m[1]) / parseInt(m[2]); 7161 7162 } else { 7163 7164 reportWarning(errorHandler, "Malformed frame rate multiplier attribute (using initial value instead)"); 7165 } 7166 7167 } 7168 7169 var efps = frm * fps; 7170 7171 // extract tick rate 7172 7173 var tr = 1; 7174 7175 var trattr = findAttribute(node, imscNames.ns_ttp, "tickRate"); 7176 7177 if (trattr === null) { 7178 7179 if (fps_attr !== null) tr = efps; 7180 7181 } else { 7182 7183 var TICK_RATE_RE = /(\d+)/; 7184 7185 m = TICK_RATE_RE.exec(trattr); 7186 7187 if (m !== null) { 7188 7189 tr = parseInt(m[1]); 7190 7191 } else { 7192 7193 reportWarning(errorHandler, "Malformed tick rate attribute (using initial value instead)"); 7194 } 7195 7196 } 7197 7198 return {effectiveFrameRate: efps, tickRate: tr}; 7199 7200 } 7201 7202 function extractExtent(node, errorHandler) { 7203 7204 var attr = findAttribute(node, imscNames.ns_tts, "extent"); 7205 7206 if (attr === null) return null; 7207 7208 var s = attr.split(" "); 7209 7210 if (s.length !== 2) { 7211 7212 reportWarning(errorHandler, "Malformed extent (ignoring)"); 7213 7214 return null; 7215 } 7216 7217 var w = imscUtils.parseLength(s[0]); 7218 7219 var h = imscUtils.parseLength(s[1]); 7220 7221 if (!h || !w) { 7222 7223 reportWarning(errorHandler, "Malformed extent values (ignoring)"); 7224 7225 return null; 7226 } 7227 7228 return {'h': h, 'w': w}; 7229 7230 } 7231 7232 function parseTimeExpression(tickRate, effectiveFrameRate, str) { 7233 7234 var CLOCK_TIME_FRACTION_RE = /^(\d{2,}):(\d\d):(\d\d(?:\.\d+)?)$/; 7235 var CLOCK_TIME_FRAMES_RE = /^(\d{2,}):(\d\d):(\d\d)\:(\d{2,})$/;
7236 var OFFSET_FRAME_RE = /^(\d+(?:\.\d+)?)f$/; 7237 var OFFSET_TICK_RE = /^(\d+(?:\.\d+)?)t$/; 7238 var OFFSET_MS_RE = /^(\d+(?:\.\d+)?)ms$/; 7239 var OFFSET_S_RE = /^(\d+(?:\.\d+)?)s$/; 7240 var OFFSET_H_RE = /^(\d+(?:\.\d+)?)h$/; 7241 var OFFSET_M_RE = /^(\d+(?:\.\d+)?)m$/; 7242 var m; 7243 var r = null; 7244 if ((m = OFFSET_FRAME_RE.exec(str)) !== null) { 7245 7246 if (effectiveFrameRate !== null) { 7247 7248 r = parseFloat(m[1]) / effectiveFrameRate; 7249 } 7250 7251 } else if ((m = OFFSET_TICK_RE.exec(str)) !== null) { 7252 7253 if (tickRate !== null) { 7254 7255 r = parseFloat(m[1]) / tickRate; 7256 } 7257 7258 } else if ((m = OFFSET_MS_RE.exec(str)) !== null) { 7259 7260 r = parseFloat(m[1]) / 1000.0; 7261 7262 } else if ((m = OFFSET_S_RE.exec(str)) !== null) { 7263 7264 r = parseFloat(m[1]); 7265 7266 } else if ((m = OFFSET_H_RE.exec(str)) !== null) { 7267 7268 r = parseFloat(m[1]) * 3600.0; 7269 7270 } else if ((m = OFFSET_M_RE.exec(str)) !== null) { 7271 7272 r = parseFloat(m[1]) * 60.0; 7273 7274 } else if ((m = CLOCK_TIME_FRACTION_RE.exec(str)) !== null) { 7275 7276 r = parseInt(m[1]) * 3600 + 7277 parseInt(m[2]) * 60 + 7278 parseFloat(m[3]); 7279 7280 } else if ((m = CLOCK_TIME_FRAMES_RE.exec(str)) !== null) { 7281 7282 /* this assumes that HH:MM:SS is a clock-time-with-fraction */ 7283 7284 if (effectiveFrameRate !== null) { 7285 7286 r = parseInt(m[1]) * 3600 + 7287 parseInt(m[2]) * 60 + 7288 parseInt(m[3]) + 7289 (m[4] === null ? 0 : parseInt(m[4]) / effectiveFrameRate); 7290 } 7291 7292 } 7293 7294 return r; 7295 } 7296 7297 function processTiming(doc, parent, node, errorHandler) { 7298 7299 /* Q: what does this do <div b=1 e=3><p b=1 e=5> ?*/ 7300 /* Q: are children clipped by parent time interval? */ 7301 7302 var isseq = parent && parent.timeContainer === "seq"; 7303 7304 /* retrieve begin value */ 7305 7306 var b = 0; 7307 7308 if (node && 'begin' in node.attributes) { 7309 7310 b = parseTimeExpression(doc.tickRate, doc.effectiveFrameRate, node.attributes.begin.value); 7311 7312 if (b === null) { 7313 7314 reportWarning(errorHandler, "Malformed begin value " + node.attributes.begin.value + " (using 0)"); 7315 7316 b = 0; 7317 7318 } 7319 7320 } 7321 7322 /* retrieve dur value */ 7323 7324 /* NOTE: end is not meaningful on seq container children and dur is equal to 0 if not specified */ 7325 7326 var d = isseq ? 0 : null; 7327 7328 if (node && 'dur' in node.attributes) { 7329 7330 d = parseTimeExpression(doc.tickRate, doc.effectiveFrameRate, node.attributes.dur.value); 7331 7332 if (d === null) { 7333 7334 reportWarning(errorHandler, "Malformed dur value " + node.attributes.dur.value + " (ignoring)"); 7335 7336 } 7337 7338 } 7339 7340 /* retrieve end value */ 7341 7342 var e = null; 7343 7344 if (node && 'end' in node.attributes) { 7345 7346 e = parseTimeExpression(doc.tickRate, doc.effectiveFrameRate, node.attributes.end.value); 7347 7348 if (e === null) { 7349 7350 reportWarning(errorHandler, "Malformed end value (ignoring)"); 7351 7352 } 7353 7354 } 7355 7356 /* compute starting offset */ 7357 7358 var start_off = 0; 7359 7360 if (parent) { 7361 7362 if (isseq && 'contents' in parent && parent.contents.length > 0) { 7363 7364 /* 7365 * if seq time container, offset from the previous sibling end 7366 */ 7367 7368 start_off = parent.contents[parent.contents.length - 1].end; 7369 7370 7371 } else { 7372 7373 /* 7374 * retrieve parent begin. Assume 0 if no parent. 7375 * 7376 */ 7377 7378 start_off = parent.begin || 0; 7379 7380 } 7381 7382 } 7383 7384 /* offset begin per time container semantics */ 7385 7386 b += start_off; 7387 7388 /* set end */ 7389 7390 if (d !== null) { 7391 7392 // use dur if specified 7393 7394 e = b + d; 7395 7396 } else { 7397 7398 /* retrieve parent end, or +infinity if none */ 7399 7400 var parent_e = (parent && 'end' in parent) ? parent.end : Number.POSITIVE_INFINITY; 7401 7402 e = (e !== null) ? e + start_off : parent_e; 7403 7404 } 7405 7406 return {begin: b, end: e}; 7407 7408 } 7409 7410 7411 7412 function mergeChainedStyles(styling, style, errorHandler) { 7413 7414 while (style.styleRefs.length > 0) { 7415 7416 var sref = style.styleRefs.pop(); 7417 7418 if (!(sref in styling.styles)) { 7419 reportError(errorHandler, "Non-existant style id referenced"); 7420 continue; 7421 } 7422 7423 mergeChainedStyles(styling, styling.styles[sref], errorHandler); 7424 7425 mergeStylesIfNotPresent(styling.styles[sref].styleAttrs, style.styleAttrs); 7426 7427 } 7428 7429 } 7430 7431 function mergeReferencedStyles(styling, stylerefs, styleattrs, errorHandler) { 7432 7433 for (var i = stylerefs.length - 1; i >= 0; i--) { 7434 7435 var sref = stylerefs[i];
7436 7437 if (!(sref in styling.styles)) { 7438 reportError(errorHandler, "Non-existant style id referenced"); 7439 continue; 7440 } 7441 7442 mergeStylesIfNotPresent(styling.styles[sref].styleAttrs, styleattrs); 7443 7444 } 7445 7446 } 7447 7448 function mergeStylesIfNotPresent(from_styles, into_styles) { 7449 7450 for (var sname in from_styles) { 7451 7452 if (sname in into_styles) 7453 continue; 7454 7455 into_styles[sname] = from_styles[sname]; 7456 7457 } 7458 7459 } 7460 7461 /* TODO: validate style format at parsing */ 7462 7463 7464 /* 7465 * ERROR HANDLING UTILITY FUNCTIONS 7466 * 7467 */ 7468 7469 function reportInfo(errorHandler, msg) { 7470 7471 if (errorHandler && errorHandler.info && errorHandler.info(msg)) 7472 throw msg; 7473 7474 } 7475 7476 function reportWarning(errorHandler, msg) { 7477 7478 if (errorHandler && errorHandler.warn && errorHandler.warn(msg)) 7479 throw msg; 7480 7481 } 7482 7483 function reportError(errorHandler, msg) { 7484 7485 if (errorHandler && errorHandler.error && errorHandler.error(msg)) 7486 throw msg; 7487 7488 } 7489 7490 function reportFatal(errorHandler, msg) { 7491 7492 if (errorHandler && errorHandler.fatal) 7493 errorHandler.fatal(msg); 7494 7495 throw msg; 7496 7497 } 7498 7499 /* 7500 * Binary search utility function 7501 * 7502 * @typedef {Object} BinarySearchResult 7503 * @property {boolean} found Was an exact match found? 7504 * @property {number} index Position of the exact match or insert position 7505 * 7506 * @returns {BinarySearchResult} 7507 */ 7508 7509 function indexOf(arr, searchval) { 7510 7511 var min = 0; 7512 var max = arr.length - 1; 7513 var cur; 7514 7515 while (min <= max) { 7516 7517 cur = Math.floor((min + max) / 2); 7518 7519 var curval = arr[cur]; 7520 7521 if (curval < searchval) { 7522 7523 min = cur + 1; 7524 7525 } else if (curval > searchval) { 7526 7527 max = cur - 1; 7528 7529 } else { 7530 7531 return {found: true, index: cur}; 7532 7533 } 7534 7535 } 7536 7537 return {found: false, index: min}; 7538 } 7539 7540 7541})(typeof exports === 'undefined' ? this.imscDoc = {} : exports, 7542 typeof sax === 'undefined' ? _dereq_(45) : sax, 7543 typeof imscNames === 'undefined' ? _dereq_(22) : imscNames, 7544 typeof imscStyles === 'undefined' ? _dereq_(23) : imscStyles, 7545 typeof imscUtils === 'undefined' ? _dereq_(24) : imscUtils); 7546 7547},{"22":22,"23":23,"24":24,"45":45}],19:[function(_dereq_,module,exports){ 7548/* 7549 * Copyright (c) 2016, Pierre-Anthony Lemieux <[email protected]> 7550 * All rights reserved. 7551 * 7552 * Redistribution and use in source and binary forms, with or without 7553 * modification, are permitted provided that the following conditions are met: 7554 * 7555 * * Redistributions of source code must retain the above copyright notice, this 7556 * list of conditions and the following disclaimer. 7557 * * Redistributions in binary form must reproduce the above copyright notice, 7558 * this list of conditions and the following disclaimer in the documentation 7559 * and/or other materials provided with the distribution. 7560 * 7561 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 7562 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 7563 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 7564 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 7565 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 7566 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 7567 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 7568 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 7569 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 7570 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 7571 * POSSIBILITY OF SUCH DAMAGE. 7572 */ 7573 7574/** 7575 * @module imscHTML 7576 */ 7577 7578; 7579(function (imscHTML, imscNames, imscStyles) { 7580 7581 /** 7582 * Function that maps <pre>smpte:background</pre> URIs to URLs resolving to image resource 7583 * @callback IMGResolver 7584 * @param {string} <pre>smpte:background</pre> URI 7585 * @return {string} PNG resource URL 7586 */ 7587 7588 7589 /**
7590 * Renders an ISD object (returned by <pre>generateISD()</pre>) into a 7591 * parent element, that must be attached to the DOM. The ISD will be rendered 7592 * into a child <pre>div</pre> 7593 * with heigh and width equal to the clientHeight and clientWidth of the element, 7594 * unless explicitly specified otherwise by the caller. Images URIs specified 7595 * by <pre>smpte:background</pre> attributes are mapped to image resource URLs 7596 * by an <pre>imgResolver</pre> function. The latter takes the value of <code>smpte:background</code> 7597 * attribute and an <code>img</code> DOM element as input, and is expected to 7598 * set the <code>src</code> attribute of the <code>img</code> to the absolute URI of the image. 7599 * <pre>displayForcedOnlyMode</pre> sets the (boolean) 7600 * value of the IMSC1 displayForcedOnlyMode parameter. 7601 * 7602 * @param {Object} isd ISD to be rendered 7603 * @param {Object} element Element into which the ISD is rendered 7604 * @param {?IMGResolver} imgResolver Resolve <pre>smpte:background</pre> URIs into URLs. 7605 * @param {?number} eheight Height (in pixel) of the child <div>div</div> or null 7606 * to use clientHeight of the parent element 7607 * @param {?number} ewidth Width (in pixel) of the child <div>div</div> or null 7608 * to use clientWidth of the parent element 7609 * @param {?boolean} displayForcedOnlyMode Value of the IMSC1 displayForcedOnlyMode parameter, 7610 * or false if null 7611 * @param {?module:imscUtils.ErrorHandler} errorHandler Error callback 7612 */ 7613 7614 imscHTML.render = function (isd, element, imgResolver, eheight, ewidth, displayForcedOnlyMode, errorHandler) { 7615 7616 /* maintain aspect ratio if specified */ 7617 7618 var height = eheight || element.clientHeight; 7619 var width = ewidth || element.clientWidth; 7620 7621 if (isd.aspectRatio !== null) { 7622 7623 var twidth = height * isd.aspectRatio; 7624 7625 if (twidth > width) { 7626 7627 height = Math.round(width / isd.aspectRatio); 7628 7629 } else { 7630 7631 width = twidth; 7632 7633 } 7634 7635 } 7636 7637 var rootcontainer = document.createElement("div"); 7638 7639 rootcontainer.style.position = "relative"; 7640 rootcontainer.style.width = width + "px"; 7641 rootcontainer.style.height = height + "px"; 7642 rootcontainer.style.margin = "auto"; 7643 rootcontainer.style.top = 0; 7644 rootcontainer.style.bottom = 0; 7645 rootcontainer.style.left = 0; 7646 rootcontainer.style.right = 0; 7647 rootcontainer.style.zIndex = 0; 7648 7649 var context = { 7650 h: height, 7651 w: width, 7652 regionH: null, 7653 regionW: null, 7654 imgResolver: imgResolver, 7655 displayForcedOnlyMode: displayForcedOnlyMode || false, 7656 isd: isd 7657 }; 7658 7659 element.appendChild(rootcontainer); 7660 7661 for (var i in isd.contents) { 7662 7663 processElement(context, rootcontainer, isd.contents[i]); 7664 7665 } 7666 7667 }; 7668 7669 function processElement(context, dom_parent, isd_element) { 7670 7671 var e; 7672 7673 if (isd_element.kind === 'region') { 7674 7675 e = document.createElement("div"); 7676 e.style.position = "absolute"; 7677 7678 } else if (isd_element.kind === 'body') { 7679 7680 e = document.createElement("div"); 7681 7682 } else if (isd_element.kind === 'div') { 7683 7684 e = document.createElement("div"); 7685 7686 } else if (isd_element.kind === 'p') { 7687 7688 e = document.createElement("p"); 7689 7690 } else if (isd_element.kind === 'span') { 7691 7692 e = document.createElement("span"); 7693 7694 //e.textContent = isd_element.text; 7695 7696 } else if (isd_element.kind === 'br') { 7697 7698 e = document.createElement("br"); 7699 7700 } 7701 7702 /* override UA default margin */ 7703 7704 e.style.margin = "0"; 7705 7706 /* tranform TTML styles to CSS styles */ 7707 7708 for (var i in STYLING_MAP_DEFS) { 7709 7710 var sm = STYLING_MAP_DEFS[i]; 7711 7712 var attr = isd_element.styleAttrs[sm.qname]; 7713 7714 if (attr !== undefined && sm.map !== null) { 7715 7716 sm.map(context, e, isd_element, attr); 7717 7718 } 7719 7720 } 7721 7722 var proc_e = e; 7723 7724 7725 // handle multiRowAlign and linePadding 7726
7727 var mra = isd_element.styleAttrs[imscStyles.byName.multiRowAlign.qname]; 7728 7729 if (mra && mra !== "auto") { 7730 7731 var s = document.createElement("span"); 7732 7733 s.style.display = "inline-block"; 7734 7735 s.style.textAlign = mra; 7736 7737 e.appendChild(s); 7738 7739 proc_e = s; 7740 7741 context.mra = mra; 7742 7743 } 7744 7745 var lp = isd_element.styleAttrs[imscStyles.byName.linePadding.qname]; 7746 7747 if (lp && lp > 0) { 7748 7749 context.lp = lp; 7750 7751 } 7752 7753 // wrap characters in spans to find the line wrap locations 7754 7755 if (isd_element.kind === "span" && isd_element.text) { 7756 7757 if (context.lp || context.mra) { 7758 7759 for (var j = 0; j < isd_element.text.length; j++) { 7760 7761 var span = document.createElement("span"); 7762 7763 span.textContent = isd_element.text.charAt(j); 7764 7765 e.appendChild(span); 7766 7767 } 7768 7769 } else { 7770 e.textContent = isd_element.text; 7771 } 7772 } 7773 7774 7775 dom_parent.appendChild(e); 7776 7777 for (var k in isd_element.contents) { 7778 7779 processElement(context, proc_e, isd_element.contents[k]); 7780 7781 } 7782 7783 // handle linePadding and multiRowAlign 7784 7785 if ((context.lp || context.mra) && isd_element.kind === "p") { 7786 7787 var elist = []; 7788 7789 constructElementList(proc_e, elist, "red"); 7790 7791 /* TODO: linePadding only supported for horizontal scripts */ 7792 7793 processLinePaddingAndMultiRowAlign(elist, context.lp * context.h); 7794 7795 /* TODO: clean-up the spans ? */ 7796 7797 if (context.lp) 7798 delete context.lp; 7799 if (context.mra) 7800 delete context.mra; 7801 7802 } 7803 7804 } 7805 7806 function pruneEmptySpans(element) { 7807 7808 var child = element.firstChild; 7809 7810 while (child) { 7811 7812 var nchild = child.nextSibling; 7813 7814 if (child.nodeType === Node.ELEMENT_NODE && 7815 child.localName === 'span') { 7816 7817 pruneEmptySpans(child); 7818 7819 if (child.childElementCount === 0 && 7820 child.textContent.length === 0) { 7821 7822 element.removeChild(child); 7823 7824 } 7825 } 7826 7827 child = nchild; 7828 } 7829 7830 } 7831 7832 function constructElementList(element, elist, bgcolor) { 7833 7834 if (element.childElementCount === 0) { 7835 7836 elist.push({ 7837 "element": element, 7838 "bgcolor": bgcolor} 7839 ); 7840 7841 } else { 7842 7843 var newbgcolor = element.style.backgroundColor || bgcolor; 7844 7845 var child = element.firstChild; 7846 7847 while (child) { 7848 7849 if (child.nodeType === Node.ELEMENT_NODE) { 7850 7851 constructElementList(child, elist, newbgcolor); 7852 7853 } 7854 7855 child = child.nextSibling; 7856 } 7857 } 7858 7859 } 7860 7861 function processLinePaddingAndMultiRowAlign(elist, lp) { 7862 7863 var line_head = null; 7864 7865 var lookingForHead = true; 7866 7867 var foundBR = false; 7868 7869 for (var i = 0; i <= elist.length; i++) { 7870 7871 /* skip <br> since they apparently have a different box top than 7872 * the rest of the line 7873 */ 7874 7875 if (i !== elist.length && elist[i].element.localName === "br") { 7876 foundBR = true; 7877 continue; 7878 } 7879 7880 /* detect new line */ 7881 7882 if (line_head === null || 7883 i === elist.length || 7884 elist[i].element.getBoundingClientRect().top !== elist[line_head].element.getBoundingClientRect().top) { 7885 7886 /* apply right padding to previous line (if applicable and unless this is the first line) */ 7887 7888 if (lp && (!lookingForHead)) { 7889 7890 for (; --i >= 0; ) { 7891 7892 if (elist[i].element.getBoundingClientRect().width !== 0) { 7893 7894 addRightPadding(elist[i].element, elist[i].color, lp); 7895 7896 if (elist[i].element.getBoundingClientRect().width !== 0 && 7897 elist[i].element.getBoundingClientRect().top === elist[line_head].element.getBoundingClientRect().top) 7898 break; 7899 7900 removeRightPadding(elist[i].element); 7901 7902 } 7903 7904 } 7905 7906 lookingForHead = true; 7907 7908 continue; 7909 7910 } 7911 7912 /* explicit <br> unless already present */ 7913 7914 if (i !== elist.length && line_head !== null && (!foundBR)) { 7915 7916 var br = document.createElement("br"); 7917 7918 elist[i].element.parentElement.insertBefore(br, elist[i].element); 7919 7920 elist.splice(i, 0, {"element": br}); 7921 7922 foundBR = true; 7923 7924 continue; 7925 7926 } 7927 7928 /* apply left padding to current line (if applicable) */ 7929 7930 if (i !== elist.length && lp) { 7931 7932 /* find first non-zero */ 7933 7934 for (; i < elist.length; i++) { 7935 7936 if (elist[i].element.getBoundingClientRect().width !== 0) { 7937 addLeftPadding(elist[i].element, elist[i].color, lp); 7938 break; 7939 } 7940 7941 } 7942 7943 } 7944 7945 lookingForHead = false; 7946 7947 foundBR = false; 7948 7949 line_head = i; 7950 7951 } 7952 7953 } 7954 7955 } 7956 7957 function addLeftPadding(e, c, lp) { 7958 e.style.paddingLeft = lp + "px"; 7959 e.style.backgroundColor = c; 7960 } 7961 7962 function addRightPadding(e, c, lp) { 7963 e.style.paddingRight = lp + "px"; 7964 e.style.backgroundColor = c; 7965 7966 } 7967 7968 function removeRightPadding(e) { 7969 e.style.paddingRight = null; 7970 } 7971 7972 7973 function HTMLStylingMapDefintion(qName, mapFunc) { 7974 this.qname = qName; 7975 this.map = mapFunc; 7976 } 7977 7978 var STYLING_MAP_DEFS = [ 7979 7980 new HTMLStylingMapDefintion( 7981 "http://www.w3.org/ns/ttml#styling backgroundColor", 7982 function (context, dom_element, isd_element, attr) { 7983 dom_element.style.backgroundColor = "rgba(" + 7984 attr[0].toString() + "," + 7985 attr[1].toString() + "," + 7986 attr[2].toString() + "," + 7987 (attr[3] / 255).toString() + 7988 ")"; 7989 } 7990 ), 7991 new HTMLStylingMapDefintion( 7992 "http://www.w3.org/ns/ttml#styling color", 7993 function (context, dom_element, isd_element, attr) { 7994 dom_element.style.color = "rgba(" + 7995 attr[0].toString() + "," + 7996 attr[1].toString() + "," + 7997 attr[2].toString() + "," + 7998 (attr[3] / 255).toString() + 7999 ")"; 8000 } 8001 ), 8002 new HTMLStylingMapDefintion( 8003 "http://www.w3.org/ns/ttml#styling direction", 8004 function (context, dom_element, isd_element, attr) { 8005 dom_element.style.direction = attr; 8006 } 8007 ), 8008 new HTMLStylingMapDefintion( 8009 "http://www.w3.org/ns/ttml#styling display", 8010 function (context, dom_element, isd_element, attr) {} 8011 ), 8012 new HTMLStylingMapDefintion( 8013 "http://www.w3.org/ns/ttml#styling displayAlign", 8014 function (context, dom_element, isd_element, attr) { 8015
8016 /* see https://css-tricks.com/snippets/css/a-guide-to-flexbox/ */ 8017 8018 /* TODO: is this affected by writing direction? */ 8019 8020 dom_element.style.display = "flex"; 8021 dom_element.style.flexDirection = "column"; 8022 8023 8024 if (attr === "before") { 8025 8026 dom_element.style.justifyContent = "flex-start"; 8027 8028 } else if (attr === "center") { 8029 8030 dom_element.style.justifyContent = "center"; 8031 8032 } else if (attr === "after") { 8033 8034 dom_element.style.justifyContent = "flex-end"; 8035 } 8036 8037 } 8038 ), 8039 new HTMLStylingMapDefintion( 8040 "http://www.w3.org/ns/ttml#styling extent", 8041 function (context, dom_element, isd_element, attr) { 8042 /* TODO: this is super ugly */ 8043 8044 context.regionH = (attr.h * context.h); 8045 context.regionW = (attr.w * context.w); 8046 8047 /* 8048 * CSS height/width are measured against the content rectangle, 8049 * whereas TTML height/width include padding 8050 */ 8051 8052 var hdelta = 0; 8053 var wdelta = 0; 8054 8055 var p = isd_element.styleAttrs["http://www.w3.org/ns/ttml#styling padding"]; 8056 8057 if (!p) { 8058 8059 /* error */ 8060 8061 }
vendor: 9,386 bytes, lines 8061-8342
8061 else { 8062 8063 hdelta = (p[0] + p[2]) * context.h; 8064 wdelta = (p[1] + p[3]) * context.w; 8065 8066 } 8067 8068 dom_element.style.height = (context.regionH - hdelta) + "px"; 8069 dom_element.style.width = (context.regionW - wdelta) + "px"; 8070 8071 } 8072 ), 8073 new HTMLStylingMapDefintion( 8074 "http://www.w3.org/ns/ttml#styling fontFamily", 8075 function (context, dom_element, isd_element, attr) { 8076 8077 var rslt = []; 8078 8079 /* per IMSC1 */ 8080 8081 for (var i in attr) { 8082 8083 if (attr[i] === "monospaceSerif") { 8084 8085 rslt.push("Courier New"); 8086 rslt.push('"Liberation Mono"'); 8087 rslt.push("Courier"); 8088 rslt.push("monospace"); 8089 8090 } else if (attr[i] === "proportionalSansSerif") { 8091 8092 rslt.push("Arial"); 8093 rslt.push("Helvetica"); 8094 rslt.push('"Liberation Sans"'); 8095 rslt.push("sans-serif"); 8096 8097 } else if (attr[i] === "monospace") { 8098 8099 rslt.push("monospace"); 8100 8101 } else if (attr[i] === "sansSerif") { 8102 8103 rslt.push("sans-serif"); 8104 8105 } else if (attr[i] === "serif") { 8106 8107 rslt.push("serif"); 8108 8109 } else if (attr[i] === "monospaceSansSerif") { 8110 8111 rslt.push("Consolas"); 8112 rslt.push("monospace"); 8113 8114 } else if (attr[i] === "proportionalSerif") { 8115 8116 rslt.push("serif"); 8117 8118 } else { 8119 8120 rslt.push(attr[i]); 8121 8122 } 8123 8124 } 8125 8126 dom_element.style.fontFamily = rslt.join(","); 8127 } 8128 ), 8129 8130 new HTMLStylingMapDefintion( 8131 "http://www.w3.org/ns/ttml#styling fontSize", 8132 function (context, dom_element, isd_element, attr) { 8133 dom_element.style.fontSize = (attr * context.h) + "px"; 8134 } 8135 ), 8136 8137 new HTMLStylingMapDefintion( 8138 "http://www.w3.org/ns/ttml#styling fontStyle", 8139 function (context, dom_element, isd_element, attr) { 8140 dom_element.style.fontStyle = attr; 8141 } 8142 ), 8143 new HTMLStylingMapDefintion( 8144 "http://www.w3.org/ns/ttml#styling fontWeight", 8145 function (context, dom_element, isd_element, attr) { 8146 dom_element.style.fontWeight = attr; 8147 } 8148 ), 8149 new HTMLStylingMapDefintion( 8150 "http://www.w3.org/ns/ttml#styling lineHeight", 8151 function (context, dom_element, isd_element, attr) { 8152 if (attr === "normal") { 8153 8154 dom_element.style.lineHeight = "normal"; 8155 8156 } else { 8157 8158 dom_element.style.lineHeight = (attr * context.h) + "px"; 8159 } 8160 } 8161 ), 8162 new HTMLStylingMapDefintion( 8163 "http://www.w3.org/ns/ttml#styling opacity", 8164 function (context, dom_element, isd_element, attr) { 8165 dom_element.style.opacity = attr; 8166 } 8167 ), 8168 new HTMLStylingMapDefintion( 8169 "http://www.w3.org/ns/ttml#styling origin", 8170 function (context, dom_element, isd_element, attr) { 8171 dom_element.style.top = (attr.h * context.h) + "px"; 8172 dom_element.style.left = (attr.w * context.w) + "px"; 8173 } 8174 ), 8175 new HTMLStylingMapDefintion( 8176 "http://www.w3.org/ns/ttml#styling overflow", 8177 function (context, dom_element, isd_element, attr) { 8178 dom_element.style.overflow = attr; 8179 } 8180 ), 8181 new HTMLStylingMapDefintion( 8182 "http://www.w3.org/ns/ttml#styling padding", 8183 function (context, dom_element, isd_element, attr) { 8184 8185 /* attr: top,left,bottom,right*/ 8186 8187 /* style: top right bottom left*/ 8188 8189 var rslt = []; 8190 8191 rslt[0] = (attr[0] * context.h) + "px"; 8192 rslt[1] = (attr[3] * context.w) + "px"; 8193 rslt[2] = (attr[2] * context.h) + "px"; 8194 rslt[3] = (attr[1] * context.w) + "px"; 8195 8196 dom_element.style.padding = rslt.join(" "); 8197 } 8198 ), 8199 new HTMLStylingMapDefintion( 8200 "http://www.w3.org/ns/ttml#styling showBackground", 8201 null 8202 ), 8203 new HTMLStylingMapDefintion( 8204 "http://www.w3.org/ns/ttml#styling textAlign", 8205 function (context, dom_element, isd_element, attr) { 8206 8207 var ta; 8208 var dir = isd_element.styleAttrs[imscStyles.byName.direction.qname]; 8209 8210 /* handle UAs that do not understand start or end */ 8211 8212 if (attr === "start") { 8213 8214 ta = (dir === "rtl") ? "right" : "left"; 8215 8216 } else if (attr === "end") { 8217 8218 ta = (dir === "rtl") ? "left" : "right"; 8219 8220 } else { 8221 8222 ta = attr; 8223 8224 } 8225 8226 dom_element.style.textAlign = ta; 8227 8228 } 8229 ), 8230 new HTMLStylingMapDefintion( 8231 "http://www.w3.org/ns/ttml#styling textDecoration", 8232 function (context, dom_element, isd_element, attr) { 8233 dom_element.style.textDecoration = attr.join(" ").replace("lineThrough", "line-through"); 8234 } 8235 ), 8236 new HTMLStylingMapDefintion( 8237 "http://www.w3.org/ns/ttml#styling textOutline", 8238 function (context, dom_element, isd_element, attr) { 8239 8240 if (attr === "none") { 8241 8242 dom_element.style.textShadow = ""; 8243 8244 } else { 8245 8246 dom_element.style.textShadow = "rgba(" + 8247 attr.color[0].toString() + "," + 8248 attr.color[1].toString() + "," + 8249 attr.color[2].toString() + "," + 8250 (attr.color[3] / 255).toString() + 8251 ")" + " 0px 0px " + 8252 (attr.thickness * context.h) + "px"; 8253 8254 } 8255 } 8256 ), 8257 new HTMLStylingMapDefintion( 8258 "http://www.w3.org/ns/ttml#styling unicodeBidi", 8259 function (context, dom_element, isd_element, attr) { 8260 8261 var ub; 8262 8263 if (attr === 'bidiOverride') { 8264 ub = "bidi-override"; 8265 } else { 8266 ub = attr; 8267 } 8268 8269 dom_element.style.unicodeBidi = ub; 8270 } 8271 ), 8272 new HTMLStylingMapDefintion( 8273 "http://www.w3.org/ns/ttml#styling visibility", 8274 function (context, dom_element, isd_element, attr) { 8275 dom_element.style.visibility = attr; 8276 } 8277 ), 8278 new HTMLStylingMapDefintion( 8279 "http://www.w3.org/ns/ttml#styling wrapOption", 8280 function (context, dom_element, isd_element, attr) { 8281 8282 if (attr === "wrap") { 8283 8284 if (isd_element.space === "preserve") { 8285 dom_element.style.whiteSpace = "pre-wrap"; 8286 } else { 8287 dom_element.style.whiteSpace = "normal"; 8288 } 8289 8290 } else { 8291 8292 if (isd_element.space === "preserve") { 8293 8294 dom_element.style.whiteSpace = "pre"; 8295 8296 } else { 8297 dom_element.style.whiteSpace = "noWrap"; 8298 } 8299 8300 } 8301 8302 } 8303 ), 8304 new HTMLStylingMapDefintion( 8305 "http://www.w3.org/ns/ttml#styling writingMode", 8306 function (context, dom_element, isd_element, attr) { 8307 if (attr === "lrtb" || attr === "lr") { 8308 8309 dom_element.style.writingMode = "horizontal-tb"; 8310 8311 } else if (attr === "rltb" || attr === "rl") { 8312 8313 dom_element.style.writingMode = "horizontal-tb"; 8314 8315 } else if (attr === "tblr") { 8316 8317 dom_element.style.writingMode = "vertical-lr"; 8318 8319 } else if (attr === "tbrl" || attr === "tb") { 8320 8321 dom_element.style.writingMode = "vertical-rl"; 8322 8323 } 8324 } 8325 ), 8326 new HTMLStylingMapDefintion( 8327 "http://www.w3.org/ns/ttml#styling zIndex", 8328 function (context, dom_element, isd_element, attr) { 8329 dom_element.style.zIndex = attr; 8330 } 8331 ), 8332 new HTMLStylingMapDefintion( 8333 "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt backgroundImage", 8334 function (context, dom_element, isd_element, attr) { 8335 8336 if (context.imgResolver !== null && attr !== null) { 8337 8338 var img = document.createElement("img"); 8339 8340 var uri = context.imgResolver(attr, img); 8341 8342 if (uri)
8342 img.src = uri; 8343 8344 img.height = context.regionH; 8345 img.width = context.regionW; 8346 8347 dom_element.appendChild(img); 8348 } 8349 } 8350 ), 8351 new HTMLStylingMapDefintion( 8352 "http://www.w3.org/ns/ttml/profile/imsc1#styling forcedDisplay", 8353 function (context, dom_element, isd_element, attr) { 8354 8355 if (context.displayForcedOnlyMode && attr === false) { 8356 dom_element.style.visibility = "hidden"; 8357 } 8358 8359 } 8360 ) 8361 ]; 8362 8363 var STYLMAP_BY_QNAME = {}; 8364 8365 for (var i in STYLING_MAP_DEFS) { 8366 8367 STYLMAP_BY_QNAME[STYLING_MAP_DEFS[i].qname] = STYLING_MAP_DEFS[i]; 8368 } 8369 8370})(typeof exports === 'undefined' ? this.imscHTML = {} : exports, 8371 typeof imscNames === 'undefined' ? _dereq_(22) : imscNames, 8372 typeof imscStyles === 'undefined' ? _dereq_(23) : imscStyles); 8373},{"22":22,"23":23}],20:[function(_dereq_,module,exports){ 8374/* 8375 * Copyright (c) 2016, Pierre-Anthony Lemieux <[email protected]> 8376 * All rights reserved. 8377 * 8378 * Redistribution and use in source and binary forms, with or without 8379 * modification, are permitted provided that the following conditions are met: 8380 * 8381 * * Redistributions of source code must retain the above copyright notice, this 8382 * list of conditions and the following disclaimer. 8383 * * Redistributions in binary form must reproduce the above copyright notice, 8384 * this list of conditions and the following disclaimer in the documentation 8385 * and/or other materials provided with the distribution. 8386 * 8387 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 8388 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 8389 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 8390 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 8391 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 8392 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 8393 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 8394 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 8395 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 8396 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 8397 * POSSIBILITY OF SUCH DAMAGE. 8398 */ 8399 8400/** 8401 * @module imscISD 8402 */ 8403 8404 8405; 8406(function (imscISD, imscNames, imscStyles) { // wrapper for non-node envs 8407 8408 /** 8409 * Creates a canonical representation of an IMSC1 document returned by <pre>imscDoc.fromXML()</pre> 8410 * at a given absolute offset in seconds. This offset does not have to be one of the values returned 8411 * by <pre>getMediaTimeEvents()</pre>. 8412 * 8413 * @param {Object} tt IMSC1 document 8414 * @param {number} offset Absolute offset (in seconds) 8415 * @param {?module:imscUtils.ErrorHandler} errorHandler Error callback 8416 * @returns {Object} Opaque in-memory representation of an ISD 8417 */ 8418 8419 imscISD.generateISD = function (tt, offset, errorHandler) { 8420 8421 /* TODO check for tt and offset validity */ 8422 8423 /* create the ISD object from the IMSC1 doc */ 8424 8425 var isd = new ISD(tt); 8426 8427 /* process regions */ 8428 8429 for (var r in tt.head.layout.regions) { 8430 8431 /* post-order traversal of the body tree per [construct intermediate document] */ 8432 8433 var c = isdProcessContentElement(tt, offset, tt.head.layout.regions[r], tt.body, null, '', tt.head.layout.regions[r], errorHandler); 8434 8435 if (c !== null) { 8436 8437 /* add the region to the ISD */ 8438 8439 isd.contents.push(c.element); 8440 } 8441 8442 8443 } 8444 8445 return isd; 8446 }; 8447 8448 function isdProcessContentElement(doc, offset, region, body, parent, inherited_region_id, elem, errorHandler) { 8449 8450 /* prune if temporally inactive */ 8451 8452 if (offset < elem.begin || offset >= elem.end) return null; 8453 8454 /*
vendor: 15,055 bytes, lines 8455-8993
8455 * set the associated region as specified by the regionID attribute, or the 8456 * inherited associated region otherwise 8457 */ 8458 8459 var associated_region_id = 'regionID' in elem && elem.regionID !== '' ? elem.regionID : inherited_region_id; 8460 8461 /* prune the element if either: 8462 * - the element is not terminal and the associated region is neither the default 8463 * region nor the parent region (this allows children to be associated with a 8464 * region later on) 8465 * - the element is terminal and the associated region is not the parent region 8466 */ 8467 8468 /* TODO: improve detection of terminal elements since <region> has no contents */ 8469 8470 if (parent !== null /* are we in the region element */ && 8471 associated_region_id !== region.id && 8472 ( 8473 (! ('contents' in elem)) || 8474 ('contents' in elem && elem.contents.length === 0) || 8475 associated_region_id !== '' 8476 ) 8477 ) 8478 return null; 8479 8480 /* create an ISD element, including applying specified styles */ 8481 8482 var isd_element = new ISDContentElement(elem); 8483 8484 /* apply set (animation) styling */ 8485 8486 for (var i in elem.sets) { 8487 8488 if (offset < elem.sets[i].begin || offset >= elem.sets[i].end) 8489 continue; 8490 8491 isd_element.styleAttrs[elem.sets[i].qname] = elem.sets[i].value; 8492 8493 } 8494 8495 /* 8496 * keep track of specified styling attributes so that we 8497 * can compute them later 8498 */ 8499 8500 var spec_attr = {}; 8501 8502 for (var qname in isd_element.styleAttrs) { 8503 8504 spec_attr[qname] = true; 8505 8506 /* special rule for tts:writingMode (section 7.29.1 of XSL) 8507 * direction is set consistently with writingMode only 8508 * if writingMode sets inline-direction to LTR or RTL 8509 */ 8510 8511 if (qname === imscStyles.byName.writingMode.qname && 8512 !(imscStyles.byName.direction.qname in isd_element.styleAttrs)) { 8513 8514 var wm = isd_element.styleAttrs[qname]; 8515 8516 if (wm === "lrtb" || wm === "lr") { 8517 8518 isd_element.styleAttrs[imscStyles.byName.direction.qname] = "ltr"; 8519 8520 } else if (wm === "rltb" || wm === "rl") { 8521 8522 isd_element.styleAttrs[imscStyles.byName.direction.qname] = "rtl"; 8523 8524 } 8525 8526 } 8527 } 8528 8529 /* inherited styling */ 8530 8531 if (parent !== null) { 8532 8533 for (var j in imscStyles.all) { 8534 8535 var sa = imscStyles.all[j]; 8536 8537 /* textDecoration has special inheritance rules */ 8538 8539 if (sa.qname === imscStyles.byName.textDecoration.qname) { 8540 8541 /* handle both textDecoration inheritance and specification */ 8542 8543 var ps = parent.styleAttrs[sa.qname]; 8544 var es = isd_element.styleAttrs[sa.qname]; 8545 var outs = []; 8546 8547 if (es === undefined) { 8548 8549 outs = ps; 8550 8551 } else if (es.indexOf("none") === -1) { 8552 8553 if ((es.indexOf("noUnderline") === -1 && 8554 ps.indexOf("underline") !== -1) || 8555 es.indexOf("underline") !== -1) { 8556 8557 outs.push("underline"); 8558 8559 } 8560 8561 if ((es.indexOf("noLineThrough") === -1 && 8562 ps.indexOf("lineThrough") !== -1) || 8563 es.indexOf("lineThrough") !== -1) { 8564 8565 outs.push("lineThrough"); 8566 8567 } 8568 8569 if ((es.indexOf("noOverline") === -1 && 8570 ps.indexOf("overline") !== -1) || 8571 es.indexOf("overline") !== -1) { 8572 8573 outs.push("overline"); 8574 8575 } 8576 8577 } else { 8578 8579 outs.push("none"); 8580 8581 } 8582 8583 isd_element.styleAttrs[sa.qname] = outs; 8584 8585 } else if (sa.inherit && 8586 (sa.qname in parent.styleAttrs) && 8587 !(sa.qname in isd_element.styleAttrs)) { 8588 8589 isd_element.styleAttrs[sa.qname] = parent.styleAttrs[sa.qname]; 8590 8591 } 8592 8593 } 8594 8595 } 8596 8597 /* initial value styling */ 8598 8599 for (var k in imscStyles.all) { 8600 8601 var ivs = imscStyles.all[k]; 8602 8603 /* skip if value is already specified */ 8604 8605 if (ivs.qname in isd_element.styleAttrs) continue; 8606 8607 /* apply initial value to elements other than region only if non-inherited */ 8608 8609 if (isd_element.kind === 'region' || (ivs.inherit === false && ivs.initial !== null)) { 8610 8611 isd_element.styleAttrs[ivs.qname] = ivs.parse(ivs.initial); 8612 8613 /* keep track of the style as specified */ 8614 8615 spec_attr[ivs.qname] = true; 8616 8617 } 8618 8619 } 8620 8621 /* compute styles (only for non-inherited styles) */ 8622 /* TODO: get rid of spec_attr */ 8623 8624 for (var z in imscStyles.all) { 8625 8626 var cs = imscStyles.all[z]; 8627 8628 if (!(cs.qname in spec_attr)) continue; 8629 8630 if (cs.compute !== null) { 8631 8632 var cstyle = cs.compute( 8633 /*doc, parent, element, attr*/ 8634 doc, 8635 parent, 8636 isd_element, 8637 isd_element.styleAttrs[cs.qname] 8638 ); 8639 8640 8641 isd_element.styleAttrs[cs.qname] = cstyle; 8642 8643 8644 // reportError(errorHandler, "Style '" + sa.qname + "' on element '" + isd_element.kind + "' cannot be computed"); 8645 8646 } 8647 8648 } 8649 8650 /* prune if tts:display is none */ 8651 8652 if (isd_element.styleAttrs[imscStyles.byName.display.qname] === "none") 8653 return null; 8654 8655 /* process contents of the element */ 8656 8657 var contents; 8658 8659 if (parent === null) { 8660 8661 /* we are processing the region */ 8662 8663 if (body === null) { 8664 8665 /* if there is no body, still process the region but with empty content */ 8666 8667 contents = []; 8668 8669 } else { 8670 8671 /*use the body element as contents */ 8672 8673 contents = [body]; 8674 8675 } 8676 8677 } else if ('contents' in elem) { 8678 8679 contents = elem.contents; 8680 8681 } 8682 8683 for (var x in contents) { 8684 8685 var c = isdProcessContentElement(doc, offset, region, body, isd_element, associated_region_id, contents[x]); 8686 8687 /* 8688 * keep child element only if they are non-null and their region match 8689 * the region of this element 8690 */ 8691 8692 if (c !== null) { 8693 8694 isd_element.contents.push(c.element); 8695 8696 } 8697 8698 } 8699 8700 /* compute used value of lineHeight="normal" */ 8701 8702 /* if (isd_element.styleAttrs[imscStyles.byName.lineHeight.qname] === "normal" ) { 8703 8704 isd_element.styleAttrs[imscStyles.byName.lineHeight.qname] = 8705 isd_element.styleAttrs[imscStyles.byName.fontSize.qname] * 1.2; 8706 8707 } 8708 */ 8709 8710 /* remove styles that are not applicable */ 8711 8712 for (var qnameb in isd_element.styleAttrs) { 8713 var da = imscStyles.byQName[qnameb]; 8714 8715 if (da.applies.indexOf(isd_element.kind) === -1) { 8716 delete isd_element.styleAttrs[qnameb]; 8717 } 8718 } 8719 8720 /* collapse white space if space is "default" */ 8721 8722 if (isd_element.kind === 'span' && isd_element.text && isd_element.space === "default") { 8723 8724 var trimmedspan = isd_element.text.replace(/\s+/g, ' '); 8725 8726 isd_element.text = trimmedspan; 8727 8728 } 8729 8730 /* trim whitespace around explicit line breaks */ 8731 8732 if (isd_element.kind === 'p') { 8733 8734 var elist = []; 8735 8736 constructSpanList(isd_element, elist); 8737 8738 var l = 0; 8739 8740 var state = "after_br"; 8741 var br_pos = 0; 8742 8743 while (true) { 8744 8745 if (state === "after_br") { 8746 8747 if (l >= elist.length || elist[l].kind === "br") { 8748 8749 state = "before_br"; 8750 br_pos = l; 8751 l--; 8752 8753 } else { 8754 8755 if (elist[l].space !== "preserve") { 8756 8757 elist[l].text = elist[l].text.replace(/^\s+/g, ''); 8758 8759 } 8760 8761 if (elist[l].text.length > 0) { 8762 8763 state = "looking_br"; 8764 l++; 8765 8766 } else { 8767 8768 elist.splice(l, 1); 8769 8770 } 8771 8772 } 8773 8774 } else if (state === "before_br") { 8775 8776 if (l < 0 || elist[l].kind === "br") { 8777 8778 state = "after_br"; 8779 l = br_pos + 1; 8780 8781 if (l >= elist.length) break; 8782 8783 } else { 8784 8785 if (elist[l].space !== "preserve") { 8786 8787 elist[l].text = elist[l].text.replace(/\s+$/g, ''); 8788 8789 } 8790 8791 if (elist[l].text.length > 0) { 8792 8793 state = "after_br"; 8794 l = br_pos + 1; 8795 8796 if (l >= elist.length) break; 8797 8798 } else { 8799 8800 elist.splice(l, 1); 8801 l--; 8802 8803 } 8804 8805 } 8806 8807 } else { 8808 8809 if (l >= elist.length || elist[l].kind === "br") { 8810 8811 state = "before_br"; 8812 br_pos = l; 8813 l--; 8814 8815 } else { 8816 8817 l++; 8818 8819 } 8820 8821 } 8822 8823 } 8824 8825 pruneEmptySpans(isd_element); 8826 8827 } 8828 8829 /* keep element if: 8830 * * contains a background image 8831 * * <br/> 8832 * * if there are children 8833 * * if <span> and has text 8834 * * if region and showBackground = always 8835 */ 8836 8837 if ((isd_element.kind === 'div' && imscStyles.byName.backgroundImage.qname in isd_element.styleAttrs) || 8838 isd_element.kind === 'br' || 8839 ('contents' in isd_element && isd_element.contents.length > 0) || 8840 (isd_element.kind === 'span' && isd_element.text !== null) || 8841 (isd_element.kind === 'region' && 8842 isd_element.styleAttrs[imscStyles.byName.showBackground.qname] === 'always')) { 8843 8844 return { 8845 region_id: associated_region_id, 8846 element: isd_element 8847 }; 8848 } 8849 8850 return null; 8851 } 8852 8853 function constructSpanList(element, elist) { 8854 8855 if ('contents' in element) { 8856 8857 for (var i in element.contents) { 8858 constructSpanList(element.contents[i], elist); 8859 } 8860 8861 } else { 8862 8863 elist.push(element); 8864 8865 } 8866 8867 } 8868 8869 function pruneEmptySpans(element) { 8870 8871 if (element.kind === 'br') { 8872 8873 return false; 8874 8875 } else if ('text' in element) { 8876 8877 return element.text.length === 0; 8878 8879 } else if ('contents' in element) { 8880 8881 var i = element.contents.length; 8882 8883 while (i--) { 8884 8885 if (pruneEmptySpans(element.contents[i])) { 8886 element.contents.splice(i, 1); 8887 } 8888 8889 } 8890 8891 return element.contents.length === 0; 8892 8893 } 8894 } 8895 8896 function ISD(tt) { 8897 this.contents = []; 8898 this.aspectRatio = tt.aspectRatio; 8899 } 8900 8901 function ISDContentElement(ttelem) { 8902 8903 /* assume the element is a region if it does not have a kind */ 8904 8905 this.kind = ttelem.kind || 'region'; 8906 8907 /* deep copy of style attributes */ 8908 this.styleAttrs = {}; 8909 8910 for (var sname in ttelem.styleAttrs) { 8911 8912 this.styleAttrs[sname] = 8913 ttelem.styleAttrs[sname]; 8914 } 8915 8916 /* TODO: clean this! */ 8917 8918 if ('text' in ttelem) { 8919 8920 this.text = ttelem.text; 8921 8922 } else if (ttelem.kind !== 'br') { 8923 8924 this.contents = []; 8925 } 8926 8927 if ('space' in ttelem) { 8928 8929 this.space = ttelem.space; 8930 } 8931 } 8932 8933 8934 /* 8935 * ERROR HANDLING UTILITY FUNCTIONS 8936 * 8937 */ 8938 8939 function reportInfo(errorHandler, msg) { 8940 8941 if (errorHandler && errorHandler.info && errorHandler.info(msg)) 8942 throw msg; 8943 8944 } 8945 8946 function reportWarning(errorHandler, msg) { 8947 8948 if (errorHandler && errorHandler.warn && errorHandler.warn(msg)) 8949 throw msg; 8950 8951 } 8952 8953 function reportError(errorHandler, msg) { 8954 8955 if (errorHandler && errorHandler.error && errorHandler.error(msg)) 8956 throw msg; 8957 8958 } 8959 8960 function reportFatal(errorHandler, msg) { 8961 8962 if (errorHandler && errorHandler.fatal) 8963 errorHandler.fatal(msg); 8964 8965 throw msg; 8966 8967 } 8968 8969 8970})(typeof exports === 'undefined' ? this.imscISD = {} : exports, 8971 typeof imscNames === 'undefined' ? _dereq_(22) : imscNames, 8972 typeof imscStyles === 'undefined' ? _dereq_(23) : imscStyles 8973 ); 8974 8975},{"22":22,"23":23}],21:[function(_dereq_,module,exports){ 8976/* 8977 * Copyright (c) 2016, Pierre-Anthony Lemieux <[email protected]> 8978 * All rights reserved. 8979 * 8980 * Redistribution and use in source and binary forms, with or without 8981 * modification, are permitted provided that the following conditions are met: 8982 * 8983 * * Redistributions of source code must retain the above copyright notice, this 8984 * list of conditions and the following disclaimer. 8985 * * Redistributions in binary form must reproduce the above copyright notice, 8986 * this list of conditions and the following disclaimer in the documentation 8987 * and/or other materials provided with the distribution. 8988 * 8989 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 8990 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 8991 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 8992 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 8993 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
8994 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 8995 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 8996 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 8997 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 8998 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 8999 * POSSIBILITY OF SUCH DAMAGE. 9000 */ 9001 9002exports.generateISD = _dereq_(20).generateISD; 9003exports.fromXML = _dereq_(18).fromXML; 9004exports.renderHTML = _dereq_(19).render; 9005},{"18":18,"19":19,"20":20}],22:[function(_dereq_,module,exports){ 9006/* 9007 * Copyright (c) 2016, Pierre-Anthony Lemieux <[email protected]> 9008 * All rights reserved. 9009 * 9010 * Redistribution and use in source and binary forms, with or without 9011 * modification, are permitted provided that the following conditions are met: 9012 * 9013 * * Redistributions of source code must retain the above copyright notice, this 9014 * list of conditions and the following disclaimer. 9015 * * Redistributions in binary form must reproduce the above copyright notice, 9016 * this list of conditions and the following disclaimer in the documentation 9017 * and/or other materials provided with the distribution. 9018 * 9019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 9020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 9023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 9024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 9025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 9026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 9027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 9028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 9029 * POSSIBILITY OF SUCH DAMAGE. 9030 */ 9031 9032/** 9033 * @module imscNames 9034 */ 9035 9036; 9037(function (imscNames) { // wrapper for non-node envs 9038 9039 imscNames.ns_tt = "http://www.w3.org/ns/ttml"; 9040 imscNames.ns_tts = "http://www.w3.org/ns/ttml#styling"; 9041 imscNames.ns_ttp = "http://www.w3.org/ns/ttml#parameter"; 9042 imscNames.ns_xml = "http://www.w3.org/XML/1998/namespace"; 9043 imscNames.ns_itts = "http://www.w3.org/ns/ttml/profile/imsc1#styling"; 9044 imscNames.ns_ittp = "http://www.w3.org/ns/ttml/profile/imsc1#parameter"; 9045 imscNames.ns_smpte = "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt"; 9046 imscNames.ns_ebutts = "urn:ebu:tt:style"; 9047 9048})(typeof exports === 'undefined' ? this.imscNames = {} : exports); 9049 9050 9051 9052 9053 9054},{}],23:[function(_dereq_,module,exports){ 9055/* 9056 * Copyright (c) 2016, Pierre-Anthony Lemieux <[email protected]> 9057 * All rights reserved. 9058 * 9059 * Redistribution and use in source and binary forms, with or without 9060 * modification, are permitted provided that the following conditions are met: 9061 * 9062 * * Redistributions of source code must retain the above copyright notice, this 9063 * list of conditions and the following disclaimer. 9064 * * Redistributions in binary form must reproduce the above copyright notice, 9065 * this list of conditions and the following disclaimer in the documentation 9066 * and/or other materials provided with the distribution. 9067 * 9068 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 9069 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9070 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9071 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 9072 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 9073 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 9074 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 9075 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 9076 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 9077 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 9078 * POSSIBILITY OF SUCH DAMAGE. 9079 */ 9080 9081/** 9082 * @module imscStyles 9083 */ 9084 9085; 9086(function (imscStyles, imscNames, imscUtils) { // wrapper for non-node envs 9087 9088 function StylingAttributeDefinition(ns, name, initialValue, appliesTo, isInherit, isAnimatable, parseFunc, c
vendor: 24,690 bytes, lines 9088-9936
9088omputeFunc) { 9089 this.name = name; 9090 this.ns = ns; 9091 this.qname = ns + " " + name; 9092 this.inherit = isInherit; 9093 this.animatable = isAnimatable; 9094 this.initial = initialValue; 9095 this.applies = appliesTo; 9096 this.parse = parseFunc; 9097 this.compute = computeFunc; 9098 } 9099 9100 imscStyles.all = [ 9101 9102 new StylingAttributeDefinition( 9103 imscNames.ns_tts, 9104 "backgroundColor", 9105 "transparent", 9106 ['body', 'div', 'p', 'region', 'span'], 9107 false, 9108 true, 9109 imscUtils.parseColor, 9110 null 9111 ), 9112 new StylingAttributeDefinition( 9113 imscNames.ns_tts, 9114 "color", 9115 "white", 9116 ['span'], 9117 true, 9118 true, 9119 imscUtils.parseColor, 9120 null 9121 ), 9122 new StylingAttributeDefinition( 9123 imscNames.ns_tts, 9124 "direction", 9125 "ltr", 9126 ['p', 'span'], 9127 true, 9128 true, 9129 function (str) { 9130 return str; 9131 }, 9132 null 9133 ), 9134 new StylingAttributeDefinition( 9135 imscNames.ns_tts, 9136 "display", 9137 "auto", 9138 ['body', 'div', 'p', 'region', 'span'], 9139 false, 9140 true, 9141 function (str) { 9142 return str; 9143 }, 9144 null 9145 ), 9146 new StylingAttributeDefinition( 9147 imscNames.ns_tts, 9148 "displayAlign", 9149 "before", 9150 ['region'], 9151 false, 9152 true, 9153 function (str) { 9154 return str; 9155 }, 9156 null 9157 ), 9158 new StylingAttributeDefinition( 9159 imscNames.ns_tts, 9160 "extent", 9161 "auto", 9162 ['tt', 'region'], 9163 false, 9164 true, 9165 function (str) { 9166 9167 if (str === "auto") { 9168 9169 return str; 9170 9171 } else { 9172 9173 var s = str.split(" "); 9174 if (s.length !== 2) return null; 9175 var w = imscUtils.parseLength(s[0]); 9176 var h = imscUtils.parseLength(s[1]); 9177 if (!h || !w) return null; 9178 return {'h': h, 'w': w}; 9179 } 9180 9181 }, 9182 function (doc, parent, element, attr) { 9183 9184 var h; 9185 var w; 9186 9187 if (attr === "auto") { 9188 9189 h = 1; 9190 9191 } else if (attr.h.unit === "%") { 9192 9193 h = attr.h.value / 100; 9194 9195 } else if (attr.h.unit === "px") { 9196 9197 h = attr.h.value / doc.pxDimensions.h; 9198 9199 } else { 9200 9201 return null; 9202 9203 } 9204 9205 if (attr === "auto") { 9206 9207 w = 1; 9208 9209 } else if (attr.w.unit === "%") { 9210 9211 w = attr.w.value / 100; 9212 9213 } else if (attr.w.unit === "px") { 9214 9215 w = attr.w.value / doc.pxDimensions.w; 9216 9217 } else { 9218 9219 return null; 9220 9221 } 9222 9223 return {'h': h, 'w': w}; 9224 } 9225 ), 9226 new StylingAttributeDefinition( 9227 imscNames.ns_tts, 9228 "fontFamily", 9229 "default", 9230 ['span'], 9231 true, 9232 true, 9233 function (str) { 9234 var ffs = str.split(","); 9235 var rslt = []; 9236 9237 for (var i in ffs) { 9238 9239 if (ffs[i].charAt(0) !== "'" && ffs[i].charAt(0) !== '"') { 9240 9241 if (ffs[i] === "default") { 9242 9243 /* per IMSC1 */ 9244 9245 rslt.push("monospaceSerif"); 9246 9247 } else { 9248 9249 rslt.push(ffs[i]); 9250 9251 } 9252 9253 } else { 9254 9255 rslt.push(ffs[i]); 9256 9257 } 9258 9259 } 9260 9261 return rslt; 9262 }, 9263 null 9264 ), 9265 new StylingAttributeDefinition( 9266 imscNames.ns_tts, 9267 "fontSize", 9268 "1c", 9269 ['span'], 9270 true, 9271 true, 9272 imscUtils.parseLength, 9273 function (doc, parent, element, attr) { 9274 9275 var fs; 9276 9277 if (attr.unit === "%") { 9278 9279 if (parent !== null) { 9280 9281 fs = parent.styleAttrs[imscStyles.byName.fontSize.qname] * attr.value / 100; 9282 9283 } else { 9284 9285 /* region, so percent of 1c */ 9286 9287 fs = attr.value / 100 / doc.cellResolution.h; 9288 9289 } 9290 9291 } else if (attr.unit === "em") { 9292 9293 if (parent !== null) { 9294 9295 fs = parent.styleAttrs[imscStyles.byName.fontSize.qname] * attr.value; 9296 9297 } else { 9298 9299 /* region, so percent of 1c */ 9300 9301 fs = attr.value / doc.cellResolution.h; 9302 9303 } 9304 9305 } else if (attr.unit === "c") { 9306 9307 fs = attr.value / doc.cellResolution.h; 9308 9309 } else if (attr.unit === "px") { 9310 9311 fs = attr.value / doc.pxDimensions.h; 9312 9313 } else { 9314 9315 return null; 9316 9317 } 9318 9319 return fs; 9320 } 9321 ), 9322 new StylingAttributeDefinition( 9323 imscNames.ns_tts, 9324 "fontStyle", 9325 "normal", 9326 ['span'], 9327 true, 9328 true, 9329 function (str) { 9330 /* TODO: handle font style */ 9331 9332 return str; 9333 }, 9334 null 9335 ), 9336 new StylingAttributeDefinition( 9337 imscNames.ns_tts, 9338 "fontWeight", 9339 "normal", 9340 ['span'], 9341 true, 9342 true, 9343 function (str) { 9344 /* TODO: handle font weight */ 9345 9346 return str; 9347 }, 9348 null 9349 ), 9350 new StylingAttributeDefinition( 9351 imscNames.ns_tts, 9352 "lineHeight", 9353 "normal", 9354 ['p'], 9355 true, 9356 true, 9357 function (str) { 9358 if (str === "normal") { 9359 return str; 9360 } else { 9361 return imscUtils.parseLength(str); 9362 } 9363 }, 9364 function (doc, parent, element, attr) { 9365 9366 var lh; 9367 9368 if (attr === "normal") { 9369 9370 /* inherit normal per https://github.com/w3c/ttml1/issues/220 */ 9371 9372 lh = attr; 9373 9374 } else if (attr.unit === "%") { 9375 9376 lh = element.styleAttrs[imscStyles.byName.fontSize.qname] * attr.value / 100; 9377 9378 } else if (attr.unit === "em") { 9379 9380 lh = element.styleAttrs[imscStyles.byName.fontSize.qname] * attr.value; 9381 9382 } else if (attr.unit === "c") { 9383 9384 lh = attr.value / doc.cellResolution.h; 9385 9386 } else if (attr.unit === "px") { 9387 9388 /* TODO: handle error if no px dimensions are provided */ 9389 9390 lh = attr.value / doc.pxDimensions.h; 9391 9392 } else { 9393 9394 return null; 9395 9396 } 9397 9398 /* TODO: create a Length constructor */ 9399 9400 return lh; 9401 } 9402 ), 9403 new StylingAttributeDefinition( 9404 imscNames.ns_tts, 9405 "opacity", 9406 1.0, 9407 ['region'], 9408 false, 9409 true, 9410 parseFloat, 9411 null 9412 ), 9413 new StylingAttributeDefinition( 9414 imscNames.ns_tts, 9415 "origin", 9416 "auto", 9417 ['region'], 9418 false, 9419 true, 9420 function (str) { 9421 9422 if (str === "auto") { 9423 9424 return str; 9425 9426 } else { 9427 9428 var s = str.split(" "); 9429 if (s.length !== 2) return null; 9430 var w = imscUtils.parseLength(s[0]); 9431 var h = imscUtils.parseLength(s[1]); 9432 if (!h || !w) return null; 9433 return {'h': h, 'w': w}; 9434 } 9435 9436 }, 9437 function (doc, parent, element, attr) { 9438 9439 var h; 9440 var w; 9441 9442 if (attr === "auto") { 9443 9444 h = 0; 9445 9446 } else if (attr.h.unit === "%") { 9447 9448 h = attr.h.value / 100; 9449 9450 } else if (attr.h.unit === "px") { 9451 9452 h = attr.h.value / doc.pxDimensions.h; 9453 9454 } else { 9455 9456 return null; 9457 9458 } 9459 9460 if (attr === "auto") { 9461 9462 w = 0; 9463 9464 } else if (attr.w.unit === "%") { 9465 9466 w = attr.w.value / 100; 9467 9468 } else if (attr.w.unit === "px") { 9469 9470 w = attr.w.value / doc.pxDimensions.w; 9471 9472 } else { 9473 9474 return null; 9475 9476 } 9477 9478 return {'h': h, 'w': w}; 9479 } 9480 ), 9481 new StylingAttributeDefinition( 9482 imscNames.ns_tts, 9483 "overflow", 9484 "hidden", 9485 ['region'], 9486 false, 9487 true, 9488 function (str) { 9489 return str; 9490 }, 9491 null 9492 ), 9493 new StylingAttributeDefinition( 9494 imscNames.ns_tts, 9495 "padding", 9496 "0px", 9497 ['region'], 9498 false, 9499 true, 9500 function (str) { 9501 9502 var s = str.split(" "); 9503 if (s.length > 4) return null; 9504 var r = []; 9505 for (var i in s) { 9506 9507 var l = imscUtils.parseLength(s[i]); 9508 if (!l) return null; 9509 r.push(l); 9510 } 9511 9512 return r; 9513 }, 9514 function (doc, parent, element, attr) { 9515 9516 var padding; 9517 9518 /* TODO: make sure we are in region */ 9519 9520 /* 9521 * expand padding shortcuts to 9522 * [before, end, after, start] 9523 * 9524 */ 9525 9526 if (attr.length === 1) { 9527 9528 padding = [attr[0], attr[0], attr[0], attr[0]]; 9529 9530 } else if (attr.length === 2) { 9531 9532 padding = [attr[0], attr[1], attr[0], attr[1]]; 9533 9534 } else if (attr.length === 3) { 9535 9536 padding = [attr[0], attr[1], attr[2], attr[1]]; 9537 9538 } else if (attr.length === 4) { 9539 9540 padding = [attr[0], attr[1], attr[2], attr[3]]; 9541 9542 } else { 9543 9544 return null; 9545 9546 } 9547 9548 /* TODO: take into account tts:direction */ 9549 9550 /* 9551 * transform [before, end, after, start] according to writingMode to 9552 * [top,left,bottom,right] 9553 * 9554 */ 9555 9556 var dir = element.styleAttrs[imscStyles.byName.writingMode.qname]; 9557 9558 if (dir === "lrtb" || dir === "lr") { 9559 9560 padding = [padding[0], padding[3], padding[2], padding[1]]; 9561 9562 } else if (dir === "rltb" || dir === "rl") { 9563 9564 padding = [padding[0], padding[1], padding[2], padding[3]]; 9565 9566 } else if (dir === "tblr") { 9567 9568 padding = [padding[3], padding[0], padding[1], padding[2]]; 9569 9570 } else if (dir === "tbrl" || dir === "tb") { 9571 9572 padding = [padding[3], padding[2], padding[1], padding[0]]; 9573 9574 } else { 9575 9576 return null; 9577 9578 } 9579 9580 var out = []; 9581 9582 for (var i in padding) { 9583 9584 if (padding[i].value === 0) { 9585 9586 out[i] = 0; 9587 9588 } else if (padding[i].unit === "%") { 9589 9590 if (i === "0" || i === "2") { 9591 9592 out[i] = element.styleAttrs[imscStyles.byName.extent.qname].h * padding[i].value / 100; 9593 9594 } else { 9595 9596 out[i] = element.styleAttrs[imscStyles.byName.extent.qname].w * padding[i].value / 100; 9597 } 9598 9599 } else if (padding[i].unit === "em") { 9600 9601 out[i] = element.styleAttrs[imscStyles.byName.fontSize.qname] * padding[i].value; 9602 9603 } else if (padding[i].unit === "c") { 9604 9605 out[i] = padding[i].value / doc.cellResolution.h; 9606 9607 } else if (padding[i].unit === "px") { 9608 9609 out[i] = padding[i].value / doc.pxDimensions.h; 9610 9611 } else { 9612 9613 return null; 9614 9615 } 9616 } 9617 9618 9619 return out; 9620 } 9621 ), 9622 new StylingAttributeDefinition( 9623 imscNames.ns_tts, 9624 "showBackground", 9625 "always", 9626 ['region'], 9627 false, 9628 true, 9629 function (str) { 9630 return str; 9631 }, 9632 null 9633 ), 9634 new StylingAttributeDefinition( 9635 imscNames.ns_tts, 9636 "textAlign", 9637 "start", 9638 ['p'], 9639 true, 9640 true, 9641 function (str) { 9642 return str; 9643 }, 9644 function (doc, parent, element, attr) { 9645 9646 /* Section 7.16.9 of XSL */ 9647 9648 if (attr === "left") { 9649 9650 return "start"; 9651 9652 } else if (attr === "right") { 9653 9654 return "end"; 9655 9656 } else { 9657 9658 return attr; 9659 9660 } 9661 } 9662 ), 9663 new StylingAttributeDefinition( 9664 imscNames.ns_tts, 9665 "textDecoration", 9666 "none", 9667 ['span'], 9668 true, 9669 true, 9670 function (str) { 9671 return str.split(" "); 9672 }, 9673 null 9674 ), 9675 new StylingAttributeDefinition( 9676 imscNames.ns_tts, 9677 "textOutline", 9678 "none", 9679 ['span'], 9680 true, 9681 true, 9682 function (str) { 9683 9684 /* 9685 * returns {c: <color>?, thichness: <length>} | "none" 9686 * 9687 */ 9688 9689 if (str === "none") { 9690 9691 return str; 9692 9693 } else { 9694 9695 var r = {}; 9696 var s = str.split(" "); 9697 if (s.length === 0 || s.length > 2) return null; 9698 var c = imscUtils.parseColor(s[0]); 9699 9700 r.color = c; 9701 9702 if (c !== null) s.shift(); 9703 9704 if (s.length !== 1) return null; 9705 9706 var l = imscUtils.parseLength(s[0]); 9707 9708 if (!l) return null; 9709 9710 r.thickness = l; 9711 9712 return r; 9713 } 9714 9715 }, 9716 function (doc, parent, element, attr) { 9717 9718 /* 9719 * returns {color: <color>, thickness: <norm length>} 9720 * 9721 */ 9722 9723 if (attr === "none") return attr; 9724 9725 var rslt = {}; 9726 9727 if (attr.color === null) { 9728 9729 rslt.color = element.styleAttrs[imscStyles.byName.color.qname]; 9730 9731 } else { 9732 9733 rslt.color = attr.color; 9734 9735 } 9736 9737 if (attr.thickness.unit === "%") { 9738 9739 rslt.thickness = element.styleAttrs[imscStyles.byName.fontSize.qname] * attr.thickness.value / 100; 9740 9741 } else if (attr.thickness.unit === "em") { 9742 9743 rslt.thickness = element.styleAttrs[imscStyles.byName.fontSize.qname] * attr.thickness.value; 9744 9745 } else if (attr.thickness.unit === "c") { 9746 9747 rslt.thickness = attr.thickness.value / doc.cellResolution.h; 9748 9749 } else if (attr.thickness.unit === "px") { 9750 9751 rslt.thickness = attr.thickness.value / doc.pxDimensions.h; 9752 9753 } else { 9754 9755 return null; 9756 9757 } 9758 9759 9760 return rslt; 9761 } 9762 ), 9763 new StylingAttributeDefinition( 9764 imscNames.ns_tts, 9765 "unicodeBidi", 9766 "normal", 9767 ['span', 'p'], 9768 false, 9769 true, 9770 function (str) { 9771 return str; 9772 }, 9773 null 9774 ), 9775 new StylingAttributeDefinition( 9776 imscNames.ns_tts, 9777 "visibility", 9778 "visible", 9779 ['body', 'div', 'p', 'region', 'span'], 9780 true, 9781 true, 9782 function (str) { 9783 return str; 9784 }, 9785 null 9786 ), 9787 new StylingAttributeDefinition( 9788 imscNames.ns_tts, 9789 "wrapOption", 9790 "wrap", 9791 ['span'], 9792 true, 9793 true, 9794 function (str) { 9795 return str; 9796 }, 9797 null 9798 ), 9799 new StylingAttributeDefinition( 9800 imscNames.ns_tts, 9801 "writingMode", 9802 "lrtb", 9803 ['region'], 9804 false, 9805 true, 9806 function (str) { 9807 return str; 9808 }, 9809 null 9810 ), 9811 new StylingAttributeDefinition( 9812 imscNames.ns_tts, 9813 "zIndex", 9814 "auto", 9815 ['region'], 9816 false, 9817 true, 9818 function (str) { 9819 9820 var rslt; 9821 9822 if (str === 'auto') { 9823 9824 rslt = str; 9825 9826 } else { 9827 9828 rslt = parseInt(str); 9829 9830 if (isNaN(rslt)) { 9831 rslt = null; 9832 } 9833 9834 } 9835 9836 return rslt; 9837 }, 9838 null 9839 ), 9840 new StylingAttributeDefinition( 9841 imscNames.ns_ebutts, 9842 "linePadding", 9843 "0c", 9844 ['p'], 9845 true, 9846 false, 9847 imscUtils.parseLength, 9848 function (doc, parent, element, attr) { 9849 if (attr.unit === "c") { 9850 9851 return attr.value / doc.cellResolution.h; 9852 9853 } else { 9854 9855 return null; 9856 9857 } 9858 } 9859 ), 9860 new StylingAttributeDefinition( 9861 imscNames.ns_ebutts, 9862 "multiRowAlign", 9863 "auto", 9864 ['p'], 9865 true, 9866 false, 9867 function (str) { 9868 return str; 9869 }, 9870 null 9871 ), 9872 9873 new StylingAttributeDefinition( 9874 imscNames.ns_smpte, 9875 "backgroundImage", 9876 null, 9877 ['div'], 9878 false, 9879 false, 9880 function (str) { 9881 return str; 9882 }, 9883 null 9884 ), 9885 9886 new StylingAttributeDefinition( 9887 imscNames.ns_itts, 9888 "forcedDisplay", 9889 "false", 9890 ['body', 'div', 'p', 'region', 'span'], 9891 true, 9892 true, 9893 function (str) { 9894 return str === 'true' ? true : false; 9895 }, 9896 null 9897 ) 9898 ]; 9899 9900 /* TODO: allow null parse function */ 9901 9902 imscStyles.byQName = {}; 9903 for (var i in imscStyles.all) { 9904 9905 imscStyles.byQName[imscStyles.all[i].qname] = imscStyles.all[i]; 9906 } 9907 9908 imscStyles.byName = {}; 9909 for (var j in imscStyles.all) { 9910 9911 imscStyles.byName[imscStyles.all[j].name] = imscStyles.all[j]; 9912 } 9913 9914})(typeof exports === 'undefined' ? this.imscStyles = {} : exports, 9915 typeof imscNames === 'undefined' ? _dereq_(22) : imscNames, 9916 typeof imscUtils === 'undefined' ? _dereq_(24) : imscUtils); 9917 9918},{"22":22,"24":24}],24:[function(_dereq_,module,exports){ 9919/* 9920 * Copyright (c) 2016, Pierre-Anthony Lemieux <[email protected]> 9921 * All rights reserved. 9922 * 9923 * Redistribution and use in source and binary forms, with or without 9924 * modification, are permitted provided that the following conditions are met: 9925 * 9926 * * Redistributions of source code must retain the above copyright notice, this 9927 * list of conditions and the following disclaimer. 9928 * * Redistributions in binary form must reproduce the above copyright notice, 9929 * this list of conditions and the following disclaimer in the documentation 9930 * and/or other materials provided with the distribution. 9931 * 9932 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 9933 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9934 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9935 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 9936 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
9937 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 9938 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 9939 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 9940 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 9941 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 9942 * POSSIBILITY OF SUCH DAMAGE. 9943 */ 9944 9945/** 9946 * @module imscUtils 9947 */ 9948 9949; 9950(function (imscUtils) { // wrapper for non-node envs 9951 9952 /* Documents the error handler interface */ 9953 9954 /** 9955 * @classdesc Generic interface for handling events. The interface exposes four 9956 * methods: 9957 * * <pre>info</pre>: unusual event that does not result in an inconsistent state 9958 * * <pre>warn</pre>: unexpected event that should not result in an inconsistent state 9959 * * <pre>error</pre>: unexpected event that may result in an inconsistent state 9960 * * <pre>fatal</pre>: unexpected event that results in an inconsistent state 9961 * and termination of processing 9962 * Each method takes a single <pre>string</pre> describing the event as argument, 9963 * and returns a single <pre>boolean</pre>, which terminates processing if <pre>true</pre>. 9964 * 9965 * @name ErrorHandler 9966 * @class 9967 */ 9968 9969 9970 /* 9971 * Parses a TTML color expression 9972 * 9973 */ 9974 9975 var HEX_COLOR_RE = /#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})?/; 9976 var DEC_COLOR_RE = /rgb\((\d+),(\d+),(\d+)\)/; 9977 var DEC_COLORA_RE = /rgba\((\d+),(\d+),(\d+),(\d+)\)/; 9978 var NAMED_COLOR = { 9979 transparent: [0, 0, 0, 0], 9980 black: [0, 0, 0, 255], 9981 silver: [192, 192, 192, 255], 9982 gray: [128, 128, 128, 255], 9983 white: [255, 255, 255, 255], 9984 maroon: [128, 0, 0, 255], 9985 red: [255, 0, 0, 255], 9986 purple: [128, 0, 128, 255], 9987 fuchsia: [255, 0, 255, 255], 9988 magenta: [255, 0, 255, 255], 9989 green: [0, 128, 0, 255], 9990 lime: [0, 255, 0, 255], 9991 olive: [128, 128, 0, 255], 9992 yellow: [255, 255, 0, 255], 9993 navy: [0, 0, 128, 255], 9994 blue: [0, 0, 255, 255], 9995 teal: [0, 128, 128, 255], 9996 aqua: [0, 255, 255, 255], 9997 cyan: [0, 255, 255, 255] 9998 }; 9999 10000 imscUtils.parseColor = function (str) { 10001 10002 var m; 10003 var r = null; 10004 if (str in NAMED_COLOR) { 10005 10006 r = NAMED_COLOR[str]; 10007 10008 } else if ((m = HEX_COLOR_RE.exec(str)) !== null) { 10009 10010 r = [parseInt(m[1], 16), 10011 parseInt(m[2], 16), 10012 parseInt(m[3], 16), 10013 (m[4] !== undefined ? parseInt(m[4], 16) : 255)]; 10014 } else if ((m = DEC_COLOR_RE.exec(str)) !== null) { 10015 10016 r = [parseInt(m[1]), 10017 parseInt(m[2]), 10018 parseInt(m[3]), 10019 255]; 10020 } else if ((m = DEC_COLORA_RE.exec(str)) !== null) { 10021 10022 r = [parseInt(m[1]), 10023 parseInt(m[2]), 10024 parseInt(m[3]), 10025 parseInt(m[4])]; 10026 } 10027 10028 return r; 10029 }; 10030 10031 var LENGTH_RE = /^((?:\+|\-)?\d*(?:\.\d+)?)(px|em|c|%)$/; 10032 10033 imscUtils.parseLength = function (str) { 10034 10035 var m; 10036 10037 var r = null; 10038 10039 if ((m = LENGTH_RE.exec(str)) !== null) { 10040 10041 r = {value: parseFloat(m[1]), unit: m[2]}; 10042 } 10043 10044 return r; 10045 }; 10046 10047})(typeof exports === 'undefined' ? this.imscUtils = {} : exports); 10048 10049},{}],25:[function(_dereq_,module,exports){ 10050if (typeof Object.create === 'function') { 10051 // implementation from standard node.js 'util' module 10052 module.exports = function inherits(ctor, superCtor) { 10053 ctor.super_ = superCtor 10054 ctor.prototype = Object.create(superCtor.prototype, { 10055 constructor: { 10056 value: ctor, 10057 enumerable: false, 10058 writable: true, 10059 configurable: true 10060 } 10061 }); 10062 }; 10063} else { 10064 // old school shim for old browsers 10065 module.exports = function inherits(ctor, superCtor) { 10066 ctor.super_ = superCtor 10067 var TempCtor = function () {} 10068 TempCtor.prototype = superCtor.prototype 10069 ctor.prototype = new TempCtor() 10070 ctor.prototype.constructor = ctor 10071 } 10072} 10073 10074},{}],26:[function(_dereq_,module,exports){ 10075/*! 10076 * Determine if an object is a Buffer 10077 * 10078 * @author Feross Aboukhadijeh <[email protected]> <http://feross.org> 10079 * @license MIT 10080 */ 10081 10082// The _isBuffer check is for Safari 5-7 support, because it's missing 10083// Object.prototype.constructor. Remove this eventually 10084module.exports = function (obj) { 10085 return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) 10086} 10087 10088function isBuffer (obj) { 10089 return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) 10090} 10091 10092// For Node v0.10 support. Remove this eventually. 10093function isSlowBuffer (obj) { 10094 return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) 10095} 10096 10097},{}],27:[function(_dereq_,module,exports){ 10098var toString = {}.toString; 10099 10100module.exports = Array.isArray || function (arr) { 10101 return toString.call(arr) == '[object Array]'; 10102}; 10103 10104},{}],28:[function(_dereq_,module,exports){ 10105(function (process){ 10106'use strict'; 10107 10108if (!process.version || 10109 process.version.indexOf('v0.') === 0 || 10110 process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { 10111 module.exports = nextTick; 10112} else { 10113 module.exports = process.nextTick; 10114} 10115 10116function nextTick(fn, arg1, arg2, arg3) { 10117 if (typeof fn !== 'function') { 10118 throw new TypeError('"callback" argument must be a function'); 10119 } 10120 var len = arguments.length; 10121 var args, i; 10122 switch (len) { 10123 case 0: 10124 case 1: 10125 return process.nextTick(fn); 10126 case 2: 10127 return process.nextTick(function afterTickOne() { 10128 fn.call(null, arg1); 10129 });
vendor: 5,156 bytes, lines 10130-10298
10130 case 3: 10131 return process.nextTick(function afterTickTwo() { 10132 fn.call(null, arg1, arg2); 10133 }); 10134 case 4: 10135 return process.nextTick(function afterTickThree() { 10136 fn.call(null, arg1, arg2, arg3); 10137 }); 10138 default: 10139 args = new Array(len - 1); 10140 i = 0; 10141 while (i < args.length) { 10142 args[i++] = arguments[i]; 10143 } 10144 return process.nextTick(function afterTick() { 10145 fn.apply(null, args); 10146 }); 10147 } 10148} 10149 10150}).call(this,_dereq_(29)) 10151 10152},{"29":29}],29:[function(_dereq_,module,exports){ 10153// shim for using process in browser 10154var process = module.exports = {}; 10155 10156// cached from whatever global is present so that test runners that stub it 10157// don't break things. But we need to wrap it in a try catch in case it is 10158// wrapped in strict mode code which doesn't define any globals. It's inside a 10159// function because try/catches deoptimize in certain engines. 10160 10161var cachedSetTimeout; 10162var cachedClearTimeout; 10163 10164function defaultSetTimout() { 10165 throw new Error('setTimeout has not been defined'); 10166} 10167function defaultClearTimeout () { 10168 throw new Error('clearTimeout has not been defined'); 10169} 10170(function () { 10171 try { 10172 if (typeof setTimeout === 'function') { 10173 cachedSetTimeout = setTimeout; 10174 } else { 10175 cachedSetTimeout = defaultSetTimout; 10176 } 10177 } catch (e) { 10178 cachedSetTimeout = defaultSetTimout; 10179 } 10180 try { 10181 if (typeof clearTimeout === 'function') { 10182 cachedClearTimeout = clearTimeout; 10183 } else { 10184 cachedClearTimeout = defaultClearTimeout; 10185 } 10186 } catch (e) { 10187 cachedClearTimeout = defaultClearTimeout; 10188 } 10189} ()) 10190function runTimeout(fun) { 10191 if (cachedSetTimeout === setTimeout) { 10192 //normal enviroments in sane situations 10193 return setTimeout(fun, 0); 10194 } 10195 // if setTimeout wasn't available but was latter defined 10196 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { 10197 cachedSetTimeout = setTimeout; 10198 return setTimeout(fun, 0); 10199 } 10200 try { 10201 // when when somebody has screwed with setTimeout but no I.E. maddness 10202 return cachedSetTimeout(fun, 0); 10203 } catch(e){ 10204 try { 10205 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 10206 return cachedSetTimeout.call(null, fun, 0); 10207 } catch(e){ 10208 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error 10209 return cachedSetTimeout.call(this, fun, 0); 10210 } 10211 } 10212 10213 10214} 10215function runClearTimeout(marker) { 10216 if (cachedClearTimeout === clearTimeout) { 10217 //normal enviroments in sane situations 10218 return clearTimeout(marker); 10219 } 10220 // if clearTimeout wasn't available but was latter defined 10221 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { 10222 cachedClearTimeout = clearTimeout; 10223 return clearTimeout(marker); 10224 } 10225 try { 10226 // when when somebody has screwed with setTimeout but no I.E. maddness 10227 return cachedClearTimeout(marker); 10228 } catch (e){ 10229 try { 10230 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 10231 return cachedClearTimeout.call(null, marker); 10232 } catch (e){ 10233 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. 10234 // Some versions of I.E. have different rules for clearTimeout vs setTimeout 10235 return cachedClearTimeout.call(this, marker); 10236 } 10237 } 10238 10239 10240 10241} 10242var queue = []; 10243var draining = false; 10244var currentQueue; 10245var queueIndex = -1; 10246 10247function cleanUpNextTick() { 10248 if (!draining || !currentQueue) { 10249 return; 10250 } 10251 draining = false; 10252 if (currentQueue.length) { 10253 queue = currentQueue.concat(queue); 10254 } else { 10255 queueIndex = -1; 10256 } 10257 if (queue.length) { 10258 drainQueue(); 10259 } 10260} 10261 10262function drainQueue() { 10263 if (draining) { 10264 return; 10265 } 10266 var timeout = runTimeout(cleanUpNextTick); 10267 draining = true; 10268 10269 var len = queue.length; 10270 while(len) { 10271 currentQueue = queue; 10272 queue = []; 10273 while (++queueIndex < len) { 10274 if (currentQueue) { 10275 currentQueue[queueIndex].run(); 10276 } 10277 } 10278 queueIndex = -1; 10279 len = queue.length; 10280 } 10281 currentQueue = null; 10282 draining = false; 10283 runClearTimeout(timeout); 10284} 10285 10286process.nextTick = function (fun) { 10287 var args = new Array(arguments.length - 1); 10288 if (arguments.length > 1) { 10289 for (var i = 1; i < arguments.length; i++) { 10290 args[i - 1] = arguments[i]; 10291 } 10292 } 10293 queue.push(new Item(fun, args)); 10294 if (queue.length === 1 && !draining) { 10295 runTimeout(drainQueue); 10296 } 10297}; 10298
vendor: 14,736 bytes, lines 10299-10759
10299// v8 likes predictible objects 10300function Item(fun, array) { 10301 this.fun = fun; 10302 this.array = array; 10303} 10304Item.prototype.run = function () { 10305 this.fun.apply(null, this.array); 10306}; 10307process.title = 'browser'; 10308process.browser = true; 10309process.env = {}; 10310process.argv = []; 10311process.version = ''; // empty string to avoid regexp issues 10312process.versions = {}; 10313 10314function noop() {} 10315 10316process.on = noop; 10317process.addListener = noop; 10318process.once = noop; 10319process.off = noop; 10320process.removeListener = noop; 10321process.removeAllListeners = noop; 10322process.emit = noop; 10323process.prependListener = noop; 10324process.prependOnceListener = noop; 10325 10326process.listeners = function (name) { return [] } 10327 10328process.binding = function (name) { 10329 throw new Error('process.binding is not supported'); 10330}; 10331 10332process.cwd = function () { return '/' }; 10333process.chdir = function (dir) { 10334 throw new Error('process.chdir is not supported'); 10335}; 10336process.umask = function() { return 0; }; 10337 10338},{}],30:[function(_dereq_,module,exports){ 10339module.exports = _dereq_(31); 10340 10341},{"31":31}],31:[function(_dereq_,module,exports){ 10342// Copyright Joyent, Inc. and other Node contributors. 10343// 10344// Permission is hereby granted, free of charge, to any person obtaining a 10345// copy of this software and associated documentation files (the 10346// "Software"), to deal in the Software without restriction, including 10347// without limitation the rights to use, copy, modify, merge, publish, 10348// distribute, sublicense, and/or sell copies of the Software, and to permit 10349// persons to whom the Software is furnished to do so, subject to the 10350// following conditions: 10351// 10352// The above copyright notice and this permission notice shall be included 10353// in all copies or substantial portions of the Software. 10354// 10355// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 10356// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 10357// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 10358// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 10359// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 10360// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 10361// USE OR OTHER DEALINGS IN THE SOFTWARE. 10362 10363// a duplex stream is just a stream that is both readable and writable. 10364// Since JS doesn't have multiple prototypal inheritance, this class 10365// prototypally inherits from Readable, and then parasitically from 10366// Writable. 10367 10368'use strict'; 10369 10370/*<replacement>*/ 10371 10372var processNextTick = _dereq_(28); 10373/*</replacement>*/ 10374 10375/*<replacement>*/ 10376var objectKeys = Object.keys || function (obj) { 10377 var keys = []; 10378 for (var key in obj) { 10379 keys.push(key); 10380 }return keys; 10381}; 10382/*</replacement>*/ 10383 10384module.exports = Duplex; 10385 10386/*<replacement>*/ 10387var util = _dereq_(12); 10388util.inherits = _dereq_(25); 10389/*</replacement>*/ 10390 10391var Readable = _dereq_(33); 10392var Writable = _dereq_(35); 10393 10394util.inherits(Duplex, Readable); 10395 10396var keys = objectKeys(Writable.prototype); 10397for (var v = 0; v < keys.length; v++) { 10398 var method = keys[v]; 10399 if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; 10400} 10401 10402function Duplex(options) { 10403 if (!(this instanceof Duplex)) return new Duplex(options); 10404 10405 Readable.call(this, options); 10406 Writable.call(this, options); 10407 10408 if (options && options.readable === false) this.readable = false; 10409 10410 if (options && options.writable === false) this.writable = false; 10411 10412 this.allowHalfOpen = true; 10413 if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; 10414 10415 this.once('end', onend); 10416} 10417 10418// the no-half-open enforcer 10419function onend() { 10420 // if we allow half-open state, or if the writable side ended, 10421 // then we're ok. 10422 if (this.allowHalfOpen || this._writableState.ended) return; 10423 10424 // no more data can be written. 10425 // But allow more writes to happen in this tick. 10426 processNextTick(onEndNT, this); 10427} 10428 10429function onEndNT(self) { 10430 self.end(); 10431} 10432 10433Object.defineProperty(Duplex.prototype, 'destroyed', { 10434 get: function () { 10435 if (this._readableState === undefined || this._writableState === undefined) { 10436 return false; 10437 } 10438 return this._readableState.destroyed && this._writableState.destroyed; 10439 }, 10440 set: function (value) { 10441 // we ignore the value if the stream 10442 // has not been initialized yet 10443 if (this._readableState === undefined || this._writableState === undefined) { 10444 return; 10445 } 10446 10447 // backward compatibility, the user is explicitly 10448 // managing destroyed 10449 this._readableState.destroyed = value; 10450 this._writableState.destroyed = value; 10451 } 10452}); 10453 10454Duplex.prototype._destroy = function (err, cb) { 10455 this.push(null); 10456 this.end(); 10457 10458 processNextTick(cb, err); 10459}; 10460 10461function forEach(xs, f) { 10462 for (var i = 0, l = xs.length; i < l; i++) { 10463 f(xs[i], i); 10464 } 10465} 10466},{"12":12,"25":25,"28":28,"33":33,"35":35}],32:[function(_dereq_,module,exports){ 10467// Copyright Joyent, Inc. and other Node contributors. 10468// 10469// Permission is hereby granted, free of charge, to any person obtaining a 10470// copy of this software and associated documentation files (the 10471// "Software"), to deal in the Software without restriction, including 10472// without limitation the rights to use, copy, modify, merge, publish, 10473// distribute, sublicense, and/or sell copies of the Software, and to permit 10474// persons to whom the Software is furnished to do so, subject to the 10475// following conditions: 10476// 10477// The above copyright notice and this permission notice shall be included 10478// in all copies or substantial portions of the Software. 10479// 10480// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 10481// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 10482// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 10483// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 10484// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 10485// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 10486// USE OR OTHER DEALINGS IN THE SOFTWARE. 10487 10488// a passthrough stream. 10489// basically just the most minimal sort of Transform stream. 10490// Every written chunk gets output as-is. 10491 10492'use strict'; 10493 10494module.exports = PassThrough; 10495 10496var Transform = _dereq_(34); 10497 10498/*<replacement>*/ 10499var util = _dereq_(12); 10500util.inherits = _dereq_(25); 10501/*</replacement>*/ 10502 10503util.inherits(PassThrough, Transform); 10504 10505function PassThrough(options) { 10506 if (!(this instanceof PassThrough)) return new PassThrough(options); 10507 10508 Transform.call(this, options); 10509} 10510 10511PassThrough.prototype._transform = function (chunk, encoding, cb) { 10512 cb(null, chunk); 10513}; 10514},{"12":12,"25":25,"34":34}],33:[function(_dereq_,module,exports){ 10515(function (process,global){ 10516// Copyright Joyent, Inc. and other Node contributors. 10517// 10518// Permission is hereby granted, free of charge, to any person obtaining a 10519// copy of this software and associated documentation files (the 10520// "Software"), to deal in the Software without restriction, including 10521// without limitation the rights to use, copy, modify, merge, publish, 10522// distribute, sublicense, and/or sell copies of the Software, and to permit 10523// persons to whom the Software is furnished to do so, subject to the 10524// following conditions: 10525// 10526// The above copyright notice and this permission notice shall be included 10527// in all copies or substantial portions of the Software. 10528// 10529// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 10530// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 10531// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 10532// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 10533// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 10534// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 10535// USE OR OTHER DEALINGS IN THE SOFTWARE. 10536 10537'use strict'; 10538 10539/*<replacement>*/ 10540 10541var processNextTick = _dereq_(28); 10542/*</replacement>*/ 10543 10544module.exports = Readable; 10545 10546/*<replacement>*/ 10547var isArray = _dereq_(27); 10548/*</replacement>*/ 10549 10550/*<replacement>*/ 10551var Duplex; 10552/*</replacement>*/ 10553 10554Readable.ReadableState = ReadableState; 10555 10556/*<replacement>*/ 10557var EE = _dereq_(16).EventEmitter; 10558 10559var EElistenerCount = function (emitter, type) { 10560 return emitter.listeners(type).length; 10561}; 10562/*</replacement>*/ 10563 10564/*<replacement>*/ 10565var Stream = _dereq_(38); 10566/*</replacement>*/ 10567 10568// TODO(bmeurer): Change this back to const once hole checks are 10569// properly optimized away early in Ignition+TurboFan. 10570/*<replacement>*/ 10571var Buffer = _dereq_(44).Buffer; 10572var OurUint8Array = global.Uint8Array || function () {}; 10573function _uint8ArrayToBuffer(chunk) { 10574 return Buffer.from(chunk); 10575} 10576function _isUint8Array(obj) { 10577 return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; 10578} 10579/*</replacement>*/ 10580 10581/*<replacement>*/ 10582var util = _dereq_(12); 10583util.inherits = _dereq_(25); 10584/*</replacement>*/ 10585 10586/*<replacement>*/ 10587var debugUtil = _dereq_(8); 10588var debug = void 0; 10589if (debugUtil && debugUtil.debuglog) { 10590 debug = debugUtil.debuglog('stream'); 10591} else { 10592 debug = function () {}; 10593} 10594/*</replacement>*/ 10595 10596var BufferList = _dereq_(36); 10597var destroyImpl = _dereq_(37); 10598var StringDecoder; 10599 10600util.inherits(Readable, Stream); 10601 10602var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; 10603 10604function prependListener(emitter, event, fn) { 10605 // Sadly this is not cacheable as some libraries bundle their own 10606 // event emitter implementation with them. 10607 if (typeof emitter.prependListener === 'function') { 10608 return emitter.prependListener(event, fn); 10609 } else { 10610 // This is a hack to make sure that our error handler is attached before any 10611 // userland ones. NEVER DO THIS. This is here only because this code needs 10612 // to continue to work with older versions of Node.js that do not include 10613 // the prependListener() method. The goal is to eventually remove this hack. 10614 if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; 10615 } 10616} 10617 10618function ReadableState(options, stream) { 10619 Duplex = Duplex || _dereq_(31); 10620 10621 options = options || {}; 10622 10623 // object stream flag. Used to make read(n) ignore n and to 10624 // make all the buffer merging and length checks go away 10625 this.objectMode = !!options.objectMode; 10626 10627 if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; 10628 10629 // the point at which it stops calling _read() to fill the buffer 10630 // Note: 0 is a valid value, means "don't call _read preemptively ever" 10631 var hwm = options.highWaterMark; 10632 var defaultHwm = this.objectMode ? 16 : 16 * 1024; 10633 this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; 10634 10635 // cast to ints. 10636 this.highWaterMark = Math.floor(this.highWaterMark); 10637 10638 // A linked list is used to store data chunks instead of an array because the 10639 // linked list can remove elements from the beginning faster than 10640 // array.shift() 10641 this.buffer = new BufferList(); 10642 this.length = 0; 10643 this.pipes = null; 10644 this.pipesCount = 0; 10645 this.flowing = null; 10646 this.ended = false; 10647 this.endEmitted = false; 10648 this.reading = false; 10649 10650 // a flag to be able to tell if the event 'readable'/'data' is emitted 10651 // immediately, or on a later tick. We set this to true at first, because 10652 // any actions that shouldn't happen until "later" should generally also 10653 // not happen before the first read call. 10654 this.sync = true; 10655 10656 // whenever we return null, then we set a flag to say 10657 // that we're awaiting a 'readable' event emission. 10658 this.needReadable = false; 10659 this.emittedReadable = false; 10660 this.readableListening = false; 10661 this.resumeScheduled = false; 10662 10663 // has it been destroyed 10664 this.destroyed = false; 10665 10666 // Crypto is kind of old and crusty. Historically, its default string 10667 // encoding is 'binary' so we have to make this configurable. 10668 // Everything else in the universe uses 'utf8', though. 10669 this.defaultEncoding = options.defaultEncoding || 'utf8'; 10670 10671 // the number of writers that are awaiting a drain event in .pipe()s 10672 this.awaitDrain = 0; 10673 10674 // if true, a maybeReadMore has been scheduled 10675 this.readingMore = false; 10676 10677 this.decoder = null; 10678 this.encoding = null; 10679 if (options.encoding) { 10680 if (!StringDecoder) StringDecoder = _dereq_(47).StringDecoder; 10681 this.decoder = new StringDecoder(options.encoding); 10682 this.encoding = options.encoding; 10683 } 10684} 10685 10686function Readable(options) { 10687 Duplex = Duplex || _dereq_(31); 10688 10689 if (!(this instanceof Readable)) return new Readable(options); 10690 10691 this._readableState = new ReadableState(options, this); 10692 10693 // legacy 10694 this.readable = true; 10695 10696 if (options) { 10697 if (typeof options.read === 'function') this._read = options.read; 10698 10699 if (typeof options.destroy === 'function') this._destroy = options.destroy; 10700 } 10701 10702 Stream.call(this); 10703} 10704 10705Object.defineProperty(Readable.prototype, 'destroyed', { 10706 get: function () { 10707 if (this._readableState === undefined) { 10708 return false; 10709 } 10710 return this._readableState.destroyed; 10711 }, 10712 set: function (value) { 10713 // we ignore the value if the stream 10714 // has not been initialized yet 10715 if (!this._readableState) { 10716 return; 10717 } 10718 10719 // backward compatibility, the user is explicitly 10720 // managing destroyed 10721 this._readableState.destroyed = value; 10722 } 10723}); 10724 10725Readable.prototype.destroy = destroyImpl.destroy; 10726Readable.prototype._undestroy = destroyImpl.undestroy; 10727Readable.prototype._destroy = function (err, cb) { 10728 this.push(null); 10729 cb(err); 10730}; 10731 10732// Manually shove something into the read() buffer. 10733// This returns true if the highWaterMark has not been hit yet, 10734// similar to how Writable.write() returns true if you should 10735// write() some more. 10736Readable.prototype.push = function (chunk, encoding) { 10737 var state = this._readableState; 10738 var skipChunkCheck; 10739 10740 if (!state.objectMode) { 10741 if (typeof chunk === 'string') { 10742 encoding = encoding || state.defaultEncoding; 10743 if (encoding !== state.encoding) { 10744 chunk = Buffer.from(chunk, encoding); 10745 encoding = ''; 10746 } 10747 skipChunkCheck = true; 10748 } 10749 } else { 10750 skipChunkCheck = true; 10751 } 10752 10753 return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); 10754}; 10755 10756// Unshift should *always* be something directly out of read() 10757Readable.prototype.unshift = function (chunk) { 10758 return readableAddChunk(this, chunk, null, true, false); 10759};
vendor: 2,776 bytes, lines 10760-10836
10760 10761function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { 10762 var state = stream._readableState; 10763 if (chunk === null) { 10764 state.reading = false; 10765 onEofChunk(stream, state); 10766 } else { 10767 var er; 10768 if (!skipChunkCheck) er = chunkInvalid(state, chunk); 10769 if (er) { 10770 stream.emit('error', er); 10771 } else if (state.objectMode || chunk && chunk.length > 0) { 10772 if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { 10773 chunk = _uint8ArrayToBuffer(chunk); 10774 } 10775 10776 if (addToFront) { 10777 if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true); 10778 } else if (state.ended) { 10779 stream.emit('error', new Error('stream.push() after EOF')); 10780 } else { 10781 state.reading = false; 10782 if (state.decoder && !encoding) { 10783 chunk = state.decoder.write(chunk); 10784 if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); 10785 } else { 10786 addChunk(stream, state, chunk, false); 10787 } 10788 } 10789 } else if (!addToFront) { 10790 state.reading = false; 10791 } 10792 } 10793 10794 return needMoreData(state); 10795} 10796 10797function addChunk(stream, state, chunk, addToFront) { 10798 if (state.flowing && state.length === 0 && !state.sync) { 10799 stream.emit('data', chunk); 10800 stream.read(0); 10801 } else { 10802 // update the buffer info. 10803 state.length += state.objectMode ? 1 : chunk.length; 10804 if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); 10805 10806 if (state.needReadable) emitReadable(stream); 10807 } 10808 maybeReadMore(stream, state); 10809} 10810 10811function chunkInvalid(state, chunk) { 10812 var er; 10813 if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { 10814 er = new TypeError('Invalid non-string/buffer chunk'); 10815 } 10816 return er; 10817} 10818 10819// if it's past the high water mark, we can push in some more. 10820// Also, if we have no data yet, we can stand some 10821// more bytes. This is to work around cases where hwm=0, 10822// such as the repl. Also, if the push() triggered a 10823// readable event, and the user called read(largeNumber) such that 10824// needReadable was set, then we ought to push more, so that another 10825// 'readable' event will be triggered. 10826function needMoreData(state) { 10827 return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); 10828} 10829 10830Readable.prototype.isPaused = function () { 10831 return this._readableState.flowing === false; 10832}; 10833 10834// backwards compatibility. 10835Readable.prototype.setEncoding = function (enc) { 10836 if (!StringDecoder) StringDecoder = _dereq_(47
vendor: 20,892 bytes, lines 10836-11522
10836).StringDecoder; 10837 this._readableState.decoder = new StringDecoder(enc); 10838 this._readableState.encoding = enc; 10839 return this; 10840}; 10841 10842// Don't raise the hwm > 8MB 10843var MAX_HWM = 0x800000; 10844function computeNewHighWaterMark(n) { 10845 if (n >= MAX_HWM) { 10846 n = MAX_HWM; 10847 } else { 10848 // Get the next highest power of 2 to prevent increasing hwm excessively in 10849 // tiny amounts 10850 n--; 10851 n |= n >>> 1; 10852 n |= n >>> 2; 10853 n |= n >>> 4; 10854 n |= n >>> 8; 10855 n |= n >>> 16; 10856 n++; 10857 } 10858 return n; 10859} 10860 10861// This function is designed to be inlinable, so please take care when making 10862// changes to the function body. 10863function howMuchToRead(n, state) { 10864 if (n <= 0 || state.length === 0 && state.ended) return 0; 10865 if (state.objectMode) return 1; 10866 if (n !== n) { 10867 // Only flow one buffer at a time 10868 if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; 10869 } 10870 // If we're asking for more than the current hwm, then raise the hwm. 10871 if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); 10872 if (n <= state.length) return n; 10873 // Don't have enough 10874 if (!state.ended) { 10875 state.needReadable = true; 10876 return 0; 10877 } 10878 return state.length; 10879} 10880 10881// you can override either this method, or the async _read(n) below. 10882Readable.prototype.read = function (n) { 10883 debug('read', n); 10884 n = parseInt(n, 10); 10885 var state = this._readableState; 10886 var nOrig = n; 10887 10888 if (n !== 0) state.emittedReadable = false; 10889 10890 // if we're doing read(0) to trigger a readable event, but we 10891 // already have a bunch of data in the buffer, then just trigger 10892 // the 'readable' event and move on. 10893 if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { 10894 debug('read: emitReadable', state.length, state.ended); 10895 if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); 10896 return null; 10897 } 10898 10899 n = howMuchToRead(n, state); 10900 10901 // if we've ended, and we're now clear, then finish it up. 10902 if (n === 0 && state.ended) { 10903 if (state.length === 0) endReadable(this); 10904 return null; 10905 } 10906 10907 // All the actual chunk generation logic needs to be 10908 // *below* the call to _read. The reason is that in certain 10909 // synthetic stream cases, such as passthrough streams, _read 10910 // may be a completely synchronous operation which may change 10911 // the state of the read buffer, providing enough data when 10912 // before there was *not* enough. 10913 // 10914 // So, the steps are: 10915 // 1. Figure out what the state of things will be after we do 10916 // a read from the buffer. 10917 // 10918 // 2. If that resulting state will trigger a _read, then call _read. 10919 // Note that this may be asynchronous, or synchronous. Yes, it is 10920 // deeply ugly to write APIs this way, but that still doesn't mean 10921 // that the Readable class should behave improperly, as streams are 10922 // designed to be sync/async agnostic. 10923 // Take note if the _read call is sync or async (ie, if the read call 10924 // has returned yet), so that we know whether or not it's safe to emit 10925 // 'readable' etc. 10926 // 10927 // 3. Actually pull the requested chunks out of the buffer and return. 10928 10929 // if we need a readable event, then we need to do some reading. 10930 var doRead = state.needReadable; 10931 debug('need readable', doRead); 10932 10933 // if we currently have less than the highWaterMark, then also read some 10934 if (state.length === 0 || state.length - n < state.highWaterMark) { 10935 doRead = true; 10936 debug('length less than watermark', doRead); 10937 } 10938 10939 // however, if we've ended, then there's no point, and if we're already 10940 // reading, then it's unnecessary. 10941 if (state.ended || state.reading) { 10942 doRead = false; 10943 debug('reading or ended', doRead); 10944 } else if (doRead) { 10945 debug('do read'); 10946 state.reading = true; 10947 state.sync = true; 10948 // if the length is currently zero, then we *need* a readable event. 10949 if (state.length === 0) state.needReadable = true; 10950 // call internal read method 10951 this._read(state.highWaterMark); 10952 state.sync = false; 10953 // If _read pushed data synchronously, then `reading` will be false, 10954 // and we need to re-evaluate how much data we can return to the user. 10955 if (!state.reading) n = howMuchToRead(nOrig, state); 10956 } 10957 10958 var ret; 10959 if (n > 0) ret = fromList(n, state);else ret = null; 10960 10961 if (ret === null) { 10962 state.needReadable = true; 10963 n = 0; 10964 } else { 10965 state.length -= n; 10966 } 10967 10968 if (state.length === 0) { 10969 // If we have nothing in the buffer, then we want to know 10970 // as soon as we *do* get something into the buffer. 10971 if (!state.ended) state.needReadable = true; 10972 10973 // If we tried to read() past the EOF, then emit end on the next tick. 10974 if (nOrig !== n && state.ended) endReadable(this); 10975 } 10976 10977 if (ret !== null) this.emit('data', ret); 10978 10979 return ret; 10980}; 10981 10982function onEofChunk(stream, state) { 10983 if (state.ended) return; 10984 if (state.decoder) { 10985 var chunk = state.decoder.end(); 10986 if (chunk && chunk.length) { 10987 state.buffer.push(chunk); 10988 state.length += state.objectMode ? 1 : chunk.length; 10989 } 10990 } 10991 state.ended = true; 10992 10993 // emit 'readable' now to make sure it gets picked up. 10994 emitReadable(stream); 10995} 10996 10997// Don't emit readable right away in sync mode, because this can trigger 10998// another read() call => stack overflow. This way, it might trigger 10999// a nextTick recursion warning, but that's not so bad. 11000function emitReadable(stream) { 11001 var state = stream._readableState; 11002 state.needReadable = false; 11003 if (!state.emittedReadable) { 11004 debug('emitReadable', state.flowing); 11005 state.emittedReadable = true; 11006 if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); 11007 } 11008} 11009 11010function emitReadable_(stream) { 11011 debug('emit readable'); 11012 stream.emit('readable'); 11013 flow(stream); 11014} 11015 11016// at this point, the user has presumably seen the 'readable' event, 11017// and called read() to consume some data. that may have triggered 11018// in turn another _read(n) call, in which case reading = true if 11019// it's in progress. 11020// However, if we're not ended, or reading, and the length < hwm, 11021// then go ahead and try to read some more preemptively. 11022function maybeReadMore(stream, state) { 11023 if (!state.readingMore) { 11024 state.readingMore = true; 11025 processNextTick(maybeReadMore_, stream, state); 11026 } 11027} 11028 11029function maybeReadMore_(stream, state) { 11030 var len = state.length; 11031 while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { 11032 debug('maybeReadMore read 0'); 11033 stream.read(0); 11034 if (len === state.length) 11035 // didn't get any data, stop spinning. 11036 break;else len = state.length; 11037 } 11038 state.readingMore = false; 11039} 11040 11041// abstract method. to be overridden in specific implementation classes. 11042// call cb(er, data) where data is <= n in length. 11043// for virtual (non-string, non-buffer) streams, "length" is somewhat 11044// arbitrary, and perhaps not very meaningful. 11045Readable.prototype._read = function (n) { 11046 this.emit('error', new Error('_read() is not implemented')); 11047}; 11048 11049Readable.prototype.pipe = function (dest, pipeOpts) { 11050 var src = this; 11051 var state = this._readableState; 11052 11053 switch (state.pipesCount) { 11054 case 0: 11055 state.pipes = dest; 11056 break; 11057 case 1: 11058 state.pipes = [state.pipes, dest]; 11059 break; 11060 default: 11061 state.pipes.push(dest); 11062 break; 11063 } 11064 state.pipesCount += 1; 11065 debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); 11066 11067 var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; 11068 11069 var endFn = doEnd ? onend : unpipe; 11070 if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); 11071 11072 dest.on('unpipe', onunpipe); 11073 function onunpipe(readable, unpipeInfo) { 11074 debug('onunpipe'); 11075 if (readable === src) { 11076 if (unpipeInfo && unpipeInfo.hasUnpiped === false) { 11077 unpipeInfo.hasUnpiped = true; 11078 cleanup(); 11079 } 11080 } 11081 } 11082 11083 function onend() { 11084 debug('onend'); 11085 dest.end(); 11086 } 11087 11088 // when the dest drains, it reduces the awaitDrain counter 11089 // on the source. This would be more elegant with a .once() 11090 // handler in flow(), but adding and removing repeatedly is 11091 // too slow. 11092 var ondrain = pipeOnDrain(src); 11093 dest.on('drain', ondrain); 11094 11095 var cleanedUp = false; 11096 function cleanup() { 11097 debug('cleanup'); 11098 // cleanup event handlers once the pipe is broken 11099 dest.removeListener('close', onclose); 11100 dest.removeListener('finish', onfinish); 11101 dest.removeListener('drain', ondrain); 11102 dest.removeListener('error', onerror); 11103 dest.removeListener('unpipe', onunpipe); 11104 src.removeListener('end', onend); 11105 src.removeListener('end', unpipe); 11106 src.removeListener('data', ondata); 11107 11108 cleanedUp = true; 11109 11110 // if the reader is waiting for a drain event from this 11111 // specific writer, then it would cause it to never start 11112 // flowing again. 11113 // So, if this is awaiting a drain, then we just call it now. 11114 // If we don't know, then assume that we are waiting for one. 11115 if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); 11116 } 11117 11118 // If the user pushes more data while we're writing to dest then we'll end up 11119 // in ondata again. However, we only want to increase awaitDrain once because 11120 // dest will only emit one 'drain' event for the multiple writes. 11121 // => Introduce a guard on increasing awaitDrain. 11122 var increasedAwaitDrain = false; 11123 src.on('data', ondata); 11124 function ondata(chunk) { 11125 debug('ondata'); 11126 increasedAwaitDrain = false; 11127 var ret = dest.write(chunk); 11128 if (false === ret && !increasedAwaitDrain) { 11129 // If the user unpiped during `dest.write()`, it is possible 11130 // to get stuck in a permanently paused state if that write 11131 // also returned false. 11132 // => Check whether `dest` is still a piping destination. 11133 if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { 11134 debug('false write response, pause', src._readableState.awaitDrain); 11135 src._readableState.awaitDrain++; 11136 increasedAwaitDrain = true; 11137 } 11138 src.pause(); 11139 } 11140 } 11141 11142 // if the dest has an error, then stop piping into it. 11143 // however, don't suppress the throwing behavior for this. 11144 function onerror(er) { 11145 debug('onerror', er); 11146 unpipe(); 11147 dest.removeListener('error', onerror); 11148 if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); 11149 } 11150 11151 // Make sure our error handler is attached before userland ones. 11152 prependListener(dest, 'error', onerror); 11153 11154 // Both close and finish should trigger unpipe, but only once. 11155 function onclose() { 11156 dest.removeListener('finish', onfinish); 11157 unpipe(); 11158 } 11159 dest.once('close', onclose); 11160 function onfinish() { 11161 debug('onfinish'); 11162 dest.removeListener('close', onclose); 11163 unpipe(); 11164 } 11165 dest.once('finish', onfinish); 11166 11167 function unpipe() { 11168 debug('unpipe'); 11169 src.unpipe(dest); 11170 } 11171 11172 // tell the dest that it's being piped to 11173 dest.emit('pipe', src); 11174 11175 // start the flow if it hasn't been started already. 11176 if (!state.flowing) { 11177 debug('pipe resume'); 11178 src.resume(); 11179 } 11180 11181 return dest; 11182}; 11183 11184function pipeOnDrain(src) { 11185 return function () { 11186 var state = src._readableState; 11187 debug('pipeOnDrain', state.awaitDrain); 11188 if (state.awaitDrain) state.awaitDrain--; 11189 if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { 11190 state.flowing = true; 11191 flow(src); 11192 } 11193 }; 11194} 11195 11196Readable.prototype.unpipe = function (dest) { 11197 var state = this._readableState; 11198 var unpipeInfo = { hasUnpiped: false }; 11199 11200 // if we're not piping anywhere, then do nothing. 11201 if (state.pipesCount === 0) return this; 11202 11203 // just one destination. most common case. 11204 if (state.pipesCount === 1) { 11205 // passed in one, but it's not the right one. 11206 if (dest && dest !== state.pipes) return this; 11207 11208 if (!dest) dest = state.pipes; 11209 11210 // got a match. 11211 state.pipes = null; 11212 state.pipesCount = 0; 11213 state.flowing = false; 11214 if (dest) dest.emit('unpipe', this, unpipeInfo); 11215 return this; 11216 } 11217 11218 // slow case. multiple pipe destinations. 11219 11220 if (!dest) { 11221 // remove all. 11222 var dests = state.pipes; 11223 var len = state.pipesCount; 11224 state.pipes = null; 11225 state.pipesCount = 0; 11226 state.flowing = false; 11227 11228 for (var i = 0; i < len; i++) { 11229 dests[i].emit('unpipe', this, unpipeInfo); 11230 }return this; 11231 } 11232 11233 // try to find the right one. 11234 var index = indexOf(state.pipes, dest); 11235 if (index === -1) return this; 11236 11237 state.pipes.splice(index, 1); 11238 state.pipesCount -= 1; 11239 if (state.pipesCount === 1) state.pipes = state.pipes[0]; 11240 11241 dest.emit('unpipe', this, unpipeInfo); 11242 11243 return this; 11244}; 11245 11246// set up data events if they are asked for 11247// Ensure readable listeners eventually get something 11248Readable.prototype.on = function (ev, fn) { 11249 var res = Stream.prototype.on.call(this, ev, fn); 11250 11251 if (ev === 'data') { 11252 // Start flowing on next tick if stream isn't explicitly paused 11253 if (this._readableState.flowing !== false) this.resume(); 11254 } else if (ev === 'readable') { 11255 var state = this._readableState; 11256 if (!state.endEmitted && !state.readableListening) { 11257 state.readableListening = state.needReadable = true; 11258 state.emittedReadable = false; 11259 if (!state.reading) { 11260 processNextTick(nReadingNextTick, this); 11261 } else if (state.length) { 11262 emitReadable(this); 11263 } 11264 } 11265 } 11266 11267 return res; 11268}; 11269Readable.prototype.addListener = Readable.prototype.on; 11270 11271function nReadingNextTick(self) { 11272 debug('readable nexttick read 0'); 11273 self.read(0); 11274} 11275 11276// pause() and resume() are remnants of the legacy readable stream API 11277// If the user uses them, then switch into old mode. 11278Readable.prototype.resume = function () { 11279 var state = this._readableState; 11280 if (!state.flowing) { 11281 debug('resume'); 11282 state.flowing = true; 11283 resume(this, state); 11284 } 11285 return this; 11286}; 11287 11288function resume(stream, state) { 11289 if (!state.resumeScheduled) { 11290 state.resumeScheduled = true; 11291 processNextTick(resume_, stream, state); 11292 } 11293} 11294 11295function resume_(stream, state) { 11296 if (!state.reading) { 11297 debug('resume read 0'); 11298 stream.read(0); 11299 } 11300 11301 state.resumeScheduled = false; 11302 state.awaitDrain = 0; 11303 stream.emit('resume'); 11304 flow(stream); 11305 if (state.flowing && !state.reading) stream.read(0); 11306} 11307 11308Readable.prototype.pause = function () { 11309 debug('call pause flowing=%j', this._readableState.flowing); 11310 if (false !== this._readableState.flowing) { 11311 debug('pause'); 11312 this._readableState.flowing = false; 11313 this.emit('pause'); 11314 } 11315 return this; 11316}; 11317 11318function flow(stream) { 11319 var state = stream._readableState; 11320 debug('flow', state.flowing); 11321 while (state.flowing && stream.read() !== null) {} 11322} 11323 11324// wrap an old-style stream as the async data source. 11325// This is *not* part of the readable stream interface. 11326// It is an ugly unfortunate mess of history. 11327Readable.prototype.wrap = function (stream) { 11328 var state = this._readableState; 11329 var paused = false; 11330 11331 var self = this; 11332 stream.on('end', function () { 11333 debug('wrapped end'); 11334 if (state.decoder && !state.ended) { 11335 var chunk = state.decoder.end(); 11336 if (chunk && chunk.length) self.push(chunk); 11337 } 11338 11339 self.push(null); 11340 }); 11341 11342 stream.on('data', function (chunk) { 11343 debug('wrapped data'); 11344 if (state.decoder) chunk = state.decoder.write(chunk); 11345 11346 // don't skip over falsy values in objectMode 11347 if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; 11348 11349 var ret = self.push(chunk); 11350 if (!ret) { 11351 paused = true; 11352 stream.pause(); 11353 } 11354 }); 11355 11356 // proxy all the other methods. 11357 // important when wrapping filters and duplexes. 11358 for (var i in stream) { 11359 if (this[i] === undefined && typeof stream[i] === 'function') { 11360 this[i] = function (method) { 11361 return function () { 11362 return stream[method].apply(stream, arguments); 11363 }; 11364 }(i); 11365 } 11366 } 11367 11368 // proxy certain important events. 11369 for (var n = 0; n < kProxyEvents.length; n++) { 11370 stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); 11371 } 11372 11373 // when we try to consume some more bytes, simply unpause the 11374 // underlying stream. 11375 self._read = function (n) { 11376 debug('wrapped _read', n); 11377 if (paused) { 11378 paused = false; 11379 stream.resume(); 11380 } 11381 }; 11382 11383 return self; 11384}; 11385 11386// exposed for testing purposes only. 11387Readable._fromList = fromList; 11388 11389// Pluck off n bytes from an array of buffers. 11390// Length is the combined lengths of all the buffers in the list. 11391// This function is designed to be inlinable, so please take care when making 11392// changes to the function body. 11393function fromList(n, state) { 11394 // nothing buffered 11395 if (state.length === 0) return null; 11396 11397 var ret; 11398 if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { 11399 // read it all, truncate the list 11400 if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); 11401 state.buffer.clear(); 11402 } else { 11403 // read part of list 11404 ret = fromListPartial(n, state.buffer, state.decoder); 11405 } 11406 11407 return ret; 11408} 11409 11410// Extracts only enough buffered data to satisfy the amount requested. 11411// This function is designed to be inlinable, so please take care when making 11412// changes to the function body. 11413function fromListPartial(n, list, hasStrings) { 11414 var ret; 11415 if (n < list.head.data.length) { 11416 // slice is the same for buffers and strings 11417 ret = list.head.data.slice(0, n); 11418 list.head.data = list.head.data.slice(n); 11419 } else if (n === list.head.data.length) { 11420 // first chunk is a perfect match 11421 ret = list.shift(); 11422 } else { 11423 // result spans more than one buffer 11424 ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); 11425 } 11426 return ret; 11427} 11428 11429// Copies a specified amount of characters from the list of buffered data 11430// chunks. 11431// This function is designed to be inlinable, so please take care when making 11432// changes to the function body. 11433function copyFromBufferString(n, list) { 11434 var p = list.head; 11435 var c = 1; 11436 var ret = p.data; 11437 n -= ret.length; 11438 while (p = p.next) { 11439 var str = p.data; 11440 var nb = n > str.length ? str.length : n; 11441 if (nb === str.length) ret += str;else ret += str.slice(0, n); 11442 n -= nb; 11443 if (n === 0) { 11444 if (nb === str.length) { 11445 ++c; 11446 if (p.next) list.head = p.next;else list.head = list.tail = null; 11447 } else { 11448 list.head = p; 11449 p.data = str.slice(nb); 11450 } 11451 break; 11452 } 11453 ++c; 11454 } 11455 list.length -= c; 11456 return ret; 11457} 11458 11459// Copies a specified amount of bytes from the list of buffered data chunks. 11460// This function is designed to be inlinable, so please take care when making 11461// changes to the function body. 11462function copyFromBuffer(n, list) { 11463 var ret = Buffer.allocUnsafe(n); 11464 var p = list.head; 11465 var c = 1; 11466 p.data.copy(ret); 11467 n -= p.data.length; 11468 while (p = p.next) { 11469 var buf = p.data; 11470 var nb = n > buf.length ? buf.length : n; 11471 buf.copy(ret, ret.length - n, 0, nb); 11472 n -= nb; 11473 if (n === 0) { 11474 if (nb === buf.length) { 11475 ++c; 11476 if (p.next) list.head = p.next;else list.head = list.tail = null; 11477 } else { 11478 list.head = p; 11479 p.data = buf.slice(nb); 11480 } 11481 break; 11482 } 11483 ++c; 11484 } 11485 list.length -= c; 11486 return ret; 11487} 11488 11489function endReadable(stream) { 11490 var state = stream._readableState; 11491 11492 // If we get here before consuming all the bytes, then that is a 11493 // bug in node. Should never happen. 11494 if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); 11495 11496 if (!state.endEmitted) { 11497 state.ended = true; 11498 processNextTick(endReadableNT, state, stream); 11499 } 11500} 11501 11502function endReadableNT(state, stream) { 11503 // Check that we didn't get one last unshift. 11504 if (!state.endEmitted && state.length === 0) { 11505 state.endEmitted = true; 11506 stream.readable = false; 11507 stream.emit('end'); 11508 } 11509} 11510 11511function forEach(xs, f) { 11512 for (var i = 0, l = xs.length; i < l; i++) { 11513 f(xs[i], i); 11514 } 11515} 11516 11517function indexOf(xs, x) { 11518 for (var i = 0, l = xs.length; i < l; i++) { 11519 if (xs[i] === x) return i; 11520 } 11521 return -1; 11522}
11523}).call(this,_dereq_(29),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 11524 11525},{"12":12,"16":16,"25":25,"27":27,"28":28,"29":29,"31":31,"36":36,"37":37,"38":38,"44":44,"47":47,"8":8}],34:[function(_dereq_,module,exports){ 11526// Copyright Joyent, Inc. and other Node contributors. 11527// 11528// Permission is hereby granted, free of charge, to any person obtaining a 11529// copy of this software and associated documentation files (the 11530// "Software"), to deal in the Software without restriction, including 11531// without limitation the rights to use, copy, modify, merge, publish, 11532// distribute, sublicense, and/or sell copies of the Software, and to permit 11533// persons to whom the Software is furnished to do so, subject to the 11534// following conditions: 11535// 11536// The above copyright notice and this permission notice shall be included 11537// in all copies or substantial portions of the Software. 11538// 11539// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 11540// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 11541// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 11542// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 11543// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 11544// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 11545// USE OR OTHER DEALINGS IN THE SOFTWARE. 11546 11547// a transform stream is a readable/writable stream where you do 11548// something with the data. Sometimes it's called a "filter", 11549// but that's not a great name for it, since that implies a thing where 11550// some bits pass through, and others are simply ignored. (That would 11551// be a valid example of a transform, of course.) 11552// 11553// While the output is causally related to the input, it's not a 11554// necessarily symmetric or synchronous transformation. For example, 11555// a zlib stream might take multiple plain-text writes(), and then 11556// emit a single compressed chunk some time in the future. 11557// 11558// Here's how this works: 11559// 11560// The Transform stream has all the aspects of the readable and writable 11561// stream classes. When you write(chunk), that calls _write(chunk,cb) 11562// internally, and returns false if there's a lot of pending writes 11563// buffered up. When you call read(), that calls _read(n) until
vendor: 25,962 bytes, lines 11564-12405
11564// there's enough pending readable data buffered up. 11565// 11566// In a transform stream, the written data is placed in a buffer. When 11567// _read(n) is called, it transforms the queued up data, calling the 11568// buffered _write cb's as it consumes chunks. If consuming a single 11569// written chunk would result in multiple output chunks, then the first 11570// outputted bit calls the readcb, and subsequent chunks just go into 11571// the read buffer, and will cause it to emit 'readable' if necessary. 11572// 11573// This way, back-pressure is actually determined by the reading side, 11574// since _read has to be called to start processing a new chunk. However, 11575// a pathological inflate type of transform can cause excessive buffering 11576// here. For example, imagine a stream where every byte of input is 11577// interpreted as an integer from 0-255, and then results in that many 11578// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in 11579// 1kb of data being output. In this case, you could write a very small 11580// amount of input, and end up with a very large amount of output. In 11581// such a pathological inflating mechanism, there'd be no way to tell 11582// the system to stop doing the transform. A single 4MB write could 11583// cause the system to run out of memory. 11584// 11585// However, even in such a pathological case, only a single written chunk 11586// would be consumed, and then the rest would wait (un-transformed) until 11587// the results of the previous transformed chunk were consumed. 11588 11589'use strict'; 11590 11591module.exports = Transform; 11592 11593var Duplex = _dereq_(31); 11594 11595/*<replacement>*/ 11596var util = _dereq_(12); 11597util.inherits = _dereq_(25); 11598/*</replacement>*/ 11599 11600util.inherits(Transform, Duplex); 11601 11602function TransformState(stream) { 11603 this.afterTransform = function (er, data) { 11604 return afterTransform(stream, er, data); 11605 }; 11606 11607 this.needTransform = false; 11608 this.transforming = false; 11609 this.writecb = null; 11610 this.writechunk = null; 11611 this.writeencoding = null; 11612} 11613 11614function afterTransform(stream, er, data) { 11615 var ts = stream._transformState; 11616 ts.transforming = false; 11617 11618 var cb = ts.writecb; 11619 11620 if (!cb) { 11621 return stream.emit('error', new Error('write callback called multiple times')); 11622 } 11623 11624 ts.writechunk = null; 11625 ts.writecb = null; 11626 11627 if (data !== null && data !== undefined) stream.push(data); 11628 11629 cb(er); 11630 11631 var rs = stream._readableState; 11632 rs.reading = false; 11633 if (rs.needReadable || rs.length < rs.highWaterMark) { 11634 stream._read(rs.highWaterMark); 11635 } 11636} 11637 11638function Transform(options) { 11639 if (!(this instanceof Transform)) return new Transform(options); 11640 11641 Duplex.call(this, options); 11642 11643 this._transformState = new TransformState(this); 11644 11645 var stream = this; 11646 11647 // start out asking for a readable event once data is transformed. 11648 this._readableState.needReadable = true; 11649 11650 // we have implemented the _read method, and done the other things 11651 // that Readable wants before the first _read call, so unset the 11652 // sync guard flag. 11653 this._readableState.sync = false; 11654 11655 if (options) { 11656 if (typeof options.transform === 'function') this._transform = options.transform; 11657 11658 if (typeof options.flush === 'function') this._flush = options.flush; 11659 } 11660 11661 // When the writable side finishes, then flush out anything remaining. 11662 this.once('prefinish', function () { 11663 if (typeof this._flush === 'function') this._flush(function (er, data) { 11664 done(stream, er, data); 11665 });else done(stream); 11666 }); 11667} 11668 11669Transform.prototype.push = function (chunk, encoding) { 11670 this._transformState.needTransform = false; 11671 return Duplex.prototype.push.call(this, chunk, encoding); 11672}; 11673 11674// This is the part where you do stuff! 11675// override this function in implementation classes. 11676// 'chunk' is an input chunk. 11677// 11678// Call `push(newChunk)` to pass along transformed output 11679// to the readable side. You may call 'push' zero or more times. 11680// 11681// Call `cb(err)` when you are done with this chunk. If you pass 11682// an error, then that'll put the hurt on the whole operation. If you 11683// never call cb(), then you'll never get another chunk. 11684Transform.prototype._transform = function (chunk, encoding, cb) { 11685 throw new Error('_transform() is not implemented'); 11686}; 11687 11688Transform.prototype._write = function (chunk, encoding, cb) { 11689 var ts = this._transformState; 11690 ts.writecb = cb; 11691 ts.writechunk = chunk; 11692 ts.writeencoding = encoding; 11693 if (!ts.transforming) { 11694 var rs = this._readableState; 11695 if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); 11696 } 11697}; 11698 11699// Doesn't matter what the args are here. 11700// _transform does all the work. 11701// That we got here means that the readable side wants more data. 11702Transform.prototype._read = function (n) { 11703 var ts = this._transformState; 11704 11705 if (ts.writechunk !== null && ts.writecb && !ts.transforming) { 11706 ts.transforming = true; 11707 this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); 11708 } else { 11709 // mark that we need a transform, so that any data that comes in 11710 // will get processed, now that we've asked for it. 11711 ts.needTransform = true; 11712 } 11713}; 11714 11715Transform.prototype._destroy = function (err, cb) { 11716 var _this = this; 11717 11718 Duplex.prototype._destroy.call(this, err, function (err2) { 11719 cb(err2); 11720 _this.emit('close'); 11721 }); 11722}; 11723 11724function done(stream, er, data) { 11725 if (er) return stream.emit('error', er); 11726 11727 if (data !== null && data !== undefined) stream.push(data); 11728 11729 // if there's nothing in the write buffer, then that means 11730 // that nothing more will ever be provided 11731 var ws = stream._writableState; 11732 var ts = stream._transformState; 11733 11734 if (ws.length) throw new Error('Calling transform done when ws.length != 0'); 11735 11736 if (ts.transforming) throw new Error('Calling transform done when still transforming'); 11737 11738 return stream.push(null); 11739} 11740},{"12":12,"25":25,"31":31}],35:[function(_dereq_,module,exports){ 11741(function (process,global){ 11742// Copyright Joyent, Inc. and other Node contributors. 11743// 11744// Permission is hereby granted, free of charge, to any person obtaining a 11745// copy of this software and associated documentation files (the 11746// "Software"), to deal in the Software without restriction, including 11747// without limitation the rights to use, copy, modify, merge, publish, 11748// distribute, sublicense, and/or sell copies of the Software, and to permit 11749// persons to whom the Software is furnished to do so, subject to the 11750// following conditions: 11751// 11752// The above copyright notice and this permission notice shall be included 11753// in all copies or substantial portions of the Software. 11754// 11755// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 11756// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 11757// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 11758// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 11759// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 11760// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 11761// USE OR OTHER DEALINGS IN THE SOFTWARE. 11762 11763// A bit simpler than readable streams. 11764// Implement an async ._write(chunk, encoding, cb), and it'll handle all 11765// the drain event emission and buffering. 11766 11767'use strict'; 11768 11769/*<replacement>*/ 11770 11771var processNextTick = _dereq_(28); 11772/*</replacement>*/ 11773 11774module.exports = Writable; 11775 11776/* <replacement> */ 11777function WriteReq(chunk, encoding, cb) { 11778 this.chunk = chunk; 11779 this.encoding = encoding; 11780 this.callback = cb; 11781 this.next = null; 11782} 11783 11784// It seems a linked list but it is not 11785// there will be only 2 of these for each stream 11786function CorkedRequest(state) { 11787 var _this = this; 11788 11789 this.next = null; 11790 this.entry = null; 11791 this.finish = function () { 11792 onCorkedFinish(_this, state); 11793 }; 11794} 11795/* </replacement> */ 11796 11797/*<replacement>*/ 11798var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; 11799/*</replacement>*/ 11800 11801/*<replacement>*/ 11802var Duplex; 11803/*</replacement>*/ 11804 11805Writable.WritableState = WritableState; 11806 11807/*<replacement>*/ 11808var util = _dereq_(12); 11809util.inherits = _dereq_(25); 11810/*</replacement>*/ 11811 11812/*<replacement>*/ 11813var internalUtil = { 11814 deprecate: _dereq_(48) 11815}; 11816/*</replacement>*/ 11817 11818/*<replacement>*/ 11819var Stream = _dereq_(38); 11820/*</replacement>*/ 11821 11822/*<replacement>*/ 11823var Buffer = _dereq_(44).Buffer; 11824var OurUint8Array = global.Uint8Array || function () {}; 11825function _uint8ArrayToBuffer(chunk) { 11826 return Buffer.from(chunk); 11827} 11828function _isUint8Array(obj) { 11829 return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; 11830} 11831/*</replacement>*/ 11832 11833var destroyImpl = _dereq_(37); 11834 11835util.inherits(Writable, Stream); 11836 11837function nop() {} 11838 11839function WritableState(options, stream) { 11840 Duplex = Duplex || _dereq_(31); 11841 11842 options = options || {}; 11843 11844 // object stream flag to indicate whether or not this stream 11845 // contains buffers or objects. 11846 this.objectMode = !!options.objectMode; 11847 11848 if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; 11849 11850 // the point at which write() starts returning false 11851 // Note: 0 is a valid value, means that we always return false if 11852 // the entire buffer is not flushed immediately on write() 11853 var hwm = options.highWaterMark; 11854 var defaultHwm = this.objectMode ? 16 : 16 * 1024; 11855 this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; 11856 11857 // cast to ints. 11858 this.highWaterMark = Math.floor(this.highWaterMark); 11859 11860 // if _final has been called 11861 this.finalCalled = false; 11862 11863 // drain event flag. 11864 this.needDrain = false; 11865 // at the start of calling end() 11866 this.ending = false; 11867 // when end() has been called, and returned 11868 this.ended = false; 11869 // when 'finish' is emitted 11870 this.finished = false; 11871 11872 // has it been destroyed 11873 this.destroyed = false; 11874 11875 // should we decode strings into buffers before passing to _write? 11876 // this is here so that some node-core streams can optimize string 11877 // handling at a lower level. 11878 var noDecode = options.decodeStrings === false; 11879 this.decodeStrings = !noDecode; 11880 11881 // Crypto is kind of old and crusty. Historically, its default string 11882 // encoding is 'binary' so we have to make this configurable. 11883 // Everything else in the universe uses 'utf8', though. 11884 this.defaultEncoding = options.defaultEncoding || 'utf8'; 11885 11886 // not an actual buffer we keep track of, but a measurement 11887 // of how much we're waiting to get pushed to some underlying 11888 // socket or file. 11889 this.length = 0; 11890 11891 // a flag to see when we're in the middle of a write. 11892 this.writing = false; 11893 11894 // when true all writes will be buffered until .uncork() call 11895 this.corked = 0; 11896 11897 // a flag to be able to tell if the onwrite cb is called immediately, 11898 // or on a later tick. We set this to true at first, because any 11899 // actions that shouldn't happen until "later" should generally also 11900 // not happen before the first write call. 11901 this.sync = true; 11902 11903 // a flag to know if we're processing previously buffered items, which 11904 // may call the _write() callback in the same tick, so that we don't 11905 // end up in an overlapped onwrite situation. 11906 this.bufferProcessing = false; 11907 11908 // the callback that's passed to _write(chunk,cb) 11909 this.onwrite = function (er) { 11910 onwrite(stream, er); 11911 }; 11912 11913 // the callback that the user supplies to write(chunk,encoding,cb) 11914 this.writecb = null; 11915 11916 // the amount that is being written when _write is called. 11917 this.writelen = 0; 11918 11919 this.bufferedRequest = null; 11920 this.lastBufferedRequest = null; 11921 11922 // number of pending user-supplied write callbacks 11923 // this must be 0 before 'finish' can be emitted 11924 this.pendingcb = 0; 11925 11926 // emit prefinish if the only thing we're waiting for is _write cbs 11927 // This is relevant for synchronous Transform streams 11928 this.prefinished = false; 11929 11930 // True if the error was already emitted and should not be thrown again 11931 this.errorEmitted = false; 11932 11933 // count buffered requests 11934 this.bufferedRequestCount = 0; 11935 11936 // allocate the first CorkedRequest, there is always 11937 // one allocated and free to use, and we maintain at most two 11938 this.corkedRequestsFree = new CorkedRequest(this); 11939} 11940 11941WritableState.prototype.getBuffer = function getBuffer() { 11942 var current = this.bufferedRequest; 11943 var out = []; 11944 while (current) { 11945 out.push(current); 11946 current = current.next; 11947 } 11948 return out; 11949}; 11950 11951(function () { 11952 try { 11953 Object.defineProperty(WritableState.prototype, 'buffer', { 11954 get: internalUtil.deprecate(function () { 11955 return this.getBuffer(); 11956 }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') 11957 }); 11958 } catch (_) {} 11959})(); 11960 11961// Test _writableState for inheritance to account for Duplex streams, 11962// whose prototype chain only points to Readable. 11963var realHasInstance; 11964if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { 11965 realHasInstance = Function.prototype[Symbol.hasInstance]; 11966 Object.defineProperty(Writable, Symbol.hasInstance, { 11967 value: function (object) { 11968 if (realHasInstance.call(this, object)) return true; 11969 11970 return object && object._writableState instanceof WritableState; 11971 } 11972 }); 11973} else { 11974 realHasInstance = function (object) { 11975 return object instanceof this; 11976 }; 11977} 11978 11979function Writable(options) { 11980 Duplex = Duplex || _dereq_(31); 11981 11982 // Writable ctor is applied to Duplexes, too. 11983 // `realHasInstance` is necessary because using plain `instanceof` 11984 // would return false, as no `_writableState` property is attached. 11985 11986 // Trying to use the custom `instanceof` for Writable here will also break the 11987 // Node.js LazyTransform implementation, which has a non-trivial getter for 11988 // `_writableState` that would lead to infinite recursion. 11989 if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { 11990 return new Writable(options); 11991 } 11992 11993 this._writableState = new WritableState(options, this); 11994 11995 // legacy. 11996 this.writable = true; 11997 11998 if (options) { 11999 if (typeof options.write === 'function') this._write = options.write; 12000 12001 if (typeof options.writev === 'function') this._writev = options.writev; 12002 12003 if (typeof options.destroy === 'function') this._destroy = options.destroy; 12004 12005 if (typeof options.final === 'function') this._final = options.final; 12006 } 12007 12008 Stream.call(this); 12009} 12010 12011// Otherwise people can pipe Writable streams, which is just wrong. 12012Writable.prototype.pipe = function () { 12013 this.emit('error', new Error('Cannot pipe, not readable')); 12014}; 12015 12016function writeAfterEnd(stream, cb) { 12017 var er = new Error('write after end'); 12018 // TODO: defer error events consistently everywhere, not just the cb 12019 stream.emit('error', er); 12020 processNextTick(cb, er); 12021} 12022 12023// Checks that a user-supplied chunk is valid, especially for the particular 12024// mode the stream is in. Currently this means that `null` is never accepted 12025// and undefined/non-string values are only allowed in object mode. 12026function validChunk(stream, state, chunk, cb) { 12027 var valid = true; 12028 var er = false; 12029 12030 if (chunk === null) { 12031 er = new TypeError('May not write null values to stream'); 12032 } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { 12033 er = new TypeError('Invalid non-string/buffer chunk'); 12034 } 12035 if (er) { 12036 stream.emit('error', er); 12037 processNextTick(cb, er); 12038 valid = false; 12039 } 12040 return valid; 12041} 12042 12043Writable.prototype.write = function (chunk, encoding, cb) { 12044 var state = this._writableState; 12045 var ret = false; 12046 var isBuf = _isUint8Array(chunk) && !state.objectMode; 12047 12048 if (isBuf && !Buffer.isBuffer(chunk)) { 12049 chunk = _uint8ArrayToBuffer(chunk); 12050 } 12051 12052 if (typeof encoding === 'function') { 12053 cb = encoding; 12054 encoding = null; 12055 } 12056 12057 if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; 12058 12059 if (typeof cb !== 'function') cb = nop; 12060 12061 if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { 12062 state.pendingcb++; 12063 ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); 12064 } 12065 12066 return ret; 12067}; 12068 12069Writable.prototype.cork = function () { 12070 var state = this._writableState; 12071 12072 state.corked++; 12073}; 12074 12075Writable.prototype.uncork = function () { 12076 var state = this._writableState; 12077 12078 if (state.corked) { 12079 state.corked--; 12080 12081 if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); 12082 } 12083}; 12084 12085Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { 12086 // node::ParseEncoding() requires lower case. 12087 if (typeof encoding === 'string') encoding = encoding.toLowerCase(); 12088 if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); 12089 this._writableState.defaultEncoding = encoding; 12090 return this; 12091}; 12092 12093function decodeChunk(state, chunk, encoding) { 12094 if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { 12095 chunk = Buffer.from(chunk, encoding); 12096 } 12097 return chunk; 12098} 12099 12100// if we're already writing something, then just put this 12101// in the queue, and wait our turn. Otherwise, call _write 12102// If we return false, then we need a drain event, so set that flag. 12103function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { 12104 if (!isBuf) { 12105 var newChunk = decodeChunk(state, chunk, encoding); 12106 if (chunk !== newChunk) { 12107 isBuf = true; 12108 encoding = 'buffer'; 12109 chunk = newChunk; 12110 } 12111 } 12112 var len = state.objectMode ? 1 : chunk.length; 12113 12114 state.length += len; 12115 12116 var ret = state.length < state.highWaterMark; 12117 // we must ensure that previous needDrain will not be reset to false. 12118 if (!ret) state.needDrain = true; 12119 12120 if (state.writing || state.corked) { 12121 var last = state.lastBufferedRequest; 12122 state.lastBufferedRequest = { 12123 chunk: chunk, 12124 encoding: encoding, 12125 isBuf: isBuf, 12126 callback: cb, 12127 next: null 12128 }; 12129 if (last) { 12130 last.next = state.lastBufferedRequest; 12131 } else { 12132 state.bufferedRequest = state.lastBufferedRequest; 12133 } 12134 state.bufferedRequestCount += 1; 12135 } else { 12136 doWrite(stream, state, false, len, chunk, encoding, cb); 12137 } 12138 12139 return ret; 12140} 12141 12142function doWrite(stream, state, writev, len, chunk, encoding, cb) { 12143 state.writelen = len; 12144 state.writecb = cb; 12145 state.writing = true; 12146 state.sync = true; 12147 if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); 12148 state.sync = false; 12149} 12150 12151function onwriteError(stream, state, sync, er, cb) { 12152 --state.pendingcb; 12153 12154 if (sync) { 12155 // defer the callback if we are being called synchronously 12156 // to avoid piling up things on the stack 12157 processNextTick(cb, er); 12158 // this can emit finish, and it will always happen 12159 // after error 12160 processNextTick(finishMaybe, stream, state); 12161 stream._writableState.errorEmitted = true; 12162 stream.emit('error', er); 12163 } else { 12164 // the caller expect this to happen before if 12165 // it is async 12166 cb(er); 12167 stream._writableState.errorEmitted = true; 12168 stream.emit('error', er); 12169 // this can emit finish, but finish must 12170 // always follow error 12171 finishMaybe(stream, state); 12172 } 12173} 12174 12175function onwriteStateUpdate(state) { 12176 state.writing = false; 12177 state.writecb = null; 12178 state.length -= state.writelen; 12179 state.writelen = 0; 12180} 12181 12182function onwrite(stream, er) { 12183 var state = stream._writableState; 12184 var sync = state.sync; 12185 var cb = state.writecb; 12186 12187 onwriteStateUpdate(state); 12188 12189 if (er) onwriteError(stream, state, sync, er, cb);else { 12190 // Check if we're actually ready to finish, but don't emit yet 12191 var finished = needFinish(state); 12192 12193 if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { 12194 clearBuffer(stream, state); 12195 } 12196 12197 if (sync) { 12198 /*<replacement>*/ 12199 asyncWrite(afterWrite, stream, state, finished, cb); 12200 /*</replacement>*/ 12201 } else { 12202 afterWrite(stream, state, finished, cb); 12203 } 12204 } 12205} 12206 12207function afterWrite(stream, state, finished, cb) { 12208 if (!finished) onwriteDrain(stream, state); 12209 state.pendingcb--; 12210 cb(); 12211 finishMaybe(stream, state); 12212} 12213 12214// Must force callback to be called on nextTick, so that we don't 12215// emit 'drain' before the write() consumer gets the 'false' return 12216// value, and has a chance to attach a 'drain' listener. 12217function onwriteDrain(stream, state) { 12218 if (state.length === 0 && state.needDrain) { 12219 state.needDrain = false; 12220 stream.emit('drain'); 12221 } 12222} 12223 12224// if there's something in the buffer waiting, then process it 12225function clearBuffer(stream, state) { 12226 state.bufferProcessing = true; 12227 var entry = state.bufferedRequest; 12228 12229 if (stream._writev && entry && entry.next) { 12230 // Fast case, write everything using _writev() 12231 var l = state.bufferedRequestCount; 12232 var buffer = new Array(l); 12233 var holder = state.corkedRequestsFree; 12234 holder.entry = entry; 12235 12236 var count = 0; 12237 var allBuffers = true; 12238 while (entry) { 12239 buffer[count] = entry; 12240 if (!entry.isBuf) allBuffers = false; 12241 entry = entry.next; 12242 count += 1; 12243 } 12244 buffer.allBuffers = allBuffers; 12245 12246 doWrite(stream, state, true, state.length, buffer, '', holder.finish); 12247 12248 // doWrite is almost always async, defer these to save a bit of time 12249 // as the hot path ends with doWrite 12250 state.pendingcb++; 12251 state.lastBufferedRequest = null; 12252 if (holder.next) { 12253 state.corkedRequestsFree = holder.next; 12254 holder.next = null; 12255 } else { 12256 state.corkedRequestsFree = new CorkedRequest(state); 12257 } 12258 } else { 12259 // Slow case, write chunks one-by-one 12260 while (entry) { 12261 var chunk = entry.chunk; 12262 var encoding = entry.encoding; 12263 var cb = entry.callback; 12264 var len = state.objectMode ? 1 : chunk.length; 12265 12266 doWrite(stream, state, false, len, chunk, encoding, cb); 12267 entry = entry.next; 12268 // if we didn't call the onwrite immediately, then 12269 // it means that we need to wait until it does. 12270 // also, that means that the chunk and cb are currently 12271 // being processed, so move the buffer counter past them. 12272 if (state.writing) { 12273 break; 12274 } 12275 } 12276 12277 if (entry === null) state.lastBufferedRequest = null; 12278 } 12279 12280 state.bufferedRequestCount = 0; 12281 state.bufferedRequest = entry; 12282 state.bufferProcessing = false; 12283} 12284 12285Writable.prototype._write = function (chunk, encoding, cb) { 12286 cb(new Error('_write() is not implemented')); 12287}; 12288 12289Writable.prototype._writev = null; 12290 12291Writable.prototype.end = function (chunk, encoding, cb) { 12292 var state = this._writableState; 12293 12294 if (typeof chunk === 'function') { 12295 cb = chunk; 12296 chunk = null; 12297 encoding = null; 12298 } else if (typeof encoding === 'function') { 12299 cb = encoding; 12300 encoding = null; 12301 } 12302 12303 if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); 12304 12305 // .end() fully uncorks 12306 if (state.corked) { 12307 state.corked = 1; 12308 this.uncork(); 12309 } 12310 12311 // ignore unnecessary end() calls. 12312 if (!state.ending && !state.finished) endWritable(this, state, cb); 12313}; 12314 12315function needFinish(state) { 12316 return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; 12317} 12318function callFinal(stream, state) { 12319 stream._final(function (err) { 12320 state.pendingcb--; 12321 if (err) { 12322 stream.emit('error', err); 12323 } 12324 state.prefinished = true; 12325 stream.emit('prefinish'); 12326 finishMaybe(stream, state); 12327 }); 12328} 12329function prefinish(stream, state) { 12330 if (!state.prefinished && !state.finalCalled) { 12331 if (typeof stream._final === 'function') { 12332 state.pendingcb++; 12333 state.finalCalled = true; 12334 processNextTick(callFinal, stream, state); 12335 } else { 12336 state.prefinished = true; 12337 stream.emit('prefinish'); 12338 } 12339 } 12340} 12341 12342function finishMaybe(stream, state) { 12343 var need = needFinish(state); 12344 if (need) { 12345 prefinish(stream, state); 12346 if (state.pendingcb === 0) { 12347 state.finished = true; 12348 stream.emit('finish'); 12349 } 12350 } 12351 return need; 12352} 12353 12354function endWritable(stream, state, cb) { 12355 state.ending = true; 12356 finishMaybe(stream, state); 12357 if (cb) { 12358 if (state.finished) processNextTick(cb);else stream.once('finish', cb); 12359 } 12360 state.ended = true; 12361 stream.writable = false; 12362} 12363 12364function onCorkedFinish(corkReq, state, err) { 12365 var entry = corkReq.entry; 12366 corkReq.entry = null; 12367 while (entry) { 12368 var cb = entry.callback; 12369 state.pendingcb--; 12370 cb(err); 12371 entry = entry.next; 12372 } 12373 if (state.corkedRequestsFree) { 12374 state.corkedRequestsFree.next = corkReq; 12375 } else { 12376 state.corkedRequestsFree = corkReq; 12377 } 12378} 12379 12380Object.defineProperty(Writable.prototype, 'destroyed', { 12381 get: function () { 12382 if (this._writableState === undefined) { 12383 return false; 12384 } 12385 return this._writableState.destroyed; 12386 }, 12387 set: function (value) { 12388 // we ignore the value if the stream 12389 // has not been initialized yet 12390 if (!this._writableState) { 12391 return; 12392 } 12393 12394 // backward compatibility, the user is explicitly 12395 // managing destroyed 12396 this._writableState.destroyed = value; 12397 } 12398}); 12399 12400Writable.prototype.destroy = destroyImpl.destroy; 12401Writable.prototype._undestroy = destroyImpl.undestroy; 12402Writable.prototype._destroy = function (err, cb) { 12403 this.end(); 12404 cb(err); 12405};
vendor: 2,326 bytes, lines 12406-12490
12406}).call(this,_dereq_(29),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 12407 12408},{"12":12,"25":25,"28":28,"29":29,"31":31,"37":37,"38":38,"44":44,"48":48}],36:[function(_dereq_,module,exports){ 12409'use strict'; 12410 12411/*<replacement>*/ 12412 12413function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 12414 12415var Buffer = _dereq_(44).Buffer; 12416/*</replacement>*/ 12417 12418function copyBuffer(src, target, offset) { 12419 src.copy(target, offset); 12420} 12421 12422module.exports = function () { 12423 function BufferList() { 12424 _classCallCheck(this, BufferList); 12425 12426 this.head = null; 12427 this.tail = null; 12428 this.length = 0; 12429 } 12430 12431 BufferList.prototype.push = function push(v) { 12432 var entry = { data: v, next: null }; 12433 if (this.length > 0) this.tail.next = entry;else this.head = entry; 12434 this.tail = entry; 12435 ++this.length; 12436 }; 12437 12438 BufferList.prototype.unshift = function unshift(v) { 12439 var entry = { data: v, next: this.head }; 12440 if (this.length === 0) this.tail = entry; 12441 this.head = entry; 12442 ++this.length; 12443 }; 12444 12445 BufferList.prototype.shift = function shift() { 12446 if (this.length === 0) return; 12447 var ret = this.head.data; 12448 if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; 12449 --this.length; 12450 return ret; 12451 }; 12452 12453 BufferList.prototype.clear = function clear() { 12454 this.head = this.tail = null; 12455 this.length = 0; 12456 }; 12457 12458 BufferList.prototype.join = function join(s) { 12459 if (this.length === 0) return ''; 12460 var p = this.head; 12461 var ret = '' + p.data; 12462 while (p = p.next) { 12463 ret += s + p.data; 12464 }return ret; 12465 }; 12466 12467 BufferList.prototype.concat = function concat(n) { 12468 if (this.length === 0) return Buffer.alloc(0); 12469 if (this.length === 1) return this.head.data; 12470 var ret = Buffer.allocUnsafe(n >>> 0); 12471 var p = this.head; 12472 var i = 0; 12473 while (p) { 12474 copyBuffer(p.data, ret, i); 12475 i += p.data.length; 12476 p = p.next; 12477 } 12478 return ret; 12479 }; 12480 12481 return BufferList; 12482}(); 12483},{"44":44}],37:[function(_dereq_,module,exports){ 12484'use strict'; 12485 12486/*<replacement>*/ 12487 12488var processNextTick = _dereq_(28); 12489/*</replacement>*/ 12490
12491// undocumented cb() API, needed for core, not for public API 12492function destroy(err, cb) { 12493 var _this = this; 12494 12495 var readableDestroyed = this._readableState && this._readableState.destroyed; 12496 var writableDestroyed = this._writableState && this._writableState.destroyed; 12497 12498 if (readableDestroyed || writableDestroyed) { 12499 if (cb) { 12500 cb(err); 12501 } else if (err && (!this._writableState || !this._writableState.errorEmitted)) { 12502 processNextTick(emitErrorNT, this, err); 12503 } 12504 return; 12505 } 12506 12507 // we set destroyed to true before firing error callbacks in order 12508 // to make it re-entrance safe in case destroy() is called within callbacks 12509 12510 if (this._readableState) { 12511 this._readableState.destroyed = true; 12512 } 12513 12514 // if this is a duplex stream mark the writable part as destroyed as well 12515 if (this._writableState) { 12516 this._writableState.destroyed = true; 12517 } 12518 12519 this._destroy(err || null, function (err) { 12520 if (!cb && err) { 12521 processNextTick(emitErrorNT, _this, err); 12522 if (_this._writableState) { 12523 _this._writableState.errorEmitted = true; 12524 } 12525 } else if (cb) { 12526 cb(err); 12527 } 12528 }); 12529} 12530 12531function undestroy() { 12532 if (this._readableState) { 12533 this._readableState.destroyed = false; 12534 this._readableState.reading = false; 12535 this._readableState.ended = false; 12536 this._readableState.endEmitted = false; 12537 } 12538 12539 if (this._writableState) { 12540 this._writableState.destroyed = false; 12541 this._writableState.ended = false; 12542 this._writableState.ending = false; 12543 this._writableState.finished = false; 12544 this._writableState.errorEmitted = false; 12545 } 12546} 12547 12548function emitErrorNT(self, err) { 12549 self.emit('error', err); 12550} 12551 12552module.exports = { 12553 destroy: destroy, 12554 undestroy: undestroy 12555}; 12556},{"28":28}],38:[function(_dereq_,module,exports){ 12557module.exports = _dereq_(16).EventEmitter; 12558 12559},{"16":16}],39:[function(_dereq_,module,exports){ 12560module.exports = _dereq_(40).PassThrough 12561 12562},{"40":40}],40:[function(_dereq_,module,exports){ 12563exports = module.exports = _dereq_(33); 12564exports.Stream = exports; 12565exports.Readable = exports; 12566exports.Writable = _dereq_(35); 12567exports.Duplex = _dereq_(31); 12568exports.Transform = _dereq_(34); 12569exports.PassThrough = _dereq_(32); 12570 12571},{"31":31,"32":32,"33":33,"34":34,"35":35}],41:[function(_dereq_,module,exports){ 12572module.exports = _dereq_(40).Transform 12573 12574},{"40":40}],42:[function(_dereq_,module,exports){ 12575module.exports = _dereq_(35); 12576 12577},{"35":35}],43:[function(_dereq_,module,exports){ 12578/** 12579 * Decimal adjustment of a number. 12580 * 12581 * @param {String} type The type of adjustment. 12582 * @param {Number} value The number. 12583 * @param {Integer} exp The exponent (the 10 logarithm of the adjustment base). 12584 * @returns {Number} The adjusted value. 12585 */ 12586var decimalAdjust = exports.decimalAdjust = function(type, value, exp) { 12587 // If the exp is undefined or zero... 12588 if (typeof exp === 'undefined' || +exp === 0) { 12589 return Math[type](value); 12590 } 12591 value = +value; 12592 exp = +exp; 12593 // If the value is not a number or the exp is not an integer... 12594 if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) { 12595 return NaN; 12596 } 12597 // Shift 12598 value = value.toString().split('e'); 12599 value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))); 12600 // Shift back 12601 value = value.toString().split('e'); 12602 return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)); 12603} 12604 12605module.exports = { 12606 round10: function(value, exp) { 12607 return decimalAdjust('round', value, exp); 12608 }, 12609 floor10: function(value, exp) { 12610 return decimalAdjust('floor', value, exp); 12611 }, 12612 ceil10: function(value, exp) { 12613 return decimalAdjust('ceil', value, exp); 12614 }, 12615}; 12616 12617module.exports.polyfill = function() { 12618 // Decimal round 12619 if (!Math.round10) { 12620 Math.round10 = module.exports.round10; 12621 } 12622 // Decimal floor 12623 if (!Math.floor10) { 12624 Math.floor10 = module.exports.floor10; 12625 } 12626 // Decimal ceil 12627 if (!Math.ceil10) { 12628 Math.ceil10 = module.exports.ceil10; 12629 } 12630}; 12631 12632},{}],44:[function(_dereq_,module,exports){ 12633/* eslint-disable node/no-deprecated-api */ 12634var buffer = _dereq_(10) 12635var Buffer = buffer.Buffer 12636 12637// alternative to using Object.keys for old browsers 12638function copyProps (src, dst) { 12639 for (var key in src) { 12640 dst[key] = src[key] 12641 } 12642} 12643if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { 12644 module.exports = buffer 12645} else { 12646 // Copy properties from require('buffer')
vendor: 11,261 bytes, lines 12647-13016
12647 copyProps(buffer, exports) 12648 exports.Buffer = SafeBuffer 12649} 12650 12651function SafeBuffer (arg, encodingOrOffset, length) { 12652 return Buffer(arg, encodingOrOffset, length) 12653} 12654 12655// Copy static methods from Buffer 12656copyProps(Buffer, SafeBuffer) 12657 12658SafeBuffer.from = function (arg, encodingOrOffset, length) { 12659 if (typeof arg === 'number') { 12660 throw new TypeError('Argument must not be a number') 12661 } 12662 return Buffer(arg, encodingOrOffset, length) 12663} 12664 12665SafeBuffer.alloc = function (size, fill, encoding) { 12666 if (typeof size !== 'number') { 12667 throw new TypeError('Argument must be a number') 12668 } 12669 var buf = Buffer(size) 12670 if (fill !== undefined) { 12671 if (typeof encoding === 'string') { 12672 buf.fill(fill, encoding) 12673 } else { 12674 buf.fill(fill) 12675 } 12676 } else { 12677 buf.fill(0) 12678 } 12679 return buf 12680} 12681 12682SafeBuffer.allocUnsafe = function (size) { 12683 if (typeof size !== 'number') { 12684 throw new TypeError('Argument must be a number') 12685 } 12686 return Buffer(size) 12687} 12688 12689SafeBuffer.allocUnsafeSlow = function (size) { 12690 if (typeof size !== 'number') { 12691 throw new TypeError('Argument must be a number') 12692 } 12693 return buffer.SlowBuffer(size) 12694} 12695 12696},{"10":10}],45:[function(_dereq_,module,exports){ 12697(function (Buffer){ 12698;(function (sax) { // wrapper for non-node envs 12699 sax.parser = function (strict, opt) { return new SAXParser(strict, opt) } 12700 sax.SAXParser = SAXParser 12701 sax.SAXStream = SAXStream 12702 sax.createStream = createStream 12703 12704 // When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns. 12705 // When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)), 12706 // since that's the earliest that a buffer overrun could occur. This way, checks are 12707 // as rare as required, but as often as necessary to ensure never crossing this bound. 12708 // Furthermore, buffers are only tested at most once per write(), so passing a very 12709 // large string into write() might have undesirable effects, but this is manageable by 12710 // the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme 12711 // edge case, result in creating at most one complete copy of the string passed in. 12712 // Set to Infinity to have unlimited buffers. 12713 sax.MAX_BUFFER_LENGTH = 64 * 1024 12714 12715 var buffers = [ 12716 'comment', 'sgmlDecl', 'textNode', 'tagName', 'doctype', 12717 'procInstName', 'procInstBody', 'entity', 'attribName', 12718 'attribValue', 'cdata', 'script' 12719 ] 12720 12721 sax.EVENTS = [ 12722 'text', 12723 'processinginstruction', 12724 'sgmldeclaration', 12725 'doctype', 12726 'comment', 12727 'opentagstart', 12728 'attribute', 12729 'opentag', 12730 'closetag', 12731 'opencdata', 12732 'cdata', 12733 'closecdata', 12734 'error', 12735 'end', 12736 'ready', 12737 'script', 12738 'opennamespace', 12739 'closenamespace' 12740 ] 12741 12742 function SAXParser (strict, opt) { 12743 if (!(this instanceof SAXParser)) { 12744 return new SAXParser(strict, opt) 12745 } 12746 12747 var parser = this 12748 clearBuffers(parser) 12749 parser.q = parser.c = '' 12750 parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH 12751 parser.opt = opt || {} 12752 parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags 12753 parser.looseCase = parser.opt.lowercase ? 'toLowerCase' : 'toUpperCase' 12754 parser.tags = [] 12755 parser.closed = parser.closedRoot = parser.sawRoot = false 12756 parser.tag = parser.error = null 12757 parser.strict = !!strict 12758 parser.noscript = !!(strict || parser.opt.noscript) 12759 parser.state = S.BEGIN 12760 parser.strictEntities = parser.opt.strictEntities 12761 parser.ENTITIES = parser.strictEntities ? Object.create(sax.XML_ENTITIES) : Object.create(sax.ENTITIES) 12762 parser.attribList = [] 12763 12764 // namespaces form a prototype chain. 12765 // it always points at the current tag, 12766 // which protos to its parent tag. 12767 if (parser.opt.xmlns) { 12768 parser.ns = Object.create(rootNS) 12769 } 12770 12771 // mostly just for error reporting 12772 parser.trackPosition = parser.opt.position !== false 12773 if (parser.trackPosition) { 12774 parser.position = parser.line = parser.column = 0 12775 } 12776 emit(parser, 'onready') 12777 } 12778 12779 if (!Object.create) { 12780 Object.create = function (o) { 12781 function F () {} 12782 F.prototype = o 12783 var newf = new F() 12784 return newf 12785 } 12786 } 12787 12788 if (!Object.keys) { 12789 Object.keys = function (o) { 12790 var a = [] 12791 for (var i in o) if (o.hasOwnProperty(i)) a.push(i) 12792 return a 12793 } 12794 } 12795 12796 function checkBufferLength (parser) { 12797 var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10) 12798 var maxActual = 0 12799 for (var i = 0, l = buffers.length; i < l; i++) { 12800 var len = parser[buffers[i]].length 12801 if (len > maxAllowed) { 12802 // Text/cdata nodes can get big, and since they're buffered, 12803 // we can get here under normal conditions. 12804 // Avoid issues by emitting the text node now, 12805 // so at least it won't get any bigger. 12806 switch (buffers[i]) { 12807 case 'textNode': 12808 closeText(parser) 12809 break 12810 12811 case 'cdata': 12812 emitNode(parser, 'oncdata', parser.cdata) 12813 parser.cdata = '' 12814 break 12815 12816 case 'script': 12817 emitNode(parser, 'onscript', parser.script) 12818 parser.script = '' 12819 break 12820 12821 default: 12822 error(parser, 'Max buffer length exceeded: ' + buffers[i]) 12823 } 12824 } 12825 maxActual = Math.max(maxActual, len) 12826 } 12827 // schedule the next check for the earliest possible buffer overrun. 12828 var m = sax.MAX_BUFFER_LENGTH - maxActual 12829 parser.bufferCheckPosition = m + parser.position 12830 } 12831 12832 function clearBuffers (parser) { 12833 for (var i = 0, l = buffers.length; i < l; i++) { 12834 parser[buffers[i]] = '' 12835 } 12836 } 12837 12838 function flushBuffers (parser) { 12839 closeText(parser) 12840 if (parser.cdata !== '') { 12841 emitNode(parser, 'oncdata', parser.cdata) 12842 parser.cdata = '' 12843 } 12844 if (parser.script !== '') { 12845 emitNode(parser, 'onscript', parser.script) 12846 parser.script = '' 12847 } 12848 } 12849 12850 SAXParser.prototype = { 12851 end: function () { end(this) }, 12852 write: write, 12853 resume: function () { this.error = null; return this }, 12854 close: function () { return this.write(null) }, 12855 flush: function () { flushBuffers(this) } 12856 } 12857 12858 var Stream 12859 try { 12860 Stream = _dereq_(46).Stream 12861 } catch (ex) { 12862 Stream = function () {} 12863 } 12864 12865 var streamWraps = sax.EVENTS.filter(function (ev) { 12866 return ev !== 'error' && ev !== 'end' 12867 }) 12868 12869 function createStream (strict, opt) { 12870 return new SAXStream(strict, opt) 12871 } 12872 12873 function SAXStream (strict, opt) { 12874 if (!(this instanceof SAXStream)) { 12875 return new SAXStream(strict, opt) 12876 } 12877 12878 Stream.apply(this) 12879 12880 this._parser = new SAXParser(strict, opt) 12881 this.writable = true 12882 this.readable = true 12883 12884 var me = this 12885 12886 this._parser.onend = function () { 12887 me.emit('end') 12888 } 12889 12890 this._parser.onerror = function (er) { 12891 me.emit('error', er) 12892 12893 // if didn't throw, then means error was handled. 12894 // go ahead and clear error, so we can write again. 12895 me._parser.error = null 12896 } 12897 12898 this._decoder = null 12899 12900 streamWraps.forEach(function (ev) { 12901 Object.defineProperty(me, 'on' + ev, { 12902 get: function () { 12903 return me._parser['on' + ev] 12904 }, 12905 set: function (h) { 12906 if (!h) { 12907 me.removeAllListeners(ev) 12908 me._parser['on' + ev] = h 12909 return h 12910 } 12911 me.on(ev, h) 12912 }, 12913 enumerable: true, 12914 configurable: false 12915 }) 12916 }) 12917 } 12918 12919 SAXStream.prototype = Object.create(Stream.prototype, { 12920 constructor: { 12921 value: SAXStream 12922 } 12923 }) 12924 12925 SAXStream.prototype.write = function (data) { 12926 if (typeof Buffer === 'function' && 12927 typeof Buffer.isBuffer === 'function' && 12928 Buffer.isBuffer(data)) { 12929 if (!this._decoder) { 12930 var SD = _dereq_(9).StringDecoder 12931 this._decoder = new SD('utf8') 12932 } 12933 data = this._decoder.write(data) 12934 } 12935 12936 this._parser.write(data.toString()) 12937 this.emit('data', data) 12938 return true 12939 } 12940 12941 SAXStream.prototype.end = function (chunk) { 12942 if (chunk && chunk.length) { 12943 this.write(chunk) 12944 } 12945 this._parser.end() 12946 return true 12947 } 12948 12949 SAXStream.prototype.on = function (ev, handler) { 12950 var me = this 12951 if (!me._parser['on' + ev] && streamWraps.indexOf(ev) !== -1) { 12952 me._parser['on' + ev] = function () { 12953 var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments) 12954 args.splice(0, 0, ev) 12955 me.emit.apply(me, args) 12956 } 12957 } 12958 12959 return Stream.prototype.on.call(me, ev, handler) 12960 } 12961 12962 // character classes and tokens 12963 var whitespace = '\r\n\t ' 12964 12965 // this really needs to be replaced with character classes. 12966 // XML allows all manner of ridiculous numbers and digits. 12967 var number = '0124356789' 12968 var letter = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 12969 12970 // (Letter | "_" | ":") 12971 var quote = '\'"' 12972 var attribEnd = whitespace + '>' 12973 var CDATA = '[CDATA[' 12974 var DOCTYPE = 'DOCTYPE' 12975 var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace' 12976 var XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/' 12977 var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE } 12978 12979 // turn all the string character sets into character class objects. 12980 whitespace = charClass(whitespace) 12981 number = charClass(number) 12982 letter = charClass(letter) 12983 12984 // http://www.w3.org/TR/REC-xml/#NT-NameStartChar 12985 // This implementation works on strings, a single character at a time 12986 // as such, it cannot ever support astral-plane characters (10000-EFFFF) 12987 // without a significant breaking change to either this parser, or the 12988 // JavaScript language. Implementation of an emoji-capable xml parser 12989 // is left as an exercise for the reader. 12990 var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/ 12991 12992 var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040\.\d-]/ 12993 12994 var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/ 12995 var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040\.\d-]/ 12996 12997 quote = charClass(quote) 12998 attribEnd = charClass(attribEnd) 12999 13000 function charClass (str) { 13001 return str.split('').reduce(function (s, c) { 13002 s[c] = true 13003 return s 13004 }, {}) 13005 } 13006 13007 function isRegExp (c) { 13008 return Object.prototype.toString.call(c) === '[object RegExp]' 13009 } 13010 13011 function is (charclass, c) { 13012 return isRegExp(charclass) ? !!c.match(charclass) : charclass[c] 13013 } 13014 13015 function not (charclass, c) { 13016 return !is(charclass
vendor: 16,337 bytes, lines 13016-13649
13016, c) 13017 } 13018 13019 var S = 0 13020 sax.STATE = { 13021 BEGIN: S++, // leading byte order mark or whitespace 13022 BEGIN_WHITESPACE: S++, // leading whitespace 13023 TEXT: S++, // general stuff 13024 TEXT_ENTITY: S++, // & and such. 13025 OPEN_WAKA: S++, // < 13026 SGML_DECL: S++, // <!BLARG 13027 SGML_DECL_QUOTED: S++, // <!BLARG foo "bar 13028 DOCTYPE: S++, // <!DOCTYPE 13029 DOCTYPE_QUOTED: S++, // <!DOCTYPE "//blah 13030 DOCTYPE_DTD: S++, // <!DOCTYPE "//blah" [ ... 13031 DOCTYPE_DTD_QUOTED: S++, // <!DOCTYPE "//blah" [ "foo 13032 COMMENT_STARTING: S++, // <!- 13033 COMMENT: S++, // <!-- 13034 COMMENT_ENDING: S++, // <!-- blah - 13035 COMMENT_ENDED: S++, // <!-- blah -- 13036 CDATA: S++, // <![CDATA[ something 13037 CDATA_ENDING: S++, // ] 13038 CDATA_ENDING_2: S++, // ]] 13039 PROC_INST: S++, // <?hi 13040 PROC_INST_BODY: S++, // <?hi there 13041 PROC_INST_ENDING: S++, // <?hi "there" ? 13042 OPEN_TAG: S++, // <strong 13043 OPEN_TAG_SLASH: S++, // <strong / 13044 ATTRIB: S++, // <a 13045 ATTRIB_NAME: S++, // <a foo 13046 ATTRIB_NAME_SAW_WHITE: S++, // <a foo _ 13047 ATTRIB_VALUE: S++, // <a foo= 13048 ATTRIB_VALUE_QUOTED: S++, // <a foo="bar 13049 ATTRIB_VALUE_CLOSED: S++, // <a foo="bar" 13050 ATTRIB_VALUE_UNQUOTED: S++, // <a foo=bar 13051 ATTRIB_VALUE_ENTITY_Q: S++, // <foo bar=""" 13052 ATTRIB_VALUE_ENTITY_U: S++, // <foo bar=" 13053 CLOSE_TAG: S++, // </a 13054 CLOSE_TAG_SAW_WHITE: S++, // </a > 13055 SCRIPT: S++, // <script> ... 13056 SCRIPT_ENDING: S++ // <script> ... < 13057 } 13058 13059 sax.XML_ENTITIES = { 13060 'amp': '&', 13061 'gt': '>', 13062 'lt': '<', 13063 'quot': '"', 13064 'apos': "'" 13065 } 13066 13067 sax.ENTITIES = { 13068 'amp': '&', 13069 'gt': '>', 13070 'lt': '<', 13071 'quot': '"', 13072 'apos': "'", 13073 'AElig': 198, 13074 'Aacute': 193, 13075 'Acirc': 194, 13076 'Agrave': 192, 13077 'Aring': 197, 13078 'Atilde': 195, 13079 'Auml': 196, 13080 'Ccedil': 199, 13081 'ETH': 208, 13082 'Eacute': 201, 13083 'Ecirc': 202, 13084 'Egrave': 200, 13085 'Euml': 203, 13086 'Iacute': 205, 13087 'Icirc': 206, 13088 'Igrave': 204, 13089 'Iuml': 207, 13090 'Ntilde': 209, 13091 'Oacute': 211, 13092 'Ocirc': 212, 13093 'Ograve': 210, 13094 'Oslash': 216, 13095 'Otilde': 213, 13096 'Ouml': 214, 13097 'THORN': 222, 13098 'Uacute': 218, 13099 'Ucirc': 219, 13100 'Ugrave': 217, 13101 'Uuml': 220, 13102 'Yacute': 221, 13103 'aacute': 225, 13104 'acirc': 226, 13105 'aelig': 230, 13106 'agrave': 224, 13107 'aring': 229, 13108 'atilde': 227, 13109 'auml': 228, 13110 'ccedil': 231, 13111 'eacute': 233, 13112 'ecirc': 234, 13113 'egrave': 232, 13114 'eth': 240, 13115 'euml': 235, 13116 'iacute': 237, 13117 'icirc': 238, 13118 'igrave': 236, 13119 'iuml': 239, 13120 'ntilde': 241, 13121 'oacute': 243, 13122 'ocirc': 244, 13123 'ograve': 242, 13124 'oslash': 248, 13125 'otilde': 245, 13126 'ouml': 246, 13127 'szlig': 223, 13128 'thorn': 254, 13129 'uacute': 250, 13130 'ucirc': 251, 13131 'ugrave': 249, 13132 'uuml': 252, 13133 'yacute': 253, 13134 'yuml': 255, 13135 'copy': 169, 13136 'reg': 174, 13137 'nbsp': 160, 13138 'iexcl': 161, 13139 'cent': 162, 13140 'pound': 163, 13141 'curren': 164, 13142 'yen': 165, 13143 'brvbar': 166, 13144 'sect': 167, 13145 'uml': 168, 13146 'ordf': 170, 13147 'laquo': 171, 13148 'not': 172, 13149 'shy': 173, 13150 'macr': 175, 13151 'deg': 176, 13152 'plusmn': 177, 13153 'sup1': 185, 13154 'sup2': 178, 13155 'sup3': 179, 13156 'acute': 180, 13157 'micro': 181, 13158 'para': 182, 13159 'middot': 183, 13160 'cedil': 184, 13161 'ordm': 186, 13162 'raquo': 187, 13163 'frac14': 188, 13164 'frac12': 189, 13165 'frac34': 190, 13166 'iquest': 191, 13167 'times': 215, 13168 'divide': 247, 13169 'OElig': 338, 13170 'oelig': 339, 13171 'Scaron': 352, 13172 'scaron': 353, 13173 'Yuml': 376, 13174 'fnof': 402, 13175 'circ': 710, 13176 'tilde': 732, 13177 'Alpha': 913, 13178 'Beta': 914, 13179 'Gamma': 915, 13180 'Delta': 916, 13181 'Epsilon': 917, 13182 'Zeta': 918, 13183 'Eta': 919, 13184 'Theta': 920, 13185 'Iota': 921, 13186 'Kappa': 922, 13187 'Lambda': 923, 13188 'Mu': 924, 13189 'Nu': 925, 13190 'Xi': 926, 13191 'Omicron': 927, 13192 'Pi': 928, 13193 'Rho': 929, 13194 'Sigma': 931, 13195 'Tau': 932, 13196 'Upsilon': 933, 13197 'Phi': 934, 13198 'Chi': 935, 13199 'Psi': 936, 13200 'Omega': 937, 13201 'alpha': 945, 13202 'beta': 946, 13203 'gamma': 947, 13204 'delta': 948, 13205 'epsilon': 949, 13206 'zeta': 950, 13207 'eta': 951, 13208 'theta': 952, 13209 'iota': 953, 13210 'kappa': 954, 13211 'lambda': 955, 13212 'mu': 956, 13213 'nu': 957, 13214 'xi': 958, 13215 'omicron': 959, 13216 'pi': 960, 13217 'rho': 961, 13218 'sigmaf': 962, 13219 'sigma': 963, 13220 'tau': 964, 13221 'upsilon': 965, 13222 'phi': 966, 13223 'chi': 967, 13224 'psi': 968, 13225 'omega': 969, 13226 'thetasym': 977, 13227 'upsih': 978, 13228 'piv': 982, 13229 'ensp': 8194, 13230 'emsp': 8195, 13231 'thinsp': 8201, 13232 'zwnj': 8204, 13233 'zwj': 8205, 13234 'lrm': 8206, 13235 'rlm': 8207, 13236 'ndash': 8211, 13237 'mdash': 8212, 13238 'lsquo': 8216, 13239 'rsquo': 8217, 13240 'sbquo': 8218, 13241 'ldquo': 8220, 13242 'rdquo': 8221, 13243 'bdquo': 8222, 13244 'dagger': 8224, 13245 'Dagger': 8225, 13246 'bull': 8226, 13247 'hellip': 8230, 13248 'permil': 8240, 13249 'prime': 8242, 13250 'Prime': 8243, 13251 'lsaquo': 8249, 13252 'rsaquo': 8250, 13253 'oline': 8254, 13254 'frasl': 8260, 13255 'euro': 8364, 13256 'image': 8465, 13257 'weierp': 8472, 13258 'real': 8476, 13259 'trade': 8482, 13260 'alefsym': 8501, 13261 'larr': 8592, 13262 'uarr': 8593, 13263 'rarr': 8594, 13264 'darr': 8595, 13265 'harr': 8596, 13266 'crarr': 8629, 13267 'lArr': 8656, 13268 'uArr': 8657, 13269 'rArr': 8658, 13270 'dArr': 8659, 13271 'hArr': 8660, 13272 'forall': 8704, 13273 'part': 8706, 13274 'exist': 8707, 13275 'empty': 8709, 13276 'nabla': 8711, 13277 'isin': 8712, 13278 'notin': 8713, 13279 'ni': 8715, 13280 'prod': 8719, 13281 'sum': 8721, 13282 'minus': 8722, 13283 'lowast': 8727, 13284 'radic': 8730, 13285 'prop': 8733, 13286 'infin': 8734, 13287 'ang': 8736, 13288 'and': 8743, 13289 'or': 8744, 13290 'cap': 8745, 13291 'cup': 8746, 13292 'int': 8747, 13293 'there4': 8756, 13294 'sim': 8764, 13295 'cong': 8773, 13296 'asymp': 8776, 13297 'ne': 8800, 13298 'equiv': 8801, 13299 'le': 8804, 13300 'ge': 8805, 13301 'sub': 8834, 13302 'sup': 8835, 13303 'nsub': 8836, 13304 'sube': 8838, 13305 'supe': 8839, 13306 'oplus': 8853, 13307 'otimes': 8855, 13308 'perp': 8869, 13309 'sdot': 8901, 13310 'lceil': 8968, 13311 'rceil': 8969, 13312 'lfloor': 8970, 13313 'rfloor': 8971, 13314 'lang': 9001, 13315 'rang': 9002, 13316 'loz': 9674, 13317 'spades': 9824, 13318 'clubs': 9827, 13319 'hearts': 9829, 13320 'diams': 9830 13321 } 13322 13323 Object.keys(sax.ENTITIES).forEach(function (key) { 13324 var e = sax.ENTITIES[key] 13325 var s = typeof e === 'number' ? String.fromCharCode(e) : e 13326 sax.ENTITIES[key] = s 13327 }) 13328 13329 for (var s in sax.STATE) { 13330 sax.STATE[sax.STATE[s]] = s 13331 } 13332 13333 // shorthand 13334 S = sax.STATE 13335 13336 function emit (parser, event, data) { 13337 parser[event] && parser[event](data) 13338 } 13339 13340 function emitNode (parser, nodeType, data) { 13341 if (parser.textNode) closeText(parser) 13342 emit(parser, nodeType, data) 13343 } 13344 13345 function closeText (parser) { 13346 parser.textNode = textopts(parser.opt, parser.textNode) 13347 if (parser.textNode) emit(parser, 'ontext', parser.textNode) 13348 parser.textNode = '' 13349 } 13350 13351 function textopts (opt, text) { 13352 if (opt.trim) text = text.trim() 13353 if (opt.normalize) text = text.replace(/\s+/g, ' ') 13354 return text 13355 } 13356 13357 function error (parser, er) { 13358 closeText(parser) 13359 if (parser.trackPosition) { 13360 er += '\nLine: ' + parser.line + 13361 '\nColumn: ' + parser.column + 13362 '\nChar: ' + parser.c 13363 } 13364 er = new Error(er) 13365 parser.error = er 13366 emit(parser, 'onerror', er) 13367 return parser 13368 } 13369 13370 function end (parser) { 13371 if (parser.sawRoot && !parser.closedRoot) strictFail(parser, 'Unclosed root tag') 13372 if ((parser.state !== S.BEGIN) && 13373 (parser.state !== S.BEGIN_WHITESPACE) && 13374 (parser.state !== S.TEXT)) { 13375 error(parser, 'Unexpected end') 13376 } 13377 closeText(parser) 13378 parser.c = '' 13379 parser.closed = true 13380 emit(parser, 'onend') 13381 SAXParser.call(parser, parser.strict, parser.opt) 13382 return parser 13383 } 13384 13385 function strictFail (parser, message) { 13386 if (typeof parser !== 'object' || !(parser instanceof SAXParser)) { 13387 throw new Error('bad call to strictFail') 13388 } 13389 if (parser.strict) { 13390 error(parser, message) 13391 } 13392 } 13393 13394 function newTag (parser) { 13395 if (!parser.strict) parser.tagName = parser.tagName[parser.looseCase]() 13396 var parent = parser.tags[parser.tags.length - 1] || parser 13397 var tag = parser.tag = { name: parser.tagName, attributes: {} } 13398 13399 // will be overridden if tag contails an xmlns="foo" or xmlns:foo="bar" 13400 if (parser.opt.xmlns) { 13401 tag.ns = parent.ns 13402 } 13403 parser.attribList.length = 0 13404 emitNode(parser, 'onopentagstart', tag) 13405 } 13406 13407 function qname (name, attribute) { 13408 var i = name.indexOf(':') 13409 var qualName = i < 0 ? [ '', name ] : name.split(':') 13410 var prefix = qualName[0] 13411 var local = qualName[1] 13412 13413 // <x "xmlns"="http://foo"> 13414 if (attribute && name === 'xmlns') { 13415 prefix = 'xmlns' 13416 local = '' 13417 } 13418 13419 return { prefix: prefix, local: local } 13420 } 13421 13422 function attrib (parser) { 13423 if (!parser.strict) { 13424 parser.attribName = parser.attribName[parser.looseCase]() 13425 } 13426 13427 if (parser.attribList.indexOf(parser.attribName) !== -1 || 13428 parser.tag.attributes.hasOwnProperty(parser.attribName)) { 13429 parser.attribName = parser.attribValue = '' 13430 return 13431 } 13432 13433 if (parser.opt.xmlns) { 13434 var qn = qname(parser.attribName, true) 13435 var prefix = qn.prefix 13436 var local = qn.local 13437 13438 if (prefix === 'xmlns') { 13439 // namespace binding attribute. push the binding into scope 13440 if (local === 'xml' && parser.attribValue !== XML_NAMESPACE) { 13441 strictFail(parser, 13442 'xml: prefix must be bound to ' + XML_NAMESPACE + '\n' + 13443 'Actual: ' + parser.attribValue) 13444 } else if (local === 'xmlns' && parser.attribValue !== XMLNS_NAMESPACE) { 13445 strictFail(parser, 13446 'xmlns: prefix must be bound to ' + XMLNS_NAMESPACE + '\n' + 13447 'Actual: ' + parser.attribValue) 13448 } else { 13449 var tag = parser.tag 13450 var parent = parser.tags[parser.tags.length - 1] || parser 13451 if (tag.ns === parent.ns) { 13452 tag.ns = Object.create(parent.ns) 13453 } 13454 tag.ns[local] = parser.attribValue 13455 } 13456 } 13457 13458 // defer onattribute events until all attributes have been seen 13459 // so any new bindings can take effect. preserve attribute order 13460 // so deferred events can be emitted in document order 13461 parser.attribList.push([parser.attribName, parser.attribValue]) 13462 } else { 13463 // in non-xmlns mode, we can emit the event right away 13464 parser.tag.attributes[parser.attribName] = parser.attribValue 13465 emitNode(parser, 'onattribute', { 13466 name: parser.attribName, 13467 value: parser.attribValue 13468 }) 13469 } 13470 13471 parser.attribName = parser.attribValue = '' 13472 } 13473 13474 function openTag (parser, selfClosing) { 13475 if (parser.opt.xmlns) { 13476 // emit namespace binding events 13477 var tag = parser.tag 13478 13479 // add namespace info to tag 13480 var qn = qname(parser.tagName) 13481 tag.prefix = qn.prefix 13482 tag.local = qn.local 13483 tag.uri = tag.ns[qn.prefix] || '' 13484 13485 if (tag.prefix && !tag.uri) { 13486 strictFail(parser, 'Unbound namespace prefix: ' + 13487 JSON.stringify(parser.tagName)) 13488 tag.uri = qn.prefix 13489 } 13490 13491 var parent = parser.tags[parser.tags.length - 1] || parser 13492 if (tag.ns && parent.ns !== tag.ns) { 13493 Object.keys(tag.ns).forEach(function (p) { 13494 emitNode(parser, 'onopennamespace', { 13495 prefix: p, 13496 uri: tag.ns[p] 13497 }) 13498 }) 13499 } 13500 13501 // handle deferred onattribute events 13502 // Note: do not apply default ns to attributes: 13503 // http://www.w3.org/TR/REC-xml-names/#defaulting 13504 for (var i = 0, l = parser.attribList.length; i < l; i++) { 13505 var nv = parser.attribList[i] 13506 var name = nv[0] 13507 var value = nv[1] 13508 var qualName = qname(name, true) 13509 var prefix = qualName.prefix 13510 var local = qualName.local 13511 var uri = prefix === '' ? '' : (tag.ns[prefix] || '') 13512 var a = { 13513 name: name, 13514 value: value, 13515 prefix: prefix, 13516 local: local, 13517 uri: uri 13518 } 13519 13520 // if there's any attributes with an undefined namespace, 13521 // then fail on them now. 13522 if (prefix && prefix !== 'xmlns' && !uri) { 13523 strictFail(parser, 'Unbound namespace prefix: ' + 13524 JSON.stringify(prefix)) 13525 a.uri = prefix 13526 } 13527 parser.tag.attributes[name] = a 13528 emitNode(parser, 'onattribute', a) 13529 } 13530 parser.attribList.length = 0 13531 } 13532 13533 parser.tag.isSelfClosing = !!selfClosing 13534 13535 // process the tag 13536 parser.sawRoot = true 13537 parser.tags.push(parser.tag) 13538 emitNode(parser, 'onopentag', parser.tag) 13539 if (!selfClosing) { 13540 // special case for <script> in non-strict mode. 13541 if (!parser.noscript && parser.tagName.toLowerCase() === 'script') { 13542 parser.state = S.SCRIPT 13543 } else { 13544 parser.state = S.TEXT 13545 } 13546 parser.tag = null 13547 parser.tagName = '' 13548 } 13549 parser.attribName = parser.attribValue = '' 13550 parser.attribList.length = 0 13551 } 13552 13553 function closeTag (parser) { 13554 if (!parser.tagName) { 13555 strictFail(parser, 'Weird empty close tag.') 13556 parser.textNode += '</>' 13557 parser.state = S.TEXT 13558 return 13559 } 13560 13561 if (parser.script) { 13562 if (parser.tagName !== 'script') { 13563 parser.script += '</' + parser.tagName + '>' 13564 parser.tagName = '' 13565 parser.state = S.SCRIPT 13566 return 13567 } 13568 emitNode(parser, 'onscript', parser.script) 13569 parser.script = '' 13570 } 13571 13572 // first make sure that the closing tag actually exists. 13573 // <a><b></c></b></a> will close everything, otherwise. 13574 var t = parser.tags.length 13575 var tagName = parser.tagName 13576 if (!parser.strict) { 13577 tagName = tagName[parser.looseCase]() 13578 } 13579 var closeTo = tagName 13580 while (t--) { 13581 var close = parser.tags[t] 13582 if (close.name !== closeTo) { 13583 // fail the first time in strict mode 13584 strictFail(parser, 'Unexpected close tag') 13585 } else { 13586 break 13587 } 13588 } 13589 13590 // didn't find it. we already failed for strict, so just abort. 13591 if (t < 0) { 13592 strictFail(parser, 'Unmatched closing tag: ' + parser.tagName) 13593 parser.textNode += '</' + parser.tagName + '>' 13594 parser.state = S.TEXT 13595 return 13596 } 13597 parser.tagName = tagName 13598 var s = parser.tags.length 13599 while (s-- > t) { 13600 var tag = parser.tag = parser.tags.pop() 13601 parser.tagName = parser.tag.name 13602 emitNode(parser, 'onclosetag', parser.tagName) 13603 13604 var x = {} 13605 for (var i in tag.ns) { 13606 x[i] = tag.ns[i] 13607 } 13608 13609 var parent = parser.tags[parser.tags.length - 1] || parser 13610 if (parser.opt.xmlns && tag.ns !== parent.ns) { 13611 // remove namespace bindings introduced by tag 13612 Object.keys(tag.ns).forEach(function (p) { 13613 var n = tag.ns[p] 13614 emitNode(parser, 'onclosenamespace', { prefix: p, uri: n }) 13615 }) 13616 } 13617 } 13618 if (t === 0) parser.closedRoot = true 13619 parser.tagName = parser.attribValue = parser.attribName = '' 13620 parser.attribList.length = 0 13621 parser.state = S.TEXT 13622 } 13623 13624 function parseEntity (parser) { 13625 var entity = parser.entity 13626 var entityLC = entity.toLowerCase() 13627 var num 13628 var numStr = '' 13629 13630 if (parser.ENTITIES[entity]) { 13631 return parser.ENTITIES[entity] 13632 } 13633 if (parser.ENTITIES[entityLC]) { 13634 return parser.ENTITIES[entityLC] 13635 } 13636 entity = entityLC 13637 if (entity.charAt(0) === '#') { 13638 if (entity.charAt(1) === 'x') { 13639 entity = entity.slice(2) 13640 num = parseInt(entity, 16) 13641 numStr = num.toString(16) 13642 } else { 13643 entity = entity.slice(1) 13644 num = parseInt(entity, 10) 13645 numStr = num.toString(10) 13646 } 13647 } 13648 entity = entity.replace(/^0+/, '') 13649 if (
vendor: 21,078 bytes, lines 13649-14327
13649numStr.toLowerCase() !== entity) { 13650 strictFail(parser, 'Invalid character entity') 13651 return '&' + parser.entity + ';' 13652 } 13653 13654 return String.fromCodePoint(num) 13655 } 13656 13657 function beginWhiteSpace (parser, c) { 13658 if (c === '<') { 13659 parser.state = S.OPEN_WAKA 13660 parser.startTagPosition = parser.position 13661 } else if (not(whitespace, c)) { 13662 // have to process this as a text node. 13663 // weird, but happens. 13664 strictFail(parser, 'Non-whitespace before first tag.') 13665 parser.textNode = c 13666 parser.state = S.TEXT 13667 } 13668 } 13669 13670 function charAt (chunk, i) { 13671 var result = '' 13672 if (i < chunk.length) { 13673 result = chunk.charAt(i) 13674 } 13675 return result 13676 } 13677 13678 function write (chunk) { 13679 var parser = this 13680 if (this.error) { 13681 throw this.error 13682 } 13683 if (parser.closed) { 13684 return error(parser, 13685 'Cannot write after close. Assign an onready handler.') 13686 } 13687 if (chunk === null) { 13688 return end(parser) 13689 } 13690 if (typeof chunk === 'object') { 13691 chunk = chunk.toString() 13692 } 13693 var i = 0 13694 var c = '' 13695 while (true) { 13696 c = charAt(chunk, i++) 13697 parser.c = c 13698 if (!c) { 13699 break 13700 } 13701 if (parser.trackPosition) { 13702 parser.position++ 13703 if (c === '\n') { 13704 parser.line++ 13705 parser.column = 0 13706 } else { 13707 parser.column++ 13708 } 13709 } 13710 switch (parser.state) { 13711 case S.BEGIN: 13712 parser.state = S.BEGIN_WHITESPACE 13713 if (c === '\uFEFF') { 13714 continue 13715 } 13716 beginWhiteSpace(parser, c) 13717 continue 13718 13719 case S.BEGIN_WHITESPACE: 13720 beginWhiteSpace(parser, c) 13721 continue 13722 13723 case S.TEXT: 13724 if (parser.sawRoot && !parser.closedRoot) { 13725 var starti = i - 1 13726 while (c && c !== '<' && c !== '&') { 13727 c = charAt(chunk, i++) 13728 if (c && parser.trackPosition) { 13729 parser.position++ 13730 if (c === '\n') { 13731 parser.line++ 13732 parser.column = 0 13733 } else { 13734 parser.column++ 13735 } 13736 } 13737 } 13738 parser.textNode += chunk.substring(starti, i - 1) 13739 } 13740 if (c === '<' && !(parser.sawRoot && parser.closedRoot && !parser.strict)) { 13741 parser.state = S.OPEN_WAKA 13742 parser.startTagPosition = parser.position 13743 } else { 13744 if (not(whitespace, c) && (!parser.sawRoot || parser.closedRoot)) { 13745 strictFail(parser, 'Text data outside of root node.') 13746 } 13747 if (c === '&') { 13748 parser.state = S.TEXT_ENTITY 13749 } else { 13750 parser.textNode += c 13751 } 13752 } 13753 continue 13754 13755 case S.SCRIPT: 13756 // only non-strict 13757 if (c === '<') { 13758 parser.state = S.SCRIPT_ENDING 13759 } else { 13760 parser.script += c 13761 } 13762 continue 13763 13764 case S.SCRIPT_ENDING: 13765 if (c === '/') { 13766 parser.state = S.CLOSE_TAG 13767 } else { 13768 parser.script += '<' + c 13769 parser.state = S.SCRIPT 13770 } 13771 continue 13772 13773 case S.OPEN_WAKA: 13774 // either a /, ?, !, or text is coming next. 13775 if (c === '!') { 13776 parser.state = S.SGML_DECL 13777 parser.sgmlDecl = '' 13778 } else if (is(whitespace, c)) { 13779 // wait for it... 13780 } else if (is(nameStart, c)) { 13781 parser.state = S.OPEN_TAG 13782 parser.tagName = c 13783 } else if (c === '/') { 13784 parser.state = S.CLOSE_TAG 13785 parser.tagName = '' 13786 } else if (c === '?') { 13787 parser.state = S.PROC_INST 13788 parser.procInstName = parser.procInstBody = '' 13789 } else { 13790 strictFail(parser, 'Unencoded <') 13791 // if there was some whitespace, then add that in. 13792 if (parser.startTagPosition + 1 < parser.position) { 13793 var pad = parser.position - parser.startTagPosition 13794 c = new Array(pad).join(' ') + c 13795 } 13796 parser.textNode += '<' + c 13797 parser.state = S.TEXT 13798 } 13799 continue 13800 13801 case S.SGML_DECL: 13802 if ((parser.sgmlDecl + c).toUpperCase() === CDATA) { 13803 emitNode(parser, 'onopencdata') 13804 parser.state = S.CDATA 13805 parser.sgmlDecl = '' 13806 parser.cdata = '' 13807 } else if (parser.sgmlDecl + c === '--') { 13808 parser.state = S.COMMENT 13809 parser.comment = '' 13810 parser.sgmlDecl = '' 13811 } else if ((parser.sgmlDecl + c).toUpperCase() === DOCTYPE) { 13812 parser.state = S.DOCTYPE 13813 if (parser.doctype || parser.sawRoot) { 13814 strictFail(parser, 13815 'Inappropriately located doctype declaration') 13816 } 13817 parser.doctype = '' 13818 parser.sgmlDecl = '' 13819 } else if (c === '>') { 13820 emitNode(parser, 'onsgmldeclaration', parser.sgmlDecl) 13821 parser.sgmlDecl = '' 13822 parser.state = S.TEXT 13823 } else if (is(quote, c)) { 13824 parser.state = S.SGML_DECL_QUOTED 13825 parser.sgmlDecl += c 13826 } else { 13827 parser.sgmlDecl += c 13828 } 13829 continue 13830 13831 case S.SGML_DECL_QUOTED: 13832 if (c === parser.q) { 13833 parser.state = S.SGML_DECL 13834 parser.q = '' 13835 } 13836 parser.sgmlDecl += c 13837 continue 13838 13839 case S.DOCTYPE: 13840 if (c === '>') { 13841 parser.state = S.TEXT 13842 emitNode(parser, 'ondoctype', parser.doctype) 13843 parser.doctype = true // just remember that we saw it. 13844 } else { 13845 parser.doctype += c 13846 if (c === '[') { 13847 parser.state = S.DOCTYPE_DTD 13848 } else if (is(quote, c)) { 13849 parser.state = S.DOCTYPE_QUOTED 13850 parser.q = c 13851 } 13852 } 13853 continue 13854 13855 case S.DOCTYPE_QUOTED: 13856 parser.doctype += c 13857 if (c === parser.q) { 13858 parser.q = '' 13859 parser.state = S.DOCTYPE 13860 } 13861 continue 13862 13863 case S.DOCTYPE_DTD: 13864 parser.doctype += c 13865 if (c === ']') { 13866 parser.state = S.DOCTYPE 13867 } else if (is(quote, c)) { 13868 parser.state = S.DOCTYPE_DTD_QUOTED 13869 parser.q = c 13870 } 13871 continue 13872 13873 case S.DOCTYPE_DTD_QUOTED: 13874 parser.doctype += c 13875 if (c === parser.q) { 13876 parser.state = S.DOCTYPE_DTD 13877 parser.q = '' 13878 } 13879 continue 13880 13881 case S.COMMENT: 13882 if (c === '-') { 13883 parser.state = S.COMMENT_ENDING 13884 } else { 13885 parser.comment += c 13886 } 13887 continue 13888 13889 case S.COMMENT_ENDING: 13890 if (c === '-') { 13891 parser.state = S.COMMENT_ENDED 13892 parser.comment = textopts(parser.opt, parser.comment) 13893 if (parser.comment) { 13894 emitNode(parser, 'oncomment', parser.comment) 13895 } 13896 parser.comment = '' 13897 } else { 13898 parser.comment += '-' + c 13899 parser.state = S.COMMENT 13900 } 13901 continue 13902 13903 case S.COMMENT_ENDED: 13904 if (c !== '>') { 13905 strictFail(parser, 'Malformed comment') 13906 // allow <!-- blah -- bloo --> in non-strict mode, 13907 // which is a comment of " blah -- bloo " 13908 parser.comment += '--' + c 13909 parser.state = S.COMMENT 13910 } else { 13911 parser.state = S.TEXT 13912 } 13913 continue 13914 13915 case S.CDATA: 13916 if (c === ']') { 13917 parser.state = S.CDATA_ENDING 13918 } else { 13919 parser.cdata += c 13920 } 13921 continue 13922 13923 case S.CDATA_ENDING: 13924 if (c === ']') { 13925 parser.state = S.CDATA_ENDING_2 13926 } else { 13927 parser.cdata += ']' + c 13928 parser.state = S.CDATA 13929 } 13930 continue 13931 13932 case S.CDATA_ENDING_2: 13933 if (c === '>') { 13934 if (parser.cdata) { 13935 emitNode(parser, 'oncdata', parser.cdata) 13936 } 13937 emitNode(parser, 'onclosecdata') 13938 parser.cdata = '' 13939 parser.state = S.TEXT 13940 } else if (c === ']') { 13941 parser.cdata += ']' 13942 } else { 13943 parser.cdata += ']]' + c 13944 parser.state = S.CDATA 13945 } 13946 continue 13947 13948 case S.PROC_INST: 13949 if (c === '?') { 13950 parser.state = S.PROC_INST_ENDING 13951 } else if (is(whitespace, c)) { 13952 parser.state = S.PROC_INST_BODY 13953 } else { 13954 parser.procInstName += c 13955 } 13956 continue 13957 13958 case S.PROC_INST_BODY: 13959 if (!parser.procInstBody && is(whitespace, c)) { 13960 continue 13961 } else if (c === '?') { 13962 parser.state = S.PROC_INST_ENDING 13963 } else { 13964 parser.procInstBody += c 13965 } 13966 continue 13967 13968 case S.PROC_INST_ENDING: 13969 if (c === '>') { 13970 emitNode(parser, 'onprocessinginstruction', { 13971 name: parser.procInstName, 13972 body: parser.procInstBody 13973 }) 13974 parser.procInstName = parser.procInstBody = '' 13975 parser.state = S.TEXT 13976 } else { 13977 parser.procInstBody += '?' + c 13978 parser.state = S.PROC_INST_BODY 13979 } 13980 continue 13981 13982 case S.OPEN_TAG: 13983 if (is(nameBody, c)) { 13984 parser.tagName += c 13985 } else { 13986 newTag(parser) 13987 if (c === '>') { 13988 openTag(parser) 13989 } else if (c === '/') { 13990 parser.state = S.OPEN_TAG_SLASH 13991 } else { 13992 if (not(whitespace, c)) { 13993 strictFail(parser, 'Invalid character in tag name') 13994 } 13995 parser.state = S.ATTRIB 13996 } 13997 } 13998 continue 13999 14000 case S.OPEN_TAG_SLASH: 14001 if (c === '>') { 14002 openTag(parser, true) 14003 closeTag(parser) 14004 } else { 14005 strictFail(parser, 'Forward-slash in opening tag not followed by >') 14006 parser.state = S.ATTRIB 14007 } 14008 continue 14009 14010 case S.ATTRIB: 14011 // haven't read the attribute name yet. 14012 if (is(whitespace, c)) { 14013 continue 14014 } else if (c === '>') { 14015 openTag(parser) 14016 } else if (c === '/') { 14017 parser.state = S.OPEN_TAG_SLASH 14018 } else if (is(nameStart, c)) { 14019 parser.attribName = c 14020 parser.attribValue = '' 14021 parser.state = S.ATTRIB_NAME 14022 } else { 14023 strictFail(parser, 'Invalid attribute name') 14024 } 14025 continue 14026 14027 case S.ATTRIB_NAME: 14028 if (c === '=') { 14029 parser.state = S.ATTRIB_VALUE 14030 } else if (c === '>') { 14031 strictFail(parser, 'Attribute without value') 14032 parser.attribValue = parser.attribName 14033 attrib(parser) 14034 openTag(parser) 14035 } else if (is(whitespace, c)) { 14036 parser.state = S.ATTRIB_NAME_SAW_WHITE 14037 } else if (is(nameBody, c)) { 14038 parser.attribName += c 14039 } else { 14040 strictFail(parser, 'Invalid attribute name') 14041 } 14042 continue 14043 14044 case S.ATTRIB_NAME_SAW_WHITE: 14045 if (c === '=') { 14046 parser.state = S.ATTRIB_VALUE 14047 } else if (is(whitespace, c)) { 14048 continue 14049 } else { 14050 strictFail(parser, 'Attribute without value') 14051 parser.tag.attributes[parser.attribName] = '' 14052 parser.attribValue = '' 14053 emitNode(parser, 'onattribute', { 14054 name: parser.attribName, 14055 value: '' 14056 }) 14057 parser.attribName = '' 14058 if (c === '>') { 14059 openTag(parser) 14060 } else if (is(nameStart, c)) { 14061 parser.attribName = c 14062 parser.state = S.ATTRIB_NAME 14063 } else { 14064 strictFail(parser, 'Invalid attribute name') 14065 parser.state = S.ATTRIB 14066 } 14067 } 14068 continue 14069 14070 case S.ATTRIB_VALUE: 14071 if (is(whitespace, c)) { 14072 continue 14073 } else if (is(quote, c)) { 14074 parser.q = c 14075 parser.state = S.ATTRIB_VALUE_QUOTED 14076 } else { 14077 strictFail(parser, 'Unquoted attribute value') 14078 parser.state = S.ATTRIB_VALUE_UNQUOTED 14079 parser.attribValue = c 14080 } 14081 continue 14082 14083 case S.ATTRIB_VALUE_QUOTED: 14084 if (c !== parser.q) { 14085 if (c === '&') { 14086 parser.state = S.ATTRIB_VALUE_ENTITY_Q 14087 } else { 14088 parser.attribValue += c 14089 } 14090 continue 14091 } 14092 attrib(parser) 14093 parser.q = '' 14094 parser.state = S.ATTRIB_VALUE_CLOSED 14095 continue 14096 14097 case S.ATTRIB_VALUE_CLOSED: 14098 if (is(whitespace, c)) { 14099 parser.state = S.ATTRIB 14100 } else if (c === '>') { 14101 openTag(parser) 14102 } else if (c === '/') { 14103 parser.state = S.OPEN_TAG_SLASH 14104 } else if (is(nameStart, c)) { 14105 strictFail(parser, 'No whitespace between attributes') 14106 parser.attribName = c 14107 parser.attribValue = '' 14108 parser.state = S.ATTRIB_NAME 14109 } else { 14110 strictFail(parser, 'Invalid attribute name') 14111 } 14112 continue 14113 14114 case S.ATTRIB_VALUE_UNQUOTED: 14115 if (not(attribEnd, c)) { 14116 if (c === '&') { 14117 parser.state = S.ATTRIB_VALUE_ENTITY_U 14118 } else { 14119 parser.attribValue += c 14120 } 14121 continue 14122 } 14123 attrib(parser) 14124 if (c === '>') { 14125 openTag(parser) 14126 } else { 14127 parser.state = S.ATTRIB 14128 } 14129 continue 14130 14131 case S.CLOSE_TAG: 14132 if (!parser.tagName) { 14133 if (is(whitespace, c)) { 14134 continue 14135 } else if (not(nameStart, c)) { 14136 if (parser.script) { 14137 parser.script += '</' + c 14138 parser.state = S.SCRIPT 14139 } else { 14140 strictFail(parser, 'Invalid tagname in closing tag.') 14141 } 14142 } else { 14143 parser.tagName = c 14144 } 14145 } else if (c === '>') { 14146 closeTag(parser) 14147 } else if (is(nameBody, c)) { 14148 parser.tagName += c 14149 } else if (parser.script) { 14150 parser.script += '</' + parser.tagName 14151 parser.tagName = '' 14152 parser.state = S.SCRIPT 14153 } else { 14154 if (not(whitespace, c)) { 14155 strictFail(parser, 'Invalid tagname in closing tag') 14156 } 14157 parser.state = S.CLOSE_TAG_SAW_WHITE 14158 } 14159 continue 14160 14161 case S.CLOSE_TAG_SAW_WHITE: 14162 if (is(whitespace, c)) { 14163 continue 14164 } 14165 if (c === '>') { 14166 closeTag(parser) 14167 } else { 14168 strictFail(parser, 'Invalid characters in closing tag') 14169 } 14170 continue 14171 14172 case S.TEXT_ENTITY: 14173 case S.ATTRIB_VALUE_ENTITY_Q: 14174 case S.ATTRIB_VALUE_ENTITY_U: 14175 var returnState 14176 var buffer 14177 switch (parser.state) { 14178 case S.TEXT_ENTITY: 14179 returnState = S.TEXT 14180 buffer = 'textNode' 14181 break 14182 14183 case S.ATTRIB_VALUE_ENTITY_Q: 14184 returnState = S.ATTRIB_VALUE_QUOTED 14185 buffer = 'attribValue' 14186 break 14187 14188 case S.ATTRIB_VALUE_ENTITY_U: 14189 returnState = S.ATTRIB_VALUE_UNQUOTED 14190 buffer = 'attribValue' 14191 break 14192 } 14193 14194 if (c === ';') { 14195 parser[buffer] += parseEntity(parser) 14196 parser.entity = '' 14197 parser.state = returnState 14198 } else if (is(parser.entity.length ? entityBody : entityStart, c)) { 14199 parser.entity += c 14200 } else { 14201 strictFail(parser, 'Invalid character in entity name') 14202 parser[buffer] += '&' + parser.entity + c 14203 parser.entity = '' 14204 parser.state = returnState 14205 } 14206 14207 continue 14208 14209 default: 14210 throw new Error(parser, 'Unknown state: ' + parser.state) 14211 } 14212 } // while 14213 14214 if (parser.position >= parser.bufferCheckPosition) { 14215 checkBufferLength(parser) 14216 } 14217 return parser 14218 } 14219 14220 /*! http://mths.be/fromcodepoint v0.1.0 by @mathias */ 14221 if (!String.fromCodePoint) { 14222 (function () { 14223 var stringFromCharCode = String.fromCharCode 14224 var floor = Math.floor 14225 var fromCodePoint = function () { 14226 var MAX_SIZE = 0x4000 14227 var codeUnits = [] 14228 var highSurrogate 14229 var lowSurrogate 14230 var index = -1 14231 var length = arguments.length 14232 if (!length) { 14233 return '' 14234 } 14235 var result = '' 14236 while (++index < length) { 14237 var codePoint = Number(arguments[index]) 14238 if ( 14239 !isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity` 14240 codePoint < 0 || // not a valid Unicode code point 14241 codePoint > 0x10FFFF || // not a valid Unicode code point 14242 floor(codePoint) !== codePoint // not an integer 14243 ) { 14244 throw RangeError('Invalid code point: ' + codePoint) 14245 } 14246 if (codePoint <= 0xFFFF) { // BMP code point 14247 codeUnits.push(codePoint) 14248 } else { // Astral code point; split in surrogate halves 14249 // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae 14250 codePoint -= 0x10000 14251 highSurrogate = (codePoint >> 10) + 0xD800 14252 lowSurrogate = (codePoint % 0x400) + 0xDC00 14253 codeUnits.push(highSurrogate, lowSurrogate) 14254 } 14255 if (index + 1 === length || codeUnits.length > MAX_SIZE) { 14256 result += stringFromCharCode.apply(null, codeUnits) 14257 codeUnits.length = 0 14258 } 14259 } 14260 return result 14261 } 14262 if (Object.defineProperty) { 14263 Object.defineProperty(String, 'fromCodePoint', { 14264 value: fromCodePoint, 14265 configurable: true, 14266 writable: true 14267 }) 14268 } else { 14269 String.fromCodePoint = fromCodePoint 14270 } 14271 }()) 14272 } 14273})(typeof exports === 'undefined' ? this.sax = {} : exports) 14274 14275}).call(this,_dereq_(10).Buffer) 14276 14277},{"10":10,"46":46,"9":9}],46:[function(_dereq_,module,exports){ 14278// Copyright Joyent, Inc. and other Node contributors. 14279// 14280// Permission is hereby granted, free of charge, to any person obtaining a 14281// copy of this software and associated documentation files (the 14282// "Software"), to deal in the Software without restriction, including 14283// without limitation the rights to use, copy, modify, merge, publish, 14284// distribute, sublicense, and/or sell copies of the Software, and to permit 14285// persons to whom the Software is furnished to do so, subject to the 14286// following conditions: 14287// 14288// The above copyright notice and this permission notice shall be included 14289// in all copies or substantial portions of the Software. 14290// 14291// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 14292// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 14293// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 14294// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 14295// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 14296// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 14297// USE OR OTHER DEALINGS IN THE SOFTWARE. 14298 14299module.exports = Stream; 14300 14301var EE = _dereq_(16).EventEmitter; 14302var inherits = _dereq_(25); 14303 14304inherits(Stream, EE); 14305Stream.Readable = _dereq_(40); 14306Stream.Writable = _dereq_(42); 14307Stream.Duplex = _dereq_(30); 14308Stream.Transform = _dereq_(41); 14309Stream.PassThrough = _dereq_(39); 14310 14311// Backwards-compat with node 0.4.x 14312Stream.Stream = Stream; 14313 14314 14315 14316// old-style streams. Note that the pipe method (the only relevant 14317// part of this class) is overridden in the Readable class. 14318 14319function Stream() { 14320 EE.call(this); 14321} 14322 14323Stream.prototype.pipe = function(dest, options) { 14324 var source = this; 14325 14326 function ondata(chunk) { 14327 if (dest.writable) {
vendor: 2,971 bytes, lines 14328-14449
14328 if (false === dest.write(chunk) && source.pause) { 14329 source.pause(); 14330 } 14331 } 14332 } 14333 14334 source.on('data', ondata); 14335 14336 function ondrain() { 14337 if (source.readable && source.resume) { 14338 source.resume(); 14339 } 14340 } 14341 14342 dest.on('drain', ondrain); 14343 14344 // If the 'end' option is not supplied, dest.end() will be called when 14345 // source gets the 'end' or 'close' events. Only dest.end() once. 14346 if (!dest._isStdio && (!options || options.end !== false)) { 14347 source.on('end', onend); 14348 source.on('close', onclose); 14349 } 14350 14351 var didOnEnd = false; 14352 function onend() { 14353 if (didOnEnd) return; 14354 didOnEnd = true; 14355 14356 dest.end(); 14357 } 14358 14359 14360 function onclose() { 14361 if (didOnEnd) return; 14362 didOnEnd = true; 14363 14364 if (typeof dest.destroy === 'function') dest.destroy(); 14365 } 14366 14367 // don't leave dangling pipes when there are errors. 14368 function onerror(er) { 14369 cleanup(); 14370 if (EE.listenerCount(this, 'error') === 0) { 14371 throw er; // Unhandled stream error in pipe. 14372 } 14373 } 14374 14375 source.on('error', onerror); 14376 dest.on('error', onerror); 14377 14378 // remove all the event listeners that were added. 14379 function cleanup() { 14380 source.removeListener('data', ondata); 14381 dest.removeListener('drain', ondrain); 14382 14383 source.removeListener('end', onend); 14384 source.removeListener('close', onclose); 14385 14386 source.removeListener('error', onerror); 14387 dest.removeListener('error', onerror); 14388 14389 source.removeListener('end', cleanup); 14390 source.removeListener('close', cleanup); 14391 14392 dest.removeListener('close', cleanup); 14393 } 14394 14395 source.on('end', cleanup); 14396 source.on('close', cleanup); 14397 14398 dest.on('close', cleanup); 14399 14400 dest.emit('pipe', source); 14401 14402 // Allow for unix-like usage: A.pipe(B).pipe(C) 14403 return dest; 14404}; 14405 14406},{"16":16,"25":25,"30":30,"39":39,"40":40,"41":41,"42":42}],47:[function(_dereq_,module,exports){ 14407'use strict'; 14408 14409var Buffer = _dereq_(44).Buffer; 14410 14411var isEncoding = Buffer.isEncoding || function (encoding) { 14412 encoding = '' + encoding; 14413 switch (encoding && encoding.toLowerCase()) { 14414 case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': 14415 return true; 14416 default: 14417 return false; 14418 } 14419}; 14420 14421function _normalizeEncoding(enc) { 14422 if (!enc) return 'utf8'; 14423 var retried; 14424 while (true) { 14425 switch (enc) { 14426 case 'utf8': 14427 case 'utf-8': 14428 return 'utf8'; 14429 case 'ucs2': 14430 case 'ucs-2': 14431 case 'utf16le': 14432 case 'utf-16le': 14433 return 'utf16le'; 14434 case 'latin1': 14435 case 'binary': 14436 return 'latin1'; 14437 case 'base64': 14438 case 'ascii': 14439 case 'hex': 14440 return enc; 14441 default: 14442 if (retried) return; // undefined 14443 enc = ('' + enc).toLowerCase(); 14444 retried = true; 14445 } 14446 } 14447}; 14448 14449// Do not cache `Buffer.isEncoding` when checking encoding names as some
vendor: 8,934 bytes, lines 14450-14737
14450// modules monkey-patch it to support additional encodings 14451function normalizeEncoding(enc) { 14452 var nenc = _normalizeEncoding(enc); 14453 if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); 14454 return nenc || enc; 14455} 14456 14457// StringDecoder provides an interface for efficiently splitting a series of 14458// buffers into a series of JS strings without breaking apart multi-byte 14459// characters. 14460exports.StringDecoder = StringDecoder; 14461function StringDecoder(encoding) { 14462 this.encoding = normalizeEncoding(encoding); 14463 var nb; 14464 switch (this.encoding) { 14465 case 'utf16le': 14466 this.text = utf16Text; 14467 this.end = utf16End; 14468 nb = 4; 14469 break; 14470 case 'utf8': 14471 this.fillLast = utf8FillLast; 14472 nb = 4; 14473 break; 14474 case 'base64': 14475 this.text = base64Text; 14476 this.end = base64End; 14477 nb = 3; 14478 break; 14479 default: 14480 this.write = simpleWrite; 14481 this.end = simpleEnd; 14482 return; 14483 } 14484 this.lastNeed = 0; 14485 this.lastTotal = 0; 14486 this.lastChar = Buffer.allocUnsafe(nb); 14487} 14488 14489StringDecoder.prototype.write = function (buf) { 14490 if (buf.length === 0) return ''; 14491 var r; 14492 var i; 14493 if (this.lastNeed) { 14494 r = this.fillLast(buf); 14495 if (r === undefined) return ''; 14496 i = this.lastNeed; 14497 this.lastNeed = 0; 14498 } else { 14499 i = 0; 14500 } 14501 if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); 14502 return r || ''; 14503}; 14504 14505StringDecoder.prototype.end = utf8End; 14506 14507// Returns only complete characters in a Buffer 14508StringDecoder.prototype.text = utf8Text; 14509 14510// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer 14511StringDecoder.prototype.fillLast = function (buf) { 14512 if (this.lastNeed <= buf.length) { 14513 buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); 14514 return this.lastChar.toString(this.encoding, 0, this.lastTotal); 14515 } 14516 buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); 14517 this.lastNeed -= buf.length; 14518}; 14519 14520// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a 14521// continuation byte. 14522function utf8CheckByte(byte) { 14523 if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; 14524 return -1; 14525} 14526 14527// Checks at most 3 bytes at the end of a Buffer in order to detect an 14528// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) 14529// needed to complete the UTF-8 character (if applicable) are returned. 14530function utf8CheckIncomplete(self, buf, i) { 14531 var j = buf.length - 1; 14532 if (j < i) return 0; 14533 var nb = utf8CheckByte(buf[j]); 14534 if (nb >= 0) { 14535 if (nb > 0) self.lastNeed = nb - 1; 14536 return nb; 14537 } 14538 if (--j < i) return 0; 14539 nb = utf8CheckByte(buf[j]); 14540 if (nb >= 0) { 14541 if (nb > 0) self.lastNeed = nb - 2; 14542 return nb; 14543 } 14544 if (--j < i) return 0; 14545 nb = utf8CheckByte(buf[j]); 14546 if (nb >= 0) { 14547 if (nb > 0) { 14548 if (nb === 2) nb = 0;else self.lastNeed = nb - 3; 14549 } 14550 return nb; 14551 } 14552 return 0; 14553} 14554 14555// Validates as many continuation bytes for a multi-byte UTF-8 character as 14556// needed or are available. If we see a non-continuation byte where we expect 14557// one, we "replace" the validated continuation bytes we've seen so far with 14558// UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding 14559// behavior. The continuation byte check is included three times in the case 14560// where all of the continuation bytes for a character exist in the same buffer. 14561// It is also done this way as a slight performance increase instead of using a 14562// loop. 14563function utf8CheckExtraBytes(self, buf, p) { 14564 if ((buf[0] & 0xC0) !== 0x80) { 14565 self.lastNeed = 0; 14566 return '\ufffd'.repeat(p); 14567 } 14568 if (self.lastNeed > 1 && buf.length > 1) { 14569 if ((buf[1] & 0xC0) !== 0x80) { 14570 self.lastNeed = 1; 14571 return '\ufffd'.repeat(p + 1); 14572 } 14573 if (self.lastNeed > 2 && buf.length > 2) { 14574 if ((buf[2] & 0xC0) !== 0x80) { 14575 self.lastNeed = 2; 14576 return '\ufffd'.repeat(p + 2); 14577 } 14578 } 14579 } 14580} 14581 14582// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. 14583function utf8FillLast(buf) { 14584 var p = this.lastTotal - this.lastNeed; 14585 var r = utf8CheckExtraBytes(this, buf, p); 14586 if (r !== undefined) return r; 14587 if (this.lastNeed <= buf.length) { 14588 buf.copy(this.lastChar, p, 0, this.lastNeed); 14589 return this.lastChar.toString(this.encoding, 0, this.lastTotal); 14590 } 14591 buf.copy(this.lastChar, p, 0, buf.length); 14592 this.lastNeed -= buf.length; 14593} 14594 14595// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a 14596// partial character, the character's bytes are buffered until the required 14597// number of bytes are available. 14598function utf8Text(buf, i) { 14599 var total = utf8CheckIncomplete(this, buf, i); 14600 if (!this.lastNeed) return buf.toString('utf8', i); 14601 this.lastTotal = total; 14602 var end = buf.length - (total - this.lastNeed); 14603 buf.copy(this.lastChar, 0, end); 14604 return buf.toString('utf8', i, end); 14605} 14606 14607// For UTF-8, a replacement character for each buffered byte of a (partial) 14608// character needs to be added to the output. 14609function utf8End(buf) { 14610 var r = buf && buf.length ? this.write(buf) : ''; 14611 if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed); 14612 return r; 14613} 14614 14615// UTF-16LE typically needs two bytes per character, but even if we have an even 14616// number of bytes available, we need to check if we end on a leading/high 14617// surrogate. In that case, we need to wait for the next two bytes in order to 14618// decode the last character properly. 14619function utf16Text(buf, i) { 14620 if ((buf.length - i) % 2 === 0) { 14621 var r = buf.toString('utf16le', i); 14622 if (r) { 14623 var c = r.charCodeAt(r.length - 1); 14624 if (c >= 0xD800 && c <= 0xDBFF) { 14625 this.lastNeed = 2; 14626 this.lastTotal = 4; 14627 this.lastChar[0] = buf[buf.length - 2]; 14628 this.lastChar[1] = buf[buf.length - 1]; 14629 return r.slice(0, -1); 14630 } 14631 } 14632 return r; 14633 } 14634 this.lastNeed = 1; 14635 this.lastTotal = 2; 14636 this.lastChar[0] = buf[buf.length - 1]; 14637 return buf.toString('utf16le', i, buf.length - 1); 14638} 14639 14640// For UTF-16LE we do not explicitly append special replacement characters if we 14641// end on a partial character, we simply let v8 handle that. 14642function utf16End(buf) { 14643 var r = buf && buf.length ? this.write(buf) : ''; 14644 if (this.lastNeed) { 14645 var end = this.lastTotal - this.lastNeed; 14646 return r + this.lastChar.toString('utf16le', 0, end); 14647 } 14648 return r; 14649} 14650 14651function base64Text(buf, i) { 14652 var n = (buf.length - i) % 3; 14653 if (n === 0) return buf.toString('base64', i); 14654 this.lastNeed = 3 - n; 14655 this.lastTotal = 3; 14656 if (n === 1) { 14657 this.lastChar[0] = buf[buf.length - 1]; 14658 } else { 14659 this.lastChar[0] = buf[buf.length - 2]; 14660 this.lastChar[1] = buf[buf.length - 1]; 14661 } 14662 return buf.toString('base64', i, buf.length - n); 14663} 14664 14665function base64End(buf) { 14666 var r = buf && buf.length ? this.write(buf) : ''; 14667 if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); 14668 return r; 14669} 14670 14671// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) 14672function simpleWrite(buf) { 14673 return buf.toString(this.encoding); 14674} 14675 14676function simpleEnd(buf) { 14677 return buf && buf.length ? this.write(buf) : ''; 14678} 14679},{"44":44}],48:[function(_dereq_,module,exports){ 14680(function (global){ 14681 14682/** 14683 * Module exports. 14684 */ 14685 14686module.exports = deprecate; 14687 14688/** 14689 * Mark that a method should not be used. 14690 * Returns a modified function which warns once by default. 14691 * 14692 * If `localStorage.noDeprecation = true` is set, then it is a no-op. 14693 * 14694 * If `localStorage.throwDeprecation = true` is set, then deprecated functions 14695 * will throw an Error when invoked. 14696 * 14697 * If `localStorage.traceDeprecation = true` is set, then deprecated functions 14698 * will invoke `console.trace()` instead of `console.error()`. 14699 * 14700 * @param {Function} fn - the function to deprecate 14701 * @param {String} msg - the string to print to the console when `fn` is invoked 14702 * @returns {Function} a new "deprecated" version of `fn` 14703 * @api public 14704 */ 14705 14706function deprecate (fn, msg) { 14707 if (config('noDeprecation')) { 14708 return fn; 14709 } 14710 14711 var warned = false; 14712 function deprecated() { 14713 if (!warned) { 14714 if (config('throwDeprecation')) { 14715 throw new Error(msg); 14716 } else if (config('traceDeprecation')) { 14717 console.trace(msg); 14718 } else { 14719 console.warn(msg); 14720 } 14721 warned = true; 14722 } 14723 return fn.apply(this, arguments); 14724 } 14725 14726 return deprecated; 14727} 14728 14729/** 14730 * Checks `localStorage` for boolean values for the given `name`. 14731 * 14732 * @param {String} name 14733 * @returns {Boolean} 14734 * @api private 14735 */ 14736 14737function config (name) {
14738 // accessing global.localStorage can trigger a DOMException in sandboxed iframes 14739 try { 14740 if (!global.localStorage) return false; 14741 } catch (_) { 14742 return false; 14743 } 14744 var val = global.localStorage[name]; 14745 if (null == val) return false; 14746 return String(val).toLowerCase() === 'true'; 14747} 14748 14749}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 14750 14751},{}],49:[function(_dereq_,module,exports){ 14752/** 14753 * The copyright in this software is being made available under the BSD License, 14754 * included below. This software may be subject to other third party and contributor 14755 * rights, including patent rights, and no such rights are granted under this license. 14756 * 14757 * Copyright (c) 2013, Dash Industry Forum. 14758 * All rights reserved. 14759 * 14760 * Redistribution and use in source and binary forms, with or without modification, 14761 * are permitted provided that the following conditions are met: 14762 * * Redistributions of source code must retain the above copyright notice, this 14763 * list of conditions and the following disclaimer. 14764 * * Redistributions in binary form must reproduce the above copyright notice, 14765 * this list of conditions and the following disclaimer in the documentation and/or 14766 * other materials provided with the distribution. 14767 * * Neither the name of Dash Industry Forum nor the names of its 14768 * contributors may be used to endorse or promote products derived from this software 14769 * without specific prior written permission. 14770 * 14771 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 14772 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14773 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 14774 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 14775 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 14776 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 14777 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 14778 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 14779 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 14780 * POSSIBILITY OF SUCH DAMAGE. 14781 */ 14782'use strict'; 14783 14784Object.defineProperty(exports, '__esModule', { 14785 value: true 14786}); 14787 14788function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 14789 14790var _EventBus = _dereq_(50); 14791 14792var _EventBus2 = _interopRequireDefault(_EventBus); 14793 14794var _eventsEvents = _dereq_(54); 14795 14796var _eventsEvents2 = _interopRequireDefault(_eventsEvents); 14797 14798var _FactoryMaker = _dereq_(51); 14799 14800var _FactoryMaker2 = _interopRequireDefault(_FactoryMaker); 14801 14802/** 14803 * @module Debug 14804 */ 14805function Debug() { 14806 14807 var context = this.context; 14808 var eventBus = (0, _EventBus2['default'])(context).getInstance(); 14809 14810 var instance = undefined, 14811 logToBrowserConsole = undefined, 14812 showLogTimestamp = undefined, 14813 showCalleeName = undefined, 14814 startTime = undefined; 14815 14816 function setup() { 14817 logToBrowserConsole = true; 14818 showLogTimestamp = true; 14819 showCalleeName = false; 14820 startTime = new Date().getTime(); 14821 } 14822 14823 /** 14824 * Prepends a timestamp in milliseconds to each log message. 14825 * @param {boolean} value Set to true if you want to see a timestamp in each log message. 14826 * @default false 14827 * @memberof module:Debug 14828 * @instance 14829 */ 14830 function setLogTimestampVisible(value) { 14831 showLogTimestamp = value; 14832 } 14833 /** 14834 * Prepends the callee object name, and media type if available, to each log message. 14835 * @param {boolean} value Set to true if you want to see the callee object name and media type in each log message. 14836 * @default false 14837 * @memberof module:Debug 14838 * @instance 14839 */ 14840 function setCalleeNameVisible(value) { 14841 showCalleeName = value; 14842 } 14843 /** 14844 * Toggles logging to the browser's javascript console. If you set to false you will still receive a log event with the same message. 14845 * @param {boolean} value Set to false if you want to turn off logging to the browser's console. 14846 * @default true 14847 * @memberof module:Debug 14848 * @instance 14849 */ 14850 function setLogToBrowserConsole(value) { 14851 logToBrowserConsole = value; 14852 } 14853 /** 14854 * Use this method to get the state of logToBrowserConsole. 14855 * @returns {boolean} The current value of logToBrowserConsole 14856 * @memberof module:Debug 14857 * @instance 14858 */ 14859 function getLogToBrowserConsole() { 14860 return logToBrowserConsole; 14861 } 14862 /** 14863 * This method will allow you send log messages to either the browser's console and/or dispatch an event to capture at the media player level. 14864 * @param {...*} arguments The message you want to log. The Arguments object is supported for this method so you can send in comma separated logging items. 14865 * @memberof module:Debug 14866 * @instance 14867 */ 14868 function log() { 14869 14870 var message = ''; 14871 var logTime = null; 14872 14873 if (showLogTimestamp) { 14874 logTime = new Date().getTime(); 14875 message += '[' + (logTime - startTime) + ']'; 14876 } 14877 14878 if (showCalleeName && this && this.getClassName) { 14879 message += '[' + this.getClassName() + ']'; 14880 if (this.getType) { 14881 message += '[' + this.getType() + ']'; 14882 } 14883 } 14884 14885 if (message.length > 0) { 14886 message += ' '; 14887 } 14888
14889 Array.apply(null, arguments).forEach(function (item) { 14890 message += item + ' '; 14891 }); 14892 14893 if (logToBrowserConsole) { 14894 console.log(message); 14895 } 14896 14897 eventBus.trigger(_eventsEvents2['default'].LOG, { message: message }); 14898 } 14899 14900 instance = { 14901 log: log, 14902 setLogTimestampVisible: setLogTimestampVisible, 14903 setCalleeNameVisible: setCalleeNameVisible, 14904 setLogToBrowserConsole: setLogToBrowserConsole, 14905 getLogToBrowserConsole: getLogToBrowserConsole 14906 }; 14907 14908 setup(); 14909 14910 return instance; 14911} 14912 14913Debug.__dashjs_factory_name = 'Debug'; 14914exports['default'] = _FactoryMaker2['default'].getSingletonFactory(Debug); 14915module.exports = exports['default']; 14916 14917},{"50":50,"51":51,"54":54}],50:[function(_dereq_,module,exports){ 14918/** 14919 * The copyright in this software is being made available under the BSD License, 14920 * included below. This software may be subject to other third party and contributor 14921 * rights, including patent rights, and no such rights are granted under this license. 14922 * 14923 * Copyright (c) 2013, Dash Industry Forum. 14924 * All rights reserved. 14925 * 14926 * Redistribution and use in source and binary forms, with or without modification, 14927 * are permitted provided that the following conditions are met: 14928 * * Redistributions of source code must retain the above copyright notice, this 14929 * list of conditions and the following disclaimer. 14930 * * Redistributions in binary form must reproduce the above copyright notice, 14931 * this list of conditions and the following disclaimer in the documentation and/or 14932 * other materials provided with the distribution. 14933 * * Neither the name of Dash Industry Forum nor the names of its 14934 * contributors may be used to endorse or promote products derived from this software 14935 * without specific prior written permission. 14936 * 14937 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 14938 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14939 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 14940 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 14941 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 14942 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 14943 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 14944 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 14945 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 14946 * POSSIBILITY OF SUCH DAMAGE. 14947 */ 14948'use strict'; 14949 14950Object.defineProperty(exports, '__esModule', { 14951 value: true 14952}); 14953 14954function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 14955 14956var _FactoryMaker = _dereq_(51); 14957 14958var _FactoryMaker2 = _interopRequireDefault(_FactoryMaker); 14959 14960var EVENT_PRIORITY_LOW = 0; 14961var EVENT_PRIORITY_HIGH = 5000; 14962 14963function EventBus() { 14964 14965 var handlers = {}; 14966 14967 function on(type, listener, scope) { 14968 var priority = arguments.length <= 3 || arguments[3] === undefined ? EVENT_PRIORITY_LOW : arguments[3]; 14969 14970 if (!type) { 14971 throw new Error('event type cannot be null or undefined'); 14972 } 14973 if (!listener || typeof listener !== 'function') { 14974 throw new Error('listener must be a function: ' + listener); 14975 } 14976 14977 if (getHandlerIdx(type, listener, scope) >= 0) return; 14978 14979 handlers[type] = handlers[type] || []; 14980 14981 var handler = { 14982 callback: listener, 14983 scope: scope, 14984 priority: priority 14985 }; 14986 14987 var inserted = handlers[type].some(function (item, idx) { 14988 if (item && priority > item.priority) { 14989 handlers[type].splice(idx, 0, handler); 14990 return true; 14991 } 14992 }); 14993 14994 if (!inserted) { 14995 handlers[type].push(handler); 14996 } 14997 } 14998 14999 function off(type, listener, scope) { 15000 if (!type || !listener || !handlers[type]) return; 15001 var idx = getHandlerIdx(type, listener, scope); 15002 if (idx < 0) return; 15003 handlers[type][idx] = null; 15004 } 15005 15006 function trigger(type, payload) { 15007 if (!type || !handlers[type]) return; 15008 15009 payload = payload || {}; 15010 15011 if (payload.hasOwnProperty('type')) throw new Error('\'type\' is a reserved word for event dispatching'); 15012 15013 payload.type = type; 15014 15015 handlers[type] = handlers[type].filter(function (item) { 15016 return item; 15017 }); 15018 handlers[type].forEach(function (handler) { 15019 return handler && handler.callback.call(handler.scope, payload); 15020 }); 15021 } 15022 15023 function getHandlerIdx(type, listener, scope) { 15024 15025 var idx = -1; 15026 15027 if (!handlers[type]) return idx; 15028 15029 handlers[type].some(function (item, index) { 15030 if (item && item.callback === listener && (!scope || scope === item.scope)) { 15031 idx = index; 15032 return true; 15033 } 15034 }); 15035 return idx; 15036 } 15037 15038 function reset() { 15039 handlers = {}; 15040 } 15041 15042 var instance = { 15043 on: on, 15044 off: off, 15045 trigger: trigger, 15046 reset: reset 15047 }; 15048 15049 return instance; 15050} 15051 15052EventBus.__dashjs_factory_name = 'EventBus'; 15053var factory = _FactoryMaker2['default'].getSingletonFactory(EventBus); 15054factory.EVENT_PRIORITY_LOW = EVENT_PRIORITY_LOW; 15055factory.EVENT_PRIORITY_HIGH = EVENT_PRIORITY_HIGH; 15056_FactoryMaker2['default'].updateSingletonFactory(EventBus.__dashjs_factory_name, factory); 15057exports['default'] = factory; 15058module.exports = exports['default']; 15059 15060},{"51":51}],51:[function(_dereq_,module,exports){ 15061/** 15062 * The copyright in this software is being made available under the BSD License, 15063 * included below. This software may be subject to other third party and contributor 15064 * rights, including patent rights, and no such rights are granted under this license. 15065 * 15066 * Copyright (c) 2013, Dash Industry Forum. 15067 * All rights reserved. 15068 * 15069 * Redistribution and use in source and binary forms, with or without modification, 15070 * are permitted provided that the following conditions are met: 15071 * * Redistributions of source code must retain the above copyright notice, this 15072 * list of conditions and the following disclaimer. 15073 * * Redistributions in binary form must reproduce the above copyright notice, 15074 * this list of conditions and the following disclaimer in the documentation and/or 15075 * other materials provided with the distribution. 15076 * * Neither the name of Dash Industry Forum nor the names of its 15077 * contributors may be used to endorse or promote products derived from this software 15078 * without specific prior written permission. 15079 * 15080 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 15081 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15082 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 15083 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 15084 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
15084INCLUDING, BUT 15085 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 15086 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 15087 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 15088 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 15089 * POSSIBILITY OF SUCH DAMAGE. 15090 */ 15091/** 15092 * @module FactoryMaker 15093 */ 15094"use strict"; 15095 15096Object.defineProperty(exports, "__esModule", { 15097 value: true 15098}); 15099var FactoryMaker = (function () { 15100 15101 var instance = undefined; 15102 var extensions = []; 15103 var singletonContexts = []; 15104 var singletonFactories = []; 15105 var classFactories = []; 15106 15107 function extend(name, childInstance, override, context) { 15108 var extensionContext = getExtensionContext(context); 15109 if (!extensionContext[name] && childInstance) { 15110 extensionContext[name] = { 15111 instance: childInstance, 15112 override: override 15113 }; 15114 } 15115 } 15116 15117 /** 15118 * Use this method from your extended object. this.factory is injected into your object. 15119 * this.factory.getSingletonInstance(this.context, 'VideoModel') 15120 * will return the video model for use in the extended object. 15121 * 15122 * @param {Object} context - injected into extended object as this.context 15123 * @param {string} className - string name found in all dash.js objects 15124 * with name __dashjs_factory_name Will be at the bottom. Will be the same as the object's name. 15125 * @returns {*} Context aware instance of specified singleton name. 15126 * @memberof module:FactoryMaker 15127 * @instance 15128 */ 15129 function getSingletonInstance(context, className) { 15130 for (var i in singletonContexts) { 15131 var obj = singletonContexts[i]; 15132 if (obj.context === context && obj.name === className) { 15133 return obj.instance; 15134 } 15135 } 15136 return null; 15137 } 15138 15139 /** 15140 * Use this method to add an singleton instance to the system. Useful for unit testing to mock objects etc. 15141 * 15142 * @param {Object} context 15143 * @param {string} className 15144 * @param {Object} instance 15145 * @memberof module:FactoryMaker 15146 * @instance 15147 */ 15148 function setSingletonInstance(context, className, instance) { 15149 for (var i in singletonContexts) { 15150 var obj = singletonContexts[i]; 15151 if (obj.context === context && obj.name === className) { 15152 singletonContexts[i].instance = instance; 15153 return; 15154 } 15155 } 15156 singletonContexts.push({ 15157 name: className, 15158 context: context, 15159 instance: instance 15160 }); 15161 } 15162 15163 /*------------------------------------------------------------------------------------------*/ 15164 15165 // Factories storage Management 15166 15167 /*------------------------------------------------------------------------------------------*/ 15168 15169 function registerFactory(name, factory, factoriesArray) { 15170 for (var i in factoriesArray) { 15171 var obj = factoriesArray[i]; 15172 if (obj.name === name) { 15173 factoriesArray[i].factory = factory; 15174 return; 15175 } 15176 } 15177 factoriesArray.push({ 15178 name: name, 15179 factory: factory 15180 }); 15181 } 15182 15183 function getFactoryByName(name, factoriesArray) { 15184 for (var i in factoriesArray) { 15185 var obj = factoriesArray[i]; 15186 if (obj.name === name) { 15187 return factoriesArray[i].factory; 15188 } 15189 } 15190 return null; 15191 } 15192 15193 function updateFactory(name, factory, factoriesArray) { 15194 for (var i in factoriesArray) { 15195 var obj = factoriesArray[i]; 15196 if (obj.name === name) { 15197 factoriesArray[i].factory = factory; 15198 return; 15199 } 15200 } 15201 } 15202 15203 /*------------------------------------------------------------------------------------------*/ 15204 15205 // Class Factories Management 15206 15207 /*------------------------------------------------------------------------------------------*/ 15208 15209 function updateClassFactory(name, factory) { 15210 updateFactory(name, factory, classFactories); 15211 } 15212 15213 function getClassFactoryByName(name) { 15214 return getFactoryByName(name, classFactories); 15215 } 15216 15217 function getClassFactory(classConstructor) { 15218 var factory = getFactoryByName(classConstructor.__dashjs_factory_name, classFactories); 15219 15220 if (!factory) { 15221 factory = function (context) { 15222 if (context === undefined) { 15223 context = {}; 15224 } 15225 return { 15226 create: function create() { 15227 return merge(classConstructor.__dashjs_factory_name, classConstructor.apply({
15228 context: context 15229 }, arguments), context, arguments); 15230 } 15231 }; 15232 }; 15233 15234 registerFactory(classConstructor.__dashjs_factory_name, factory, classFactories); // store factory 15235 } 15236 return factory; 15237 } 15238 15239 /*------------------------------------------------------------------------------------------*/ 15240 15241 // Singleton Factory MAangement 15242 15243 /*------------------------------------------------------------------------------------------*/ 15244 15245 function updateSingletonFactory(name, factory) { 15246 updateFactory(name, factory, singletonFactories); 15247 } 15248 15249 function getSingletonFactoryByName(name) { 15250 return getFactoryByName(name, singletonFactories); 15251 } 15252 15253 function getSingletonFactory(classConstructor) { 15254 var factory = getFactoryByName(classConstructor.__dashjs_factory_name, singletonFactories); 15255 if (!factory) { 15256 factory = function (context) { 15257 var instance = undefined; 15258 if (context === undefined) { 15259 context = {}; 15260 } 15261 return { 15262 getInstance: function getInstance() { 15263 // If we don't have an instance yet check for one on the context 15264 if (!instance) { 15265 instance = getSingletonInstance(context, classConstructor.__dashjs_factory_name); 15266 } 15267 // If there's no instance on the context then create one 15268 if (!instance) { 15269 instance = merge(classConstructor.__dashjs_factory_name, classConstructor.apply({ 15270 context: context 15271 }, arguments), context, arguments); 15272 singletonContexts.push({ 15273 name: classConstructor.__dashjs_factory_name, 15274 context: context, 15275 instance: instance 15276 }); 15277 } 15278 return instance; 15279 } 15280 }; 15281 }; 15282 registerFactory(classConstructor.__dashjs_factory_name, factory, singletonFactories); // store factory 15283 } 15284 15285 return factory; 15286 } 15287 15288 function merge(name, classConstructor, context, args) { 15289 // Add getClassName function to class instance prototype (used by Debug) 15290 classConstructor.getClassName = function () { 15291 return name; 15292 }; 15293 15294 var extensionContext = getExtensionContext(context); 15295 var extensionObject = extensionContext[name]; 15296 if (extensionObject) { 15297 var extension = extensionObject.instance; 15298 if (extensionObject.override) { 15299 //Override public methods in parent but keep parent. 15300 extension = extension.apply({ 15301 context: context, 15302 factory: instance, 15303 parent: classConstructor 15304 }, args); 15305 for (var prop in extension) { 15306 if (classConstructor.hasOwnProperty(prop)) { 15307 classConstructor[prop] = extension[prop]; 15308 } 15309 } 15310 } else { 15311 //replace parent object completely with new object. Same as dijon. 15312 return extension.apply({ 15313 context: context, 15314 factory: instance 15315 }, args); 15316 } 15317 } 15318 return classConstructor; 15319 } 15320 15321 function getExtensionContext(context) { 15322 var extensionContext = undefined; 15323 extensions.forEach(function (obj) { 15324 if (obj === context) { 15325 extensionContext = obj; 15326 } 15327 }); 15328 if (!extensionContext) { 15329 extensions.push(context); 15330 extensionContext = context; 15331 } 15332 return extensionContext; 15333 } 15334 15335 instance = { 15336 extend: extend, 15337 getSingletonInstance: getSingletonInstance, 15338 setSingletonInstance: setSingletonInstance, 15339 getSingletonFactory: getSingletonFactory, 15340 getSingletonFactoryByName: getSingletonFactoryByName, 15341 updateSingletonFactory: updateSingletonFactory, 15342 getClassFactory: getClassFactory, 15343 getClassFactoryByName: getClassFactoryByName, 15344 updateClassFactory: updateClassFactory 15345 }; 15346 15347 return instance; 15348})(); 15349 15350exports["default"] = FactoryMaker; 15351module.exports = exports["default"]; 15352 15353},{}],52:[function(_dereq_,module,exports){ 15354'use strict'; 15355 15356Object.defineProperty(exports, '__esModule', { 15357 value: true 15358}); 15359exports.getVersionString = getVersionString; 15360var VERSION = '2.6.2'; 15361 15362function getVersionString() { 15363 return VERSION; 15364} 15365 15366},{}],53:[function(_dereq_,module,exports){ 15367/** 15368 * The copyright in this software is being made available under the BSD License, 15369 * included below. This software may be subject to other third party and contributor 15370 * rights, including patent rights, and no such rights are granted under this license. 15371 * 15372 * Copyright (c) 2013, Dash Industry Forum. 15373 * All rights reserved. 15374 * 15375 * Redistribution and use in source and binary forms, with or without modification, 15376 * are permitted provided that the following conditions are met: 15377 * * Redistributions of source code must retain the above copyright notice, this 15378 * list of conditions and the following disclaimer. 15379 * * Redistributions in binary form must reproduce the above copyright notice, 15380 * this list of conditions and the following disclaimer in the documentation and/or 15381 * other materials provided with the distribution. 15382 * * Neither the name of Dash Industry Forum nor the names of its 15383 * contributors may be used to endorse or promote products derived from this software 15384 * without specific prior written permission. 15385 * 15386 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 15387 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15388 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 15389 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 15390 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
15390INCLUDING, BUT 15391 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 15392 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 15393 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 15394 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 15395 * POSSIBILITY OF SUCH DAMAGE. 15396 */ 15397'use strict'; 15398 15399Object.defineProperty(exports, '__esModule', { 15400 value: true 15401}); 15402 15403var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 15404 15405function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 15406 15407function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 15408 15409function _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; } 15410 15411var _EventsBase2 = _dereq_(55); 15412 15413var _EventsBase3 = _interopRequireDefault(_EventsBase2); 15414 15415/** 15416 * These are internal events that should not be needed at the player level. 15417 * If you find and event in here that you would like access to from MediaPlayer level 15418 * please add an issue at https://github.com/Dash-Industry-Forum/dash.js/issues/new 15419 * @class 15420 * @ignore 15421 */ 15422 15423var CoreEvents = (function (_EventsBase) { 15424 _inherits(CoreEvents, _EventsBase); 15425 15426 function CoreEvents() { 15427 _classCallCheck(this, CoreEvents); 15428 15429 _get(Object.getPrototypeOf(CoreEvents.prototype), 'constructor', this).call(this); 15430 this.BUFFERING_COMPLETED = 'bufferingCompleted'; 15431 this.BUFFER_CLEARED = 'bufferCleared'; 15432 this.BUFFER_LEVEL_UPDATED = 'bufferLevelUpdated'; 15433 this.BYTES_APPENDED = 'bytesAppended'; 15434 this.CHECK_FOR_EXISTENCE_COMPLETED = 'checkForExistenceCompleted'; 15435 this.CURRENT_TRACK_CHANGED = 'currentTrackChanged'; 15436 this.DATA_UPDATE_COMPLETED = 'dataUpdateCompleted'; 15437 this.DATA_UPDATE_STARTED = 'dataUpdateStarted'; 15438 this.INITIALIZATION_LOADED = 'initializationLoaded'; 15439 this.INIT_FRAGMENT_LOADED = 'initFragmentLoaded'; 15440 this.INIT_REQUESTED = 'initRequested'; 15441 this.INTERNAL_MANIFEST_LOADED = 'internalManifestLoaded'; 15442 this.LIVE_EDGE_SEARCH_COMPLETED = 'liveEdgeSearchCompleted'; 15443 this.LOADING_COMPLETED = 'loadingCompleted'; 15444 this.LOADING_PROGRESS = 'loadingProgress'; 15445 this.LOADING_ABANDONED = 'loadingAborted'; 15446 this.MANIFEST_UPDATED = 'manifestUpdated'; 15447 this.MEDIA_FRAGMENT_LOADED = 'mediaFragmentLoaded'; 15448 this.QUOTA_EXCEEDED = 'quotaExceeded'; 15449 this.REPRESENTATION_UPDATED = 'representationUpdated'; 15450 this.SEGMENTS_LOADED = 'segmentsLoaded'; 15451 this.SERVICE_LOCATION_BLACKLIST_ADD = 'serviceLocationBlacklistAdd'; 15452 this.SERVICE_LOCATION_BLACKLIST_CHANGED = 'serviceLocationBlacklistChanged'; 15453 this.SOURCEBUFFER_APPEND_COMPLETED = 'sourceBufferAppendCompleted'; 15454 this.SOURCEBUFFER_REMOVE_COMPLETED = 'sourceBufferRemoveCompleted'; 15455 this.STREAMS_COMPOSED = 'streamsComposed'; 15456 this.STREAM_BUFFERING_COMPLETED = 'streamBufferingCompleted'; 15457 this.STREAM_COMPLETED = 'streamCompleted'; 15458 this.TIMED_TEXT_REQUESTED = 'timedTextRequested'; 15459 this.TIME_SYNCHRONIZATION_COMPLETED = 'timeSynchronizationComplete'; 15460 this.URL_RESOLUTION_FAILED = 'urlResolutionFailed'; 15461 this.VIDEO_CHUNK_RECEIVED = 'videoChunkReceived'; 15462 this.WALLCLOCK_TIME_UPDATED = 'wallclockTimeUpdated'; 15463 this.XLINK_ELEMENT_LOADED = 'xlinkElementLoaded'; 15464 this.XLINK_READY = 'xlinkReady'; 15465 } 15466 15467 return CoreEvents; 15468})(_EventsBase3['default']); 15469 15470exports['default'] = CoreEvents; 15471module.exports = exports['default']; 15472 15473},{"55":55}],54:[function(_dereq_,module,exports){ 15474/** 15475 * The copyright in this software is being made available under the BSD License, 15476 * included below. This software may be subject to other third party and contributor 15477 * rights, including patent rights, and no such rights are granted under this license. 15478 * 15479 * Copyright (c) 2013, Dash Industry Forum. 15480 * All rights reserved. 15481 * 15482 * Redistribution and use in source and binary forms, with or without modification, 15483 * are permitted provided that the following conditions are met: 15484 * * Redistributions of source code must retain the above copyright notice, this 15485 * list of conditions and the following disclaimer. 15486 * * Redistributions in binary form must reproduce the above copyright notice, 15487 * this list of conditions and the following disclaimer in the documentation and/or 15488 * other materials provided with the distribution. 15489 * * Neither the name of Dash Industry Forum nor the names of its 15490 * contributors may be used to endorse or promote products derived from this software 15491 * without specific prior written permission. 15492 * 15493 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 15494 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15495 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 15496 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 15497 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
15497INCLUDING, BUT 15498 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 15499 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 15500 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 15501 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 15502 * POSSIBILITY OF SUCH DAMAGE. 15503 */ 15504/** 15505 * @class 15506 * @ignore 15507 */ 15508'use strict'; 15509 15510Object.defineProperty(exports, '__esModule', { 15511 value: true 15512}); 15513 15514var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 15515 15516function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 15517 15518function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 15519 15520function _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; } 15521 15522var _CoreEvents2 = _dereq_(53); 15523 15524var _CoreEvents3 = _interopRequireDefault(_CoreEvents2); 15525 15526var Events = (function (_CoreEvents) { 15527 _inherits(Events, _CoreEvents); 15528 15529 function Events() { 15530 _classCallCheck(this, Events); 15531 15532 _get(Object.getPrototypeOf(Events.prototype), 'constructor', this).apply(this, arguments); 15533 } 15534 15535 return Events; 15536})(_CoreEvents3['default']); 15537 15538var events = new Events(); 15539exports['default'] = events; 15540module.exports = exports['default']; 15541 15542},{"53":53}],55:[function(_dereq_,module,exports){ 15543/** 15544 * The copyright in this software is being made available under the BSD License, 15545 * included below. This software may be subject to other third party and contributor 15546 * rights, including patent rights, and no such rights are granted under this license. 15547 * 15548 * Copyright (c) 2013, Dash Industry Forum. 15549 * All rights reserved. 15550 * 15551 * Redistribution and use in source and binary forms, with or without modification, 15552 * are permitted provided that the following conditions are met: 15553 * * Redistributions of source code must retain the above copyright notice, this 15554 * list of conditions and the following disclaimer. 15555 * * Redistributions in binary form must reproduce the above copyright notice, 15556 * this list of conditions and the following disclaimer in the documentation and/or 15557 * other materials provided with the distribution. 15558 * * Neither the name of Dash Industry Forum nor the names of its 15559 * contributors may be used to endorse or promote products derived from this software 15560 * without specific prior written permission. 15561 * 15562 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 15563 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15564 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 15565 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 15566 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 15567 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 15568 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 15569 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 15570 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 15571 * POSSIBILITY OF SUCH DAMAGE. 15572 */ 15573/** 15574 * @class 15575 * @ignore 15576 */ 15577'use strict'; 15578 15579Object.defineProperty(exports, '__esModule', { 15580 value: true 15581}); 15582 15583var _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; }; })();
15584 15585function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 15586 15587var EventsBase = (function () { 15588 function EventsBase() { 15589 _classCallCheck(this, EventsBase); 15590 } 15591 15592 _createClass(EventsBase, [{ 15593 key: 'extend', 15594 value: function extend(events, config) { 15595 if (!events) return; 15596 15597 var override = config ? config.override : false; 15598 var publicOnly = config ? config.publicOnly : false; 15599 15600 for (var evt in events) { 15601 if (!events.hasOwnProperty(evt) || this[evt] && !override) continue; 15602 if (publicOnly && events[evt].indexOf('public_') === -1) continue; 15603 this[evt] = events[evt]; 15604 } 15605 } 15606 }]); 15607 15608 return EventsBase; 15609})(); 15610 15611exports['default'] = EventsBase; 15612module.exports = exports['default']; 15613 15614},{}],56:[function(_dereq_,module,exports){ 15615/** 15616 * The copyright in this software is being made available under the BSD License, 15617 * included below. This software may be subject to other third party and contributor 15618 * rights, including patent rights, and no such rights are granted under this license. 15619 * 15620 * Copyright (c) 2013, Dash Industry Forum. 15621 * All rights reserved. 15622 * 15623 * Redistribution and use in source and binary forms, with or without modification, 15624 * are permitted provided that the following conditions are met: 15625 * * Redistributions of source code must retain the above copyright notice, this 15626 * list of conditions and the following disclaimer. 15627 * * Redistributions in binary form must reproduce the above copyright notice, 15628 * this list of conditions and the following disclaimer in the documentation and/or 15629 * other materials provided with the distribution. 15630 * * Neither the name of Dash Industry Forum nor the names of its 15631 * contributors may be used to endorse or promote products derived from this software 15632 * without specific prior written permission. 15633 * 15634 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 15635 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15636 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 15637 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 15638 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 15639 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 15640 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 15641 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 15642 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 15643 * POSSIBILITY OF SUCH DAMAGE. 15644 */ 15645 15646'use strict'; 15647 15648Object.defineProperty(exports, '__esModule', { 15649 value: true 15650}); 15651 15652function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 15653 15654var _streamingConstantsConstants = _dereq_(100); 15655 15656var _streamingConstantsConstants2 = _interopRequireDefault(_streamingConstantsConstants); 15657 15658var _streamingVoRepresentationInfo = _dereq_(215); 15659 15660var _streamingVoRepresentationInfo2 = _interopRequireDefault(_streamingVoRepresentationInfo); 15661 15662var _streamingVoMediaInfo = _dereq_(213); 15663 15664var _streamingVoMediaInfo2 = _interopRequireDefault(_streamingVoMediaInfo); 15665 15666var _streamingVoStreamInfo = _dereq_(216); 15667 15668var _streamingVoStreamInfo2 = _interopRequireDefault(_streamingVoStreamInfo); 15669 15670var _streamingVoManifestInfo = _dereq_(212); 15671 15672var _streamingVoManifestInfo2 = _interopRequireDefault(_streamingVoManifestInfo); 15673 15674var _voEvent = _dereq_(83); 15675 15676var _voEvent2 = _interopRequireDefault(_voEvent); 15677 15678var _coreFactoryMaker = _dereq_(51); 15679 15680var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 15681 15682var _externalsCea608Parser = _dereq_(2); 15683 15684var _externalsCea608Parser2 = _interopRequireDefault(_externalsCea608Parser); 15685 15686function DashAdapter() { 15687 var instance = undefined, 15688 dashManifestModel = undefined, 15689 voPeriods = undefined, 15690 voAdaptations = undefined; 15691 15692 function setup() { 15693 reset(); 15694 } 15695 15696 function setConfig(config) { 15697 if (!config) return; 15698 15699 if (config.dashManifestModel) { 15700 dashManifestModel = config.dashManifestModel; 15701 } 15702 } 15703 15704 function getRepresentationForRepresentationInfo(representationInfo, representationController) { 15705 return representationController && representationInfo ? representationController.getRepresentationForQuality(representationInfo.quality) : null; 15706 } 15707 15708 function getAdaptationForMediaInfo(mediaInfo) { 15709 15710 if (!mediaInfo || !mediaInfo.streamInfo || mediaInfo.streamInfo.id === undefined || !voAdaptations[mediaInfo.streamInfo.id]) return null; 15711 return voAdaptations[mediaInfo.streamInfo.id][mediaInfo.index]; 15712 } 15713 15714 function getPeriodForStreamInfo(streamInfo, voPeriodsArray) { 15715 var ln = voPeriodsArray.length; 15716 15717 for (var i = 0; i < ln; i++) { 15718 var voPeriod = voPeriodsArray[i]; 15719 15720 if (streamInfo.id === voPeriod.id) return voPeriod; 15721 } 15722 15723 return null; 15724 } 15725 15726 function convertRepresentationToRepresentationInfo(voRepresentation) { 15727 var representationInfo = new _streamingVoRepresentationInfo2['default'](); 15728 var realAdaptation = voRepresentation.adaptation.period.mpd.manifest.Period_asArray[voRepresentation.adaptation.period.index].AdaptationSet_asArray[voRepresentation.adaptation.index]; 15729 var realRepresentation = dashManifestModel.getRepresentationFor(voRepresentation.index, realAdaptation); 15730 15731 representationInfo.id = voRepresentation.id; 15732 representationInfo.quality = voRepresentation.index; 15733 representationInfo.bandwidth = dashManifestModel.getBandwidth(realRepresentation); 15734 representationInfo.DVRWindow = voRepresentation.segmentAvailabilityRange; 15735 representationInfo.fragmentDuration = voRepresentation.segmentDuration || (voRepresentation.segments && voRepresentation.segments.length > 0 ? voRepresentation.segments[0].duration : NaN); 15736 representationInfo.MSETimeOffset = voRepresentation.MSETimeOffset; 15737 representationInfo.useCalculatedLiveEdgeTime = voRepresentation.useCalculatedLiveEdgeTime; 15738 representationInfo.mediaInfo = convertAdaptationToMediaInfo(voRepresentation.adaptation); 15739 15740 return representationInfo; 15741 } 15742 15743 function convertAdaptationToMediaInfo(adaptation) {
15744 var mediaInfo = new _streamingVoMediaInfo2['default'](); 15745 var realAdaptation = adaptation.period.mpd.manifest.Period_asArray[adaptation.period.index].AdaptationSet_asArray[adaptation.index]; 15746 var viewpoint = undefined; 15747 15748 mediaInfo.id = adaptation.id; 15749 mediaInfo.index = adaptation.index; 15750 mediaInfo.type = adaptation.type; 15751 mediaInfo.streamInfo = convertPeriodToStreamInfo(adaptation.period); 15752 mediaInfo.representationCount = dashManifestModel.getRepresentationCount(realAdaptation); 15753 mediaInfo.lang = dashManifestModel.getLanguageForAdaptation(realAdaptation); 15754 viewpoint = dashManifestModel.getViewpointForAdaptation(realAdaptation); 15755 mediaInfo.viewpoint = viewpoint ? viewpoint.value : undefined; 15756 mediaInfo.accessibility = dashManifestModel.getAccessibilityForAdaptation(realAdaptation).map(function (accessibility) { 15757 var accessibilityValue = accessibility.value; 15758 var accessibilityData = accessibilityValue; 15759 if (accessibility.schemeIdUri && accessibility.schemeIdUri.search('cea-608') >= 0 && typeof _externalsCea608Parser2['default'] !== 'undefined') { 15760 if (accessibilityValue) { 15761 accessibilityData = 'cea-608:' + accessibilityValue; 15762 } else { 15763 accessibilityData = 'cea-608'; 15764 } 15765 mediaInfo.embeddedCaptions = true; 15766 } 15767 return accessibilityData; 15768 }); 15769 15770 mediaInfo.audioChannelConfiguration = dashManifestModel.getAudioChannelConfigurationForAdaptation(realAdaptation).map(function (audioChannelConfiguration) { 15771 return audioChannelConfiguration.value; 15772 }); 15773 mediaInfo.roles = dashManifestModel.getRolesForAdaptation(realAdaptation).map(function (role) { 15774 return role.value; 15775 }); 15776 mediaInfo.codec = dashManifestModel.getCodec(realAdaptation); 15777 mediaInfo.mimeType = dashManifestModel.getMimeType(realAdaptation); 15778 mediaInfo.contentProtection = dashManifestModel.getContentProtectionData(realAdaptation); 15779 mediaInfo.bitrateList = dashManifestModel.getBitrateListForAdaptation(realAdaptation); 15780 15781 if (mediaInfo.contentProtection) { 15782 mediaInfo.contentProtection.forEach(function (item) { 15783 item.KID = dashManifestModel.getKID(item); 15784 }); 15785 } 15786 15787 mediaInfo.isText = dashManifestModel.getIsTextTrack(mediaInfo.mimeType); 15788 15789 return mediaInfo; 15790 } 15791 15792 function convertVideoInfoToEmbeddedTextInfo(mediaInfo, channel, lang) { 15793 mediaInfo.id = channel; // CC1, CC2, CC3, or CC4 15794 mediaInfo.index = 100 + parseInt(channel.substring(2, 3)); 15795 mediaInfo.type = _streamingConstantsConstants2['default'].EMBEDDED_TEXT; 15796 mediaInfo.codec = 'cea-608-in-SEI'; 15797 mediaInfo.isText = true; 15798 mediaInfo.isEmbedded = true; 15799 mediaInfo.lang = channel + ' ' + lang; 15800 mediaInfo.roles = ['caption']; 15801 } 15802 15803 function convertPeriodToStreamInfo(period) { 15804 var streamInfo = new _streamingVoStreamInfo2['default'](); 15805 var THRESHOLD = 1; 15806 15807 streamInfo.id = period.id; 15808 streamInfo.index = period.index; 15809 streamInfo.start = period.start; 15810 streamInfo.duration = period.duration; 15811 streamInfo.manifestInfo = convertMpdToManifestInfo(period.mpd); 15812 streamInfo.isLast = period.mpd.manifest.Period_asArray.length === 1 || Math.abs(streamInfo.start + streamInfo.duration - streamInfo.manifestInfo.duration) < THRESHOLD; 15813 15814 return streamInfo; 15815 } 15816 15817 function convertMpdToManifestInfo(mpd) { 15818 var manifestInfo = new _streamingVoManifestInfo2['default'](); 15819 15820 manifestInfo.DVRWindowSize = mpd.timeShiftBufferDepth; 15821 manifestInfo.loadedTime = mpd.manifest.loadedTime; 15822 manifestInfo.availableFrom = mpd.availabilityStartTime; 15823 manifestInfo.minBufferTime = mpd.manifest.minBufferTime; 15824 manifestInfo.maxFragmentDuration = mpd.maxSegmentDuration; 15825 manifestInfo.duration = dashManifestModel.getDuration(mpd.manifest); 15826 manifestInfo.isDynamic = dashManifestModel.getIsDynamic(mpd.manifest); 15827 15828 return manifestInfo; 15829 } 15830 15831 function getMediaInfoForType(streamInfo, type) { 15832 15833 if (voPeriods.length === 0) { 15834 return null; 15835 } 15836 15837 var manifest = voPeriods[0].mpd.manifest; 15838 var realAdaptation = dashManifestModel.getAdaptationForType(manifest, streamInfo.index, type, streamInfo); 15839 if (!realAdaptation) return null; 15840 15841 var selectedVoPeriod = getPeriodForStreamInfo(streamInfo, voPeriods); 15842 var periodId = selectedVoPeriod.id; 15843 var idx = dashManifestModel.getIndexForAdaptation(realAdaptation, manifest, streamInfo.index); 15844 15845 voAdaptations[periodId] = voAdaptations[periodId] || dashManifestModel.getAdaptationsForPeriod(selectedVoPeriod); 15846 15847 return convertAdaptationToMediaInfo(voAdaptations[periodId][idx]); 15848 } 15849 15850 function getAllMediaInfoForType(streamInfo, type, externalManifest) { 15851 var voLocalPeriods = voPeriods; 15852 var manifest = externalManifest; 15853 var mediaArr = []; 15854 var data = undefined, 15855 media = undefined, 15856 idx = undefined, 15857 i = undefined, 15858 j = undefined, 15859 ln = undefined; 15860 15861 if (manifest) { 15862 checkSetConfigCall(); 15863 var mpd = dashManifestModel.getMpd(manifest); 15864 15865 voLocalPeriods = dashManifestModel.getRegularPeriods(mpd); 15866 } else { 15867 if (voPeriods.length > 0) { 15868 manifest = voPeriods[0].mpd.manifest; 15869 } else { 15870 return mediaArr; 15871 } 15872 } 15873 15874 var selectedVoPeriod = getPeriodForStreamInfo(streamInfo, voLocalPeriods); 15875 var periodId = selectedVoPeriod.id; 15876 var adaptationsForType = dashManifestModel.getAdaptationsForType(manifest, streamInfo.index, type !== _streamingConstantsConstants2['default'].EMBEDDED_TEXT ? type : _streamingConstantsConstants2['default'].VIDEO); 15877 15878 if (!adaptationsForType) return mediaArr; 15879 15880 voAdaptations[periodId] = voAdaptations[periodId] || dashManifestModel.getAdaptationsForPeriod(selectedVoPeriod); 15881 15882 for (i = 0, ln = adaptationsForType.length; i < ln; i++) { 15883 data = adaptationsForType[i]; 15884 idx = dashManifestModel.getIndexForAdaptation(data, manifest, streamInfo.index); 15885 media = convertAdaptationToMediaInfo(voAdaptations[periodId][idx]); 15886 15887 if (type === _streamingConstantsConstants2['default'].EMBEDDED_TEXT) { 15888 var accessibilityLength = media.accessibility.length; 15889 for (j = 0; j < accessibilityLength; j++) { 15890 if (!media) { 15891 continue; 15892 } 15893 var accessibility = media.accessibility[j];
15894 if (accessibility.indexOf('cea-608:') === 0) { 15895 var value = accessibility.substring(8); 15896 var parts = value.split(';'); 15897 if (parts[0].substring(0, 2) === 'CC') { 15898 for (j = 0; j < parts.length; j++) { 15899 if (!media) { 15900 media = convertAdaptationToMediaInfo.call(this, voAdaptations[periodId][idx]); 15901 } 15902 convertVideoInfoToEmbeddedTextInfo(media, parts[j].substring(0, 3), parts[j].substring(4)); 15903 mediaArr.push(media); 15904 media = null; 15905 } 15906 } else { 15907 for (j = 0; j < parts.length; j++) { 15908 // Only languages for CC1, CC2, ... 15909 if (!media) { 15910 media = convertAdaptationToMediaInfo.call(this, voAdaptations[periodId][idx]); 15911 } 15912 convertVideoInfoToEmbeddedTextInfo(media, 'CC' + (j + 1), parts[j]); 15913 mediaArr.push(media); 15914 media = null; 15915 } 15916 } 15917 } else if (accessibility.indexOf('cea-608') === 0) { 15918 // Nothing known. We interpret it as CC1=eng 15919 convertVideoInfoToEmbeddedTextInfo(media, _streamingConstantsConstants2['default'].CC1, 'eng'); 15920 mediaArr.push(media); 15921 media = null; 15922 } 15923 } 15924 } 15925 if (media && type !== _streamingConstantsConstants2['default'].EMBEDDED_TEXT) { 15926 mediaArr.push(media); 15927 } 15928 } 15929 15930 return mediaArr; 15931 } 15932 15933 function checkSetConfigCall() { 15934 if (!dashManifestModel || !dashManifestModel.hasOwnProperty('getMpd') || !dashManifestModel.hasOwnProperty('getRegularPeriods')) { 15935 throw new Error('setConfig function has to be called previously'); 15936 } 15937 } 15938 15939 function updatePeriods(newManifest) { 15940 if (!newManifest) return null; 15941 15942 checkSetConfigCall(); 15943 15944 var mpd = dashManifestModel.getMpd(newManifest); 15945 15946 voPeriods = dashManifestModel.getRegularPeriods(mpd); 15947 voAdaptations = {}; 15948 } 15949 15950 function getStreamsInfo(externalManifest) { 15951 var streams = []; 15952 var voLocalPeriods = voPeriods; 15953 15954 //if manifest is defined, getStreamsInfo is for an outside manifest, not the current one 15955 if (externalManifest) { 15956 checkSetConfigCall(); 15957 var mpd = dashManifestModel.getMpd(externalManifest); 15958 15959 voLocalPeriods = dashManifestModel.getRegularPeriods(mpd); 15960 } 15961 15962 for (var i = 0; i < voLocalPeriods.length; i++) { 15963 streams.push(convertPeriodToStreamInfo(voLocalPeriods[i])); 15964 } 15965 15966 return streams; 15967 } 15968 15969 function checkStreamProcessor(streamProcessor) { 15970 if (!streamProcessor || !streamProcessor.hasOwnProperty('getRepresentationController') || !streamProcessor.hasOwnProperty('getIndexHandler') || !streamProcessor.hasOwnProperty('getMediaInfo') || !streamProcessor.hasOwnProperty('getType') || !streamProcessor.hasOwnProperty('getStreamInfo')) { 15971 throw new Error('streamProcessor parameter is missing or malformed!'); 15972 } 15973 } 15974 15975 function checkRepresentationController(representationController) { 15976 if (!representationController || !representationController.hasOwnProperty('getRepresentationForQuality') || !representationController.hasOwnProperty('getCurrentRepresentation')) { 15977 throw new Error('representationController parameter is missing or malformed!'); 15978 } 15979 } 15980 15981 function checkQuality(quality) { 15982 var isInt = quality !== null && !isNaN(quality) && quality % 1 === 0; 15983 15984 if (!isInt) {
15985 throw new Error('quality argument is not an integer'); 15986 } 15987 } 15988 15989 function getInitRequest(streamProcessor, quality) { 15990 var representationController = undefined, 15991 representation = undefined, 15992 indexHandler = undefined; 15993 15994 checkStreamProcessor(streamProcessor); 15995 checkQuality(quality); 15996 15997 representationController = streamProcessor.getRepresentationController(); 15998 indexHandler = streamProcessor.getIndexHandler(); 15999 16000 representation = representationController ? representationController.getRepresentationForQuality(quality) : null; 16001 16002 return indexHandler ? indexHandler.getInitRequest(representation) : null; 16003 } 16004 16005 function getNextFragmentRequest(streamProcessor, trackInfo) { 16006 var representationController = undefined, 16007 representation = undefined, 16008 indexHandler = undefined; 16009 16010 checkStreamProcessor(streamProcessor); 16011 16012 representationController = streamProcessor.getRepresentationController(); 16013 representation = getRepresentationForRepresentationInfo(trackInfo, representationController); 16014 indexHandler = streamProcessor.getIndexHandler(); 16015 16016 return indexHandler ? indexHandler.getNextSegmentRequest(representation) : null; 16017 } 16018 16019 function getFragmentRequestForTime(streamProcessor, trackInfo, time, options) { 16020 var representationController = undefined, 16021 representation = undefined, 16022 indexHandler = undefined; 16023 16024 checkStreamProcessor(streamProcessor); 16025 16026 representationController = streamProcessor.getRepresentationController(); 16027 representation = getRepresentationForRepresentationInfo(trackInfo, representationController); 16028 indexHandler = streamProcessor.getIndexHandler(); 16029 16030 return indexHandler ? indexHandler.getSegmentRequestForTime(representation, time, options) : null; 16031 } 16032 16033 function generateFragmentRequestForTime(streamProcessor, trackInfo, time) { 16034 var representationController = undefined, 16035 representation = undefined, 16036 indexHandler = undefined; 16037 16038 checkStreamProcessor(streamProcessor); 16039 16040 representationController = streamProcessor.getRepresentationController(); 16041 representation = getRepresentationForRepresentationInfo(trackInfo, representationController); 16042 indexHandler = streamProcessor.getIndexHandler(); 16043 16044 return indexHandler ? indexHandler.generateSegmentRequestForTime(representation, time) : null; 16045 } 16046 16047 function getIndexHandlerTime(streamProcessor) { 16048 checkStreamProcessor(streamProcessor); 16049 16050 var indexHandler = streamProcessor.getIndexHandler(); 16051 16052 if (indexHandler) { 16053 return indexHandler.getCurrentTime(); 16054 } 16055 return NaN; 16056 } 16057 16058 function setIndexHandlerTime(streamProcessor, value) { 16059 checkStreamProcessor(streamProcessor); 16060 16061 var indexHandler = streamProcessor.getIndexHandler(); 16062 if (indexHandler) { 16063 indexHandler.setCurrentTime(value); 16064 } 16065 } 16066 16067 function updateData(streamProcessor) { 16068 checkStreamProcessor(streamProcessor); 16069 16070 var selectedVoPeriod = getPeriodForStreamInfo(streamProcessor.getStreamInfo(), voPeriods); 16071 var mediaInfo = streamProcessor.getMediaInfo(); 16072 var voAdaptation = getAdaptationForMediaInfo(mediaInfo); 16073 var type = streamProcessor.getType(); 16074 16075 var id = undefined, 16076 realAdaptation = undefined; 16077 16078 id = mediaInfo ? mediaInfo.id : null; 16079 if (voPeriods.length > 0) { 16080 realAdaptation = id ? dashManifestModel.getAdaptationForId(id, voPeriods[0].mpd.manifest, selectedVoPeriod.index) : dashManifestModel.getAdaptationForIndex(mediaInfo.index, voPeriods[0].mpd.manifest, selectedVoPeriod.index); 16081 streamProcessor.getRepresentationController().updateData(realAdaptation, voAdaptation, type); 16082 } 16083 } 16084 16085 function getRepresentationInfoForQuality(representationController, quality) { 16086 checkRepresentationController(representationController); 16087 checkQuality(quality); 16088 16089 var voRepresentation = representationController.getRepresentationForQuality(quality);
16090 return voRepresentation ? convertRepresentationToRepresentationInfo(voRepresentation) : null; 16091 } 16092 16093 function getCurrentRepresentationInfo(representationController) { 16094 checkRepresentationController(representationController); 16095 var voRepresentation = representationController.getCurrentRepresentation(); 16096 return voRepresentation ? convertRepresentationToRepresentationInfo(voRepresentation) : null; 16097 } 16098 16099 function getEvent(eventBox, eventStreams, startTime) { 16100 if (!eventBox || !eventStreams) { 16101 return null; 16102 } 16103 var event = new _voEvent2['default'](); 16104 var schemeIdUri = eventBox.scheme_id_uri; 16105 var value = eventBox.value; 16106 var timescale = eventBox.timescale; 16107 var presentationTimeDelta = eventBox.presentation_time_delta; 16108 var duration = eventBox.event_duration; 16109 var id = eventBox.id; 16110 var messageData = eventBox.message_data; 16111 var presentationTime = startTime * timescale + presentationTimeDelta; 16112 16113 if (!eventStreams[schemeIdUri]) return null; 16114 16115 event.eventStream = eventStreams[schemeIdUri]; 16116 event.eventStream.value = value; 16117 event.eventStream.timescale = timescale; 16118 event.duration = duration; 16119 event.id = id; 16120 event.presentationTime = presentationTime; 16121 event.messageData = messageData; 16122 event.presentationTimeDelta = presentationTimeDelta; 16123 16124 return event; 16125 } 16126 16127 function getEventsFor(info, streamProcessor) { 16128 16129 var events = []; 16130 16131 if (voPeriods.length === 0) { 16132 return events; 16133 } 16134 16135 var manifest = voPeriods[0].mpd.manifest; 16136 16137 if (info instanceof _streamingVoStreamInfo2['default']) { 16138 events = dashManifestModel.getEventsForPeriod(getPeriodForStreamInfo(info, voPeriods)); 16139 } else if (info instanceof _streamingVoMediaInfo2['default']) { 16140 events = dashManifestModel.getEventStreamForAdaptationSet(manifest, getAdaptationForMediaInfo(info)); 16141 } else if (info instanceof _streamingVoRepresentationInfo2['default']) { 16142 events = dashManifestModel.getEventStreamForRepresentation(manifest, getRepresentationForRepresentationInfo(info, streamProcessor.getRepresentationController())); 16143 } 16144 16145 return events; 16146 } 16147 16148 function reset() { 16149 voPeriods = []; 16150 voAdaptations = {}; 16151 } 16152 16153 instance = { 16154 convertDataToRepresentationInfo: convertRepresentationToRepresentationInfo, 16155 getDataForMedia: getAdaptationForMediaInfo, 16156 getStreamsInfo: getStreamsInfo, 16157 getMediaInfoForType: getMediaInfoForType, 16158 getAllMediaInfoForType: getAllMediaInfoForType, 16159 getCurrentRepresentationInfo: getCurrentRepresentationInfo, 16160 getRepresentationInfoForQuality: getRepresentationInfoForQuality, 16161 updateData: updateData, 16162 getInitRequest: getInitRequest, 16163 getNextFragmentRequest: getNextFragmentRequest, 16164 getFragmentRequestForTime: getFragmentRequestForTime, 16165 generateFragmentRequestForTime: generateFragmentRequestForTime, 16166 getIndexHandlerTime: getIndexHandlerTime, 16167 setIndexHandlerTime: setIndexHandlerTime, 16168 getEventsFor: getEventsFor, 16169 getEvent: getEvent, 16170 setConfig: setConfig, 16171 updatePeriods: updatePeriods, 16172 reset: reset 16173 }; 16174 16175 setup(); 16176 return instance; 16177} 16178 16179DashAdapter.__dashjs_factory_name = 'DashAdapter'; 16180exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(DashAdapter); 16181module.exports = exports['default']; 16182 16183},{"100":100,"2":2,"212":212,"213":213,"215":215,"216":216,"51":51,"83":83}],57:[function(_dereq_,module,exports){ 16184/** 16185 * The copyright in this software is being made available under the BSD License, 16186 * included below. This software may be subject to other third party and contributor 16187 * rights, including patent rights, and no such rights are granted under this license. 16188 * 16189 * Copyright (c) 2013, Dash Industry Forum. 16190 * All rights reserved. 16191 * 16192 * Redistribution and use in source and binary forms, with or without modification, 16193 * are permitted provided that the following conditions are met: 16194 * * Redistributions of source code must retain the above copyright notice, this 16195 * list of conditions and the following disclaimer. 16196 * * Redistributions in binary form must reproduce the above copyright notice, 16197 * this list of conditions and the following disclaimer in the documentation and/or 16198 * other materials provided with the distribution. 16199 * * Neither the name of Dash Industry Forum nor the names of its 16200 * contributors may be used to endorse or promote products derived from this software 16201 * without specific prior written permission. 16202 * 16203 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 16204 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16205 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16206 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 16207 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
16207INCLUDING, BUT 16208 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 16209 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 16210 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 16211 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 16212 * POSSIBILITY OF SUCH DAMAGE. 16213 */ 16214'use strict'; 16215 16216Object.defineProperty(exports, '__esModule', { 16217 value: true 16218}); 16219 16220function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16221 16222var _streamingConstantsConstants = _dereq_(100); 16223 16224var _streamingConstantsConstants2 = _interopRequireDefault(_streamingConstantsConstants); 16225 16226var _constantsDashConstants = _dereq_(61); 16227 16228var _constantsDashConstants2 = _interopRequireDefault(_constantsDashConstants); 16229 16230var _streamingVoFragmentRequest = _dereq_(209); 16231 16232var _streamingVoFragmentRequest2 = _interopRequireDefault(_streamingVoFragmentRequest); 16233 16234var _streamingVoDashJSError = _dereq_(207); 16235 16236var _streamingVoDashJSError2 = _interopRequireDefault(_streamingVoDashJSError); 16237 16238var _streamingVoMetricsHTTPRequest = _dereq_(224); 16239 16240var _coreEventsEvents = _dereq_(54); 16241 16242var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 16243 16244var _coreEventBus = _dereq_(50); 16245 16246var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 16247 16248var _coreFactoryMaker = _dereq_(51); 16249 16250var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 16251 16252var _coreDebug = _dereq_(49); 16253 16254var _coreDebug2 = _interopRequireDefault(_coreDebug); 16255 16256var _streamingUtilsURLUtils = _dereq_(202); 16257 16258var _streamingUtilsURLUtils2 = _interopRequireDefault(_streamingUtilsURLUtils); 16259 16260var _voRepresentation = _dereq_(87); 16261 16262var _voRepresentation2 = _interopRequireDefault(_voRepresentation); 16263 16264var _utilsSegmentsUtils = _dereq_(77); 16265 16266var _utilsSegmentsGetter = _dereq_(76); 16267 16268var _utilsSegmentsGetter2 = _interopRequireDefault(_utilsSegmentsGetter); 16269 16270var _SegmentBaseLoader = _dereq_(59); 16271 16272var _SegmentBaseLoader2 = _interopRequireDefault(_SegmentBaseLoader); 16273 16274var _WebmSegmentBaseLoader = _dereq_(60); 16275 16276var _WebmSegmentBaseLoader2 = _interopRequireDefault(_WebmSegmentBaseLoader); 16277 16278var SEGMENTS_UNAVAILABLE_ERROR_CODE = 1; 16279 16280function DashHandler(config) { 16281 16282 var context = this.context; 16283 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 16284 var urlUtils = (0, _streamingUtilsURLUtils2['default'])(context).getInstance(); 16285 16286 var segmentBaseLoader = undefined; 16287 var timelineConverter = config.timelineConverter; 16288 var dashMetrics = config.dashMetrics; 16289 var metricsModel = config.metricsModel; 16290 var mediaPlayerModel = config.mediaPlayerModel; 16291 var errHandler = config.errHandler; 16292 var baseURLController = config.baseURLController; 16293 16294 var instance = undefined, 16295 log = undefined, 16296 index = undefined, 16297 requestedTime = undefined, 16298 currentTime = undefined, 16299 earliestTime = undefined, 16300 streamProcessor = undefined, 16301 segmentsGetter = undefined; 16302 16303 function setup() { 16304 log = (0, _coreDebug2['default'])(context).getInstance().log.bind(instance); 16305 16306 resetInitialSettings(); 16307 16308 segmentBaseLoader = isWebM(config.mimeType) ? (0, _WebmSegmentBaseLoader2['default'])(context).getInstance() : (0, _SegmentBaseLoader2['default'])(context).getInstance(); 16309 segmentBaseLoader.setConfig({ 16310 baseURLController: baseURLController, 16311 metricsModel: metricsModel, 16312 mediaPlayerModel: mediaPlayerModel, 16313 errHandler: errHandler 16314 }); 16315 16316 eventBus.on(_coreEventsEvents2['default'].INITIALIZATION_LOADED, onInitializationLoaded, instance); 16317 eventBus.on(_coreEventsEvents2['default'].SEGMENTS_LOADED, onSegmentsLoaded, instance); 16318 } 16319 16320 function isWebM(mimeType) { 16321 var type = mimeType.split('/')[1]; 16322 16323 return 'webm' === type.toLowerCase(); 16324 } 16325 16326 function initialize(StreamProcessor) { 16327 streamProcessor = StreamProcessor; 16328 16329 var isDynamic = streamProcessor ? streamProcessor.getStreamInfo().manifestInfo.isDynamic : null; 16330 16331 segmentBaseLoader.initialize(); 16332 16333 segmentsGetter = (0, _utilsSegmentsGetter2['default'])(context).create(config, isDynamic); 16334 } 16335 16336 function getStreamProcessor() { 16337 return streamProcessor; 16338 } 16339 16340 function setCurrentTime(value) { 16341 currentTime = value; 16342 } 16343 16344 function getCurrentTime() { 16345 return currentTime; 16346 } 16347 16348 function getEarliestTime() { 16349 return earliestTime; 16350 } 16351 16352 function resetInitialSettings() { 16353 index = -1; 16354 currentTime = 0; 16355 earliestTime = NaN; 16356 requestedTime = null; 16357 streamProcessor = null; 16358 segmentsGetter = null; 16359 } 16360 16361 function reset() { 16362 resetInitialSettings();
16363 16364 eventBus.off(_coreEventsEvents2['default'].INITIALIZATION_LOADED, onInitializationLoaded, instance); 16365 eventBus.off(_coreEventsEvents2['default'].SEGMENTS_LOADED, onSegmentsLoaded, instance); 16366 } 16367 16368 function unescapeDollarsInTemplate(url) { 16369 return url ? url.split('$$').join('$') : url; 16370 } 16371 16372 function replaceIDForTemplate(url, value) { 16373 if (value === null || url === null || url.indexOf('$RepresentationID$') === -1) { 16374 return url; 16375 } 16376 var v = value.toString(); 16377 return url.split('$RepresentationID$').join(v); 16378 } 16379 16380 function setRequestUrl(request, destination, representation) { 16381 var baseURL = baseURLController.resolve(representation.path); 16382 var url = undefined, 16383 serviceLocation = undefined; 16384 16385 if (!baseURL || destination === baseURL.url || !urlUtils.isRelative(destination)) { 16386 url = destination; 16387 } else { 16388 url = baseURL.url; 16389 serviceLocation = baseURL.serviceLocation; 16390 16391 if (destination) { 16392 url = urlUtils.resolve(destination, url); 16393 } 16394 } 16395 16396 if (urlUtils.isRelative(url)) { 16397 return false; 16398 } 16399 16400 request.url = url; 16401 request.serviceLocation = serviceLocation; 16402 16403 return true; 16404 } 16405 16406 function generateInitRequest(representation, mediaType) { 16407 16408 var request = new _streamingVoFragmentRequest2['default'](); 16409 var period = representation.adaptation.period; 16410 var presentationStartTime = period.start; 16411 var isDynamic = streamProcessor ? streamProcessor.getStreamInfo().manifestInfo.isDynamic : null; 16412 16413 request.mediaType = mediaType; 16414 request.type = _streamingVoMetricsHTTPRequest.HTTPRequest.INIT_SEGMENT_TYPE; 16415 request.range = representation.range; 16416 request.availabilityStartTime = timelineConverter.calcAvailabilityStartTimeFromPresentationTime(presentationStartTime, period.mpd, isDynamic); 16417 request.availabilityEndTime = timelineConverter.calcAvailabilityEndTimeFromPresentationTime(presentationStartTime + period.duration, period.mpd, isDynamic); 16418 request.quality = representation.index; 16419 request.mediaInfo = streamProcessor ? streamProcessor.getMediaInfo() : null; 16420 request.representationId = representation.id; 16421 16422 if (setRequestUrl(request, representation.initialization, representation)) { 16423 return request; 16424 } 16425 } 16426 16427 function getInitRequest(representation) { 16428 var type = streamProcessor ? streamProcessor.getType() : null; 16429 if (!representation) return null; 16430 var request = generateInitRequest(representation, type); 16431 return request; 16432 } 16433 16434 function isMediaFinished(representation) { 16435 16436 var isFinished = false; 16437 var isDynamic = streamProcessor ? streamProcessor.getStreamInfo().manifestInfo.isDynamic : null; 16438 16439 if (!isDynamic && index === representation.availableSegmentsNumber) { 16440 isFinished = true; 16441 } else { 16442 var seg = (0, _utilsSegmentsUtils.getSegmentByIndex)(index, representation); 16443 if (seg) { 16444 var time = seg.presentationStartTime - representation.adaptation.period.start; 16445 var duration = representation.adaptation.period.duration; 16446 log(representation.segmentInfoType + ': ' + time + ' / ' + duration); 16447 isFinished = representation.segmentInfoType === _constantsDashConstants2['default'].SEGMENT_TIMELINE && isDynamic ? false : time >= duration; 16448 } else { 16449 log('isMediaFinished - no segment found'); 16450 } 16451 } 16452 16453 return isFinished; 16454 } 16455 16456 function updateSegments(voRepresentation) { 16457 segmentsGetter.getSegments(voRepresentation, requestedTime, index, onSegmentListUpdated); 16458 } 16459 16460 function onSegmentListUpdated(voRepresentation, segments) { 16461 var isDynamic = streamProcessor ? streamProcessor.getStreamInfo().manifestInfo.isDynamic : null; 16462 voRepresentation.segments = segments; 16463 if (segments && segments.length > 0) { 16464 earliestTime = isNaN(earliestTime) ? segments[0].presentationStartTime : Math.min(segments[0].presentationStartTime, earliestTime); 16465 if (isDynamic && isNaN(timelineConverter.getExpectedLiveEdge())) { 16466 var lastSegment = segments[segments.length - 1]; 16467 var liveEdge = lastSegment.presentationStartTime; 16468 var metrics = metricsModel.getMetricsFor(_streamingConstantsConstants2['default'].STREAM); 16469 // the last segment is the Expected, not calculated, live edge. 16470 timelineConverter.setExpectedLiveEdge(liveEdge); 16471 metricsModel.updateManifestUpdateInfo(dashMetrics.getCurrentManifestUpdate(metrics), { presentationStartTime: liveEdge });
16472 } 16473 } 16474 } 16475 16476 function updateSegmentList(voRepresentation) { 16477 16478 if (!voRepresentation) { 16479 throw new Error('no representation'); 16480 } 16481 16482 voRepresentation.segments = null; 16483 16484 updateSegments(voRepresentation); 16485 } 16486 16487 function updateRepresentation(voRepresentation, keepIdx) { 16488 var hasInitialization = _voRepresentation2['default'].hasInitialization(voRepresentation); 16489 var hasSegments = _voRepresentation2['default'].hasSegments(voRepresentation); 16490 var type = streamProcessor ? streamProcessor.getType() : null; 16491 var isDynamic = streamProcessor ? streamProcessor.getStreamInfo().manifestInfo.isDynamic : null; 16492 var error = undefined; 16493 16494 if (!voRepresentation.segmentDuration && !voRepresentation.segments) { 16495 updateSegmentList(voRepresentation); 16496 } 16497 16498 voRepresentation.segmentAvailabilityRange = null; 16499 voRepresentation.segmentAvailabilityRange = timelineConverter.calcSegmentAvailabilityRange(voRepresentation, isDynamic); 16500 16501 if (voRepresentation.segmentAvailabilityRange.end < voRepresentation.segmentAvailabilityRange.start && !voRepresentation.useCalculatedLiveEdgeTime) { 16502 error = new _streamingVoDashJSError2['default'](SEGMENTS_UNAVAILABLE_ERROR_CODE, 'no segments are available yet', { availabilityDelay: voRepresentation.segmentAvailabilityRange.start - voRepresentation.segmentAvailabilityRange.end }); 16503 eventBus.trigger(_coreEventsEvents2['default'].REPRESENTATION_UPDATED, { sender: this, representation: voRepresentation, error: error }); 16504 return; 16505 } 16506 16507 if (!keepIdx) index = -1; 16508 16509 if (voRepresentation.segmentDuration) { 16510 updateSegmentList(voRepresentation); 16511 } 16512 16513 if (!hasInitialization) { 16514 segmentBaseLoader.loadInitialization(voRepresentation); 16515 } 16516 16517 if (!hasSegments) { 16518 segmentBaseLoader.loadSegments(voRepresentation, type, voRepresentation.indexRange); 16519 } 16520 16521 if (hasInitialization && hasSegments) { 16522 eventBus.trigger(_coreEventsEvents2['default'].REPRESENTATION_UPDATED, { sender: this, representation: voRepresentation }); 16523 } 16524 } 16525 16526 function getIndexForSegments(time, representation, timeThreshold) { 16527 var segments = representation.segments; 16528 var ln = segments ? segments.length : null; 16529 16530 var idx = -1; 16531 var epsilon = undefined, 16532 frag = undefined, 16533 ft = undefined, 16534 fd = undefined, 16535 i = undefined; 16536 16537 if (segments && ln > 0) { 16538 for (i = 0; i < ln; i++) { 16539 frag = segments[i]; 16540 ft = frag.presentationStartTime; 16541 fd = frag.duration; 16542 epsilon = timeThreshold === undefined || timeThreshold === null ? fd / 2 : timeThreshold; 16543 if (time + epsilon >= ft && time - epsilon < ft + fd) { 16544 idx = frag.availabilityIdx; 16545 break; 16546 } 16547 } 16548 } 16549 16550 return idx; 16551 } 16552 16553 function getRequestForSegment(segment) { 16554 if (segment === null || segment === undefined) { 16555 return null; 16556 } 16557 16558 var request = new _streamingVoFragmentRequest2['default'](); 16559 var representation = segment.representation; 16560 var bandwidth = representation.adaptation.period.mpd.manifest.Period_asArray[representation.adaptation.period.index].AdaptationSet_asArray[representation.adaptation.index].Representation_asArray[representation.index].bandwidth; 16561 var url = segment.media; 16562 var type = streamProcessor ? streamProcessor.getType() : null; 16563 16564 url = (0, _utilsSegmentsUtils.replaceTokenForTemplate)(url, 'Number', segment.replacementNumber); 16565 url = (0, _utilsSegmentsUtils.replaceTokenForTemplate)(url, 'Time', segment.replacementTime); 16566 url = (0, _utilsSegmentsUtils.replaceTokenForTemplate)(url, 'Bandwidth', bandwidth); 16567 url = replaceIDForTemplate(url, representation.id); 16568 url = unescapeDollarsInTemplate(url); 16569 16570 request.mediaType = type; 16571 request.type = _streamingVoMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE; 16572 request.range = segment.mediaRange; 16573 request.startTime = segment.presentationStartTime; 16574 request.duration = segment.duration; 16575 request.timescale = representation.timescale; 16576 request.availabilityStartTime = segment.availabilityStartTime; 16577 request.availabilityEndTime = segment.availabilityEndTime; 16578 request.wallStartTime = segment.wallStartTime; 16579 request.quality = representation.index; 16580 request.index = segment.availabilityIdx; 16581 request.mediaInfo = streamProcessor.getMediaInfo(); 16582 request.adaptationIndex = representation.adaptation.index; 16583 16584 if (setRequestUrl(request, url, representation)) { 16585 return request; 16586 } 16587 } 16588 16589 function getSegmentRequestForTime(representation, time, options) { 16590 var request = undefined, 16591 segment = undefined, 16592 finished = undefined; 16593 16594 var type = streamProcessor ? streamProcessor.getType() : null; 16595 var isDynamic = streamProcessor ? streamProcessor.getStreamInfo().manifestInfo.isDynamic : null; 16596 var idx = index; 16597 var keepIdx = options ? options.keepIdx : false; 16598 var timeThreshold = options ? options.timeThreshold : null; 16599 var ignoreIsFinished = options && options.ignoreIsFinished ? true : false; 16600 16601 if (!representation) { 16602 return null; 16603 } 16604 16605 if (requestedTime !== time) { 16606 // When playing at live edge with 0 delay we may loop back with same time and index until it is available. Reduces verboseness of logs. 16607 requestedTime = time; 16608 log('Getting the request for ' + type + ' time : ' + time); 16609 } 16610 16611 updateSegments(representation); 16612 index = getIndexForSegments(time, representation, timeThreshold); 16613 //Index may be -1 if getSegments needs to update again. So after getSegments is called and updated then try to get index again. 16614 if (index < 0) { 16615 updateSegments(representation); 16616 index = getIndexForSegments(time, representation, timeThreshold); 16617 } 16618 16619 if (index > 0) { 16620 log('Index for ' + type + ' time ' + time + ' is ' + index); 16621 } 16622 16623 finished = !ignoreIsFinished ? isMediaFinished(representation) : false; 16624 if (finished) { 16625 request = new _streamingVoFragmentRequest2['default'](); 16626 request.action = _streamingVoFragmentRequest2['default'].ACTION_COMPLETE; 16627 request.index = index; 16628 request.mediaType = type; 16629 request.mediaInfo = streamProcessor.getMediaInfo(); 16630 log('Signal complete.', request); 16631 } else { 16632 segment = (0, _utilsSegmentsUtils.getSegmentByIndex)(index, representation); 16633 request = getRequestForSegment(segment); 16634 // log('[getSegmentRequestForTime]request is ' + JSON.stringify(request)); 16635 } 16636 16637 if (keepIdx && idx >= 0) { 16638 index = representation.segmentInfoType === _constantsDashConstants2['default'].SEGMENT_TIMELINE && isDynamic ? index : idx; 16639 } 16640 16641 return request; 16642 } 16643 16644 function generateSegmentRequestForTime(representation, time) { 16645 var step = (representation.segmentAvailabilityRange.end - representation.segmentAvailabilityRange.start) / 2; 16646 16647 representation.segments = null; 16648 representation.segmentAvailabilityRange = { start: time - step, end: time + step }; 16649 return getSegmentRequestForTime(representation, time, { keepIdx: false, ignoreIsFinished: true });
16650 } 16651 16652 function getNextSegmentRequest(representation) { 16653 var request = undefined, 16654 segment = undefined, 16655 finished = undefined; 16656 16657 var type = streamProcessor ? streamProcessor.getType() : null; 16658 var isDynamic = streamProcessor ? streamProcessor.getStreamInfo().manifestInfo.isDynamic : null; 16659 16660 if (!representation || index === -1) { 16661 return null; 16662 } 16663 16664 requestedTime = null; 16665 index++; 16666 16667 log('Getting the next request at index: ' + index); 16668 16669 // check that there is a segment in this index. If none, update segments and wait for next time loop is called 16670 var seg = (0, _utilsSegmentsUtils.getSegmentByIndex)(index, representation); 16671 if (!seg && isDynamic) { 16672 log('No segment found at index: ' + index + '. Wait for next loop'); 16673 updateSegments(representation); 16674 index--; 16675 return null; 16676 } 16677 16678 finished = isMediaFinished(representation); 16679 if (finished) { 16680 request = new _streamingVoFragmentRequest2['default'](); 16681 request.action = _streamingVoFragmentRequest2['default'].ACTION_COMPLETE; 16682 request.index = index; 16683 request.mediaType = type; 16684 request.mediaInfo = streamProcessor.getMediaInfo(); 16685 log('Signal complete.'); 16686 } else { 16687 updateSegments(representation); 16688 segment = (0, _utilsSegmentsUtils.getSegmentByIndex)(index, representation); 16689 request = getRequestForSegment(segment); 16690 // log('[getSegmentRequestForTime]request is ' + JSON.stringify(request)); 16691 if (!segment && isDynamic) { 16692 /* 16693 Sometimes when playing dynamic streams with 0 fragment delay at live edge we ask for 16694 an index before it is available so we decrement index back and send null request 16695 which triggers the validate loop to rerun and the next time the segment should be 16696 available. 16697 */ 16698 index--; 16699 } 16700 } 16701 16702 return request; 16703 } 16704 16705 function onInitializationLoaded(e) { 16706 var representation = e.representation; 16707 //log("Got an initialization."); 16708 if (!representation.segments) return; 16709 16710 eventBus.trigger(_coreEventsEvents2['default'].REPRESENTATION_UPDATED, { sender: this, representation: representation }); 16711 } 16712 16713 function onSegmentsLoaded(e) { 16714 var type = streamProcessor ? streamProcessor.getType() : null; 16715 var isDynamic = streamProcessor ? streamProcessor.getStreamInfo().manifestInfo.isDynamic : null; 16716 if (e.error || type !== e.mediaType) return; 16717 16718 var fragments = e.segments; 16719 var representation = e.representation; 16720 var segments = []; 16721 var count = 0; 16722 16723 var i = undefined, 16724 len = undefined, 16725 s = undefined, 16726 seg = undefined; 16727 16728 for (i = 0, len = fragments.length; i < len; i++) { 16729 s = fragments[i]; 16730 16731 seg = (0, _utilsSegmentsUtils.getTimeBasedSegment)(timelineConverter, isDynamic, representation, s.startTime, s.duration, s.timescale, s.media, s.mediaRange, count); 16732 16733 segments.push(seg); 16734 seg = null; 16735 count++; 16736 } 16737 16738 representation.segmentAvailabilityRange = { start: segments[0].presentationStartTime, end: segments[len - 1].presentationStartTime }; 16739 representation.availableSegmentsNumber = len; 16740 16741 onSegmentListUpdated(representation, segments); 16742 16743 if (!_voRepresentation2['default'].hasInitialization(representation)) return; 16744 16745 eventBus.trigger(_coreEventsEvents2['default'].REPRESENTATION_UPDATED, { sender: this, representation: representation }); 16746 } 16747 16748 instance = { 16749 initialize: initialize, 16750 getStreamProcessor: getStreamProcessor, 16751 getInitRequest: getInitRequest, 16752 getSegmentRequestForTime: getSegmentRequestForTime, 16753 getNextSegmentRequest: getNextSegmentRequest, 16754 generateSegmentRequestForTime: generateSegmentRequestForTime, 16755 updateRepresentation: updateRepresentation, 16756 updateSegmentList: updateSegmentList, 16757 setCurrentTime: setCurrentTime, 16758 getCurrentTime: getCurrentTime, 16759 getEarliestTime: getEarliestTime, 16760 reset: reset 16761 }; 16762 16763 setup(); 16764 16765 return instance; 16766} 16767 16768DashHandler.__dashjs_factory_name = 'DashHandler'; 16769var factory = _coreFactoryMaker2['default'].getClassFactory(DashHandler); 16770factory.SEGMENTS_UNAVAILABLE_ERROR_CODE = SEGMENTS_UNAVAILABLE_ERROR_CODE; 16771_coreFactoryMaker2['default'].updateClassFactory(DashHandler.__dashjs_factory_name, factory); 16772exports['default'] = factory; 16773module.exports = exports['default']; 16774 16775}
16775,{"100":100,"202":202,"207":207,"209":209,"224":224,"49":49,"50":50,"51":51,"54":54,"59":59,"60":60,"61":61,"76":76,"77":77,"87":87}],58:[function(_dereq_,module,exports){ 16776/** 16777 * The copyright in this software is being made available under the BSD License, 16778 * included below. This software may be subject to other third party and contributor 16779 * rights, including patent rights, and no such rights are granted under this license. 16780 * 16781 * Copyright (c) 2013, Dash Industry Forum. 16782 * All rights reserved. 16783 * 16784 * Redistribution and use in source and binary forms, with or without modification, 16785 * are permitted provided that the following conditions are met: 16786 * * Redistributions of source code must retain the above copyright notice, this 16787 * list of conditions and the following disclaimer. 16788 * * Redistributions in binary form must reproduce the above copyright notice, 16789 * this list of conditions and the following disclaimer in the documentation and/or 16790 * other materials provided with the distribution. 16791 * * Neither the name of Dash Industry Forum nor the names of its 16792 * contributors may be used to endorse or promote products derived from this software 16793 * without specific prior written permission. 16794 * 16795 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 16796 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16797 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16798 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 16799 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16800 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 16801 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 16802 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 16803 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 16804 * POSSIBILITY OF SUCH DAMAGE. 16805 */ 16806'use strict'; 16807 16808Object.defineProperty(exports, '__esModule', { 16809 value: true 16810}); 16811 16812function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 16813 16814var _streamingVoMetricsHTTPRequest = _dereq_(224); 16815 16816var _coreFactoryMaker = _dereq_(51); 16817 16818var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 16819 16820var _streamingConstantsMetricsConstants = _dereq_(101); 16821 16822var _streamingConstantsMetricsConstants2 = _interopRequireDefault(_streamingConstantsMetricsConstants); 16823 16824var _round10 = _dereq_(43); 16825 16826/** 16827 * @module DashMetrics 16828 * @param {object} config configuration passed to DashMetrics 16829 */ 16830function DashMetrics(config) { 16831 16832 var instance = undefined; 16833 var dashManifestModel = config.dashManifestModel; 16834 var manifestModel = config.manifestModel; 16835 16836 function getBandwidthForRepresentation(representationId, periodId) { 16837 var representation = undefined; 16838 var manifest = manifestModel.getValue(); 16839 var period = manifest.Period_asArray[periodId]; 16840 16841 representation = findRepresentation(period, representationId); 16842 16843 if (representation === null) { 16844 return null; 16845 } 16846 16847 return representation.bandwidth; 16848 } 16849 16850 /** 16851 * 16852 * @param {string} representationId 16853 * @param {number} periodIdx 16854 * @returns {*} 16855 */ 16856 function getIndexForRepresentation(representationId, periodIdx) { 16857 var representationIndex = undefined; 16858 var manifest = manifestModel.getValue(); 16859 var period = manifest.Period_asArray[periodIdx]; 16860 16861 representationIndex = findRepresentationIndex(period, representationId); 16862 return representationIndex; 16863 } 16864 16865 /** 16866 * This method returns the current max index based on what is defined in the MPD. 16867 * 16868 * @param {string} bufferType - String 'audio' or 'video', 16869 * @param {number} periodIdx - Make sure this is the period index not id 16870 * @return {number} 16871 * @memberof module:DashMetrics 16872 * @instance 16873 */ 16874 function getMaxIndexForBufferType(bufferType, periodIdx) { 16875 var maxIndex = undefined; 16876 var manifest = manifestModel.getValue(); 16877 var period = manifest.Period_asArray[periodIdx]; 16878 16879 maxIndex = findMaxBufferIndex(period, bufferType);
16880 return maxIndex; 16881 } 16882 16883 /** 16884 * @param {MetricsList} metrics 16885 * @returns {*} 16886 * @memberof module:DashMetrics 16887 * @instance 16888 */ 16889 function getCurrentRepresentationSwitch(metrics) { 16890 return getCurrent(metrics, _streamingConstantsMetricsConstants2['default'].TRACK_SWITCH); 16891 } 16892 16893 /** 16894 * @param {MetricsList} metrics 16895 * @returns {*} 16896 * @memberof module:DashMetrics 16897 * @instance 16898 */ 16899 function getLatestBufferLevelVO(metrics) { 16900 return getCurrent(metrics, _streamingConstantsMetricsConstants2['default'].BUFFER_LEVEL); 16901 } 16902 16903 /** 16904 * @param {MetricsList} metrics 16905 * @returns {number} 16906 * @memberof module:DashMetrics 16907 * @instance 16908 */ 16909 function getCurrentBufferLevel(metrics) { 16910 var vo = getLatestBufferLevelVO(metrics); 16911 16912 if (vo) { 16913 return (0, _round10.round10)(vo.level / 1000, -3); 16914 } 16915 16916 return 0; 16917 } 16918 16919 /** 16920 * @param {MetricsList} metrics 16921 * @returns {null|*|vo} 16922 * @memberof module:DashMetrics 16923 * @instance 16924 */ 16925 function getRequestsQueue(metrics) { 16926 return metrics ? metrics.RequestsQueue : null; 16927 } 16928 16929 /** 16930 * @param {MetricsList} metrics 16931 * @returns {*} 16932 * @memberof module:DashMetrics 16933 * @instance 16934 */ 16935 function getCurrentHttpRequest(metrics) { 16936 if (!metrics) { 16937 return null; 16938 } 16939 16940 var httpList = metrics.HttpList; 16941 var currentHttpList = null; 16942 16943 var httpListLength = undefined, 16944 httpListLastIndex = undefined; 16945 16946 if (!httpList || httpList.length <= 0) { 16947 return null; 16948 } 16949 16950 httpListLength = httpList.length; 16951 httpListLastIndex = httpListLength - 1; 16952 16953 while (httpListLastIndex >= 0) { 16954 if (httpList[httpListLastIndex].responsecode) { 16955 currentHttpList = httpList[httpListLastIndex]; 16956 break; 16957 } 16958 httpListLastIndex--; 16959 } 16960 return currentHttpList; 16961 } 16962 16963 /** 16964 * @param {MetricsList} metrics 16965 * @returns {*} 16966 * @memberof module:DashMetrics 16967 * @instance 16968 */ 16969 function getHttpRequests(metrics) { 16970 if (!metrics) { 16971 return []; 16972 } 16973 16974 return !!metrics.HttpList ? metrics.HttpList : []; 16975 } 16976 16977 /** 16978 * @param {MetricsList} metrics 16979 * @param {string} metricName 16980 * @returns {*} 16981 * @memberof module:DashMetrics 16982 * @instance 16983 */ 16984 function getCurrent(metrics, metricName) { 16985 if (!metrics) { 16986 return null; 16987 } 16988 16989 var list = metrics[metricName]; 16990 16991 if (!list) { 16992 return null; 16993 } 16994 16995 var length = list.length; 16996 16997 if (length <= 0) { 16998 return null; 16999 } 17000 17001 return list[length - 1]; 17002 } 17003 17004 /** 17005 * @param {MetricsList} metrics 17006 * @returns {*} 17007 * @memberof module:DashMetrics 17008 * @instance 17009 */ 17010 function getCurrentDroppedFrames(metrics) { 17011 return getCurrent(metrics, _streamingConstantsMetricsConstants2['default'].DROPPED_FRAMES); 17012 } 17013 17014 /** 17015 * @param {MetricsList} metrics 17016 * @returns {*} 17017 * @memberof module:DashMetrics 17018 * @instance 17019 */ 17020 function getCurrentSchedulingInfo(metrics) { 17021 return getCurrent(metrics, _streamingConstantsMetricsConstants2['default'].SCHEDULING_INFO); 17022 } 17023 17024 /** 17025 * @param {MetricsList} metrics 17026 * @returns {*} 17027 * @memberof module:DashMetrics 17028 * @instance 17029 */ 17030 function getCurrentManifestUpdate(metrics) { 17031 return getCurrent(metrics, _streamingConstantsMetricsConstants2['default'].MANIFEST_UPDATE); 17032 } 17033 17034 /** 17035 * @param {MetricsList} metrics 17036 * @returns {*} 17037 * @memberof module:DashMetrics 17038 * @instance 17039 */ 17040 function getCurrentDVRInfo(metrics) { 17041 return getCurrent(metrics, _streamingConstantsMetricsConstants2['default'].DVR_INFO); 17042 } 17043 17044 /** 17045 * @param {MetricsList} metrics 17046 * @param {string} id 17047 * @returns {*} 17048 * @memberof module:DashMetrics 17049 * @instance 17050 */ 17051 function getLatestMPDRequestHeaderValueByID(metrics, id) { 17052 var headers = {}; 17053 var httpRequestList = undefined, 17054 httpRequest = undefined, 17055 i = undefined; 17056 17057 httpRequestList = getHttpRequests(metrics); 17058 17059 for (i = httpRequestList.length - 1; i >= 0; i--) { 17060 httpRequest = httpRequestList[i]; 17061 17062 if (httpRequest.type === _streamingVoMetricsHTTPRequest.HTTPRequest.MPD_TYPE) { 17063 headers = parseResponseHeaders(httpRequest._responseHeaders); 17064 break; 17065 } 17066 } 17067 17068 return headers[id] === undefined ? null : headers[id]; 17069 } 17070 17071 /** 17072 * @param {MetricsList} metrics 17073 * @param {string} id 17074 * @returns {*} 17075 * @memberof module:DashMetrics 17076 * @instance 17077 */ 17078 function getLatestFragmentRequestHeaderValueByID(metrics, id) { 17079 var headers = {}; 17080 var httpRequest = getCurrentHttpRequest(metrics); 17081 if (httpRequest) { 17082 headers = parseResponseHeaders(httpRequest._responseHeaders); 17083 } 17084 return headers[id] === undefined ? null : headers[id]; 17085 } 17086 17087 function parseResponseHeaders(headerStr) { 17088 var headers = {}; 17089 if (!headerStr) { 17090 return headers; 17091 } 17092 17093 // Trim headerStr to fix a MS Edge bug with xhr.getAllResponseHeaders method 17094 // which send a string starting with a "\n" character 17095 var headerPairs = headerStr.trim().split('\r\n'); 17096 for (var i = 0, ilen = headerPairs.length; i < ilen; i++) { 17097 var headerPair = headerPairs[i]; 17098 var index = headerPair.indexOf(': '); 17099 if (index > 0) { 17100 headers[headerPair.substring(0, index)] = headerPair.substring(index + 2); 17101 } 17102 } 17103 return headers; 17104 } 17105 17106 function findRepresentationIndex(period, representationId) { 17107 var index = findRepresentation(period, representationId, true); 17108 17109 if (index !== null) { 17110 return index; 17111 } 17112 17113 return -1; 17114 } 17115 17116 function findRepresentation(period, representationId, returnIndex) { 17117 var adaptationSet = undefined, 17118 adaptationSetArray = undefined, 17119 representation = undefined, 17120 representationArray = undefined, 17121 adaptationSetArrayIndex = undefined, 17122 representationArrayIndex = undefined; 17123 17124 if (period) { 17125 adaptationSetArray = period.AdaptationSet_asArray; 17126 for (adaptationSetArrayIndex = 0; adaptationSetArrayIndex < adaptationSetArray.length; adaptationSetArrayIndex = adaptationSetArrayIndex + 1) { 17127 adaptationSet = adaptationSetArray[adaptationSetArrayIndex]; 17128 representationArray = adaptationSet.Representation_asArray; 17129 for (representationArrayIndex = 0; representationArrayIndex < representationArray.length; representationArrayIndex = representationArrayIndex + 1) { 17130 representation = representationArray[representationArrayIndex]; 17131 if (representationId === representation.id) { 17132 if (returnIndex) { 17133 return representationArrayIndex; 17134 } else { 17135 return representation; 17136 } 17137 } 17138 } 17139 } 17140 } 17141 17142 return null; 17143 } 17144 17145 function adaptationIsType(adaptation, bufferType) { 17146 return dashManifestModel.getIsTypeOf(adaptation, bufferType); 17147 } 17148 17149 function findMaxBufferIndex(period, bufferType) { 17150 var adaptationSet = undefined, 17151 adaptationSetArray = undefined, 17152 representationArray = undefined, 17153 adaptationSetArrayIndex = undefined; 17154 17155 if (!period || !bufferType) return -1; 17156 17157 adaptationSetArray = period.AdaptationSet_asArray; 17158 for (adaptationSetArrayIndex = 0; adaptationSetArrayIndex < adaptationSetArray.length; adaptationSetArrayIndex = adaptationSetArrayIndex + 1) { 17159 adaptationSet = adaptationSetArray[adaptationSetArrayIndex]; 17160 representationArray = adaptationSet.Representation_asArray; 17161 if (adaptationIsType(adaptationSet, bufferType)) { 17162 return representationArray.length; 17163 } 17164 } 17165 17166 return -1; 17167 } 17168 17169 instance = { 17170 getBandwidthForRepresentation: getBandwidthForRepresentation, 17171 getIndexForRepresentation: getIndexForRepresentation, 17172 getMaxIndexForBufferType: getMaxIndexForBufferType, 17173 getCurrentRepresentationSwitch: getCurrentRepresentationSwitch, 17174 getLatestBufferLevelVO: getLatestBufferLevelVO, 17175 getCurrentBufferLevel: getCurrentBufferLevel, 17176 getCurrentHttpRequest: getCurrentHttpRequest, 17177 getHttpRequests: getHttpRequests, 17178 getCurrentDroppedFrames: getCurrentDroppedFrames, 17179 getCurrentSchedulingInfo: getCurrentSchedulingInfo, 17180 getCurrentDVRInfo: getCurrentDVRInfo, 17181 getCurrentManifestUpdate: getCurrentManifestUpdate, 17182 getLatestFragmentRequestHeaderValueByID: getLatestFragmentRequestHeaderValueByID, 17183 getLatestMPDRequestHeaderValueByID: getLatestMPDRequestHeaderValueByID, 17184 getRequestsQueue: getRequestsQueue 17185 }; 17186 17187 return instance; 17188} 17189 17190DashMetrics.__dashjs_factory_name = 'DashMetrics'; 17191exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(DashMetrics); 17192module.exports = exports['default']; 17193 17194},{"101":101,"224":224,"43":43,"51":51}],59:[function(_dereq_,module,exports){ 17195/** 17196 * The copyright in this software is being made available under the BSD License, 17197 * included below. This software may be subject to other third party and contributor 17198 * rights, including patent rights, and no such rights are granted under this license. 17199 * 17200 * Copyright (c) 2013, Dash Industry Forum. 17201 * All rights reserved. 17202 * 17203 * Redistribution and use in source and binary forms, with or without modification, 17204 * are permitted provided that the following conditions are met: 17205 * * Redistributions of source code must retain the above copyright notice, this 17206 * list of conditions and the following disclaimer. 17207 * * Redistributions in binary form must reproduce the above copyright notice, 17208 * this list of conditions and the following disclaimer in the documentation and/or 17209 * other materials provided with the distribution. 17210 * * Neither the name of Dash Industry Forum nor the names of its 17211 * contributors may be used to endorse or promote products derived from this software 17212 * without specific prior written permission. 17213 * 17214 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 17215 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17216 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17217 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 17218 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
17218INCLUDING, BUT 17219 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 17220 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 17221 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 17222 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 17223 * POSSIBILITY OF SUCH DAMAGE. 17224 */ 17225'use strict'; 17226 17227Object.defineProperty(exports, '__esModule', { 17228 value: true 17229}); 17230 17231function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17232 17233var _streamingUtilsRequestModifier = _dereq_(200); 17234 17235var _streamingUtilsRequestModifier2 = _interopRequireDefault(_streamingUtilsRequestModifier); 17236 17237var _voSegment = _dereq_(88); 17238 17239var _voSegment2 = _interopRequireDefault(_voSegment); 17240 17241var _streamingVoDashJSError = _dereq_(207); 17242 17243var _streamingVoDashJSError2 = _interopRequireDefault(_streamingVoDashJSError); 17244 17245var _coreEventsEvents = _dereq_(54); 17246 17247var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 17248 17249var _coreEventBus = _dereq_(50); 17250 17251var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 17252 17253var _streamingUtilsBoxParser = _dereq_(190); 17254 17255var _streamingUtilsBoxParser2 = _interopRequireDefault(_streamingUtilsBoxParser); 17256 17257var _coreFactoryMaker = _dereq_(51); 17258 17259var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 17260 17261var _coreDebug = _dereq_(49); 17262 17263var _coreDebug2 = _interopRequireDefault(_coreDebug); 17264 17265var _streamingVoMetricsHTTPRequest = _dereq_(224); 17266 17267var _streamingVoFragmentRequest = _dereq_(209); 17268 17269var _streamingVoFragmentRequest2 = _interopRequireDefault(_streamingVoFragmentRequest); 17270 17271var _streamingXHRLoader = _dereq_(98); 17272 17273var _streamingXHRLoader2 = _interopRequireDefault(_streamingXHRLoader); 17274 17275function SegmentBaseLoader() { 17276 17277 var context = this.context; 17278 var log = (0, _coreDebug2['default'])(context).getInstance().log; 17279 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 17280 17281 var instance = undefined, 17282 errHandler = undefined, 17283 boxParser = undefined, 17284 requestModifier = undefined, 17285 metricsModel = undefined, 17286 mediaPlayerModel = undefined, 17287 xhrLoader = undefined, 17288 baseURLController = undefined; 17289 17290 function initialize() { 17291 boxParser = (0, _streamingUtilsBoxParser2['default'])(context).getInstance(); 17292 requestModifier = (0, _streamingUtilsRequestModifier2['default'])(context).getInstance(); 17293 xhrLoader = (0, _streamingXHRLoader2['default'])(context).create({ 17294 errHandler: errHandler, 17295 metricsModel: metricsModel, 17296 mediaPlayerModel: mediaPlayerModel, 17297 requestModifier: requestModifier 17298 }); 17299 } 17300 17301 function setConfig(config) { 17302 if (config.baseURLController) { 17303 baseURLController = config.baseURLController; 17304 } 17305 17306 if (config.metricsModel) { 17307 metricsModel = config.metricsModel; 17308 } 17309 17310 if (config.mediaPlayerModel) { 17311 mediaPlayerModel = config.mediaPlayerModel; 17312 } 17313 17314 if (config.errHandler) { 17315 errHandler = config.errHandler; 17316 } 17317 } 17318 17319 function checkSetConfigCall() { 17320 if (!baseURLController || !baseURLController.hasOwnProperty('resolve')) { 17321 throw new Error('setConfig function has to be called previously'); 17322 } 17323 } 17324 17325 function loadInitialization(representation, loadingInfo) { 17326 checkSetConfigCall(); 17327 var initRange = null; 17328 var isoFile = null; 17329 var baseUrl = baseURLController.resolve(representation.path); 17330 var info = loadingInfo || { 17331 init: true, 17332 url: baseUrl ? baseUrl.url : undefined, 17333 range: { 17334 start: 0, 17335 end: 1500 17336 }, 17337 searching: false, 17338 bytesLoaded: 0, 17339 bytesToLoad: 1500 17340 }; 17341 17342 log('Start searching for initialization.'); 17343 17344 var request = getFragmentRequest(info); 17345 17346 var onload = function onload(response) { 17347 17348 info.bytesLoaded = info.range.end; 17349 isoFile = boxParser.parse(response); 17350 initRange = findInitRange(isoFile); 17351 17352 if (initRange) { 17353 representation.range = initRange; 17354 // note that we don't explicitly set rep.initialization as this 17355 // will be computed when all BaseURLs are resolved later 17356 eventBus.trigger(_coreEventsEvents2['default'].INITIALIZATION_LOADED, { representation: representation }); 17357 } else { 17358 info.range.end = info.bytesLoaded + info.bytesToLoad; 17359 loadInitialization(representation, info); 17360 } 17361 }; 17362 17363 var onerror = function onerror() { 17364 eventBus.trigger(_coreEventsEvents2['default'].INITIALIZATION_LOADED, { representation: representation }); 17365 }; 17366 17367 xhrLoader.load({ request: request, success: onload, error: onerror }); 17368 17369 log('Perform init search: ' + info.url); 17370 } 17371 17372 function loadSegments(representation, type, range, loadingInfo, callback) { 17373 checkSetConfigCall(); 17374 if (range && (range.start === undefined || range.end === undefined)) { 17375 var parts = range ? range.toString().split('-') : null; 17376 range = parts ? { start: parseFloat(parts[0]), end: parseFloat(parts[1]) } : null; 17377 } 17378 17379 callback = !callback ? onLoaded : callback; 17380 var isoFile = null; 17381 var sidx = null; 17382 var hasRange = !!range; 17383 var baseUrl = baseURLController.resolve(representation.path); 17384 var info = { 17385 init: false, 17386 url: baseUrl ? baseUrl.url : undefined, 17387 range: hasRange ? range : { start: 0, end: 1500 }, 17388 searching: !hasRange, 17389 bytesLoaded: loadingInfo ? loadingInfo.bytesLoaded : 0, 17390 bytesToLoad: 1500 17391 }; 17392 17393 var request = getFragmentRequest(info); 17394 17395 var onload = function onload(response) { 17396 var extraBytes = info.bytesToLoad; 17397 var loadedLength = response.byteLength; 17398 17399 info.bytesLoaded = info.range.end - info.range.start; 17400 isoFile = boxParser.parse(response); 17401 sidx = isoFile.getBox('sidx'); 17402 17403 if (!sidx || !sidx.isComplete) { 17404 if (sidx) { 17405 info.range.start = sidx.offset || info.range.start; 17406 info.range.end = info.range.start + (sidx.size || extraBytes); 17407 } else if (loadedLength < info.bytesLoaded) { 17408 // if we have reached a search limit or if we have reached the end of the file we have to stop trying to find sidx 17409 callback(null, representation, type); 17410 return; 17411 } else { 17412 var lastBox = isoFile.getLastBox(); 17413 17414 if (lastBox && lastBox.size) { 17415 info.range.start = lastBox.offset + lastBox.size; 17416 info.range.end = info.range.start + extraBytes; 17417 } else { 17418 info.range.end += extraBytes; 17419 } 17420 } 17421 loadSegments(representation, type, info.range, info, callback); 17422 } else { 17423 var ref = sidx.references; 17424 var loadMultiSidx = undefined, 17425 segments = undefined; 17426 17427 if (ref !== null && ref !== undefined && ref.length > 0) { 17428 loadMultiSidx = ref[0].reference_type === 1; 17429 } 17430 17431 if (loadMultiSidx) { 17432 (function () { 17433 log('Initiate multiple SIDX load.'); 17434 info.range.end = info.range.start + sidx.size; 17435 17436 var j = undefined, 17437 len = undefined, 17438 ss = undefined, 17439 se = undefined, 17440 r = undefined; 17441 var segs = []; 17442 var count = 0; 17443 var offset = (sidx.offset || info.range.start) + sidx.size; 17444 var tmpCallback = function tmpCallback(result) { 17445 if (result) { 17446 segs = segs.concat(result); 17447 count++; 17448 17449 if (count >= len) { 17450 callback(segs, representation, type); 17451 } 17452 } else { 17453 callback(null, representation, type); 17454 } 17455 }; 17456 17457 for (j = 0, len = ref.length; j < len; j++) { 17458 ss = offset; 17459 se = offset + ref[j].referenced_size - 1; 17460 offset = offset + ref[j].referenced_size; 17461 r = { start: ss, end: se }; 17462 loadSegments(representation, null, r, info, tmpCallback); 17463 } 17464 })(); 17465 } else { 17466 log('Parsing segments from SIDX.');
17467 segments = getSegmentsForSidx(sidx, info); 17468 callback(segments, representation, type); 17469 } 17470 } 17471 }; 17472 17473 var onerror = function onerror() { 17474 callback(null, representation, type); 17475 }; 17476 17477 xhrLoader.load({ request: request, success: onload, error: onerror }); 17478 log('Perform SIDX load: ' + info.url); 17479 } 17480 17481 function reset() { 17482 xhrLoader.abort(); 17483 xhrLoader = null; 17484 errHandler = null; 17485 boxParser = null; 17486 requestModifier = null; 17487 } 17488 17489 function getSegmentsForSidx(sidx, info) { 17490 17491 var refs = sidx.references; 17492 var len = refs.length; 17493 var timescale = sidx.timescale; 17494 var time = sidx.earliest_presentation_time; 17495 var start = info.range.start + sidx.offset + sidx.first_offset + sidx.size; 17496 var segments = []; 17497 var segment = undefined, 17498 end = undefined, 17499 duration = undefined, 17500 size = undefined; 17501 17502 for (var i = 0; i < len; i++) { 17503 duration = refs[i].subsegment_duration; 17504 size = refs[i].referenced_size; 17505 17506 segment = new _voSegment2['default'](); 17507 // note that we don't explicitly set segment.media as this will be 17508 // computed when all BaseURLs are resolved later 17509 segment.duration = duration; 17510 segment.startTime = time; 17511 segment.timescale = timescale; 17512 end = start + size - 1; 17513 segment.mediaRange = start + '-' + end; 17514 segments.push(segment); 17515 time += duration; 17516 start += size; 17517 } 17518 17519 return segments; 17520 } 17521 17522 function findInitRange(isoFile) { 17523 var ftyp = isoFile.getBox('ftyp'); 17524 var moov = isoFile.getBox('moov'); 17525 17526 var initRange = null; 17527 var start = undefined, 17528 end = undefined; 17529 17530 log('Searching for initialization.'); 17531 17532 if (moov && moov.isComplete) { 17533 start = ftyp ? ftyp.offset : moov.offset; 17534 end = moov.offset + moov.size - 1; 17535 initRange = start + '-' + end; 17536 17537 log('Found the initialization. Range: ' + initRange); 17538 } 17539 17540 return initRange; 17541 } 17542 17543 function getFragmentRequest(info) { 17544 if (!info.url) { 17545 return; 17546 } 17547 17548 var request = new _streamingVoFragmentRequest2['default'](); 17549 17550 request.type = info.init ? _streamingVoMetricsHTTPRequest.HTTPRequest.INIT_SEGMENT_TYPE : _streamingVoMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE; 17551 request.url = info.url; 17552 request.range = info.range.start + '-' + info.range.end; 17553 17554 return request; 17555 } 17556 17557 function onLoaded(segments, representation, type) { 17558 if (segments) { 17559 eventBus.trigger(_coreEventsEvents2['default'].SEGMENTS_LOADED, { segments: segments, representation: representation, mediaType: type }); 17560 } else { 17561 eventBus.trigger(_coreEventsEvents2['default'].SEGMENTS_LOADED, { segments: null, representation: representation, mediaType: type, error: new _streamingVoDashJSError2['default'](null, 'error loading segments', null) }); 17562 } 17563 } 17564 17565 instance = { 17566 setConfig: setConfig, 17567 initialize: initialize, 17568 loadInitialization: loadInitialization, 17569 loadSegments: loadSegments, 17570 reset: reset 17571 }; 17572 17573 return instance; 17574} 17575 17576SegmentBaseLoader.__dashjs_factory_name = 'SegmentBaseLoader'; 17577exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(SegmentBaseLoader); 17578module.exports = exports['default']; 17579 17580},{"190":190,"200":200,"207":207,"209":209,"224":224,"49":49,"50":50,"51":51,"54":54,"88":88,"98":98}],60:[function(_dereq_,module,exports){ 17581'use strict'; 17582 17583Object.defineProperty(exports, '__esModule', { 17584 value: true 17585}); 17586 17587function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 17588 17589var _coreEventsEvents = _dereq_(54); 17590 17591var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 17592 17593var _coreEventBus = _dereq_(50); 17594 17595var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 17596 17597var _streamingUtilsEBMLParser = _dereq_(194); 17598 17599var _streamingUtilsEBMLParser2 = _interopRequireDefault(_streamingUtilsEBMLParser); 17600 17601var _coreFactoryMaker = _dereq_(51); 17602 17603var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 17604 17605var _coreDebug = _dereq_(49); 17606 17607var _coreDebug2 = _interopRequireDefault(_coreDebug); 17608 17609var _streamingUtilsRequestModifier = _dereq_(200); 17610 17611var _streamingUtilsRequestModifier2 = _interopRequireDefault(_streamingUtilsRequestModifier); 17612 17613var _voSegment = _dereq_(88); 17614 17615var _voSegment2 = _interopRequireDefault(_voSegment); 17616 17617var _streamingVoMetricsHTTPRequest = _dereq_(224); 17618 17619var _streamingVoFragmentRequest = _dereq_(209); 17620 17621var _streamingVoFragmentRequest2 = _interopRequireDefault(_streamingVoFragmentRequest); 17622 17623var _streamingXHRLoader = _dereq_(98); 17624 17625var _streamingXHRLoader2 = _interopRequireDefault(_streamingXHRLoader); 17626 17627function WebmSegmentBaseLoader() { 17628 17629 var context = this.context; 17630 var log = (0, _coreDebug2['default'])(context).getInstance().log; 17631 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 17632 17633 var instance = undefined, 17634 WebM = undefined, 17635 errHandler = undefined, 17636 requestModifier = undefined, 17637 metricsModel = undefined, 17638 mediaPlayerModel = undefined, 17639 xhrLoader = undefined, 17640 baseURLController = undefined; 17641 17642 function setup() { 17643 WebM = { 17644 EBML: { 17645 tag: 0x1A45DFA3, 17646 required: true 17647 }, 17648 Segment: { 17649 tag: 0x18538067, 17650 required: true, 17651 SeekHead: { 17652 tag: 0x114D9B74, 17653 required: true 17654 }, 17655 Info: { 17656 tag: 0x1549A966, 17657 required: true,
17658 TimecodeScale: { 17659 tag: 0x2AD7B1, 17660 required: true, 17661 parse: 'getMatroskaUint' 17662 }, 17663 Duration: { 17664 tag: 0x4489, 17665 required: true, 17666 parse: 'getMatroskaFloat' 17667 } 17668 }, 17669 Tracks: { 17670 tag: 0x1654AE6B, 17671 required: true 17672 }, 17673 Cues: { 17674 tag: 0x1C53BB6B, 17675 required: true, 17676 CuePoint: { 17677 tag: 0xBB, 17678 required: true, 17679 CueTime: { 17680 tag: 0xB3, 17681 required: true, 17682 parse: 'getMatroskaUint' 17683 }, 17684 CueTrackPositions: { 17685 tag: 0xB7, 17686 required: true, 17687 CueTrack: { 17688 tag: 0xF7, 17689 required: true, 17690 parse: 'getMatroskaUint' 17691 }, 17692 CueClusterPosition: { 17693 tag: 0xF1, 17694 required: true, 17695 parse: 'getMatroskaUint' 17696 }, 17697 CueBlockNumber: { 17698 tag: 0x5378 17699 } 17700 } 17701 } 17702 } 17703 }, 17704 Void: { 17705 tag: 0xEC, 17706 required: true 17707 } 17708 }; 17709 } 17710 17711 function initialize() { 17712 requestModifier = (0, _streamingUtilsRequestModifier2['default'])(context).getInstance(); 17713 xhrLoader = (0, _streamingXHRLoader2['default'])(context).create({ 17714 errHandler: errHandler, 17715 metricsModel: metricsModel, 17716 mediaPlayerModel: mediaPlayerModel, 17717 requestModifier: requestModifier 17718 }); 17719 } 17720 17721 function setConfig(config) { 17722 if (!config.baseURLController || !config.metricsModel || !config.mediaPlayerModel || !config.errHandler) { 17723 throw new Error('Missing config parameter(s)'); 17724 } 17725 baseURLController = config.baseURLController; 17726 metricsModel = config.metricsModel; 17727 mediaPlayerModel = config.mediaPlayerModel; 17728 errHandler = config.errHandler; 17729 } 17730 17731 function parseCues(ab) { 17732 var cues = []; 17733 var cue = undefined; 17734 var cueSize = undefined; 17735 var cueTrack = undefined; 17736 var ebmlParser = (0, _streamingUtilsEBMLParser2['default'])(context).create({ 17737 data: ab 17738 }); 17739 var numSize = undefined; 17740 17741 ebmlParser.consumeTag(WebM.Segment.Cues); 17742 cueSize = ebmlParser.getMatroskaCodedNum(); 17743 17744 while (ebmlParser.moreData() && ebmlParser.consumeTagAndSize(WebM.Segment.Cues.CuePoint, true)) { 17745 cue = {}; 17746 17747 cue.CueTime = ebmlParser.parseTag(WebM.Segment.Cues.CuePoint.CueTime); 17748 17749 cue.CueTracks = []; 17750 while (ebmlParser.moreData() && ebmlParser.consumeTagAndSize(WebM.Segment.Cues.CuePoint.CueTrackPositions, true)) { 17751 cueTrack = {}; 17752 17753 cueTrack.Track = ebmlParser.parseTag(WebM.Segment.Cues.CuePoint.CueTrackPositions.CueTrack); 17754 if (cueTrack.Track === 0) { 17755 throw new Error('Cue track cannot be 0'); 17756 } 17757 17758 cueTrack.ClusterPosition = ebmlParser.parseTag(WebM.Segment.Cues.CuePoint.CueTrackPositions.CueClusterPosition); 17759 17760 // block number is strictly optional. 17761 // we also have to make sure we don't go beyond the end 17762 // of the cues 17763 if (ebmlParser.getPos() + 4 > cueSize || !ebmlParser.consumeTag(WebM.Segment.Cues.CuePoint.CueTrackPositions.CueBlockNumber, true)) { 17764 cue.CueTracks.push(cueTrack); 17765 } else { 17766 // since we have already consumed the tag, get the size of 17767 // the tag's payload, and manually parse an unsigned int 17768 // from the bit stream 17769 numSize = ebmlParser.getMatroskaCodedNum(); 17770 cueTrack.BlockNumber = ebmlParser.getMatroskaUint(numSize); 17771 17772 cue.CueTracks.push(cueTrack); 17773 } 17774 } 17775 17776 if (cue.CueTracks.length === 0) { 17777 throw new Error('Mandatory cuetrack not found'); 17778 } 17779 cues.push(cue); 17780 } 17781 17782 if (cues.length === 0) { 17783 throw new Error('mandatory cuepoint not found'); 17784 } 17785 return cues; 17786 } 17787 17788 function parseSegments(data, segmentStart, segmentEnd, segmentDuration) { 17789 var duration = undefined; 17790 var parsed = undefined; 17791 var segments = undefined; 17792 var segment = undefined; 17793 var i = undefined; 17794 var len = undefined; 17795 var start = undefined; 17796 var end = undefined; 17797 17798 parsed = parseCues(data); 17799 segments = []; 17800 17801 // we are assuming one cue track per cue point 17802 // both duration and media range require the i + 1 segment 17803 // the final segment has to use global segment parameters 17804 for (i = 0, len = parsed.length; i < len; i += 1) { 17805 segment = new _voSegment2['default'](); 17806 duration = 0; 17807 17808 if (i < parsed.length - 1) { 17809 duration = parsed[i + 1].CueTime - parsed[i].CueTime; 17810 } else { 17811 duration = segmentDuration - parsed[i].CueTime; 17812 } 17813 17814 // note that we don't explicitly set segment.media as this will be 17815 // computed when all BaseURLs are resolved later 17816 segment.duration = duration; 17817 segment.startTime = parsed[i].CueTime; 17818 segment.timescale = 1000; // hardcoded for ms 17819 start = parsed[i].CueTracks[0].ClusterPosition + segmentStart; 17820 17821 if (i < parsed.length - 1) { 17822 end = parsed[i + 1].CueTracks[0].ClusterPosition + segmentStart - 1; 17823 } else { 17824 end = segmentEnd - 1; 17825 } 17826 17827 segment.mediaRange = start + '-' + end; 17828 segments.push(segment); 17829 } 17830 17831 log('Parsed cues: ' + segments.length + ' cues.'); 17832 17833 return segments; 17834 } 17835 17836 function parseEbmlHeader(data, media, theRange, callback) { 17837 var ebmlParser = (0, _streamingUtilsEBMLParser2['default'])(context).create({ 17838 data: data 17839 }); 17840 var duration = undefined; 17841 var segments = undefined; 17842 var parts = theRange.split('-'); 17843 var request = null; 17844 var info = { 17845 url: media, 17846 range: { 17847 start: parseFloat(parts[0]), 17848 end: parseFloat(parts[1]) 17849 }, 17850 request: request 17851 }; 17852 var segmentEnd = undefined; 17853 var segmentStart = undefined; 17854 17855 log('Parse EBML header: ' + info.url); 17856 17857 // skip over the header itself 17858 ebmlParser.skipOverElement(WebM.EBML); 17859 ebmlParser.consumeTag(WebM.Segment); 17860 17861 // segments start here 17862 segmentEnd = ebmlParser.getMatroskaCodedNum(); 17863 segmentEnd += ebmlParser.getPos(); 17864 segmentStart = ebmlParser.getPos(); 17865 17866 // skip over any top level elements to get to the segment info 17867 while (ebmlParser.moreData() && !ebmlParser.consumeTagAndSize(WebM.Segment.Info, true)) { 17868 if (!(ebmlParser.skipOverElement(WebM.Segment.SeekHead, true) || ebmlParser.skipOverElement(WebM.Segment.Tracks, true) || ebmlParser.skipOverElement(WebM.Segment.Cues, true) || ebmlParser.skipOverElement(WebM.Void, true))) { 17869 throw new Error('no valid top level element found'); 17870 } 17871 } 17872 17873 // we only need one thing in segment info, duration 17874 while (duration === undefined) { 17875 var infoTag = ebmlParser.getMatroskaCodedNum(true); 17876 var infoElementSize = ebmlParser.getMatroskaCodedNum(); 17877 17878 switch (infoTag) { 17879 case WebM.Segment.Info.Duration.tag: 17880 duration = ebmlParser[WebM.Segment.Info.Duration.parse](infoElementSize); 17881 break; 17882 default: 17883 ebmlParser.setPos(ebmlParser.getPos() + infoElementSize); 17884 break; 17885 } 17886 } 17887 17888 // once we have what we need from segment info, we jump right to the 17889 // cues 17890 17891 request = getFragmentRequest(info); 17892 17893 var onload = function onload(response) { 17894 segments = parseSegments(response, segmentStart, segmentEnd, duration); 17895 callback(segments); 17896 }; 17897 17898 var onloadend = function onloadend() { 17899 log('Download Error: Cues ' + info.url); 17900 callback(null); 17901 }; 17902 17903 xhrLoader.load({ 17904 request: request, 17905 success: onload, 17906 error: onloadend 17907 }); 17908 17909 log('Perform cues load: ' + info.url + ' bytes=' + info.range.start + '-' + info.range.end); 17910 } 17911 17912 function checkSetConfigCall() { 17913 if (!baseURLController || !baseURLController.hasOwnProperty('resolve')) { 17914 throw new Error('setConfig function has to be called previously'); 17915 } 17916 } 17917 17918 function loadInitialization(representation, loadingInfo) { 17919 checkSetConfigCall(); 17920 var request = null; 17921 var baseUrl = baseURLController.resolve(representation.path); 17922 var media = baseUrl ? baseUrl.url : undefined; 17923 var initRange = representation.range.split('-'); 17924 var info = loadingInfo || { 17925 range: { 17926 start: parseFloat(initRange[0]), 17927 end: parseFloat(initRange[1]) 17928 }, 17929 request: request, 17930 url: media, 17931 init: true 17932 }; 17933 17934 log('Start loading initialization.'); 17935 17936 request = getFragmentRequest(info); 17937 17938 var onload = function onload() { 17939 // note that we don't explicitly set rep.initialization as this 17940 // will be computed when all BaseURLs are resolved later 17941 eventBus.trigger(_coreEventsEvents2['default'].INITIALIZATION_LOADED, { 17942 representation: representation 17943 }); 17944 }; 17945 17946 var onloadend = function onloadend() { 17947 eventBus.trigger(_coreEventsEvents2['default'].INITIALIZATION_LOADED, { 17948 representation: representation 17949 }); 17950 }; 17951 17952 xhrLoader.load({ 17953 request: request, 17954 success: onload, 17955 error: onloadend 17956 }); 17957 17958 log('Perform init load: ' + info.url); 17959 } 17960 17961 function loadSegments(representation, type, theRange, callback) { 17962 checkSetConfigCall(); 17963 var request = null; 17964 var baseUrl = baseURLController.resolve(representation.path); 17965 var media = baseUrl ? baseUrl.url : undefined; 17966 var bytesToLoad = 8192; 17967 var info = { 17968 bytesLoaded: 0, 17969 bytesToLoad: bytesToLoad, 17970 range: { 17971 start: 0, 17972 end: bytesToLoad 17973 }, 17974 request: request, 17975 url: media, 17976 init: false 17977 }; 17978 17979 callback = !callback ? onLoaded : callback; 17980 request = getFragmentRequest(info); 17981 17982 // first load the header, but preserve the manifest range so we can 17983 // load the cues after parsing the header 17984 // NOTE: we expect segment info to appear in the first 8192 bytes 17985 log('Parsing ebml header'); 17986 17987 var onload = function onload(response) { 17988 parseEbmlHeader(response, media, theRange, function (segments) { 17989 callback(segments, representation, type); 17990 }); 17991 }; 17992 17993 var onloadend = function onloadend() { 17994 callback(null, representation, type); 17995 }; 17996 17997 xhrLoader.load({ 17998 request: request, 17999 success: onload, 18000 error: onloadend 18001 }); 18002 } 18003 18004 function onLoaded(segments, representation, type) { 18005 if (segments) { 18006 eventBus.trigger(_coreEventsEvents2['default'].SEGMENTS_LOADED, { 18007 segments: segments, 18008 representation: representation, 18009 mediaType: type 18010 }); 18011 } else { 18012 eventBus.trigger(_coreEventsEvents2['default'].SEGMENTS_LOADED, { 18013 segments: null, 18014 representation: representation, 18015 mediaType: type, 18016 error: new Error(null, 'error loading segments', null) 18017 }); 18018 } 18019 } 18020 18021 function getFragmentRequest(info) { 18022 var request = new _streamingVoFragmentRequest2['default'](); 18023 18024 request.type = info.init ? _streamingVoMetricsHTTPRequest.HTTPRequest.INIT_SEGMENT_TYPE : _streamingVoMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE; 18025 request.url = info.url; 18026 request.range = info.range.start + '-' + info.range.end; 18027 18028 return request; 18029 } 18030 18031 function reset() { 18032 errHandler = null; 18033 requestModifier = null; 18034 log = null; 18035 } 18036 18037 instance = { 18038 setConfig: setConfig, 18039 initialize: initialize, 18040 loadInitialization: loadInitialization, 18041 loadSegments: loadSegments, 18042 reset: reset 18043 }; 18044 18045 setup(); 18046 18047 return instance; 18048} 18049 18050WebmSegmentBaseLoader.__dashjs_factory_name = 'WebmSegmentBaseLoader'; 18051exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(WebmSegmentBaseLoader); 18052module.exports = exports['default']; 18053 18054}
18054,{"194":194,"200":200,"209":209,"224":224,"49":49,"50":50,"51":51,"54":54,"88":88,"98":98}],61:[function(_dereq_,module,exports){ 18055/** 18056 * The copyright in this software is being made available under the BSD License, 18057 * included below. This software may be subject to other third party and contributor 18058 * rights, including patent rights, and no such rights are granted under this license. 18059 * 18060 * Copyright (c) 2013, Dash Industry Forum. 18061 * All rights reserved. 18062 * 18063 * Redistribution and use in source and binary forms, with or without modification, 18064 * are permitted provided that the following conditions are met: 18065 * * Redistributions of source code must retain the above copyright notice, this 18066 * list of conditions and the following disclaimer. 18067 * * Redistributions in binary form must reproduce the above copyright notice, 18068 * this list of conditions and the following disclaimer in the documentation and/or 18069 * other materials provided with the distribution. 18070 * * Neither the name of Dash Industry Forum nor the names of its 18071 * contributors may be used to endorse or promote products derived from this software 18072 * without specific prior written permission. 18073 * 18074 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 18075 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18076 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18077 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18078 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18079 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 18080 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 18081 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 18082 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 18083 * POSSIBILITY OF SUCH DAMAGE. 18084 */ 18085 18086/** 18087 * Dash constants declaration 18088 * @class 18089 * @ignore 18090 */ 18091'use strict'; 18092 18093Object.defineProperty(exports, '__esModule', { 18094 value: true 18095}); 18096 18097var _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; }; })(); 18098 18099function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 18100 18101var DashConstants = (function () { 18102 _createClass(DashConstants, [{ 18103 key: 'init', 18104 value: function init() { 18105 this.BASE_URL = 'BaseURL'; 18106 this.SEGMENT_BASE = 'SegmentBase'; 18107 this.SEGMENT_TEMPLATE = 'SegmentTemplate'; 18108 this.SEGMENT_LIST = 'SegmentList'; 18109 this.SEGMENT_URL = 'SegmentURL'; 18110 this.SEGMENT_TIMELINE = 'SegmentTimeline'; 18111 this.SEGMENT_PROFILES = 'segmentProfiles'; 18112 this.ADAPTATION_SET = 'AdaptationSet'; 18113 this.REPRESENTATION = 'Representation'; 18114 this.REPRESENTATION_INDEX = 'RepresentationIndex'; 18115 this.SUB_REPRESENTATION = 'SubRepresentation'; 18116 this.INITIALIZATION = 'Initialization'; 18117 this.INITIALIZATION_MINUS = 'initialization'; 18118 this.MPD = 'MPD'; 18119 this.PERIOD = 'Period'; 18120 this.ASSET_IDENTIFIER = 'AssetIdentifier'; 18121 this.EVENT_STREAM = 'EventStream'; 18122 this.ID = 'id'; 18123 this.PROFILES = 'profiles'; 18124 this.SERVICE_LOCATION = 'serviceLocation'; 18125 this.RANGE = 'range'; 18126 this.INDEX = 'index'; 18127 this.MEDIA = 'media'; 18128 this.BYTE_RANGE = 'byteRange'; 18129 this.INDEX_RANGE = 'indexRange'; 18130 this.MEDIA_RANGE = 'mediaRange'; 18131 this.VALUE = 'value'; 18132 this.CONTENT_TYPE = 'contentType'; 18133 this.MIME_TYPE = 'mimeType'; 18134 this.BITSTREAM_SWITCHING = 'BitstreamSwitching'; 18135 this.BITSTREAM_SWITCHING_MINUS = 'bitstreamSwitching'; 18136 this.CODECS = 'codecs'; 18137 this.DEPENDENCY_ID = 'dependencyId'; 18138 this.MEDIA_STREAM_STRUCTURE_ID = 'mediaStreamStructureId'; 18139 this.METRICS = 'Metrics'; 18140 this.METRICS_MINUS = 'metrics'; 18141 this.REPORTING = 'Reporting'; 18142 this.WIDTH = 'width'; 18143 this.HEIGHT = 'height'; 18144 this.SAR = 'sar'; 18145 this.FRAMERATE = 'frameRate'; 18146 this.AUDIO_SAMPLING_RATE = 'audioSamplingRate'; 18147 this.MAXIMUM_SAP_PERIOD = 'maximumSAPPeriod'; 18148 this.START_WITH_SAP = 'startWithSAP'; 18149 this.MAX_PLAYOUT_RATE = 'maxPlayoutRate'; 18150 this.CODING_DEPENDENCY = 'codingDependency'; 18151 this.SCAN_TYPE = 'scanType'; 18152 this.FRAME_PACKING = 'FramePacking'; 18153 this.AUDIO_CHANNEL_CONFIGURATION = 'AudioChannelConfiguration'; 18154 this.CONTENT_PROTECTION = 'ContentProtection'; 18155 this.ESSENTIAL_PROPERTY = 'EssentialProperty'; 18156 this.SUPPLEMENTAL_PROPERTY = 'SupplementalProperty'; 18157 this.INBAND_EVENT_STREAM = 'InbandEventStream'; 18158 this.ACCESSIBILITY = 'Accessibility'; 18159 this.ROLE = 'Role'; 18160 this.RATING = 'Rating'; 18161 this.CONTENT_COMPONENT = 'ContentComponent'; 18162 this.SUBSET = 'Subset'; 18163 this.LANG = 'lang'; 18164 this.VIEWPOINT = 'Viewpoint'; 18165 this.ROLE_ASARRAY = 'Role_asArray'; 18166 this.ACCESSIBILITY_ASARRAY = 'Accessibility_asArray'; 18167 this.AUDIOCHANNELCONFIGURATION_ASARRAY = 'AudioChannelConfiguration_asArray'; 18168 this.CONTENTPROTECTION_ASARRAY = 'ContentProtection_asArray'; 18169 this.MAIN = 'main'; 18170 this.DYNAMIC = 'dynamic'; 18171 this.MEDIA_PRESENTATION_DURATION = 'mediaPresentationDuration';
18172 this.MINIMUM_UPDATE_PERIOD = 'minimumUpdatePeriod'; 18173 this.CODEC_PRIVATE_DATA = 'codecPrivateData'; 18174 this.BANDWITH = 'bandwidth'; 18175 this.SOURCE_URL = 'sourceURL'; 18176 this.TIMESCALE = 'timescale'; 18177 this.DURATION = 'duration'; 18178 this.START_NUMBER = 'startNumber'; 18179 this.PRESENTATION_TIME_OFFSET = 'presentationTimeOffset'; 18180 this.AVAILABILITY_START_TIME = 'availabilityStartTime'; 18181 this.AVAILABILITY_END_TIME = 'availabilityEndTime'; 18182 this.TIMESHIFT_BUFFER_DEPTH = 'timeShiftBufferDepth'; 18183 this.MAX_SEGMENT_DURATION = 'maxSegmentDuration'; 18184 this.PRESENTATION_TIME = 'presentationTime'; 18185 this.MIN_BUFFER_TIME = 'minBufferTime'; 18186 this.MAX_SUBSEGMENT_DURATION = 'maxSubsegmentDuration'; 18187 this.START = 'start'; 18188 this.CENC_DEFAULT_KID = 'cenc:default_KID'; 18189 this.DVB_PRIORITY = 'dvb:priority'; 18190 this.DVB_WEIGHT = 'dvb:weight'; 18191 } 18192 }]); 18193 18194 function DashConstants() { 18195 _classCallCheck(this, DashConstants); 18196 18197 this.init(); 18198 } 18199 18200 return DashConstants; 18201})(); 18202 18203var constants = new DashConstants(); 18204exports['default'] = constants; 18205module.exports = exports['default']; 18206 18207},{}],62:[function(_dereq_,module,exports){ 18208/** 18209 * The copyright in this software is being made available under the BSD License, 18210 * included below. This software may be subject to other third party and contributor 18211 * rights, including patent rights, and no such rights are granted under this license. 18212 * 18213 * Copyright (c) 2013, Dash Industry Forum. 18214 * All rights reserved. 18215 * 18216 * Redistribution and use in source and binary forms, with or without modification, 18217 * are permitted provided that the following conditions are met: 18218 * * Redistributions of source code must retain the above copyright notice, this 18219 * list of conditions and the following disclaimer. 18220 * * Redistributions in binary form must reproduce the above copyright notice, 18221 * this list of conditions and the following disclaimer in the documentation and/or 18222 * other materials provided with the distribution. 18223 * * Neither the name of Dash Industry Forum nor the names of its 18224 * contributors may be used to endorse or promote products derived from this software 18225 * without specific prior written permission. 18226 * 18227 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 18228 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18229 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18230 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18231 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18232 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 18233 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 18234 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 18235 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 18236 * POSSIBILITY OF SUCH DAMAGE. 18237 */ 18238'use strict'; 18239 18240Object.defineProperty(exports, '__esModule', { 18241 value: true 18242}); 18243 18244function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18245 18246var _streamingConstantsConstants = _dereq_(100); 18247 18248var _streamingConstantsConstants2 = _interopRequireDefault(_streamingConstantsConstants); 18249 18250var _constantsDashConstants = _dereq_(61); 18251 18252var _constantsDashConstants2 = _interopRequireDefault(_constantsDashConstants); 18253 18254var _streamingVoDashJSError = _dereq_(207); 18255 18256var _streamingVoDashJSError2 = _interopRequireDefault(_streamingVoDashJSError); 18257 18258var _coreEventBus = _dereq_(50); 18259 18260var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 18261 18262var _coreEventsEvents = _dereq_(54); 18263 18264var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 18265 18266var _streamingMediaPlayerEvents = _dereq_(94); 18267 18268var _streamingMediaPlayerEvents2 = _interopRequireDefault(_streamingMediaPlayerEvents); 18269 18270var _coreFactoryMaker = _dereq_(51); 18271 18272var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 18273 18274var _voRepresentation = _dereq_(87); 18275 18276var _voRepresentation2 = _interopRequireDefault(_voRepresentation); 18277 18278function RepresentationController() { 18279 18280 var SEGMENTS_UPDATE_FAILED_ERROR_CODE = 1; 18281 18282 var context = this.context; 18283 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 18284 18285 var instance = undefined, 18286 realAdaptation = undefined, 18287 realAdaptationIndex = undefined, 18288 updating = undefined, 18289 voAvailableRepresentations = undefined, 18290 currentVoRepresentation = undefined, 18291 abrController = undefined, 18292 indexHandler = undefined, 18293 playbackController = undefined, 18294 metricsModel = undefined, 18295 domStorage = undefined, 18296 timelineConverter = undefined, 18297 dashManifestModel = undefined, 18298 dashMetrics = undefined, 18299 streamProcessor = undefined, 18300 manifestModel = undefined; 18301 18302 function setup() { 18303 resetInitialSettings();
18304 18305 eventBus.on(_coreEventsEvents2['default'].QUALITY_CHANGE_REQUESTED, onQualityChanged, instance); 18306 eventBus.on(_coreEventsEvents2['default'].REPRESENTATION_UPDATED, onRepresentationUpdated, instance); 18307 eventBus.on(_coreEventsEvents2['default'].WALLCLOCK_TIME_UPDATED, onWallclockTimeUpdated, instance); 18308 eventBus.on(_coreEventsEvents2['default'].BUFFER_LEVEL_UPDATED, onBufferLevelUpdated, instance); 18309 } 18310 18311 function setConfig(config) { 18312 // allow the abrController created in setup to be overidden 18313 if (config.abrController) { 18314 abrController = config.abrController; 18315 } 18316 if (config.domStorage) { 18317 domStorage = config.domStorage; 18318 } 18319 if (config.metricsModel) { 18320 metricsModel = config.metricsModel; 18321 } 18322 if (config.dashMetrics) { 18323 dashMetrics = config.dashMetrics; 18324 } 18325 if (config.dashManifestModel) { 18326 dashManifestModel = config.dashManifestModel; 18327 } 18328 if (config.playbackController) { 18329 playbackController = config.playbackController; 18330 } 18331 if (config.timelineConverter) { 18332 timelineConverter = config.timelineConverter; 18333 } 18334 if (config.manifestModel) { 18335 manifestModel = config.manifestModel; 18336 } 18337 if (config.streamProcessor) { 18338 streamProcessor = config.streamProcessor; 18339 } 18340 } 18341 18342 function initialize() { 18343 indexHandler = streamProcessor.getIndexHandler(); 18344 } 18345 18346 function getStreamProcessor() { 18347 return streamProcessor; 18348 } 18349 18350 function getData() { 18351 return realAdaptation; 18352 } 18353 18354 function getDataIndex() { 18355 return realAdaptationIndex; 18356 } 18357 18358 function isUpdating() { 18359 return updating; 18360 } 18361 18362 function getCurrentRepresentation() { 18363 return currentVoRepresentation; 18364 } 18365 18366 function resetInitialSettings() { 18367 realAdaptation = null; 18368 realAdaptationIndex = -1; 18369 updating = true; 18370 voAvailableRepresentations = []; 18371 abrController = null; 18372 playbackController = null; 18373 metricsModel = null; 18374 domStorage = null; 18375 timelineConverter = null; 18376 dashManifestModel = null; 18377 dashMetrics = null; 18378 } 18379 18380 function reset() { 18381 18382 eventBus.off(_coreEventsEvents2['default'].QUALITY_CHANGE_REQUESTED, onQualityChanged, instance); 18383 eventBus.off(_coreEventsEvents2['default'].REPRESENTATION_UPDATED, onRepresentationUpdated, instance); 18384 eventBus.off(_coreEventsEvents2['default'].WALLCLOCK_TIME_UPDATED, onWallclockTimeUpdated, instance); 18385 eventBus.off(_coreEventsEvents2['default'].BUFFER_LEVEL_UPDATED, onBufferLevelUpdated, instance); 18386 18387 resetInitialSettings(); 18388 } 18389 18390 function updateData(newRealAdaptation, voAdaptation, type) { 18391 var quality = undefined, 18392 averageThroughput = undefined; 18393 18394 var bitrate = null; 18395 var streamInfo = streamProcessor.getStreamInfo(); 18396 var maxQuality = abrController.getTopQualityIndexFor(type, streamInfo.id); 18397 18398 updating = true; 18399 eventBus.trigger(_coreEventsEvents2['default'].DATA_UPDATE_STARTED, { sender: this }); 18400 18401 voAvailableRepresentations = updateRepresentations(voAdaptation); 18402 18403 if (realAdaptation === null && type !== _streamingConstantsConstants2['default'].FRAGMENTED_TEXT) { 18404 averageThroughput = abrController.getThroughputHistory().getAverageThroughput(type); 18405 bitrate = averageThroughput || abrController.getInitialBitrateFor(type, streamInfo); 18406 quality = abrController.getQualityForBitrate(streamProcessor.getMediaInfo(), bitrate); 18407 } else { 18408 quality = abrController.getQualityFor(type, streamInfo); 18409 } 18410 18411 if (quality > maxQuality) { 18412 quality = maxQuality; 18413 } 18414 18415 currentVoRepresentation = getRepresentationForQuality(quality); 18416 realAdaptation = newRealAdaptation; 18417 18418 if (type !== _streamingConstantsConstants2['default'].VIDEO && type !== _streamingConstantsConstants2['default'].AUDIO && type !== _streamingConstantsConstants2['default'].FRAGMENTED_TEXT) { 18419 updating = false; 18420 eventBus.trigger(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, { sender: this, data: realAdaptation, currentRepresentation: currentVoRepresentation }); 18421 return; 18422 } 18423 18424 for (var i = 0; i < voAvailableRepresentations.length; i++) { 18425 indexHandler.updateRepresentation(voAvailableRepresentations[i], true); 18426 } 18427 } 18428 18429 function addRepresentationSwitch() { 18430 var now = new Date(); 18431 var currentRepresentation = getCurrentRepresentation(); 18432 var currentVideoTimeMs = playbackController.getTime() * 1000; 18433 18434 metricsModel.addRepresentationSwitch(currentRepresentation.adaptation.type, now, currentVideoTimeMs, currentRepresentation.id); 18435 } 18436 18437 function addDVRMetric() { 18438 var streamInfo = streamProcessor.getStreamInfo(); 18439 var manifestInfo = streamInfo ? streamInfo.manifestInfo : null; 18440 var isDynamic = manifestInfo ? manifestInfo.isDynamic : null; 18441 var range = timelineConverter.calcSegmentAvailabilityRange(currentVoRepresentation, isDynamic); 18442 metricsModel.addDVRInfo(streamProcessor.getType(), playbackController.getTime(), manifestInfo, range); 18443 } 18444 18445 function getRepresentationForQuality(quality) { 18446 return voAvailableRepresentations[quality]; 18447 } 18448 18449 function getQualityForRepresentation(voRepresentation) { 18450 return voAvailableRepresentations.indexOf(voRepresentation); 18451 } 18452 18453 function isAllRepresentationsUpdated() { 18454 for (var i = 0, ln = voAvailableRepresentations.length; i < ln; i++) { 18455 var segmentInfoType = voAvailableRepresentations[i].segmentInfoType; 18456 if (voAvailableRepresentations[i].segmentAvailabilityRange === null || !_voRepresentation2['default'].hasInitialization(voAvailableRepresentations[i]) || (segmentInfoType === _constantsDashConstants2['default'].SEGMENT_BASE || segmentInfoType === _constantsDashConstants2['default'].BASE_URL) && !voAvailableRepresentations[i].segments) { 18457 return false; 18458 } 18459 } 18460 18461 return true; 18462 } 18463 18464 function updateRepresentations(voAdaptation) { 18465 var voReps = undefined; 18466 18467 realAdaptationIndex = dashManifestModel.getIndexForAdaptation(realAdaptation, voAdaptation.period.mpd.manifest, voAdaptation.period.index); 18468 voReps = dashManifestModel.getRepresentationsForAdaptation(voAdaptation); 18469 18470 return voReps; 18471 } 18472 18473 function updateAvailabilityWindow(isDynamic) { 18474 var voRepresentation = undefined; 18475 18476 for (var i = 0, ln = voAvailableRepresentations.length; i < ln; i++) { 18477 voRepresentation = voAvailableRepresentations[i]; 18478 voRepresentation.segmentAvailabilityRange = timelineConverter.calcSegmentAvailabilityRange(voRepresentation, isDynamic); 18479 } 18480 } 18481 18482 function resetAvailabilityWindow() { 18483 voAvailableRepresentations.forEach(function (rep) { 18484 rep.segmentAvailabilityRange = null; 18485 }); 18486 } 18487 18488 function postponeUpdate(postponeTimePeriod) {
18489 var delay = postponeTimePeriod; 18490 var update = function update() { 18491 if (isUpdating()) return; 18492 18493 updating = true; 18494 eventBus.trigger(_coreEventsEvents2['default'].DATA_UPDATE_STARTED, { sender: instance }); 18495 18496 // clear the segmentAvailabilityRange for all reps. 18497 // this ensures all are updated before the live edge search starts 18498 resetAvailabilityWindow(); 18499 18500 for (var i = 0; i < voAvailableRepresentations.length; i++) { 18501 indexHandler.updateRepresentation(voAvailableRepresentations[i], true); 18502 } 18503 }; 18504 18505 updating = false; 18506 eventBus.trigger(_streamingMediaPlayerEvents2['default'].AST_IN_FUTURE, { delay: delay }); 18507 setTimeout(update, delay); 18508 } 18509 18510 function onRepresentationUpdated(e) { 18511 if (e.sender.getStreamProcessor() !== streamProcessor || !isUpdating()) return; 18512 18513 var r = e.representation; 18514 var streamMetrics = metricsModel.getMetricsFor(_streamingConstantsConstants2['default'].STREAM); 18515 var metrics = metricsModel.getMetricsFor(getCurrentRepresentation().adaptation.type); 18516 var manifestUpdateInfo = dashMetrics.getCurrentManifestUpdate(streamMetrics); 18517 var alreadyAdded = false; 18518 var postponeTimePeriod = 0; 18519 var repInfo = undefined, 18520 err = undefined, 18521 repSwitch = undefined; 18522 18523 if (r.adaptation.period.mpd.manifest.type === _constantsDashConstants2['default'].DYNAMIC && !r.adaptation.period.mpd.manifest.ignorePostponeTimePeriod) { 18524 var segmentAvailabilityTimePeriod = r.segmentAvailabilityRange.end - r.segmentAvailabilityRange.start; 18525 // We must put things to sleep unless till e.g. the startTime calculation in ScheduleController.onLiveEdgeSearchCompleted fall after the segmentAvailabilityRange.start 18526 var liveDelay = playbackController.computeLiveDelay(currentVoRepresentation.segmentDuration, streamProcessor.getStreamInfo().manifestInfo.DVRWindowSize); 18527 postponeTimePeriod = (liveDelay - segmentAvailabilityTimePeriod) * 1000; 18528 } 18529 18530 if (postponeTimePeriod > 0) { 18531 addDVRMetric(); 18532 postponeUpdate(postponeTimePeriod); 18533 err = new _streamingVoDashJSError2['default'](SEGMENTS_UPDATE_FAILED_ERROR_CODE, 'Segments update failed', null); 18534 eventBus.trigger(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, { sender: this, data: realAdaptation, currentRepresentation: currentVoRepresentation, error: err }); 18535 18536 return; 18537 } 18538 18539 if (manifestUpdateInfo) { 18540 for (var i = 0; i < manifestUpdateInfo.representationInfo.length; i++) { 18541 repInfo = manifestUpdateInfo.representationInfo[i]; 18542 if (repInfo.index === r.index && repInfo.mediaType === streamProcessor.getType()) { 18543 alreadyAdded = true; 18544 break; 18545 } 18546 } 18547 18548 if (!alreadyAdded) { 18549 metricsModel.addManifestUpdateRepresentationInfo(manifestUpdateInfo, r.id, r.index, r.adaptation.period.index, streamProcessor.getType(), r.presentationTimeOffset, r.startNumber, r.segmentInfoType); 18550 } 18551 } 18552 18553 if (isAllRepresentationsUpdated()) { 18554 updating = false; 18555 abrController.setPlaybackQuality(streamProcessor.getType(), streamProcessor.getStreamInfo(), getQualityForRepresentation(currentVoRepresentation)); 18556 metricsModel.updateManifestUpdateInfo(manifestUpdateInfo, { latency: currentVoRepresentation.segmentAvailabilityRange.end - playbackController.getTime() }); 18557 18558 repSwitch = dashMetrics.getCurrentRepresentationSwitch(metrics); 18559 18560 if (!repSwitch) { 18561 addRepresentationSwitch(); 18562 } 18563 18564 eventBus.trigger(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, { sender: this, data: realAdaptation, currentRepresentation: currentVoRepresentation }); 18565 } 18566 } 18567 18568 function onWallclockTimeUpdated(e) { 18569 if (e.isDynamic) { 18570 updateAvailabilityWindow(e.isDynamic); 18571 } 18572 } 18573 18574 function onBufferLevelUpdated(e) { 18575 if (e.sender.getStreamProcessor() !== streamProcessor) return; 18576 var manifest = manifestModel.getValue(); 18577 if (!manifest.doNotUpdateDVRWindowOnBufferUpdated) { 18578 addDVRMetric(); 18579 } 18580 } 18581 18582 function onQualityChanged(e) { 18583 if (e.mediaType !== streamProcessor.getType() || streamProcessor.getStreamInfo().id !== e.streamInfo.id) return; 18584 18585 if (e.oldQuality !== e.newQuality) { 18586 currentVoRepresentation = getRepresentationForQuality(e.newQuality); 18587 var bitrate = abrController.getThroughputHistory().getAverageThroughput(e.mediaType); 18588 if (!isNaN(bitrate)) { 18589 domStorage.setSavedBitrateSettings(e.mediaType, bitrate); 18590 } 18591 addRepresentationSwitch(); 18592 } 18593 } 18594 18595 instance = { 18596 initialize: initialize, 18597 setConfig: setConfig, 18598 getData: getData, 18599 getDataIndex: getDataIndex, 18600 isUpdating: isUpdating, 18601 updateData: updateData, 18602 getStreamProcessor: getStreamProcessor, 18603 getCurrentRepresentation: getCurrentRepresentation, 18604 getRepresentationForQuality: getRepresentationForQuality, 18605 reset: reset 18606 }; 18607 18608 setup(); 18609 return instance; 18610} 18611 18612RepresentationController.__dashjs_factory_name = 'RepresentationController'; 18613exports['default'] = _coreFactoryMaker2['default'].getClassFactory(RepresentationController); 18614module.exports = exports['default']; 18615 18616},{"100":100,"207":207,"50":50,"51":51,"54":54,"61":61,"87":87,"94":94}],63:[function(_dereq_,module,exports){ 18617/** 18618 * The copyright in this software is being made available under the BSD License, 18619 * included below. This software may be subject to other third party and contributor 18620 * rights, including patent rights, and no such rights are granted under this license. 18621 * 18622 * Copyright (c) 2013, Dash Industry Forum. 18623 * All rights reserved. 18624 * 18625 * Redistribution and use in source and binary forms, with or without modification, 18626 * are permitted provided that the following conditions are met: 18627 * * Redistributions of source code must retain the above copyright notice, this 18628 * list of conditions and the following disclaimer. 18629 * * Redistributions in binary form must reproduce the above copyright notice, 18630 * this list of conditions and the following disclaimer in the documentation and/or 18631 * other materials provided with the distribution. 18632 * * Neither the name of Dash Industry Forum nor the names of its 18633 * contributors may be used to endorse or promote products derived from this software 18634 * without specific prior written permission. 18635 * 18636 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 18637 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18638 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18639 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18640 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
18640INCLUDING, BUT 18641 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 18642 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 18643 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 18644 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 18645 * POSSIBILITY OF SUCH DAMAGE. 18646 */ 18647'use strict'; 18648 18649Object.defineProperty(exports, '__esModule', { 18650 value: true 18651}); 18652 18653function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 18654 18655var _streamingConstantsConstants = _dereq_(100); 18656 18657var _streamingConstantsConstants2 = _interopRequireDefault(_streamingConstantsConstants); 18658 18659var _constantsDashConstants = _dereq_(61); 18660 18661var _constantsDashConstants2 = _interopRequireDefault(_constantsDashConstants); 18662 18663var _voRepresentation = _dereq_(87); 18664 18665var _voRepresentation2 = _interopRequireDefault(_voRepresentation); 18666 18667var _voAdaptationSet = _dereq_(81); 18668 18669var _voAdaptationSet2 = _interopRequireDefault(_voAdaptationSet); 18670 18671var _voPeriod = _dereq_(86); 18672 18673var _voPeriod2 = _interopRequireDefault(_voPeriod); 18674 18675var _voMpd = _dereq_(85); 18676 18677var _voMpd2 = _interopRequireDefault(_voMpd); 18678 18679var _voUTCTiming = _dereq_(89); 18680 18681var _voUTCTiming2 = _interopRequireDefault(_voUTCTiming); 18682 18683var _voEvent = _dereq_(83); 18684 18685var _voEvent2 = _interopRequireDefault(_voEvent); 18686 18687var _voBaseURL = _dereq_(82); 18688 18689var _voBaseURL2 = _interopRequireDefault(_voBaseURL); 18690 18691var _voEventStream = _dereq_(84); 18692 18693var _voEventStream2 = _interopRequireDefault(_voEventStream); 18694 18695var _streamingUtilsObjectUtils = _dereq_(199); 18696 18697var _streamingUtilsObjectUtils2 = _interopRequireDefault(_streamingUtilsObjectUtils); 18698 18699var _streamingUtilsURLUtils = _dereq_(202); 18700 18701var _streamingUtilsURLUtils2 = _interopRequireDefault(_streamingUtilsURLUtils); 18702 18703var _coreFactoryMaker = _dereq_(51); 18704 18705var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 18706 18707function DashManifestModel(config) { 18708 18709 var instance = undefined; 18710 var context = this.context; 18711 18712 var urlUtils = (0, _streamingUtilsURLUtils2['default'])(context).getInstance(); 18713 var mediaController = config.mediaController; 18714 var timelineConverter = config.timelineConverter; 18715 var adapter = config.adapter; 18716 18717 var PROFILE_DVB = 'urn:dvb:dash:profile:dvb-dash:2014'; 18718 var isInteger = Number.isInteger || function (value) { 18719 return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; 18720 }; 18721 18722 function getIsTypeOf(adaptation, type) { 18723 18724 var i = undefined, 18725 len = undefined, 18726 representation = undefined, 18727 col = undefined, 18728 mimeTypeRegEx = undefined, 18729 codecs = undefined; 18730 var result = false; 18731 var found = false; 18732 18733 if (!adaptation) { 18734 throw new Error('adaptation is not defined'); 18735 } 18736 18737 if (!type) { 18738 throw new Error('type is not defined'); 18739 } 18740 18741 if (adaptation.hasOwnProperty('ContentComponent_asArray')) { 18742 col = adaptation.ContentComponent_asArray; 18743 } 18744 18745 mimeTypeRegEx = type !== _streamingConstantsConstants2['default'].TEXT ? new RegExp(type) : new RegExp('(vtt|ttml)'); 18746 18747 if (adaptation.Representation_asArray && adaptation.Representation_asArray.length && adaptation.Representation_asArray.length > 0 && adaptation.Representation_asArray[0].hasOwnProperty(_constantsDashConstants2['default'].CODECS)) { 18748 // Just check the start of the codecs string 18749 codecs = adaptation.Representation_asArray[0].codecs; 18750 if (codecs.search(_streamingConstantsConstants2['default'].STPP) === 0 || codecs.search(_streamingConstantsConstants2['default'].WVTT) === 0) { 18751 return type === _streamingConstantsConstants2['default'].FRAGMENTED_TEXT; 18752 } 18753 } 18754 18755 if (col) { 18756 if (col.length > 1) { 18757 return type === _streamingConstantsConstants2['default'].MUXED; 18758 } else if (col[0] && col[0].contentType === type) { 18759 result = true; 18760 found = true; 18761 } 18762 } 18763 18764 if (adaptation.hasOwnProperty(_constantsDashConstants2['default'].MIME_TYPE)) { 18765 result = mimeTypeRegEx.test(adaptation.mimeType); 18766 found = true; 18767 } 18768 18769 // couldn't find on adaptationset, so check a representation 18770 if (!found) { 18771 i = 0; 18772 len = adaptation.Representation_asArray && adaptation.Representation_asArray.length ? adaptation.Representation_asArray.length : 0; 18773 while (!found && i < len) { 18774 representation = adaptation.Representation_asArray[i]; 18775 18776 if (representation.hasOwnProperty(_constantsDashConstants2['default'].MIME_TYPE)) { 18777 result = mimeTypeRegEx.test(representation.mimeType); 18778 found = true; 18779 } 18780 18781 i++; 18782 } 18783 } 18784 18785 return result; 18786 } 18787 18788 function getIsAudio(adaptation) { 18789 return getIsTypeOf(adaptation, _streamingConstantsConstants2['default'].AUDIO); 18790 } 18791 18792 function getIsVideo(adaptation) { 18793 return getIsTypeOf(adaptation, _streamingConstantsConstants2['default'].VIDEO); 18794 } 18795 18796 function getIsFragmentedText(adaptation) { 18797 return getIsTypeOf(adaptation, _streamingConstantsConstants2['default'].FRAGMENTED_TEXT); 18798 } 18799 18800 function getIsText(adaptation) { 18801 return getIsTypeOf(adaptation, _streamingConstantsConstants2['default'].TEXT); 18802 } 18803 18804 function getIsMuxed(adaptation) { 18805 return getIsTypeOf(adaptation, _streamingConstantsConstants2['default'].MUXED); 18806 } 18807 18808 function getIsTextTrack(type) { 18809 return type === 'text/vtt' || type === 'application/ttml+xml'; 18810 } 18811 18812 function getLanguageForAdaptation(adaptation) { 18813 var lang = ''; 18814 18815 if (adaptation && adaptation.hasOwnProperty(_constantsDashConstants2['default'].LANG)) { 18816 //Filter out any other characters not allowed according to RFC5646 18817 lang = adaptation.lang.replace(/[^A-Za-z0-9-]/g, ''); 18818 } 18819 18820 return lang; 18821 } 18822 18823 function getViewpointForAdaptation(adaptation) { 18824 return adaptation && adaptation.hasOwnProperty(_constantsDashConstants2['default'].VIEWPOINT) ? adaptation.Viewpoint : null; 18825 } 18826 18827 function getRolesForAdaptation(adaptation) { 18828 return adaptation && adaptation.hasOwnProperty(_constantsDashConstants2['default'].ROLE_ASARRAY) ? adaptation.Role_asArray : []; 18829 } 18830 18831 function getAccessibilityForAdaptation(adaptation) { 18832 return adaptation && adaptation.hasOwnProperty(_constantsDashConstants2['default'].ACCESSIBILITY_ASARRAY) ? adaptation.Accessibility_asArray : []; 18833 } 18834 18835 function getAudioChannelConfigurationForAdaptation(adaptation) { 18836 return adaptation && adaptation.hasOwnProperty(_constantsDashConstants2['default'].AUDIOCHANNELCONFIGURATION_ASARRAY) ? adaptation.AudioChannelConfiguration_asArray : []; 18837 } 18838 18839 function getIsMain(adaptation) { 18840 return getRolesForAdaptation(adaptation).filter(function (role) { 18841 return role.value === _constantsDashConstants2['default'].MAIN; 18842 })[0]; 18843 } 18844 18845 function getRepresentationSortFunction() { 18846 return function (a, b) { 18847 return a.bandwidth - b.bandwidth; 18848 }; 18849 } 18850 18851 function processAdaptation(realAdaptation) { 18852 if (realAdaptation && realAdaptation.Representation_asArray !== undefined && realAdaptation.Representation_asArray !== null) { 18853 realAdaptation.Representation_asArray.sort(getRepresentationSortFunction()); 18854 } 18855 18856 return realAdaptation; 18857 } 18858
18859 function getAdaptationForId(id, manifest, periodIndex) { 18860 var realAdaptations = manifest && manifest.Period_asArray && isInteger(periodIndex) ? manifest.Period_asArray[periodIndex] ? manifest.Period_asArray[periodIndex].AdaptationSet_asArray : [] : []; 18861 var i = undefined, 18862 len = undefined; 18863 18864 for (i = 0, len = realAdaptations.length; i < len; i++) { 18865 if (realAdaptations[i].hasOwnProperty(_constantsDashConstants2['default'].ID) && realAdaptations[i].id === id) { 18866 return realAdaptations[i]; 18867 } 18868 } 18869 18870 return null; 18871 } 18872 18873 function getAdaptationForIndex(index, manifest, periodIndex) { 18874 var realAdaptations = manifest && manifest.Period_asArray && isInteger(periodIndex) ? manifest.Period_asArray[periodIndex] ? manifest.Period_asArray[periodIndex].AdaptationSet_asArray : null : null; 18875 if (realAdaptations && isInteger(index)) { 18876 return realAdaptations[index]; 18877 } else { 18878 return null; 18879 } 18880 } 18881 18882 function getIndexForAdaptation(realAdaptation, manifest, periodIndex) { 18883 var realAdaptations = manifest && manifest.Period_asArray && isInteger(periodIndex) ? manifest.Period_asArray[periodIndex] ? manifest.Period_asArray[periodIndex].AdaptationSet_asArray : [] : []; 18884 var len = realAdaptations.length; 18885 18886 if (realAdaptation) { 18887 for (var i = 0; i < len; i++) { 18888 var objectUtils = (0, _streamingUtilsObjectUtils2['default'])(context).getInstance(); 18889 if (objectUtils.areEqual(realAdaptations[i], realAdaptation)) { 18890 return i; 18891 } 18892 } 18893 } 18894 18895 return -1; 18896 } 18897 18898 function getAdaptationsForType(manifest, periodIndex, type) { 18899 var realAdaptationSet = manifest && manifest.Period_asArray && isInteger(periodIndex) ? manifest.Period_asArray[periodIndex] ? manifest.Period_asArray[periodIndex].AdaptationSet_asArray : [] : []; 18900 var i = undefined, 18901 len = undefined; 18902 var adaptations = []; 18903 18904 for (i = 0, len = realAdaptationSet.length; i < len; i++) { 18905 if (getIsTypeOf(realAdaptationSet[i], type)) { 18906 adaptations.push(processAdaptation(realAdaptationSet[i])); 18907 } 18908 } 18909 18910 return adaptations; 18911 } 18912 18913 function getAdaptationForType(manifest, periodIndex, type, streamInfo) { 18914 var adaptations = getAdaptationsForType(manifest, periodIndex, type); 18915 18916 if (!adaptations || adaptations.length === 0) return null; 18917 18918 if (adaptations.length > 1 && streamInfo) { 18919 var currentTrack = mediaController.getCurrentTrackFor(type, streamInfo); 18920 var allMediaInfoForType = adapter.getAllMediaInfoForType(streamInfo, type); 18921 for (var i = 0, ln = adaptations.length; i < ln; i++) { 18922 if (currentTrack && mediaController.isTracksEqual(currentTrack, allMediaInfoForType[i])) { 18923 return adaptations[i]; 18924 } 18925 } 18926 for (var i = 0, ln = adaptations.length; i < ln; i++) { 18927 if (getIsMain(adaptations[i])) { 18928 return adaptations[i]; 18929 } 18930 } 18931 } 18932 18933 return adaptations[0]; 18934 } 18935 18936 function getCodec(adaptation, representationId) { 18937 if (adaptation && adaptation.Representation_asArray && adaptation.Representation_asArray.length > 0) { 18938 var representation = isInteger(representationId) && representationId >= 0 && representationId < adaptation.Representation_asArray.length ? adaptation.Representation_asArray[representationId] : adaptation.Representation_asArray[0]; 18939 return representation.mimeType + ';codecs="' + representation.codecs + '"'; 18940 } 18941 18942 return null; 18943 } 18944 18945 function getMimeType(adaptation) { 18946 return adaptation && adaptation.Representation_asArray && adaptation.Representation_asArray.length > 0 ? adaptation.Representation_asArray[0].mimeType : null; 18947 } 18948 18949 function getKID(adaptation) { 18950 if (!adaptation || !adaptation.hasOwnProperty(_constantsDashConstants2['default'].CENC_DEFAULT_KID)) { 18951 return null; 18952 } 18953 return adaptation[_constantsDashConstants2['default'].CENC_DEFAULT_KID]; 18954 } 18955 18956 function getContentProtectionData(adaptation) { 18957 if (!adaptation || !adaptation.hasOwnProperty(_constantsDashConstants2['default'].CONTENTPROTECTION_ASARRAY) || adaptation.ContentProtection_asArray.length === 0) { 18958 return null; 18959 } 18960 return adaptation.ContentProtection_asArray; 18961 } 18962 18963 function getIsDynamic(manifest) { 18964 var isDynamic = false; 18965 if (manifest && manifest.hasOwnProperty('type')) { 18966 isDynamic = manifest.type === _constantsDashConstants2['default'].DYNAMIC; 18967 } 18968 return isDynamic; 18969 } 18970 18971 function hasProfile(manifest, profile) { 18972 var has = false; 18973 18974 if (manifest && manifest.profiles && manifest.profiles.length > 0) { 18975 has = manifest.profiles.indexOf(profile) !== -1; 18976 } 18977 18978 return has; 18979 } 18980 18981 function getIsDVB(manifest) { 18982 return hasProfile(manifest, PROFILE_DVB); 18983 } 18984 18985 function getDuration(manifest) { 18986 var mpdDuration = undefined; 18987 //@mediaPresentationDuration specifies the duration of the entire Media Presentation. 18988 //If the attribute is not present, the duration of the Media Presentation is unknown. 18989 if (manifest && manifest.hasOwnProperty(_constantsDashConstants2['default'].MEDIA_PRESENTATION_DURATION)) { 18990 mpdDuration = manifest.mediaPresentationDuration; 18991 } else { 18992 mpdDuration = Number.MAX_SAFE_INTEGER || Number.MAX_VALUE; 18993 } 18994 18995 return mpdDuration; 18996 } 18997 18998 function getBandwidth(representation) { 18999 return representation && representation.bandwidth ? representation.bandwidth : NaN; 19000 } 19001 19002 function getManifestUpdatePeriod(manifest) { 19003 var latencyOfLastUpdate = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; 19004
19005 var delay = NaN; 19006 if (manifest && manifest.hasOwnProperty(_constantsDashConstants2['default'].MINIMUM_UPDATE_PERIOD)) { 19007 delay = manifest.minimumUpdatePeriod; 19008 } 19009 return isNaN(delay) ? delay : Math.max(delay - latencyOfLastUpdate, 1); 19010 } 19011 19012 function getRepresentationCount(adaptation) { 19013 return adaptation && adaptation.Representation_asArray && adaptation.Representation_asArray.length ? adaptation.Representation_asArray.length : 0; 19014 } 19015 19016 function getBitrateListForAdaptation(realAdaptation) { 19017 if (!realAdaptation || !realAdaptation.Representation_asArray || !realAdaptation.Representation_asArray.length) return null; 19018 19019 var processedRealAdaptation = processAdaptation(realAdaptation); 19020 var realRepresentations = processedRealAdaptation.Representation_asArray; 19021 var ln = realRepresentations.length; 19022 var bitrateList = []; 19023 var i = 0; 19024 19025 for (i = 0; i < ln; i++) { 19026 bitrateList.push({ 19027 bandwidth: realRepresentations[i].bandwidth, 19028 width: realRepresentations[i].width || 0, 19029 height: realRepresentations[i].height || 0, 19030 scanType: realRepresentations[i].scanType || null 19031 }); 19032 } 19033 19034 return bitrateList; 19035 } 19036 19037 function getRepresentationFor(index, adaptation) { 19038 return adaptation && adaptation.Representation_asArray && adaptation.Representation_asArray.length > 0 && isInteger(index) ? adaptation.Representation_asArray[index] : null; 19039 } 19040 19041 function getRepresentationsForAdaptation(voAdaptation) { 19042 var voRepresentations = []; 19043 var voRepresentation = undefined, 19044 initialization = undefined, 19045 segmentInfo = undefined, 19046 processedRealAdaptation = undefined, 19047 realRepresentation = undefined, 19048 i = undefined, 19049 s = undefined; 19050 19051 if (voAdaptation && voAdaptation.period && isInteger(voAdaptation.period.index)) { 19052 var periodArray = voAdaptation.period.mpd.manifest.Period_asArray[voAdaptation.period.index]; 19053 if (periodArray && periodArray.AdaptationSet_asArray && isInteger(voAdaptation.index)) { 19054 processedRealAdaptation = processAdaptation(periodArray.AdaptationSet_asArray[voAdaptation.index]); 19055 } 19056 } 19057 19058 for (i = 0; processedRealAdaptation && i < processedRealAdaptation.Representation_asArray.length; i++) { 19059 realRepresentation = processedRealAdaptation.Representation_asArray[i]; 19060 voRepresentation = new _voRepresentation2['default'](); 19061 voRepresentation.index = i; 19062 voRepresentation.adaptation = voAdaptation; 19063 19064 if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].ID)) { 19065 voRepresentation.id = realRepresentation.id; 19066 } 19067 if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].CODECS)) { 19068 voRepresentation.codecs = realRepresentation.codecs; 19069 } 19070 if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].CODEC_PRIVATE_DATA)) { 19071 voRepresentation.codecPrivateData = realRepresentation.codecPrivateData; 19072 } 19073 if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].BANDWITH)) { 19074 voRepresentation.bandwidth = realRepresentation.bandwidth; 19075 } 19076 if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].WIDTH)) { 19077 voRepresentation.width = realRepresentation.width; 19078 } 19079 if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].HEIGHT)) { 19080 voRepresentation.height = realRepresentation.height; 19081 } 19082 if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].SCAN_TYPE)) { 19083 voRepresentation.scanType = realRepresentation.scanType; 19084 } 19085 if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].MAX_PLAYOUT_RATE)) { 19086 voRepresentation.maxPlayoutRate = realRepresentation.maxPlayoutRate; 19087 } 19088 if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].SEGMENT_BASE)) { 19089 segmentInfo = realRepresentation.SegmentBase; 19090 voRepresentation.segmentInfoType = _constantsDashConstants2['default'].SEGMENT_BASE; 19091 } else if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].SEGMENT_LIST)) { 19092 segmentInfo = realRepresentation.SegmentList; 19093 19094 if (segmentInfo.hasOwnProperty(_constantsDashConstants2['default'].SEGMENT_TIMELINE)) { 19095 voRepresentation.segmentInfoType = _constantsDashConstants2['default'].SEGMENT_TIMELINE; 19096 s = segmentInfo.SegmentTimeline.S_asArray[segmentInfo.SegmentTimeline.S_asArray.length - 1]; 19097 if (!s.hasOwnProperty('r') || s.r >= 0) { 19098 voRepresentation.useCalculatedLiveEdgeTime = true; 19099 } 19100 } else { 19101 voRepresentation.segmentInfoType = _constantsDashConstants2['default'].SEGMENT_LIST; 19102 voRepresentation.useCalculatedLiveEdgeTime = true; 19103 } 19104 } else if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].SEGMENT_TEMPLATE)) { 19105 segmentInfo = realRepresentation.SegmentTemplate; 19106 19107 if (segmentInfo.hasOwnProperty(_constantsDashConstants2['default'].SEGMENT_TIMELINE)) { 19108 voRepresentation.segmentInfoType = _constantsDashConstants2['default'].SEGMENT_TIMELINE; 19109 s = segmentInfo.SegmentTimeline.S_asArray[segmentInfo.SegmentTimeline.S_asArray.length - 1]; 19110 if (!s.hasOwnProperty('r') || s.r >= 0) { 19111 voRepresentation.useCalculatedLiveEdgeTime = true; 19112 } 19113 } else { 19114 voRepresentation.segmentInfoType = _constantsDashConstants2['default'].SEGMENT_TEMPLATE; 19115 } 19116 19117 if (segmentInfo.hasOwnProperty(_constantsDashConstants2['default'].INITIALIZATION_MINUS)) { 19118 voRepresentation.initialization = segmentInfo.initialization.split('$Bandwidth$').join(realRepresentation.bandwidth).split('$RepresentationID$').join(realRepresentation.id); 19119 } 19120 } else { 19121 voRepresentation.segmentInfoType = _constantsDashConstants2['default'].BASE_URL; 19122 } 19123 19124 if (segmentInfo) { 19125 if (segmentInfo.hasOwnProperty(_constantsDashConstants2['default'].INITIALIZATION)) { 19126 initialization = segmentInfo.Initialization; 19127 19128 if (initialization.hasOwnProperty(_constantsDashConstants2['default'].SOURCE_URL)) { 19129 voRepresentation.initialization = initialization.sourceURL; 19130 } else if (initialization.hasOwnProperty(_constantsDashConstants2['default'].RANGE)) { 19131 voRepresentation.range = initialization.range; 19132 // initialization source url will be determined from 19133 // BaseURL when resolved at load time. 19134 } 19135 } else if (realRepresentation.hasOwnProperty(_constantsDashConstants2['default'].MIME_TYPE) && getIsTextTrack(realRepresentation.mimeType)) { 19136 voRepresentation.range = 0; 19137 } 19138 19139 if (segmentInfo.hasOwnProperty(_constantsDashConstants2['default'].TIMESCALE)) { 19140 voRepresentation.timescale = segmentInfo.timescale; 19141 } 19142 if (segmentInfo.hasOwnProperty(_constantsDashConstants2['default'].DURATION)) { 19143 // TODO according to the spec @maxSegmentDuration specifies the maximum duration of any Segment in any Representation in the Media Presentation 19144 // It is also said that for a SegmentTimeline any @d value shall not exceed the value of MPD@maxSegmentDuration, but nothing is said about 19145 // SegmentTemplate @duration attribute. We need to find out if @maxSegmentDuration should be used instead of calculated duration if the the duration 19146 // exceeds @maxSegmentDuration 19147 //representation.segmentDuration = Math.min(segmentInfo.duration / representation.timescale, adaptation.period.mpd.maxSegmentDuration); 19148 voRepresentation.segmentDuration = segmentInfo.duration / voRepresentation.timescale; 19149 } 19150 if (segmentInfo.hasOwnProperty(_constantsDashConstants2['default'].START_NUMBER)) { 19151 voRepresentation.startNumber = segmentInfo.startNumber; 19152 } 19153 if (segmentInfo.hasOwnProperty(_constantsDashConstants2['default'].INDEX_RANGE)) { 19154 voRepresentation.indexRange = segmentInfo.indexRange; 19155 } 19156 if (segmentInfo.hasOwnProperty(_constantsDashConstants2['default'].PRESENTATION_TIME_OFFSET)) { 19157 voRepresentation.presentationTimeOffset = segmentInfo.presentationTimeOffset / voRepresentation.timescale; 19158 } 19159 } 19160 19161 voRepresentation.MSETimeOffset = timelineConverter.calcMSETimeOffset(voRepresentation); 19162 voRepresentation.path = [voAdaptation.period.index, voAdaptation.index, i]; 19163 voRepresentations.push(voRepresentation); 19164 } 19165 19166 return voRepresentations; 19167 } 19168 19169 function getAdaptationsForPeriod(voPeriod) { 19170 var realPeriod = voPeriod && isInteger(voPeriod.index) ? voPeriod.mpd.manifest.Period_asArray[voPeriod.index] : null; 19171 var voAdaptations = []; 19172 var voAdaptationSet = undefined, 19173 realAdaptationSet = undefined, 19174 i = undefined; 19175 19176 if (realPeriod && realPeriod.AdaptationSet_asArray) { 19177 for (i = 0; i < realPeriod.AdaptationSet_asArray.length; i++) { 19178 realAdaptationSet = realPeriod.AdaptationSet_asArray[i]; 19179 voAdaptationSet = new _voAdaptationSet2['default'](); 19180 if (realAdaptationSet.hasOwnProperty(_constantsDashConstants2['default'].ID)) { 19181 voAdaptationSet.id = realAdaptationSet.id; 19182 } 19183 voAdaptationSet.index = i; 19184 voAdaptationSet.period = voPeriod; 19185 19186 if (getIsMuxed(realAdaptationSet)) { 19187 voAdaptationSet.type = _streamingConstantsConstants2['default'].MUXED; 19188 } else if (getIsAudio(realAdaptationSet)) { 19189 voAdaptationSet.type = _streamingConstantsConstants2['default'].AUDIO; 19190 } else if (getIsVideo(realAdaptationSet)) { 19191 voAdaptationSet.type = _streamingConstantsConstants2['default'].VIDEO; 19192 } else if (getIsFragmentedText(realAdaptationSet)) { 19193 voAdaptationSet.type = _streamingConstantsConstants2['default'].FRAGMENTED_TEXT; 19194 } else { 19195 voAdaptationSet.type = _streamingConstantsConstants2['default'].TEXT; 19196 } 19197 voAdaptations.push(voAdaptationSet); 19198 } 19199 } 19200 19201 return voAdaptations; 19202 } 19203 19204 function getRegularPeriods(mpd) { 19205 var isDynamic = mpd ? getIsDynamic(mpd.manifest) : false; 19206 var voPeriods = []; 19207 var realPeriod1 = null; 19208 var realPeriod = null; 19209 var voPeriod1 = null; 19210 var voPeriod = null; 19211 var len = undefined, 19212 i = undefined; 19213 19214 for (i = 0, len = mpd && mpd.manifest && mpd.manifest.Period_asArray ? mpd.manifest.Period_asArray.length : 0; i < len; i++) { 19215 realPeriod = mpd.manifest.Period_asArray[i]; 19216 19217 // If the attribute @start is present in the Period, then the 19218 // Period is a regular Period and the PeriodStart is equal 19219 // to the value of this attribute. 19220 if (realPeriod.hasOwnProperty(_constantsDashConstants2['default'].START)) { 19221 voPeriod = new _voPeriod2['default'](); 19222 voPeriod.start = realPeriod.start; 19223 } 19224 // If the @start attribute is absent, but the previous Per
19224iod 19225 // element contains a @duration attribute then then this new 19226 // Period is also a regular Period. The start time of the new 19227 // Period PeriodStart is the sum of the start time of the previous 19228 // Period PeriodStart and the value of the attribute @duration 19229 // of the previous Period. 19230 else if (realPeriod1 !== null && realPeriod.hasOwnProperty(_constantsDashConstants2['default'].DURATION) && voPeriod1 !== null) { 19231 voPeriod = new _voPeriod2['default'](); 19232 voPeriod.start = voPeriod1.start + voPeriod1.duration; 19233 voPeriod.duration = realPeriod.duration; 19234 } 19235 // If (i) @start attribute is absent, and (ii) the Period element 19236 // is the first in the MPD, and (iii) the MPD@type is 'static', 19237 // then the PeriodStart time shall be set to zero. 19238 else if (i === 0 && !isDynamic) { 19239 voPeriod = new _voPeriod2['default'](); 19240 voPeriod.start = 0; 19241 } 19242 19243 // The Period extends until the PeriodStart of the next Period. 19244 // The difference between the PeriodStart time of a Period and 19245 // the PeriodStart time of the following Period. 19246 if (voPeriod1 !== null && isNaN(voPeriod1.duration)) { 19247 voPeriod1.duration = voPeriod.start - voPeriod1.start; 19248 } 19249 19250 if (voPeriod !== null) { 19251 voPeriod.id = getPeriodId(realPeriod, i); 19252 } 19253 19254 if (voPeriod !== null && realPeriod.hasOwnProperty(_constantsDashConstants2['default'].DURATION)) { 19255 voPeriod.duration = realPeriod.duration; 19256 } 19257 19258 if (voPeriod !== null) { 19259 voPeriod.index = i; 19260 voPeriod.mpd = mpd; 19261 voPeriods.push(voPeriod); 19262 realPeriod1 = realPeriod; 19263 voPeriod1 = voPeriod; 19264 } 19265 19266 realPeriod = null; 19267 voPeriod = null; 19268 } 19269 19270 if (voPeriods.length === 0) { 19271 return voPeriods; 19272 } 19273 19274 // The last Period extends until the end of the Media Presentation. 19275 // The difference between the PeriodStart time of the last Period 19276 // and the mpd duration 19277 if (voPeriod1 !== null && isNaN(voPeriod1.duration)) { 19278 voPeriod1.duration = getEndTimeForLastPeriod(voPeriod1) - voPeriod1.start; 19279 } 19280 19281 return voPeriods; 19282 } 19283 19284 function getPeriodId(realPeriod, i) { 19285 if (!realPeriod) { 19286 throw new Error('Period cannot be null or undefined'); 19287 } 19288 19289 var id = _voPeriod2['default'].DEFAULT_ID + '_' + i; 19290 19291 if (realPeriod.hasOwnProperty(_constantsDashConstants2['default'].ID) && realPeriod.id.length > 0 && realPeriod.id !== '__proto__') { 19292 id = realPeriod.id; 19293 } 19294 19295 return id; 19296 } 19297 19298 function getMpd(manifest) { 19299 var mpd = new _voMpd2['default'](); 19300 19301 if (manifest) { 19302 mpd.manifest = manifest; 19303 19304 if (manifest.hasOwnProperty(_constantsDashConstants2['default'].AVAILABILITY_START_TIME)) { 19305 mpd.availabilityStartTime = new Date(manifest.availabilityStartTime.getTime()); 19306 } else { 19307 mpd.availabilityStartTime = new Date(manifest.loadedTime.getTime()); 19308 } 19309 19310 if (manifest.hasOwnProperty(_constantsDashConstants2['default'].AVAILABILITY_END_TIME)) { 19311 mpd.availabilityEndTime = new Date(manifest.availabilityEndTime.getTime()); 19312 } 19313 19314 if (manifest.hasOwnProperty(_constantsDashConstants2['default'].MINIMUM_UPDATE_PERIOD)) { 19315 mpd.minimumUpdatePeriod = manifest.minimumUpdatePeriod; 19316 } 19317 19318 if (manifest.hasOwnProperty(_constantsDashConstants2['default'].MEDIA_PRESENTATION_DURATION)) { 19319 mpd.mediaPresentationDuration = manifest.mediaPresentationDuration; 19320 } 19321 19322 if (manifest.hasOwnProperty(_streamingConstantsConstants2['default'].SUGGESTED_PRESENTATION_DELAY)) { 19323 mpd.suggestedPresentationDelay = manifest.suggestedPresentationDelay; 19324 } 19325 19326 if (manifest.hasOwnProperty(_constantsDashConstants2['default'].TIMESHIFT_BUFFER_DEPTH)) { 19327 mpd.timeShiftBufferDepth = manifest.timeShiftBufferDepth; 19328 } 19329 19330 if (manifest.hasOwnProperty(_constantsDashConstants2['default'].MAX_SEGMENT_DURATION)) { 19331 mpd.maxSegmentDuration = manifest.maxSegmentDuration; 19332 } 19333 } 19334 19335 return mpd; 19336 } 19337
19338 function getEndTimeForLastPeriod(voPeriod) { 19339 var isDynamic = getIsDynamic(voPeriod.mpd.manifest); 19340 19341 var periodEnd = undefined; 19342 if (voPeriod.mpd.manifest.mediaPresentationDuration) { 19343 periodEnd = voPeriod.mpd.manifest.mediaPresentationDuration; 19344 } else if (voPeriod.duration) { 19345 periodEnd = voPeriod.duration; 19346 } else if (isDynamic) { 19347 periodEnd = Number.POSITIVE_INFINITY; 19348 } else { 19349 throw new Error('Must have @mediaPresentationDuratio on MPD or an explicit @duration on the last period.'); 19350 } 19351 19352 return periodEnd; 19353 } 19354 19355 function getEventsForPeriod(period) { 19356 var manifest = period && period.mpd && period.mpd.manifest ? period.mpd.manifest : null; 19357 var periodArray = manifest ? manifest.Period_asArray : null; 19358 var eventStreams = periodArray && period && isInteger(period.index) ? periodArray[period.index].EventStream_asArray : null; 19359 var events = []; 19360 var i = undefined, 19361 j = undefined; 19362 19363 if (eventStreams) { 19364 for (i = 0; i < eventStreams.length; i++) { 19365 var eventStream = new _voEventStream2['default'](); 19366 eventStream.period = period; 19367 eventStream.timescale = 1; 19368 19369 if (eventStreams[i].hasOwnProperty(_streamingConstantsConstants2['default'].SCHEME_ID_URI)) { 19370 eventStream.schemeIdUri = eventStreams[i].schemeIdUri; 19371 } else { 19372 throw new Error('Invalid EventStream. SchemeIdUri has to be set'); 19373 } 19374 if (eventStreams[i].hasOwnProperty(_constantsDashConstants2['default'].TIMESCALE)) { 19375 eventStream.timescale = eventStreams[i].timescale; 19376 } 19377 if (eventStreams[i].hasOwnProperty(_constantsDashConstants2['default'].VALUE)) { 19378 eventStream.value = eventStreams[i].value; 19379 } 19380 for (j = 0; j < eventStreams[i].Event_asArray.length; j++) { 19381 var _event = new _voEvent2['default'](); 19382 _event.presentationTime = 0; 19383 _event.eventStream = eventStream; 19384 19385 if (eventStreams[i].Event_asArray[j].hasOwnProperty(_constantsDashConstants2['default'].PRESENTATION_TIME)) { 19386 _event.presentationTime = eventStreams[i].Event_asArray[j].presentationTime; 19387 } 19388 if (eventStreams[i].Event_asArray[j].hasOwnProperty(_constantsDashConstants2['default'].DURATION)) { 19389 _event.duration = eventStreams[i].Event_asArray[j].duration; 19390 } 19391 if (eventStreams[i].Event_asArray[j].hasOwnProperty(_constantsDashConstants2['default'].ID)) { 19392 _event.id = eventStreams[i].Event_asArray[j].id; 19393 } 19394 events.push(_event); 19395 } 19396 } 19397 } 19398 19399 return events; 19400 } 19401 19402 function getEventStreams(inbandStreams, representation) { 19403 var eventStreams = []; 19404 var i = undefined; 19405 19406 if (!inbandStreams) return eventStreams; 19407 19408 for (i = 0; i < inbandStreams.length; i++) { 19409 var eventStream = new _voEventStream2['default'](); 19410 eventStream.timescale = 1; 19411 eventStream.representation = representation; 19412 19413 if (inbandStreams[i].hasOwnProperty(_streamingConstantsConstants2['default'].SCHEME_ID_URI)) { 19414 eventStream.schemeIdUri = inbandStreams[i].schemeIdUri; 19415 } else { 19416 throw new Error('Invalid EventStream. SchemeIdUri has to be set'); 19417 } 19418 if (inbandStreams[i].hasOwnProperty(_constantsDashConstants2['default'].TIMESCALE)) { 19419 eventStream.timescale = inbandStreams[i].timescale; 19420 } 19421 if (inbandStreams[i].hasOwnProperty(_constantsDashConstants2['default'].VALUE)) { 19422 eventStream.value = inbandStreams[i].value; 19423 } 19424 eventStreams.push(eventStream); 19425 } 19426 19427 return eventStreams; 19428 } 19429 19430 function getEventStreamForAdaptationSet(manifest, adaptation) { 19431 var inbandStreams = undefined, 19432 periodArray = undefined, 19433 adaptationArray = undefined; 19434 19435 if (manifest && manifest.Period_asArray && adaptation && adaptation.period && isInteger(adaptation.period.index)) { 19436 periodArray = manifest.Period_asArray[adaptation.period.index]; 19437 if (periodArray && periodArray.AdaptationSet_asArray && isInteger(adaptation.index)) { 19438 adaptationArray = periodArray.AdaptationSet_asArray[adaptation.index]; 19439 if (adaptationArray) { 19440 inbandStreams = adaptationArray.InbandEventStream_asArray; 19441 } 19442 } 19443 } 19444 19445 return getEventStreams(inbandStreams, null); 19446 } 19447 19448 function getEventStreamForRepresentation(manifest, representation) { 19449 var inbandStreams = undefined, 19450 periodArray = undefined, 19451 adaptationArray = undefined, 19452 representationArray = undefined; 19453 19454 if (manifest && manifest.Period_asArray && representation && representation.adaptation && representation.adaptation.period && isInteger(representation.adaptation.period.index)) { 19455 periodArray = manifest.Period_asArray[representation.adaptation.period.index]; 19456 if (periodArray && periodArray.AdaptationSet_asArray && isInteger(representation.adaptation.index)) { 19457 adaptationArray = periodArray.AdaptationSet_asArray[representation.adaptation.index]; 19458 if (adaptationArray && adaptationArray.Representation_asArray && isInteger(representation.index)) { 19459 representationArray = adaptationArray.Representation_asArray[representation.index]; 19460 if (representationArray) { 19461 inbandStreams = representationArray.InbandEventStream_asArray; 19462 } 19463 } 19464 } 19465 } 19466 19467 return getEventStreams(inbandStreams, representation); 19468 } 19469 19470 function getUTCTimingSources(manifest) { 19471 var isDynamic = getIsDynamic(manifest); 19472 var hasAST = manifest ? manifest.hasOwnProperty(_constantsDashConstants2['default'].AVAILABILITY_START_TIME) : false; 19473 var utcTimingsArray = manifest ? manifest.UTCTiming_asArray : null; 19474 var utcTimingEntries = []; 19475 19476 // do not bother synchronizing the clock unless MPD is live, 19477 // or it is static and has availabilityStartTime attribute 19478 if (isDynamic || hasAST) { 19479 if (utcTimingsArray) { 19480 // the order is important here - 23009-1 states that the order 19481 // in the manifest "indicates relative preference, first having 19482 // the highest, and the last the lowest priority". 19483 utcTimingsArray.forEach(function (utcTiming) { 19484 var entry = new _voUTCTiming2['default'](); 19485 19486 if (utcTiming.hasOwnProperty(_streamingConstantsConstants2['default'].SCHEME_ID_URI)) { 19487 entry.schemeIdUri = utcTiming.schemeIdUri; 19488 } else { 19489 // entries of type DescriptorType with no schemeIdUri 19490 // are meaningless. let's just ignore this entry and 19491 // move on. 19492 return; 19493 } 19494 19495 // this is (incorrectly) interpreted as a number - schema 19496 // defines it as a string 19497 if (utcTiming.hasOwnProperty(_constantsDashConstants2['default'].VALUE)) { 19498 entry.value = utcTiming.value.toString(); 19499 } else { 19500 // without a value, there's not a lot we can do with 19501 // this entry. let's just ignore this one and move on 19502 return; 19503 } 19504 19505 // we're not interested in the optional id or any other 19506 // attributes which might be attached to the entry 19507 19508 utcTimingEntries.push(entry); 19509 }); 19510 } 19511 } 19512 19513 return utcTimingEntries; 19514 } 19515 19516 function getBaseURLsFromElement(node) { 19517 var baseUrls = []; 19518 // if node.BaseURL_asArray and node.baseUri are undefined entries 19519 // will be [undefined] which entries.some will just skip 19520 var entries = node.BaseURL_asArray || [node.baseUri]; 19521 var earlyReturn = false; 19522
19523 entries.some(function (entry) { 19524 if (entry) { 19525 var baseUrl = new _voBaseURL2['default'](); 19526 var text = entry.__text || entry; 19527 19528 if (urlUtils.isRelative(text)) { 19529 // it doesn't really make sense to have relative and 19530 // absolute URLs at the same level, or multiple 19531 // relative URLs at the same level, so assume we are 19532 // done from this level of the MPD 19533 earlyReturn = true; 19534 19535 // deal with the specific case where the MPD@BaseURL 19536 // is specified and is relative. when no MPD@BaseURL 19537 // entries exist, that case is handled by the 19538 // [node.baseUri] in the entries definition. 19539 if (node.baseUri) { 19540 text = urlUtils.resolve(text, node.baseUri); 19541 } 19542 } 19543 19544 baseUrl.url = text; 19545 19546 // serviceLocation is optional, but we need it in order 19547 // to blacklist correctly. if it's not available, use 19548 // anything unique since there's no relationship to any 19549 // other BaseURL and, in theory, the url should be 19550 // unique so use this instead. 19551 if (entry.hasOwnProperty(_constantsDashConstants2['default'].SERVICE_LOCATION) && entry.serviceLocation.length) { 19552 baseUrl.serviceLocation = entry.serviceLocation; 19553 } else { 19554 baseUrl.serviceLocation = text; 19555 } 19556 19557 if (entry.hasOwnProperty(_constantsDashConstants2['default'].DVB_PRIORITY)) { 19558 baseUrl.dvb_priority = entry[_constantsDashConstants2['default'].DVB_PRIORITY]; 19559 } 19560 19561 if (entry.hasOwnProperty(_constantsDashConstants2['default'].DVB_WEIGHT)) { 19562 baseUrl.dvb_weight = entry[_constantsDashConstants2['default'].DVB_WEIGHT]; 19563 } 19564 19565 /* NOTE: byteRange, availabilityTimeOffset, 19566 * availabilityTimeComplete currently unused 19567 */ 19568 19569 baseUrls.push(baseUrl); 19570 19571 return earlyReturn; 19572 } 19573 }); 19574 19575 return baseUrls; 19576 } 19577 19578 function getLocation(manifest) { 19579 if (manifest && manifest.hasOwnProperty(_streamingConstantsConstants2['default'].LOCATION)) { 19580 // for now, do not support multiple Locations - 19581 // just set Location to the first Location. 19582 manifest.Location = manifest.Location_asArray[0]; 19583 19584 return manifest.Location; 19585 } 19586 19587 // may well be undefined 19588 return undefined; 19589 } 19590 19591 instance = { 19592 getIsTypeOf: getIsTypeOf, 19593 getIsAudio: getIsAudio, 19594 getIsVideo: getIsVideo, 19595 getIsText: getIsText, 19596 getIsMuxed: getIsMuxed, 19597 getIsTextTrack: getIsTextTrack, 19598 getIsFragmentedText: getIsFragmentedText, 19599 getIsMain: getIsMain, 19600 getLanguageForAdaptation: getLanguageForAdaptation, 19601 getViewpointForAdaptation: getViewpointForAdaptation, 19602 getRolesForAdaptation: getRolesForAdaptation, 19603 getAccessibilityForAdaptation: getAccessibilityForAdaptation, 19604 getAudioChannelConfigurationForAdaptation: getAudioChannelConfigurationForAdaptation, 19605 getAdaptationForIndex: getAdaptationForIndex, 19606 getIndexForAdaptation: getIndexForAdaptation, 19607 getAdaptationForId: getAdaptationForId, 19608 getAdaptationsForType: getAdaptationsForType, 19609 getAdaptationForType: getAdaptationForType, 19610 getCodec: getCodec, 19611 getMimeType: getMimeType, 19612 getKID: getKID, 19613 getContentProtectionData: getContentProtectionData, 19614 getIsDynamic: getIsDynamic, 19615 getIsDVB: getIsDVB, 19616 getDuration: getDuration, 19617 getBandwidth: getBandwidth, 19618 getManifestUpdatePeriod: getManifestUpdatePeriod, 19619 getRepresentationCount: getRepresentationCount, 19620 getBitrateListForAdaptation: getBitrateListForAdaptation, 19621 getRepresentationFor: getRepresentationFor, 19622 getRepresentationsForAdaptation: getRepresentationsForAdaptation, 19623 getAdaptationsForPeriod: getAdaptationsForPeriod, 19624 getRegularPeriods: getRegularPeriods, 19625 getMpd: getMpd, 19626 getEventsForPeriod: getEventsForPeriod, 19627 getEventStreamForAdaptationSet: getEventStreamForAdaptationSet, 19628 getEventStreamForRepresentation: getEventStreamForRepresentation, 19629 getUTCTimingSources: getUTCTimingSources, 19630 getBaseURLsFromElement: getBaseURLsFromElement, 19631 getRepresentationSortFunction: getRepresentationSortFunction, 19632 getLocation: getLocation 19633 }; 19634 19635 return instance; 19636} 19637 19638DashManifestModel.__dashjs_factory_name = 'DashManifestModel'; 19639exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(DashManifestModel); 19640module.exports = exports['default']; 19641 19642},{"100":100,"199":199,"202":202,"51":51,"61":61,"81":81,"82":82,"83":83,"84":84,"85":85,"86":86,"87":87,"89":89}],64:[function(_dereq_,module,exports){ 19643/** 19644 * The copyright in this software is being made available under the BSD License, 19645 * included below. This software may be subject to other third party and contributor 19646 * rights, including patent rights, and no such rights are granted under this license. 19647 * 19648 * Copyright (c) 2013, Dash Industry Forum. 19649 * All rights reserved. 19650 * 19651 * Redistribution and use in source and binary forms, with or without modification, 19652 * are permitted provided that the following conditions are met: 19653 * * Redistributions of source code must retain the above copyright notice, this 19654 * list of conditions and the following disclaimer. 19655 * * Redistributions in binary form must reproduce the above copyright notice, 19656 * this list of conditions and the following disclaimer in the documentation and/or 19657 * other materials provided with the distribution. 19658 * * Neither the name of Dash Industry Forum nor the names of its 19659 * contributors may be used to endorse or promote products derived from this software 19660 * without specific prior written permission. 19661 * 19662 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 19663 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19664 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19665 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19666 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
19666INCLUDING, BUT 19667 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19668 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 19669 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 19670 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 19671 * POSSIBILITY OF SUCH DAMAGE. 19672 */ 19673'use strict'; 19674 19675Object.defineProperty(exports, '__esModule', { 19676 value: true 19677}); 19678 19679function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19680 19681var _coreFactoryMaker = _dereq_(51); 19682 19683var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 19684 19685var _coreDebug = _dereq_(49); 19686 19687var _coreDebug2 = _interopRequireDefault(_coreDebug); 19688 19689var _externalsObjectiron = _dereq_(3); 19690 19691var _externalsObjectiron2 = _interopRequireDefault(_externalsObjectiron); 19692 19693var _externalsXml2json = _dereq_(4); 19694 19695var _externalsXml2json2 = _interopRequireDefault(_externalsXml2json); 19696 19697var _matchersStringMatcher = _dereq_(73); 19698 19699var _matchersStringMatcher2 = _interopRequireDefault(_matchersStringMatcher); 19700 19701var _matchersDurationMatcher = _dereq_(71);
19702 19703var _matchersDurationMatcher2 = _interopRequireDefault(_matchersDurationMatcher); 19704 19705var _matchersDateTimeMatcher = _dereq_(70); 19706 19707var _matchersDateTimeMatcher2 = _interopRequireDefault(_matchersDateTimeMatcher); 19708 19709var _matchersNumericMatcher = _dereq_(72); 19710 19711var _matchersNumericMatcher2 = _interopRequireDefault(_matchersNumericMatcher); 19712 19713var _mapsRepresentationBaseValuesMap = _dereq_(67); 19714 19715var _mapsRepresentationBaseValuesMap2 = _interopRequireDefault(_mapsRepresentationBaseValuesMap); 19716 19717var _mapsSegmentValuesMap = _dereq_(68); 19718 19719var _mapsSegmentValuesMap2 = _interopRequireDefault(_mapsSegmentValuesMap); 19720 19721function DashParser(config) { 19722 19723 var context = this.context; 19724 var log = (0, _coreDebug2['default'])(context).getInstance().log; 19725 var errorHandler = config.errorHandler; 19726 19727 var instance = undefined, 19728 matchers = undefined, 19729 converter = undefined, 19730 objectIron = undefined; 19731 19732 function setup() { 19733 matchers = [new _matchersDurationMatcher2['default'](), new _matchersDateTimeMatcher2['default'](), new _matchersNumericMatcher2['default'](), new _matchersStringMatcher2['default']() // last in list to take precedence over NumericMatcher 19734 ]; 19735 19736 converter = new _externalsXml2json2['default']({ 19737 escapeMode: false, 19738 attributePrefix: '', 19739 arrayAccessForm: 'property', 19740 emptyNodeForm: 'object', 19741 stripWhitespaces: false, 19742 enableToStringFunc: false, 19743 ignoreRoot: true, 19744 matchers: matchers 19745 }); 19746 19747 objectIron = new _externalsObjectiron2['default']([new _mapsRepresentationBaseValuesMap2['default'](), new _mapsSegmentValuesMap2['default']()]); 19748 } 19749 19750 function checkConfig() { 19751 if (!errorHandler || !errorHandler.hasOwnProperty('manifestError')) { 19752 throw new Error('Missing config parameter(s)'); 19753 } 19754 } 19755 19756 function getMatchers() { 19757 return matchers; 19758 } 19759 19760 function getIron() { 19761 return objectIron; 19762 } 19763 19764 function parse(data) { 19765 var manifest = undefined; 19766 19767 checkConfig(); 19768 19769 try { 19770 var startTime = window.performance.now(); 19771 19772 manifest = converter.xml_str2json(data); 19773 19774 if (!manifest) { 19775 throw new Error('parser error'); 19776 } 19777 19778 var jsonTime = window.performance.now(); 19779 19780 objectIron.run(manifest); 19781 19782 var ironedTime = window.performance.now(); 19783 19784 log('Parsing complete: ( xml2json: ' + (jsonTime - startTime).toPrecision(3) + 'ms, objectiron: ' + (ironedTime - jsonTime).toPrecision(3) + 'ms, total: ' + ((ironedTime - startTime) / 1000).toPrecision(3) + 's)'); 19785 } catch (err) { 19786 errorHandler.manifestError('parsing the manifest failed', 'parse', data, err); 19787 return null; 19788 } 19789 19790 return manifest; 19791 } 19792 19793 instance = { 19794 parse: parse, 19795 getMatchers: getMatchers, 19796 getIron: getIron 19797 }; 19798 19799 setup(); 19800 19801 return instance; 19802} 19803 19804DashParser.__dashjs_factory_name = 'DashParser'; 19805exports['default'] = _coreFactoryMaker2['default'].getClassFactory(DashParser); 19806module.exports = exports['default']; 19807 19808},{"3":3,"4":4,"49":49,"51":51,"67":67,"68":68,"70":70,"71":71,"72":72,"73":73}],65:[function(_dereq_,module,exports){ 19809/** 19810 * The copyright in this software is being made available under the BSD License, 19811 * included below. This software may be subject to other third party and contributor 19812 * rights, including patent rights, and no such rights are granted under this license. 19813 * 19814 * Copyright (c) 2013, Dash Industry Forum. 19815 * All rights reserved. 19816 * 19817 * Redistribution and use in source and binary forms, with or without modification, 19818 * are permitted provided that the following conditions are met: 19819 * * Redistributions of source code must retain the above copyright notice, this 19820 * list of conditions and the following disclaimer. 19821 * * Redistributions in binary form must reproduce the above copyright notice, 19822 * this list of conditions and the following disclaimer in the documentation and/or 19823 * other materials provided with the distribution. 19824 * * Neither the name of Dash Industry Forum nor the names of its 19825 * contributors may be used to endorse or promote products derived from this software 19826 * without specific prior written permission. 19827 * 19828 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 19829 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19830 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19831 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19832 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
19832INCLUDING, BUT 19833 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19834 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 19835 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 19836 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 19837 * POSSIBILITY OF SUCH DAMAGE. 19838 */ 19839/** 19840 * @classdesc a property belonging to a MapNode 19841 */ 19842 19843"use strict"; 19844 19845Object.defineProperty(exports, "__esModule", { 19846 value: true 19847}); 19848 19849var _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; }; })(); 19850 19851function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 19852 19853var CommonProperty = (function () { 19854 function CommonProperty(name, merge) { 19855 _classCallCheck(this, CommonProperty); 19856 19857 var getDefaultMergeForName = function getDefaultMergeForName(n) { 19858 return n && n.length && n.charAt(0) === n.charAt(0).toUpperCase(); 19859 }; 19860 19861 this._name = name; 19862 this._merge = merge !== undefined ? merge : getDefaultMergeForName(name); 19863 } 19864 19865 _createClass(CommonProperty, [{ 19866 key: "name", 19867 get: function get() { 19868 return this._name; 19869 } 19870 }, { 19871 key: "merge", 19872 get: function get() { 19873 return this._merge; 19874 } 19875 }]); 19876 19877 return CommonProperty; 19878})(); 19879 19880exports["default"] = CommonProperty; 19881module.exports = exports["default"]; 19882 19883},{}],66:[function(_dereq_,module,exports){ 19884/** 19885 * The copyright in this software is being made available under the BSD License, 19886 * included below. This software may be subject to other third party and contributor 19887 * rights, including patent rights, and no such rights are granted under this license. 19888 * 19889 * Copyright (c) 2013, Dash Industry Forum. 19890 * All rights reserved. 19891 * 19892 * Redistribution and use in source and binary forms, with or without modification, 19893 * are permitted provided that the following conditions are met: 19894 * * Redistributions of source code must retain the above copyright notice, this 19895 * list of conditions and the following disclaimer. 19896 * * Redistributions in binary form must reproduce the above copyright notice, 19897 * this list of conditions and the following disclaimer in the documentation and/or 19898 * other materials provided with the distribution. 19899 * * Neither the name of Dash Industry Forum nor the names of its 19900 * contributors may be used to endorse or promote products derived from this software 19901 * without specific prior written permission. 19902 * 19903 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 19904 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19905 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19906 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19907 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19908 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19909 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 19910 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 19911 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 19912 * POSSIBILITY OF SUCH DAMAGE. 19913 */ 19914/** 19915 * @classdesc a node at some level in a ValueMap 19916 */ 19917'use strict'; 19918 19919Object.defineProperty(exports, '__esModule', { 19920 value: true 19921}); 19922 19923var _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; }; })();
19924 19925function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 19926 19927function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 19928 19929var _CommonProperty = _dereq_(65); 19930 19931var _CommonProperty2 = _interopRequireDefault(_CommonProperty); 19932 19933var MapNode = (function () { 19934 function MapNode(name, properties, children, isRoot, isArray) { 19935 var _this = this; 19936 19937 _classCallCheck(this, MapNode); 19938 19939 this._name = name || ''; 19940 this._properties = []; 19941 this._children = children || []; 19942 this._isRoot = isRoot || false; 19943 this._isArray = isArray || true; 19944 19945 if (Array.isArray(properties)) { 19946 properties.forEach(function (p) { 19947 _this._properties.push(new _CommonProperty2['default'](p)); 19948 }); 19949 } 19950 } 19951 19952 _createClass(MapNode, [{ 19953 key: 'name', 19954 get: function get() { 19955 return this._name; 19956 } 19957 }, { 19958 key: 'isRoot', 19959 get: function get() { 19960 return this._isRoot; 19961 } 19962 }, { 19963 key: 'isArray', 19964 get: function get() { 19965 return this._isArray; 19966 } 19967 }, { 19968 key: 'children', 19969 get: function get() { 19970 return this._children; 19971 } 19972 }, { 19973 key: 'properties', 19974 get: function get() { 19975 return this._properties; 19976 } 19977 }]); 19978 19979 return MapNode; 19980})(); 19981 19982exports['default'] = MapNode; 19983module.exports = exports['default']; 19984 19985},{"65":65}],67:[function(_dereq_,module,exports){ 19986/** 19987 * The copyright in this software is being made available under the BSD License, 19988 * included below. This software may be subject to other third party and contributor 19989 * rights, including patent rights, and no such rights are granted under this license. 19990 * 19991 * Copyright (c) 2013, Dash Industry Forum. 19992 * All rights reserved. 19993 * 19994 * Redistribution and use in source and binary forms, with or without modification, 19995 * are permitted provided that the following conditions are met: 19996 * * Redistributions of source code must retain the above copyright notice, this 19997 * list of conditions and the following disclaimer. 19998 * * Redistributions in binary form must reproduce the above copyright notice, 19999 * this list of conditions and the following disclaimer in the documentation and/or 20000 * other materials provided with the distribution. 20001 * * Neither the name of Dash Industry Forum nor the names of its 20002 * contributors may be used to endorse or promote products derived from this software 20003 * without specific prior written permission. 20004 * 20005 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20006 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20007 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20008 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20009 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20010 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20011 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20012 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20013 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20014 * POSSIBILITY OF SUCH DAMAGE. 20015 */ 20016/** 20017 * @classdesc a RepresentationBaseValuesMap type for input to objectiron 20018 */ 20019'use strict'; 20020 20021Object.defineProperty(exports, '__esModule', { 20022 value: true 20023}); 20024 20025var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 20026 20027function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20028 20029function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 20030 20031function _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, { c
20031onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 20032 20033var _MapNode2 = _dereq_(66); 20034 20035var _MapNode3 = _interopRequireDefault(_MapNode2); 20036 20037var _constantsDashConstants = _dereq_(61); 20038 20039var _constantsDashConstants2 = _interopRequireDefault(_constantsDashConstants); 20040 20041var RepresentationBaseValuesMap = (function (_MapNode) { 20042 _inherits(RepresentationBaseValuesMap, _MapNode); 20043 20044 function RepresentationBaseValuesMap() { 20045 _classCallCheck(this, RepresentationBaseValuesMap); 20046 20047 var commonProperties = [_constantsDashConstants2['default'].PROFILES, _constantsDashConstants2['default'].WIDTH, _constantsDashConstants2['default'].HEIGHT, _constantsDashConstants2['default'].SAR, _constantsDashConstants2['default'].FRAMERATE, _constantsDashConstants2['default'].AUDIO_SAMPLING_RATE, _constantsDashConstants2['default'].MIME_TYPE, _constantsDashConstants2['default'].SEGMENT_PROFILES, _constantsDashConstants2['default'].CODECS, _constantsDashConstants2['default'].MAXIMUM_SAP_PERIOD, _constantsDashConstants2['default'].START_WITH_SAP, _constantsDashConstants2['default'].MAX_PLAYOUT_RATE, _constantsDashConstants2['default'].CODING_DEPENDENCY, _constantsDashConstants2['default'].SCAN_TYPE, _constantsDashConstants2['default'].FRAME_PACKING, _constantsDashConstants2['default'].AUDIO_CHANNEL_CONFIGURATION, _constantsDashConstants2['default'].CONTENT_PROTECTION, _constantsDashConstants2['default'].ESSENTIAL_PROPERTY, _constantsDashConstants2['default'].SUPPLEMENTAL_PROPERTY, _constantsDashConstants2['default'].INBAND_EVENT_STREAM]; 20048 20049 _get(Object.getPrototypeOf(RepresentationBaseValuesMap.prototype), 'constructor', this).call(this, _constantsDashConstants2['default'].ADAPTATION_SET, commonProperties, [new _MapNode3['default'](_constantsDashConstants2['default'].REPRESENTATION, commonProperties, [new _MapNode3['default'](_constantsDashConstants2['default'].SUB_REPRESENTATION, commonProperties)])]); 20050 } 20051 20052 return RepresentationBaseValuesMap; 20053})(_MapNode3['default']); 20054 20055exports['default'] = RepresentationBaseValuesMap; 20056module.exports = exports['default']; 20057 20058},{"61":61,"66":66}],68:[function(_dereq_,module,exports){ 20059/** 20060 * The copyright in this software is being made available under the BSD License, 20061 * included below. This software may be subject to other third party and contributor 20062 * rights, including patent rights, and no such rights are granted under this license. 20063 * 20064 * Copyright (c) 2013, Dash Industry Forum. 20065 * All rights reserved. 20066 * 20067 * Redistribution and use in source and binary forms, with or without modification, 20068 * are permitted provided that the following conditions are met: 20069 * * Redistributions of source code must retain the above copyright notice, this 20070 * list of conditions and the following disclaimer. 20071 * * Redistributions in binary form must reproduce the above copyright notice, 20072 * this list of conditions and the following disclaimer in the documentation and/or 20073 * other materials provided with the distribution. 20074 * * Neither the name of Dash Industry Forum nor the names of its 20075 * contributors may be used to endorse or promote products derived from this software 20076 * without specific prior written permission. 20077 * 20078 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20079 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20080 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20081 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20082 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20083 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20084 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20085 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20086 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20087 * POSSIBILITY OF SUCH DAMAGE. 20088 */ 20089/** 20090 * @classdesc a SegmentValuesMap type for input to objectiron 20091 */ 20092'use strict'; 20093 20094Object.defineProperty(exports, '__esModule', { 20095 value: true 20096}); 20097 20098var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 20099 20100function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20101 20102function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 20103 20104function _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, { c
20104onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 20105 20106var _MapNode2 = _dereq_(66); 20107 20108var _MapNode3 = _interopRequireDefault(_MapNode2); 20109 20110var _constantsDashConstants = _dereq_(61); 20111 20112var _constantsDashConstants2 = _interopRequireDefault(_constantsDashConstants); 20113 20114var SegmentValuesMap = (function (_MapNode) { 20115 _inherits(SegmentValuesMap, _MapNode); 20116 20117 function SegmentValuesMap() { 20118 _classCallCheck(this, SegmentValuesMap); 20119 20120 var commonProperties = [_constantsDashConstants2['default'].SEGMENT_BASE, _constantsDashConstants2['default'].SEGMENT_TEMPLATE, _constantsDashConstants2['default'].SEGMENT_LIST]; 20121 20122 _get(Object.getPrototypeOf(SegmentValuesMap.prototype), 'constructor', this).call(this, _constantsDashConstants2['default'].PERIOD, commonProperties, [new _MapNode3['default'](_constantsDashConstants2['default'].ADAPTATION_SET, commonProperties, [new _MapNode3['default'](_constantsDashConstants2['default'].REPRESENTATION, commonProperties)])]); 20123 } 20124 20125 return SegmentValuesMap; 20126})(_MapNode3['default']); 20127 20128exports['default'] = SegmentValuesMap; 20129module.exports = exports['default']; 20130 20131},{"61":61,"66":66}],69:[function(_dereq_,module,exports){ 20132/** 20133 * The copyright in this software is being made available under the BSD License, 20134 * included below. This software may be subject to other third party and contributor 20135 * rights, including patent rights, and no such rights are granted under this license. 20136 * 20137 * Copyright (c) 2013, Dash Industry Forum. 20138 * All rights reserved. 20139 * 20140 * Redistribution and use in source and binary forms, with or without modification, 20141 * are permitted provided that the following conditions are met: 20142 * * Redistributions of source code must retain the above copyright notice, this 20143 * list of conditions and the following disclaimer. 20144 * * Redistributions in binary form must reproduce the above copyright notice, 20145 * this list of conditions and the following disclaimer in the documentation and/or 20146 * other materials provided with the distribution. 20147 * * Neither the name of Dash Industry Forum nor the names of its 20148 * contributors may be used to endorse or promote products derived from this software 20149 * without specific prior written permission. 20150 * 20151 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20152 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20153 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20154 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20155 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20156 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20157 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20158 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20159 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20160 * POSSIBILITY OF SUCH DAMAGE. 20161 */ 20162/** 20163 * @classdesc a base type for matching and converting types in manifest to 20164 * something more useful 20165 */ 20166 20167"use strict"; 20168 20169Object.defineProperty(exports, "__esModule", { 20170 value: true 20171}); 20172 20173var _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; }; })(); 20174 20175function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20176 20177var BaseMatcher = (function () { 20178 function BaseMatcher(test, converter) { 20179 _classCallCheck(this, BaseMatcher); 20180 20181 this._test = test; 20182 this._converter = converter; 20183 } 20184 20185 _createClass(BaseMatcher, [{ 20186 key: "test", 20187 get: function get() { 20188 return this._test; 20189 } 20190 }, { 20191 key: "converter", 20192 get: function get() { 20193 return this._converter; 20194 } 20195 }]); 20196 20197 return BaseMatcher; 20198})(); 20199 20200exports["default"] = BaseMatcher; 20201module.exports = exports["default"]; 20202 20203},{}],70:[function(_dereq_,module,exports){ 20204/** 20205 * The copyright in this software is being made available under the BSD License, 20206 * included below. This software may be subject to other third party and contributor 20207 * rights, including patent rights, and no such rights are granted under this license. 20208 * 20209 * Copyright (c) 2013, Dash Industry Forum. 20210 * All rights reserved. 20211 * 20212 * Redistribution and use in source and binary forms, with or without modification, 20213 * are permitted provided that the following conditions are met: 20214 * * Redistributions of source code must retain the above copyright notice, this 20215 * list of conditions and the following disclaimer. 20216 * * Redistributions in binary form must reproduce the above copyright notice, 20217 * this list of conditions and the following disclaimer in the documentation and/or 20218 * other materials provided with the distribution. 20219 * * Neither the name of Dash Industry Forum nor the names of its 20220 * contributors may be used to endorse or promote products derived from this software 20221 * without specific prior written permission. 20222 * 20223 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20224 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20225 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20226 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20227 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
20227INCLUDING, BUT 20228 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20229 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20230 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20231 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20232 * POSSIBILITY OF SUCH DAMAGE. 20233 */ 20234/** 20235 * @classdesc matches and converts xs:datetime to Date 20236 */ 20237'use strict'; 20238 20239Object.defineProperty(exports, '__esModule', { 20240 value: true 20241}); 20242 20243var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 20244 20245function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20246 20247function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 20248 20249function _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; } 20250 20251var _BaseMatcher2 = _dereq_(69); 20252 20253var _BaseMatcher3 = _interopRequireDefault(_BaseMatcher2); 20254 20255var SECONDS_IN_MIN = 60; 20256var MINUTES_IN_HOUR = 60; 20257var MILLISECONDS_IN_SECONDS = 1000; 20258 20259var datetimeRegex = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(?:([+-])([0-9]{2})(?::?)([0-9]{2}))?/; 20260 20261var DateTimeMatcher = (function (_BaseMatcher) { 20262 _inherits(DateTimeMatcher, _BaseMatcher); 20263 20264 function DateTimeMatcher() { 20265 _classCallCheck(this, DateTimeMatcher); 20266 20267 _get(Object.getPrototypeOf(DateTimeMatcher.prototype), 'constructor', this).call(this, function (attr) { 20268 return datetimeRegex.test(attr.value); 20269 }, function (str) { 20270 var match = datetimeRegex.exec(str); 20271 var utcDate = undefined; 20272 20273 // If the string does not contain a timezone offset different browsers can interpret it either 20274 // as UTC or as a local time so we have to parse the string manually to normalize the given date value for 20275 // all browsers 20276 utcDate = Date.UTC(parseInt(match[1], 10), parseInt(match[2], 10) - 1, // months start from zero 20277 parseInt(match[3], 10), parseInt(match[4], 10), parseInt(match[5], 10), match[6] && parseInt(match[6], 10) || 0, match[7] && parseFloat(match[7]) * MILLISECONDS_IN_SECONDS || 0); 20278 20279 // If the date has timezone offset take it into account as well 20280 if (match[9] && match[10]) { 20281 var timezoneOffset = parseInt(match[9], 10) * MINUTES_IN_HOUR + parseInt(match[10], 10); 20282 utcDate += (match[8] === '+' ? -1 : +1) * timezoneOffset * SECONDS_IN_MIN * MILLISECONDS_IN_SECONDS; 20283 } 20284 20285 return new Date(utcDate); 20286 }); 20287 } 20288 20289 return DateTimeMatcher; 20290})(_BaseMatcher3['default']); 20291 20292exports['default'] = DateTimeMatcher; 20293module.exports = exports['default']; 20294 20295},{"69":69}],71:[function(_dereq_,module,exports){ 20296/** 20297 * The copyright in this software is being made available under the BSD License, 20298 * included below. This software may be subject to other third party and contributor 20299 * rights, including patent rights, and no such rights are granted under this license. 20300 * 20301 * Copyright (c) 2013, Dash Industry Forum. 20302 * All rights reserved. 20303 * 20304 * Redistribution and use in source and binary forms, with or without modification, 20305 * are permitted provided that the following conditions are met: 20306 * * Redistributions of source code must retain the above copyright notice, this 20307 * list of conditions and the following disclaimer. 20308 * * Redistributions in binary form must reproduce the above copyright notice, 20309 * this list of conditions and the following disclaimer in the documentation and/or 20310 * other materials provided with the distribution. 20311 * * Neither the name of Dash Industry Forum nor the names of its 20312 * contributors may be used to endorse or promote products derived from this software 20313 * without specific prior written permission. 20314 * 20315 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20316 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20317 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20318 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20319 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
20319INCLUDING, BUT 20320 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20321 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20322 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20323 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20324 * POSSIBILITY OF SUCH DAMAGE. 20325 */ 20326/** 20327 * @classdesc matches and converts xs:duration to seconds 20328 */ 20329'use strict'; 20330 20331Object.defineProperty(exports, '__esModule', { 20332 value: true 20333}); 20334 20335var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 20336 20337function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20338 20339function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 20340 20341function _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; } 20342 20343var _BaseMatcher2 = _dereq_(69); 20344 20345var _BaseMatcher3 = _interopRequireDefault(_BaseMatcher2); 20346 20347var _streamingConstantsConstants = _dereq_(100); 20348 20349var _streamingConstantsConstants2 = _interopRequireDefault(_streamingConstantsConstants); 20350 20351var _constantsDashConstants = _dereq_(61); 20352 20353var _constantsDashConstants2 = _interopRequireDefault(_constantsDashConstants); 20354 20355var durationRegex = /^([-])?P(([\d.]*)Y)?(([\d.]*)M)?(([\d.]*)D)?T?(([\d.]*)H)?(([\d.]*)M)?(([\d.]*)S)?/; 20356 20357var SECONDS_IN_YEAR = 365 * 24 * 60 * 60; 20358var SECONDS_IN_MONTH = 30 * 24 * 60 * 60; 20359var SECONDS_IN_DAY = 24 * 60 * 60; 20360var SECONDS_IN_HOUR = 60 * 60; 20361var SECONDS_IN_MIN = 60; 20362 20363var DurationMatcher = (function (_BaseMatcher) { 20364 _inherits(DurationMatcher, _BaseMatcher); 20365 20366 function DurationMatcher() { 20367 _classCallCheck(this, DurationMatcher); 20368 20369 _get(Object.getPrototypeOf(DurationMatcher.prototype), 'constructor', this).call(this, function (attr) { 20370 var attributeList = [_constantsDashConstants2['default'].MIN_BUFFER_TIME, _constantsDashConstants2['default'].MEDIA_PRESENTATION_DURATION, _constantsDashConstants2['default'].MINIMUM_UPDATE_PERIOD, _constantsDashConstants2['default'].TIMESHIFT_BUFFER_DEPTH, _constantsDashConstants2['default'].MAX_SEGMENT_DURATION, _constantsDashConstants2['default'].MAX_SUBSEGMENT_DURATION, _streamingConstantsConstants2['default'].SUGGESTED_PRESENTATION_DELAY, _constantsDashConstants2['default'].START, _streamingConstantsConstants2['default'].START_TIME, _constantsDashConstants2['default'].DURATION]; 20371 var len = attributeList.length; 20372 20373 for (var i = 0; i < len; i++) { 20374 if (attr.nodeName === attributeList[i]) { 20375 return durationRegex.test(attr.value); 20376 } 20377 } 20378 20379 return false; 20380 }, function (str) { 20381 //str = "P10Y10M10DT10H10M10.1S"; 20382 var match = durationRegex.exec(str); 20383 var result = parseFloat(match[2] || 0) * SECONDS_IN_YEAR + parseFloat(match[4] || 0) * SECONDS_IN_MONTH + parseFloat(match[6] || 0) * SECONDS_IN_DAY + parseFloat(match[8] || 0) * SECONDS_IN_HOUR + parseFloat(match[10] || 0) * SECONDS_IN_MIN + parseFloat(match[12] || 0); 20384 20385 if (match[1] !== undefined) { 20386 result = -result; 20387 } 20388 20389 return result; 20390 }); 20391 } 20392 20393 return DurationMatcher; 20394})(_BaseMatcher3['default']); 20395 20396exports['default'] = DurationMatcher; 20397module.exports = exports['default']; 20398 20399},{"100":100,"61":61,"69":69}],72:[function(_dereq_,module,exports){ 20400/** 20401 * The copyright in this software is being made available under the BSD License, 20402 * included below. This software may be subject to other third party and contributor 20403 * rights, including patent rights, and no such rights are granted under this license. 20404 * 20405 * Copyright (c) 2013, Dash Industry Forum. 20406 * All rights reserved. 20407 * 20408 * Redistribution and use in source and binary forms, with or without modification, 20409 * are permitted provided that the following conditions are met: 20410 * * Redistributions of source code must retain the above copyright notice, this 20411 * list of conditions and the following disclaimer. 20412 * * Redistributions in binary form must reproduce the above copyright notice, 20413 * this list of conditions and the following disclaimer in the documentation and/or 20414 * other materials provided with the distribution. 20415 * * Neither the name of Dash Industry Forum nor the names of its 20416 * contributors may be used to endorse or promote products derived from this software 20417 * without specific prior written permission. 20418 * 20419 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20420 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20421 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20422 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20423 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
20423INCLUDING, BUT 20424 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20425 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20426 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20427 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20428 * POSSIBILITY OF SUCH DAMAGE. 20429 */ 20430/** 20431 * @classdesc Matches and converts xs:numeric to float 20432 */ 20433'use strict'; 20434 20435Object.defineProperty(exports, '__esModule', { 20436 value: true 20437}); 20438 20439var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 20440 20441function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20442 20443function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 20444 20445function _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; } 20446 20447var _BaseMatcher2 = _dereq_(69); 20448 20449var _BaseMatcher3 = _interopRequireDefault(_BaseMatcher2); 20450 20451var numericRegex = /^[-+]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?$/; 20452 20453var NumericMatcher = (function (_BaseMatcher) { 20454 _inherits(NumericMatcher, _BaseMatcher); 20455 20456 function NumericMatcher() { 20457 _classCallCheck(this, NumericMatcher); 20458 20459 _get(Object.getPrototypeOf(NumericMatcher.prototype), 'constructor', this).call(this, function (attr) { 20460 return numericRegex.test(attr.value); 20461 }, function (str) { 20462 return parseFloat(str); 20463 }); 20464 } 20465 20466 return NumericMatcher; 20467})(_BaseMatcher3['default']); 20468 20469exports['default'] = NumericMatcher; 20470module.exports = exports['default']; 20471 20472},{"69":69}],73:[function(_dereq_,module,exports){ 20473/** 20474 * The copyright in this software is being made available under the BSD License, 20475 * included below. This software may be subject to other third party and contributor 20476 * rights, including patent rights, and no such rights are granted under this license. 20477 * 20478 * Copyright (c) 2013, Dash Industry Forum. 20479 * All rights reserved. 20480 * 20481 * Redistribution and use in source and binary forms, with or without modification, 20482 * are permitted provided that the following conditions are met: 20483 * * Redistributions of source code must retain the above copyright notice, this 20484 * list of conditions and the following disclaimer. 20485 * * Redistributions in binary form must reproduce the above copyright notice, 20486 * this list of conditions and the following disclaimer in the documentation and/or 20487 * other materials provided with the distribution. 20488 * * Neither the name of Dash Industry Forum nor the names of its 20489 * contributors may be used to endorse or promote products derived from this software 20490 * without specific prior written permission. 20491 * 20492 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20493 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20494 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20495 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20496 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
20496INCLUDING, BUT 20497 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20498 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20499 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20500 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20501 * POSSIBILITY OF SUCH DAMAGE. 20502 */ 20503/** 20504 * @classdesc Matches and converts xs:string to string, but only for specific attributes on specific nodes 20505 */ 20506'use strict'; 20507 20508Object.defineProperty(exports, '__esModule', { 20509 value: true 20510}); 20511 20512var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 20513 20514function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20515 20516function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 20517 20518function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 20519 20520function _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; } 20521 20522var _BaseMatcher2 = _dereq_(69); 20523 20524var _BaseMatcher3 = _interopRequireDefault(_BaseMatcher2); 20525 20526var _constantsDashConstants = _dereq_(61); 20527 20528var _constantsDashConstants2 = _interopRequireDefault(_constantsDashConstants); 20529 20530var StringMatcher = (function (_BaseMatcher) { 20531 _inherits(StringMatcher, _BaseMatcher); 20532 20533 function StringMatcher() { 20534 _classCallCheck(this, StringMatcher); 20535 20536 _get(Object.getPrototypeOf(StringMatcher.prototype), 'constructor', this).call(this, function (attr, nodeName) { 20537 var _stringAttrsInElements; 20538 20539 var stringAttrsInElements = (_stringAttrsInElements = {}, _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].MPD, [_constantsDashConstants2['default'].ID, _constantsDashConstants2['default'].PROFILES]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].PERIOD, [_constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].BASE_URL, [_constantsDashConstants2['default'].SERVICE_LOCATION, _constantsDashConstants2['default'].BYTE_RANGE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].SEGMENT_BASE, [_constantsDashConstants2['default'].INDEX_RANGE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].INITIALIZATION, [_constantsDashConstants2['default'].RANGE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].REPRESENTATION_INDEX, [_constantsDashConstants2['default'].RANGE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].SEGMENT_LIST, [_constantsDashConstants2['default'].INDEX_RANGE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].BITSTREAM_SWITCHING, [_constantsDashConstants2['default'].RANGE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].SEGMENT_URL, [_constantsDashConstants2['default'].MEDIA_RANGE, _constantsDashConstants2['default'].INDEX_RANGE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].SEGMENT_TEMPLATE, [_constantsDashConstants2['default'].INDEX_RANGE, _constantsDashConstants2['default'].MEDIA, _constantsDashConstants2['default'].INDEX, _constantsDashConstants2['default'].INITIALIZATION_MINUS, _constantsDashConstants2['default'].BITSTREAM_SWITCHING_MINUS]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].ASSET_IDENTIFIER, [_
20539constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].EVENT_STREAM, [_constantsDashConstants2['default'].VALUE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].ADAPTATION_SET, [_constantsDashConstants2['default'].PROFILES, _constantsDashConstants2['default'].MIME_TYPE, _constantsDashConstants2['default'].SEGMENT_PROFILES, _constantsDashConstants2['default'].CODECS, _constantsDashConstants2['default'].CONTENT_TYPE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].FRAME_PACKING, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].AUDIO_CHANNEL_CONFIGURATION, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].CONTENT_PROTECTION, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].ESSENTIAL_PROPERTY, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].SUPPLEMENTAL_PROPERTY, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].INBAND_EVENT_STREAM, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].ACCESSIBILITY, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].ROLE, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].RATING, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].VIEWPOINT, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].CONTENT_COMPONENT, [_constantsDashConstants2['default'].CONTENT_TYPE]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].REPRESENTATION, [_constantsDashConstants2['default'].ID, _constantsDashConstants2['default'].DEPENDENCY_ID, _constantsDashConstants2['default'].MEDIA_STREAM_STRUCTURE_ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].SUBSET, [_constantsDashConstants2['default'].ID]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].METRICS, [_constantsDashConstants2['default'].METRICS_MINUS]), _defineProperty(_stringAttrsInElements, _constantsDashConstants2['default'].REPORTING, [_constantsDashConstants2['default'].VALUE, _constantsDashConstants2['default'].ID]), _stringAttrsInElements); 20540 if (stringAttrsInElements.hasOwnProperty(nodeName)) { 20541 var attrNames = stringAttrsInElements[nodeName]; 20542 if (attrNames !== undefined) { 20543 return attrNames.indexOf(attr.name) >= 0; 20544 } else { 20545 return false; 20546 } 20547 } 20548 return false; 20549 }, function (str) { 20550 return String(str); 20551 }); 20552 } 20553 20554 return StringMatcher; 20555})(_BaseMatcher3['default']); 20556 20557exports['default'] = StringMatcher; 20558module.exports = exports['default']; 20559 20560},{"61":61,"69":69}],74:[function(_dereq_,module,exports){ 20561/** 20562 * The copyright in this software is being made available under the BSD License, 20563 * included below. This software may be subject to other third party and contributor 20564 * rights, including patent rights, and no such rights are granted under this license. 20565 * 20566 * Copyright (c) 2013, Dash Industry Forum. 20567 * All rights reserved. 20568 * 20569 * Redistribution and use in source and binary forms, with or without modification, 20570 * are permitted provided that the following conditions are met: 20571 * * Redistributions of source code must retain the above copyright notice, this 20572 * list of conditions and the following disclaimer. 20573 * * Redistributions in binary form must reproduce the above copyright notice, 20574 * this list of conditions and the following disclaimer in the documentation and/or 20575 * other materials provided with the distribution. 20576 * * Neither the name of Dash Industry Forum nor the names of its 20577 * contributors may be used to endorse or promote products derived from this software 20578 * without specific prior written permission. 20579 * 20580 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20581 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20582 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20583 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20584 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
20584INCLUDING, BUT 20585 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20586 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20587 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20588 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20589 * POSSIBILITY OF SUCH DAMAGE. 20590 */ 20591 20592'use strict'; 20593 20594Object.defineProperty(exports, '__esModule', { 20595 value: true 20596}); 20597 20598function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20599 20600var _coreFactoryMaker = _dereq_(51); 20601 20602var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 20603 20604function FragmentedTextBoxParser() { 20605 20606 var instance = undefined, 20607 boxParser = undefined; 20608 20609 function setConfig(config) { 20610 if (!config) return; 20611 20612 if (config.boxParser) { 20613 boxParser = config.boxParser; 20614 } 20615 } 20616 20617 function getSamplesInfo(ab) { 20618 if (!boxParser) { 20619 throw new Error('boxParser is undefined'); 20620 } 20621 20622 if (!ab) { 20623 return { sampleList: [], lastSequenceNumber: NaN, totalDuration: NaN, numSequences: NaN }; 20624 } 20625 var isoFile = boxParser.parse(ab); 20626 // zero or more moofs 20627 var moofBoxes = isoFile.getBoxes('moof'); 20628 // exactly one mfhd per moof 20629 var mfhdBoxes = isoFile.getBoxes('mfhd'); 20630 20631 var sampleDuration = undefined, 20632 sampleCompositionTimeOffset = undefined, 20633 sampleCount = undefined, 20634 sampleSize = undefined, 20635 sampleDts = undefined, 20636 sampleList = undefined, 20637 sample = undefined, 20638 i = undefined, 20639 j = undefined, 20640 k = undefined, 20641 l = undefined, 20642 m = undefined, 20643 n = undefined, 20644 dataOffset = undefined, 20645 lastSequenceNumber = undefined, 20646 numSequences = undefined, 20647 totalDuration = undefined; 20648 20649 numSequences = isoFile.getBoxes('moof').length; 20650 lastSequenceNumber = mfhdBoxes[mfhdBoxes.length - 1].sequence_number; 20651 sampleCount = 0; 20652 20653 sampleList = []; 20654 var subsIndex = -1; 20655 var nextSubsSample = -1; 20656 for (l = 0; l < moofBoxes.length; l++) { 20657 var moofBox = moofBoxes[l]; 20658 // zero or more trafs per moof 20659 var trafBoxes = moofBox.getChildBoxes('traf'); 20660 for (j = 0; j < trafBoxes.length; j++) { 20661 var trafBox = trafBoxes[j]; 20662 // exactly one tfhd per traf 20663 var tfhdBox = trafBox.getChildBox('tfhd'); 20664 // zero or one tfdt per traf 20665 var tfdtBox = trafBox.getChildBox('tfdt'); 20666 sampleDts = tfdtBox.baseMediaDecodeTime; 20667 // zero or more truns per traf 20668 var trunBoxes = trafBox.getChildBoxes('trun'); 20669 // zero or more subs per traf 20670 var subsBoxes = trafBox.getChildBoxes('subs'); 20671 for (k = 0; k < trunBoxes.length; k++) { 20672 var trunBox = trunBoxes[k]; 20673 sampleCount = trunBox.sample_count; 20674 dataOffset = (tfhdBox.base_data_offset || 0) + (trunBox.data_offset || 0); 20675 20676 for (i = 0; i < sampleCount; i++) { 20677 sample = trunBox.samples[i]; 20678 sampleDuration = sample.sample_duration !== undefined ? sample.sample_duration : tfhdBox.default_sample_duration; 20679 sampleSize = sample.sample_size !== undefined ? sample.sample_size : tfhdBox.default_sample_size; 20680 sampleCompositionTimeOffset = sample.sample_composition_time_offset !== undefined ? sample.sample_composition_time_offset : 0; 20681 var sampleData = { 20682 'dts': sampleDts, 20683 'cts': sampleDts + sampleCompositionTimeOffset, 20684 'duration': sampleDuration, 20685 'offset': moofBox.offset + dataOffset, 20686 'size': sampleSize, 20687 'subSizes': [sampleSize] 20688 }; 20689 if (subsBoxes) { 20690 for (m = 0; m < subsBoxes.length; m++) { 20691 var subsBox = subsBoxes[m]; 20692 if (subsIndex < subsBox.entry_count && i > nextSubsSample) { 20693 subsIndex++; 20694 nextSubsSample += subsBox.entries[subsIndex].sample_delta; 20695 } 20696 if (i == nextSubsSample) { 20697 sampleData.subSizes = []; 20698 var entry = subsBox.entries[subsIndex]; 20699 for (n = 0; n < entry.subsample_count; n++) { 20700 sampleData.subSizes.push(entry.subsamples[n].subsample_size); 20701 } 20702 } 20703 } 20704 } 20705 sampleList.push(sampleData); 20706 dataOffset += sampleSize; 20707 sampleDts += sampleDuration; 20708 } 20709 } 20710 totalDuration = sampleDts - tfdtBox.baseMediaDecodeTime; 20711 } 20712 } 20713 return { sampleList: sampleList, lastSequenceNumber: lastSequenceNumber, totalDuration: totalDuration, numSequences: numSequences }; 20714 } 20715 20716 function getMediaTimescaleFromMoov(ab) { 20717 if (!boxParser) { 20718 throw new Error('boxParser is undefined'); 20719 } 20720 20721 var isoFile = boxParser.parse(ab); 20722 var mdhdBox = isoFile ? isoFile.getBox('mdhd') : undefined; 20723 20724 return mdhdBox ? mdhdBox.timescale : NaN; 20725 } 20726 20727 instance = { 20728 getSamplesInfo: getSamplesInfo, 20729 getMediaTimescaleFromMoov: getMediaTimescaleFromMoov,
20730 setConfig: setConfig 20731 }; 20732 20733 return instance; 20734} 20735 20736FragmentedTextBoxParser.__dashjs_factory_name = 'FragmentedTextBoxParser'; 20737exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(FragmentedTextBoxParser); 20738module.exports = exports['default']; 20739 20740},{"51":51}],75:[function(_dereq_,module,exports){ 20741/** 20742 * The copyright in this software is being made available under the BSD License, 20743 * included below. This software may be subject to other third party and contributor 20744 * rights, including patent rights, and no such rights are granted under this license. 20745 * 20746 * Copyright (c) 2013, Dash Industry Forum. 20747 * All rights reserved. 20748 * 20749 * Redistribution and use in source and binary forms, with or without modification, 20750 * are permitted provided that the following conditions are met: 20751 * * Redistributions of source code must retain the above copyright notice, this 20752 * list of conditions and the following disclaimer. 20753 * * Redistributions in binary form must reproduce the above copyright notice, 20754 * this list of conditions and the following disclaimer in the documentation and/or 20755 * other materials provided with the distribution. 20756 * * Neither the name of Dash Industry Forum nor the names of its 20757 * contributors may be used to endorse or promote products derived from this software 20758 * without specific prior written permission. 20759 * 20760 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20761 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20762 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20763 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20764 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20765 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20766 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20767 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20768 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20769 * POSSIBILITY OF SUCH DAMAGE. 20770 */ 20771 20772'use strict'; 20773 20774Object.defineProperty(exports, '__esModule', { 20775 value: true 20776}); 20777 20778function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20779 20780var _coreFactoryMaker = _dereq_(51); 20781 20782var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 20783 20784var _SegmentsUtils = _dereq_(77); 20785 20786function ListSegmentsGetter(config, isDynamic) { 20787 20788 var timelineConverter = config.timelineConverter; 20789 20790 var instance = undefined; 20791 20792 function getSegmentsFromList(representation, requestedTime, index) { 20793 var list = representation.adaptation.period.mpd.manifest.Period_asArray[representation.adaptation.period.index].AdaptationSet_asArray[representation.adaptation.index].Representation_asArray[representation.index].SegmentList; 20794 var len = list.SegmentURL_asArray.length; 20795 20796 var segments = []; 20797 20798 var periodSegIdx = undefined, 20799 seg = undefined, 20800 s = undefined, 20801 range = undefined, 20802 startIdx = undefined, 20803 endIdx = undefined, 20804 start = undefined; 20805 20806 start = representation.startNumber; 20807 20808 range = (0, _SegmentsUtils.decideSegmentListRangeForTemplate)(timelineConverter, isDynamic, representation, requestedTime, index); 20809 startIdx = Math.max(range.start, 0); 20810 endIdx = Math.min(range.end, list.SegmentURL_asArray.length - 1); 20811 20812 for (periodSegIdx = startIdx; periodSegIdx <= endIdx; periodSegIdx++) { 20813 s = list.SegmentURL_asArray[periodSegIdx]; 20814 20815 seg = (0, _SegmentsUtils.getIndexBasedSegment)(timelineConverter, isDynamic, representation, periodSegIdx); 20816 seg.replacementTime = (start + periodSegIdx - 1) * representation.segmentDuration; 20817 seg.media = s.media ? s.media : ''; 20818 seg.mediaRange = s.mediaRange; 20819 seg.index = s.index; 20820 seg.indexRange = s.indexRange; 20821 20822 segments.push(seg); 20823 seg = null; 20824 } 20825 20826 representation.availableSegmentsNumber = len; 20827 20828 return segments; 20829 } 20830 20831 instance = { 20832 getSegments: getSegmentsFromList 20833 }; 20834 20835 return instance; 20836} 20837 20838ListSegmentsGetter.__dashjs_factory_name = 'ListSegmentsGetter'; 20839var factory = _coreFactoryMaker2['default'].getClassFactory(ListSegmentsGetter); 20840exports['default'] = factory; 20841module.exports = exports['default']; 20842 20843},{"51":51,"77":77}],76:[function(_dereq_,module,exports){ 20844/** 20845 * The copyright in this software is being made available under the BSD License, 20846 * included below. This software may be subject to other third party and contributor 20847 * rights, including patent rights, and no such rights are granted under this license. 20848 * 20849 * Copyright (c) 2013, Dash Industry Forum. 20850 * All rights reserved. 20851 * 20852 * Redistribution and use in source and binary forms, with or without modification, 20853 * are permitted provided that the following conditions are met: 20854 * * Redistributions of source code must retain the above copyright notice, this 20855 * list of conditions and the following disclaimer. 20856 * * Redistributions in binary form must reproduce the above copyright notice, 20857 * this list of conditions and the following disclaimer in the documentation and/or 20858 * other materials provided with the distribution. 20859 * * Neither the name of Dash Industry Forum nor the names of its 20860 * contributors may be used to endorse or promote products derived from this software 20861 * without specific prior written permission. 20862 * 20863 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20864 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20865 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20866 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20867 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
20867INCLUDING, BUT 20868 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20869 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20870 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20871 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20872 * POSSIBILITY OF SUCH DAMAGE. 20873 */ 20874'use strict'; 20875 20876Object.defineProperty(exports, '__esModule', { 20877 value: true 20878}); 20879 20880function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 20881 20882var _constantsDashConstants = _dereq_(61); 20883 20884var _constantsDashConstants2 = _interopRequireDefault(_constantsDashConstants); 20885 20886var _coreFactoryMaker = _dereq_(51); 20887 20888var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 20889 20890var _TimelineSegmentsGetter = _dereq_(80); 20891 20892var _TimelineSegmentsGetter2 = _interopRequireDefault(_TimelineSegmentsGetter); 20893 20894var _TemplateSegmentsGetter = _dereq_(78); 20895 20896var _TemplateSegmentsGetter2 = _interopRequireDefault(_TemplateSegmentsGetter); 20897 20898var _ListSegmentsGetter = _dereq_(75); 20899 20900var _ListSegmentsGetter2 = _interopRequireDefault(_ListSegmentsGetter); 20901 20902function SegmentsGetter(config, isDynamic) { 20903 20904 var context = this.context; 20905 20906 var instance = undefined, 20907 timelineSegmentsGetter = undefined, 20908 templateSegmentsGetter = undefined, 20909 listSegmentsGetter = undefined; 20910 20911 function setup() { 20912 timelineSegmentsGetter = (0, _TimelineSegmentsGetter2['default'])(context).create(config, isDynamic); 20913 templateSegmentsGetter = (0, _TemplateSegmentsGetter2['default'])(context).create(config, isDynamic); 20914 listSegmentsGetter = (0, _ListSegmentsGetter2['default'])(context).create(config, isDynamic); 20915 } 20916 20917 function getSegments(representation, requestedTime, index, onSegmentListUpdatedCallback) { 20918 var segments = undefined; 20919 var type = representation.segmentInfoType; 20920 20921 // Already figure out the segments. 20922 if (type === _constantsDashConstants2['default'].SEGMENT_BASE || type === _constantsDashConstants2['default'].BASE_URL || !isSegmentListUpdateRequired(representation, index)) { 20923 segments = representation.segments; 20924 } else { 20925 if (type === _constantsDashConstants2['default'].SEGMENT_TIMELINE) { 20926 segments = timelineSegmentsGetter.getSegments(representation, requestedTime, index); 20927 } else if (type === _constantsDashConstants2['default'].SEGMENT_TEMPLATE) { 20928 segments = templateSegmentsGetter.getSegments(representation, requestedTime, index); 20929 } else if (type === _constantsDashConstants2['default'].SEGMENT_LIST) { 20930 segments = listSegmentsGetter.getSegments(representation, requestedTime, index); 20931 } 20932 20933 if (onSegmentListUpdatedCallback) { 20934 onSegmentListUpdatedCallback(representation, segments); 20935 } 20936 } 20937 } 20938 20939 function isSegmentListUpdateRequired(representation, index) { 20940 var segments = representation.segments; 20941 var updateRequired = false; 20942 20943 var upperIdx = undefined, 20944 lowerIdx = undefined; 20945 20946 if (!segments || segments.length === 0) { 20947 updateRequired = true; 20948 } else { 20949 lowerIdx = segments[0].availabilityIdx; 20950 upperIdx = segments[segments.length - 1].availabilityIdx; 20951 updateRequired = index < lowerIdx || index > upperIdx; 20952 } 20953 20954 return updateRequired; 20955 } 20956 20957 instance = { 20958 getSegments: getSegments 20959 }; 20960 20961 setup(); 20962 20963 return instance; 20964} 20965 20966SegmentsGetter.__dashjs_factory_name = 'SegmentsGetter'; 20967var factory = _coreFactoryMaker2['default'].getClassFactory(SegmentsGetter); 20968exports['default'] = factory; 20969module.exports = exports['default']; 20970 20971},{"51":51,"61":61,"75":75,"78":78,"80":80}],77:[function(_dereq_,module,exports){ 20972/** 20973 * The copyright in this software is being made available under the BSD License, 20974 * included below. This software may be subject to other third party and contributor 20975 * rights, including patent rights, and no such rights are granted under this license. 20976 * 20977 * Copyright (c) 2013, Dash Industry Forum. 20978 * All rights reserved. 20979 * 20980 * Redistribution and use in source and binary forms, with or without modification, 20981 * are permitted provided that the following conditions are met: 20982 * * Redistributions of source code must retain the above copyright notice, this 20983 * list of conditions and the following disclaimer. 20984 * * Redistributions in binary form must reproduce the above copyright notice, 20985 * this list of conditions and the following disclaimer in the documentation and/or 20986 * other materials provided with the distribution. 20987 * * Neither the name of Dash Industry Forum nor the names of its 20988 * contributors may be used to endorse or promote products derived from this software 20989 * without specific prior written permission. 20990 * 20991 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 20992 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20993 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20994 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20995 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
20995INCLUDING, BUT 20996 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20997 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20998 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20999 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 21000 * POSSIBILITY OF SUCH DAMAGE. 21001 */ 21002 21003'use strict'; 21004 21005Object.defineProperty(exports, '__esModule', { 21006 value: true 21007}); 21008exports.replaceTokenForTemplate = replaceTokenForTemplate; 21009exports.getIndexBasedSegment = getIndexBasedSegment; 21010exports.getTimeBasedSegment = getTimeBasedSegment; 21011exports.getSegmentByIndex = getSegmentByIndex; 21012exports.decideSegmentListRangeForTemplate = decideSegmentListRangeForTemplate; 21013 21014function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21015 21016var _voSegment = _dereq_(88); 21017 21018var _voSegment2 = _interopRequireDefault(_voSegment); 21019 21020function zeroPadToLength(numStr, minStrLength) { 21021 while (numStr.length < minStrLength) { 21022 numStr = '0' + numStr; 21023 } 21024 return numStr; 21025} 21026 21027function getNumberForSegment(segment, segmentIndex) { 21028 return segment.representation.startNumber + segmentIndex; 21029} 21030 21031function replaceTokenForTemplate(url, token, value) { 21032 var formatTag = '%0'; 21033 21034 var startPos = undefined, 21035 endPos = undefined, 21036 formatTagPos = undefined, 21037 specifier = undefined, 21038 width = undefined, 21039 paddedValue = undefined; 21040 21041 var tokenLen = token.length; 21042 var formatTagLen = formatTag.length; 21043 21044 if (!url) { 21045 return url; 21046 } 21047 21048 // keep looping round until all instances of <token> have been 21049 // replaced. once that has happened, startPos below will be -1 21050 // and the completed url will be returned. 21051 while (true) { 21052 21053 // check if there is a valid $<token>...$ identifier 21054 // if not, return the url as is. 21055 startPos = url.indexOf('$' + token); 21056 if (startPos < 0) { 21057 return url; 21058 } 21059 21060 // the next '$' must be the end of the identifier 21061 // if there isn't one, return the url as is. 21062 endPos = url.indexOf('$', startPos + tokenLen); 21063 if (endPos < 0) { 21064 return url; 21065 } 21066 21067 // now see if there is an additional format tag suffixed to 21068 // the identifier within the enclosing '$' characters 21069 formatTagPos = url.indexOf(formatTag, startPos + tokenLen); 21070 if (formatTagPos > startPos && formatTagPos < endPos) { 21071 21072 specifier = url.charAt(endPos - 1); 21073 width = parseInt(url.substring(formatTagPos + formatTagLen, endPos - 1), 10); 21074 21075 // support the minimum specifiers required by IEEE 1003.1 21076 // (d, i , o, u, x, and X) for completeness 21077 switch (specifier) { 21078 // treat all int types as uint, 21079 // hence deliberate fallthrough 21080 case 'd': 21081 case 'i': 21082 case 'u': 21083 paddedValue = zeroPadToLength(value.toString(), width); 21084 break; 21085 case 'x': 21086 paddedValue = zeroPadToLength(value.toString(16), width); 21087 break; 21088 case 'X': 21089 paddedValue = zeroPadToLength(value.toString(16), width).toUpperCase(); 21090 break; 21091 case 'o': 21092 paddedValue = zeroPadToLength(value.toString(8), width); 21093 break; 21094 default: 21095 //TODO: commented out logging to supress jshint warning -- `log` is undefined here 21096 //log('Unsupported/invalid IEEE 1003.1 format identifier string in URL'); 21097 return url; 21098 } 21099 } else { 21100 paddedValue = value; 21101 } 21102 21103 url = url.substring(0, startPos) + paddedValue + url.substring(endPos + 1); 21104 } 21105} 21106 21107function getIndexBasedSegment(timelineConverter, isDynamic, representation, index) { 21108 var seg = undefined, 21109 duration = undefined, 21110 presentationStartTime = undefined, 21111 presentationEndTime = undefined; 21112 21113 duration = representation.segmentDuration; 21114 21115 /* 21116 * From spec - If neither @duration attribute nor SegmentTimeline element is present, then the Representation 21117 * shall contain exactly one Media Segment. The MPD start time is 0 and the MPD duration is obtained 21118 * in the same way as for the last Media Segment in the Representation. 21119 */ 21120 if (isNaN(duration)) { 21121 duration = representation.adaptation.period.duration; 21122 } 21123 21124 presentationStartTime = representation.adaptation.period.start + index * duration; 21125 presentationEndTime = presentationStartTime + duration; 21126 21127 seg = new _voSegment2['default'](); 21128 21129 seg.representation = representation; 21130 seg.duration = duration; 21131 seg.presentationStartTime = presentationStartTime; 21132 21133 seg.mediaStartTime = timelineConverter.calcMediaTimeFromPresentationTime(seg.presentationStartTime, representation); 21134 21135 seg.availabilityStartTime = timelineConverter.calcAvailabilityStartTimeFromPresentationTime(seg.presentationStartTime, representation.adaptation.period.mpd, isDynamic); 21136 seg.availabilityEndTime = timelineConverter.calcAvailabilityEndTimeFromPresentationTime(presentationEndTime, representation.adaptation.period.mpd, isDynamic); 21137
21138 // at this wall clock time, the video element currentTime should be seg.presentationStartTime 21139 seg.wallStartTime = timelineConverter.calcWallTimeForSegment(seg, isDynamic); 21140 21141 seg.replacementNumber = getNumberForSegment(seg, index); 21142 seg.availabilityIdx = index; 21143 21144 return seg; 21145} 21146 21147function getTimeBasedSegment(timelineConverter, isDynamic, representation, time, duration, fTimescale, url, range, index, tManifest) { 21148 var scaledTime = time / fTimescale; 21149 var scaledDuration = Math.min(duration / fTimescale, representation.adaptation.period.mpd.maxSegmentDuration); 21150 21151 var presentationStartTime = undefined, 21152 presentationEndTime = undefined, 21153 seg = undefined; 21154 21155 presentationStartTime = timelineConverter.calcPresentationTimeFromMediaTime(scaledTime, representation); 21156 presentationEndTime = presentationStartTime + scaledDuration; 21157 21158 seg = new _voSegment2['default'](); 21159 21160 seg.representation = representation; 21161 seg.duration = scaledDuration; 21162 seg.mediaStartTime = scaledTime; 21163 21164 seg.presentationStartTime = presentationStartTime; 21165 21166 // For SegmentTimeline every segment is available at loadedTime 21167 seg.availabilityStartTime = representation.adaptation.period.mpd.manifest.loadedTime; 21168 seg.availabilityEndTime = timelineConverter.calcAvailabilityEndTimeFromPresentationTime(presentationEndTime, representation.adaptation.period.mpd, isDynamic); 21169 21170 // at this wall clock time, the video element currentTime should be seg.presentationStartTime 21171 seg.wallStartTime = timelineConverter.calcWallTimeForSegment(seg, isDynamic); 21172 21173 seg.replacementTime = tManifest ? tManifest : time; 21174 21175 seg.replacementNumber = getNumberForSegment(seg, index); 21176 21177 url = replaceTokenForTemplate(url, 'Number', seg.replacementNumber); 21178 url = replaceTokenForTemplate(url, 'Time', seg.replacementTime); 21179 seg.media = url; 21180 seg.mediaRange = range; 21181 seg.availabilityIdx = index; 21182 21183 return seg; 21184} 21185 21186function getSegmentByIndex(index, representation) { 21187 if (!representation || !representation.segments) return null; 21188 21189 var ln = representation.segments.length; 21190 var seg = undefined, 21191 i = undefined; 21192 21193 if (index < ln) { 21194 seg = representation.segments[index]; 21195 if (seg && seg.availabilityIdx === index) { 21196 return seg; 21197 } 21198 } 21199 21200 for (i = 0; i < ln; i++) { 21201 seg = representation.segments[i]; 21202 21203 if (seg && seg.availabilityIdx === index) { 21204 return seg; 21205 } 21206 } 21207 21208 return null; 21209} 21210 21211function decideSegmentListRangeForTemplate(timelineConverter, isDynamic, representation, requestedTime, index, givenAvailabilityUpperLimit) { 21212 var duration = representation.segmentDuration; 21213 var minBufferTime = representation.adaptation.period.mpd.manifest.minBufferTime; 21214 var availabilityWindow = representation.segmentAvailabilityRange; 21215 var periodRelativeRange = { 21216 start: timelineConverter.calcPeriodRelativeTimeFromMpdRelativeTime(representation, availabilityWindow.start), 21217 end: timelineConverter.calcPeriodRelativeTimeFromMpdRelativeTime(representation, availabilityWindow.end) 21218 }; 21219 var currentSegmentList = representation.segments; 21220 var availabilityLowerLimit = 2 * duration; 21221 var availabilityUpperLimit = givenAvailabilityUpperLimit || Math.max(2 * minBufferTime, 10 * duration); 21222 21223 var originAvailabilityTime = NaN; 21224 var originSegment = null; 21225 21226 var start = undefined, 21227 end = undefined, 21228 range = undefined; 21229 21230 periodRelativeRange.start = Math.max(periodRelativeRange.start, 0); 21231 21232 if (isDynamic && !timelineConverter.isTimeSyncCompleted()) { 21233 start = Math.floor(periodRelativeRange.start / duration); 21234 end = Math.floor(periodRelativeRange.end / duration); 21235 range = { start: start, end: end }; 21236 return range; 21237 } 21238 21239 // if segments exist we should try to find the latest buffered time, which is the presentation time of the 21240 // segment for the current index 21241 if (currentSegmentList && currentSegmentList.length > 0) { 21242 originSegment = getSegmentByIndex(index, representation); 21243 if (originSegment) { 21244 originAvailabilityTime = timelineConverter.calcPeriodRelativeTimeFromMpdRelativeTime(representation, originSegment.presentationStartTime); 21245 } else { 21246 originAvailabilityTime = index > 0 ? index * duration : timelineConverter.calcPeriodRelativeTimeFromMpdRelativeTime(representation, requestedTime); 21247 } 21248 } else { 21249 // If no segments exist, but index > 0, it means that we switch to the other representation, so 21250 // we should proceed from this time. 21251 // Otherwise we should start from the beginning for static mpds or from the end (live edge) for dynamic mpds 21252 originAvailabilityTime = index > 0 ? index * duration : isDynamic ? periodRelativeRange.end : periodRelativeRange.start; 21253 } 21254 21255 // segment list should not be out of the availability window range 21256 start = Math.floor(Math.max(originAvailabilityTime - availabilityLowerLimit, peri
21256odRelativeRange.start) / duration); 21257 end = Math.floor(Math.min(start + availabilityUpperLimit / duration, periodRelativeRange.end / duration)); 21258 21259 range = { start: start, end: end }; 21260 21261 return range; 21262} 21263 21264},{"88":88}],78:[function(_dereq_,module,exports){ 21265/** 21266 * The copyright in this software is being made available under the BSD License, 21267 * included below. This software may be subject to other third party and contributor 21268 * rights, including patent rights, and no such rights are granted under this license. 21269 * 21270 * Copyright (c) 2013, Dash Industry Forum. 21271 * All rights reserved. 21272 * 21273 * Redistribution and use in source and binary forms, with or without modification, 21274 * are permitted provided that the following conditions are met: 21275 * * Redistributions of source code must retain the above copyright notice, this 21276 * list of conditions and the following disclaimer. 21277 * * Redistributions in binary form must reproduce the above copyright notice, 21278 * this list of conditions and the following disclaimer in the documentation and/or 21279 * other materials provided with the distribution. 21280 * * Neither the name of Dash Industry Forum nor the names of its 21281 * contributors may be used to endorse or promote products derived from this software 21282 * without specific prior written permission. 21283 * 21284 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 21285 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21286 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21287 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21288 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21289 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21290 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21291 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21292 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 21293 * POSSIBILITY OF SUCH DAMAGE. 21294 */ 21295 21296'use strict'; 21297 21298Object.defineProperty(exports, '__esModule', { 21299 value: true 21300}); 21301 21302function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21303 21304var _coreFactoryMaker = _dereq_(51); 21305 21306var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 21307 21308var _SegmentsUtils = _dereq_(77); 21309 21310function TemplateSegmentsGetter(config, isDynamic) { 21311 21312 var timelineConverter = config.timelineConverter; 21313 21314 var instance = undefined; 21315 21316 function getSegmentsFromTemplate(representation, requestedTime, index) { 21317 var template = representation.adaptation.period.mpd.manifest.Period_asArray[representation.adaptation.period.index].AdaptationSet_asArray[representation.adaptation.index].Representation_asArray[representation.index].SegmentTemplate; 21318 var duration = representation.segmentDuration; 21319 var availabilityWindow = representation.segmentAvailabilityRange; 21320 21321 var segments = []; 21322 var url = null; 21323 var seg = null; 21324 21325 var segmentRange = undefined, 21326 periodSegIdx = undefined, 21327 startIdx = undefined, 21328 endIdx = undefined, 21329 start = undefined; 21330 21331 start = representation.startNumber; 21332 21333 if (isNaN(duration) && !isDynamic) { 21334 segmentRange = { start: start, end: start }; 21335 } else { 21336 segmentRange = (0, _SegmentsUtils.decideSegmentListRangeForTemplate)(timelineConverter, isDynamic, representation, requestedTime, index); 21337 } 21338 21339 startIdx = segmentRange.start; 21340 endIdx = segmentRange.end; 21341 21342 for (periodSegIdx = startIdx; periodSegIdx <= endIdx; periodSegIdx++) { 21343 21344 seg = (0, _SegmentsUtils.getIndexBasedSegment)(timelineConverter, isDynamic, representation, periodSegIdx); 21345 seg.replacementTime = (start + periodSegIdx - 1) * representation.segmentDuration; 21346 url = template.media; 21347 url = (0, _SegmentsUtils.replaceTokenForTemplate)(url, 'Number', seg.replacementNumber); 21348 url = (0, _SegmentsUtils.replaceTokenForTemplate)(url, 'Time', seg.replacementTime); 21349 seg.media = url; 21350 21351 segments.push(seg); 21352 seg = null; 21353 } 21354 21355 if (isNaN(duration)) { 21356 representation.availableSegmentsNumber = 1; 21357 } else {
21358 representation.availableSegmentsNumber = Math.ceil((availabilityWindow.end - availabilityWindow.start) / duration); 21359 } 21360 21361 return segments; 21362 } 21363 21364 instance = { 21365 getSegments: getSegmentsFromTemplate 21366 }; 21367 21368 return instance; 21369} 21370 21371TemplateSegmentsGetter.__dashjs_factory_name = 'TemplateSegmentsGetter'; 21372var factory = _coreFactoryMaker2['default'].getClassFactory(TemplateSegmentsGetter); 21373exports['default'] = factory; 21374module.exports = exports['default']; 21375 21376},{"51":51,"77":77}],79:[function(_dereq_,module,exports){ 21377/** 21378 * The copyright in this software is being made available under the BSD License, 21379 * included below. This software may be subject to other third party and contributor 21380 * rights, including patent rights, and no such rights are granted under this license. 21381 * 21382 * Copyright (c) 2013, Dash Industry Forum. 21383 * All rights reserved. 21384 * 21385 * Redistribution and use in source and binary forms, with or without modification, 21386 * are permitted provided that the following conditions are met: 21387 * * Redistributions of source code must retain the above copyright notice, this 21388 * list of conditions and the following disclaimer. 21389 * * Redistributions in binary form must reproduce the above copyright notice, 21390 * this list of conditions and the following disclaimer in the documentation and/or 21391 * other materials provided with the distribution. 21392 * * Neither the name of Dash Industry Forum nor the names of its 21393 * contributors may be used to endorse or promote products derived from this software 21394 * without specific prior written permission. 21395 * 21396 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 21397 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21398 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21399 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21400 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21401 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21402 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21403 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21404 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 21405 * POSSIBILITY OF SUCH DAMAGE. 21406 */ 21407'use strict'; 21408 21409Object.defineProperty(exports, '__esModule', { 21410 value: true 21411}); 21412 21413function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21414 21415var _coreEventBus = _dereq_(50); 21416 21417var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 21418 21419var _coreEventsEvents = _dereq_(54); 21420 21421var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 21422 21423var _coreFactoryMaker = _dereq_(51); 21424 21425var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 21426 21427function TimelineConverter() { 21428 21429 var context = this.context; 21430 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 21431 21432 var instance = undefined, 21433 clientServerTimeShift = undefined, 21434 isClientServerTimeSyncCompleted = undefined, 21435 expectedLiveEdge = undefined; 21436 21437 function initialize() { 21438 resetInitialSettings(); 21439 eventBus.on(_coreEventsEvents2['default'].TIME_SYNCHRONIZATION_COMPLETED, onTimeSyncComplete, this); 21440 } 21441 21442 function isTimeSyncCompleted() { 21443 return isClientServerTimeSyncCompleted; 21444 } 21445 21446 function setTimeSyncCompleted(value) { 21447 isClientServerTimeSyncCompleted = value; 21448 } 21449 21450 function getClientTimeOffset() { 21451 return clientServerTimeShift; 21452 } 21453 21454 function setClientTimeOffset(value) { 21455 clientServerTimeShift = value; 21456 } 21457 21458 function getExpectedLiveEdge() { 21459 return expectedLiveEdge; 21460 } 21461 21462 function setExpectedLiveEdge(value) { 21463 expectedLiveEdge = value; 21464 } 21465 21466 function calcAvailabilityTimeFromPresentationTime(presentationTime, mpd, isDynamic, calculateEnd) { 21467 var availabilityTime = NaN; 21468 21469 if (calculateEnd) { 21470 //@timeShiftBufferDepth specifies the duration of the time shifting buffer that is guaranteed 21471 // to be available for a Media Presentation with type 'dynamic'. 21472 // When not present, the value is infinite. 21473 if (isDynamic && mpd.timeShiftBufferDepth != Number.POSITIVE_INFINITY) { 21474 availabilityTime = new Date(mpd.availabilityStartTime.getTime() + (presentationTime + mpd.timeShiftBufferDepth) * 1000); 21475 } else { 21476 availabilityTime = mpd.availabilityEndTime; 21477 } 21478 } else { 21479 if (isDynamic) { 21480 availabilityTime = new Date(mpd.availabilityStartTime.getTime() + (presentationTime - clientServerTimeShift) * 1000); 21481 } else { 21482 // in static mpd, all segments are available at the same time 21483 availabilityTime = mpd.availabilityStartTime; 21484 } 21485 } 21486 21487 return availabilityTime; 21488 } 21489 21490 function calcAvailabilityStartTimeFromPresentationTime(presentationTime, mpd, isDynamic) { 21491 return calcAvailabilityTimeFromPresentationTime.call(this, presentationTime, mpd, isDynamic); 21492 } 21493 21494 function calcAvailabilityEndTimeFromPresentationTime(presentationTime, mpd, isDynamic) { 21495 return calcAvailabilityTimeFromPresentationTime.call(this, presentationTime, mpd, isDynamic, true); 21496 } 21497
21498 function calcPresentationTimeFromWallTime(wallTime, period) { 21499 //console.log("XXX", wallTime.getTime() - period.mpd.availabilityStartTime.getTime(), clientServerTimeShift * 1000, clientServerTimeShift, period.mpd.availabilityStartTime.getTime()) 21500 return (wallTime.getTime() - period.mpd.availabilityStartTime.getTime() + clientServerTimeShift * 1000) / 1000; 21501 } 21502 21503 function calcPresentationTimeFromMediaTime(mediaTime, representation) { 21504 var periodStart = representation.adaptation.period.start; 21505 var presentationOffset = representation.presentationTimeOffset; 21506 21507 return mediaTime + (periodStart - presentationOffset); 21508 } 21509 21510 function calcMediaTimeFromPresentationTime(presentationTime, representation) { 21511 var periodStart = representation.adaptation.period.start; 21512 var presentationOffset = representation.presentationTimeOffset; 21513 21514 return presentationTime - periodStart + presentationOffset; 21515 } 21516 21517 function calcWallTimeForSegment(segment, isDynamic) { 21518 var suggestedPresentationDelay = undefined, 21519 displayStartTime = undefined, 21520 wallTime = undefined; 21521 21522 if (isDynamic) { 21523 suggestedPresentationDelay = segment.representation.adaptation.period.mpd.suggestedPresentationDelay; 21524 displayStartTime = segment.presentationStartTime + suggestedPresentationDelay; 21525 wallTime = new Date(segment.availabilityStartTime.getTime() + displayStartTime * 1000); 21526 } 21527 21528 return wallTime; 21529 } 21530 21531 function calcSegmentAvailabilityRange(voRepresentation, isDynamic) { 21532 21533 // Static Range Finder 21534 var voPeriod = voRepresentation.adaptation.period; 21535 var range = { start: voPeriod.start, end: voPeriod.start + voPeriod.duration }; 21536 if (!isDynamic) return range; 21537 21538 if (!isClientServerTimeSyncCompleted && voRepresentation.segmentAvailabilityRange) { 21539 return voRepresentation.segmentAvailabilityRange; 21540 } 21541 21542 //Dyanmic Range Finder 21543 var d = voRepresentation.segmentDuration || (voRepresentation.segments && voRepresentation.segments.length ? voRepresentation.segments[voRepresentation.segments.length - 1].duration : 0); 21544 var now = calcPresentationTimeFromWallTime(new Date(), voPeriod); 21545 var periodEnd = voPeriod.start + voPeriod.duration; 21546 range.start = Math.max(now - voPeriod.mpd.timeShiftBufferDepth, voPeriod.start); 21547 range.end = now >= periodEnd && now - d < periodEnd ? periodEnd - d : now - d; 21548 21549 return range; 21550 } 21551 21552 function calcPeriodRelativeTimeFromMpdRelativeTime(representation, mpdRelativeTime) { 21553 var periodStartTime = representation.adaptation.period.start; 21554 return mpdRelativeTime - periodStartTime; 21555 } 21556 21557 /* 21558 * We need to figure out if we want to timesync for segmentTimeine where useCalculatedLiveEdge = true 21559 * seems we figure out client offset based on logic in liveEdgeFinder getLiveEdge timelineConverter.setClientTimeOffset(liveEdge - representationInfo.DVRWindow.end); 21560 * FYI StreamController's onManifestUpdated entry point to timeSync 21561 * */ 21562 function onTimeSyncComplete(e) { 21563 21564 if (isClientServerTimeSyncCompleted) return; 21565 21566 if (e.offset !== undefined) { 21567 21568 setClientTimeOffset(e.offset / 1000); 21569 isClientServerTimeSyncCompleted = true; 21570 } 21571 } 21572 21573 function calcMSETimeOffset(representation) { 21574 // The MSEOffset is offset from AST for media. It is Period@start - presentationTimeOffset 21575 var presentationOffset = representation.presentationTimeOffset; 21576 var periodStart = representation.adaptation.period.start; 21577 return periodStart - presentationOffset; 21578 } 21579 21580 function resetInitialSettings() { 21581 clientServerTimeShift = 0; 21582 isClientServerTimeSyncCompleted = false; 21583 expectedLiveEdge = NaN; 21584 } 21585 21586 function reset() { 21587 eventBus.off(_coreEventsEvents2['default'].TIME_SYNCHRONIZATION_COMPLETED, onTimeSyncComplete, this); 21588 resetInitialSettings();
21589 } 21590 21591 instance = { 21592 initialize: initialize, 21593 isTimeSyncCompleted: isTimeSyncCompleted, 21594 setTimeSyncCompleted: setTimeSyncCompleted, 21595 getClientTimeOffset: getClientTimeOffset, 21596 setClientTimeOffset: setClientTimeOffset, 21597 getExpectedLiveEdge: getExpectedLiveEdge, 21598 setExpectedLiveEdge: setExpectedLiveEdge, 21599 calcAvailabilityStartTimeFromPresentationTime: calcAvailabilityStartTimeFromPresentationTime, 21600 calcAvailabilityEndTimeFromPresentationTime: calcAvailabilityEndTimeFromPresentationTime, 21601 calcPresentationTimeFromWallTime: calcPresentationTimeFromWallTime, 21602 calcPresentationTimeFromMediaTime: calcPresentationTimeFromMediaTime, 21603 calcPeriodRelativeTimeFromMpdRelativeTime: calcPeriodRelativeTimeFromMpdRelativeTime, 21604 calcMediaTimeFromPresentationTime: calcMediaTimeFromPresentationTime, 21605 calcSegmentAvailabilityRange: calcSegmentAvailabilityRange, 21606 calcWallTimeForSegment: calcWallTimeForSegment, 21607 calcMSETimeOffset: calcMSETimeOffset, 21608 reset: reset 21609 }; 21610 21611 return instance; 21612} 21613 21614TimelineConverter.__dashjs_factory_name = 'TimelineConverter'; 21615exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(TimelineConverter); 21616module.exports = exports['default']; 21617 21618},{"50":50,"51":51,"54":54}],80:[function(_dereq_,module,exports){ 21619/** 21620 * The copyright in this software is being made available under the BSD License, 21621 * included below. This software may be subject to other third party and contributor 21622 * rights, including patent rights, and no such rights are granted under this license. 21623 * 21624 * Copyright (c) 2013, Dash Industry Forum. 21625 * All rights reserved. 21626 * 21627 * Redistribution and use in source and binary forms, with or without modification, 21628 * are permitted provided that the following conditions are met: 21629 * * Redistributions of source code must retain the above copyright notice, this 21630 * list of conditions and the following disclaimer. 21631 * * Redistributions in binary form must reproduce the above copyright notice, 21632 * this list of conditions and the following disclaimer in the documentation and/or 21633 * other materials provided with the distribution. 21634 * * Neither the name of Dash Industry Forum nor the names of its 21635 * contributors may be used to endorse or promote products derived from this software 21636 * without specific prior written permission. 21637 * 21638 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 21639 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21640 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21641 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21642 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21643 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21644 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21645 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21646 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 21647 * POSSIBILITY OF SUCH DAMAGE. 21648 */ 21649 21650'use strict'; 21651 21652Object.defineProperty(exports, '__esModule', { 21653 value: true 21654}); 21655 21656function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 21657 21658var _coreFactoryMaker = _dereq_(51); 21659 21660var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 21661 21662var _SegmentsUtils = _dereq_(77); 21663 21664function TimelineSegmentsGetter(config, isDynamic) { 21665 21666 var timelineConverter = config.timelineConverter; 21667 21668 var instance = undefined; 21669 21670 function checkConfig() { 21671 if (!timelineConverter || !timelineConverter.hasOwnProperty('calcMediaTimeFromPresentationTime') || !timelineConverter.hasOwnProperty('calcSegmentAvailabilityRange') || !timelineConverter.hasOwnProperty('calcMediaTimeFromPresentationTime')) { 21672 throw new Error('Missing config parameter(s)'); 21673 } 21674 } 21675 21676 function getSegmentsFromTimeline(representation, requestedTime, index) { 21677 21678 checkConfig(); 21679 21680 if (!representation) { 21681 throw new Error('no representation'); 21682 } 21683 21684 if (requestedTime === undefined) { 21685 requestedTime = null; 21686 } 21687 21688 var base = representation.adaptation.period.mpd.manifest.Period_asArray[representation.adaptation.period.index].AdaptationSet_asArray[representation.adaptation.index].Representation_asArray[representation.index].SegmentTemplate || representation.adaptation.period.mpd.manifest.Period_asArray[representation.adaptation.period.index].AdaptationSet_asArray[representation.adaptation.index].Representation_asArray[representation.index].SegmentList; 21689 var timeline = base.SegmentTimeline; 21690 var list = base.SegmentURL_asArray; 21691 var isAvailableSegmentNumberCalculated = representation.availableSegmentsNumber > 0; 21692 21693 var maxSegmentsAhead = undefined; 21694 21695 maxSegmentsAhead = index > -1 || requestedTime !== null ? 10 : Infinity; 21696 21697 var time = 0; 21698 var scaledTime = 0; 21699 var availabilityIdx = -1; 21700 var segments = []; 21701 var requiredMediaTime = null; 21702 21703 var fragments = undefined, 21704 frag = undefined, 21705 i = undefined, 21706 len = undefined, 21707 j = undefined, 21708 repeat = undefined, 21709 repeatEndTime = undefined, 21710 nextFrag = undefined, 21711 hasEnoughSegments = undefined, 21712 startIdx = undefined, 21713 fTimescale = undefined; 21714 21715 var createSegment = function createSegment(s, i) { 21716 var media = base.media; 21717 var mediaRange = s.mediaRange; 21718 21719 if (list) { 21720 media = list[i].media || ''; 21721 mediaRange = list[i].mediaRange; 21722 } 21723 21724 return (0, _SegmentsUtils.getTimeBasedSegment)(timelineConverter, isDynamic, representation, time, s.d, fTimescale, media, mediaRange, availabilityIdx, s.tManifest); 21725 }; 21726 21727 fTimescale = representation.timescale; 21728 21729 fragments = timeline.S_asArray; 21730 21731 startIdx = index; 21732 21733 if (requestedTime !== null) { 21734 requiredMediaTime = timelineConverter.calcMediaTimeFromPresentationTime(requestedTime, representation); 21735 } 21736 21737 for (i = 0, len = fragments.length; i < len; i++) { 21738 frag = fragments[i]; 21739 repeat = 0; 21740 if (frag.hasOwnProperty('r')) { 21741 repeat = frag.r; 21742 } 21743 21744 //For a repeated S element, t belongs only to the first segment 21745 if (frag.hasOwnProperty('t')) { 21746 time = frag.t; 21747 scaledTime = time / fTimescale; 21748 } 21749 21750 //This is a special case: "A negative value of the @r attribute of the S element indicates that the duration indicated in @d attribute repeats until the start of the next S element, the end of the Period or until the 21751 // next MPD update." 21752 if (repeat < 0) { 21753 nextFrag = fragments[i + 1];
21754 21755 if (nextFrag && nextFrag.hasOwnProperty('t')) { 21756 repeatEndTime = nextFrag.t / fTimescale; 21757 } else { 21758 var availabilityEnd = representation.segmentAvailabilityRange ? representation.segmentAvailabilityRange.end : timelineConverter.calcSegmentAvailabilityRange(representation, isDynamic).end; 21759 repeatEndTime = timelineConverter.calcMediaTimeFromPresentationTime(availabilityEnd, representation); 21760 representation.segmentDuration = frag.d / fTimescale; 21761 } 21762 21763 repeat = Math.ceil((repeatEndTime - scaledTime) / (frag.d / fTimescale)) - 1; 21764 } 21765 21766 // if we have enough segments in the list, but we have not calculated the total number of the segments yet we 21767 // should continue the loop and calc the number. Once it is calculated, we can break the loop. 21768 if (hasEnoughSegments) { 21769 if (isAvailableSegmentNumberCalculated) break; 21770 availabilityIdx += repeat + 1; 21771 continue; 21772 } 21773 21774 for (j = 0; j <= repeat; j++) { 21775 availabilityIdx++; 21776 21777 if (segments.length > maxSegmentsAhead) { 21778 hasEnoughSegments = true; 21779 if (isAvailableSegmentNumberCalculated) break; 21780 continue; 21781 } 21782 21783 if (requiredMediaTime !== null) { 21784 // In some cases when requiredMediaTime = actual end time of the last segment 21785 // it is possible that this time a bit exceeds the declared end time of the last segment. 21786 // in this case we still need to include the last segment in the segment list. to do this we 21787 // use a correction factor = 1.5. This number is used because the largest possible deviation is 21788 // is 50% of segment duration. 21789 if (scaledTime >= requiredMediaTime - frag.d / fTimescale * 1.5) { 21790 segments.push(createSegment(frag, availabilityIdx)); 21791 } 21792 } else if (availabilityIdx >= startIdx) { 21793 segments.push(createSegment(frag, availabilityIdx)); 21794 } 21795 21796 time += frag.d; 21797 scaledTime = time / fTimescale; 21798 } 21799 } 21800 21801 if (!isAvailableSegmentNumberCalculated) { 21802 representation.availableSegmentsNumber = availabilityIdx + 1; 21803 } 21804 21805 return segments; 21806 } 21807 21808 instance = { 21809 getSegments: getSegmentsFromTimeline 21810 }; 21811 21812 return instance; 21813} 21814 21815TimelineSegmentsGetter.__dashjs_factory_name = 'TimelineSegmentsGetter'; 21816var factory = _coreFactoryMaker2['default'].getClassFactory(TimelineSegmentsGetter); 21817exports['default'] = factory; 21818module.exports = exports['default']; 21819 21820},{"51":51,"77":77}],81:[function(_dereq_,module,exports){ 21821/** 21822 * The copyright in this software is being made available under the BSD License, 21823 * included below. This software may be subject to other third party and contributor 21824 * rights, including patent rights, and no such rights are granted under this license. 21825 * 21826 * Copyright (c) 2013, Dash Industry Forum. 21827 * All rights reserved. 21828 * 21829 * Redistribution and use in source and binary forms, with or without modification, 21830 * are permitted provided that the following conditions are met: 21831 * * Redistributions of source code must retain the above copyright notice, this 21832 * list of conditions and the following disclaimer. 21833 * * Redistributions in binary form must reproduce the above copyright notice, 21834 * this list of conditions and the following disclaimer in the documentation and/or 21835 * other materials provided with the distribution. 21836 * * Neither the name of Dash Industry Forum nor the names of its 21837 * contributors may be used to endorse or promote products derived from this software 21838 * without specific prior written permission. 21839 * 21840 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 21841 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21842 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21843 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21844 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
21844INCLUDING, BUT 21845 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21846 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21847 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21848 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 21849 * POSSIBILITY OF SUCH DAMAGE. 21850 */ 21851/** 21852 * @class 21853 * @ignore 21854 */ 21855"use strict"; 21856 21857Object.defineProperty(exports, "__esModule", { 21858 value: true 21859}); 21860 21861function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 21862 21863var AdaptationSet = function AdaptationSet() { 21864 _classCallCheck(this, AdaptationSet); 21865 21866 this.period = null; 21867 this.index = -1; 21868 this.type = null; 21869}; 21870 21871exports["default"] = AdaptationSet; 21872module.exports = exports["default"]; 21873 21874},{}],82:[function(_dereq_,module,exports){ 21875/** 21876 * The copyright in this software is being made available under the BSD License, 21877 * included below. This software may be subject to other third party and contributor 21878 * rights, including patent rights, and no such rights are granted under this license. 21879 * 21880 * Copyright (c) 2013, Dash Industry Forum. 21881 * All rights reserved. 21882 * 21883 * Redistribution and use in source and binary forms, with or without modification, 21884 * are permitted provided that the following conditions are met: 21885 * * Redistributions of source code must retain the above copyright notice, this 21886 * list of conditions and the following disclaimer. 21887 * * Redistributions in binary form must reproduce the above copyright notice, 21888 * this list of conditions and the following disclaimer in the documentation and/or 21889 * other materials provided with the distribution. 21890 * * Neither the name of Dash Industry Forum nor the names of its 21891 * contributors may be used to endorse or promote products derived from this software 21892 * without specific prior written permission. 21893 * 21894 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 21895 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21896 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21897 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21898 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21899 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21900 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21901 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21902 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 21903 * POSSIBILITY OF SUCH DAMAGE. 21904 */ 21905/** 21906 * @class 21907 * @ignore 21908 */ 21909 21910'use strict'; 21911 21912Object.defineProperty(exports, '__esModule', { 21913 value: true 21914}); 21915 21916function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 21917 21918var DEFAULT_DVB_PRIORITY = 1; 21919var DEFAULT_DVB_WEIGHT = 1; 21920 21921var BaseURL = function BaseURL(url, serviceLocation, priority, weight) { 21922 _classCallCheck(this, BaseURL); 21923 21924 this.url = url || ''; 21925 this.serviceLocation = serviceLocation || url || ''; 21926 21927 // DVB extensions 21928 this.dvb_priority = priority || DEFAULT_DVB_PRIORITY; 21929 this.dvb_weight = weight || DEFAULT_DVB_WEIGHT; 21930 21931 /* currently unused: 21932 * byteRange, 21933 * availabilityTimeOffset, 21934 * availabilityTimeComplete 21935 */ 21936}; 21937 21938BaseURL.DEFAULT_DVB_PRIORITY = DEFAULT_DVB_PRIORITY; 21939BaseURL.DEFAULT_DVB_WEIGHT = DEFAULT_DVB_WEIGHT; 21940 21941exports['default'] = BaseURL; 21942module.exports = exports['default']; 21943 21944},{}],83:[function(_dereq_,module,exports){ 21945/** 21946 * The copyright in this software is being made available under the BSD License, 21947 * included below. This software may be subject to other third party and contributor 21948 * rights, including patent rights, and no such rights are granted under this license. 21949 * 21950 * Copyright (c) 2013, Dash Industry Forum. 21951 * All rights reserved. 21952 * 21953 * Redistribution and use in source and binary forms, with or without modification, 21954 * are permitted provided that the following conditions are met: 21955 * * Redistributions of source code must retain the above copyright notice, this 21956 * list of conditions and the following disclaimer. 21957 * * Redistributions in binary form must reproduce the above copyright notice, 21958 * this list of conditions and the following disclaimer in the documentation and/or 21959 * other materials provided with the distribution. 21960 * * Neither the name of Dash Industry Forum nor the names of its 21961 * contributors may be used to endorse or promote products derived from this software 21962 * without specific prior written permission. 21963 * 21964 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 21965 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21966 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21967 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21968 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
21968INCLUDING, BUT 21969 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21970 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21971 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21972 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 21973 * POSSIBILITY OF SUCH DAMAGE. 21974 */ 21975/** 21976 * @class 21977 * @ignore 21978 */ 21979'use strict'; 21980 21981Object.defineProperty(exports, '__esModule', { 21982 value: true 21983}); 21984 21985function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 21986 21987var Event = function Event() { 21988 _classCallCheck(this, Event); 21989 21990 this.duration = NaN; 21991 this.presentationTime = NaN; 21992 this.id = NaN; 21993 this.messageData = ''; 21994 this.eventStream = null; 21995 this.presentationTimeDelta = NaN; // Specific EMSG Box parameter 21996}; 21997 21998exports['default'] = Event; 21999module.exports = exports['default']; 22000 22001},{}],84:[function(_dereq_,module,exports){ 22002/** 22003 * The copyright in this software is being made available under the BSD License, 22004 * included below. This software may be subject to other third party and contributor 22005 * rights, including patent rights, and no such rights are granted under this license. 22006 * 22007 * Copyright (c) 2013, Dash Industry Forum. 22008 * All rights reserved. 22009 * 22010 * Redistribution and use in source and binary forms, with or without modification, 22011 * are permitted provided that the following conditions are met: 22012 * * Redistributions of source code must retain the above copyright notice, this 22013 * list of conditions and the following disclaimer. 22014 * * Redistributions in binary form must reproduce the above copyright notice, 22015 * this list of conditions and the following disclaimer in the documentation and/or 22016 * other materials provided with the distribution. 22017 * * Neither the name of Dash Industry Forum nor the names of its 22018 * contributors may be used to endorse or promote products derived from this software 22019 * without specific prior written permission. 22020 * 22021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 22022 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22023 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22024 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22025 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22026 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22028 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22029 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22030 * POSSIBILITY OF SUCH DAMAGE. 22031 */ 22032/** 22033 * @class 22034 * @ignore 22035 */ 22036'use strict'; 22037 22038Object.defineProperty(exports, '__esModule', { 22039 value: true 22040}); 22041 22042function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 22043 22044var EventStream = function EventStream() { 22045 _classCallCheck(this, EventStream); 22046 22047 this.adaptionSet = null; 22048 this.representation = null; 22049 this.period = null; 22050 this.timescale = 1; 22051 this.value = ''; 22052 this.schemeIdUri = ''; 22053}; 22054 22055exports['default'] = EventStream; 22056module.exports = exports['default']; 22057 22058},{}],85:[function(_dereq_,module,exports){ 22059/** 22060 * The copyright in this software is being made available under the BSD License, 22061 * included below. This software may be subject to other third party and contributor 22062 * rights, including patent rights, and no such rights are granted under this license. 22063 * 22064 * Copyright (c) 2013, Dash Industry Forum. 22065 * All rights reserved. 22066 * 22067 * Redistribution and use in source and binary forms, with or without modification, 22068 * are permitted provided that the following conditions are met: 22069 * * Redistributions of source code must retain the above copyright notice, this 22070 * list of conditions and the following disclaimer. 22071 * * Redistributions in binary form must reproduce the above copyright notice, 22072 * this list of conditions and the following disclaimer in the documentation and/or 22073 * other materials provided with the distribution. 22074 * * Neither the name of Dash Industry Forum nor the names of its 22075 * contributors may be used to endorse or promote products derived from this software 22076 * without specific prior written permission. 22077 * 22078 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 22079 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22080 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22081 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22082 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
22082INCLUDING, BUT 22083 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22084 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22085 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22086 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22087 * POSSIBILITY OF SUCH DAMAGE. 22088 */ 22089/** 22090 * @class 22091 * @ignore 22092 */ 22093"use strict"; 22094 22095Object.defineProperty(exports, "__esModule", { 22096 value: true 22097}); 22098 22099function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22100 22101var Mpd = function Mpd() { 22102 _classCallCheck(this, Mpd); 22103 22104 this.manifest = null; 22105 this.suggestedPresentationDelay = 0; 22106 this.availabilityStartTime = null; 22107 this.availabilityEndTime = Number.POSITIVE_INFINITY; 22108 this.timeShiftBufferDepth = Number.POSITIVE_INFINITY; 22109 this.maxSegmentDuration = Number.POSITIVE_INFINITY; 22110 this.minimumUpdatePeriod = NaN; 22111 this.mediaPresentationDuration = NaN; 22112}; 22113 22114exports["default"] = Mpd; 22115module.exports = exports["default"]; 22116 22117},{}],86:[function(_dereq_,module,exports){ 22118/** 22119 * The copyright in this software is being made available under the BSD License, 22120 * included below. This software may be subject to other third party and contributor 22121 * rights, including patent rights, and no such rights are granted under this license. 22122 * 22123 * Copyright (c) 2013, Dash Industry Forum. 22124 * All rights reserved. 22125 * 22126 * Redistribution and use in source and binary forms, with or without modification, 22127 * are permitted provided that the following conditions are met: 22128 * * Redistributions of source code must retain the above copyright notice, this 22129 * list of conditions and the following disclaimer. 22130 * * Redistributions in binary form must reproduce the above copyright notice, 22131 * this list of conditions and the following disclaimer in the documentation and/or 22132 * other materials provided with the distribution. 22133 * * Neither the name of Dash Industry Forum nor the names of its 22134 * contributors may be used to endorse or promote products derived from this software 22135 * without specific prior written permission. 22136 * 22137 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 22138 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22139 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22140 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22141 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22142 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22143 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22144 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22145 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22146 * POSSIBILITY OF SUCH DAMAGE. 22147 */ 22148/** 22149 * @class 22150 * @ignore 22151 */ 22152'use strict'; 22153 22154Object.defineProperty(exports, '__esModule', { 22155 value: true 22156}); 22157 22158function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 22159 22160var Period = function Period() { 22161 _classCallCheck(this, Period); 22162 22163 this.id = null; 22164 this.index = -1; 22165 this.duration = NaN; 22166 this.start = NaN; 22167 this.mpd = null; 22168}; 22169 22170Period.DEFAULT_ID = 'defaultId'; 22171 22172exports['default'] = Period; 22173module.exports = exports['default']; 22174 22175},{}],87:[function(_dereq_,module,exports){ 22176/** 22177 * The copyright in this software is being made available under the BSD License, 22178 * included below. This software may be subject to other third party and contributor 22179 * rights, including patent rights, and no such rights are granted under this license. 22180 * 22181 * Copyright (c) 2013, Dash Industry Forum. 22182 * All rights reserved. 22183 * 22184 * Redistribution and use in source and binary forms, with or without modification, 22185 * are permitted provided that the following conditions are met: 22186 * * Redistributions of source code must retain the above copyright notice, this 22187 * list of conditions and the following disclaimer. 22188 * * Redistributions in binary form must reproduce the above copyright notice, 22189 * this list of conditions and the following disclaimer in the documentation and/or 22190 * other materials provided with the distribution. 22191 * * Neither the name of Dash Industry Forum nor the names of its 22192 * contributors may be used to endorse or promote products derived from this software 22193 * without specific prior written permission. 22194 * 22195 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 22196 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22197 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22198 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22199 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
22199INCLUDING, BUT 22200 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22201 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22202 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22203 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22204 * POSSIBILITY OF SUCH DAMAGE. 22205 */ 22206/** 22207 * @class 22208 * @ignore 22209 */ 22210 22211'use strict'; 22212 22213Object.defineProperty(exports, '__esModule', { 22214 value: true 22215}); 22216 22217var _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; }; })(); 22218 22219function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 22220 22221function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 22222 22223var _constantsDashConstants = _dereq_(61); 22224 22225var _constantsDashConstants2 = _interopRequireDefault(_constantsDashConstants); 22226 22227var Representation = (function () { 22228 function Representation() { 22229 _classCallCheck(this, Representation); 22230 22231 this.id = null; 22232 this.index = -1; 22233 this.adaptation = null; 22234 this.segmentInfoType = null; 22235 this.initialization = null; 22236 this.codecs = null; 22237 this.codecPrivateData = null; 22238 this.segmentDuration = NaN; 22239 this.timescale = 1; 22240 this.startNumber = 1; 22241 this.indexRange = null; 22242 this.range = null; 22243 this.presentationTimeOffset = 0; 22244 // Set the source buffer timeOffset to this 22245 this.MSETimeOffset = NaN; 22246 this.segmentAvailabilityRange = null; 22247 this.availableSegmentsNumber = 0; 22248 this.bandwidth = NaN; 22249 this.width = NaN; 22250 this.height = NaN; 22251 this.scanType = null; 22252 this.maxPlayoutRate = NaN; 22253 } 22254 22255 _createClass(Representation, null, [{ 22256 key: 'hasInitialization', 22257 value: function hasInitialization(r) { 22258 return r.initialization !== null || (r.segmentInfoType !== _constantsDashConstants2['default'].BASE_URL || r.segmentInfoType !== _constantsDashConstants2['default'].SEGMENT_BASE) && r.range !== null; 22259 } 22260 }, { 22261 key: 'hasSegments', 22262 value: function hasSegments(r) { 22263 return r.segmentInfoType !== _constantsDashConstants2['default'].BASE_URL && r.segmentInfoType !== _constantsDashConstants2['default'].SEGMENT_BASE && !r.indexRange; 22264 } 22265 }]); 22266 22267 return Representation; 22268})(); 22269 22270exports['default'] = Representation; 22271module.exports = exports['default']; 22272 22273},{"61":61}],88:[function(_dereq_,module,exports){ 22274/** 22275 * The copyright in this software is being made available under the BSD License, 22276 * included below. This software may be subject to other third party and contributor 22277 * rights, including patent rights, and no such rights are granted under this license. 22278 * 22279 * Copyright (c) 2013, Dash Industry Forum. 22280 * All rights reserved. 22281 * 22282 * Redistribution and use in source and binary forms, with or without modification, 22283 * are permitted provided that the following conditions are met: 22284 * * Redistributions of source code must retain the above copyright notice, this 22285 * list of conditions and the following disclaimer. 22286 * * Redistributions in binary form must reproduce the above copyright notice, 22287 * this list of conditions and the following disclaimer in the documentation and/or 22288 * other materials provided with the distribution. 22289 * * Neither the name of Dash Industry Forum nor the names of its 22290 * contributors may be used to endorse or promote products derived from this software 22291 * without specific prior written permission. 22292 * 22293 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 22294 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22295 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22296 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22297 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
22297INCLUDING, BUT 22298 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22299 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22300 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22301 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22302 * POSSIBILITY OF SUCH DAMAGE. 22303 */ 22304/** 22305 * @class 22306 * @ignore 22307 */ 22308"use strict"; 22309 22310Object.defineProperty(exports, "__esModule", { 22311 value: true 22312}); 22313 22314function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22315 22316var Segment = function Segment() { 22317 _classCallCheck(this, Segment); 22318 22319 this.indexRange = null; 22320 this.index = null; 22321 this.mediaRange = null; 22322 this.media = null; 22323 this.duration = NaN; 22324 // this is the time that should be inserted into the media url 22325 this.replacementTime = null; 22326 // this is the number that should be inserted into the media url 22327 this.replacementNumber = NaN; 22328 // This is supposed to match the time encoded in the media Segment 22329 this.mediaStartTime = NaN; 22330 // When the source buffer timeOffset is set to MSETimeOffset this is the 22331 // time that will match the seekTarget and video.currentTime 22332 this.presentationStartTime = NaN; 22333 // Do not schedule this segment until 22334 this.availabilityStartTime = NaN; 22335 // Ignore and discard this segment after 22336 this.availabilityEndTime = NaN; 22337 // The index of the segment inside the availability window 22338 this.availabilityIdx = NaN; 22339 // For dynamic mpd's, this is the wall clock time that the video 22340 // element currentTime should be presentationStartTime 22341 this.wallStartTime = NaN; 22342 this.representation = null; 22343}; 22344 22345exports["default"] = Segment; 22346module.exports = exports["default"]; 22347 22348},{}],89:[function(_dereq_,module,exports){ 22349/** 22350 * The copyright in this software is being made available under the BSD License, 22351 * included below. This software may be subject to other third party and contributor 22352 * rights, including patent rights, and no such rights are granted under this license. 22353 * 22354 * Copyright (c) 2013, Dash Industry Forum. 22355 * All rights reserved. 22356 * 22357 * Redistribution and use in source and binary forms, with or without modification, 22358 * are permitted provided that the following conditions are met: 22359 * * Redistributions of source code must retain the above copyright notice, this 22360 * list of conditions and the following disclaimer. 22361 * * Redistributions in binary form must reproduce the above copyright notice, 22362 * this list of conditions and the following disclaimer in the documentation and/or 22363 * other materials provided with the distribution. 22364 * * Neither the name of Dash Industry Forum nor the names of its 22365 * contributors may be used to endorse or promote products derived from this software 22366 * without specific prior written permission. 22367 * 22368 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 22369 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22370 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22371 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22372 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22373 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22374 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22375 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22376 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22377 * POSSIBILITY OF SUCH DAMAGE. 22378 */ 22379/** 22380 * @class 22381 * @ignore 22382 */ 22383'use strict'; 22384 22385Object.defineProperty(exports, '__esModule', { 22386 value: true 22387}); 22388 22389function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 22390 22391var UTCTiming = function UTCTiming() { 22392 _classCallCheck(this, UTCTiming); 22393 22394 // UTCTiming is a DescriptorType and doesn't have any additional fields 22395 this.schemeIdUri = ''; 22396 this.value = ''; 22397}; 22398 22399exports['default'] = UTCTiming; 22400module.exports = exports['default']; 22401 22402},{}],90:[function(_dereq_,module,exports){ 22403/** 22404 * The copyright in this software is being made available under the BSD License, 22405 * included below. This software may be subject to other third party and contributor 22406 * rights, including patent rights, and no such rights are granted under this license. 22407 * 22408 * Copyright (c) 2013, Dash Industry Forum. 22409 * All rights reserved. 22410 * 22411 * Redistribution and use in source and binary forms, with or without modification, 22412 * are permitted provided that the following conditions are met: 22413 * * Redistributions of source code must retain the above copyright notice, this 22414 * list of conditions and the following disclaimer. 22415 * * Redistributions in binary form must reproduce the above copyright notice, 22416 * this list of conditions and the following disclaimer in the documentation and/or 22417 * other materials provided with the distribution. 22418 * * Neither the name of Dash Industry Forum nor the names of its 22419 * contributors may be used to endorse or promote products derived from this software 22420 * without specific prior written permission. 22421 * 22422 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 22423 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22424 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22425 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22426 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
22426INCLUDING, BUT 22427 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22428 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22429 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22430 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22431 * POSSIBILITY OF SUCH DAMAGE. 22432 */ 22433'use strict'; 22434 22435Object.defineProperty(exports, '__esModule', { 22436 value: true 22437}); 22438 22439function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 22440 22441var _XHRLoader = _dereq_(98); 22442 22443var _XHRLoader2 = _interopRequireDefault(_XHRLoader); 22444 22445var _voHeadRequest = _dereq_(210); 22446 22447var _voHeadRequest2 = _interopRequireDefault(_voHeadRequest); 22448 22449var _voDashJSError = _dereq_(207); 22450 22451var _voDashJSError2 = _interopRequireDefault(_voDashJSError); 22452 22453var _coreEventBus = _dereq_(50); 22454 22455var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 22456 22457var _coreEventsEvents = _dereq_(54); 22458 22459var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 22460 22461var _coreFactoryMaker = _dereq_(51); 22462 22463var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 22464 22465var FRAGMENT_LOADER_ERROR_LOADING_FAILURE = 1; 22466var FRAGMENT_LOADER_ERROR_NULL_REQUEST = 2; 22467var FRAGMENT_LOADER_MESSAGE_NULL_REQUEST = 'request is null'; 22468 22469function FragmentLoader(config) { 22470 22471 var context = this.context; 22472 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 22473 22474 var instance = undefined, 22475 xhrLoader = undefined; 22476 22477 function setup() { 22478 xhrLoader = (0, _XHRLoader2['default'])(context).create({ 22479 errHandler: config.errHandler, 22480 metricsModel: config.metricsModel, 22481 mediaPlayerModel: config.mediaPlayerModel, 22482 requestModifier: config.requestModifier 22483 }); 22484 } 22485 22486 function checkForExistence(request) { 22487 var report = function report(success) { 22488 eventBus.trigger(_coreEventsEvents2['default'].CHECK_FOR_EXISTENCE_COMPLETED, { 22489 request: request, 22490 exists: success 22491 }); 22492 }; 22493 22494 if (request) { 22495 var headRequest = new _voHeadRequest2['default'](request.url); 22496 22497 xhrLoader.load({ 22498 request: headRequest, 22499 success: function success() { 22500 report(true); 22501 }, 22502 error: function error() { 22503 report(false); 22504 } 22505 }); 22506 } else { 22507 report(false); 22508 } 22509 } 22510 22511 function load(request) { 22512 var report = function report(data, error) { 22513 eventBus.trigger(_coreEventsEvents2['default'].LOADING_COMPLETED, { 22514 request: request, 22515 response: data || null, 22516 error: error || null, 22517 sender: instance 22518 }); 22519 }; 22520 22521 if (request) { 22522 xhrLoader.load({ 22523 request: request, 22524 progress: function progress() { 22525 eventBus.trigger(_coreEventsEvents2['default'].LOADING_PROGRESS, { 22526 request: request 22527 }); 22528 }, 22529 success: function success(data) { 22530 report(data); 22531 }, 22532 error: function error(xhr, statusText, errorText) { 22533 report(undefined, new _voDashJSError2['default'](FRAGMENT_LOADER_ERROR_LOADING_FAILURE, errorText, statusText)); 22534 }, 22535 abort: function abort(request, status) { 22536 if (request && status === 0) { 22537 eventBus.trigger(_coreEventsEvents2['default'].LOADING_ABANDONED, { request: request, mediaType: request.mediaType, sender: instance }); 22538 } 22539 } 22540 }); 22541 } else { 22542 report(undefined, new _voDashJSError2['default'](FRAGMENT_LOADER_ERROR_NULL_REQUEST, FRAGMENT_LOADER_MESSAGE_NULL_REQUEST)); 22543 } 22544 } 22545 22546 function abort() { 22547 if (xhrLoader) { 22548 xhrLoader.abort(); 22549 } 22550 } 22551 22552 function reset() { 22553 if (xhrLoader) { 22554 xhrLoader.abort(); 22555 xhrLoader = null; 22556 } 22557 } 22558 22559 instance = { 22560 checkForExistence: checkForExistence, 22561 load: load, 22562 abort: abort, 22563 reset: reset 22564 }; 22565 22566 setup(); 22567 22568 return instance; 22569} 22570 22571FragmentLoader.__dashjs_factory_name = 'FragmentLoader'; 22572 22573var factory = _coreFactoryMaker2['default'].getClassFactory(FragmentLoader); 22574factory.FRAGMENT_LOADER_ERROR_LOADING_FAILURE = FRAGMENT_LOADER_ERROR_LOADING_FAILURE; 22575factory.FRAGMENT_LOADER_ERROR_NULL_REQUEST = FRAGMENT_LOADER_ERROR_NULL_REQUEST; 22576_coreFactoryMaker2['default'].updateClassFactory(FragmentLoader.__dashjs_factory_name, factory); 22577exports['default'] = factory; 22578module.exports = exports['default']; 22579 22580},{"207":207,"210":210,"50":50,"51":51,"54":54,"98":98}],91:[function(_dereq_,module,exports){ 22581/** 22582 * The copyright in this software is being made available under the BSD License, 22583 * included below. This software may be subject to other third party and contributor 22584 * rights, including patent rights, and no such rights are granted under this license. 22585 * 22586 * Copyright (c) 2013, Dash Industry Forum. 22587 * All rights reserved. 22588 * 22589 * Redistribution and use in source and binary forms, with or without modification, 22590 * are permitted provided that the following conditions are met: 22591 * * Redistributions of source code must retain the above copyright notice, this 22592 * list of conditions and the following disclaimer. 22593 * * Redistributions in binary form must reproduce the above copyright notice, 22594 * this list of conditions and the following disclaimer in the documentation and/or 22595 * other materials provided with the distribution. 22596 * * Neither the name of Dash Industry Forum nor the names of its 22597 * contributors may be used to endorse or promote products derived from this software 22598 * without specific prior written permission. 22599 * 22600 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 22601 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22602 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22603 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22604 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
22604INCLUDING, BUT 22605 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22606 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22607 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22608 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22609 * POSSIBILITY OF SUCH DAMAGE. 22610 */ 22611'use strict'; 22612 22613Object.defineProperty(exports, '__esModule', { 22614 value: true 22615}); 22616 22617function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 22618 22619var _constantsConstants = _dereq_(100); 22620 22621var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 22622 22623var _controllersXlinkController = _dereq_(115); 22624 22625var _controllersXlinkController2 = _interopRequireDefault(_controllersXlinkController); 22626 22627var _XHRLoader = _dereq_(98); 22628 22629var _XHRLoader2 = _interopRequireDefault(_XHRLoader); 22630 22631var _utilsURLUtils = _dereq_(202); 22632 22633var _utilsURLUtils2 = _interopRequireDefault(_utilsURLUtils); 22634 22635var _voTextRequest = _dereq_(217); 22636 22637var _voTextRequest2 = _interopRequireDefault(_voTextRequest); 22638 22639var _voDashJSError = _dereq_(207); 22640 22641var _voDashJSError2 = _interopRequireDefault(_voDashJSError); 22642 22643var _voMetricsHTTPRequest = _dereq_(224); 22644 22645var _coreEventBus = _dereq_(50); 22646 22647var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 22648 22649var _coreEventsEvents = _dereq_(54); 22650 22651var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 22652 22653var _coreFactoryMaker = _dereq_(51); 22654 22655var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 22656 22657var _dashParserDashParser = _dereq_(64); 22658 22659var _dashParserDashParser2 = _interopRequireDefault(_dashParserDashParser); 22660 22661var _coreDebug = _dereq_(49); 22662 22663var _coreDebug2 = _interopRequireDefault(_coreDebug); 22664 22665var MANIFEST_LOADER_ERROR_PARSING_FAILURE = 1; 22666var MANIFEST_LOADER_ERROR_LOADING_FAILURE = 2; 22667var MANIFEST_LOADER_MESSAGE_PARSING_FAILURE = 'parsing failed'; 22668 22669function ManifestLoader(config) { 22670 22671 var context = this.context; 22672 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 22673 var urlUtils = (0, _utilsURLUtils2['default'])(context).getInstance(); 22674 var debug = (0, _coreDebug2['default'])(context).getInstance(); 22675 var log = debug.log; 22676 22677 var instance = undefined, 22678 xhrLoader = undefined, 22679 xlinkController = undefined, 22680 parser = undefined; 22681 var mssHandler = config.mssHandler; 22682 var errHandler = config.errHandler; 22683 22684 function setup() { 22685 eventBus.on(_coreEventsEvents2['default'].XLINK_READY, onXlinkReady, instance); 22686 22687 xhrLoader = (0, _XHRLoader2['default'])(context).create({ 22688 errHandler: errHandler, 22689 metricsModel: config.metricsModel, 22690 mediaPlayerModel: config.mediaPlayerModel, 22691 requestModifier: config.requestModifier 22692 }); 22693 22694 xlinkController = (0, _controllersXlinkController2['default'])(context).create({ 22695 errHandler: errHandler, 22696 metricsModel: config.metricsModel, 22697 mediaPlayerModel: config.mediaPlayerModel, 22698 requestModifier: config.requestModifier 22699 }); 22700 22701 parser = null; 22702 } 22703 22704 function onXlinkReady(event) { 22705 eventBus.trigger(_coreEventsEvents2['default'].INTERNAL_MANIFEST_LOADED, { 22706 manifest: event.manifest 22707 }); 22708 } 22709 22710 function createParser(data) { 22711 var parser = null; 22712 // Analyze manifest content to detect protocol and select appropriate parser 22713 if (data.indexOf('SmoothStreamingMedia') > -1) { 22714 //do some business to transform it into a Dash Manifest 22715 if (mssHandler) { 22716 parser = mssHandler.createMssParser(); 22717 mssHandler.registerEvents(); 22718 } else { 22719 errHandler.manifestError('manifest type unsupported', 'createParser'); 22720 } 22721 return parser; 22722 } else if (data.indexOf('MPD') > -1) { 22723 return (0, _dashParserDashParser2['default'])(context).create({ 22724 errorHandler: errHandler 22725 }); 22726 } else { 22727 return parser; 22728 } 22729 } 22730 22731 function load(url) { 22732 var request = new _voTextRequest2['default'](url, _voMetricsHTTPRequest.HTTPRequest.MPD_TYPE); 22733 22734 xhrLoader.load({ 22735 request: request, 22736 success: function success(data, textStatus, xhr) { 22737 var actualUrl = undefined, 22738 baseUri = undefined; 22739 22740 // Handle redirects for the MPD - as per RFC3986 Section 5.1.3 22741 // also handily resolves relative MPD URLs to absolute 22742 if (xhr.responseURL && xhr.responseURL !== url) { 22743 baseUri = urlUtils.parseBaseUrl(xhr.responseURL); 22744 actualUrl = xhr.responseURL; 22745 } else { 22746 // usually this case will be caught and resolved by 22747 // xhr.responseURL above but it is not available for IE11 and Edge/12 and Edge/13 22748 // baseUri must be absolute for BaseURL resolution later 22749 if (urlUtils.isRelative(url)) { 22750 url = urlUtils.resolve(url, window.location.href); 22751 } 22752 22753 baseUri = urlUtils.parseBaseUrl(url); 22754 } 22755 22756 // Create parser according to manifest type 22757 if (parser === null) { 22758 parser = createParser(data); 22759 } 22760 22761 if (parser === null) { 22762 eventBus.trigger(_coreEventsEvents2['default'].INT
22762ERNAL_MANIFEST_LOADED, { 22763 manifest: null, 22764 error: new _voDashJSError2['default'](MANIFEST_LOADER_ERROR_PARSING_FAILURE, 'Failed detecting manifest type: ' + url) 22765 }); 22766 return; 22767 } 22768 22769 // init xlinkcontroller with matchers and iron object from created parser 22770 xlinkController.setMatchers(parser.getMatchers()); 22771 xlinkController.setIron(parser.getIron()); 22772 22773 var manifest = parser.parse(data); 22774 22775 if (manifest) { 22776 manifest.url = actualUrl || url; 22777 22778 // URL from which the MPD was originally retrieved (MPD updates will not change this value) 22779 if (!manifest.originalUrl) { 22780 manifest.originalUrl = manifest.url; 22781 } 22782 22783 // In the following, we only use the first Location entry even if many are available 22784 // Compare with ManifestUpdater/DashManifestModel 22785 if (manifest.hasOwnProperty(_constantsConstants2['default'].LOCATION)) { 22786 baseUri = urlUtils.parseBaseUrl(manifest.Location_asArray[0]); 22787 log('BaseURI set by Location to: ' + baseUri); 22788 } 22789 22790 manifest.baseUri = baseUri; 22791 manifest.loadedTime = new Date(); 22792 xlinkController.resolveManifestOnLoad(manifest); 22793 } else { 22794 eventBus.trigger(_coreEventsEvents2['default'].INTERNAL_MANIFEST_LOADED, { 22795 manifest: null, 22796 error: new _voDashJSError2['default'](MANIFEST_LOADER_ERROR_PARSING_FAILURE, MANIFEST_LOADER_MESSAGE_PARSING_FAILURE) 22797 }); 22798 } 22799 }, 22800 error: function error(xhr, statusText, errorText) { 22801 eventBus.trigger(_coreEventsEvents2['default'].INTERNAL_MANIFEST_LOADED, { 22802 manifest: null, 22803 error: new _voDashJSError2['default'](MANIFEST_LOADER_ERROR_LOADING_FAILURE, 'Failed loading manifest: ' + url + ', ' + errorText) 22804 }); 22805 } 22806 }); 22807 } 22808 22809 function reset() { 22810 eventBus.off(_coreEventsEvents2['default'].XLINK_READY, onXlinkReady, instance); 22811 22812 if (xlinkController) { 22813 xlinkController.reset(); 22814 xlinkController = null; 22815 } 22816 22817 if (xhrLoader) { 22818 xhrLoader.abort(); 22819 xhrLoader = null; 22820 } 22821 22822 if (mssHandler) { 22823 mssHandler.reset(); 22824 } 22825 } 22826 22827 instance = { 22828 load: load, 22829 reset: reset 22830 }; 22831 22832 setup(); 22833 22834 return instance; 22835} 22836 22837ManifestLoader.__dashjs_factory_name = 'ManifestLoader'; 22838 22839var factory = _coreFactoryMaker2['default'].getClassFactory(ManifestLoader); 22840factory.MANIFEST_LOADER_ERROR_PARSING_FAILURE = MANIFEST_LOADER_ERROR_PARSING_FAILURE; 22841factory.MANIFEST_LOADER_ERROR_LOADING_FAILURE = MANIFEST_LOADER_ERROR_LOADING_FAILURE; 22842_coreFactoryMaker2['default'].updateClassFactory(ManifestLoader.__dashjs_factory_name, factory); 22843exports['default'] = factory; 22844module.exports = exports['default']; 22845 22846},{"100":100,"115":115,"202":202,"207":207,"217":217,"224":224,"49":49,"50":50,"51":51,"54":54,"64":64,"98":98}],92:[function(_dereq_,module,exports){ 22847/** 22848 * The copyright in this software is being made available under the BSD License, 22849 * included below. This software may be subject to other third party and contributor 22850 * rights, including patent rights, and no such rights are granted under this license. 22851 * 22852 * Copyright (c) 2013, Dash Industry Forum. 22853 * All rights reserved. 22854 * 22855 * Redistribution and use in source and binary forms, with or without modification, 22856 * are permitted provided that the following conditions are met: 22857 * * Redistributions of source code must retain the above copyright notice, this 22858 * list of conditions and the following disclaimer. 22859 * * Redistributions in binary form must reproduce the above copyright notice, 22860 * this list of conditions and the following disclaimer in the documentation and/or 22861 * other materials provided with the distribution. 22862 * * Neither the name of Dash Industry Forum nor the names of its 22863 * contributors may be used to endorse or promote products derived from this software 22864 * without specific prior written permission. 22865 * 22866 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 22867 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22868 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22869 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22870 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
22870INCLUDING, BUT 22871 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22872 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22873 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22874 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22875 * POSSIBILITY OF SUCH DAMAGE. 22876 */ 22877'use strict'; 22878 22879Object.defineProperty(exports, '__esModule', { 22880 value: true 22881}); 22882 22883function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 22884 22885var _coreEventBus = _dereq_(50); 22886 22887var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 22888 22889var _coreEventsEvents = _dereq_(54); 22890 22891var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 22892 22893var _coreFactoryMaker = _dereq_(51); 22894 22895var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 22896 22897var _coreDebug = _dereq_(49); 22898 22899var _coreDebug2 = _interopRequireDefault(_coreDebug); 22900 22901function ManifestUpdater() { 22902 22903 var context = this.context; 22904 var log = (0, _coreDebug2['default'])(context).getInstance().log; 22905 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 22906 22907 var instance = undefined, 22908 refreshDelay = undefined, 22909 refreshTimer = undefined, 22910 isPaused = undefined, 22911 isUpdating = undefined, 22912 manifestLoader = undefined, 22913 manifestModel = undefined, 22914 dashManifestModel = undefined, 22915 mediaPlayerModel = undefined; 22916 22917 function setConfig(config) { 22918 if (!config) return; 22919 22920 if (config.manifestModel) { 22921 manifestModel = config.manifestModel; 22922 } 22923 if (config.dashManifestModel) { 22924 dashManifestModel = config.dashManifestModel; 22925 } 22926 if (config.mediaPlayerModel) { 22927 mediaPlayerModel = config.mediaPlayerModel; 22928 } 22929 if (config.manifestLoader) { 22930 manifestLoader = config.manifestLoader; 22931 } 22932 } 22933 22934 function initialize() { 22935 resetInitialSettings(); 22936 22937 eventBus.on(_coreEventsEvents2['default'].STREAMS_COMPOSED, onStreamsComposed, this); 22938 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_STARTED, onPlaybackStarted, this); 22939 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_PAUSED, onPlaybackPaused, this); 22940 eventBus.on(_coreEventsEvents2['default'].INTERNAL_MANIFEST_LOADED, onManifestLoaded, this); 22941 } 22942 22943 function setManifest(manifest) { 22944 update(manifest); 22945 } 22946 22947 function resetInitialSettings() { 22948 refreshDelay = NaN; 22949 isUpdating = false; 22950 isPaused = true; 22951 stopManifestRefreshTimer(); 22952 } 22953 22954 function reset() { 22955 22956 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_STARTED, onPlaybackStarted, this); 22957 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_PAUSED, onPlaybackPaused, this); 22958 eventBus.off(_coreEventsEvents2['default'].STREAMS_COMPOSED, onStreamsComposed, this); 22959 eventBus.off(_coreEventsEvents2['default'].INTERNAL_MANIFEST_LOADED, onManifestLoaded, this); 22960 22961 resetInitialSettings(); 22962 } 22963 22964 function stopManifestRefreshTimer() { 22965 if (refreshTimer !== null) { 22966 clearInterval(refreshTimer); 22967 refreshTimer = null; 22968 } 22969 } 22970 22971 function startManifestRefreshTimer() { 22972 stopManifestRefreshTimer(); 22973 if (!isNaN(refreshDelay)) { 22974 log('Refresh manifest in ' + refreshDelay + ' seconds.'); 22975 refreshTimer = setTimeout(onRefreshTimer, refreshDelay * 1000); 22976 } 22977 } 22978 22979 function refreshManifest() { 22980 isUpdating = true; 22981 var manifest = manifestModel.getValue(); 22982 var url = manifest.url; 22983 var location = dashManifestModel.getLocation(manifest); 22984 if (location) { 22985 url = location; 22986 } 22987 manifestLoader.load(url); 22988 } 22989 22990 function update(manifest) { 22991 22992 manifestModel.setValue(manifest); 22993 22994 var date = new Date(); 22995 var latencyOfLastUpdate = (date.getTime() - manifest.loadedTime.getTime()) / 1000; 22996 refreshDelay = dashManifestModel.getManifestUpdatePeriod(manifest, latencyOfLastUpdate); 22997 22998 eventBus.trigger(_coreEventsEvents2['default'].MANIFEST_UPDATED, { manifest: manifest }); 22999 log('Manifest has been refreshed at ' + date + '[' + date.getTime() / 1000 + '] '); 23000 23001 if (!isPaused) { 23002 startManifestRefreshTimer(); 23003 } 23004 } 23005 23006 function onRefreshTimer() { 23007 if (isPaused && !mediaPlayerModel.getScheduleWhilePaused() || isUpdating) return; 23008 refreshManifest(); 23009 } 23010 23011 function onManifestLoaded(e) { 23012 if (!e.error) { 23013 update(e.manifest); 23014 } 23015 } 23016 23017 function onPlaybackStarted() /*e*/{ 23018 isPaused = false; 23019 startManifestRefreshTimer(); 23020 } 23021 23022 function onPlaybackPaused() /*e*/{ 23023 isPaused = true; 23024 stopManifestRefreshTimer(); 23025 } 23026 23027 function onStreamsComposed() /*e*/{ 23028 // When streams are ready we can consider manifest update completed. Resolve the update promise. 23029 isUpdating = false; 23030 } 23031 23032 instance = { 23033 initialize: initialize, 23034 setManifest: setManifest, 23035 refreshManifest: refreshManifest, 23036 setConfig: setConfig, 23037 reset: reset 23038 }; 23039 23040 return instance; 23041} 23042ManifestUpdater.__dashjs_factory_name = 'ManifestUpdater'; 23043exports['default'] = _coreFactoryMaker2['default'].getClassFactory(ManifestUpdater); 23044module.exports = exports['default']; 23045 23046},{"49":49,"50":50,"51":51,"54":54}],93:[function(_dereq_,module,exports){ 23047/** 23048 * The copyright in this software is being made available under the BSD License, 23049 * included below. This software may be subject to other third party and contributor 23050 * rights, including patent rights, and no such rights are granted under this license. 23051 * 23052 * Copyright (c) 2013, Dash Industry Forum. 23053 * All rights reserved. 23054 * 23055 * Redistribution and use in source and binary forms, with or without modification, 23056 * are permitted provided that the following conditions are met: 23057 * * Redistributions of source code must retain the above copyright notice, this 23058 * list of conditions and the following disclaimer. 23059 * * Redistributions in binary form must reproduce the above copyright notice, 23060 * this list of conditions and the following disclaimer in the documentation and/or 23061 * other materials provided with the distribution. 23062 * * Neither the name of Dash Industry Forum nor the names of its 23063 * contributors may be used to endorse or promote products derived from this software 23064 * without specific prior written permission. 23065 * 23066 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 23067 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23068 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23069 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23070 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
23070INCLUDING, BUT 23071 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23072 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23073 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23074 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 23075 * POSSIBILITY OF SUCH DAMAGE. 23076 */ 23077'use strict'; 23078 23079Object.defineProperty(exports, '__esModule', { 23080 value: true 23081}); 23082 23083function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 23084 23085var _constantsConstants = _dereq_(100); 23086 23087var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 23088 23089var _constantsMetricsConstants = _dereq_(101); 23090 23091var _constantsMetricsConstants2 = _interopRequireDefault(_constantsMetricsConstants); 23092 23093var _dashVoUTCTiming = _dereq_(89); 23094 23095var _dashVoUTCTiming2 = _interopRequireDefault(_dashVoUTCTiming); 23096 23097var _controllersPlaybackController = _dereq_(110); 23098 23099var _controllersPlaybackController2 = _interopRequireDefault(_controllersPlaybackController); 23100 23101var _controllersStreamController = _dereq_(113); 23102 23103var _controllersStreamController2 = _interopRequireDefault(_controllersStreamController); 23104 23105var _controllersMediaController = _dereq_(108); 23106 23107var _controllersMediaController2 = _interopRequireDefault(_controllersMediaController); 23108 23109var _ManifestLoader = _dereq_(91); 23110 23111var _ManifestLoader2 = _interopRequireDefault(_ManifestLoader); 23112 23113var _utilsErrorHandler = _dereq_(195); 23114 23115var _utilsErrorHandler2 = _interopRequireDefault(_utilsErrorHandler); 23116 23117var _utilsCapabilities = _dereq_(191); 23118 23119var _utilsCapabilities2 = _interopRequireDefault(_utilsCapabilities); 23120 23121var _textTextTracks = _dereq_(188); 23122 23123var _textTextTracks2 = _interopRequireDefault(_textTextTracks); 23124 23125var _utilsRequestModifier = _dereq_(200); 23126 23127var _utilsRequestModifier2 = _interopRequireDefault(_utilsRequestModifier); 23128 23129var _textTextController = _dereq_(186); 23130 23131var _textTextController2 = _interopRequireDefault(_textTextController); 23132 23133var _modelsURIQueryAndFragmentModel = _dereq_(144); 23134 23135var _modelsURIQueryAndFragmentModel2 = _interopRequireDefault(_modelsURIQueryAndFragmentModel); 23136 23137var _modelsManifestModel = _dereq_(141); 23138 23139var _modelsManifestModel2 = _interopRequireDefault(_modelsManifestModel); 23140 23141var _modelsMediaPlayerModel = _dereq_(142); 23142 23143var _modelsMediaPlayerModel2 = _interopRequireDefault(_modelsMediaPlayerModel); 23144 23145var _modelsMetricsModel = _dereq_(143); 23146 23147var _modelsMetricsModel2 = _interopRequireDefault(_modelsMetricsModel); 23148 23149var _controllersAbrController = _dereq_(102); 23150 23151var _controllersAbrController2 = _interopRequireDefault(_controllersAbrController); 23152 23153var _controllersSourceBufferController = _dereq_(112); 23154 23155var _controllersSourceBufferController2 = _interopRequireDefault(_controllersSourceBufferController); 23156 23157var _modelsVideoModel = _dereq_(145); 23158 23159var _modelsVideoModel2 = _interopRequireDefault(_modelsVideoModel); 23160 23161var _utilsDOMStorage = _dereq_(193); 23162 23163var _utilsDOMStorage2 = _interopRequireDefault(_utilsDOMStorage); 23164 23165var _coreDebug = _dereq_(49); 23166 23167var _coreDebug2 = _interopRequireDefault(_coreDebug); 23168 23169var _coreEventBus = _dereq_(50); 23170 23171var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 23172 23173var _coreEventsEvents = _dereq_(54); 23174 23175var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 23176 23177var _MediaPlayerEvents = _dereq_(94); 23178 23179var _MediaPlayerEvents2 = _interopRequireDefault(_MediaPlayerEvents); 23180 23181var _coreFactoryMaker = _dereq_(51); 23182 23183var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 23184 23185var _coreVersion = _dereq_(52); 23186 23187//Dash 23188 23189var _dashDashAdapter = _dereq_(56); 23190 23191var _dashDashAdapter2 = _interopRequireDefault(_dashDashAdapter); 23192 23193var _dashModelsDashManifestModel = _dereq_(63); 23194 23195var _dashModelsDashManifestModel2 = _interopRequireDefault(_dashModelsDashManifestModel); 23196 23197var _dashDashMetrics = _dereq_(58); 23198 23199var _dashDashMetrics2 = _interopRequireDefault(_dashDashMetrics); 23200 23201var _dashUtilsTimelineConverter = _dereq_(79); 23202 23203var _dashUtilsTimelineConverter2 = _interopRequireDefault(_dashUtilsTimelineConverter); 23204 23205var _voMetricsHTTPRequest = _dereq_(224); 23206 23207var _externalsBase64 = _dereq_(1); 23208 23209var _externalsBase642 = _interopRequireDefault(_externalsBase64); 23210 23211var _codemIsoboxer = _dereq_(11); 23212 23213var _codemIsoboxer2 = _interopRequireDefault(_codemIsoboxer); 23214 23215/** 23216 * @module MediaPlayer 23217 * @description The MediaPlayer is the primary dash.js Module and a Facade to build your player around. 23218 * It will allow you access to all the important dash.js properties/methods via the public API and all the 23219 * events to build a robust DASH media player. 23220 */ 23221function MediaPlayer() { 23222 23223 var PLAYBACK_NOT_INITIALIZED_ERROR = 'You must first call initialize() to init playback before calling this method'; 23224 var ELEMENT_NOT_ATTACHED_ERROR = 'You must first call attachView() to set the video element before calling this method'; 23225 var SOURCE_NOT_ATTACHED_ERROR = 'You must first call attachSource() with a valid source before calling this method'; 23226 var MEDIA_PLAYER_NOT_INITIALIZED_ERROR = 'MediaPlayer not initialized!'; 23227 23228 var context = this.context; 23229 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 23230 var debug = (0, _coreDebug2['default'])(context).getInstance(); 23231 var log = debug.log; 23232 23233 var instance = undefined, 23234 source = undefined, 23235 protectionData = undefined, 23236 mediaPlayerInitialized = undefined, 23237 playbackInitialized = undefined, 23238 autoPlay = undefined, 23239 abrController = undefined, 23240 timelineConverter = undefined, 23241 mediaController = undefined, 23242 protectionController = undefined, 23243 metricsReportingController = undefined, 23244 mssHandler = undefined, 23245 adapter = undefined, 23246 metricsModel = undefined, 23247 mediaPlayerModel = undefined, 23248 errHandler = undefined, 23249 capabilities = undefined, 23250 streamController = undefined, 23251 playbackController = undefined, 23252 dashMetrics = undefined, 23253 dashManifestModel = undefined, 23254 manifestModel = undefined, 23255 videoModel = undefined, 23256 textController = undefined, 23257 domStorage = undefined; 23258 23259 /* 23260 --------------------------------------------------------------------------- 23261 INIT FUNCTIONS 23262 --------------------------------------------------------------------------- 23263 */ 23264 function setup() { 23265 mediaPlayerInitialized = false; 23266 playbackInitialized = false; 23267 autoPlay = true; 23268 protectionController = null; 23269 protectionData = null; 23270 adapter = null; 23271 _coreEventsEvents2['default'].extend(_MediaPlayerEvents2['default']); 23272 mediaPlayerModel = (0, _modelsMediaPlayerModel2['default'])(context).getInstance(); 23273 } 23274 23275 /** 23276 * Configure media plyer with customs controllers. Helpful for tests 23277 * 23278 * @param {object=} config controllers configuration 23279 * @memberof module:MediaPlayer 23280 * @instance 23281 */ 23282 function setConfig(config) { 23283 if (!config) { 23284 return; 23285 } 23286 if (config.capabilities) { 23287 capabilities = config.capabilities; 23288 } 23289 if (config.streamController) { 23290 streamController = config.streamController; 23291 } 23292 if (config.playbackController) { 23293 playbackController = config.playbackController; 23294 } 23295 if (config.mediaPlayerModel) { 23296 mediaPlayerModel = config.mediaPlayerModel; 23297 } 23298 if (config.abrController) { 23299 abrController = config.abrController; 23300 } 23301 if (config.mediaController) { 23302 mediaController = config.mediaController; 23303 } 23304 } 23305 23306 /** 23307 * Upon creating the MediaPlayer you must call initialize before you call anything else. 23308 * There is one exception to this rule. It is crucial to call {@link module:MediaPlayer#extend extend()} 23309 * with all your extensions prior to calling initialize. 23310 * 23311 * ALL arguments are optional and there are individual methods to set each argument later on. 23312 * The args in this method are just for convenience and should only be used for a simple player setup. 23313 * 23314 * @param {HTML5MediaElement=} view - Optional arg to set the video element. {@link module:MediaPlayer#attachView attachView()} 23315 * @param {string=} source - Optional arg to set the media source. {@link module:MediaPlayer#attachSource attachSource()} 23316 * @param {boolean=} AutoPlay - Optional arg to set auto play. {@link module:MediaPlayer#setAutoPlay setAutoPlay()} 23317 * @see {@link module:MediaPlayer#attachView attachView()} 23318 * @see {@link module:MediaPlayer#attachSource attachSource()} 23319 * @see {@link module:MediaPlayer#setAutoPlay setAutoPlay()} 23320 * @memberof module:MediaPlayer 23321 * @instance 23322 */ 23323 function initialize(view, source, AutoPlay) { 23324 23325 if (!capabilities) { 23326 capabilities = (0, _utilsCapabilities2['default'])(context).getInstance(); 23327 } 23328 errHandler = (0, _utilsErrorHandler2['default'])(context).getInstance(); 23329 23330 if (!capabilities.supportsMediaSource()) { 23331 errHandler.capabilityError('mediasource'); 23332 return; 23333 } 23334 23335 if (mediaPlayerInitialized) return; 23336 mediaPlayerInitialized = true; 23337 23338 // init some controllers and models 23339 timelineConverter = (0, _dashUtilsTimelineConverter2['default'])(context).getInstance(); 23340 if (!abrController) { 23341 abrController = (0, _controllersAbrController2['default'])(context).getInstance(); 23342 } 23343 23344 if (!playbackController) { 23345 playbackController = (0, _controllersPlaybackController2['default'])(context).getInstance(); 23346 } 23347 23348 if (!mediaController) { 23349 mediaController = (0, _controllersMediaController2['default'])(context).getInstance(); 23350 } 23351 23352 adapter = (0, _dashDashAdapter2['default'])(context).getInstance(); 23353 dashManifestModel = (0, _dashModelsDashManifestModel2['default'])(context).getInstance({ 23354 mediaController: mediaController, 23355 timelineConverter: timelineConverter, 23356 adapter: adapter 23357 }); 23358 manifestModel = (0, _modelsManifestModel2['default'])(context).getInstance(); 23359 dashMetrics = (0, _dashDashMetrics2['default'])(context).getInstance({ 23360 manifestModel: manifestModel, 23361 dashManifestModel: dashManifestModel 23362 }); 23363 metricsModel = (0, _modelsMetricsModel2['default'])(context).getInstance(); 23364 23365 textController = (0, _textTextController2['default'])(context).getInstance(); 23366 domStorage = (0, _utilsDOMStorage2['default'])(context).getInstance({ 23367 mediaPlayerModel: mediaPlayerModel 23368 }); 23369 23370 adapter.setConfig({ 23371 dashManifestModel: dashManifestModel 23372 }); 23373 metricsModel.setConfig({ 23374 adapter: adapter 23375 }); 23376 23377 restoreDefaultUTCTimingSources(); 23378 setAutoPlay(AutoPlay !== undefined ? AutoPlay : true); 23379 23380 if (view) { 23381 attachView(view); 23382 } 23383 23384 if (source) { 23385 attachSource(source); 23386 } 23387 23388 log('[dash.js ' + getVersion() + '] ' + 'MediaPlayer has been initialized'); 23389 } 23390 23391 /** 23392 * Sets the MPD source and the video element to null. You can also reset the MediaPlayer by 23393 * calling attachSource with a new source file. 23394 * 23395 * Calling this method is all that is necessary to destroy a MediaPlayer instance. 23396 * 23397 * @memberof module:MediaPlayer 23398 * @instance 23399 */ 23400 function reset() { 23401 attachSource(null); 23402 attachView(null); 23403 protectionData = null; 23404 if (protectionController) { 23405 protectionController.reset(); 23406 protectionController = null; 23407 } 23408 if (metricsReportingController) { 23409 metricsReportingController.reset(); 23410 metricsReportingController = null; 23411 } 23412 } 23413 23414 /** 23415 * The ready state of the MediaPlayer based on both the video element and MPD source being defined. 23416 * 23417 * @returns {boolean} The current ready state of the MediaPlayer 23418 * @see {@link module:MediaPlayer#attachView attachView()} 23419 * @see {@link module:MediaPlayer#attachSource attachSource()} 23420 * @memberof module:MediaPlayer 23421 * @instance 23422 */ 23423 function isReady() { 23424 return !!videoModel && !!source; 23425 } 23426 23427 /** 23428 * Use the on method to listen for public events found in MediaPlayer.events. {@link MediaPlayerEvents} 23429 * 23430 * @param {string} type - {@link MediaPlayerEvents} 23431 * @param {Function} listener - callback method when the event fires. 23432 * @param {Object} scope - context of the listener so it can be removed properly. 23433 * @memberof module:MediaPlayer 23434 * @instance 23435 */ 23436 function on(type, listener, scope) { 23437 eventBus.on(type, listener, scope); 23438 } 23439 23440 /** 23441 * Use the off method to remove listeners for public events found in MediaPlayer.events. {@link MediaPlayerEvents} 23442 * 23443 * @param {string} type - {@link MediaPlayerEvents} 23444 * @param {Function} listener - callback method when the event fires. 23445 * @param {Object} scope - context of the listener so it can be removed properly. 23446 * @memberof module:MediaPlayer 23447 * @instance 23448 */ 23449 function off(type, listener, scope) { 23450 eventBus.off(type, listener, scope); 23451 } 23452 23453 /** 23454 * Current version of Dash.js 23455 * @returns {string}
23455 the current dash.js version string. 23456 * @memberof module:MediaPlayer 23457 * @instance 23458 */ 23459 function getVersion() { 23460 return (0, _coreVersion.getVersionString)(); 23461 } 23462 23463 /** 23464 * Use this method to access the dash.js logging class. 23465 * 23466 * @returns {Debug} 23467 * @memberof module:MediaPlayer 23468 * @instance 23469 */ 23470 function getDebug() { 23471 return debug; 23472 } 23473 23474 /* 23475 --------------------------------------------------------------------------- 23476 PLAYBACK FUNCTIONS 23477 --------------------------------------------------------------------------- 23478 */ 23479 /** 23480 * The play method initiates playback of the media defined by the {@link module:MediaPlayer#attachSource attachSource()} method. 23481 * This method will call play on the native Video Element. 23482 * 23483 * @see {@link module:MediaPlayer#attachSource attachSource()} 23484 * @memberof module:MediaPlayer 23485 * @instance 23486 */ 23487 function play() { 23488 if (!playbackInitialized) { 23489 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23490 } 23491 if (!autoPlay || isPaused() && playbackInitialized) { 23492 playbackController.play(); 23493 } 23494 } 23495 23496 /** 23497 * This method will call pause on the native Video Element. 23498 * 23499 * @memberof module:MediaPlayer 23500 * @instance 23501 */ 23502 function pause() { 23503 if (!playbackInitialized) { 23504 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23505 } 23506 playbackController.pause(); 23507 } 23508 23509 /** 23510 * Returns a Boolean that indicates whether the Video Element is paused. 23511 * @return {boolean} 23512 * @memberof module:MediaPlayer 23513 * @instance 23514 */ 23515 function isPaused() { 23516 if (!playbackInitialized) { 23517 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23518 } 23519 return playbackController.isPaused(); 23520 } 23521 23522 /** 23523 * Sets the currentTime property of the attached video element. If it is a live stream with a 23524 * timeShiftBufferLength, then the DVR window offset will be automatically calculated. 23525 * 23526 * @param {number} value - A relative time, in seconds, based on the return value of the {@link module:MediaPlayer#duration duration()} method is expected 23527 * @see {@link module:MediaPlayer#getDVRSeekOffset getDVRSeekOffset()} 23528 * @memberof module:MediaPlayer 23529 * @instance 23530 */ 23531 function seek(value) { 23532 if (!playbackInitialized) { 23533 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23534 } 23535 var s = playbackController.getIsDynamic() ? getDVRSeekOffset(value) : value; 23536 playbackController.seek(s); 23537 } 23538 23539 /** 23540 * Returns a Boolean that indicates whether the media is in the process of seeking to a new position. 23541 * @return {boolean} 23542 * @memberof module:MediaPlayer 23543 * @instance 23544 */ 23545 function isSeeking() { 23546 if (!playbackInitialized) { 23547 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23548 } 23549 return playbackController.isSeeking(); 23550 } 23551 23552 /** 23553 * Returns a Boolean that indicates whether the media is in the process of dynamic. 23554 * @return {boolean} 23555 * @memberof module:MediaPlayer 23556 * @instance 23557 */ 23558 function isDynamic() { 23559 if (!playbackInitialized) { 23560 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23561 } 23562 return playbackController.getIsDynamic(); 23563 } 23564 23565 /** 23566 * Use this method to set the native Video Element's playback rate. 23567 * @param {number} value 23568 * @memberof module:MediaPlayer 23569 * @instance 23570 */ 23571 function setPlaybackRate(value) { 23572 if (!videoModel) { 23573 throw ELEMENT_NOT_ATTACHED_ERROR; 23574 } 23575 getVideoElement().playbackRate = value; 23576 } 23577 23578 /** 23579 * Returns the current playback rate. 23580 * @returns {number} 23581 * @memberof module:MediaPlayer 23582 * @instance 23583 */ 23584 function getPlaybackRate() { 23585 if (!videoModel) { 23586 throw ELEMENT_NOT_ATTACHED_ERROR; 23587 } 23588 return getVideoElement().playbackRate; 23589 } 23590 23591 /** 23592 * Use this method to set the native Video Element's muted state. Takes a Boolean that determines whether audio is muted. true if the audio is muted and false otherwise. 23593 * @param {boolean} value 23594 * @memberof module:MediaPlayer 23595 * @instance 23596 */ 23597 function setMute(value) { 23598 if (!videoModel) { 23599 throw ELEMENT_NOT_ATTACHED_ERROR; 23600 } 23601 getVideoElement().muted = value; 23602 } 23603 23604 /** 23605 * A Boolean that determines whether audio is muted. 23606 * @returns {boolean} 23607 * @memberof module:MediaPlayer 23608 * @instance 23609 */ 23610 function isMuted() { 23611 if (!videoModel) { 23612 throw ELEMENT_NOT_ATTACHED_ERROR; 23613 } 23614 return getVideoElement().muted; 23615 } 23616 23617 /** 23618 * A double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). 23619 * @param {number} value 23620 * @memberof module:MediaPlayer 23621 * @instance 23622 */ 23623 function setVolume(value) { 23624 if (!videoModel) { 23625 throw ELEMENT_NOT_ATTACHED_ERROR; 23626 } 23627 getVideoElement().volume = value; 23628 } 23629 23630 /** 23631 * Returns the current audio volume, from 0.0 (silent) to 1.0 (loudest). 23632 * @returns {number} 23633 * @memberof module:MediaPlayer 23634 * @instance 23635 */ 23636 function getVolume() { 23637 if (!videoModel) { 23638 throw ELEMENT_NOT_ATTACHED_ERROR; 23639 } 23640 return getVideoElement().volume; 23641 } 23642 23643 /** 23644 * The length of the buffer for a given media type, in seconds. Valid media 23645 * types are "video", "audio" and "fragmentedText". If no type is passed 23646 * in, then the minimum of video, audio and fragmentedText buffer length is
23647 * returned. NaN is returned if an invalid type is requested, the 23648 * presentation does not contain that type, or if no arguments are passed 23649 * and the presentation does not include any adaption sets of valid media 23650 * type. 23651 * 23652 * @param {string} type - the media type of the buffer 23653 * @returns {number} The length of the buffer for the given media type, in 23654 * seconds, or NaN 23655 * @memberof module:MediaPlayer 23656 * @instance 23657 */ 23658 function getBufferLength(type) { 23659 var types = [_constantsConstants2['default'].VIDEO, _constantsConstants2['default'].AUDIO, _constantsConstants2['default'].FRAGMENTED_TEXT]; 23660 if (!type) { 23661 var buffer = types.map(function (t) { 23662 return getTracksFor(t).length > 0 ? getDashMetrics().getCurrentBufferLevel(getMetricsFor(t)) : Number.MAX_VALUE; 23663 }).reduce(function (p, c) { 23664 return Math.min(p, c); 23665 }); 23666 return buffer === Number.MAX_VALUE ? NaN : buffer; 23667 } else { 23668 if (types.indexOf(type) !== -1) { 23669 var buffer = getDashMetrics().getCurrentBufferLevel(getMetricsFor(type)); 23670 return buffer ? buffer : NaN; 23671 } else { 23672 log('Warning - getBufferLength requested for invalid type'); 23673 return NaN; 23674 } 23675 } 23676 } 23677 23678 /** 23679 * The timeShiftBufferLength (DVR Window), in seconds. 23680 * 23681 * @returns {number} The window of allowable play time behind the live point of a live stream. 23682 * @memberof module:MediaPlayer 23683 * @instance 23684 */ 23685 function getDVRWindowSize() { 23686 var metric = getDVRInfoMetric(); 23687 if (!metric) { 23688 return 0; 23689 } 23690 return metric.manifestInfo.DVRWindowSize; 23691 } 23692 23693 /** 23694 * This method should only be used with a live stream that has a valid timeShiftBufferLength (DVR Window). 23695 * NOTE - If you do not need the raw offset value (i.e. media analytics, tracking, etc) consider using the {@link module:MediaPlayer#seek seek()} method 23696 * which will calculate this value for you and set the video element's currentTime property all in one simple call. 23697 * 23698 * @param {number} value - A relative time, in seconds, based on the return value of the {@link module:MediaPlayer#duration duration()} method is expected. 23699 * @returns {number} A value that is relative the available range within the timeShiftBufferLength (DVR Window). 23700 * @see {@link module:MediaPlayer#seek seek()} 23701 * @memberof module:MediaPlayer 23702 * @instance 23703 */ 23704 function getDVRSeekOffset(value) { 23705 var metric = getDVRInfoMetric(); 23706 23707 if (!metric) { 23708 return 0; 23709 } 23710 23711 var val = metric.range.start + value; 23712 23713 if (val > metric.range.end) { 23714 val = metric.range.end; 23715 } 23716 23717 return val; 23718 } 23719 23720 /** 23721 * Current time of the playhead, in seconds. 23722 * 23723 * If called with no arguments then the returned time value is time elapsed since the start point of the first stream, or if it is a live stream, then the time will be based on the return value of the {@link module:MediaPlayer#duration duration()} method. 23724 * However if a stream ID is supplied then time is relative to the start of that stream, or is null if there is no such stream id in the manifest. 23725 * 23726 * @param {string} streamId - The ID of a stream that the returned playhead time must be relative to the start of. If undefined, then playhead time is relative to the first stream. 23727 * @returns {number} The current playhead time of the media, or null. 23728 * @memberof module:MediaPlayer 23729 * @instance 23730 */ 23731 function time(streamId) { 23732 if (!playbackInitialized) { 23733 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23734 } 23735 var t = getVideoElement().currentTime; 23736 23737 if (streamId !== undefined) { 23738 t = streamController.getTimeRelativeToStreamId(t, streamId); 23739 } else if (playbackController.getIsDynamic()) { 23740 var metric = getDVRInfoMetric(); 23741 t = metric === null ? 0 : duration() - (metric.range.end - metric.time); 23742 } 23743 23744 return t; 23745 } 23746 23747 /** 23748 * Duration of the media's playback, in seconds. 23749 * 23750 * @returns {number} The current duration of the media. 23751 * @memberof module:MediaPlayer 23752 * @instance 23753 */ 23754 function duration() { 23755 if (!playbackInitialized) { 23756 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23757 } 23758 var d = getVideoElement().duration; 23759 23760 if (playbackController.getIsDynamic()) { 23761 23762 var metric = getDVRInfoMetric(); 23763 var range = undefined; 23764 23765 if (!metric) { 23766 return 0; 23767 } 23768 23769 range = metric.range.end - metric.range.start; 23770 d = range < metric.manifestInfo.DVRWindowSize ? range : metric.manifestInfo.DVRWindowSize; 23771 } 23772 return d; 23773 } 23774 23775 /** 23776 * Use this method to get the current playhead time as an absolute value, the time in seconds since midnight UTC, Jan 1 1970. 23777 * Note - this property only has meaning for live streams. If called before play() has begun, it will return a value of NaN. 23778 * 23779 * @returns {number} The current playhead time as UTC timestamp. 23780 * @memberof module:MediaPlayer 23781 * @instance 23782 */ 23783 function timeAsUTC() { 23784 if (!playbackInitialized) { 23785 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23786 } 23787 if (time() < 0) { 23788 return NaN; 23789 } 23790 return getAsUTC(time()); 23791 } 23792 23793 /** 23794 * Use this method to get the current duration as an absolute value, the time in seconds since midnight UTC, Jan 1 1970. 23795 * Note - this property only has meaning for live streams. 23796 * 23797 * @returns {number} The current duration as UTC timestamp. 23798 * @memberof module:MediaPlayer 23799 * @instance 23800 */ 23801 function durationAsUTC() { 23802 if (!playbackInitialized) { 23803 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23804 } 23805 return getAsUTC(duration()); 23806 } 23807 23808 /* 23809 --------------------------------------------------------------------------- 23810 AUTO BITRATE 23811 --------------------------------------------------------------------------- 23812 */ 23813 /** 23814 * When switching multi-bitrate content (auto or manual mode) this property specifies the maximum bitrate allowed. 23815 * If you set this property to a value lower than that currently playing, the switching engine will switch down to 23816 * satisfy this requirement. If you set it to a value that is lower than the lowest bitrate, it will still play 23817 * that lowest bitrate. 23818 *
23819 * You can set or remove this bitrate cap at anytime before or during playback. To clear this setting you must use the API 23820 * and set the value param to NaN. 23821 * 23822 * This feature is typically used to reserve higher bitrates for playback only when the player is in large or full-screen format. 23823 * 23824 * @param {string} type - 'video' or 'audio' are the type options. 23825 * @param {number} value - Value in kbps representing the maximum bitrate allowed. 23826 * @memberof module:MediaPlayer 23827 * @instance 23828 */ 23829 function setMaxAllowedBitrateFor(type, value) { 23830 abrController.setMaxAllowedBitrateFor(type, value); 23831 } 23832 23833 /** 23834 * When switching multi-bitrate content (auto or manual mode) this property specifies the minimum bitrate allowed. 23835 * If you set this property to a value higher than that currently playing, the switching engine will switch up to 23836 * satisfy this requirement. If you set it to a value that is lower than the lowest bitrate, it will still play 23837 * that lowest bitrate. 23838 * 23839 * You can set or remove this bitrate limit at anytime before or during playback. To clear this setting you must use the API 23840 * and set the value param to NaN. 23841 * 23842 * This feature is used to force higher quality playback. 23843 * 23844 * @param {string} type - 'video' or 'audio' are the type options. 23845 * @param {number} value - Value in kbps representing the minimum bitrate allowed. 23846 * @memberof module:MediaPlayer 23847 * @instance 23848 */ 23849 function setMinAllowedBitrateFor(type, value) { 23850 abrController.setMinAllowedBitrateFor(type, value); 23851 } 23852 23853 /** 23854 * @param {string} type - 'video' or 'audio' are the type options. 23855 * @memberof module:MediaPlayer 23856 * @see {@link module:MediaPlayer#setMaxAllowedBitrateFor setMaxAllowedBitrateFor()} 23857 * @instance 23858 */ 23859 function getMaxAllowedBitrateFor(type) { 23860 return abrController.getMaxAllowedBitrateFor(type); 23861 } 23862 23863 /** 23864 * @param {string} type - 'video' or 'audio' are the type options. 23865 * @memberof module:MediaPlayer 23866 * @see {@link module:MediaPlayer#setMinAllowedBitrateFor setMinAllowedBitrateFor()} 23867 * @instance 23868 */ 23869 function getMinAllowedBitrateFor(type) { 23870 return abrController.getMinAllowedBitrateFor(type); 23871 } 23872 23873 /** 23874 * When switching multi-bitrate content (auto or manual mode) this property specifies the maximum representation allowed, 23875 * as a proportion of the size of the representation set. 23876 * 23877 * You can set or remove this cap at anytime before or during playback. To clear this setting you must use the API 23878 * and set the value param to NaN. 23879 * 23880 * If both this and maxAllowedBitrate are defined, maxAllowedBitrate is evaluated first, then maxAllowedRepresentation, 23881 * i.e. the lowest value from executing these rules is used. 23882 * 23883 * This feature is typically used to reserve higher representations for playback only when connected over a fast connection. 23884 * 23885 * @param {string} type - 'video' or 'audio' are the type options. 23886 * @param {number} value - number between 0 and 1, where 1 is allow all representations, and 0 is allow only the lowest. 23887 * @memberof module:MediaPlayer 23888 * @instance 23889 */ 23890 function setMaxAllowedRepresentationRatioFor(type, value) { 23891 abrController.setMaxAllowedRepresentationRatioFor(type, value); 23892 } 23893 23894 /** 23895 * @param {string} type - 'video' or 'audio' are the type options. 23896 * @returns {number} The current representation ratio cap. 23897 * @memberof module:MediaPlayer 23898 * @see {@link module:MediaPlayer#setMaxAllowedRepresentationRatioFor setMaxAllowedRepresentationRatioFor()} 23899 * @instance 23900 */ 23901 function getMaxAllowedRepresentationRatioFor(type) { 23902 return abrController.getMaxAllowedRepresentationRatioFor(type); 23903 } 23904 23905 /** 23906 * Gets the current download quality for media type. The ABR rules update this value before every new download 23907 * unless setAutoSwitchQualityFor(type, false) is called. 23908 * 23909 * @param {string} type - 'video' or 'audio' 23910 * @returns {number} the quality index, 0 corresponding to the lowest bitrate 23911 * @memberof module:MediaPlayer 23912 * @see {@link module:MediaPlayer#setAutoSwitchQualityFor setAutoSwitchQualityFor()} 23913 * @see {@link module:MediaPlayer#setQualityFor setQualityFor()} 23914 * @instance 23915 */ 23916 function getQualityFor(type) { 23917 if (!playbackInitialized) { 23918 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23919 } 23920 return abrController.getQualityFor(type, streamController.getActiveStreamInfo()); 23921 } 23922 23923 /** 23924 * Sets the current quality for media type instead of letting the ABR Heuristics automatically selecting it. 23925 * This value will be overwritten by the ABR rules unless setAutoSwitchQualityFor(type, false) is called. 23926 * 23927 * @param {string} type - 'video' or 'audio' 23928 * @param {number} value - the quality index, 0 corresponding to the lowest bitrate 23929 * @memberof module:MediaPlayer 23930 * @see {@link module:MediaPlayer#setAutoSwitchQualityFor setAutoSwitchQualityFor()} 23931 * @see {@link module:MediaPlayer#getQualityFor getQualityFor()} 23932 * @instance 23933 */ 23934 function setQualityFor(type, value) { 23935 if (!playbackInitialized) { 23936 throw PLAYBACK_NOT_INITIALIZED_ERROR; 23937 } 23938 abrController.setPlaybackQuality(type, streamController.getActiveStreamInfo(), value); 23939 } 23940 23941 /** 23942 * Update the video element size variables 23943 * Should be called on window resize (or any other time player is resized). Fullscreen does trigger a window resize event. 23944 * 23945 * Once windowResizeEventCalled = true, abrController.checkPortalSize() will use element size variables rather than querying clientWidth every time. 23946 * 23947 * @memberof module:MediaPlayer 23948 * @instance 23949 */ 23950 function updatePortalSize() { 23951 abrController.setElementSize(); 23952 abrController.setWindowResizeEventCalled(true); 23953 } 23954 23955 /** 23956 * @memberof module:MediaPlayer 23957 * @instance 23958 */ 23959 function getLimitBitrateByPortal() { 23960 return abrController.getLimitBitrateByPortal(); 23961 } 23962 23963 /** 23964 * Sets whether to limit the representation used based on the size of the playback area 23965 * 23966 * @param {boolean} value 23967 * @memberof module:MediaPlayer 23968 * @instance 23969 */ 23970 function setLimitBitrateByPortal(value) { 23971 abrController.setLimitBitrateByPortal(value); 23972 } 23973 23974 /** 23975 * @memberof module:MediaPlayer 23976 * @instance 23977 */ 23978 function getUsePixelRatioInLimitBitrateByPortal() { 23979 return abrController.getUsePixelRatioInLimitBitrateByPortal(); 23980 } 23981 23982 /** 23983 * Sets whether to take into account the device's pixel ratio when defining the portal dimensions. 23984 * Useful on, for example, retina displays. 23985 * 23986 * @param {boolean} value 23987 * @memberof module:MediaPlayer 23988 * @instance 23989 * @default {boolean} false 23990 */ 23991 function setUsePixelRatioInLimitBitrateByPortal(value) { 23992 abrController.setUsePixelRatioInLimitBitrateByPortal(value); 23993 } 23994 23995 /** 23996 * Use this method to explicitly set the starting bitrate for audio | video 23997 * 23998 * @param {string} type 23999 * @param {number} value - A value of the initial bitrate, kbps 24000 * @memberof module:MediaPlayer 24001 * @instance 24002 */ 24003 function setInitialBitrateFor(type, value) { 24004 abrController.setInitialBitrateFor(type, value); 24005 } 24006 24007 /** 24008 * @param {string} type 24009 * @returns {number} A value of the initial bitrate, kbps 24010 * @memberof module:MediaPlayer 24011 * @instance 24012 */ 24013 function getInitialBitrateFor(type) { 24014 if (!playbackInitialized) { 24015 throw PLAYBACK_NOT_INITIALIZED_ERROR; //abrController.getInitialBitrateFor is overloaded with ratioDict logic that needs manifest force it to not be callable pre play. 24016 } 24017 return abrController.getInitialBitrateFor(type); 24018 } 24019 24020 /** 24021 * @param {string} type 24022 * @param {number} value - A value of the initial Representation Ratio 24023 * @memberof module:MediaPlayer 24024 * @instance 24025 */ 24026 function setInitialRepresentationRatioFor(type, value) { 24027 abrController.setInitialRepresentationRatioFor(type, value); 24028 } 24029 24030 /** 24031 * @param {string} type 24032 * @returns {number} A value of the initial Representation Ratio 24033 * @memberof module:MediaPlayer 24034 * @instance 24035 */ 24036 function getInitialRepresentationRatioFor(type) { 24037 return abrController.getInitialRepresentationRatioFor(type); 24038 } 24039 24040 /** 24041 * @param {string} type - 'audio' | 'video' 24042 * @returns {boolean} Current state of adaptive bitrate switching 24043 * @memberof module:MediaPlayer 24044 * @instance 24045 */ 24046 function getAutoSwitchQualityFor(type) { 24047 return abrController.getAutoSwitchBitrateFor(type); 24048 } 24049 24050 /** 24051 * Set to false to switch off adaptive bitrate switching. 24052 * 24053 * @param {string} type - 'audio' | 'video' 24054 * @param {boolean} value 24055 * @default true 24056 * @memberof module:MediaPlayer 24057 * @instance 24058 */ 24059 function setAutoSwitchQualityFor(type, value) { 24060 abrController.setAutoSwitchBitrateFor(type, value); 24061 } 24062 24063 /** 24064 * Get the value of useDeadTimeLatency in AbrController. @see setUseDeadTimeLatencyForAbr 24065 * 24066 * @returns {boolean} 24067 * 24068 * @memberof module:MediaPlayer 24069 * @instance 24070 */ 24071 function getUseDeadTimeLatencyForAbr() { 24072 return abrController.getUseDeadTimeLatency(); 24073 } 24074 24075 /** 24076 * Set the value of useDeadTimeLatency in AbrController. If true, only the download 24077 * portion will be considered part of the download bitrate and latency will be 24078 * regarded as static. If false, the reciprocal of the whole transfer time will be used. 24079 * Defaults to true. 24080 * 24081 * @param {boolean=} useDeadTimeLatency - True or false flag. 24082 * 24083 * @memberof module:MediaPlayer 24084 * @instance 24085 */ 24086 function setUseDeadTimeLatencyForAbr(useDeadTimeLatency) { 24087 abrController.setUseDeadTimeLatency(useDeadTimeLatency);
24088 } 24089 24090 /* 24091 --------------------------------------------------------------------------- 24092 MEDIA PLAYER CONFIGURATION 24093 --------------------------------------------------------------------------- 24094 */ 24095 /** 24096 * <p>Set to false to prevent stream from auto-playing when the view is attached.</p> 24097 * 24098 * @param {boolean} value 24099 * @default true 24100 * @memberof module:MediaPlayer 24101 * @see {@link module:MediaPlayer#attachView attachView()} 24102 * @instance 24103 * 24104 */ 24105 function setAutoPlay(value) { 24106 autoPlay = value; 24107 } 24108 24109 /** 24110 * @returns {boolean} The current autoPlay state. 24111 * @memberof module:MediaPlayer 24112 * @instance 24113 */ 24114 function getAutoPlay() { 24115 return autoPlay; 24116 } 24117 24118 /** 24119 * <p>Changing this value will lower or increase live stream latency. The detected segment duration will be multiplied by this value 24120 * to define a time in seconds to delay a live stream from the live edge.</p> 24121 * <p>Lowering this value will lower latency but may decrease the player's ability to build a stable buffer.</p> 24122 * 24123 * @param {number} value - Represents how many segment durations to delay the live stream. 24124 * @default 4 24125 * @memberof module:MediaPlayer 24126 * @see {@link module:MediaPlayer#useSuggestedPresentationDelay useSuggestedPresentationDelay()} 24127 * @instance 24128 */ 24129 function setLiveDelayFragmentCount(value) { 24130 mediaPlayerModel.setLiveDelayFragmentCount(value); 24131 } 24132 24133 /** 24134 * <p>Equivalent in seconds of setLiveDelayFragmentCount</p> 24135 * <p>Lowering this value will lower latency but may decrease the player's ability to build a stable buffer.</p> 24136 * <p>This value should be less than the manifest duration by a couple of segment durations to avoid playback issues</p> 24137 * <p>If set, this parameter will take precedence over setLiveDelayFragmentCount and manifest info</p> 24138 * 24139 * @param {number} value - Represents how many seconds to delay the live stream. 24140 * @default undefined 24141 * @memberof module:MediaPlayer 24142 * @see {@link module:MediaPlayer#useSuggestedPresentationDelay useSuggestedPresentationDelay()} 24143 * @instance 24144 */ 24145 function setLiveDelay(value) { 24146 mediaPlayerModel.setLiveDelay(value); 24147 } 24148 24149 /** 24150 * @memberof module:MediaPlayer 24151 * @see {@link module:MediaPlayer#setLiveDelay setLiveDelay()} 24152 * @instance 24153 * @returns {number|undefined} Current live stream delay in seconds when previously set, or `undefined` 24154 */ 24155 function getLiveDelay() { 24156 return mediaPlayerModel.getLiveDelay(); 24157 } 24158 24159 /** 24160 * <p>Set to true if you would like to override the default live delay and honor the SuggestedPresentationDelay attribute in by the manifest.</p> 24161 * @param {boolean} value 24162 * @default false 24163 * @memberof module:MediaPlayer 24164 * @see {@link module:MediaPlayer#setLiveDelayFragmentCount setLiveDelayFragmentCount()} 24165 * @instance 24166 */ 24167 function useSuggestedPresentationDelay(value) { 24168 mediaPlayerModel.setUseSuggestedPresentationDelay(value); 24169 } 24170 24171 /** 24172 * Set to false if you would like to disable the last known bit rate from being stored during playback and used 24173 * to set the initial bit rate for subsequent playback within the expiration window. 24174 * 24175 * The default expiration is one hour, defined in milliseconds. If expired, the default initial bit rate (closest to 1000 kbps) will be used 24176 * for that session and a new bit rate will be stored during that session. 24177 * 24178 * @param {boolean} enable - Will toggle if feature is enabled. True to enable, False to disable. 24179 * @param {number=} ttl - (Optional) A value defined in milliseconds representing how long to cache the bit rate for. Time to live. 24180 * @default enable = True, ttl = 360000 (1 hour) 24181 * @memberof module:MediaPlayer 24182 * @instance 24183 * 24184 */ 24185 function enableLastBitrateCaching(enable, ttl) { 24186 mediaPlayerModel.setLastBitrateCachingInfo(enable, ttl); 24187 } 24188 24189 /** 24190 * Set to false if you would like to disable the last known lang for audio (or camera angle for video) from being stored during playback and used 24191 * to set the initial settings for subsequent playback within the expiration window. 24192 * 24193 * The default expiration is one hour, defined in milliseconds. If expired, the default settings will be used 24194 * for that session and a new settings will be stored during that session. 24195 * 24196 * @param {boolean} enable - Will toggle if feature is enabled. True to enable, False to disable. 24197 * @param {number=} [ttl] - (Optional) A value defined in milliseconds representing how long to cache the settings for. Time to live. 24198 * @default enable = True, ttl = 360000 (1 hour) 24199 * @memberof module:MediaPlayer 24200 * @instance 24201 * 24202 */ 24203 function enableLastMediaSettingsCaching(enable, ttl) { 24204 mediaPlayerModel.setLastMediaSettingsCachingInfo(enable, ttl); 24205 } 24206 24207 /** 24208 * Set to true if you would like dash.js to keep downloading fragments in the background 24209 * when the video element is paused. 24210 * 24211 * @default true 24212 * @param {boolean} value 24213 * @memberof module:MediaPlayer 24214 * @instance 24215 */ 24216 function setScheduleWhilePaused(value) { 24217 mediaPlayerModel.setScheduleWhilePaused(value); 24218 } 24219 24220 /** 24221 * Returns a boolean of the current state of ScheduleWhilePaused. 24222 * @returns {boolean} 24223 * @see {@link module:MediaPlayer#setScheduleWhilePaused setScheduleWhilePaused()} 24224 * @memberof module:MediaPlayer 24225 * @instance 24226 */ 24227 function getScheduleWhilePaused() { 24228 return mediaPlayerModel.getScheduleWhilePaused(); 24229 } 24230 24231 /** 24232 * When enabled, after an ABR up-switch in quality, instead of requesting and appending the next fragment 24233 * at the end of the current buffer range it is requested and appended closer to the current time 24234 * When enabled, The maximum time to render a higher quality is current time + (1.5 * fragment duration). 24235 * 24236 * Note, When ABR down-switch is detected, we appended the lower quality at the end of the buffer range to preserve the 24237 * higher quality media for as long as possible. 24238 * 24239 * If enabled, it should be noted there are a few cases when the client will not replace inside buffer range but rather 24240 * just append at the end. 1. When the buffer level is less than one fragment duration 2. The client 24241 * is in an Abandonment State due to recent fragment abandonment event. 24242 * 24243 * Known issues: 24244 * 1. In IE11 with auto switching off, if a user switches to a quality they can not download in time the 24245 * fragment may be appended in the same range as the playhead or even in the past, in IE11 it may cause a stutter 24246 * or stall in playback. 24247 * 24248 * 24249 * @param {boolean} value 24250 * @default {boolean} false 24251 * @memberof module:MediaPlayer 24252 * @instance 24253 */ 24254 function setFastSwitchEnabled(value) { 24255 //TODO we need to look at track switches for adaptation sets. If always replace it works much like this but clears buffer. Maybe too many ways to do same thing. 24256 mediaPlayerModel.setFastSwitchEnabled(value); 24257 } 24258 24259 /** 24260 * Enabled by default. Will return the current state of Fast Switch. 24261 * @return {boolean} Returns true if FastSwitch ABR is enabled. 24262 * @see {@link module:MediaPlayer#setFastSwitchEnabled setFastSwitchEnabled()} 24263 * @memberof module:MediaPlayer 24264 * @instance 24265 */ 24266 function getFastSwitchEnabled() { 24267 return mediaPlayerModel.getFastSwitchEnabled(); 24268 } 24269 24270 /** 24271 * Obsolete since version 2.6.0. 24272 * Buffer-occupancy ABR is now switched on and off dynamically. 24273 * @see {@link module:MediaPlayer#setABRStrategy setABRStrategy()} 24274 * 24275 * @param {boolean} value 24276 * @memberof module:MediaPlayer 24277 * @instance 24278 */ 24279 function enableBufferOccupancyABR(value) { 24280 throw new Error('Calling obsolete function - enabledBufferOccupancyABR(' + value + ') has no effect.'); 24281 } 24282 24283 /** 24284 * Sets the ABR strategy. Valid strategies are "abrDynamic", "abrBola" and "abrThroughput". 24285 * The ABR strategy can also be changed during a streaming session.
24286 * The call has no effect if an invalid method is passed. 24287 * 24288 * The BOLA strategy chooses bitrate based on current buffer level, with higher bitrates for higher buffer levels. 24289 * The Throughput strategy chooses bitrate based on the recent throughput history. 24290 * The Dynamic strategy switches smoothly between BOLA and Throughput in real time, playing to the strengths of both. 24291 * 24292 * @param {string} value 24293 * @default "abrDynamic" 24294 * @memberof module:MediaPlayer 24295 * @instance 24296 */ 24297 function setABRStrategy(value) { 24298 if (value === _constantsConstants2['default'].ABR_STRATEGY_DYNAMIC || value === _constantsConstants2['default'].ABR_STRATEGY_BOLA || value === _constantsConstants2['default'].ABR_STRATEGY_THROUGHPUT) { 24299 mediaPlayerModel.setABRStrategy(value); 24300 } else { 24301 log('Warning: Ignoring setABRStrategy(' + value + ') - unknown value.'); 24302 } 24303 } 24304 24305 /** 24306 * Returns the current ABR strategy being used. 24307 * @return {string} "abrDynamic", "abrBola" or "abrThroughput" 24308 * @see {@link module:MediaPlayer#setABRStrategy setABRStrategy()} 24309 * @memberof module:MediaPlayer 24310 * @instance 24311 */ 24312 function getABRStrategy() { 24313 return mediaPlayerModel.getABRStrategy(); 24314 } 24315 24316 /** 24317 * Enable/disable builtin dashjs ABR rules 24318 * @param {boolean} value 24319 * @default true 24320 * @memberof module:MediaPlayer 24321 * @instance 24322 */ 24323 function useDefaultABRRules(value) { 24324 mediaPlayerModel.setUseDefaultABRRules(value); 24325 } 24326 24327 /** 24328 * Add a custom ABR Rule 24329 * Rule will be apply on next stream if a stream is being played 24330 * 24331 * @param {string} type - rule type (one of ['qualitySwitchRules','abandonFragmentRules']) 24332 * @param {string} rulename - name of rule (used to identify custom rule). If one rule of same name has been added, then existing rule will be updated 24333 * @param {object} rule - the rule object instance 24334 * @memberof module:MediaPlayer 24335 * @instance 24336 */ 24337 function addABRCustomRule(type, rulename, rule) { 24338 mediaPlayerModel.addABRCustomRule(type, rulename, rule); 24339 } 24340 24341 /** 24342 * Remove a custom ABR Rule 24343 * 24344 * @param {string} rulename - name of the rule to be removed 24345 * @memberof module:MediaPlayer 24346 * @instance 24347 */ 24348 function removeABRCustomRule(rulename) { 24349 mediaPlayerModel.removeABRCustomRule(rulename); 24350 } 24351 24352 /** 24353 * Remove all custom rules 24354 * @memberof module:MediaPlayer 24355 * @instance 24356 */ 24357 function removeAllABRCustomRule() { 24358 mediaPlayerModel.removeAllABRCustomRule(); 24359 } 24360 24361 /** 24362 * Sets the moving average method used for smoothing throughput estimates. Valid methods are 24363 * "slidingWindow" and "ewma". The call has no effect if an invalid method is passed. 24364 * 24365 * The sliding window moving average method computes the average throughput using the last four segments downloaded. 24366 * If the stream is live (as opposed to VOD), then only the last three segments are used. 24367 * If wide variations in throughput are detected, the number of segments can be dynamically increased to avoid oscillations. 24368 * 24369 * The exponentially weighted moving average (EWMA) method computes the average using exponential smoothing. 24370 * Two separate estimates are maintained, a fast one with a three-second half life and a slow one with an eight-second half life. 24371 * The throughput estimate at any time is the minimum of the fast and slow estimates. 24372 * This allows a fast reaction to a bandwidth drop and prevents oscillations on bandwidth spikes. 24373 * 24374 * @param {string} value 24375 * @default {string} 'slidingWindow' 24376 * @memberof module:MediaPlayer 24377 * @instance 24378 */ 24379 function setMovingAverageMethod(value) { 24380 if (value === _constantsConstants2['default'].MOVING_AVERAGE_SLIDING_WINDOW || value === _constantsConstants2['default'].MOVING_AVERAGE_EWMA) { 24381 mediaPlayerModel.setMovingAverageMethod(value); 24382 } else { 24383 log('Warning: Ignoring setMovingAverageMethod(' + value + ') - unknown value.'); 24384 } 24385 } 24386 24387 /** 24388 * Return the current moving average method used for smoothing throughput estimates. 24389 * @return {string} Returns "slidingWindow" or "ewma". 24390 * @see {@link module:MediaPlayer#setMovingAverageMethod setMovingAverageMethod()} 24391 * @memberof module:MediaPlayer 24392 * @instance 24393 */ 24394 function getMovingAverageMethod() { 24395 return mediaPlayerModel.getMovingAverageMethod(); 24396 } 24397 24398 /** 24399 * <p>Allows you to set a scheme and server source for UTC live edge detection for dynamic streams. 24400 * If UTCTiming is defined in the manifest, it will take precedence over any time source manually added.</p> 24401 * <p>If you have exposed the Date header, use the method {@link module:MediaPlayer#clearDefaultUTCTimingSources clearDefaultUTCTimingSources()}. 24402 * This will allow the date header on the manifest to be used instead of a time server</p> 24403 * @param {string} schemeIdUri - <ul> 24404 * <li>urn:mpeg:dash:utc:http-head:2014</li> 24405 * <li>urn:mpeg:dash:utc:http-xsdate:2014</li> 24406 * <li>urn:mpeg:dash:utc:http-iso:2014</li> 24407 * <li>
24407urn:mpeg:dash:utc:direct:2014</li> 24408 * </ul> 24409 * <p>Some specs referencing early ISO23009-1 drafts incorrectly use 24410 * 2012 in the URI, rather than 2014. support these for now.</p> 24411 * <ul> 24412 * <li>urn:mpeg:dash:utc:http-head:2012</li> 24413 * <li>urn:mpeg:dash:utc:http-xsdate:2012</li> 24414 * <li>urn:mpeg:dash:utc:http-iso:2012</li> 24415 * <li>urn:mpeg:dash:utc:direct:2012</li> 24416 * </ul> 24417 * @param {string} value - Path to a time source. 24418 * @default 24419 * <ul> 24420 * <li>schemeIdUri:urn:mpeg:dash:utc:http-xsdate:2014</li> 24421 * <li>value:http://time.akamai.com</li> 24422 * </ul> 24423 * @memberof module:MediaPlayer 24424 * @see {@link module:MediaPlayer#removeUTCTimingSource removeUTCTimingSource()} 24425 * @instance 24426 */ 24427 function addUTCTimingSource(schemeIdUri, value) { 24428 removeUTCTimingSource(schemeIdUri, value); //check if it already exists and remove if so. 24429 var vo = new _dashVoUTCTiming2['default'](); 24430 vo.schemeIdUri = schemeIdUri; 24431 vo.value = value; 24432 mediaPlayerModel.getUTCTimingSources().push(vo); 24433 } 24434 24435 /** 24436 * <p>Allows you to remove a UTC time source. Both schemeIdUri and value need to match the Dash.vo.UTCTiming properties in order for the 24437 * entry to be removed from the array</p> 24438 * @param {string} schemeIdUri - see {@link module:MediaPlayer#addUTCTimingSource addUTCTimingSource()} 24439 * @param {string} value - see {@link module:MediaPlayer#addUTCTimingSource addUTCTimingSource()} 24440 * @memberof module:MediaPlayer 24441 * @see {@link module:MediaPlayer#clearDefaultUTCTimingSources clearDefaultUTCTimingSources()} 24442 * @instance 24443 */ 24444 function removeUTCTimingSource(schemeIdUri, value) { 24445 var UTCTimingSources = mediaPlayerModel.getUTCTimingSources(); 24446 UTCTimingSources.forEach(function (obj, idx) { 24447 if (obj.schemeIdUri === schemeIdUri && obj.value === value) { 24448 UTCTimingSources.splice(idx, 1); 24449 } 24450 }); 24451 } 24452 24453 /** 24454 * <p>Allows you to clear the stored array of time sources.</p> 24455 * <p>Example use: If you have exposed the Date header, calling this method 24456 * will allow the date header on the manifest to be used instead of the time server.</p> 24457 * <p>Example use: Calling this method, assuming there is not an exposed date header on the manifest, will default back 24458 * to using a binary search to discover the live edge</p> 24459 * 24460 * @memberof module:MediaPlayer 24461 * @see {@link module:MediaPlayer#restoreDefaultUTCTimingSources restoreDefaultUTCTimingSources()} 24462 * @instance 24463 */ 24464 function clearDefaultUTCTimingSources() { 24465 mediaPlayerModel.setUTCTimingSources([]); 24466 } 24467 24468 /** 24469 * <p>Allows you to restore the default time sources after calling {@link module:MediaPlayer#clearDefaultUTCTimingSources clearDefaultUTCTimingSources()}</p> 24470 * 24471 * @default 24472 * <ul> 24473 * <li>schemeIdUri:urn:mpeg:dash:utc:http-xsdate:2014</li> 24474 * <li>value:http://time.akamai.com</li> 24475 * </ul> 24476 * 24477 * @memberof module:MediaPlayer 24478 * @see {@link module:MediaPlayer#addUTCTimingSource addUTCTimingSource()} 24479 * @instance 24480 */ 24481 function restoreDefaultUTCTimingSources() { 24482 addUTCTimingSource(_modelsMediaPlayerModel2['default'].DEFAULT_UTC_TIMING_SOURCE.scheme, _modelsMediaPlayerModel2['default'].DEFAULT_UTC_TIMING_SOURCE.value); 24483 } 24484 24485 /** 24486 * <p>Allows you to enable the use of the Date Header, if exposed with CORS, as a timing source for live edge detection. The 24487 * use of the date header will happen only after the other timing source that take precedence fail or are omitted as described. 24488 * {@link module:MediaPlayer#clearDefaultUTCTimingSources clearDefaultUTCTimingSources()} </p> 24489 * 24490 * @param {boolean} value - true to enable 24491 * @default {boolean} True 24492 * @memberof module:MediaPlayer 24493 * @see {@link module:MediaPlayer#addUTCTimingSource addUTCTimingSource()} 24494 * @instance 24495 */ 24496 function enableManifestDateHeaderTimeSource(value) { 24497 mediaPlayerModel.setUseManifestDateHeaderTimeSource(value); 24498 } 24499 24500 /** 24501 * This value influences the buffer pruning logic. 24502 * Allows you to modify the buffer that is kept in source buffer in seconds. 24503 * 0|-----------bufferToPrune-----------|-----bufferToKeep-----|currentTime| 24504 * 24505 * @default 30 seconds 24506 * @param {int} value 24507 * @memberof module:MediaPlayer 24508 * @instance 24509 */ 24510 function setBufferToKeep(value) { 24511 mediaPlayerModel.setBufferToKeep(value); 24512 } 24513 24514 /** 24515 * This value influences the buffer pruning logic. 24516 * Allows you to modify the interval of pruning buffer in seconds. 24517 * 24518 * @default 30 seconds 24519 * @param {int} value 24520 * @memberof module:MediaPlayer 24521 * @instance 24522 */ 24523 function setBufferPruningInterval(value) { 24524 mediaPlayerModel.setBufferPruningInterval(value); 24525 } 24526 24527 /** 24528 * The time that the internal buffer target will be set to post startup/seeks (NOT top quality). 24529 * 24530 * When the time is set higher than the default you will have to wait longer 24531 * to see automatic bitrate switches but will have a larger buffer which 24532 * will increase stability. 24533 * 24534 * @default 12 seconds. 24535 * @param {int} value 24536 * @memberof module:MediaPlayer 24537 * @instance 24538 */ 24539 function setStableBufferTime(value) { 24540 mediaPlayerModel.setStableBufferTime(value); 24541 } 24542 24543 /** 24544 * The time that the internal buffer target will be set to post startup/seeks (NOT top quality). 24545 * 24546 * When the time is set higher than the default you will have to wait longer 24547 * to see automatic bitrate switches but will have a larger buffer which 24548 * will increase stability. 24549 * 24550 * @default 12 seconds. 24551 * @memberof module:MediaPlayer 24552 * @instance 24553 */ 24554 function getStableBufferTime() { 24555 return mediaPlayerModel.getStableBufferTime(); 24556 } 24557 24558 /** 24559 * The time that the internal buffer target will be set to once playing the top quality. 24560 * If there are multiple bitrates in your adaptation, and the media is playing at the highest 24561 * bitrate, then we try to build a larger buffer at the top quality to increase stability 24562 * and to maintain media quality. 24563 * 24564 * @default 30 seconds. 24565 * @param {int} value 24566 /** 24567 * The time that the internal buffer target will be set to once playing the top quality. 24568 * If there are multiple bitrates in your adaptation, and the media is playing at the highest 24569 * bitrate, then we try to build a larger buffer at the top quality to increase stability 24570 * and to maintain media quality. 24571 * 24572 * @default 30 seconds. 24573 * @param {int} value 24574 * @memberof module:MediaPlayer 24575 * @instance 24576 */ 24577 function setBufferTimeAtTopQuality(value) { 24578 mediaPlayerModel.setBufferTimeAtTopQuality(value); 24579 } 24580 24581 /** 24582 * The time that the internal buffer target will be set to once playing the top quality. 24583 * If there are multiple bitrates in your adaptation, and the media is playing at the highest 24584 * bitrate, then we try to build a larger buffer at the top quality to increase stability 24585 * and to maintain media quality. 24586 * 24587 * @default 30 seconds. 24588 * @memberof module:MediaPlayer 24589 * @instance 24590 */ 24591 function getBufferTimeAtTopQuality() { 24592 return mediaPlayerModel.getBufferTimeAtTopQuality(); 24593 } 24594 24595 /** 24596 * The time that the internal buffer target will be set to once playing the top quality for long form content. 24597 * 24598 * @default 60 seconds. 24599 * @see {@link module:MediaPlayer#setLongFormContentDurationThreshold setLongFormContentDurationThreshold()} 24600 * @see {@link module:MediaPlayer#setBufferTimeAtTopQuality setBufferTimeAtTopQuality()} 24601 * @param {int} value 24602 * @memberof module:MediaPlayer 24603 * @instance 24604 */ 24605 function setBufferTimeAtTopQualityLongForm(value) { 24606 mediaPlayerModel.setBufferTimeAtTopQualityLongForm(value); 24607 } 24608 24609 /** 24610 * The time that the internal buffer target will be set to once playing the top quality for long form content. 24611 * 24612 * @default 60 seconds. 24613 * @see {@link module:MediaPlayer#setLongFormContentDurationThreshold setLongFormContentDurationThreshold()} 24614 * @see {@link module:MediaPlayer#setBufferTimeAtTopQuality setBufferTimeAtTopQuality()} 24615 * @memberof module:MediaPlayer 24616 * @instance 24617 */ 24618 function getBufferTimeAtTopQualityLongForm() { 24619 return mediaPlayerModel.getBufferTimeAtTopQualityLongForm(); 24620 } 24621 24622 /** 24623 * The threshold which defines if the media is considered long form content. 24624 * This will directly affect the buffer targets when playing back at the top quality. 24625 * 24626 * @see {@link module:MediaPlayer#setBufferTimeAtTopQualityLongForm setBufferTimeAtTopQualityLongForm()} 24627 * @default 600 seconds (10 minutes). 24628 * @param {number} value 24629 * @memberof module:MediaPlayer 24630 * @instance 24631 */ 24632 function setLongFormContentDurationThreshold(value) { 24633 mediaPlayerModel.setLongFormContentDurationThreshold(value); 24634 } 24635 24636 /** 24637 * Obsolete since version 2.6.0. 24638 * ABR rules now switch from Throughput to Buffer Occupancy mode when there is sufficient buffer. 24639 * This renders the rich buffer mechanism redundant. 24640 * 24641 * @param {number} value 24642 * @memberof module:MediaPlayer 24643 * @instance 24644 */ 24645 function setRichBufferThreshold(value) { 24646 throw new Error('Calling obsolete function - setRichBufferThreshold(' + value + ') has no effect.'); 24647 } 24648 24649 /** 24650 * A percentage between 0.0 and 1 to reduce the measured throughput calculations. 24651 * The default is 0.9. The lower the value the more conservative and restricted the 24652 * measured throughput calculations will be. please use carefully. This will directly 24653 * affect the ABR logic in dash.js 24654 * 24655 * @param {number} value 24656 * @memberof module:MediaPlayer 24657 * @instance 24658 */ 24659 function setBandwidthSafetyFactor(value) { 24660 mediaPlayerModel.setBandwidthSafetyFactor(value); 24661 } 24662 24663 /** 24664 * Returns the number of the current BandwidthSafetyFactor 24665 * 24666 * @return {number} value 24667 * @see {@link module:MediaPlayer#setBandwidthSafetyFactor setBandwidthSafetyFactor()} 24668 * @memberof module:MediaPlayer 24669 * @instance 24670 */ 24671 function getBandwidthSafetyFactor() { 24672 return mediaPlayerModel.getBandwidthSafetyFactor(); 24673 } 24674 24675 /** 24676 * Returns the average throughput computed in the ABR logic 24677 * 24678 * @param {string} type 24679 * @return {number} value 24680 * @memberof module:MediaPlayer 24681 * @instance 24682 */ 24683 function getAverageThroughput(type) { 24684 var throughputHistory = abrController.getThroughputHistory(); 24685 return throughputHistory ? throughputHistory.getAverageThroughput(type) : 0; 24686 } 24687 24688 /** 24689 * A timeout value in seconds, which during the ABRController will block switch-up events. 24690 * This will only take effect after an abandoned fragment event occurs. 24691 * 24692 * @default 10 seconds 24693 * @param {int} value 24694 * @memberof module:MediaPlayer 24695 * @instance 24696 */ 24697 function setAbandonLoadTimeout(value) { 24698 mediaPlayerModel.setAbandonLoadTimeout(value); 24699 } 24700 24701 /** 24702 * Total number of retry attempts that will occur on a fragment load before it fails. 24703 * Increase this value to a maximum in order to achieve an automatic playback resume 24704 * in case of completely lost internet connection. 24705 * 24706 * @default 3 24707 * @param {int} value 24708 * @memberof module:MediaPlayer 24709 * @instance 24710 */ 24711 function setFragmentLoaderRetryAttempts(value) { 24712 mediaPlayerModel.setFragmentRetryAttempts(value); 24713 } 24714 24715 /** 24716 * Time in milliseconds of which to reload a failed fragment load attempt. 24717 * 24718 * @default 1000 milliseconds 24719 * @param {int} value 24720 * @memberof module:MediaPlayer 24721 * @instance 24722 */ 24723 function setFragmentLoaderRetryInterval(value) { 24724 mediaPlayerModel.setFragmentRetryInterval(value); 24725 } 24726 24727 /** 24728 * Total number of retry attempts that will occur on a manifest load before it fails. 24729 * 24730 * @default 4 24731 * @param {int} value 24732 * @memberof module:MediaPlayer 24733 * @instance 24734 */ 24735 function setManifestLoaderRetryAttempts(value) { 24736 mediaPlayerModel.setManifestRetryAttempts(value); 24737 } 24738 24739 /** 24740 * Time in milliseconds of which to reload a failed manifest load attempt. 24741 * 24742 * @default 1000 milliseconds 24743 * @param {int} value 24744 * @memberof module:MediaPlayer 24745 * @instance 24746 */ 24747 function setManifestLoaderRetryInterval(value) { 24748 mediaPlayerModel.setManifestRetryInterval(value); 24749 } 24750 24751 /** 24752 * Sets whether withCredentials on XHR requests for a particular request 24753 * type is true or false 24754 * 24755 * @default false 24756 * @param {string} type - one of HTTPRequest.*_TYPE 24757 * @param {boolean} value 24758 * @memberof module:MediaPlayer 24759 * @instance 24760 */ 24761 function setXHRWithCredentialsForType(type, value) { 24762 mediaPlayerModel.setXHRWithCredentialsForType(type, value); 24763 } 24764 24765 /** 24766 * Gets whether withCredentials on XHR requests for a particular request 24767 * type is true or false 24768 * 24769 * @param {string} type - one of HTTPRequest.*_TYPE 24770 * @return {boolean} 24771 * @memberof module:MediaPlayer 24772 * @instance 24773 */ 24774 function getXHRWithCredentialsForType(type) { 24775 return mediaPlayerModel.getXHRWithCredentialsForType(type); 24776 } 24777 24778 /* 24779 --------------------------------------------------------------------------- 24780 METRICS 24781 --------------------------------------------------------------------------- 24782 */ 24783 /** 24784 * Returns the DashMetrics.js Module. You use this Module to get access to all the public metrics 24785 * stored in dash.js 24786 * 24787 * @see {@link module:DashMetrics} 24788 * @returns {Object} 24789 * @memberof module:MediaPlayer 24790 * @instance 24791 */ 24792 function getDashMetrics() { 24793 return dashMetrics; 24794 } 24795 24796 /** 24797 * 24798 * @param {string} type 24799 * @returns {Object} 24800 * @memberof module:MediaPlayer 24801 * @instance 24802 */ 24803 function getMetricsFor(type) {
24804 return metricsModel.getReadOnlyMetricsFor(type); 24805 } 24806 /* 24807 --------------------------------------------------------------------------- 24808 TEXT MANAGEMENT 24809 --------------------------------------------------------------------------- 24810 */ 24811 /** 24812 * Use this method to change the current text track for both external time text files and fragmented text tracks. There is no need to 24813 * set the track mode on the video object to switch a track when using this method. 24814 * 24815 * @param {number} idx - Index of track based on the order of the order the tracks are added Use -1 to disable all tracks. (turn captions off). Use module:MediaPlayer#dashjs.MediaPlayer.events.TEXT_TRACK_ADDED. 24816 * @see {@link module:MediaPlayer#dashjs.MediaPlayer.events.TEXT_TRACK_ADDED} 24817 * @memberof module:MediaPlayer 24818 * @instance 24819 */ 24820 function setTextTrack(idx) { 24821 if (!playbackInitialized) { 24822 throw PLAYBACK_NOT_INITIALIZED_ERROR; 24823 } 24824 24825 if (textController === undefined) { 24826 textController = (0, _textTextController2['default'])(context).getInstance(); 24827 } 24828 24829 textController.setTextTrack(idx); 24830 } 24831 24832 function getCurrentTextTrackIndex() { 24833 var idx = NaN; 24834 if (textController) { 24835 idx = textController.getCurrentTrackIdx(); 24836 } 24837 return idx; 24838 } 24839 24840 /** 24841 * This method serves to control captions z-index value. If 'true' is passed, the captions will have the highest z-index and be 24842 * displayed on top of other html elements. Default value is 'false' (z-index is not set). 24843 * @param {boolean} value 24844 * @memberof module:MediaPlayer 24845 * @instance 24846 */ 24847 function displayCaptionsOnTop(value) { 24848 var textTracks = (0, _textTextTracks2['default'])(context).getInstance(); 24849 textTracks.setConfig({ 24850 videoModel: videoModel 24851 }); 24852 textTracks.initialize(); 24853 textTracks.displayCConTop(value); 24854 } 24855 24856 /* 24857 --------------------------------------------------------------------------- 24858 VIDEO ELEMENT MANAGEMENT 24859 --------------------------------------------------------------------------- 24860 */ 24861 24862 /** 24863 * Returns instance of Video Element that was attached by calling attachView() 24864 * @returns {Object} 24865 * @memberof module:MediaPlayer 24866 * @instance 24867 */ 24868 function getVideoElement() { 24869 if (!videoModel) { 24870 throw ELEMENT_NOT_ATTACHED_ERROR; 24871 } 24872 return videoModel.getElement(); 24873 } 24874 24875 /** 24876 * Returns instance of Video Container that was attached by calling attachVideoContainer() 24877 * @returns {Object} 24878 * @memberof module:MediaPlayer 24879 * @instance 24880 */ 24881 function getVideoContainer() { 24882 return videoModel ? videoModel.getVideoContainer() : null; 24883 } 24884 24885 /** 24886 * Use this method to attach an HTML5 element that wraps the video element. 24887 * 24888 * @param {HTMLElement} container - The HTML5 element containing the video element. 24889 * @memberof module:MediaPlayer 24890 * @instance 24891 */ 24892 function attachVideoContainer(container) { 24893 if (!videoModel) { 24894 throw ELEMENT_NOT_ATTACHED_ERROR; 24895 } 24896 videoModel.setVideoContainer(container); 24897 } 24898 24899 /** 24900 * Use this method to attach an HTML5 VideoElement for dash.js to operate upon. 24901 * 24902 * @param {Object} element - An HTMLMediaElement that has already been defined in the DOM (or equivalent stub). 24903 * @memberof module:MediaPlayer 24904 * @instance 24905 */ 24906 function attachView(element) { 24907 if (!mediaPlayerInitialized) { 24908 throw MEDIA_PLAYER_NOT_INITIALIZED_ERROR; 24909 } 24910 videoModel = null; 24911 if (element) { 24912 videoModel = (0, _modelsVideoModel2['default'])(context).getInstance(); 24913 videoModel.initialize(); 24914 videoModel.setElement(element); 24915 detectProtection(); 24916 detectMetricsReporting(); 24917 detectMss(); 24918 } 24919 resetAndInitializePlayback(); 24920 } 24921 24922 /** 24923 * Returns instance of Div that was attached by calling attachTTMLRenderingDiv() 24924 * @returns {Object} 24925 * @memberof module:MediaPlayer 24926 * @instance 24927 */ 24928 function getTTMLRenderingDiv() { 24929 return videoModel ? videoModel.getTTMLRenderingDiv() : null; 24930 } 24931 24932 /** 24933 * Use this method to attach an HTML5 div for dash.js to render rich TTML subtitles. 24934 * 24935 * @param {HTMLDivElement} div - An unstyled div placed after the video element. It will be styled to match the video size and overlay z-order. 24936 * @memberof module:MediaPlayer 24937 * @instance 24938 */ 24939 function attachTTMLRenderingDiv(div) { 24940 if (!videoModel) { 24941 throw ELEMENT_NOT_ATTACHED_ERROR; 24942 } 24943 videoModel.setTTMLRenderingDiv(div); 24944 } 24945 24946 /* 24947 --------------------------------------------------------------------------- 24948 STREAM AND TRACK MANAGEMENT 24949 --------------------------------------------------------------------------- 24950 */ 24951 /** 24952 * @param {string} type 24953 * @returns {Array} 24954 * @memberof module:MediaPlayer 24955 * @instance 24956 */ 24957 function getBitrateInfoListFor(type) { 24958 if (!playbackInitialized) { 24959 throw PLAYBACK_NOT_INITIALIZED_ERROR; 24960 } 24961 var stream = getActiveStream(); 24962 return stream ? stream.getBitrateListFor(type) : []; 24963 } 24964 24965 /** 24966 * This method returns the list of all available streams from a given manifest 24967 * @param {Object} manifest 24968 * @returns {Array} list of {@link StreamInfo} 24969 * @memberof module:MediaPlayer 24970 * @instance 24971 */ 24972 function getStreamsFromManifest(manifest) { 24973 if (!playbackInitialized) { 24974 throw PLAYBACK_NOT_INITIALIZED_ERROR; 24975 } 24976 return adapter.getStreamsInfo(manifest); 24977 } 24978 24979 /** 24980 * This method returns the list of all available tracks for a given media type 24981 * @param {string} type 24982 * @returns {Array} list of {@link MediaInfo} 24983 * @memberof module:MediaPlayer 24984 * @instance 24985 */ 24986 function getTracksFor(type) { 24987 if (!playbackInitialized) { 24988 throw PLAYBACK_NOT_INITIALIZED_ERROR; 24989 } 24990 var streamInfo = streamController.getActiveStreamInfo(); 24991 if (!streamInfo) return []; 24992 return mediaController.getTracksFor(type, streamInfo); 24993 } 24994 24995 /** 24996 * This method returns the list of all available tracks for a given media type and streamInfo from a given manifest 24997 * @param {string} type 24998 * @param {Object} manifest 24999 * @param {Object} streamInfo 25000 * @returns {Array} list of {@link MediaInfo} 25001 * @memberof module:MediaPlayer 25002 * @instance 25003 */ 25004 function getTracksForTypeFromManifest(type, manifest, streamInfo) { 25005 if (!playbackInitialized) { 25006 throw PLAYBACK_NOT_INITIALIZED_ERROR; 25007 } 25008 25009 streamInfo = streamInfo || adapter.getStreamsInfo(manifest)[0]; 25010 25011 return streamInfo ? adapter.getAllMediaInfoForType(streamInfo, type, manifest) : []; 25012 } 25013 25014 /** 25015 * @param {string} type 25016 * @returns {Object|null} {@link MediaInfo} 25017 * 25018 * @memberof module:MediaPlayer 25019 * @instance 25020 */ 25021 function getCurrentTrackFor(type) { 25022 if (!playbackInitialized) { 25023 throw PLAYBACK_NOT_INITIALIZED_ERROR; 25024 } 25025 var streamInfo = streamController.getActiveStreamInfo(); 25026 25027 if (!streamInfo) return null; 25028 25029 return mediaController.getCurrentTrackFor(type, streamInfo); 25030 } 25031 25032 /** 25033 * This method allows to set media settings that will be used to pick the initial track. Format of the settings 25034 * is following: 25035 * {lang: langValue, 25036 * viewpoint: viewpointValue, 25037 * audioChannelConfiguration: audioChannelConfigurationValue, 25038 * accessibility: accessibilityValue, 25039 * role: roleValue} 25040 * 25041 * 25042 * @param {string} type 25043 * @param {Object} value 25044 * @memberof module:MediaPlayer 25045 * @instance 25046 */ 25047 function setInitialMediaSettingsFor(type, value) { 25048 mediaController.setInitialSettings(type, value); 25049 } 25050 25051 /** 25052 * This method returns media settings that is used to pick the initial track. Format of the settings 25053 * is following: 25054 * {lang: langValue, 25055 * viewpoint: viewpointValue, 25056 * audioChannelConfiguration: audioChannelConfigurationValue, 25057 * accessibility: accessibilityValue, 25058 * role: roleValue} 25059 * @param {string} type 25060 * @returns {Object} 25061 * @memberof module:MediaPlayer 25062 * @instance 25063 */ 25064 function getInitialMediaSettingsFor(type) { 25065 return mediaController.getInitialSettings(type); 25066 } 25067 25068 /** 25069 * @param {MediaInfo} track - instance of {@link MediaInfo} 25070 * @memberof module:MediaPlayer 25071 * @instance 25072 */ 25073 function setCurrentTrack(track) { 25074 if (!playbackInitialized) { 25075 throw PLAYBACK_NOT_INITIALIZED_ERROR; 25076 } 25077 mediaController.setTrack(track); 25078 } 25079 25080 /** 25081 * This method returns the current track switch mode. 25082 * 25083 * @param {string} type 25084 * @returns {string} mode 25085 * @memberof module:MediaPlayer 25086 * @instance 25087 */ 25088 function getTrackSwitchModeFor(type) { 25089 return mediaController.getSwitchMode(type); 25090 } 25091 25092 /** 25093 * This method sets the current track switch mode. Available options are: 25094 * 25095 * MediaController.TRACK_SWITCH_MODE_NEVER_REPLACE 25096 * (used to forbid clearing the buffered data (prior to current playback position) after track switch. Default for video) 25097 * 25098 * MediaController.TRACK_SWITCH_MODE_ALWAYS_REPLACE 25099 * (used to clear the buffered data (prior to current playback position) after track switch. Default for audio) 25100 * 25101 * @param {string} type 25102 * @param {string} mode 25103 * @memberof module:MediaPlayer 25104 * @instance 25105 */ 25106 function setTrackSwitchModeFor(type, mode) { 25107 mediaController.setSwitchMode(type, mode); 25108 } 25109 25110 /** 25111 * This method sets the selection mode for the initial track. This mode defines how the initial track will be selected 25112 * if no initial media settings are set. If initial media settings are set this parameter will be ignored. Available options are: 25113 * 25114 * MediaController.TRACK_SELECTION_MODE_HIGHEST_BITRATE 25115 * this mode makes the player select the track with a highest bitrate. This mode is a default mode. 25116 * 25117 * MediaController.TRACK_SELECTION_MODE_WIDEST_RANGE 25118 * this mode makes the player select the track with a widest range of bitrates 25119 * 25120 * @param {string} mode 25121 * @memberof module:MediaPlayer 25122 * @instance 25123 */ 25124 function setSelectionModeForInitialTrack(mode) { 25125 mediaController.setSelectionModeForInitialTrack(mode); 25126 } 25127 25128 /** 25129 * This method returns the track selection mode. 25130 * 25131 * @returns {string} mode 25132 * @memberof module:MediaPlayer 25133 * @instance 25134 */ 25135 function getSelectionModeForInitialTrack() { 25136 return mediaController.getSelectionModeForInitialTrack(); 25137 } 25138 25139 /* 25140 --------------------------------------------------------------------------- 25141 PROTECTION MANAGEMENT 25142 --------------------------------------------------------------------------- 25143 /** 25144 * Detects if Protection is included and returns an instance of ProtectionController.js 25145 * @memberof module:MediaPlayer 25146 * @instance 25147 */ 25148 function getProtectionController() { 25149 return detectProtection(); 25150 } 25151 25152 /** 25153 * Will override dash.js protection controller. 25154 * @param {ProtectionController} value - valid protection controller instance. 25155 * @memberof module:MediaPlayer 25156 * @instance 25157 */ 25158 function attachProtectionController(value) { 25159 protectionController = value; 25160 } 25161 25162 /** 25163 * @param {ProtectionData}
25163 value - object containing 25164 * property names corresponding to key system name strings and associated 25165 * values being instances of. 25166 * @memberof module:MediaPlayer 25167 * @instance 25168 */ 25169 function setProtectionData(value) { 25170 protectionData = value; 25171 } 25172 25173 /* 25174 --------------------------------------------------------------------------- 25175 TOOLS AND OTHERS FUNCTIONS 25176 --------------------------------------------------------------------------- 25177 */ 25178 /** 25179 * Allows application to retrieve a manifest. Manifest loading is asynchro 25180 * nous and 25181 * requires the app-provided callback function 25182 * 25183 * @param {string} url - url the manifest url 25184 * @param {function} callback - A Callback function provided when retrieving manifests 25185 * @memberof module:MediaPlayer 25186 * @instance 25187 */ 25188 function retrieveManifest(url, callback) { 25189 var manifestLoader = createManifestLoader(); 25190 var self = this; 25191 25192 var handler = function handler(e) { 25193 if (!e.error) { 25194 callback(e.manifest); 25195 } else { 25196 callback(null, e.error); 25197 } 25198 eventBus.off(_coreEventsEvents2['default'].INTERNAL_MANIFEST_LOADED, handler, self); 25199 manifestLoader.reset(); 25200 }; 25201 25202 eventBus.on(_coreEventsEvents2['default'].INTERNAL_MANIFEST_LOADED, handler, self); 25203 25204 var uriQueryFragModel = (0, _modelsURIQueryAndFragmentModel2['default'])(context).getInstance(); 25205 uriQueryFragModel.initialize(); 25206 manifestLoader.load(uriQueryFragModel.parseURI(url)); 25207 } 25208 25209 /** 25210 * Returns the source string or manifest that was attached by calling attachSource() 25211 * @returns {string | manifest} 25212 * @memberof module:MediaPlayer 25213 * @instance 25214 */ 25215 function getSource() { 25216 if (!source) { 25217 throw SOURCE_NOT_ATTACHED_ERROR; 25218 } 25219 return source; 25220 } 25221 25222 /** 25223 * Use this method to set a source URL to a valid MPD manifest file OR 25224 * a previously downloaded and parsed manifest object. Optionally, can 25225 * also provide protection information 25226 * 25227 * @param {string|Object} urlOrManifest - A URL to a valid MPD manifest file, or a 25228 * parsed manifest object. 25229 * 25230 * 25231 * @throws "MediaPlayer not initialized!" 25232 * 25233 * @memberof module:MediaPlayer 25234 * @instance 25235 */ 25236 function attachSource(urlOrManifest) { 25237 if (!mediaPlayerInitialized) { 25238 throw MEDIA_PLAYER_NOT_INITIALIZED_ERROR; 25239 } 25240 25241 if (typeof urlOrManifest === 'string') { 25242 var uriQueryFragModel = (0, _modelsURIQueryAndFragmentModel2['default'])(context).getInstance(); 25243 uriQueryFragModel.initialize(); 25244 source = uriQueryFragModel.parseURI(urlOrManifest); 25245 } else { 25246 source = urlOrManifest; 25247 } 25248 25249 resetAndInitializePlayback(); 25250 } 25251 25252 /** 25253 * A utility methods which converts UTC timestamp value into a valid time and date string. 25254 * 25255 * @param {number} time - UTC timestamp to be converted into date and time. 25256 * @param {string} locales - a region identifier (i.e. en_US). 25257 * @param {boolean} hour12 - 12 vs 24 hour. Set to true for 12 hour time formatting. 25258 * @param {boolean} withDate - default is false. Set to true to append current date to UTC time format. 25259 * @returns {string} A formatted time and date string. 25260 * @memberof module:MediaPlayer 25261 * @instance 25262 */ 25263 function formatUTC(time, locales, hour12) { 25264 var withDate = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3]; 25265 25266 var dt = new Date(time * 1000); 25267 var d = dt.toLocaleDateString(locales); 25268 var t = dt.toLocaleTimeString(locales, { 25269 hour12: hour12 25270 }); 25271 return withDate ? t + ' ' + d : t; 25272 } 25273 25274 /** 25275 * A utility method which converts seconds into TimeCode (i.e. 300 --> 05:00). 25276 * 25277 * @param {number} value - A number in seconds to be converted into a formatted time code. 25278 * @returns {string} A formatted time code string. 25279 * @memberof module:MediaPlayer 25280 * @instance 25281 */ 25282 function convertToTimeCode(value) { 25283 value = Math.max(value, 0); 25284 25285 var h = Math.floor(value / 3600); 25286 var m = Math.floor(value % 3600 / 60); 25287 var s = Math.floor(value % 3600 % 60); 25288 return (h === 0 ? '' : h < 10 ? '0' + h.toString() + ':' : h.toString() + ':') + (m < 10 ? '0' + m.toString() : m.toString()) + ':' + (s < 10 ? '0' + s.toString() : s.toString()); 25289 } 25290 25291 /** 25292 * This method should be used to extend or replace internal dash.js objects. 25293 * There are two ways to extend dash.js (determined by the override argument): 25294 * <ol> 25295 * <li>If you set override to true any public method or property in your custom object will 25296 * override the dash.js parent object's property(ies) and will be used instead but the 25297 * dash.js parent module will still be created.</li> 25298 * 25299 * <li>If you set override to false your object will completely replace the dash.js object.
25300 * (Note: This is how it was in 1.x of Dash.js with Dijon).</li> 25301 * </ol> 25302 * <b>When you extend you get access to this.context, this.factory and this.parent to operate with in your custom object.</b> 25303 * <ul> 25304 * <li><b>this.context</b> - can be used to pass context for singleton access.</li> 25305 * <li><b>this.factory</b> - can be used to call factory.getSingletonInstance().</li> 25306 * <li><b>this.parent</b> - is the reference of the parent object to call other public methods. (this.parent is excluded if you extend with override set to false or option 2)</li> 25307 * </ul> 25308 * <b>You must call extend before you call initialize</b> 25309 * @see {@link module:MediaPlayer#initialize initialize()} 25310 * @param {string} parentNameString - name of parent module 25311 * @param {Object} childInstance - overriding object 25312 * @param {boolean} override - replace only some methods (true) or the whole object (false) 25313 * @memberof module:MediaPlayer 25314 * @instance 25315 */ 25316 function extend(parentNameString, childInstance, override) { 25317 _coreFactoryMaker2['default'].extend(parentNameString, childInstance, override, context); 25318 } 25319 25320 /* 25321 --------------------------------------------------------------------------- 25322 DEPRECATED FUNCTIONS 25323 --------------------------------------------------------------------------- 25324 */ 25325 /** 25326 * @deprecated Since version 2.1.0. <b>Instead use:</b> 25327 * <ul> 25328 * <li>{@link module:MediaPlayer#getVideoElement getVideoElement()}</li> 25329 * <li>{@link module:MediaPlayer#getSource getSource()}</li> 25330 * <li>{@link module:MediaPlayer#getVideoContainer getVideoContainer()}</li> 25331 * <li>{@link module:MediaPlayer#getTTMLRenderingDiv getTTMLRenderingDiv()}</li> 25332 * </ul> 25333 * 25334 * @returns {VideoModel} 25335 * @memberof module:MediaPlayer 25336 * @instance 25337 */ 25338 function getVideoModel() { 25339 if (!videoModel) { 25340 throw ELEMENT_NOT_ATTACHED_ERROR; 25341 } 25342 return videoModel; 25343 } 25344 25345 /** 25346 * @deprecated since version 2.0 Instead use {@link module:MediaPlayer#getAutoSwitchQualityFor getAutoSwitchQualityFor()}. 25347 * @returns {boolean} Current state of adaptive bitrate switching 25348 * @memberof module:MediaPlayer 25349 * @instance 25350 */ 25351 function getAutoSwitchQuality() { 25352 return abrController.getAutoSwitchBitrateFor(_constantsConstants2['default'].VIDEO) || abrController.getAutoSwitchBitrateFor(_constantsConstants2['default'].AUDIO); 25353 } 25354 25355 /** 25356 * Set to false to switch off adaptive bitrate switching. 25357 * 25358 * @deprecated since version 2.0 Instead use {@link module:MediaPlayer#setAutoSwitchQualityFor setAutoSwitchQualityFor()}. 25359 * @param {boolean} value 25360 * @default true 25361 * @memberof module:MediaPlayer 25362 * @instance 25363 */ 25364 function setAutoSwitchQuality(value) { 25365 abrController.setAutoSwitchBitrateFor(_constantsConstants2['default'].VIDEO, value); 25366 abrController.setAutoSwitchBitrateFor(_constantsConstants2['default'].AUDIO, value); 25367 } 25368 25369 /** 25370 * Sets whether withCredentials on all XHR requests is true or false 25371 * @default false 25372 * @param {boolean} value 25373 * @memberof module:MediaPlayer 25374 * @instance 25375 * @deprecated since version 2.4 - use setXHRWithCredentialsForType 25376 */ 25377 function setXHRWithCredentials(value) { 25378 setXHRWithCredentialsForType(undefined, value); 25379 } 25380 25381 //*********************************** 25382 // PRIVATE METHODS 25383 //*********************************** 25384 25385 function resetAndInitializePlayback() { 25386 if (playbackInitialized) { 25387 playbackInitialized = false; 25388 adapter.reset(); 25389 streamController.reset(); 25390 playbackController.reset(); 25391 abrController.reset(); 25392 mediaController.reset(); 25393 textController.reset(); 25394 if (protectionController) { 25395 protectionController.reset(); 25396 protectionController = null; 25397 detectProtection(); 25398 } 25399 if (isReady()) { 25400 initializePlayback(); 25401 } 25402 } else if (isReady()) { 25403 initializePlayback(); 25404 } 25405 } 25406 25407 function createPlaybackControllers() { 25408 25409 // creates or get objects instances 25410 var manifestLoader = createManifestLoader(); 25411 25412 var sourceBufferController = (0, _controllersSourceBufferController2['default'])(context).getInstance({ 25413 textController: textController 25414 }); 25415 25416 if (!streamController) { 25417 streamController = (0, _controllersStreamController2['default'])(context).getInstance(); 25418 } 25419 25420 // configure controllers 25421 mediaController.setConfig({ 25422 errHandler: errHandler, 25423 domStorage: domStorage 25424 }); 25425 25426 streamController.setConfig({ 25427 capabilities: capabilities, 25428 manifestLoader: manifestLoader, 25429 manifestModel: manifestModel, 25430 dashManifestModel: dashManifestModel, 25431 mediaPlayerModel: mediaPlayerModel, 25432 protectionController: protectionController, 25433 adapter: adapter, 25434 metricsModel: metricsModel, 25435 dashMetrics: dashMetrics, 25436 errHandler: errHandler, 25437 timelineConverter: timelineConverter, 25438 videoModel: videoModel, 25439 playbackController: playbackController, 25440 domStorage: domStorage, 25441 abrController: abrController, 25442 mediaController: mediaController, 25443 textController: textController, 25444 sourceBufferController: sourceBufferController 25445 }); 25446 25447 playbackController.setConfig({ 25448 streamController: streamController, 25449 metricsModel: metricsModel, 25450 dashMetrics: dashMetrics, 25451 manifestModel: manifestModel, 25452 mediaPlayerModel: mediaPlayerModel, 25453 dashManifestModel: dashManifestModel, 25454 adapter: adapter, 25455 videoModel: videoModel 25456 }); 25457 25458 abrController.setConfig({ 25459 streamController: streamController, 25460 domStorage: domStorage, 25461 mediaPlayerModel: mediaPlayerModel, 25462 metricsModel: metricsModel, 25463 dashMetrics: dashMetrics, 25464 dashManifestModel: dashManifestModel, 25465 manifestModel: manifestModel, 25466 videoModel: videoModel, 25467 adapter: adapter 25468 }); 25469 abrController.createAbrRulesCollection(); 25470 25471 textController.setConfig({ 25472 errHandler: errHandler, 25473 manifestModel: manifestModel, 25474 dashManifestModel: dashManifestModel, 25475 mediaController: mediaController, 25476 streamController: streamController, 25477 videoModel: videoModel 25478 }); 25479 // initialises controller 25480 streamController.initialize(autoPlay, protectionData); 25481 } 25482 25483 function createManifestLoader() { 25484 return (0, _ManifestLoader2['default'])(context).create({ 25485 errHandler: errHandler, 25486 metricsModel: metricsModel, 25487 mediaPlayerModel: mediaPlayerModel, 25488 requestModifier: (0, _utilsRequestModifier2['default'])(context).getInstance(), 25489 mssHandler: mssHandler 25490 }); 25491 } 25492 25493 function detectProtection() { 25494 if (protectionController) { 25495 return protectionController; 25496 } 25497 // do not require Protection as dependencies as this is optional and intended to be loaded separately 25498 var Protection = dashjs.Protection; /* jshint ignore:line */ 25499 if (typeof Protection === 'function') { 25500 //TODO need a better way to register/detect plugin components 25501 var protection = Protection(context).create(); 25502 _coreEventsEvents2['default'].extend(Protection.events); 25503 _MediaPlayerEvents2['default'].extend(Protection.events, { 25504 publicOnly: true 25505 }); 25506 protectionController = protection.createProtectionSystem({ 25507 log: log, 25508 errHandler: errHandler, 25509 videoModel: videoModel, 25510 capabilities: capabilities, 25511 eventBus: eventBus, 25512 adapter: adapter, 25513 events: _coreEventsEvents2['default'], 25514 BASE64: _externalsBase642['default'], 25515 constants: _constantsConstants2['default'] 25516 }); 25517 return protectionController; 25518 } 25519 25520 return null; 25521 } 25522 25523 function detectMetricsReporting() { 25524 if (metricsReportingController) { 25525 return; 25526 } 25527 // do not require MetricsReporting as dependencies as this is optional and intended to be loaded separately 25528 var MetricsReporting = dashjs.MetricsReporting; /* jshint ignore:line */ 25529 if (typeof MetricsReporting === 'function') { 25530 //TODO need a better way to register/detect plugin components 25531 var metricsReporting = MetricsReporting(context).create(); 25532 25533 metricsReportingController = metricsReporting.createMetricsReporting({ 25534 log: log, 25535 eventBus: eventBus, 25536 mediaElement: getVideoElement(), 25537 dashManifestModel: dashManifestModel, 25538 metricsModel: metricsModel, 25539 events: _coreEventsEvents2['default'], 25540 constants: _constantsConstants2['default'], 25541 metricsConstants: _constantsMetricsConstants2['default'] 25542 }); 25543 } 25544 } 25545 25546 function detectMss() { 25547 if (mssHandler) { 25548 return; 25549 } 25550 // do not require MssHandler as dependencies as this is optional and intended to be loaded separately 25551 var MssHandler = dashjs.MssHandler; /* jshint ignore:line */ 25552 if (typeof MssHandler === 'function') { 25553 //TODO need a better way to register/detect plugin components 25554 mssHandler = MssHandler(context).create({ 25555 eventBus: eventBus, 25556 mediaPlayerModel: mediaPlayerModel, 25557 metricsModel: metricsModel, 25558 playbackController: playbackController, 25559 protectionController: protectionController, 25560 errHandler: errHandler, 25561 events: _coreEventsEvents2['default'], 25562 constants: _constantsConstants2['default'], 25563 log: log, 25564 initSegmentType: _voMetricsHTTPRequest.HTTPRequest.INIT_SEGMENT_TYPE, 25565 BASE64: _externalsBase642['default'], 25566 ISOBoxer: _codemIsoboxer2['default'] 25567 }); 25568 } 25569 } 25570 25571 function getDVRInfoMetric() {
25572 var metric = metricsModel.getReadOnlyMetricsFor(_constantsConstants2['default'].VIDEO) || metricsModel.getReadOnlyMetricsFor(_constantsConstants2['default'].AUDIO); 25573 return dashMetrics.getCurrentDVRInfo(metric); 25574 } 25575 25576 function getAsUTC(valToConvert) { 25577 var metric = getDVRInfoMetric(); 25578 var availableFrom = undefined, 25579 utcValue = undefined; 25580 25581 if (!metric) { 25582 return 0; 25583 } 25584 availableFrom = metric.manifestInfo.availableFrom.getTime() / 1000; 25585 utcValue = valToConvert + (availableFrom + metric.range.start); 25586 return utcValue; 25587 } 25588 25589 function getActiveStream() { 25590 if (!playbackInitialized) { 25591 throw PLAYBACK_NOT_INITIALIZED_ERROR; 25592 } 25593 var streamInfo = streamController.getActiveStreamInfo(); 25594 return streamInfo ? streamController.getStreamById(streamInfo.id) : null; 25595 } 25596 25597 function initializePlayback() { 25598 if (!playbackInitialized) { 25599 createPlaybackControllers(); 25600 25601 playbackInitialized = true; 25602 log('Playback Initialized'); 25603 25604 if (typeof source === 'string') { 25605 streamController.load(source); 25606 } else { 25607 streamController.loadWithManifest(source); 25608 } 25609 } 25610 } 25611 25612 instance = { 25613 initialize: initialize, 25614 setConfig: setConfig, 25615 on: on, 25616 off: off, 25617 extend: extend, 25618 attachView: attachView, 25619 attachSource: attachSource, 25620 isReady: isReady, 25621 play: play, 25622 isPaused: isPaused, 25623 pause: pause, 25624 isSeeking: isSeeking, 25625 isDynamic: isDynamic, 25626 seek: seek, 25627 setPlaybackRate: setPlaybackRate, 25628 getPlaybackRate: getPlaybackRate, 25629 setMute: setMute, 25630 isMuted: isMuted, 25631 setVolume: setVolume, 25632 getVolume: getVolume, 25633 time: time, 25634 duration: duration, 25635 timeAsUTC: timeAsUTC, 25636 durationAsUTC: durationAsUTC, 25637 getActiveStream: getActiveStream, 25638 getDVRWindowSize: getDVRWindowSize, 25639 getDVRSeekOffset: getDVRSeekOffset, 25640 convertToTimeCode: convertToTimeCode, 25641 formatUTC: formatUTC, 25642 getVersion: getVersion, 25643 getDebug: getDebug, 25644 getBufferLength: getBufferLength, 25645 getVideoModel: getVideoModel, 25646 getVideoContainer: getVideoContainer, 25647 getTTMLRenderingDiv: getTTMLRenderingDiv, 25648 getVideoElement: getVideoElement, 25649 getSource: getSource, 25650 setLiveDelayFragmentCount: setLiveDelayFragmentCount, 25651 setLiveDelay: setLiveDelay, 25652 getLiveDelay: getLiveDelay, 25653 useSuggestedPresentationDelay: useSuggestedPresentationDelay, 25654 enableLastBitrateCaching: enableLastBitrateCaching, 25655 enableLastMediaSettingsCaching: enableLastMediaSettingsCaching, 25656 setMaxAllowedBitrateFor: setMaxAllowedBitrateFor, 25657 getMaxAllowedBitrateFor: getMaxAllowedBitrateFor, 25658 setMinAllowedBitrateFor: setMinAllowedBitrateFor, 25659 getMinAllowedBitrateFor: getMinAllowedBitrateFor, 25660 setMaxAllowedRepresentationRatioFor: setMaxAllowedRepresentationRatioFor, 25661 getMaxAllowedRepresentationRatioFor: getMaxAllowedRepresentationRatioFor, 25662 setAutoPlay: setAutoPlay, 25663 getAutoPlay: getAutoPlay, 25664 setScheduleWhilePaused: setScheduleWhilePaused, 25665 getScheduleWhilePaused: getScheduleWhilePaused, 25666 getDashMetrics: getDashMetrics, 25667 getMetricsFor: getMetricsFor, 25668 getQualityFor: getQualityFor, 25669 setQualityFor: setQualityFor, 25670 updatePortalSize: updatePortalSize, 25671 getLimitBitrateByPortal: getLimitBitrateByPortal, 25672 setLimitBitrateByPortal: setLimitBitrateByPortal, 25673 getUsePixelRatioInLimitBitrateByPortal: getUsePixelRatioInLimitBitrateByPortal, 25674 setUsePixelRatioInLimitBitrateByPortal: setUsePixelRatioInLimitBitrateByPortal, 25675 setTextTrack: setTextTrack, 25676 getBitrateInfoListFor: getBitrateInfoListFor, 25677 setInitialBitrateFor: setInitialBitrateFor, 25678 getInitialBitrateFor: getInitialBitrateFor, 25679 setInitialRepresentationRatioFor: setInitialRepresentationRatioFor, 25680 getInitialRepresentationRatioFor: getInitialRepresentationRatioFor, 25681 getStreamsFromManifest: getStreamsFromManifest, 25682 getTracksFor: getTracksFor, 25683 getTracksForTypeFromManifest: getTracksForTypeFromManifest, 25684 getCurrentTrackFor: getCurrentTrackFor, 25685 setInitialMediaSettingsFor: setInitialMediaSettingsFor, 25686 getInitialMediaSettingsFor: getInitialMediaSettingsFor, 25687 setCurrentTrack: setCurrentTrack, 25688 getTrackSwitchModeFor: getTrackSwitchModeFor, 25689 setTrackSwitchModeFor: setTrackSwitchModeFor, 25690 setSelectionModeForInitialTrack: setSelectionModeForInitialTrack, 25691 getSelectionModeForInitialTrack: getSelectionModeForInitialTrack, 25692 getAutoSwitchQuality: getAutoSwitchQuality, 25693 setAutoSwitchQuality: setAutoSwitchQuality, 25694 setFastSwitchEnabled: setFastSwitchEnabled, 25695 getFastSwitchEnabled: getFastSwitchEnabled, 25696 setMovingAverageMethod: setMovingAverageMethod, 25697 getMovingAverageMethod: getMovingAverageMethod, 25698 getAutoSwitchQualityFor: getAutoSwitchQualityFor, 25699 setAutoSwitchQualityFor: setAutoSwitchQualityFor, 25700 enableBufferOccupancyABR: enableBufferOccupancyABR, 25701 setABRStrategy: setABRStrategy, 25702 getABRStrategy: getABRStrategy, 25703 useDefaultABRRules: useDefaultABRRules, 25704 addABRCustomRule: addABRCustomRule, 25705 removeABRCustomRule: removeABRCustomRule, 25706 removeAllABRCustomRule: removeAllABRCustomRule, 25707 setBandwidthSafetyFactor: setBandwidthSafetyFactor, 25708 getBandwidthSafetyFactor: getBandwidthSafetyFactor, 25709 getAverageThroughput: getAverageThroughput, 25710 setAbandonLoadTimeout: setAbandonLoadTimeout, 25711 retrieveManifest: retrieveManifest, 25712 addUTCTimingSource: addUTCTimingSource, 25713 removeUTCTimingSource: removeUTCTimingSource, 25714 clearDefaultUTCTimingSources: clearDefaultUTCTimingSources, 25715 restoreDefaultUTCTimingSources: restoreDefaultUTCTimingSources, 25716 setBufferToKeep: setBufferToKeep, 25717 setBufferPruningInterval: setBufferPruningInterval, 25718 setStableBufferTime: setStableBufferTime, 25719 getStableBufferTime: getStableBufferTime, 25720 setBufferTimeAtTopQuality: setBufferTimeAtTopQuality, 25721 getBufferTimeAtTopQuality: getBufferTimeAtTopQuality, 25722 setBufferTimeAtTopQualityLongForm: setBufferTimeAtTopQualityLongForm, 25723 getBufferTimeAtTopQualityLongForm: getBufferTimeAtTopQualityLongForm, 25724 setFragmentLoaderRetryAttempts: setFragmentLoaderRetryAttempts, 25725 setFragmentLoaderRetryInterval: setFragmentLoaderRetryInterval, 25726 setManifestLoaderRetryAttempts: setManifestLoaderRetryAttempts, 25727 setManifestLoaderRetryInterval: setManifestLoaderRetryInterval, 25728 setXHRWithCredentials: setXHRWithCredentials, 25729 setXHRWithCredentialsForType: setXHRWithCredentialsForType, 25730 getXHRWithCredentialsForType: getXHRWithCredentialsForType, 25731 setLongFormContentDurationThreshold: setLongFormContentDurationThreshold, 25732 setRichBufferThreshold: setRichBufferThreshold, 25733 getProtectionController: getProtectionController, 25734 attachProtectionController: attachProtectionController, 25735 setProtectionData: setProtectionData, 25736 enableManifestDateHeaderTimeSource: enableManifestDateHeaderTimeSource, 25737 displayCaptionsOnTop: displayCaptionsOnTop, 25738 attachVideoContainer: attachVideoContainer, 25739 attachTTMLRenderingDiv: attachTTMLRenderingDiv, 25740 getCurrentTextTrackIndex: getCurrentTextTrackIndex, 25741 getUseDeadTimeLatencyForAbr: getUseDeadTimeLatencyForAbr, 25742 setUseDeadTimeLatencyForAbr: setUseDeadTimeLatencyForAbr, 25743 reset: reset 25744 }; 25745 25746 setup(); 25747 25748 return instance; 25749} 25750 25751MediaPlayer.__dashjs_factory_name = 'MediaPlayer'; 25752var factory = _coreFactoryMaker2['default'].getClassFactory(MediaPlayer); 25753factory.events = _MediaPlayerEvents2['default']; 25754_coreFactoryMaker2['default'].updateClassFactory(MediaPlayer.__dashjs_factory_name, factory); 25755 25756exports['default'] = factory; 25757module.exports = exports['default']; 25758 25759},{"1":1,"100":100,"101":101,"102":102,"108":108,"11":11,"110":110,"112":112,"113":113,"141":141,"142":142,"143":143,"144":144,"145":145,"186":186,"188":188,"191":191,"193":193,"195":195,"200":200,"224":224,"49":49,"50":50,"51":51,"52":52,"54":54,"56":56,"58"
vendor: 12,298 bytes, lines 25759-26058
25759:58,"63":63,"79":79,"89":89,"91":91,"94":94}],94:[function(_dereq_,module,exports){ 25760/** 25761 * The copyright in this software is being made available under the BSD License, 25762 * included below. This software may be subject to other third party and contributor 25763 * rights, including patent rights, and no such rights are granted under this license. 25764 * 25765 * Copyright (c) 2013, Dash Industry Forum. 25766 * All rights reserved. 25767 * 25768 * Redistribution and use in source and binary forms, with or without modification, 25769 * are permitted provided that the following conditions are met: 25770 * * Redistributions of source code must retain the above copyright notice, this 25771 * list of conditions and the following disclaimer. 25772 * * Redistributions in binary form must reproduce the above copyright notice, 25773 * this list of conditions and the following disclaimer in the documentation and/or 25774 * other materials provided with the distribution. 25775 * * Neither the name of Dash Industry Forum nor the names of its 25776 * contributors may be used to endorse or promote products derived from this software 25777 * without specific prior written permission. 25778 * 25779 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 25780 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25781 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25782 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25783 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25784 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25785 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25786 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25787 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25788 * POSSIBILITY OF SUCH DAMAGE. 25789 */ 25790'use strict'; 25791 25792Object.defineProperty(exports, '__esModule', { 25793 value: true 25794}); 25795 25796var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 25797 25798function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 25799 25800function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 25801 25802function _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; } 25803 25804var _coreEventsEventsBase = _dereq_(55); 25805 25806var _coreEventsEventsBase2 = _interopRequireDefault(_coreEventsEventsBase); 25807 25808/** 25809 * @class 25810 * 25811 */ 25812 25813var MediaPlayerEvents = (function (_EventsBase) { 25814 _inherits(MediaPlayerEvents, _EventsBase); 25815 25816 /** 25817 * @description Public facing external events to be used when developing a player that implements dash.js. 25818 */ 25819 25820 function MediaPlayerEvents() { 25821 _classCallCheck(this, MediaPlayerEvents); 25822 25823 _get(Object.getPrototypeOf(MediaPlayerEvents.prototype), 'constructor', this).call(this); 25824 /** 25825 * Triggered when playback will not start yet 25826 * as the MPD's availabilityStartTime is in the future. 25827 * Check delay property in payload to determine time before playback will start. 25828 */ 25829 this.AST_IN_FUTURE = 'astInFuture'; 25830 /** 25831 * Triggered when the video element's buffer state changes to stalled. 25832 * Check mediaType in payload to determine type (Video, Audio, FragmentedText). 25833 * @event MediaPlayerEvents#BUFFER_EMPTY 25834 */ 25835 this.BUFFER_EMPTY = 'bufferStalled'; 25836 /** 25837 * Triggered when the video element's buffer state changes to loaded. 25838 * Check mediaType in payload to determine type (Video, Audio, FragmentedText). 25839 * @event MediaPlayerEvents#BUFFER_LOADED 25840 */ 25841 this.BUFFER_LOADED = 'bufferLoaded'; 25842 25843 /** 25844 * Triggered when the video element's buffer state changes, either stalled or loaded. Check payload for state. 25845 * @event MediaPlayerEvents#BUFFER_LEVEL_STATE_CHANGED 25846 */ 25847 this.BUFFER_LEVEL_STATE_CHANGED = 'bufferStateChanged'; 25848 25849 /** 25850 * Triggered when there is an error from the element or MSE source buffer. 25851 * @event MediaPlayerEvents#ERROR 25852 */ 25853 this.ERROR = 'error'; 25854 25855 /** 25856 * Triggered when a fragment download has completed. 25857 * @event MediaPlayerEvents#FRAGMENT_LOADING_COMPLETED 25858 */ 25859 this.FRAGMENT_LOADING_COMPLETED = 'fragmentLoadingCompleted'; 25860 /** 25861 * Triggered when a fragment download has started. 25862 * @event MediaPlayerEvents#FRAGMENT_LOADING_STARTED 25863 */ 25864 this.FRAGMENT_LOADING_STARTED = 'fragmentLoadingStarted'; 25865 /** 25866 * Triggered when a fragment download is abandoned due to detection of slow download base on the ABR abandon rule.. 25867 * @event MediaPlayerEvents#FRAGMENT_LOADING_ABANDONED 25868 */ 25869 this.FRAGMENT_LOADING_ABANDONED = 'fragmentLoadingAbandoned'; 25870 /** 25871 * Triggered when {@link module:Debug} log method is called. 25872 * @event MediaPlayerEvents#LOG 25873 */ 25874 this.LOG = 'log'; 25875 //TODO refactor with internal event 25876 /** 25877 * Triggered when the manifest load is complete 25878 * @event MediaPlayerEvents#MANIFEST_LOADED 25879 */ 25880 this.MANIFEST_LOADED = 'manifestLoaded'; 25881 /** 25882 * Triggered anytime there is a change to the overall metrics. 25883 * @event MediaPlayerEvents#METRICS_CHANGED 25884 */ 25885 this.METRICS_CHANGED = 'metricsChanged'; 25886 /** 25887 * Triggered when an individual metric is added, updated or cleared. 25888 * @event MediaPlayerEvents#METRIC_CHANGED 25889 */ 25890 this.METRIC_CHANGED = 'metricChanged'; 25891 /** 25892 * Triggered every time a new metric is added. 25893 * @event MediaPlayerEvents#METRIC_ADDED 25894 */ 25895 this.METRIC_ADDED = 'metricAdded'; 25896 /** 25897 * Triggered every time a metric is updated. 25898 * @event MediaPlayerEvents#METRIC_UPDATED 25899 */ 25900 this.METRIC_UPDATED = 'metricUpdated'; 25901 /** 25902 * Triggered at the stream end of a period. 25903 * @event MediaPlayerEvents#PERIOD_SWITCH_COMPLETED 25904 */ 25905 this.PERIOD_SWITCH_COMPLETED = 'periodSwitchCompleted'; 25906 /** 25907 * Triggered when a new period starts. 25908 * @event MediaPlayerEvents#PERIOD_SWITCH_STARTED 25909 */ 25910 this.PERIOD_SWITCH_STARTED = 'periodSwitchStarted'; 25911 25912 /** 25913 * Triggered when an ABR up /down switch is initialed; either by user in manual mode or auto mode via ABR rules. 25914 * @event MediaPlayerEvents#QUALITY_CHANGE_REQUESTED 25915 */ 25916 this.QUALITY_CHANGE_REQUESTED = 'qualityChangeRequested'; 25917 25918 /** 25919 * Triggered when the new ABR quality is being rendered on-screen. 25920 * @event MediaPlayerEvents#QUALITY_CHANGE_RENDERED 25921 */ 25922 this.QUALITY_CHANGE_RENDERED = 'qualityChangeRendered'; 25923 25924 /** 25925 * Triggered when the stream is setup and ready. 25926 * @event MediaPlayerEvents#STREAM_INITIALIZED 25927 */ 25928 this.STREAM_INITIALIZED = 'streamInitialized'; 25929 25930 /** 25931 * Triggered when the player has been reset. 25932 * @event MediaPlayerEvents#STREAM_TEARDOWN_COMPLETE 25933 */ 25934 this.STREAM_TEARDOWN_COMPLETE = 'streamTeardownComplete'; 25935 25936 /** 25937 * Triggered once all text tracks detected in the MPD are added to the video element. 25938 * @event MediaPlayerEvents#TEXT_TRACKS_ADDED 25939 */ 25940 this.TEXT_TRACKS_ADDED = 'allTextTracksAdded'; 25941 /** 25942 * Triggered when a text track is added to the video element's TextTrackList 25943 * @event MediaPlayerEvents#TEXT_TRACK_ADDED 25944 */ 25945 this.TEXT_TRACK_ADDED = 'textTrackAdded'; 25946 25947 /** 25948 * Sent when enough data is available that the media can be played, 25949 * at least for a couple of frames. This corresponds to the 25950 * HAVE_ENOUGH_DATA readyState. 25951 * @event MediaPlayerEvents#CAN_PLAY 25952 */ 25953 this.CAN_PLAY = 'canPlay'; 25954 25955 /** 25956 * Sent when playback completes. 25957 * @event MediaPlayerEvents#PLAYBACK_ENDED 25958 */ 25959 this.PLAYBACK_ENDED = 'playbackEnded'; 25960 25961 /** 25962 * Sent when an error occurs. The element's error 25963 * attribute contains more information. 25964 * @event MediaPlayerEvents#PLAYBACK_ERROR 25965 */ 25966 this.PLAYBACK_ERROR = 'playbackError'; 25967 /** 25968 * Sent when playback is not allowed (for example if user gesture is needed). 25969 * @event MediaPlayerEvents#PLAYBACK_NOT_ALLOWED 25970 */ 25971 this.PLAYBACK_NOT_ALLOWED = 'playbackNotAllowed'; 25972 /** 25973 * The media's metadata has finished loading; all attributes now 25974 * contain as much useful information as they're going to. 25975 * @event MediaPlayerEvents#PLAYBACK_METADATA_LOADED 25976 */ 25977 this.PLAYBACK_METADATA_LOADED = 'playbackMetaDataLoaded'; 25978 /** 25979 * Sent when playback is paused. 25980 * @event MediaPlayerEvents#PLAYBACK_PAUSED 25981 */ 25982 this.PLAYBACK_PAUSED = 'playbackPaused'; 25983 /** 25984 * Sent when the media begins to play (either for the first time, after having been paused, 25985 * or after ending and then restarting). 25986 * 25987 * @event MediaPlayerEvents#PLAYBACK_PLAYING 25988 */ 25989 this.PLAYBACK_PLAYING = 'playbackPlaying'; 25990 /** 25991 * Sent periodically to inform interested parties of progress downloading 25992 * the media. Information about the current amount of the media that has 25993 * been downloaded is available in the media element's buffered attribute. 25994 * @event MediaPlayerEvents#PLAYBACK_PROGRESS 25995 */ 25996 this.PLAYBACK_PROGRESS = 'playbackProgress'; 25997 /** 25998 * Sent when the playback speed changes. 25999 * @event MediaPlayerEvents#PLAYBACK_RATE_CHANGED 26000 */ 26001 this.PLAYBACK_RATE_CHANGED = 'playbackRateChanged'; 26002 /** 26003 * Sent when a seek operation completes. 26004 * @event MediaPlayerEvents#PLAYBACK_SEEKED 26005 */ 26006 this.PLAYBACK_SEEKED = 'playbackSeeked'; 26007 /** 26008 * Sent when a seek operation begins. 26009 * @event MediaPlayerEvents#PLAYBACK_SEEKING 26010 */ 26011 this.PLAYBACK_SEEKING = 'playbackSeeking'; 26012 26013 /** 26014 * Sent when a seek operation has been asked. 26015 * @event MediaPlayerEvents#PLAYBACK_SEEK_ASKED 26016 */ 26017 this.PLAYBACK_SEEK_ASKED = 'playbackSeekAsked'; 26018 26019 /** 26020 * Sent when playback of the media starts after having been paused; 26021 * that is, when playback is resumed after a prior pause event. 26022 * 26023 * @event MediaPlayerEvents#PLAYBACK_STARTED 26024 */ 26025 this.PLAYBACK_STARTED = 'playbackStarted'; 26026 /** 26027 * The time indicated by the element's currentTime attribute has changed. 26028 * @event MediaPlayerEvents#PLAYBACK_TIME_UPDATED 26029 */ 26030 this.PLAYBACK_TIME_UPDATED = 'playbackTimeUpdated'; 26031 } 26032 26033 return MediaPlayerEvents; 26034})(_coreEventsEventsBase2['default']); 26035 26036var mediaPlayerEvents = new MediaPlayerEvents(); 26037exports['default'] = mediaPlayerEvents; 26038module.exports = exports['default']; 26039 26040},{"55":55}],95:[function(_dereq_,module,exports){ 26041'use strict'; 26042 26043Object.defineProperty(exports, '__esModule', { 26044 value: true 26045}); 26046 26047function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 26048 26049var _MediaPlayer = _dereq_(93); 26050 26051var _MediaPlayer2 = _interopRequireDefault(_MediaPlayer); 26052 26053function MediaPlayerFactory() { 26054 26055 /** 26056 * mime-type identifier for any source content to be accepted as a dash manifest by the create() method. 26057 * @type {string} 26058 */
26059 var SUPPORTED_MIME_TYPE = 'application/dash+xml'; 26060 26061 /** 26062 * A new MediaPlayer is instantiated for the supplied videoElement and optional source and context. If no context is provided, 26063 * a default DashContext is used. If no source is provided, the videoElement is interrogated to extract the first source whose 26064 * type is application/dash+xml. 26065 * The autoplay property of the videoElement is preserved. Any preload attribute is ignored. This method should be called after the page onLoad event is dispatched. 26066 * @param {HTMLMediaElement} video 26067 * @param {HTMLSourceElement} source 26068 * @param {Object} context 26069 * @returns {MediaPlayer|null} 26070 */ 26071 function create(video, source, context) { 26072 if (!video || video.nodeName !== 'VIDEO') return null; 26073 26074 if (video._dashjs_player) return video._dashjs_player; 26075 26076 var player = undefined; 26077 var videoID = video.id || video.name || 'video element'; 26078 26079 source = source || [].slice.call(video.querySelectorAll('source')).filter(function (s) { 26080 return s.type == SUPPORTED_MIME_TYPE; 26081 })[0]; 26082 if (!source && video.src) { 26083 source = document.createElement('source'); 26084 source.src = video.src; 26085 } else if (!source && !video.src) { 26086 return null; 26087 } 26088 26089 context = context || {}; 26090 player = (0, _MediaPlayer2['default'])(context).create(); 26091 player.initialize(video, source.src, video.autoplay); 26092 player.getDebug().log('Converted ' + videoID + ' to dash.js player and added content: ' + source.src); 26093 26094 // Store a reference to the player on the video element so it can be gotten at for debugging and so we know its 26095 // already been setup. 26096 video._dashjs_player = player; 26097 26098 return player; 26099 } 26100 26101 /** 26102 * Searches the provided scope for all instances of the indicated selector. If no scope is provided, document is used. If no selector is 26103 * specified, [data-dashjs-player] is used. The declarative setup also looks for source elements with the type attribute set to 'application/dash+xml'. 26104 * It then looks for those video elements which have a source element defined with a type matching 'application/dash+xml'. 26105 * A new MediaPlayer is instantiated for each matching video element and the appropriate source is assigned. 26106 * The autoplay property of the video element is preserved. Any preload attribute is ignored. This method should be called after the page onLoad event is dispatched. 26107 * Returns an array holding all the MediaPlayer instances that were added by this method. 26108 * @param {string} selector - CSS selector 26109 * @param {Object} scope 26110 * @returns {Array} an array of MediaPlayer objects 26111 */ 26112 function createAll(selector, scope) { 26113 var aPlayers = []; 26114 selector = selector || '[data-dashjs-player]'; 26115 scope = scope || document; 26116 var videos = scope.querySelectorAll(selector); 26117 for (var i = 0; i < videos.length; i++) { 26118 var player = create(videos[i], null); 26119 aPlayers.push(player); 26120 } 26121 26122 var sources = scope.querySelectorAll('source[type="' + SUPPORTED_MIME_TYPE + '"]'); 26123 for (var i = 0; i < sources.length; i++) { 26124 var video = findVideo(sources[i]); 26125 var player = create(video, null); 26126 aPlayers.push(player); 26127 } 26128 26129 return aPlayers; 26130 } 26131 26132 function findVideo(_x) { 26133 var _again = true; 26134 26135 _function: while (_again) { 26136 var el = _x; 26137 _again = false; 26138 26139 if (el.nodeName.toLowerCase() === 'video') { 26140 return el; 26141 } else { 26142 _x = el.parentNode; 26143 _again = true; 26144 continue _function; 26145 } 26146 } 26147 } 26148 26149 return { 26150 create: create, 26151 createAll: createAll 26152 }; 26153} 26154 26155var instance = MediaPlayerFactory(); 26156var loadInterval = undefined; 26157 26158function loadHandler() { 26159 window.removeEventListener('load', loadHandler); 26160 instance.createAll(); 26161} 26162 26163function loadIntervalHandler() { 26164 if (window.dashjs) { 26165 window.clearInterval(loadInterval); 26166 instance.createAll(); 26167 } 26168} 26169 26170var avoidAutoCreate = typeof window !== 'undefined' && window && window.dashjs && window.dashjs.skipAutoCreate; 26171 26172if (!avoidAutoCreate && typeof window !== 'undefined' && window && window.addEventListener) { 26173 if (window.document.readyState === 'complete') { 26174 if (window.dashjs) { 26175 instance.createAll(); 26176 } else { 26177 // If loaded asynchronously, window.readyState may be 'complete' even if dashjs hasn't loaded yet 26178 loadInterval = window.setInterval(loadIntervalHandler, 500); 26179 } 26180 } else { 26181 window.addEventListener('load', loadHandler); 26182 } 26183} 26184 26185exports['default'] = instance; 26186module.exports = exports['default']; 26187 26188},{"93":93}],96:[function(_dereq_,module,exports){ 26189/** 26190 * The copyright in this software is being made available under the BSD License, 26191 * included below. This software may be subject to other third party and contributor 26192 * rights, including patent rights, and no such rights are granted under this license. 26193 * 26194 * Copyright (c) 2013, Dash Industry Forum. 26195 * All rights reserved. 26196 * 26197 * Redistribution and use in source and binary forms, with or without modification, 26198 * are permitted provided that the following conditions are met: 26199 * * Redistributions of source code must retain the above copyright notice, this 26200 * list of conditions and the following disclaimer. 26201 * * Redistributions in binary form must reproduce the above copyright notice, 26202 * this list of conditions and the following disclaimer in the documentation and/or 26203 * other materials provided with the distribution. 26204 * * Neither the name of Dash Industry Forum nor the names of its 26205 * contributors may be used to endorse or promote products derived from this software 26206 * without specific prior written permission. 26207 * 26208 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 26209 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26210 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26211 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26212 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
26212INCLUDING, BUT 26213 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26214 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26215 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26216 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26217 * POSSIBILITY OF SUCH DAMAGE. 26218 */ 26219'use strict'; 26220 26221Object.defineProperty(exports, '__esModule', { 26222 value: true 26223}); 26224 26225function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 26226 26227var _constantsConstants = _dereq_(100); 26228 26229var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 26230 26231var _StreamProcessor = _dereq_(97); 26232 26233var _StreamProcessor2 = _interopRequireDefault(_StreamProcessor); 26234 26235var _controllersEventController = _dereq_(106); 26236 26237var _controllersEventController2 = _interopRequireDefault(_controllersEventController); 26238 26239var _controllersFragmentController = _dereq_(107); 26240 26241var _controllersFragmentController2 = _interopRequireDefault(_controllersFragmentController); 26242 26243var _coreEventBus = _dereq_(50); 26244 26245var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 26246 26247var _coreEventsEvents = _dereq_(54); 26248 26249var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 26250 26251var _coreDebug = _dereq_(49); 26252 26253var _coreDebug2 = _interopRequireDefault(_coreDebug); 26254 26255var _coreFactoryMaker = _dereq_(51); 26256 26257var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 26258 26259function Stream(config) { 26260 26261 var DATA_UPDATE_FAILED_ERROR_CODE = 1; 26262 26263 var context = this.context; 26264 var log = (0, _coreDebug2['default'])(context).getInstance().log; 26265 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 26266 26267 var manifestModel = config.manifestModel; 26268 var dashManifestModel = config.dashManifestModel; 26269 var mediaPlayerModel = config.mediaPlayerModel; 26270 var manifestUpdater = config.manifestUpdater; 26271 var adapter = config.adapter; 26272 var capabilities = config.capabilities; 26273 var errHandler = config.errHandler; 26274 var timelineConverter = config.timelineConverter; 26275 var metricsModel = config.metricsModel; 26276 var abrController = config.abrController; 26277 var playbackController = config.playbackController; 26278 var mediaController = config.mediaController; 26279 var textController = config.textController; 26280 26281 var instance = undefined, 26282 streamProcessors = undefined, 26283 isStreamActivated = undefined, 26284 isMediaInitialized = undefined, 26285 streamInfo = undefined, 26286 updateError = undefined, 26287 isUpdating = undefined, 26288 protectionController = undefined, 26289 fragmentController = undefined, 26290 eventController = undefined, 26291 trackChangedEvent = undefined; 26292 26293 function setup() { 26294 resetInitialSettings(); 26295 26296 fragmentController = (0, _controllersFragmentController2['default'])(context).create({ 26297 mediaPlayerModel: mediaPlayerModel, 26298 metricsModel: metricsModel, 26299 errHandler: errHandler 26300 }); 26301 26302 eventBus.on(_coreEventsEvents2['default'].BUFFERING_COMPLETED, onBufferingCompleted, instance); 26303 eventBus.on(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, instance); 26304 } 26305 26306 function initialize(StreamInfo, ProtectionController) { 26307 streamInfo = StreamInfo; 26308 protectionController = ProtectionController; 26309 if (protectionController) { 26310 eventBus.on(_coreEventsEvents2['default'].KEY_ERROR, onProtectionError, instance); 26311 eventBus.on(_coreEventsEvents2['default'].SERVER_CERTIFICATE_UPDATED, onProtectionError, instance); 26312 eventBus.on(_coreEventsEvents2['default'].LICENSE_REQUEST_COMPLETE, onProtectionError, instance); 26313 eventBus.on(_coreEventsEvents2['default'].KEY_SYSTEM_SELECTED, onProtectionError, instance); 26314 eventBus.on(_coreEventsEvents2['default'].KEY_SESSION_CREATED, onProtectionError, instance); 26315 } 26316 } 26317 26318 /** 26319 * Activates Stream by re-initializing some of its components 26320 * @param {MediaSource} mediaSource 26321 * @memberof Stream# 26322 */ 26323 function activate(mediaSource) {
26324 if (!isStreamActivated) { 26325 eventBus.on(_coreEventsEvents2['default'].CURRENT_TRACK_CHANGED, onCurrentTrackChanged, instance); 26326 initializeMedia(mediaSource); 26327 isStreamActivated = true; 26328 } 26329 //else { // TODO Check track change mode but why is this here. commented it out for now to check. 26330 // createBuffers(); 26331 //} 26332 } 26333 26334 /** 26335 * Partially resets some of the Stream elements 26336 * @memberof Stream# 26337 */ 26338 function deactivate() { 26339 var ln = streamProcessors ? streamProcessors.length : 0; 26340 for (var i = 0; i < ln; i++) { 26341 streamProcessors[i].reset(); 26342 } 26343 streamProcessors = []; 26344 isStreamActivated = false; 26345 isMediaInitialized = false; 26346 clearEventController(); 26347 eventBus.off(_coreEventsEvents2['default'].CURRENT_TRACK_CHANGED, onCurrentTrackChanged, instance); 26348 } 26349 26350 function resetInitialSettings() { 26351 deactivate(); 26352 streamInfo = null; 26353 updateError = {}; 26354 isUpdating = false; 26355 } 26356 26357 function reset() { 26358 26359 if (playbackController) { 26360 playbackController.pause(); 26361 } 26362 26363 if (fragmentController) { 26364 fragmentController.reset(); 26365 fragmentController = null; 26366 } 26367 26368 resetInitialSettings(); 26369 26370 log = null; 26371 26372 eventBus.off(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, instance); 26373 eventBus.off(_coreEventsEvents2['default'].BUFFERING_COMPLETED, onBufferingCompleted, instance); 26374 eventBus.off(_coreEventsEvents2['default'].KEY_ERROR, onProtectionError, instance); 26375 eventBus.off(_coreEventsEvents2['default'].SERVER_CERTIFICATE_UPDATED, onProtectionError, instance); 26376 eventBus.off(_coreEventsEvents2['default'].LICENSE_REQUEST_COMPLETE, onProtectionError, instance); 26377 eventBus.off(_coreEventsEvents2['default'].KEY_SYSTEM_SELECTED, onProtectionError, instance); 26378 eventBus.off(_coreEventsEvents2['default'].KEY_SESSION_CREATED, onProtectionError, instance); 26379 } 26380 26381 function getDuration() { 26382 return streamInfo ? streamInfo.duration : NaN; 26383 } 26384 26385 function getStartTime() { 26386 return streamInfo ? streamInfo.start : NaN; 26387 } 26388 26389 function getId() { 26390 return streamInfo ? streamInfo.id : NaN; 26391 } 26392 26393 function getStreamInfo() { 26394 return streamInfo; 26395 } 26396 26397 function getEventController() { 26398 return eventController; 26399 } 26400 26401 function getFragmentController() { 26402 return fragmentController; 26403 } 26404 26405 function checkConfig() { 26406 if (!abrController || !abrController.hasOwnProperty('getBitrateList') || !adapter || !adapter.hasOwnProperty('getAllMediaInfoForType') || !adapter.hasOwnProperty('getEventsFor')) { 26407 throw new Error('Missing config parameter(s)'); 26408 } 26409 } 26410 26411 /** 26412 * @param {string} type 26413 * @returns {Array} 26414 * @memberof Stream# 26415 */ 26416 function getBitrateListFor(type) { 26417 checkConfig(); 26418 var mediaInfo = getMediaInfo(type); 26419 return abrController.getBitrateList(mediaInfo); 26420 } 26421 26422 function startEventController() { 26423 if (eventController) { 26424 eventController.start(); 26425 } 26426 } 26427 26428 function clearEventController() { 26429 if (eventController) { 26430 eventController.clear(); 26431 } 26432 } 26433 26434 function onProtectionError(event) { 26435 if (event.error) { 26436 errHandler.mediaKeySessionError(event.error); 26437 log(event.error); 26438 reset(); 26439 } 26440 } 26441 26442 function getMimeTypeOrType(mediaInfo) { 26443 return mediaInfo.type === _constantsConstants2['default'].TEXT ? mediaInfo.mimeType : mediaInfo.type; 26444 } 26445 26446 function isMediaSupported(mediaInfo) { 26447 var type = mediaInfo.type; 26448 var codec = undefined, 26449 msg = undefined; 26450 26451 if (type === _constantsConstants2['default'].MUXED && mediaInfo) { 26452 msg = 'Multiplexed representations are intentionally not supported, as they are not compliant with the DASH-AVC/264 guidelines'; 26453 log(msg); 26454 errHandler.manifestError(msg, 'multiplexedrep', manifestModel.getValue()); 26455 return false; 26456 } 26457 26458 if (type === _constantsConstants2['default'].TEXT || type === _constantsConstants2['default'].FRAGMENTED_TEXT || type === _constantsConstants2['default'].EMBEDDED_TEXT) { 26459 return true; 26460 } 26461 codec = mediaInfo.codec; 26462 log(type + ' codec: ' + codec); 26463 26464 if (!!mediaInfo.contentProtection && !capabilities.supportsEncryptedMedia()) { 26465 errHandler.capabilityError('encryptedmedia'); 26466 } else if (!capabilities.supportsCodec(codec)) { 26467 msg = type + 'Codec (' + codec + ') is not supported.'; 26468 errHandler.manifestError(msg, 'codec', manifestModel.getValue()); 26469 log(msg); 26470 return false; 26471 } 26472 26473 return true; 26474 } 26475 26476 function onCurrentTrackChanged(e) { 26477 if (e.newMediaInfo.streamInfo.id !== streamInfo.id) return; 26478 26479 var processor = getProcessorForMediaInfo(e.oldMediaInfo); 26480 if (!processor) return; 26481 26482 var currentTime = playbackController.getTime(); 26483 log('Stream - Process track changed at current time ' + currentTime); 26484 var mediaInfo = e.newMediaInfo; 26485 var manifest = manifestModel.getValue(); 26486 26487 log('Stream - Update stream controller'); 26488 if (manifest.refreshManifestOnSwitchTrack) { 26489 log('Stream - Refreshing manifest for switch track'); 26490 trackChangedEvent = e; 26491 manifestUpdater.refreshManifest(); 26492 } else { 26493 processor.updateMediaInfo(mediaInfo); 26494 if (mediaInfo.type !== _constantsConstants2['default'].FRAGMENTED_TEXT) { 26495 processor.switchTrackAsked(); 26496 } 26497 } 26498 } 26499 26500 function createStreamProcessor(mediaInfo, mediaSource, optionalSettings) { 26501 var streamProcessor = (0, _StreamProcessor2['default'])(context).create({ 26502 type: getMimeTypeOrType(mediaInfo), 26503 mimeType: mediaInfo.mimeType, 26504 timelineConverter: timelineConverter, 26505 adapter: adapter, 26506 manifestModel: manifestModel, 26507 dashManifestModel: dashManifestModel, 26508 mediaPlayerModel: mediaPlayerModel, 26509 metricsModel: metricsModel, 26510 dashMetrics: config.dashMetrics, 26511 baseURLController: config.baseURLController, 26512 stream: instance, 26513 abrController: abrController, 26514 domStorage: config.domStorage, 26515 playbackController: playbackController, 26516 mediaController: mediaController, 26517 streamController: config.streamController, 26518 textController: textController, 26519 sourceBufferController: config.sourceBufferController, 26520 errHandler: errHandler 26521 }); 26522 26523 var allMediaForType = adapter.getAllMediaInfoForType(streamInfo, mediaInfo.type); 26524 streamProcessor.initialize(mediaSource); 26525 abrController.updateTopQualityIndex(mediaInfo); 26526 26527 if (optionalSettings) { 26528 streamProcessor.setBuffer(optionalSettings.buffer); 26529 streamProcessor.getIndexHandler().setCurrentTime(optionalSettings.currentTime); 26530 streamProcessors[optionalSettings.replaceIdx] = streamProcessor; 26531 } else { 26532 streamProcessors.push(streamProcessor); 26533 } 26534 26535 if (optionalSettings && optionalSettings.ignoreMediaInfo) { 26536 return; 26537 } 26538 26539 if (mediaInfo.type === _constantsConstants2['default'].TEXT || mediaInfo.type === _constantsConstants2['default'].FRAGMENTED_TEXT) { 26540 var idx = undefined; 26541 for (var i = 0; i < allMediaForType.length; i++) { 26542 if (allMediaForType[i].index === mediaInfo.index) { 26543 idx = i; 26544 } 26545 streamProcessor.updateMediaInfo(allMediaForType[i]); //creates text tracks for all adaptations in one stream processor 26546 } 26547 if (mediaInfo.type === _constantsConstants2['default'].FRAGMENTED_TEXT) { 26548 streamProcessor.updateMediaInfo(allMediaForType[idx]); //sets the initial media info 26549 } 26550 } else { 26551 streamProcessor.updateMediaInfo(mediaInfo); 26552 } 26553 } 26554 26555 function initializeMediaForType(type, mediaSource) { 26556 var allMediaForType = adapter.getAllMediaInfoForType(streamInfo, type); 26557 26558 var mediaInfo = null; 26559 var initialMediaInfo = undefined; 26560 26561 if (!allMediaForType || allMediaForType.length === 0) { 26562 log('No ' + type + ' data.'); 26563 return; 26564 } 26565 26566 for (var i = 0, ln = allMediaForType.length; i < ln; i++) { 26567 mediaInfo = allMediaForType[i]; 26568 26569 if (type === _constantsConstants2['default'].EMBEDDED_TEXT) { 26570 textController.addEmbeddedTrack(mediaInfo); 26571 } else { 26572 if (!isMediaSupported(mediaInfo)) { 26573 continue; 26574 } 26575 if (mediaController.isMultiTrackSupportedByType(mediaInfo.type)) { 26576 mediaController.addTrack(mediaInfo, streamInfo); 26577 } 26578 } 26579 } 26580 26581 if (type === _constantsConstants2['default'].EMBEDDED_TEXT || mediaController.getTracksFor(type, streamInfo).length === 0) { 26582 return; 26583 } 26584 26585 mediaController.checkInitialMediaSettingsForType(type, streamInfo); 26586 initialMediaInfo = mediaController.getCurrentTrackFor(type, streamInfo); 26587 26588 // TODO : How to tell index handler live/duration? 26589 // TODO : Pass to controller and then pass to each method on handler? 26590 26591 createStreamProcessor(initialMediaInfo, mediaSource); 26592 } 26593 26594 function initializeMedia(mediaSource) { 26595 checkConfig(); 26596 var events = undefined; 26597 26598 eventController = (0, _controllersEventController2['default'])(context).create(); 26599 26600 eventController.setConfig({ 26601 manifestModel: manifestModel, 26602 manifestUpdater: manifestUpdater, 26603 playbackController: playbackController 26604 }); 26605 events = adapter.getEventsFor(streamInfo); 26606 eventController.addInlineEvents(events); 26607 26608 isUpdating = true; 26609 26610 filterCodecs(_constantsConstants2['default'].VIDEO); 26611 filterCodecs(_constantsConstants2['default'].AUDIO); 26612 26613 initializeMediaForType(_constantsConstants2['default'].VIDEO, mediaSource); 26614 initializeMediaForType(_constantsConstants2['default'].AUDIO, mediaSource); 26615 initializeMediaForType(_constantsConstants2['default'].TEXT, mediaSource); 26616 initializeMediaForType(_constantsConstants2['default'].FRAGMENTED_TEXT, mediaSource); 26617 initializeMediaForType(_constantsConstants2['default'].EMBEDDED_TEXT, mediaSource); 26618 initializeMediaForType(_constantsConstants2['default'].MUXED, mediaSource); 26619 26620 createBuffers(); 26621 26622 //TODO. Consider initialization of TextSourceBuffer here if embeddedText, but no sideloadedText. 26623 26624 isMediaInitialized = true; 26625 isUpdating = false; 26626 26627 if (streamProcessors.length === 0) { 26628 var msg = 'No streams to play.'; 26629 errHandler.manifestError(msg, 'nostreams', manifestModel.getValue()); 26630 log(msg); 26631 } else { 26632 //log("Playback initialized!"); 26633 checkIfInitializationCompleted(); 26634 } 26635 } 26636 26637 function filterCodecs(type) { 26638 var realAdaptation = dashManifestModel.getAdaptationForType(manifestModel.getValue(), streamInfo.index, type, streamInfo); 26639 26640 if (!realAdaptation || !Array.isArray(realAdaptation.Representation_asArray)) return null; 26641 26642 // Filter codecs that are not supported 26643 realAdaptation.Representation_asArray.filter(function (_, i) { 26644 // keep at least codec from lowest representation 26645 if (i === 0) return true; 26646 26647 var codec = dashManifestModel.getCodec(realAdaptation, i); 26648 if (!capabilities.supportsCodec(codec)) { 26649 log('[Stream] codec not supported: ' + codec); 26650 return false; 26651 } 26652 return true; 26653 }); 26654 } 26655 26656 function checkIfInitializationCompleted() { 26657 var ln = streamProcessors.length; 26658 var hasError = !!updateError.audio || !!updateError.video; 26659 var error = hasError ? new Error(DATA_UPDATE_FAILED_ERROR_CODE, 'Data update failed', null) : null; 26660 26661 for (var i = 0; i < ln; i++) { 26662 if (streamProcessors[i].isUpdating() || isUpdating) { 26663 return; 26664 } 26665 } 26666 26667 if (!isMediaInitialized) { 26668 return; 26669 } 26670 if (protectionController) { 26671 protectionController.initialize(manifestModel.getValue(), getMediaInfo(_constantsConstants2['default'].AUDIO), getMediaInfo(_constantsConstants2['default'].VIDEO)); 26672 } 26673 eventBus.trigger(_coreEventsEvents2['default'].STREAM_INITIALIZED, { 26674 streamInfo: streamInfo, 26675 error: error 26676 }); 26677 } 26678 26679 function getMediaInfo(type) { 26680 var ln = streamProcessors.length; 26681 var mediaCtrl = null; 26682 26683 for (var i = 0; i < ln; i++) { 26684 mediaCtrl = streamProcessors[i]; 26685 26686 if (mediaCtrl.getType() === type) { 26687 return mediaCtrl.getMediaInfo(); 26688 } 26689 } 26690 26691 return null; 26692 } 26693 26694 function createBuffers() { 26695 for (var i = 0, ln = streamProcessors.length; i < ln; i++) { 26696 streamProcessors[i].createBuffer(); 26697 } 26698 } 26699 26700 function onBufferingCompleted(e) { 26701 if (e.streamInfo !== streamInfo) { 26702 return; 26703 } 26704 26705 var processors = getProcessors(); 26706 var ln = processors.length; 26707 26708 // if there is at least one buffer controller that has not completed buffering yet do nothing 26709 for (var i = 0; i < ln; i++) { 26710 if (!processors[i].isBufferingCompleted()) { 26711 return; 26712 } 26713 } 26714 26715 eventBus.trigger(_coreEventsEvents2['default'].STREAM_BUFFERING_COMPLETED, { 26716 streamInfo: streamInfo 26717 }); 26718 } 26719 26720 function onDataUpdateCompleted(e) { 26721 var sp = e.sender.getStreamProcessor(); 26722 26723 if (sp.getStreamInfo() !== streamInfo) { 26724 return; 26725 } 26726 26727 updateError[sp.getType()] = e.error; 26728 checkIfInitializationCompleted(); 26729 } 26730 26731 function getProcessorForMediaInfo(mediaInfo) { 26732 if (!mediaInfo) { 26733 return false; 26734 } 26735 26736 var processors = getProcessors(); 26737 26738 return processors.filter(function (processor) { 26739 return processor.getType() === mediaInfo.type; 26740 })[0]; 26741 } 26742 26743 function getProcessors() { 26744 var ln = streamProcessors.length; 26745 var arr = []; 26746 26747 var type = undefined, 26748 controller = undefined; 26749 26750 for (var i = 0; i < ln; i++) { 26751 controller = streamProcessors[i]; 26752 type = controller.getType(); 26753 26754 if (type === _constantsConstants2['default'].AUDIO || type === _constantsConstants2['default'].VIDEO || type === _constantsConstants2['default'].FRAGMENTED_TEXT) { 26755 arr.push(controller); 26756 } 26757 } 26758 26759 return arr; 26760 } 26761 26762 function updateData(updatedStreamInfo) { 26763 26764 log('Manifest updated... updating data system wide.'); 26765
26766 isStreamActivated = false; 26767 isUpdating = true; 26768 streamInfo = updatedStreamInfo; 26769 26770 if (eventController) { 26771 var events = adapter.getEventsFor(streamInfo); 26772 eventController.addInlineEvents(events); 26773 } 26774 26775 filterCodecs(_constantsConstants2['default'].VIDEO); 26776 filterCodecs(_constantsConstants2['default'].AUDIO); 26777 26778 for (var i = 0, ln = streamProcessors.length; i < ln; i++) { 26779 var streamProcessor = streamProcessors[i]; 26780 var mediaInfo = adapter.getMediaInfoForType(streamInfo, streamProcessor.getType()); 26781 abrController.updateTopQualityIndex(mediaInfo); 26782 streamProcessor.updateMediaInfo(mediaInfo); 26783 } 26784 26785 if (trackChangedEvent) { 26786 var mediaInfo = trackChangedEvent.newMediaInfo; 26787 if (mediaInfo.type !== 'fragmentedText') { 26788 var processor = getProcessorForMediaInfo(trackChangedEvent.oldMediaInfo); 26789 if (!processor) return; 26790 processor.switchTrackAsked(); 26791 trackChangedEvent = undefined; 26792 } 26793 } 26794 26795 isUpdating = false; 26796 checkIfInitializationCompleted(); 26797 } 26798 26799 instance = { 26800 initialize: initialize, 26801 activate: activate, 26802 deactivate: deactivate, 26803 getDuration: getDuration, 26804 getStartTime: getStartTime, 26805 getId: getId, 26806 getStreamInfo: getStreamInfo, 26807 getFragmentController: getFragmentController, 26808 getEventController: getEventController, 26809 getBitrateListFor: getBitrateListFor, 26810 startEventController: startEventController, 26811 updateData: updateData, 26812 reset: reset, 26813 getProcessors: getProcessors 26814 }; 26815 26816 setup(); 26817 return instance; 26818} 26819 26820Stream.__dashjs_factory_name = 'Stream'; 26821exports['default'] = _coreFactoryMaker2['default'].getClassFactory(Stream); 26822module.exports = exports['default']; 26823 26824},{"100":100,"106":106,"107":107,"49":49,"50":50,"51":51,"54":54,"97":97}],97:[function(_dereq_,module,exports){ 26825/** 26826 * The copyright in this software is being made available under the BSD License, 26827 * included below. This software may be subject to other third party and contributor 26828 * rights, including patent rights, and no such rights are granted under this license. 26829 * 26830 * Copyright (c) 2013, Dash Industry Forum. 26831 * All rights reserved. 26832 * 26833 * Redistribution and use in source and binary forms, with or without modification, 26834 * are permitted provided that the following conditions are met: 26835 * * Redistributions of source code must retain the above copyright notice, this 26836 * list of conditions and the following disclaimer. 26837 * * Redistributions in binary form must reproduce the above copyright notice, 26838 * this list of conditions and the following disclaimer in the documentation and/or 26839 * other materials provided with the distribution. 26840 * * Neither the name of Dash Industry Forum nor the names of its 26841 * contributors may be used to endorse or promote products derived from this software 26842 * without specific prior written permission. 26843 * 26844 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 26845 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26846 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26847 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26848 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26849 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26850 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26851 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26852 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26853 * POSSIBILITY OF SUCH DAMAGE. 26854 */ 26855'use strict'; 26856 26857Object.defineProperty(exports, '__esModule', { 26858 value: true 26859}); 26860 26861function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 26862 26863var _constantsConstants = _dereq_(100); 26864 26865var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 26866 26867var _utilsLiveEdgeFinder = _dereq_(198); 26868 26869var _utilsLiveEdgeFinder2 = _interopRequireDefault(_utilsLiveEdgeFinder); 26870 26871var _controllersBufferController = _dereq_(105); 26872 26873var _controllersBufferController2 = _interopRequireDefault(_controllersBufferController); 26874 26875var _textTextBufferController = _dereq_(185); 26876 26877var _textTextBufferController2 = _interopRequireDefault(_textTextBufferController); 26878 26879var _controllersScheduleController = _dereq_(111); 26880 26881var _controllersScheduleController2 = _interopRequireDefault(_controllersScheduleController); 26882 26883var _dashControllersRepresentationController = _dereq_(62); 26884 26885var _dashControllersRepresentationController2 = _interopRequireDefault(_dashControllersRepresentationController); 26886 26887var _coreFactoryMaker = _dereq_(51); 26888 26889var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 26890 26891var _dashDashHandler = _dereq_(57); 26892 26893var _dashDashHandler2 = _interopRequireDefault(_dashDashHandler); 26894 26895function StreamProcessor(config) { 26896 26897 var context = this.context; 26898 26899 var indexHandler = undefined; 26900 var type = config.type; 26901 var errHandler = config.errHandler; 26902 var mimeType = config.mimeType; 26903 var timelineConverter = config.timelineConverter; 26904 var adapter = config.adapter; 26905 var manifestModel = config.manifestModel; 26906 var mediaPlayerModel = config.mediaPlayerModel; 26907 var stream = config.stream; 26908 var abrController = config.abrController; 26909 var playbackController = config.playbackController; 26910 var streamController = config.streamController; 26911 var mediaController = config.mediaController; 26912 var textController = config.textController; 26913 var sourceBufferController = config.sourceBufferController; 26914 var domStorage = config.domStorage; 26915 var metricsModel = config.metricsModel; 26916 var dashMetrics = config.dashMetrics; 26917 var dashManifestModel = config.dashManifestModel; 26918 26919 var instance = undefined, 26920 mediaInfo = undefined, 26921 mediaInfoArr = undefined, 26922 bufferController = undefined, 26923 scheduleController = undefined, 26924 liveEdgeFinder = undefined, 26925 representationController = undefined, 26926 fragmentModel = undefined, 26927 spExternalControllers = undefined; 26928 26929 function setup() { 26930 liveEdgeFinder = (0, _utilsLiveEdgeFinder2['default'])(context).create({ 26931 timelineConverter: timelineConverter, 26932 streamProcessor: instance 26933 }); 26934 resetInitialSettings();
26935 } 26936 26937 function initialize(mediaSource) { 26938 26939 indexHandler = (0, _dashDashHandler2['default'])(context).create({ 26940 mimeType: mimeType, 26941 timelineConverter: timelineConverter, 26942 dashMetrics: dashMetrics, 26943 metricsModel: metricsModel, 26944 mediaPlayerModel: mediaPlayerModel, 26945 baseURLController: config.baseURLController, 26946 errHandler: errHandler 26947 }); 26948 26949 // initialize controllers 26950 indexHandler.initialize(this); 26951 abrController.registerStreamType(type, this); 26952 26953 fragmentModel = stream.getFragmentController().getModel(type); 26954 fragmentModel.setStreamProcessor(instance); 26955 26956 bufferController = createBufferControllerForType(type); 26957 scheduleController = (0, _controllersScheduleController2['default'])(context).create({ 26958 type: type, 26959 metricsModel: metricsModel, 26960 adapter: adapter, 26961 dashMetrics: dashMetrics, 26962 dashManifestModel: dashManifestModel, 26963 timelineConverter: timelineConverter, 26964 mediaPlayerModel: mediaPlayerModel, 26965 abrController: abrController, 26966 playbackController: playbackController, 26967 streamController: streamController, 26968 textController: textController, 26969 sourceBufferController: sourceBufferController, 26970 streamProcessor: this 26971 }); 26972 26973 representationController = (0, _dashControllersRepresentationController2['default'])(context).create(); 26974 26975 representationController.setConfig({ 26976 abrController: abrController, 26977 domStorage: domStorage, 26978 metricsModel: metricsModel, 26979 dashMetrics: dashMetrics, 26980 dashManifestModel: dashManifestModel, 26981 manifestModel: manifestModel, 26982 playbackController: playbackController, 26983 timelineConverter: timelineConverter, 26984 streamProcessor: this 26985 }); 26986 bufferController.initialize(mediaSource); 26987 scheduleController.initialize(); 26988 representationController.initialize(); 26989 } 26990 26991 function registerExternalController(controller) { 26992 spExternalControllers.push(controller); 26993 } 26994 26995 function unregisterExternalController(controller) { 26996 var index = spExternalControllers.indexOf(controller); 26997 26998 if (index !== -1) { 26999 spExternalControllers.splice(index, 1); 27000 } 27001 } 27002 27003 function unregisterAllExternalController() { 27004 spExternalControllers = []; 27005 } 27006 27007 function resetInitialSettings() { 27008 mediaInfoArr = []; 27009 mediaInfo = null; 27010 unregisterAllExternalController(); 27011 } 27012 27013 function reset(errored) { 27014 27015 indexHandler.reset(); 27016 27017 if (bufferController) { 27018 bufferController.reset(errored); 27019 bufferController = null; 27020 } 27021 27022 if (scheduleController) { 27023 scheduleController.reset(); 27024 scheduleController = null; 27025 } 27026 27027 if (representationController) { 27028 representationController.reset(); 27029 representationController = null; 27030 } 27031 27032 spExternalControllers.forEach(function (controller) { 27033 controller.reset(); 27034 }); 27035 27036 resetInitialSettings(); 27037 type = null; 27038 stream = null; 27039 liveEdgeFinder.reset(); 27040 } 27041 27042 function isUpdating() { 27043 return representationController ? representationController.isUpdating() : false; 27044 } 27045 27046 function getType() { 27047 return type; 27048 } 27049 27050 function getRepresentationController() { 27051 return representationController; 27052 } 27053 27054 function getIndexHandler() { 27055 return indexHandler; 27056 } 27057 27058 function getFragmentController() { 27059 return stream ? stream.getFragmentController() : null; 27060 } 27061 27062 function getBuffer() { 27063 return bufferController.getBuffer(); 27064 } 27065 27066 function setBuffer(buffer) { 27067 bufferController.setBuffer(buffer); 27068 } 27069 27070 function getBufferController() { 27071 return bufferController; 27072 } 27073 27074 function getFragmentModel() { 27075 return fragmentModel; 27076 } 27077 27078 function getLiveEdgeFinder() { 27079 return liveEdgeFinder; 27080 } 27081 27082 function getStreamInfo() { 27083 return stream ? stream.getStreamInfo() : null; 27084 } 27085
27086 function getEventController() { 27087 return stream ? stream.getEventController() : null; 27088 } 27089 27090 function updateMediaInfo(newMediaInfo) { 27091 if (newMediaInfo !== mediaInfo && (!newMediaInfo || !mediaInfo || newMediaInfo.type === mediaInfo.type)) { 27092 mediaInfo = newMediaInfo; 27093 } 27094 if (mediaInfoArr.indexOf(newMediaInfo) === -1) { 27095 mediaInfoArr.push(newMediaInfo); 27096 } 27097 adapter.updateData(this); 27098 } 27099 27100 function getMediaInfoArr() { 27101 return mediaInfoArr; 27102 } 27103 27104 function getMediaInfo() { 27105 return mediaInfo; 27106 } 27107 27108 function getMediaSource() { 27109 return bufferController.getMediaSource(); 27110 } 27111 27112 function getScheduleController() { 27113 return scheduleController; 27114 } 27115 27116 function getCurrentRepresentationInfo() { 27117 return adapter.getCurrentRepresentationInfo(representationController); 27118 } 27119 27120 function getRepresentationInfoForQuality(quality) { 27121 return adapter.getRepresentationInfoForQuality(representationController, quality); 27122 } 27123 27124 function isBufferingCompleted() { 27125 if (bufferController) { 27126 return bufferController.getIsBufferingCompleted(); 27127 } 27128 27129 return false; 27130 } 27131 27132 function getBufferLevel() { 27133 return bufferController.getBufferLevel(); 27134 } 27135 27136 function switchInitData(representationId) { 27137 if (bufferController) { 27138 bufferController.switchInitData(getStreamInfo().id, representationId); 27139 } 27140 } 27141 27142 function createBuffer() { 27143 return bufferController.getBuffer() || bufferController.createBuffer(mediaInfo); 27144 } 27145 27146 function switchTrackAsked() { 27147 scheduleController.switchTrackAsked(); 27148 } 27149 27150 function createBufferControllerForType(type) { 27151 var controller = null; 27152 27153 if (type === _constantsConstants2['default'].VIDEO || type === _constantsConstants2['default'].AUDIO) { 27154 controller = (0, _controllersBufferController2['default'])(context).create({ 27155 type: type, 27156 metricsModel: metricsModel, 27157 mediaPlayerModel: mediaPlayerModel, 27158 manifestModel: manifestModel, 27159 sourceBufferController: sourceBufferController, 27160 errHandler: errHandler, 27161 streamController: streamController, 27162 mediaController: mediaController, 27163 adapter: adapter, 27164 textController: textController, 27165 abrController: abrController, 27166 playbackController: playbackController, 27167 streamProcessor: instance 27168 }); 27169 } else { 27170 controller = (0, _textTextBufferController2['default'])(context).create({ 27171 type: type, 27172 metricsModel: metricsModel, 27173 mediaPlayerModel: mediaPlayerModel, 27174 manifestModel: manifestModel, 27175 sourceBufferController: sourceBufferController, 27176 errHandler: errHandler, 27177 streamController: streamController, 27178 mediaController: mediaController, 27179 adapter: adapter, 27180 textController: textController, 27181 abrController: abrController, 27182 playbackController: playbackController, 27183 streamProcessor: instance 27184 }); 27185 } 27186 27187 return controller; 27188 } 27189 27190 instance = { 27191 initialize: initialize, 27192 isUpdating: isUpdating, 27193 getType: getType, 27194 getBufferController: getBufferController, 27195 getFragmentModel: getFragmentModel, 27196 getScheduleController: getScheduleController, 27197 getLiveEdgeFinder: getLiveEdgeFinder, 27198 getEventController: getEventController, 27199 getFragmentController: getFragmentController, 27200 getRepresentationController: getRepresentationController, 27201 getIndexHandler: getIndexHandler, 27202 getCurrentRepresentationInfo: getCurrentRepresentationInfo, 27203 getRepresentationInfoForQuality: getRepresentationInfoForQuality, 27204 getBufferLevel: getBufferLevel, 27205 switchInitData: switchInitData, 27206 isBufferingCompleted: isBufferingCompleted, 27207 createBuffer: createBuffer, 27208 getStreamInfo: getStreamInfo, 27209 updateMediaInfo: updateMediaInfo, 27210 switchTrackAsked: switchTrackAsked, 27211 getMediaInfoArr: getMediaInfoArr, 27212 getMediaInfo: getMediaInfo, 27213 getMediaSource: getMediaSource, 27214 getBuffer: getBuffer, 27215 setBuffer: setBuffer, 27216 registerExternalController: registerExternalController, 27217 unregisterExternalController: unregisterExternalController, 27218 unregisterAllExternalController: unregisterAllExternalController, 27219 reset: reset 27220 }; 27221 27222 setup(); 27223 return instance; 27224} 27225StreamProcessor.__dashjs_factory_name = 'StreamProcessor'; 27226exports['default'] = _coreFactoryMaker2['default'].getClassFactory(StreamProcessor); 27227module.exports = exports['default']; 27228 27229},{"100":100,"105":105,"111":111,"185":185,"198":198,"51":51,"57":57,"62":62}],98:[function(_dereq_,module,exports){ 27230/** 27231 * The copyright in this software is being made available under the BSD License, 27232 * included below. This software may be subject to other third party and contributor 27233 * rights, including patent rights, and no such rights are granted under this license. 27234 * 27235 * Copyright (c) 2013, Dash Industry Forum. 27236 * All rights reserved. 27237 * 27238 * Redistribution and use in source and binary forms, with or without modification, 27239 * are permitted provided that the following conditions are met: 27240 * * Redistributions of source code must retain the above copyright notice, this 27241 * list of conditions and the following disclaimer. 27242 * * Redistributions in binary form must reproduce the above copyright notice, 27243 * this list of conditions and the following disclaimer in the documentation and/or 27244 * other materials provided with the distribution. 27245 * * Neither the name of Dash Industry Forum nor the names of its 27246 * contributors may be used to endorse or promote products derived from this software 27247 * without specific prior written permission. 27248 * 27249 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 27250 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27251 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27252 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27253 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
27253INCLUDING, BUT 27254 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27255 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27256 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27257 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27258 * POSSIBILITY OF SUCH DAMAGE. 27259 */ 27260'use strict'; 27261 27262Object.defineProperty(exports, '__esModule', { 27263 value: true 27264}); 27265 27266function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 27267 27268function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 27269 27270var _voMetricsHTTPRequest = _dereq_(224); 27271 27272var _coreFactoryMaker = _dereq_(51); 27273 27274var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 27275 27276var _utilsErrorHandlerJs = _dereq_(195); 27277 27278var _utilsErrorHandlerJs2 = _interopRequireDefault(_utilsErrorHandlerJs); 27279 27280/** 27281 * @module XHRLoader 27282 * @description Manages download of resources via HTTP. 27283 * @param {Object} cfg - dependancies from parent 27284 */ 27285function XHRLoader(cfg) { 27286 //const context = this.context; 27287 //const log = Debug(context).getInstance().log; 27288 var errHandler = cfg.errHandler; 27289 var metricsModel = cfg.metricsModel; 27290 var mediaPlayerModel = cfg.mediaPlayerModel; 27291 var requestModifier = cfg.requestModifier; 27292 27293 var instance = undefined; 27294 var xhrs = undefined; 27295 var delayedXhrs = undefined; 27296 var retryTimers = undefined; 27297 var downloadErrorToRequestTypeMap = undefined; 27298 27299 function setup() { 27300 var _downloadErrorToRequestTypeMap; 27301 27302 xhrs = []; 27303 delayedXhrs = []; 27304 retryTimers = []; 27305 27306 downloadErrorToRequestTypeMap = (_downloadErrorToRequestTypeMap = {}, _defineProperty(_downloadErrorToRequestTypeMap, _voMetricsHTTPRequest.HTTPRequest.MPD_TYPE, _utilsErrorHandlerJs2['default'].DOWNLOAD_ERROR_ID_MANIFEST), _defineProperty(_downloadErrorToRequestTypeMap, _voMetricsHTTPRequest.HTTPRequest.XLINK_EXPANSION_TYPE, _utilsErrorHandlerJs2['default'].DOWNLOAD_ERROR_ID_XLINK), _defineProperty(_downloadErrorToRequestTypeMap, _voMetricsHTTPRequest.HTTPRequest.INIT_SEGMENT_TYPE, _utilsErrorHandlerJs2['default'].DOWNLOAD_ERROR_ID_INITIALIZATION), _defineProperty(_downloadErrorToRequestTypeMap, _voMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE, _utilsErrorHandlerJs2['default'].DOWNLOAD_ERROR_ID_CONTENT), _defineProperty(_downloadErrorToRequestTypeMap, _voMetricsHTTPRequest.HTTPRequest.INDEX_SEGMENT_TYPE, _utilsErrorHandlerJs2['default'].DOWNLOAD_ERROR_ID_CONTENT), _defineProperty(_downloadErrorToRequestTypeMap, _voMetricsHTTPRequest.HTTPRequest.BITSTREAM_SWITCHING_SEGMENT_TYPE, _utilsErrorHandlerJs2['default'].DOWNLOAD_ERROR_ID_CONTENT), _defineProperty(_downloadErrorToRequestTypeMap, _voMetricsHTTPRequest.HTTPRequest.OTHER_TYPE, _utilsErrorHandlerJs2['default'].DOWNLOAD_ERROR_ID_CONTENT), _downloadErrorToRequestTypeMap); 27307 } 27308 27309 function internalLoad(config, remainingAttempts) { 27310 27311 var request = config.request; 27312 var xhr = new XMLHttpRequest(); 27313 var traces = []; 27314 var firstProgress = true; 27315 var needFailureReport = true; 27316 var requestStartTime = new Date(); 27317 var lastTraceTime = requestStartTime; 27318 var lastTraceReceivedCount = 0; 27319 27320 var handleLoaded = function handleLoaded(success) { 27321 needFailureReport = false; 27322 27323 request.requestStartDate = requestStartTime; 27324 request.requestEndDate = new Date(); 27325 request.firstByteDate = request.firstByteDate || requestStartTime; 27326 27327 if (!request.checkExistenceOnly) { 27328 metricsModel.addHttpRequest(request.mediaType, null, request.type, request.url, xhr.responseURL || null, request.serviceLocation || null, request.range || null, request.requestStartDate, request.firstByteDate, request.requestEndDate, xhr.status, request.duration, xhr.getAllResponseHeaders(), success ? traces : null); 27329 } 27330 }; 27331 27332 var onloadend = function onloadend() { 27333 if (xhrs.indexOf(xhr) === -1) { 27334 return; 27335 } else {
27336 xhrs.splice(xhrs.indexOf(xhr), 1); 27337 } 27338 27339 if (needFailureReport) { 27340 handleLoaded(false); 27341 27342 if (remainingAttempts > 0) { 27343 remainingAttempts--; 27344 retryTimers.push(setTimeout(function () { 27345 internalLoad(config, remainingAttempts); 27346 }, mediaPlayerModel.getRetryIntervalForType(request.type))); 27347 } else { 27348 errHandler.downloadError(downloadErrorToRequestTypeMap[request.type], request.url, request); 27349 27350 if (config.error) { 27351 config.error(request, 'error', xhr.statusText); 27352 } 27353 27354 if (config.complete) { 27355 config.complete(request, xhr.statusText); 27356 } 27357 } 27358 } 27359 }; 27360 27361 var progress = function progress(event) { 27362 var currentTime = new Date(); 27363 27364 if (firstProgress) { 27365 firstProgress = false; 27366 if (!event.lengthComputable || event.lengthComputable && event.total !== event.loaded) { 27367 request.firstByteDate = currentTime; 27368 } 27369 } 27370 27371 if (event.lengthComputable) { 27372 request.bytesLoaded = event.loaded; 27373 request.bytesTotal = event.total; 27374 } 27375 27376 traces.push({ 27377 s: lastTraceTime, 27378 d: currentTime.getTime() - lastTraceTime.getTime(), 27379 b: [event.loaded ? event.loaded - lastTraceReceivedCount : 0] 27380 }); 27381 27382 lastTraceTime = currentTime; 27383 lastTraceReceivedCount = event.loaded; 27384 27385 if (config.progress) { 27386 config.progress(); 27387 } 27388 }; 27389 27390 var onload = function onload() { 27391 if (xhr.status >= 200 && xhr.status <= 299) { 27392 handleLoaded(true); 27393 27394 if (config.success) { 27395 config.success(xhr.response, xhr.statusText, xhr); 27396 } 27397 27398 if (config.complete) { 27399 config.complete(request, xhr.statusText); 27400 } 27401 } 27402 }; 27403 27404 var onabort = function onabort() { 27405 if (config.abort) { 27406 config.abort(request, xhr.status); 27407 } 27408 }; 27409 27410 if (!requestModifier || !metricsModel || !errHandler) { 27411 throw new Error('config object is not correct or missing'); 27412 } 27413 27414 try { 27415 var modifiedUrl = requestModifier.modifyRequestURL(request.url); 27416 var verb = request.checkExistenceOnly ? _voMetricsHTTPRequest.HTTPRequest.HEAD : _voMetricsHTTPRequest.HTTPRequest.GET; 27417 27418 xhr.open(verb, modifiedUrl, true); 27419 27420 if (request.responseType) { 27421 xhr.responseType = request.responseType; 27422 } 27423 27424 if (request.range) { 27425 xhr.setRequestHeader('Range', 'bytes=' + request.range); 27426 } 27427 27428 if (!request.requestStartDate) { 27429 request.requestStartDate = requestStartTime; 27430 } 27431 27432 xhr = requestModifier.modifyRequestHeader(xhr); 27433 27434 xhr.withCredentials = mediaPlayerModel.getXHRWithCredentialsForType(request.type); 27435 27436 xhr.onload = onload; 27437 xhr.onloadend = onloadend; 27438 xhr.onerror = onloadend; 27439 xhr.onprogress = progress; 27440 xhr.onabort = onabort; 27441 27442 // Adds the ability to delay single fragment loading time to control buffer. 27443 var now = new Date().getTime(); 27444 if (isNaN(request.delayLoadingTime) || now >= request.delayLoadingTime) { 27445 // no delay - just send xhr 27446 27447 xhrs.push(xhr); 27448 xhr.send(); 27449 } else { 27450 (function () { 27451 // delay 27452 var delayedXhr = { xhr: xhr }; 27453 delayedXhrs.push(delayedXhr); 27454 delayedXhr.delayTimeout = setTimeout(function () { 27455 if (delayedXhrs.indexOf(delayedXhr) === -1) { 27456 return; 27457 } else { 27458 delayedXhrs.splice(delayedXhrs.indexOf(delayedXhr), 1); 27459 } 27460 try { 27461 requestStartTime = new Date(); 27462 lastTraceTime = requestStartTime; 27463 xhrs.push(delayedXhr.xhr); 27464 delayedXhr.xhr.send(); 27465 } catch (e) { 27466 delayedXhr.xhr.onerror(); 27467 } 27468 }, request.delayLoadingTime - now); 27469 })(); 27470 } 27471 } catch (e) { 27472 xhr.onerror(); 27473 } 27474 } 27475 27476 /** 27477 * Initiates a download of the resource described by config.request 27478 * @param {Object} config - contains request (FragmentRequest or derived type), and callbacks 27479 * @memberof module:XHRLoader 27480 * @instance 27481 */ 27482 function load(config) { 27483 if (config.request) { 27484 internalLoad(config, mediaPlayerModel.getRetryAttemptsForType(config.request.type)); 27485 } 27486 } 27487 27488 /** 27489 * Aborts any inflight downloads 27490 * @memberof module:XHRLoader 27491 * @instance 27492 */ 27493 function abort() {
27494 retryTimers.forEach(function (t) { 27495 return clearTimeout(t); 27496 }); 27497 retryTimers = []; 27498 27499 delayedXhrs.forEach(function (x) { 27500 return clearTimeout(x.delayTimeout); 27501 }); 27502 delayedXhrs = []; 27503 27504 xhrs.forEach(function (x) { 27505 // abort will trigger onloadend which we don't want 27506 // when deliberately aborting inflight requests - 27507 // set them to undefined so they are not called 27508 x.onloadend = x.onerror = x.onprogress = undefined; 27509 x.abort(); 27510 }); 27511 xhrs = []; 27512 } 27513 27514 instance = { 27515 load: load, 27516 abort: abort 27517 }; 27518 27519 setup(); 27520 27521 return instance; 27522} 27523 27524XHRLoader.__dashjs_factory_name = 'XHRLoader'; 27525 27526var factory = _coreFactoryMaker2['default'].getClassFactory(XHRLoader); 27527exports['default'] = factory; 27528module.exports = exports['default']; 27529 27530},{"195":195,"224":224,"51":51}],99:[function(_dereq_,module,exports){ 27531/** 27532 * The copyright in this software is being made available under the BSD License, 27533 * included below. This software may be subject to other third party and contributor 27534 * rights, including patent rights, and no such rights are granted under this license. 27535 * 27536 * Copyright (c) 2013, Dash Industry Forum. 27537 * All rights reserved. 27538 * 27539 * Redistribution and use in source and binary forms, with or without modification, 27540 * are permitted provided that the following conditions are met: 27541 * * Redistributions of source code must retain the above copyright notice, this 27542 * list of conditions and the following disclaimer. 27543 * * Redistributions in binary form must reproduce the above copyright notice, 27544 * this list of conditions and the following disclaimer in the documentation and/or 27545 * other materials provided with the distribution. 27546 * * Neither the name of Dash Industry Forum nor the names of its 27547 * contributors may be used to endorse or promote products derived from this software 27548 * without specific prior written permission. 27549 * 27550 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 27551 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27552 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27553 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27554 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27555 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27556 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27557 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27558 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27559 * POSSIBILITY OF SUCH DAMAGE. 27560 */ 27561'use strict'; 27562 27563Object.defineProperty(exports, '__esModule', { 27564 value: true 27565}); 27566 27567function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 27568 27569var _voDashJSError = _dereq_(207); 27570 27571var _voDashJSError2 = _interopRequireDefault(_voDashJSError); 27572 27573var _XHRLoader = _dereq_(98); 27574 27575var _XHRLoader2 = _interopRequireDefault(_XHRLoader); 27576 27577var _voMetricsHTTPRequest = _dereq_(224); 27578 27579var _voTextRequest = _dereq_(217); 27580 27581var _voTextRequest2 = _interopRequireDefault(_voTextRequest); 27582 27583var _coreEventBus = _dereq_(50); 27584 27585var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 27586 27587var _coreEventsEvents = _dereq_(54); 27588 27589var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 27590 27591var _coreFactoryMaker = _dereq_(51); 27592 27593var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 27594 27595var XLINK_LOADER_ERROR_LOADING_FAILURE = 1; 27596 27597function XlinkLoader(config) { 27598 27599 var RESOLVE_TO_ZERO = 'urn:mpeg:dash:resolve-to-zero:2013'; 27600 27601 var context = this.context; 27602 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 27603 27604 var xhrLoader = (0, _XHRLoader2['default'])(context).create({ 27605 errHandler: config.errHandler, 27606 metricsModel: config.metricsModel, 27607 mediaPlayerModel: config.mediaPlayerModel, 27608 requestModifier: config.requestModifier 27609 });
27610 27611 var instance = undefined; 27612 27613 function load(url, element, resolveObject) { 27614 var report = function report(content, resolveToZero) { 27615 element.resolved = true; 27616 element.resolvedContent = content ? content : null; 27617 27618 eventBus.trigger(_coreEventsEvents2['default'].XLINK_ELEMENT_LOADED, { 27619 element: element, 27620 resolveObject: resolveObject, 27621 error: content || resolveToZero ? null : new _voDashJSError2['default'](XLINK_LOADER_ERROR_LOADING_FAILURE, 'Failed loading Xlink element: ' + url) 27622 }); 27623 }; 27624 27625 if (url === RESOLVE_TO_ZERO) { 27626 report(null, true); 27627 } else { 27628 var request = new _voTextRequest2['default'](url, _voMetricsHTTPRequest.HTTPRequest.XLINK_TYPE); 27629 27630 xhrLoader.load({ 27631 request: request, 27632 success: function success(data) { 27633 report(data); 27634 }, 27635 error: function error() { 27636 report(null); 27637 } 27638 }); 27639 } 27640 } 27641 27642 function reset() { 27643 if (xhrLoader) { 27644 xhrLoader.abort(); 27645 xhrLoader = null; 27646 } 27647 } 27648 27649 instance = { 27650 load: load, 27651 reset: reset 27652 }; 27653 27654 return instance; 27655} 27656 27657XlinkLoader.__dashjs_factory_name = 'XlinkLoader'; 27658 27659var factory = _coreFactoryMaker2['default'].getClassFactory(XlinkLoader); 27660factory.XLINK_LOADER_ERROR_LOADING_FAILURE = XLINK_LOADER_ERROR_LOADING_FAILURE; 27661_coreFactoryMaker2['default'].updateClassFactory(XlinkLoader.__dashjs_factory_name, factory); 27662exports['default'] = factory; 27663module.exports = exports['default']; 27664 27665},{"207":207,"217":217,"224":224,"50":50,"51":51,"54":54,"98":98}],100:[function(_dereq_,module,exports){ 27666/** 27667 * The copyright in this software is being made available under the BSD License, 27668 * included below. This software may be subject to other third party and contributor 27669 * rights, including patent rights, and no such rights are granted under this license. 27670 * 27671 * Copyright (c) 2013, Dash Industry Forum. 27672 * All rights reserved. 27673 * 27674 * Redistribution and use in source and binary forms, with or without modification, 27675 * are permitted provided that the following conditions are met: 27676 * * Redistributions of source code must retain the above copyright notice, this 27677 * list of conditions and the following disclaimer. 27678 * * Redistributions in binary form must reproduce the above copyright notice, 27679 * this list of conditions and the following disclaimer in the documentation and/or 27680 * other materials provided with the distribution. 27681 * * Neither the name of Dash Industry Forum nor the names of its 27682 * contributors may be used to endorse or promote products derived from this software 27683 * without specific prior written permission. 27684 * 27685 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 27686 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27687 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27688 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27689 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27690 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27691 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27692 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27693 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27694 * POSSIBILITY OF SUCH DAMAGE. 27695 */ 27696 27697/** 27698 * Constants declaration 27699 * @class 27700 * @ignore 27701 */ 27702'use strict'; 27703 27704Object.defineProperty(exports, '__esModule', { 27705 value: true 27706}); 27707 27708var _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; }; })();
27709 27710function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 27711 27712var Constants = (function () { 27713 _createClass(Constants, [{ 27714 key: 'init', 27715 value: function init() { 27716 this.STREAM = 'stream'; 27717 this.VIDEO = 'video'; 27718 this.AUDIO = 'audio'; 27719 this.TEXT = 'text'; 27720 this.FRAGMENTED_TEXT = 'fragmentedText'; 27721 this.EMBEDDED_TEXT = 'embeddedText'; 27722 this.MUXED = 'muxed'; 27723 this.LOCATION = 'Location'; 27724 this.INITIALIZE = 'initialize'; 27725 this.TEXT_SHOWING = 'showing'; 27726 this.TEXT_HIDDEN = 'hidden'; 27727 this.CC1 = 'CC1'; 27728 this.CC3 = 'CC3'; 27729 this.STPP = 'stpp'; 27730 this.TTML = 'ttml'; 27731 this.VTT = 'vtt'; 27732 this.WVTT = 'wvtt'; 27733 this.UTF8 = 'utf-8'; 27734 this.SUGGESTED_PRESENTATION_DELAY = 'suggestedPresentationDelay'; 27735 this.SCHEME_ID_URI = 'schemeIdUri'; 27736 this.START_TIME = 'starttime'; 27737 this.ABR_STRATEGY_DYNAMIC = 'abrDynamic'; 27738 this.ABR_STRATEGY_BOLA = 'abrBola'; 27739 this.ABR_STRATEGY_THROUGHPUT = 'abrThroughput'; 27740 this.MOVING_AVERAGE_SLIDING_WINDOW = 'slidingWindow'; 27741 this.MOVING_AVERAGE_EWMA = 'ewma'; 27742 } 27743 }]); 27744 27745 function Constants() { 27746 _classCallCheck(this, Constants); 27747 27748 this.init(); 27749 } 27750 27751 return Constants; 27752})(); 27753 27754var constants = new Constants(); 27755exports['default'] = constants; 27756module.exports = exports['default']; 27757 27758},{}],101:[function(_dereq_,module,exports){ 27759/** 27760 * The copyright in this software is being made available under the BSD License, 27761 * included below. This software may be subject to other third party and contributor 27762 * rights, including patent rights, and no such rights are granted under this license. 27763 * 27764 * Copyright (c) 2013, Dash Industry Forum. 27765 * All rights reserved. 27766 * 27767 * Redistribution and use in source and binary forms, with or without modification, 27768 * are permitted provided that the following conditions are met: 27769 * * Redistributions of source code must retain the above copyright notice, this 27770 * list of conditions and the following disclaimer. 27771 * * Redistributions in binary form must reproduce the above copyright notice, 27772 * this list of conditions and the following disclaimer in the documentation and/or 27773 * other materials provided with the distribution. 27774 * * Neither the name of Dash Industry Forum nor the names of its 27775 * contributors may be used to endorse or promote products derived from this software 27776 * without specific prior written permission. 27777 * 27778 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 27779 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27780 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27781 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27782 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27783 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27784 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27785 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27786 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27787 * POSSIBILITY OF SUCH DAMAGE. 27788 */ 27789 27790/** 27791 * Metrics Constants declaration 27792 * @class 27793 * @ignore 27794 */ 27795'use strict'; 27796 27797Object.defineProperty(exports, '__esModule', { 27798 value: true 27799}); 27800 27801var _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; }; })();
27802 27803function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 27804 27805var MetricsConstants = (function () { 27806 _createClass(MetricsConstants, [{ 27807 key: 'init', 27808 value: function init() { 27809 this.TCP_CONNECTION = 'TcpList'; 27810 this.HTTP_REQUEST = 'HttpList'; 27811 this.TRACK_SWITCH = 'RepSwitchList'; 27812 this.BUFFER_LEVEL = 'BufferLevel'; 27813 this.BUFFER_STATE = 'BufferState'; 27814 this.DVR_INFO = 'DVRInfo'; 27815 this.DROPPED_FRAMES = 'DroppedFrames'; 27816 this.SCHEDULING_INFO = 'SchedulingInfo'; 27817 this.REQUESTS_QUEUE = 'RequestsQueue'; 27818 this.MANIFEST_UPDATE = 'ManifestUpdate'; 27819 this.MANIFEST_UPDATE_STREAM_INFO = 'ManifestUpdatePeriodInfo'; 27820 this.MANIFEST_UPDATE_TRACK_INFO = 'ManifestUpdateRepresentationInfo'; 27821 this.PLAY_LIST = 'PlayList'; 27822 this.DVB_ERRORS = 'DVBErrors'; 27823 } 27824 }]); 27825 27826 function MetricsConstants() { 27827 _classCallCheck(this, MetricsConstants); 27828 27829 this.init(); 27830 } 27831 27832 return MetricsConstants; 27833})(); 27834 27835var constants = new MetricsConstants(); 27836exports['default'] = constants; 27837module.exports = exports['default']; 27838 27839},{}],102:[function(_dereq_,module,exports){ 27840/** 27841 * The copyright in this software is being made available under the BSD License, 27842 * included below. This software may be subject to other third party and contributor 27843 * rights, including patent rights, and no such rights are granted under this license. 27844 * 27845 * Copyright (c) 2013, Dash Industry Forum. 27846 * All rights reserved. 27847 * 27848 * Redistribution and use in source and binary forms, with or without modification, 27849 * are permitted provided that the following conditions are met: 27850 * * Redistributions of source code must retain the above copyright notice, this 27851 * list of conditions and the following disclaimer. 27852 * * Redistributions in binary form must reproduce the above copyright notice, 27853 * this list of conditions and the following disclaimer in the documentation and/or 27854 * other materials provided with the distribution. 27855 * * Neither the name of Dash Industry Forum nor the names of its 27856 * contributors may be used to endorse or promote products derived from this software 27857 * without specific prior written permission. 27858 * 27859 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 27860 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27861 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27862 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27863 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27864 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27865 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27866 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27867 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27868 * POSSIBILITY OF SUCH DAMAGE. 27869 */ 27870 27871'use strict'; 27872 27873Object.defineProperty(exports, '__esModule', { 27874 value: true 27875}); 27876 27877function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 27878 27879var _rulesAbrABRRulesCollection = _dereq_(174); 27880 27881var _rulesAbrABRRulesCollection2 = _interopRequireDefault(_rulesAbrABRRulesCollection); 27882 27883var _constantsConstants = _dereq_(100); 27884 27885var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 27886 27887var _constantsMetricsConstants = _dereq_(101); 27888 27889var _constantsMetricsConstants2 = _interopRequireDefault(_constantsMetricsConstants); 27890 27891var _voBitrateInfo = _dereq_(206); 27892 27893var _voBitrateInfo2 = _interopRequireDefault(_voBitrateInfo); 27894 27895var _modelsFragmentModel = _dereq_(140); 27896 27897var _modelsFragmentModel2 = _interopRequireDefault(_modelsFragmentModel); 27898 27899var _coreEventBus = _dereq_(50); 27900 27901var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 27902 27903var _coreEventsEvents = _dereq_(54); 27904 27905var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 27906 27907var _coreFactoryMaker = _dereq_(51); 27908 27909var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 27910 27911var _rulesRulesContextJs = _dereq_(170); 27912 27913var _rulesRulesContextJs2 = _interopRequireDefault(_rulesRulesContextJs); 27914 27915var _rulesSwitchRequestJs = _dereq_(171); 27916 27917var _rulesSwitchRequestJs2 = _interopRequireDefault(_rulesSwitchRequestJs); 27918 27919var _rulesSwitchRequestHistoryJs = _dereq_(172); 27920 27921var _rulesSwitchRequestHistoryJs2 = _interopRequireDefault(_rulesSwitchRequestHistoryJs); 27922 27923var _rulesDroppedFramesHistoryJs = _dereq_(169); 27924 27925var _rulesDroppedFramesHistoryJs2 = _interopRequireDefault(_rulesDroppedFramesHistoryJs); 27926 27927var _rulesThroughputHistoryJs = _dereq_(173); 27928 27929var _rulesThroughputHistoryJs2 = _interopRequireDefault(_rulesThroughputHistoryJs); 27930 27931var _voMetricsHTTPRequest = _dereq_(224); 27932 27933var _coreDebug = _dereq_(49); 27934 27935var _coreDebug2 = _interopRequireDefault(_coreDebug); 27936 27937var ABANDON_LOAD = 'abandonload'; 27938var ALLOW_LOAD = 'allowload'; 27939var DEFAULT_VIDEO_BITRATE = 1000; 27940var DEFAULT_AUDIO_BITRATE = 100; 27941var QUALITY_DEFAULT = 0; 27942 27943function AbrController() { 27944 27945 var context = this.context; 27946 var debug = (0, _coreDebug2['default'])(context).getInstance(); 27947 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 27948 27949 var instance = undefined, 27950 log = undefined, 27951 abrRulesCollection = undefined, 27952 streamController = undefined, 27953 autoSwitchBitrate = undefined, 27954 topQualities = undefined, 27955 qualityDict = undefined, 27956 bitrateDict = undefined, 27957 ratioDict = undefined, 27958 streamProcessorDict = undefined, 27959 abandonmentStateDict = undefined, 27960 abandonmentTimeout = undefined, 27961 limitBitrateByPortal = undefined, 27962 usePixelRatioInLimitBitrateByPortal = undefined, 27963 windowResizeEventCalled = undefined, 27964 elementWidth = undefined, 27965 elementHeight = undefined, 27966 manifestModel = undefined, 27967 dashManifestModel = undefined, 27968 adapter = undefined, 27969 videoModel = undefined, 27970 mediaPlayerModel = undefined, 27971 domStorage = undefined, 27972 playbackIndex = undefined, 27973 switchHistoryDict = undefined, 27974 droppedFramesHistory = undefined, 27975 throughputHistory = undefined, 27976 isUsingBufferOccupancyABRDict = undefined, 27977 metricsModel = undefined, 27978 dashMetrics = undefined, 27979 useDeadTimeLatency = undefined; 27980 27981 function setup() { 27982 log = debug.log.bind(instance); 27983 27984 resetInitialSettings();
27985 } 27986 27987 function registerStreamType(type, streamProcessor) { 27988 switchHistoryDict[type] = (0, _rulesSwitchRequestHistoryJs2['default'])(context).create(); 27989 streamProcessorDict[type] = streamProcessor; 27990 abandonmentStateDict[type] = abandonmentStateDict[type] || {}; 27991 abandonmentStateDict[type].state = ALLOW_LOAD; 27992 isUsingBufferOccupancyABRDict[type] = false; 27993 eventBus.on(_coreEventsEvents2['default'].LOADING_PROGRESS, onFragmentLoadProgress, this); 27994 if (type == _constantsConstants2['default'].VIDEO) { 27995 eventBus.on(_coreEventsEvents2['default'].QUALITY_CHANGE_RENDERED, onQualityChangeRendered, this); 27996 droppedFramesHistory = (0, _rulesDroppedFramesHistoryJs2['default'])(context).create(); 27997 setElementSize(); 27998 } 27999 eventBus.on(_coreEventsEvents2['default'].METRIC_ADDED, onMetricAdded, this); 28000 throughputHistory = (0, _rulesThroughputHistoryJs2['default'])(context).create({ 28001 mediaPlayerModel: mediaPlayerModel 28002 }); 28003 } 28004 28005 function createAbrRulesCollection() { 28006 abrRulesCollection = (0, _rulesAbrABRRulesCollection2['default'])(context).create({ 28007 metricsModel: metricsModel, 28008 dashMetrics: dashMetrics, 28009 mediaPlayerModel: mediaPlayerModel, 28010 adapter: adapter 28011 }); 28012 28013 abrRulesCollection.initialize(); 28014 } 28015 28016 function resetInitialSettings() { 28017 autoSwitchBitrate = { video: true, audio: true }; 28018 topQualities = {}; 28019 qualityDict = {}; 28020 bitrateDict = {}; 28021 ratioDict = {}; 28022 abandonmentStateDict = {}; 28023 streamProcessorDict = {}; 28024 switchHistoryDict = {}; 28025 isUsingBufferOccupancyABRDict = {}; 28026 limitBitrateByPortal = false; 28027 useDeadTimeLatency = true; 28028 usePixelRatioInLimitBitrateByPortal = false; 28029 if (windowResizeEventCalled === undefined) { 28030 windowResizeEventCalled = false; 28031 } 28032 playbackIndex = undefined; 28033 droppedFramesHistory = undefined; 28034 throughputHistory = undefined; 28035 clearTimeout(abandonmentTimeout); 28036 abandonmentTimeout = null; 28037 } 28038 28039 function reset() { 28040 28041 resetInitialSettings(); 28042 28043 eventBus.off(_coreEventsEvents2['default'].LOADING_PROGRESS, onFragmentLoadProgress, this); 28044 eventBus.off(_coreEventsEvents2['default'].QUALITY_CHANGE_RENDERED, onQualityChangeRendered, this); 28045 eventBus.off(_coreEventsEvents2['default'].METRIC_ADDED, onMetricAdded, this); 28046 28047 if (abrRulesCollection) { 28048 abrRulesCollection.reset(); 28049 } 28050 } 28051 28052 function setConfig(config) { 28053 if (!config) return; 28054 28055 if (config.streamController) { 28056 streamController = config.streamController; 28057 } 28058 if (config.domStorage) { 28059 domStorage = config.domStorage; 28060 } 28061 if (config.mediaPlayerModel) { 28062 mediaPlayerModel = config.mediaPlayerModel; 28063 } 28064 if (config.metricsModel) { 28065 metricsModel = config.metricsModel; 28066 } 28067 if (config.dashMetrics) { 28068 dashMetrics = config.dashMetrics; 28069 } 28070 if (config.dashManifestModel) { 28071 dashManifestModel = config.dashManifestModel; 28072 } 28073 if (config.adapter) { 28074 adapter = config.adapter; 28075 } 28076 if (config.manifestModel) { 28077 manifestModel = config.manifestModel; 28078 } 28079 if (config.videoModel) { 28080 videoModel = config.videoModel; 28081 } 28082 } 28083 28084 function onQualityChangeRendered(e) { 28085 if (e.mediaType === _constantsConstants2['default'].VIDEO) { 28086 playbackIndex = e.oldQuality; 28087 droppedFramesHistory.push(playbackIndex, videoModel.getPlaybackQuality()); 28088 } 28089 } 28090 28091 function onMetricAdded(e) { 28092 if (e.metric === _constantsMetricsConstants2['default'].HTTP_REQUEST && e.value && e.value.type === _voMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE && (e.mediaType === _constantsConstants2['default'].AUDIO || e.mediaType === _constantsConstants2['default'].VIDEO)) { 28093 throughputHistory.push(e.mediaType, e.value, useDeadTimeLatency);
28094 } 28095 28096 if (e.metric === _constantsMetricsConstants2['default'].BUFFER_LEVEL && (e.mediaType === _constantsConstants2['default'].AUDIO || e.mediaType === _constantsConstants2['default'].VIDEO)) { 28097 updateIsUsingBufferOccupancyABR(e.mediaType, 0.001 * e.value.level); 28098 } 28099 } 28100 28101 function getTopQualityIndexFor(type, id) { 28102 var idx = undefined; 28103 topQualities[id] = topQualities[id] || {}; 28104 28105 if (!topQualities[id].hasOwnProperty(type)) { 28106 topQualities[id][type] = 0; 28107 } 28108 28109 idx = checkMaxBitrate(topQualities[id][type], type); 28110 idx = checkMaxRepresentationRatio(idx, type, topQualities[id][type]); 28111 idx = checkPortalSize(idx, type); 28112 return idx; 28113 } 28114 28115 /** 28116 * @param {string} type 28117 * @returns {number} A value of the initial bitrate, kbps 28118 * @memberof AbrController# 28119 */ 28120 function getInitialBitrateFor(type) { 28121 28122 var savedBitrate = domStorage.getSavedBitrateSettings(type); 28123 28124 if (!bitrateDict.hasOwnProperty(type)) { 28125 if (ratioDict.hasOwnProperty(type)) { 28126 var manifest = manifestModel.getValue(); 28127 var representation = dashManifestModel.getAdaptationForType(manifest, 0, type).Representation; 28128 28129 if (Array.isArray(representation)) { 28130 var repIdx = Math.max(Math.round(representation.length * ratioDict[type]) - 1, 0); 28131 bitrateDict[type] = representation[repIdx].bandwidth; 28132 } else { 28133 bitrateDict[type] = 0; 28134 } 28135 } else if (!isNaN(savedBitrate)) { 28136 bitrateDict[type] = savedBitrate; 28137 } else { 28138 bitrateDict[type] = type === _constantsConstants2['default'].VIDEO ? DEFAULT_VIDEO_BITRATE : DEFAULT_AUDIO_BITRATE; 28139 } 28140 } 28141 28142 return bitrateDict[type]; 28143 } 28144 28145 /** 28146 * @param {string} type 28147 * @param {number} value A value of the initial bitrate, kbps 28148 * @memberof AbrController# 28149 */ 28150 function setInitialBitrateFor(type, value) { 28151 bitrateDict[type] = value; 28152 } 28153 28154 function getInitialRepresentationRatioFor(type) { 28155 if (!ratioDict.hasOwnProperty(type)) { 28156 return null; 28157 } 28158 28159 return ratioDict[type]; 28160 } 28161 28162 function setInitialRepresentationRatioFor(type, value) { 28163 ratioDict[type] = value; 28164 } 28165 28166 function getMaxAllowedBitrateFor(type) { 28167 if (bitrateDict.hasOwnProperty('max') && bitrateDict.max.hasOwnProperty(type)) { 28168 return bitrateDict.max[type]; 28169 } 28170 return NaN; 28171 } 28172 28173 function getMinAllowedBitrateFor(type) { 28174 if (bitrateDict.hasOwnProperty('min') && bitrateDict.min.hasOwnProperty(type)) { 28175 return bitrateDict.min[type]; 28176 } 28177 return NaN; 28178 } 28179 28180 //TODO change bitrateDict structure to hold one object for video and audio with initial and max values internal. 28181 // This means you need to update all the logic around initial bitrate DOMStorage, RebController etc... 28182 function setMaxAllowedBitrateFor(type, value) { 28183 bitrateDict.max = bitrateDict.max || {}; 28184 bitrateDict.max[type] = value; 28185 } 28186 28187 function setMinAllowedBitrateFor(type, value) { 28188 bitrateDict.min = bitrateDict.min || {}; 28189 bitrateDict.min[type] = value; 28190 } 28191 28192 function getMaxAllowedRepresentationRatioFor(type) { 28193 if (ratioDict.hasOwnProperty('max') && ratioDict.max.hasOwnProperty(type)) { 28194 return ratioDict.max[type]; 28195 } 28196 return 1; 28197 } 28198 28199 function setMaxAllowedRepresentationRatioFor(type, value) { 28200 ratioDict.max = ratioDict.max || {}; 28201 ratioDict.max[type] = value; 28202 } 28203 28204 function getAutoSwitchBitrateFor(type) { 28205 return autoSwitchBitrate[type]; 28206 } 28207 28208 function setAutoSwitchBitrateFor(type, value) { 28209 autoSwitchBitrate[type] = value; 28210 } 28211 28212 function getLimitBitrateByPortal() { 28213 return limitBitrateByPortal; 28214 } 28215 28216 function setLimitBitrateByPortal(value) { 28217 limitBitrateByPortal = value; 28218 } 28219 28220 function getUsePixelRatioInLimitBitrateByPortal() { 28221 return usePixelRatioInLimitBitrateByPortal; 28222 } 28223 28224 function setUsePixelRatioInLimitBitrateByPortal(value) { 28225 usePixelRatioInLimitBitrateByPortal = value; 28226 } 28227 28228 function getUseDeadTimeLatency() { 28229 return useDeadTimeLatency; 28230 } 28231 28232 function setUseDeadTimeLatency(value) { 28233 useDeadTimeLatency = value; 28234 } 28235 28236 function checkPlaybackQuality(type) { 28237 if (type && streamProcessorDict && streamProcessorDict[type]) { 28238 var streamInfo = streamProcessorDict[type].getStreamInfo(); 28239 var streamId = streamInfo ? streamInfo.id : null; 28240 var oldQuality = getQualityFor(type); 28241 var rulesContext = (0, _rulesRulesContextJs2['default'])(context).create({ 28242 abrController: instance, 28243 streamProcessor: streamProcessorDict[type], 28244 currentValue: oldQuality, 28245 switchHistory: switchHistoryDict[type], 28246 droppedFramesHistory: droppedFramesHistory, 28247 useBufferOccupancyABR: useBufferOccupancyABR(type) 28248 }); 28249 28250 if (droppedFramesHistory) { 28251 droppedFramesHistory.push(playbackIndex, videoModel.getPlaybackQuality()); 28252 } 28253 28254 //log("ABR enabled? (" + autoSwitchBitrate + ")"); 28255 if (getAutoSwitchBitrateFor(type)) { 28256 var topQualityIdx = getTopQualityIndexFor(type, streamId); 28257 var switchRequest = abrRulesCollection.getMaxQuality(rulesContext); 28258 var newQuality = switchRequest.quality; 28259 if (newQuality > topQualityIdx) { 28260 newQuality = topQualityIdx; 28261 } 28262 switchHistoryDict[type].push({ oldValue: oldQuality, newValue: newQuality }); 28263 28264 if (newQuality > _rulesSwitchRequestJs2['default'].NO_CHANGE && newQuality != oldQuality) { 28265 if (abandonmentStateDict[type].state === ALLOW_LOAD || newQuality > oldQuality) { 28266 changeQuality(type, oldQuality, newQuality, topQualityIdx, switchRequest.reason); 28267 } 28268 } else if (debug.getLogToBrowserConsole()) { 28269 var bufferLevel = dashMetrics.getCurrentBufferLevel(metricsModel.getReadOnlyMetricsF
28269or(type)); 28270 log('AbrController (' + type + ') stay on ' + oldQuality + '/' + topQualityIdx + ' (buffer: ' + bufferLevel + ')'); 28271 } 28272 } 28273 } 28274 } 28275 28276 function setPlaybackQuality(type, streamInfo, newQuality, reason) { 28277 var id = streamInfo.id; 28278 var oldQuality = getQualityFor(type); 28279 var isInt = newQuality !== null && !isNaN(newQuality) && newQuality % 1 === 0; 28280 28281 if (!isInt) throw new Error('argument is not an integer'); 28282 28283 var topQualityIdx = getTopQualityIndexFor(type, id); 28284 if (newQuality !== oldQuality && newQuality >= 0 && newQuality <= topQualityIdx) { 28285 changeQuality(type, oldQuality, newQuality, topQualityIdx, reason); 28286 } 28287 } 28288 28289 function changeQuality(type, oldQuality, newQuality, topQualityIdx, reason) { 28290 if (type && streamProcessorDict[type]) { 28291 var streamInfo = streamProcessorDict[type].getStreamInfo(); 28292 var id = streamInfo ? streamInfo.id : null; 28293 if (debug.getLogToBrowserConsole()) { 28294 var bufferLevel = dashMetrics.getCurrentBufferLevel(metricsModel.getReadOnlyMetricsFor(type)); 28295 log('AbrController (' + type + ') switch from ' + oldQuality + ' to ' + newQuality + '/' + topQualityIdx + ' (buffer: ' + bufferLevel + ')\n' + JSON.stringify(reason)); 28296 } 28297 setQualityFor(type, id, newQuality); 28298 eventBus.trigger(_coreEventsEvents2['default'].QUALITY_CHANGE_REQUESTED, { mediaType: type, streamInfo: streamInfo, oldQuality: oldQuality, newQuality: newQuality, reason: reason }); 28299 } 28300 } 28301 28302 function setAbandonmentStateFor(type, state) { 28303 abandonmentStateDict[type].state = state; 28304 } 28305 28306 function getAbandonmentStateFor(type) { 28307 return abandonmentStateDict[type].state; 28308 } 28309 28310 /** 28311 * @param {MediaInfo} mediaInfo 28312 * @param {number} bitrate A bitrate value, kbps 28313 * @param {number} latency Expected latency of connection, ms 28314 * @returns {number}
28314 A quality index <= for the given bitrate 28315 * @memberof AbrController# 28316 */ 28317 function getQualityForBitrate(mediaInfo, bitrate, latency) { 28318 if (useDeadTimeLatency && latency && streamProcessorDict[mediaInfo.type].getCurrentRepresentationInfo() && streamProcessorDict[mediaInfo.type].getCurrentRepresentationInfo().fragmentDuration) { 28319 latency = latency / 1000; 28320 var fragmentDuration = streamProcessorDict[mediaInfo.type].getCurrentRepresentationInfo().fragmentDuration; 28321 if (latency > fragmentDuration) { 28322 return 0; 28323 } else { 28324 var deadTimeRatio = latency / fragmentDuration; 28325 bitrate = bitrate * (1 - deadTimeRatio); 28326 } 28327 } 28328 28329 var bitrateList = getBitrateList(mediaInfo); 28330 if (!bitrateList || bitrateList.length === 0) { 28331 return QUALITY_DEFAULT; 28332 } 28333 28334 for (var i = bitrateList.length - 1; i >= 0; i--) { 28335 var bitrateInfo = bitrateList[i]; 28336 if (bitrate * 1000 >= bitrateInfo.bitrate) { 28337 return i; 28338 } 28339 } 28340 return 0; 28341 } 28342 28343 /** 28344 * @param {MediaInfo} mediaInfo 28345 * @returns {Array|null} A list of {@link BitrateInfo} objects 28346 * @memberof AbrController# 28347 */ 28348 function getBitrateList(mediaInfo) { 28349 if (!mediaInfo || !mediaInfo.bitrateList) return null; 28350 28351 var bitrateList = mediaInfo.bitrateList; 28352 var type = mediaInfo.type; 28353 28354 var infoList = []; 28355 var bitrateInfo = undefined; 28356 28357 for (var i = 0, ln = bitrateList.length; i < ln; i++) { 28358 bitrateInfo = new _voBitrateInfo2['default'](); 28359 bitrateInfo.mediaType = type; 28360 bitrateInfo.qualityIndex = i; 28361 bitrateInfo.bitrate = bitrateList[i].bandwidth; 28362 bitrateInfo.width = bitrateList[i].width; 28363 bitrateInfo.height = bitrateList[i].height; 28364 bitrateInfo.scanType = bitrateList[i].scanType; 28365 infoList.push(bitrateInfo); 28366 } 28367 28368 return infoList; 28369 } 28370 28371 function updateIsUsingBufferOccupancyABR(mediaType, bufferLevel) { 28372 var strategy = mediaPlayerModel.getABRStrategy(); 28373 28374 if (strategy === _constantsConstants2['default'].ABR_STRATEGY_BOLA) { 28375 isUsingBufferOccupancyABRDict[mediaType] = true; 28376 return; 28377 } else if (strategy === _constantsConstants2['default'].ABR_STRATEGY_THROUGHPUT) { 28378 isUsingBufferOccupancyABRDict[mediaType] = false; 28379 return; 28380 } 28381 // else ABR_STRATEGY_DYNAMIC 28382 28383 var stableBufferTime = mediaPlayerModel.getStableBufferTime(); 28384 var switchOnThreshold = stableBufferTime; 28385 var switchOffThreshold = 0.5 * stableBufferTime; 28386 28387 var useBufferABR = isUsingBufferOccupancyABRDict[mediaType]; 28388 var newUseBufferABR = bufferLevel > (useBufferABR ? switchOffThreshold : switchOnThreshold); // use hysteresis to avoid oscillating rules 28389 isUsingBufferOccupancyABRDict[mediaType] = newUseBufferABR; 28390 28391 if (newUseBufferABR !== useBufferABR) { 28392 if (newUseBufferABR) { 28393 log('AbrController (' + mediaType + ') switching from throughput to buffer occupancy ABR rule (buffer: ' + bufferLevel.toFixed(3) + ').'); 28394 } else { 28395 log('AbrController (' + mediaType + ') switching from buffer occupancy to throughput ABR rule (buffer: ' + bufferLevel.toFixed(3) + ').'); 28396 } 28397 } 28398 } 28399 28400 function useBufferOccupancyABR(mediaType) { 28401 return isUsingBufferOccupancyABRDict[mediaType]; 28402 } 28403 28404 function getThroughputHistory() { 28405 return throughputHistory; 28406 } 28407 28408 function updateTopQualityIndex(mediaInfo) { 28409 var type = mediaInfo.type; 28410 var streamId = mediaInfo.streamInfo.id; 28411 var max = mediaInfo.representationCount - 1; 28412 28413 setTopQualityIndex(type, streamId, max); 28414 28415 return max; 28416 } 28417 28418 function isPlayingAtTopQuality(streamInfo) { 28419 var isAtTop = undefined; 28420 var streamId = streamInfo.id; 28421 var audioQuality = getQualityFor(_constantsConstants2['default'].AUDIO); 28422 var videoQuality = getQualityFor(_constantsConstants2['default'].VIDEO); 28423 28424 isAtTop = audioQuality === getTopQualityIndexFor(_constantsConstants2['default'].AUDIO, streamId) && videoQuality === getTopQualityIndexFor(_constantsConstants2['default'].VIDEO, streamId); 28425 28426 return isAtTop; 28427 } 28428 28429 function getQualityFor(type) { 28430 if (type && streamProcessorDict[type]) { 28431 var streamInfo = streamProcessorDict[type].getStreamInfo(); 28432 var id = streamInfo ? streamInfo.id : null; 28433 var quality = undefined; 28434 28435 if (id) { 28436 qualityDict[id] = qualityDict[id] || {}; 28437 28438 if (!qualityDict[id].hasOwnProperty(type)) { 28439 qualityDict[id][type] = QUALITY_DEFAULT; 28440 } 28441 28442 quality = qualityDict[id][type]; 28443 return quality; 28444 } 28445 } 28446 return QUALITY_DEFAULT; 28447 } 28448 28449 function setQualityFor(type, id, value) { 28450 qualityDict[id] = qualityDict[id] || {}; 28451 qualityDict[id][type] = value; 28452 } 28453 28454 function setTopQualityIndex(type, id, value) { 28455 topQualities[id] = topQualities[id] || {}; 28456 topQualities[id][type] = value; 28457 } 28458 28459 function checkMaxBitrate(idx, type) { 28460 var newIdx = idx; 28461 28462 if (!streamProcessorDict[type]) { 28463 return newIdx; 28464 } 28465 28466 var minBitrate = getMinAllowedBitrateFor(type); 28467 if (minBitrate) { 28468 var minIdx = getQualityForBitrate(streamProcessorDict[type].getMediaInfo(), minBitrate); 28469 newIdx = Math.max(idx, minIdx); 28470 } 28471 28472 var maxBitrate = getMaxAllowedBitrateFor(type); 28473 if (maxBitrate) { 28474 var maxIdx = getQualityForBitrate(streamProcessorDict[type].getMediaInfo(), maxBitrate); 28475 newIdx = Math.min(newIdx, maxIdx); 28476 } 28477 28478 return newIdx; 28479 } 28480 28481 function checkMaxRepresentationRatio(idx, type, maxIdx) { 28482 var maxRepresentationRatio = getMaxAllowedRepresentationRatioFor(type); 28483 if (isNaN(maxRepresentationRatio) || maxRepresentationRatio >= 1 || maxRepresentationRatio < 0) { 28484 return idx; 28485 } 28486 return Math.min(idx, Math.round(maxIdx * maxRepresentationRatio)); 28487 } 28488 28489 function setWindowResizeEventCalled(value) { 28490 windowResizeEventCalled = value; 28491 } 28492 28493 function setElementSize() { 28494 var hasPixelRatio = usePixelRatioInLimitBitrateByPortal && window.hasOwnProperty('devicePixelRatio'); 28495 var pixelRatio = hasPixelRatio ? window.devicePixelRatio : 1; 28496 elementWidth = videoModel.getClientWidth() * pixelRatio; 28497 elementHeight = videoModel.getClientHeight() * pixelRatio; 28498 } 28499 28500 function checkPortalSize(idx, type) { 28501 if (type !== _constantsConstants2['default'].VIDEO || !limitBitrateByPortal || !streamProcessorDict[type]) { 28502 return idx; 28503 } 28504 28505 if (!windowResizeEventCalled) { 28506 setElementSize(); 28507 } 28508 28509 var manifest = manifestModel.getValue(); 28510 var representation = dashManifestModel.getAdaptationForType(manifest, 0, type).Representation; 28511 var newIdx = idx; 28512 28513 if (elementWidth > 0 && elementHeight > 0) { 28514 while (newIdx > 0 && representation[newIdx] && elementWidth < representation[newIdx].width && elementWidth - representation[newIdx - 1].width < representation[newIdx].width - elementWidth) { 28515 newIdx = newIdx - 1; 28516 } 28517 28518 if (representation.length - 2 >= newIdx && representation[newIdx].width === representation[newIdx + 1].width) { 28519 newIdx = Math.min(idx, newIdx + 1); 28520 } 28521 } 28522 28523 return newIdx; 28524 } 28525 28526 function onFragmentLoadProgress(e) { 28527 var type = e.request.mediaType; 28528 if (getAutoSwitchBitrateFor(type)) { 28529 var streamProcessor = streamProcessorDict[type]; 28530 if (!streamProcessor) return; // There may be a fragment load in progress when we switch periods and recreated some controllers. 28531 28532 var rulesContext = (0, _rulesRulesContextJs2['default'])(context).create({ 28533 abrController: instance, 28534 streamProcessor: streamProcessor, 28535 currentRequest: e.request, 28536 useBufferOccupancyABR: useBufferOccupancyABR(type) 28537 }); 28538 var switchRequest = abrRulesCollection.shouldAbandonFragment(rulesContext); 28539 //Removed overrideFunc 28540 // function (currentValue, newValue) { 28541 // return newValue; 28542 // });
28543 28544 if (switchRequest.quality > _rulesSwitchRequestJs2['default'].NO_CHANGE) { 28545 var fragmentModel = streamProcessor.getFragmentModel(); 28546 var request = fragmentModel.getRequests({ state: _modelsFragmentModel2['default'].FRAGMENT_MODEL_LOADING, index: e.request.index })[0]; 28547 if (request) { 28548 //TODO Check if we should abort or if better to finish download. check bytesLoaded/Total 28549 fragmentModel.abortRequests(); 28550 setAbandonmentStateFor(type, ABANDON_LOAD); 28551 switchHistoryDict[type].reset(); 28552 switchHistoryDict[type].push({ oldValue: getQualityFor(type, streamController.getActiveStreamInfo()), newValue: switchRequest.quality, confidence: 1, reason: switchRequest.reason }); 28553 setPlaybackQuality(type, streamController.getActiveStreamInfo(), switchRequest.quality, switchRequest.reason); 28554 28555 clearTimeout(abandonmentTimeout); 28556 abandonmentTimeout = setTimeout(function () { 28557 setAbandonmentStateFor(type, ALLOW_LOAD);abandonmentTimeout = null; 28558 }, mediaPlayerModel.getAbandonLoadTimeout()); 28559 } 28560 } 28561 } 28562 } 28563 28564 instance = { 28565 isPlayingAtTopQuality: isPlayingAtTopQuality, 28566 updateTopQualityIndex: updateTopQualityIndex, 28567 getThroughputHistory: getThroughputHistory, 28568 getBitrateList: getBitrateList, 28569 getQualityForBitrate: getQualityForBitrate, 28570 getMaxAllowedBitrateFor: getMaxAllowedBitrateFor, 28571 getMinAllowedBitrateFor: getMinAllowedBitrateFor, 28572 setMaxAllowedBitrateFor: setMaxAllowedBitrateFor, 28573 setMinAllowedBitrateFor: setMinAllowedBitrateFor, 28574 getMaxAllowedRepresentationRatioFor: getMaxAllowedRepresentationRatioFor, 28575 setMaxAllowedRepresentationRatioFor: setMaxAllowedRepresentationRatioFor, 28576 getInitialBitrateFor: getInitialBitrateFor, 28577 setInitialBitrateFor: setInitialBitrateFor, 28578 getInitialRepresentationRatioFor: getInitialRepresentationRatioFor, 28579 setInitialRepresentationRatioFor: setInitialRepresentationRatioFor, 28580 setAutoSwitchBitrateFor: setAutoSwitchBitrateFor, 28581 getAutoSwitchBitrateFor: getAutoSwitchBitrateFor, 28582 getUseDeadTimeLatency: getUseDeadTimeLatency, 28583 setUseDeadTimeLatency: setUseDeadTimeLatency, 28584 setLimitBitrateByPortal: setLimitBitrateByPortal, 28585 getLimitBitrateByPortal: getLimitBitrateByPortal, 28586 getUsePixelRatioInLimitBitrateByPortal: getUsePixelRatioInLimitBitrateByPortal, 28587 setUsePixelRatioInLimitBitrateByPortal: setUsePixelRatioInLimitBitrateByPortal, 28588 getQualityFor: getQualityFor, 28589 getAbandonmentStateFor: getAbandonmentStateFor, 28590 setPlaybackQuality: setPlaybackQuality, 28591 checkPlaybackQuality: checkPlaybackQuality, 28592 getTopQualityIndexFor: getTopQualityIndexFor, 28593 setElementSize: setElementSize, 28594 setWindowResizeEventCalled: setWindowResizeEventCalled, 28595 createAbrRulesCollection: createAbrRulesCollection, 28596 registerStreamType: registerStreamType, 28597 setConfig: setConfig, 28598 reset: reset 28599 }; 28600 28601 setup(); 28602 28603 return instance; 28604} 28605 28606AbrController.__dashjs_factory_name = 'AbrController'; 28607var factory = _coreFactoryMaker2['default'].getSingletonFactory(AbrController); 28608factory.ABANDON_LOAD = ABANDON_LOAD; 28609factory.QUALITY_DEFAULT = QUALITY_DEFAULT; 28610_coreFactoryMaker2['default'].updateSingletonFactory(AbrController.__dashjs_factory_name, factory); 28611exports['default'] = factory; 28612module.exports = exports['default']; 28613 28614},{"100":100,"101":101,"140":140,"169":169,"170":170,"171":171,"172":172,"173":173,"174":174,"206":206,"224":224,"49":49,"50":50,"51":51,"54":54}],103:[function(_dereq_,module,exports){ 28615/** 28616 * The copyright in this software is being made available under the BSD License, 28617 * included below. This software may be subject to other third party and contributor 28618 * rights, including patent rights, and no such rights are granted under this license. 28619 * 28620 * Copyright (c) 2013, Dash Industry Forum. 28621 * All rights reserved. 28622 * 28623 * Redistribution and use in source and binary forms, with or without modification, 28624 * are permitted provided that the following conditions are met: 28625 * * Redistributions of source code must retain the above copyright notice, this 28626 * list of conditions and the following disclaimer. 28627 * * Redistributions in binary form must reproduce the above copyright notice, 28628 * this list of conditions and the following disclaimer in the documentation and/or 28629 * other materials provided with the distribution. 28630 * * Neither the name of Dash Industry Forum nor the names of its 28631 * contributors may be used to endorse or promote products derived from this software 28632 * without specific prior written permission. 28633 * 28634 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 28635 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 28636 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28637 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28638 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
28638INCLUDING, BUT 28639 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28640 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28641 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28642 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28643 * POSSIBILITY OF SUCH DAMAGE. 28644 */ 28645 28646'use strict'; 28647 28648Object.defineProperty(exports, '__esModule', { 28649 value: true 28650}); 28651 28652function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 28653 28654var _modelsBaseURLTreeModel = _dereq_(139); 28655 28656var _modelsBaseURLTreeModel2 = _interopRequireDefault(_modelsBaseURLTreeModel); 28657 28658var _utilsBaseURLSelector = _dereq_(189); 28659 28660var _utilsBaseURLSelector2 = _interopRequireDefault(_utilsBaseURLSelector); 28661 28662var _utilsURLUtils = _dereq_(202); 28663 28664var _utilsURLUtils2 = _interopRequireDefault(_utilsURLUtils); 28665 28666var _dashVoBaseURL = _dereq_(82); 28667 28668var _dashVoBaseURL2 = _interopRequireDefault(_dashVoBaseURL); 28669 28670var _coreFactoryMaker = _dereq_(51); 28671 28672var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 28673 28674var _coreEventBus = _dereq_(50); 28675 28676var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 28677 28678var _coreEventsEvents = _dereq_(54); 28679 28680var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 28681 28682function BaseURLController() { 28683 28684 var instance = undefined; 28685 var dashManifestModel = undefined; 28686 28687 var context = this.context; 28688 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 28689 var urlUtils = (0, _utilsURLUtils2['default'])(context).getInstance(); 28690 28691 var baseURLTreeModel = undefined, 28692 baseURLSelector = undefined; 28693 28694 function onBlackListChanged(e) { 28695 baseURLTreeModel.invalidateSelectedIndexes(e.entry); 28696 } 28697 28698 function setup() { 28699 baseURLTreeModel = (0, _modelsBaseURLTreeModel2['default'])(context).create(); 28700 baseURLSelector = (0, _utilsBaseURLSelector2['default'])(context).create(); 28701 28702 eventBus.on(_coreEventsEvents2['default'].SERVICE_LOCATION_BLACKLIST_CHANGED, onBlackListChanged, instance); 28703 } 28704 28705 function setConfig(config) { 28706 if (config.baseURLTreeModel) { 28707 baseURLTreeModel = config.baseURLTreeModel; 28708 } 28709 28710 if (config.baseURLSelector) { 28711 baseURLSelector = config.baseURLSelector; 28712 } 28713 28714 if (config.dashManifestModel) { 28715 dashManifestModel = config.dashManifestModel; 28716 } 28717 } 28718 28719 function update(manifest) { 28720 baseURLTreeModel.update(manifest); 28721 baseURLSelector.chooseSelectorFromManifest(manifest); 28722 } 28723 28724 function resolve(path) { 28725 var baseUrls = baseURLTreeModel.getForPath(path); 28726 28727 var baseUrl = baseUrls.reduce(function (p, c) { 28728 var b = baseURLSelector.select(c); 28729 28730 if (b) { 28731 if (!urlUtils.isRelative(b.url)) { 28732 p.url = b.url; 28733 p.serviceLocation = b.serviceLocation; 28734 } else { 28735 p.url = urlUtils.resolve(b.url, p.url); 28736 } 28737 } else { 28738 return new _dashVoBaseURL2['default'](); 28739 } 28740 28741 return p; 28742 }, new _dashVoBaseURL2['default']()); 28743 28744 if (!urlUtils.isRelative(baseUrl.url)) { 28745 return baseUrl; 28746 } 28747 } 28748 28749 function reset() { 28750 baseURLTreeModel.reset(); 28751 baseURLSelector.reset(); 28752 } 28753 28754 function initialize(data) { 28755 28756 // report config to baseURLTreeModel and baseURLSelector 28757 baseURLTreeModel.setConfig({ 28758 dashManifestModel: dashManifestModel 28759 }); 28760 baseURLSelector.setConfig({ 28761 dashManifestModel: dashManifestModel 28762 }); 28763 28764 update(data); 28765 } 28766 28767 instance = { 28768 reset: reset, 28769 initialize: initialize, 28770 resolve: resolve, 28771 setConfig: setConfig 28772 }; 28773 28774 setup(); 28775 28776 return instance; 28777} 28778 28779BaseURLController.__dashjs_factory_name = 'BaseURLController'; 28780exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(BaseURLController); 28781module.exports = exports['default']; 28782 28783},{"139":139,"189":189,"202":202,"50":50,"51":51,"54":54,"82":82}],104:[function(_dereq_,module,exports){ 28784/** 28785 * The copyright in this software is being made available under the BSD License, 28786 * included below. This software may be subject to other third party and contributor 28787 * rights, including patent rights, and no such rights are granted under this license. 28788 * 28789 * Copyright (c) 2013, Dash Industry Forum. 28790 * All rights reserved. 28791 * 28792 * Redistribution and use in source and binary forms, with or without modification, 28793 * are permitted provided that the following conditions are met: 28794 * * Redistributions of source code must retain the above copyright notice, this 28795 * list of conditions and the following disclaimer. 28796 * * Redistributions in binary form must reproduce the above copyright notice, 28797 * this list of conditions and the following disclaimer in the documentation and/or 28798 * other materials provided with the distribution. 28799 * * Neither the name of Dash Industry Forum nor the names of its 28800 * contributors may be used to endorse or promote products derived from this software 28801 * without specific prior written permission. 28802 * 28803 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 28804 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 28805 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28806 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28807 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
28807INCLUDING, BUT 28808 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28809 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28810 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28811 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28812 * POSSIBILITY OF SUCH DAMAGE. 28813 */ 28814 28815'use strict'; 28816 28817Object.defineProperty(exports, '__esModule', { 28818 value: true 28819}); 28820 28821function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 28822 28823var _coreFactoryMaker = _dereq_(51); 28824 28825var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 28826 28827var _coreEventBus = _dereq_(50); 28828 28829var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 28830 28831function BlackListController(config) { 28832 28833 var blacklist = []; 28834 28835 var eventBus = (0, _coreEventBus2['default'])(this.context).getInstance(); 28836 var updateEventName = config.updateEventName; 28837 var addBlacklistEventName = config.addBlacklistEventName; 28838 28839 function contains(query) { 28840 if (!blacklist.length || !query || !query.length) { 28841 return false; 28842 } 28843 28844 return blacklist.indexOf(query) !== -1; 28845 } 28846 28847 function add(entry) { 28848 if (blacklist.indexOf(entry) !== -1) { 28849 return; 28850 } 28851 28852 blacklist.push(entry); 28853 28854 eventBus.trigger(updateEventName, { 28855 entry: entry 28856 }); 28857 } 28858 28859 function onAddBlackList(e) { 28860 add(e.entry); 28861 } 28862 28863 function setup() { 28864 if (addBlacklistEventName) { 28865 eventBus.on(addBlacklistEventName, onAddBlackList, this); 28866 } 28867 } 28868 28869 function reset() { 28870 blacklist = []; 28871 } 28872 28873 setup(); 28874 28875 return { 28876 add: add, 28877 contains: contains, 28878 reset: reset 28879 }; 28880} 28881 28882BlackListController.__dashjs_factory_name = 'BlackListController'; 28883exports['default'] = _coreFactoryMaker2['default'].getClassFactory(BlackListController); 28884module.exports = exports['default']; 28885 28886},{"50":50,"51":51}],105:[function(_dereq_,module,exports){ 28887/** 28888 * The copyright in this software is being made available under the BSD License, 28889 * included below. This software may be subject to other third party and contributor 28890 * rights, including patent rights, and no such rights are granted under this license. 28891 * 28892 * Copyright (c) 2013, Dash Industry Forum. 28893 * All rights reserved. 28894 * 28895 * Redistribution and use in source and binary forms, with or without modification, 28896 * are permitted provided that the following conditions are met: 28897 * * Redistributions of source code must retain the above copyright notice, this 28898 * list of conditions and the following disclaimer. 28899 * * Redistributions in binary form must reproduce the above copyright notice, 28900 * this list of conditions and the following disclaimer in the documentation and/or 28901 * other materials provided with the distribution. 28902 * * Neither the name of Dash Industry Forum nor the names of its 28903 * contributors may be used to endorse or promote products derived from this software 28904 * without specific prior written permission. 28905 * 28906 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 28907 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 28908 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28909 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28910 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28911 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28912 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28913 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28914 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28915 * POSSIBILITY OF SUCH DAMAGE. 28916 */ 28917'use strict'; 28918 28919Object.defineProperty(exports, '__esModule', { 28920 value: true 28921}); 28922 28923function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 28924 28925var _constantsConstants = _dereq_(100); 28926 28927var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 28928 28929var _modelsFragmentModel = _dereq_(140); 28930 28931var _modelsFragmentModel2 = _interopRequireDefault(_modelsFragmentModel); 28932 28933var _SourceBufferController = _dereq_(112); 28934 28935var _SourceBufferController2 = _interopRequireDefault(_SourceBufferController); 28936 28937var _AbrController = _dereq_(102); 28938 28939var _AbrController2 = _interopRequireDefault(_AbrController); 28940 28941var _MediaController = _dereq_(108); 28942 28943var _MediaController2 = _interopRequireDefault(_MediaController); 28944 28945var _coreEventBus = _dereq_(50); 28946 28947var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 28948 28949var _coreEventsEvents = _dereq_(54); 28950 28951var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 28952 28953var _utilsBoxParser = _dereq_(190); 28954 28955var _utilsBoxParser2 = _interopRequireDefault(_utilsBoxParser); 28956 28957var _coreFactoryMaker = _dereq_(51); 28958 28959var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 28960 28961var _coreDebug = _dereq_(49); 28962 28963var _coreDebug2 = _interopRequireDefault(_coreDebug); 28964 28965var _utilsInitCache = _dereq_(196); 28966 28967var _utilsInitCache2 = _interopRequireDefault(_utilsInitCache); 28968 28969var BUFFER_LOADED = 'bufferLoaded'; 28970var BUFFER_EMPTY = 'bufferStalled'; 28971var STALL_THRESHOLD = 0.5; 28972 28973var BUFFER_CONTROLLER_TYPE = 'BufferController'; 28974 28975function BufferController(config) { 28976 28977 var context = this.context; 28978 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 28979 var metricsModel = config.metricsModel; 28980 var mediaPlayerModel = config.mediaPlayerModel; 28981 var sourceBufferController = config.sourceBufferController; 28982 var errHandler = config.errHandler; 28983 var streamController = config.streamController; 28984 var mediaController = config.mediaController; 28985 var adapter = config.adapter; 28986 var textController = config.textController; 28987 var abrController = config.abrController; 28988 var playbackController = config.playbackController; 28989 var type = config.type; 28990 var streamProcessor = config.streamProcessor; 28991 28992 var instance = undefined, 28993 log = undefined, 28994 requiredQuality = undefined, 28995 isBufferingCompleted = undefined, 28996 bufferLevel = undefined, 28997 criticalBufferLevel = undefined, 28998 mediaSource = undefined, 28999 maxAppendedIndex = undefined, 29000 lastIndex = undefined, 29001 buffer = undefined, 29002 bufferState = undefined, 29003 appendedBytesInfo = undefined, 29004 wallclockTicked = undefined, 29005 appendingMediaChunk = undefined, 29006 isAppendingInProgress = undefined, 29007 isPruningInProgress = undefined, 29008 initCache = undefined, 29009 seekStartTime = undefined, 29010 seekClearedBufferingCompleted = undefined, 29011 isSafariOnMac = undefined; 29012 29013 function setup() { 29014 log = (0, _coreDebug2['default'])(context).getInstance().log.bind(instance); 29015 initCache = (0, _utilsInitCache2['default'])(context).getInstance(); 29016 29017 resetInitialSettings();
29018 } 29019 29020 function getBufferControllerType() { 29021 return BUFFER_CONTROLLER_TYPE; 29022 } 29023 29024 function initialize(Source) { 29025 setMediaSource(Source); 29026 29027 requiredQuality = abrController.getQualityFor(type, streamProcessor.getStreamInfo()); 29028 var ua = navigator.userAgent.toLowerCase(); 29029 //This whole test is just for safari on a mac. 29030 isSafariOnMac = /safari/.test(ua) && /mac/.test(ua) && !/chrome/.test(ua) && !/windows phone/.test(ua); 29031 29032 eventBus.on(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, this); 29033 eventBus.on(_coreEventsEvents2['default'].INIT_FRAGMENT_LOADED, onInitFragmentLoaded, this); 29034 eventBus.on(_coreEventsEvents2['default'].MEDIA_FRAGMENT_LOADED, onMediaFragmentLoaded, this); 29035 eventBus.on(_coreEventsEvents2['default'].QUALITY_CHANGE_REQUESTED, onQualityChanged, this); 29036 eventBus.on(_coreEventsEvents2['default'].STREAM_COMPLETED, onStreamCompleted, this); 29037 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_PROGRESS, onPlaybackProgression, this); 29038 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_TIME_UPDATED, onPlaybackProgression, this); 29039 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_RATE_CHANGED, onPlaybackRateChanged, this); 29040 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, this); 29041 eventBus.on(_coreEventsEvents2['default'].WALLCLOCK_TIME_UPDATED, onWallclockTimeUpdated, this); 29042 eventBus.on(_coreEventsEvents2['default'].CURRENT_TRACK_CHANGED, onCurrentTrackChanged, this, _coreEventBus2['default'].EVENT_PRIORITY_HIGH); 29043 eventBus.on(_coreEventsEvents2['default'].SOURCEBUFFER_APPEND_COMPLETED, onAppended, this); 29044 eventBus.on(_coreEventsEvents2['default'].SOURCEBUFFER_REMOVE_COMPLETED, onRemoved, this); 29045 29046 if (isSafariOnMac) { 29047 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_SEEKED, onSeeked, this); 29048 } 29049 } 29050 29051 function createBuffer(mediaInfo) { 29052 if (!mediaInfo || !mediaSource || !streamProcessor) return null; 29053 29054 var sourceBuffer = null; 29055 29056 try { 29057 sourceBuffer = sourceBufferController.createSourceBuffer(mediaSource, mediaInfo); 29058 29059 if (sourceBuffer && sourceBuffer.hasOwnProperty(_constantsConstants2['default'].INITIALIZE)) { 29060 sourceBuffer.initialize(type, streamProcessor); 29061 } 29062 } catch (e) { 29063 errHandler.mediaSourceError('Error creating ' + type + ' source buffer.'); 29064 } 29065 setBuffer(sourceBuffer); 29066 updateBufferTimestampOffset(streamProcessor.getRepresentationInfoForQuality(requiredQuality).MSETimeOffset); 29067 return sourceBuffer; 29068 } 29069 29070 function isActive() { 29071 return streamProcessor && streamController ? streamProcessor.getStreamInfo().id === streamController.getActiveStreamInfo().id : false; 29072 } 29073 29074 function onInitFragmentLoaded(e) { 29075 if (e.fragmentModel !== streamProcessor.getFragmentModel()) return; 29076 log('Init fragment finished loading saving to', type + '\'s init cache'); 29077 initCache.save(e.chunk); 29078 appendToBuffer(e.chunk); 29079 } 29080 29081 function switchInitData(streamId, representationId) { 29082 var chunk = initCache.extract(streamId, representationId); 29083 if (chunk) { 29084 appendToBuffer(chunk); 29085 } else { 29086 eventBus.trigger(_coreEventsEvents2['default'].INIT_REQUESTED, { sender: instance }); 29087 } 29088 } 29089 29090 function onMediaFragmentLoaded(e) { 29091 if (e.fragmentModel !== streamProcessor.getFragmentModel()) return; 29092 29093 var chunk = e.chunk; 29094 var bytes = chunk.bytes; 29095 var quality = chunk.quality; 29096 var currentRepresentation = streamProcessor.getRepresentationInfoForQuality(quality); 29097 var eventStreamMedia = adapter.getEventsFor(currentRepresentation.mediaInfo, streamProcessor); 29098 var eventStreamTrack = adapter.getEventsFor(currentRepresentation, streamProcessor); 29099 29100 if (eventStreamMedia && eventStreamMedia.length > 0 || eventStreamTrack && eventStreamTrack.length > 0) { 29101 var request = streamProcessor.getFragmentModel().getRequests({ 29102 state: _modelsFragmentModel2['default'].FRAGMENT_MODEL_EXECUTED, 29103 quality: quality, 29104 index: chunk.index 29105 })[0]; 29106 29107 var events = handleInbandEvents(bytes, request, eventStreamMedia, eventStreamTrack);
29108 streamProcessor.getEventController().addInbandEvents(events); 29109 } 29110 29111 appendToBuffer(chunk); 29112 } 29113 29114 function appendToBuffer(chunk) { 29115 isAppendingInProgress = true; 29116 appendedBytesInfo = chunk; 29117 sourceBufferController.append(buffer, chunk); 29118 29119 if (chunk.mediaInfo.type === _constantsConstants2['default'].VIDEO) { 29120 eventBus.trigger(_coreEventsEvents2['default'].VIDEO_CHUNK_RECEIVED, { chunk: chunk }); 29121 } 29122 } 29123 29124 function onAppended(e) { 29125 if (buffer === e.buffer) { 29126 if (e.error) { 29127 if (e.error.code === _SourceBufferController2['default'].QUOTA_EXCEEDED_ERROR_CODE) { 29128 criticalBufferLevel = sourceBufferController.getTotalBufferedTime(buffer) * 0.8; 29129 } 29130 if (e.error.code === _SourceBufferController2['default'].QUOTA_EXCEEDED_ERROR_CODE || !hasEnoughSpaceToAppend()) { 29131 eventBus.trigger(_coreEventsEvents2['default'].QUOTA_EXCEEDED, { sender: instance, criticalBufferLevel: criticalBufferLevel }); //Tells ScheduleController to stop scheduling. 29132 clearBuffer(getClearRange()); // Then we clear the buffer and onCleared event will tell ScheduleController to start scheduling again. 29133 } 29134 return; 29135 } 29136 29137 if (appendedBytesInfo && !isNaN(appendedBytesInfo.index)) { 29138 maxAppendedIndex = Math.max(appendedBytesInfo.index, maxAppendedIndex); 29139 checkIfBufferingCompleted(); 29140 } 29141 29142 var ranges = sourceBufferController.getAllRanges(buffer); 29143 if (ranges && ranges.length > 0) { 29144 for (var i = 0, len = ranges.length; i < len; i++) { 29145 log('Buffered Range for type:', type, ':', ranges.start(i), ' - ', ranges.end(i)); 29146 } 29147 } 29148 29149 onPlaybackProgression(); 29150 isAppendingInProgress = false; 29151 if (appendedBytesInfo) { 29152 eventBus.trigger(_coreEventsEvents2['default'].BYTES_APPENDED, { 29153 sender: instance, 29154 quality: appendedBytesInfo.quality, 29155 startTime: appendedBytesInfo.start, 29156 index: appendedBytesInfo.index, 29157 bufferedRanges: ranges 29158 }); 29159 } 29160 } 29161 } 29162 29163 function onQualityChanged(e) { 29164 if (requiredQuality === e.newQuality || type !== e.mediaType || streamProcessor.getStreamInfo().id !== e.streamInfo.id) return; 29165 29166 updateBufferTimestampOffset(streamProcessor.getRepresentationInfoForQuality(e.newQuality).MSETimeOffset); 29167 requiredQuality = e.newQuality; 29168 } 29169 29170 //********************************************************************** 29171 // START Buffer Level, State & Sufficiency Handling. 29172 //********************************************************************** 29173 function onPlaybackSeeking() { 29174 if (isBufferingCompleted) { 29175 seekClearedBufferingCompleted = true; 29176 isBufferingCompleted = false; 29177 maxAppendedIndex = 0; 29178 } 29179 seekStartTime = undefined; 29180 onPlaybackProgression(); 29181 } 29182 29183 function getWorkingTime() { 29184 // This function returns current working time for buffer (either start time or current time if playback has started) 29185 var ret = playbackController.getTime(); 29186 29187 if (seekStartTime) { 29188 // if there is a seek start time, the first buffer data will be available on maximum value between first buffer range value and seek start time. 29189 var ranges = sourceBufferController.getAllRanges(buffer); 29190 if (ranges && ranges.length) { 29191 ret = Math.max(ranges.start(0), seekStartTime); 29192 } 29193 } 29194 return ret; 29195 } 29196 29197 function onPlaybackProgression() { 29198 updateBufferLevel(); 29199 addBufferMetrics(); 29200 } 29201 29202 function updateBufferLevel() { 29203 if (playbackController) {
29204 bufferLevel = sourceBufferController.getBufferLength(buffer, getWorkingTime()); 29205 eventBus.trigger(_coreEventsEvents2['default'].BUFFER_LEVEL_UPDATED, { sender: instance, bufferLevel: bufferLevel }); 29206 checkIfSufficientBuffer(); 29207 } 29208 } 29209 29210 function addBufferMetrics() { 29211 if (!isActive()) return; 29212 metricsModel.addBufferState(type, bufferState, streamProcessor.getScheduleController().getBufferTarget()); 29213 metricsModel.addBufferLevel(type, new Date(), bufferLevel * 1000); 29214 } 29215 29216 function checkIfBufferingCompleted() { 29217 var isLastIdxAppended = maxAppendedIndex >= lastIndex - 1; // Handles 0 and non 0 based request index 29218 if (isLastIdxAppended && !isBufferingCompleted) { 29219 isBufferingCompleted = true; 29220 eventBus.trigger(_coreEventsEvents2['default'].BUFFERING_COMPLETED, { sender: instance, streamInfo: streamProcessor.getStreamInfo() }); 29221 } 29222 } 29223 29224 function checkIfSufficientBuffer() { 29225 // No need to check buffer if type is not audio or video (for example if several errors occur during text parsing, so that the buffer cannot be filled, no error must occur on video playback) 29226 if (type !== 'audio' && type !== 'video') return; 29227 29228 if (seekClearedBufferingCompleted && !isBufferingCompleted && playbackController && playbackController.getTimeToStreamEnd() - bufferLevel < STALL_THRESHOLD) { 29229 seekClearedBufferingCompleted = false; 29230 isBufferingCompleted = true; 29231 eventBus.trigger(_coreEventsEvents2['default'].BUFFERING_COMPLETED, { sender: instance, streamInfo: streamProcessor.getStreamInfo() }); 29232 } 29233 29234 if (bufferLevel < STALL_THRESHOLD && !isBufferingCompleted) { 29235 notifyBufferStateChanged(BUFFER_EMPTY); 29236 } else { 29237 notifyBufferStateChanged(BUFFER_LOADED); 29238 } 29239 } 29240 29241 function notifyBufferStateChanged(state) { 29242 if (bufferState === state || type === _constantsConstants2['default'].FRAGMENTED_TEXT && textController.getAllTracksAreDisabled()) return; 29243 bufferState = state; 29244 addBufferMetrics(); 29245 eventBus.trigger(_coreEventsEvents2['default'].BUFFER_LEVEL_STATE_CHANGED, { sender: instance, state: state, mediaType: type, streamInfo: streamProcessor.getStreamInfo() }); 29246 eventBus.trigger(state === BUFFER_LOADED ? _coreEventsEvents2['default'].BUFFER_LOADED : _coreEventsEvents2['default'].BUFFER_EMPTY, { mediaType: type }); 29247 log(state === BUFFER_LOADED ? 'Got enough buffer to start.' : 'Waiting for more buffer before starting playback.'); 29248 } 29249 29250 function handleInbandEvents(data, request, mediaInbandEvents, trackInbandEvents) { 29251 var fragmentStartTime = Math.max(isNaN(request.startTime) ? 0 : request.startTime, 0); 29252 var eventStreams = []; 29253 var events = []; 29254 29255 /* Extract the possible schemeIdUri : If a DASH client detects an event message box with a scheme that is not defined in MPD, the client is expected to ignore it */ 29256 var inbandEvents = mediaInbandEvents.concat(trackInbandEvents); 29257 for (var i = 0, ln = inbandEvents.length; i < ln; i++) { 29258 eventStreams[inbandEvents[i].schemeIdUri] = inbandEvents[i]; 29259 } 29260 29261 var isoFile = (0, _utilsBoxParser2['default'])(context).getInstance().parse(data); 29262 var eventBoxes = isoFile.getBoxes('emsg'); 29263 29264 for (var i = 0, ln = eventBoxes.length; i < ln; i++) { 29265 var _event = adapter.getEvent(eventBoxes[i], eventStreams, fragmentStartTime); 29266 29267 if (_event) { 29268 events.push(_event); 29269 } 29270 } 29271 29272 return events; 29273 } 29274 29275 function hasEnoughSpaceToAppend() { 29276 var totalBufferedTime = sourceBufferController.getTotalBufferedTime(buffer); 29277 return totalBufferedTime < criticalBufferLevel; 29278 } 29279 29280 /* prune buffer on our own in background to avoid browsers pruning buffer silently */ 29281 function pruneBuffer() { 29282 if (!buffer) return; 29283 if (type === _constantsConstants2['default'].FRAGMENTED_TEXT) return; 29284 var start = buffer.buffered.length ? buffer.buffered.start(0) : 0; 29285 var bufferToPrune = playbackController.getTime() - start - mediaPlayerModel.getBufferToKeep(); 29286 if (bufferToPrune > 0) { 29287 log('pruning buffer: ' + bufferToPrune + ' seconds.'); 29288 isPruningInProgress = true; 29289 sourceBufferController.remove(buffer, 0, Math.round(start + bufferToPrune), mediaSource); 29290 } 29291 } 29292 29293 function getClearRange(threshold) { 29294 if (!buffer) return null; 29295 29296 // we need to remove data that is more than one fragment before the video currentTime 29297 var currentTime = playbackController.getTime(); 29298 var req = streamProcessor.getFragmentModel().getRequests({ state: _modelsFragmentModel2['default'].FRAGMENT_MODEL_EXECUTED, time: currentTime, threshold: threshold })[0]; 29299 var range = sourceBufferController.getBufferRange(buffer, currentTime); 29300 29301 var removeEnd = req && !isNaN(req.startTime) ? req.startTime : Math.floor(currentTime); 29302 if (range === null && buffer.buffered.length > 0) { 29303 removeEnd = buffer.buffered.end(buffer.buffered.length - 1); 29304 } 29305 29306 return { 29307 start: buffer.buffered.start(0), 29308 end: removeEnd 29309 }; 29310 } 29311 29312 function clearBuffer(range) { 29313 if (!range || !buffer) return; 29314 sourceBufferController.remove(buffer, range.start, range.end, mediaSource); 29315 } 29316 29317 function onRemoved(e) { 29318 if (buffer !== e.buffer) return; 29319 29320 if (isPruningInProgress) { 29321 isPruningInProgress = false; 29322 } 29323 29324 updateBufferLevel(); 29325 eventBus.trigger(_coreEventsEvents2['default'].BUFFER_CLEARED, { sender: instance, from: e.from, to: e.to, hasEnoughSpaceToAppend: hasEnoughSpaceToAppend() }); 29326 //TODO - REMEMBER removed a timerout hack calling clearBuffer after manifestInfo.minBufferTime * 1000 if !hasEnoughSpaceToAppend() Aug 04 2016 29327 } 29328
29329 function updateBufferTimestampOffset(MSETimeOffset) { 29330 // Each track can have its own @presentationTimeOffset, so we should set the offset 29331 // if it has changed after switching the quality or updating an mpd 29332 if (buffer && buffer.timestampOffset !== MSETimeOffset && !isNaN(MSETimeOffset)) { 29333 buffer.timestampOffset = MSETimeOffset; 29334 } 29335 } 29336 29337 function onDataUpdateCompleted(e) { 29338 if (e.sender.getStreamProcessor() !== streamProcessor || e.error) return; 29339 updateBufferTimestampOffset(e.currentRepresentation.MSETimeOffset); 29340 } 29341 29342 function onStreamCompleted(e) { 29343 if (e.fragmentModel !== streamProcessor.getFragmentModel()) return; 29344 lastIndex = e.request.index; 29345 checkIfBufferingCompleted(); 29346 } 29347 29348 function onCurrentTrackChanged(e) { 29349 if (!buffer || e.newMediaInfo.type !== type || e.newMediaInfo.streamInfo.id !== streamProcessor.getStreamInfo().id) return; 29350 if (mediaController.getSwitchMode(type) === _MediaController2['default'].TRACK_SWITCH_MODE_ALWAYS_REPLACE) { 29351 clearBuffer(getClearRange(0)); 29352 } 29353 } 29354 29355 function onWallclockTimeUpdated() { 29356 wallclockTicked++; 29357 var secondsElapsed = wallclockTicked * (mediaPlayerModel.getWallclockTimeUpdateInterval() / 1000); 29358 if (secondsElapsed >= mediaPlayerModel.getBufferPruningInterval() && !isAppendingInProgress) { 29359 wallclockTicked = 0; 29360 pruneBuffer(); 29361 } 29362 } 29363 29364 /* 29365 * Listener set only for MacOS Safari. 29366 * MacOS Safari doesn't like buffer being appended to the start of a buffered range. 29367 * It removes a little bit of buffer just after the segment we append. 29368 * Therefore, let's remove all buffer ahead of us after a seek. 29369 */ 29370 function onSeeked() { 29371 removeBufferAhead(playbackController.getTime()); 29372 } 29373 29374 //Removes buffered ranges ahead. It will not remove anything part of the current buffer timeRange. 29375 function removeBufferAhead(time) { 29376 var ranges = sourceBufferController.getAllRanges(buffer); 29377 for (var i = 0; i < ranges.length; i++) { 29378 if (ranges.start(i) > time) { 29379 log('Removing buffer from: ' + ranges.start(i) + '-' + ranges.end(i)); 29380 sourceBufferController.remove(buffer, ranges.start(i), ranges.end(i), mediaSource); 29381 } 29382 } 29383 } 29384 29385 function onPlaybackRateChanged() { 29386 checkIfSufficientBuffer(); 29387 } 29388 29389 function getType() { 29390 return type; 29391 } 29392 29393 function getStreamProcessor() { 29394 return streamProcessor; 29395 } 29396 29397 function setSeekStartTime(value) { 29398 seekStartTime = value; 29399 } 29400 29401 function getBuffer() { 29402 return buffer; 29403 } 29404 29405 function setBuffer(value) { 29406 buffer = value; 29407 } 29408 29409 function getBufferLevel() { 29410 return bufferLevel; 29411 } 29412 29413 function setMediaSource(value) { 29414 mediaSource = value; 29415 } 29416 29417 function getMediaSource() { 29418 return mediaSource; 29419 } 29420 29421 function getIsBufferingCompleted() { 29422 return isBufferingCompleted; 29423 } 29424 29425 function resetInitialSettings() { 29426 criticalBufferLevel = Number.POSITIVE_INFINITY; 29427 bufferState = BUFFER_EMPTY; 29428 requiredQuality = _AbrController2['default'].QUALITY_DEFAULT; 29429 lastIndex = Number.POSITIVE_INFINITY; 29430 maxAppendedIndex = 0; 29431 appendedBytesInfo = null; 29432 appendingMediaChunk = false; 29433 isBufferingCompleted = false; 29434 isAppendingInProgress = false; 29435 isPruningInProgress = false; 29436 seekClearedBufferingCompleted = false; 29437 bufferLevel = 0; 29438 wallclockTicked = 0; 29439 } 29440 29441 function reset(errored) { 29442 eventBus.off(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, this); 29443 eventBus.off(_coreEventsEvents2['default'].QUALITY_CHANGE_REQUESTED, onQualityChanged, this); 29444 eventBus.off(_coreEventsEvents2['default'].INIT_FRAGMENT_LOADED, onInitFragmentLoaded, this); 29445 eventBus.off(_coreEventsEvents2['default'].MEDIA_FRAGMENT_LOADED, onMediaFragmentLoaded, this); 29446 eventBus.off(_coreEventsEvents2['default'].STREAM_COMPLETED, onStreamCompleted, this); 29447 eventBus.off(_coreEventsEvents2['default'].CURRENT_TRACK_CHANGED, onCurrentTrackChanged, this); 29448 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_PROGRESS, onPlaybackProgression, this); 29449 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_TIME_UPDATED, onPlaybackProgression, this); 29450 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_RATE_CHANGED, onPlaybackRateChanged, this); 29451 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, this); 29452 eventBus.off(_coreEventsEvents2['default'].WALLCLOCK_TIME_UPDATED, onWallclockTimeUpdated, this); 29453 eventBus.off(_coreEventsEvents2['default'].SOURCEBUFFER_APPEND_COMPLETED, onAppended, this); 29454 eventBus.off(_coreEventsEvents2['default'].SOURCEBUFFER_REMOVE_COMPLETED, onRemoved, this); 29455 29456 if (isSafariOnMac) { 29457 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_SEEKED, onSeeked, this); 29458 } 29459 29460 resetInitialSettings();
29461 29462 if (!errored) { 29463 sourceBufferController.abort(mediaSource, buffer); 29464 sourceBufferController.removeSourceBuffer(mediaSource, buffer); 29465 } 29466 29467 buffer = null; 29468 } 29469 29470 instance = { 29471 getBufferControllerType: getBufferControllerType, 29472 initialize: initialize, 29473 createBuffer: createBuffer, 29474 getType: getType, 29475 getStreamProcessor: getStreamProcessor, 29476 setSeekStartTime: setSeekStartTime, 29477 getBuffer: getBuffer, 29478 setBuffer: setBuffer, 29479 getBufferLevel: getBufferLevel, 29480 setMediaSource: setMediaSource, 29481 getMediaSource: getMediaSource, 29482 getIsBufferingCompleted: getIsBufferingCompleted, 29483 switchInitData: switchInitData, 29484 reset: reset 29485 }; 29486 29487 setup(); 29488 return instance; 29489} 29490 29491BufferController.__dashjs_factory_name = BUFFER_CONTROLLER_TYPE; 29492var factory = _coreFactoryMaker2['default'].getClassFactory(BufferController); 29493factory.BUFFER_LOADED = BUFFER_LOADED; 29494factory.BUFFER_EMPTY = BUFFER_EMPTY; 29495_coreFactoryMaker2['default'].updateClassFactory(BufferController.__dashjs_factory_name, factory); 29496exports['default'] = factory; 29497module.exports = exports['default']; 29498 29499},{"100":100,"102":102,"108":108,"112":112,"140":140,"190":190,"196":196,"49":49,"50":50,"51":51,"54":54}],106:[function(_dereq_,module,exports){ 29500/** 29501 * The copyright in this software is being made available under the BSD License, 29502 * included below. This software may be subject to other third party and contributor 29503 * rights, including patent rights, and no such rights are granted under this license. 29504 * 29505 * Copyright (c) 2013, Dash Industry Forum. 29506 * All rights reserved. 29507 * 29508 * Redistribution and use in source and binary forms, with or without modification, 29509 * are permitted provided that the following conditions are met: 29510 * * Redistributions of source code must retain the above copyright notice, this 29511 * list of conditions and the following disclaimer. 29512 * * Redistributions in binary form must reproduce the above copyright notice, 29513 * this list of conditions and the following disclaimer in the documentation and/or 29514 * other materials provided with the distribution. 29515 * * Neither the name of Dash Industry Forum nor the names of its 29516 * contributors may be used to endorse or promote products derived from this software 29517 * without specific prior written permission. 29518 * 29519 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 29520 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29521 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29522 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29523 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29524 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29525 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29526 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29527 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29528 * POSSIBILITY OF SUCH DAMAGE. 29529 */ 29530 29531'use strict'; 29532 29533Object.defineProperty(exports, '__esModule', { 29534 value: true 29535}); 29536 29537function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 29538 29539var _coreFactoryMaker = _dereq_(51); 29540 29541var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 29542 29543var _coreDebug = _dereq_(49); 29544 29545var _coreDebug2 = _interopRequireDefault(_coreDebug); 29546 29547var _coreEventBus = _dereq_(50); 29548 29549var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 29550 29551function EventController() { 29552 29553 var MPD_RELOAD_SCHEME = 'urn:mpeg:dash:event:2012'; 29554 var MPD_RELOAD_VALUE = 1; 29555 29556 var context = this.context; 29557 var log = (0, _coreDebug2['default'])(context).getInstance().log; 29558 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 29559 29560 var instance = undefined, 29561 inlineEvents = undefined, 29562 // Holds all Inline Events not triggered yet 29563 inbandEvents = undefined, 29564 // Holds all Inband Events not triggered yet 29565 activeEvents = undefined, 29566 // Holds all Events currently running 29567 eventInterval = undefined, 29568 // variable holding the setInterval 29569 refreshDelay = undefined, 29570 // refreshTime for the setInterval 29571 presentationTimeThreshold = undefined, 29572 manifestModel = undefined, 29573 manifestUpdater = undefined, 29574 playbackController = undefined, 29575 isStarted = undefined; 29576 29577 function setup() { 29578 resetInitialSettings();
29579 } 29580 29581 function resetInitialSettings() { 29582 isStarted = false; 29583 inlineEvents = {}; 29584 inbandEvents = {}; 29585 activeEvents = {}; 29586 eventInterval = null; 29587 refreshDelay = 100; 29588 presentationTimeThreshold = refreshDelay / 1000; 29589 } 29590 29591 function checkSetConfigCall() { 29592 if (!manifestModel || !manifestUpdater || !playbackController) { 29593 throw new Error('setConfig function has to be called previously'); 29594 } 29595 } 29596 29597 function clear() { 29598 if (eventInterval !== null && isStarted) { 29599 clearInterval(eventInterval); 29600 eventInterval = null; 29601 isStarted = false; 29602 } 29603 } 29604 29605 function start() { 29606 checkSetConfigCall(); 29607 log('Start Event Controller'); 29608 if (!isStarted && !isNaN(refreshDelay)) { 29609 isStarted = true; 29610 eventInterval = setInterval(onEventTimer, refreshDelay); 29611 } 29612 } 29613 29614 /** 29615 * Add events to the eventList. Events that are not in the mpd anymore but not triggered yet will still be deleted 29616 * @param {Array.<Object>} values 29617 */ 29618 function addInlineEvents(values) { 29619 checkSetConfigCall(); 29620 29621 inlineEvents = {}; 29622 29623 if (values) { 29624 for (var i = 0; i < values.length; i++) { 29625 var event = values[i]; 29626 inlineEvents[event.id] = event; 29627 log('Add inline event with id ' + event.id); 29628 } 29629 } 29630 log('Added ' + values.length + ' inline events'); 29631 } 29632 29633 /** 29634 * i.e. processing of any one event message box with the same id is sufficient 29635 * @param {Array.<Object>} values 29636 */ 29637 function addInbandEvents(values) { 29638 checkSetConfigCall(); 29639 29640 for (var i = 0; i < values.length; i++) { 29641 var event = values[i]; 29642 if (!(event.id in inbandEvents)) { 29643 inbandEvents[event.id] = event; 29644 log('Add inband event with id ' + event.id); 29645 } else { 29646 log('Repeated event with id ' + event.id); 29647 } 29648 } 29649 } 29650 29651 /** 29652 * Remove events which are over from the list 29653 */ 29654 function removeEvents() { 29655 if (activeEvents) { 29656 var currentVideoTime = playbackController.getTime(); 29657 var eventIds = Object.keys(activeEvents); 29658 29659 for (var i = 0; i < eventIds.length; i++) { 29660 var eventId = eventIds[i]; 29661 var curr = activeEvents[eventId]; 29662 if (curr !== null && (curr.duration + curr.presentationTime) / curr.eventStream.timescale < currentVideoTime) { 29663 log('Remove Event ' + eventId + ' at time ' + currentVideoTime); 29664 curr = null; 29665 delete activeEvents[eventId]; 29666 } 29667 } 29668 } 29669 } 29670 29671 /** 29672 * Iterate through the eventList and trigger/remove the events 29673 */ 29674 function onEventTimer() { 29675 triggerEvents(inbandEvents); 29676 triggerEvents(inlineEvents); 29677 removeEvents(); 29678 } 29679 29680 function refreshManifest() { 29681 checkSetConfigCall(); 29682 manifestUpdater.refreshManifest(); 29683 } 29684 29685 function triggerEvents(events) { 29686 var currentVideoTime = playbackController.getTime(); 29687 var presentationTime; 29688 29689 /* == Trigger events that are ready == */ 29690 if (events) { 29691 var eventIds = Object.keys(events); 29692 for (var i = 0; i < eventIds.length; i++) { 29693 var eventId = eventIds[i]; 29694 var curr = events[eventId]; 29695 29696 if (curr !== undefined) { 29697 presentationTime = curr.presentationTime / curr.eventStream.timescale; 29698 if (presentationTime === 0 || presentationTime <= currentVideoTime && presentationTime + presentationTimeThreshold > currentVideoTime) { 29699 log('Start Event ' + eventId + ' at ' + currentVideoTime); 29700 if (curr.duration > 0) { 29701 activeEvents[eventId] = curr; 29702 } 29703 if (curr.eventStream.schemeIdUri == MPD_RELOAD_SCHEME && curr.eventStream.value == MPD_RELOAD_VALUE) { 29704 refreshManifest(); 29705 } else { 29706 eventBus.trigger(curr.eventStream.schemeIdUri, { event: curr }); 29707 } 29708 delete events[eventId]; 29709 } 29710 } 29711 } 29712 } 29713 } 29714 29715 function setConfig(config) { 29716 if (!config) return; 29717 29718 if (config.manifestModel) { 29719 manifestModel = config.manifestModel; 29720 } 29721 29722 if (config.manifestUpdater) { 29723 manifestUpdater = config.manifestUpdater; 29724 } 29725 29726 if (config.playbackController) { 29727 playbackController = config.playbackController; 29728 } 29729 } 29730 29731 function reset() { 29732 clear(); 29733 resetInitialSettings();
29734 } 29735 29736 instance = { 29737 addInlineEvents: addInlineEvents, 29738 addInbandEvents: addInbandEvents, 29739 clear: clear, 29740 start: start, 29741 setConfig: setConfig, 29742 reset: reset 29743 }; 29744 29745 setup(); 29746 29747 return instance; 29748} 29749 29750EventController.__dashjs_factory_name = 'EventController'; 29751exports['default'] = _coreFactoryMaker2['default'].getClassFactory(EventController); 29752module.exports = exports['default']; 29753 29754},{"49":49,"50":50,"51":51}],107:[function(_dereq_,module,exports){ 29755/** 29756 * The copyright in this software is being made available under the BSD License, 29757 * included below. This software may be subject to other third party and contributor 29758 * rights, including patent rights, and no such rights are granted under this license. 29759 * 29760 * Copyright (c) 2013, Dash Industry Forum. 29761 * All rights reserved. 29762 * 29763 * Redistribution and use in source and binary forms, with or without modification, 29764 * are permitted provided that the following conditions are met: 29765 * * Redistributions of source code must retain the above copyright notice, this 29766 * list of conditions and the following disclaimer. 29767 * * Redistributions in binary form must reproduce the above copyright notice, 29768 * this list of conditions and the following disclaimer in the documentation and/or 29769 * other materials provided with the distribution. 29770 * * Neither the name of Dash Industry Forum nor the names of its 29771 * contributors may be used to endorse or promote products derived from this software 29772 * without specific prior written permission. 29773 * 29774 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 29775 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29776 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29777 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29778 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29779 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29780 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29781 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29782 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29783 * POSSIBILITY OF SUCH DAMAGE. 29784 */ 29785'use strict'; 29786 29787Object.defineProperty(exports, '__esModule', { 29788 value: true 29789}); 29790 29791function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 29792 29793var _constantsConstants = _dereq_(100); 29794 29795var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 29796 29797var _voMetricsHTTPRequest = _dereq_(224); 29798 29799var _voDataChunk = _dereq_(208); 29800 29801var _voDataChunk2 = _interopRequireDefault(_voDataChunk); 29802 29803var _modelsFragmentModel = _dereq_(140); 29804 29805var _modelsFragmentModel2 = _interopRequireDefault(_modelsFragmentModel); 29806 29807var _FragmentLoader = _dereq_(90); 29808 29809var _FragmentLoader2 = _interopRequireDefault(_FragmentLoader); 29810 29811var _utilsRequestModifier = _dereq_(200); 29812 29813var _utilsRequestModifier2 = _interopRequireDefault(_utilsRequestModifier); 29814 29815var _coreEventBus = _dereq_(50); 29816 29817var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 29818 29819var _coreEventsEvents = _dereq_(54); 29820 29821var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 29822 29823var _coreFactoryMaker = _dereq_(51); 29824 29825var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 29826 29827var _coreDebug = _dereq_(49); 29828 29829var _coreDebug2 = _interopRequireDefault(_coreDebug); 29830 29831function FragmentController(config) { 29832 29833 var context = this.context; 29834 var log = (0, _coreDebug2['default'])(context).getInstance().log; 29835 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 29836 29837 var errHandler = config.errHandler; 29838 var mediaPlayerModel = config.mediaPlayerModel; 29839 var metricsModel = config.metricsModel; 29840 29841 var instance = undefined, 29842 fragmentModels = undefined; 29843 29844 function setup() { 29845 resetInitialSettings(); 29846 eventBus.on(_coreEventsEvents2['default'].FRAGMENT_LOADING_COMPLETED, onFragmentLoadingCompleted, instance); 29847 } 29848 29849 function getModel(type) { 29850 var model = fragmentModels[type]; 29851 if (!model) { 29852 model = (0, _modelsFragmentModel2['default'])(context).create({ 29853 metricsModel: metricsModel, 29854 fragmentLoader: (0, _FragmentLoader2['default'])(context).create({ 29855 metricsModel: metricsModel, 29856 mediaPlayerModel: mediaPlayerModel, 29857 errHandler: errHandler, 29858 requestModifier: (0, _utilsRequestModifier2['default'])(context).getInstance() 29859 }) 29860 }); 29861 29862 fragmentModels[type] = model; 29863 } 29864 29865 return model; 29866 } 29867 29868 function isInitializationRequest(request) { 29869 return request && request.type && request.type === _voMetricsHTTPRequest.HTTPRequest.INIT_SEGMENT_TYPE; 29870 } 29871 29872 function resetInitialSettings() { 29873 for (var model in fragmentModels) { 29874 fragmentModels[model].reset(); 29875 } 29876 fragmentModels = {}; 29877 } 29878 29879 function reset() { 29880 eventBus.off(_coreEventsEvents2['default'].FRAGMENT_LOADING_COMPLETED, onFragmentLoadingCompleted, this); 29881 resetInitialSettings();
29882 } 29883 29884 function createDataChunk(bytes, request, streamId) { 29885 var chunk = new _voDataChunk2['default'](); 29886 29887 chunk.streamId = streamId; 29888 chunk.mediaInfo = request.mediaInfo; 29889 chunk.segmentType = request.type; 29890 chunk.start = request.startTime; 29891 chunk.duration = request.duration; 29892 chunk.end = chunk.start + chunk.duration; 29893 chunk.bytes = bytes; 29894 chunk.index = request.index; 29895 chunk.quality = request.quality; 29896 chunk.representationId = request.representationId; 29897 29898 return chunk; 29899 } 29900 29901 function onFragmentLoadingCompleted(e) { 29902 if (fragmentModels[e.request.mediaType] !== e.sender) { 29903 return; 29904 } 29905 29906 var request = e.request; 29907 var bytes = e.response; 29908 var isInit = isInitializationRequest(request); 29909 var streamInfo = request.mediaInfo.streamInfo; 29910 29911 if (e.error) { 29912 if (e.request.mediaType === _constantsConstants2['default'].AUDIO || e.request.mediaType === _constantsConstants2['default'].VIDEO) { 29913 // add service location to blacklist controller - only for audio or video. text should not set errors 29914 eventBus.trigger(_coreEventsEvents2['default'].SERVICE_LOCATION_BLACKLIST_ADD, { entry: e.request.serviceLocation }); 29915 } 29916 } 29917 29918 if (!bytes || !streamInfo) { 29919 log('No ' + request.mediaType + ' bytes to push or stream is inactive.'); 29920 return; 29921 } 29922 29923 var chunk = createDataChunk(bytes, request, streamInfo.id); 29924 eventBus.trigger(isInit ? _coreEventsEvents2['default'].INIT_FRAGMENT_LOADED : _coreEventsEvents2['default'].MEDIA_FRAGMENT_LOADED, { 29925 chunk: chunk, 29926 fragmentModel: e.sender 29927 }); 29928 } 29929 29930 instance = { 29931 getModel: getModel, 29932 isInitializationRequest: isInitializationRequest, 29933 reset: reset 29934 }; 29935 29936 setup(); 29937 29938 return instance; 29939} 29940 29941FragmentController.__dashjs_factory_name = 'FragmentController'; 29942exports['default'] = _coreFactoryMaker2['default'].getClassFactory(FragmentController); 29943module.exports = exports['default']; 29944 29945},{"100":100,"140":140,"200":200,"208":208,"224":224,"49":49,"50":50,"51":51,"54":54,"90":90}],108:[function(_dereq_,module,exports){ 29946/** 29947 * The copyright in this software is being made available under the BSD License, 29948 * included below. This software may be subject to other third party and contributor 29949 * rights, including patent rights, and no such rights are granted under this license. 29950 * 29951 * Copyright (c) 2013, Dash Industry Forum. 29952 * All rights reserved. 29953 * 29954 * Redistribution and use in source and binary forms, with or without modification, 29955 * are permitted provided that the following conditions are met: 29956 * * Redistributions of source code must retain the above copyright notice, this 29957 * list of conditions and the following disclaimer. 29958 * * Redistributions in binary form must reproduce the above copyright notice, 29959 * this list of conditions and the following disclaimer in the documentation and/or 29960 * other materials provided with the distribution. 29961 * * Neither the name of Dash Industry Forum nor the names of its 29962 * contributors may be used to endorse or promote products derived from this software 29963 * without specific prior written permission. 29964 * 29965 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 29966 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29967 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29968 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29969 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29970 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29971 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29972 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29973 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29974 * POSSIBILITY OF SUCH DAMAGE. 29975 */ 29976'use strict'; 29977 29978Object.defineProperty(exports, '__esModule', { 29979 value: true 29980}); 29981 29982function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 29983 29984var _constantsConstants = _dereq_(100); 29985 29986var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 29987 29988var _coreEventsEvents = _dereq_(54); 29989 29990var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 29991 29992var _coreEventBus = _dereq_(50); 29993 29994var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 29995 29996var _coreFactoryMaker = _dereq_(51); 29997 29998var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 29999 30000var _coreDebug = _dereq_(49); 30001 30002var _coreDebug2 = _interopRequireDefault(_coreDebug); 30003 30004var TRACK_SWITCH_MODE_NEVER_REPLACE = 'neverReplace'; 30005var TRACK_SWITCH_MODE_ALWAYS_REPLACE = 'alwaysReplace'; 30006var TRACK_SELECTION_MODE_HIGHEST_BITRATE = 'highestBitrate'; 30007var TRACK_SELECTION_MODE_WIDEST_RANGE = 'widestRange'; 30008var DEFAULT_INIT_TRACK_SELECTION_MODE = TRACK_SELECTION_MODE_HIGHEST_BITRATE; 30009 30010function MediaController() { 30011 30012 var context = this.context; 30013 var log = (0, _coreDebug2['default'])(context).getInstance().log; 30014 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 30015 30016 var instance = undefined, 30017 tracks = undefined, 30018 initialSettings = undefined, 30019 selectionMode = undefined, 30020 switchMode = undefined, 30021 errHandler = undefined, 30022 domStorage = undefined; 30023
30024 var validTrackSwitchModes = [TRACK_SWITCH_MODE_ALWAYS_REPLACE, TRACK_SWITCH_MODE_NEVER_REPLACE]; 30025 30026 var validTrackSelectionModes = [TRACK_SELECTION_MODE_HIGHEST_BITRATE, TRACK_SELECTION_MODE_WIDEST_RANGE]; 30027 30028 function setup() { 30029 reset(); 30030 } 30031 30032 /** 30033 * @param {string} type 30034 * @param {StreamInfo} streamInfo 30035 * @memberof MediaController# 30036 */ 30037 function checkInitialMediaSettingsForType(type, streamInfo) { 30038 var settings = getInitialSettings(type); 30039 var tracksForType = getTracksFor(type, streamInfo); 30040 var tracks = []; 30041 30042 if (type === _constantsConstants2['default'].FRAGMENTED_TEXT) { 30043 // Choose the first track 30044 setTrack(tracksForType[0]); 30045 return; 30046 } 30047 30048 if (!settings) { 30049 settings = domStorage.getSavedMediaSettings(type); 30050 setInitialSettings(type, settings); 30051 } 30052 30053 if (!tracksForType || tracksForType.length === 0) return; 30054 30055 if (settings) { 30056 tracksForType.forEach(function (track) { 30057 if (matchSettings(settings, track)) { 30058 tracks.push(track); 30059 } 30060 }); 30061 } 30062 30063 if (tracks.length === 0) { 30064 setTrack(selectInitialTrack(tracksForType)); 30065 } else { 30066 if (tracks.length > 1) { 30067 setTrack(selectInitialTrack(tracks)); 30068 } else { 30069 setTrack(tracks[0]); 30070 } 30071 } 30072 } 30073 30074 /** 30075 * @param {MediaInfo} track 30076 * @memberof MediaController# 30077 */ 30078 function addTrack(track) { 30079 var mediaType = track ? track.type : null; 30080 var streamId = track ? track.streamInfo.id : null; 30081 var initSettings = getInitialSettings(mediaType); 30082 30083 if (!track || !isMultiTrackSupportedByType(mediaType)) return; 30084 30085 tracks[streamId] = tracks[streamId] || createTrackInfo(); 30086 30087 if (tracks[streamId][mediaType].list.indexOf(track) >= 0) return; 30088 30089 tracks[streamId][mediaType].list.push(track); 30090 30091 if (initSettings && matchSettings(initSettings, track) && !getCurrentTrackFor(mediaType, track.streamInfo)) { 30092 setTrack(track); 30093 } 30094 } 30095 30096 /** 30097 * @param {string} type 30098 * @param {StreamInfo} streamInfo 30099 * @returns {Array} 30100 * @memberof MediaController# 30101 */ 30102 function getTracksFor(type, streamInfo) { 30103 if (!type || !streamInfo) return []; 30104 30105 var id = streamInfo.id; 30106 30107 if (!tracks[id] || !tracks[id][type]) return []; 30108 30109 return tracks[id][type].list; 30110 } 30111 30112 /** 30113 * @param {string} type 30114 * @param {StreamInfo} streamInfo 30115 * @returns {Object|null} 30116 * @memberof MediaController# 30117 */ 30118 function getCurrentTrackFor(type, streamInfo) { 30119 if (!type || !streamInfo || streamInfo && !tracks[streamInfo.id]) return null; 30120 return tracks[streamInfo.id][type].current; 30121 } 30122 30123 /** 30124 * @param {MediaInfo} track 30125 * @returns {boolean} 30126 * @memberof MediaController# 30127 */ 30128 function isCurrentTrack(track) { 30129 var type = track.type; 30130 var id = track.streamInfo.id; 30131 30132 return tracks[id] && tracks[id][type] && isTracksEqual(tracks[id][type].current, track); 30133 } 30134 30135 /** 30136 * @param {MediaInfo} track 30137 * @memberof MediaController# 30138 */ 30139 function setTrack(track) { 30140 if (!track) return; 30141 30142 var type = track.type; 30143 var streamInfo = track.streamInfo; 30144 var id = streamInfo.id; 30145 var current = getCurrentTrackFor(type, streamInfo); 30146 30147 if (!tracks[id] || !tracks[id][type] || current && isTracksEqual(track, current)) return; 30148 30149 tracks[id][type].current = track; 30150 30151 if (current) { 30152 eventBus.trigger(_coreEventsEvents2['default'].CURRENT_TRACK_CHANGED, { oldMediaInfo: current, newMediaInfo: track, switchMode: switchMode[type] }); 30153 } 30154 30155 var settings = extractSettings(track); 30156 30157 if (!settings || !tracks[id][type].storeLastSettings) return; 30158 30159 if (settings.roles) { 30160 settings.role = settings.roles[0]; 30161 delete settings.roles; 30162 } 30163 30164 if (settings.accessibility) { 30165 settings.accessibility = settings.accessibility[0]; 30166 } 30167 30168 if (settings.audioChannelConfiguration) { 30169 settings.audioChannelConfiguration = settings.audioChannelConfiguration[0]; 30170 } 30171 30172 domStorage.setSavedMediaSettings(type, settings); 30173 } 30174 30175 /** 30176 * @param {string} type 30177 * @param {Object} value 30178 * @memberof MediaController# 30179 */ 30180 function setInitialSettings(type, value) { 30181 if (!type || !value) return; 30182 30183 initialSettings[type] = value; 30184 } 30185 30186 /** 30187 * @param {string} type 30188 * @returns {Object|null} 30189 * @memberof MediaController# 30190 */ 30191 function getInitialSettings(type) { 30192 if (!type) return null; 30193 30194 return initialSettings[type]; 30195 } 30196 30197 /** 30198 * @param {string} type 30199 * @param {string} mode 30200 * @memberof MediaController# 30201 */ 30202 function setSwitchMode(type, mode) { 30203 var isModeSupported = validTrackSwitchModes.indexOf(mode) !== -1; 30204 30205 if (!isModeSupported) { 30206 log('track switch mode is not supported: ' + mode); 30207 return; 30208 } 30209 30210 switchMode[type] = mode; 30211 } 30212 30213 /** 30214 * @param {string} type 30215 * @returns {string} mode 30216 * @memberof MediaController# 30217 */ 30218 function getSwitchMode(type) { 30219 return switchMode[type]; 30220 } 30221 30222 /** 30223 * @param {string} mode 30224 * @memberof MediaController# 30225 */ 30226 function setSelectionModeForInitialTrack(mode) { 30227 var isModeSupported = validTrackSelectionModes.indexOf(mode) !== -1; 30228 30229 if (!isModeSupported) { 30230 log('track selection mode is not supported: ' + mode); 30231 return; 30232 } 30233 selectionMode = mode; 30234 } 30235 30236 /** 30237 * @returns {string} mode 30238 * @memberof MediaController# 30239 */ 30240 function getSelectionModeForInitialTrack() { 30241 return selectionMode || DEFAULT_INIT_TRACK_SELECTION_MODE; 30242 } 30243 30244 /** 30245 * @param {string} type 30246 * @returns {boolean} 30247 * @memberof MediaController# 30248 */ 30249 function isMultiTrackSupportedByType(type) { 30250 return type === _constantsConstants2['default'].AUDIO || type === _constantsConstants2['default'].VIDEO || type === _constantsConstants2['default'].TEXT || type === _constantsConstants2['default'].FRAGMENTED_TEXT; 30251 } 30252 30253 /** 30254 * @param {MediaInfo} t1 - first track to compare 30255 * @param {MediaInfo} t2 - second track to compare 30256 * @returns {boolean} 30257 * @memberof MediaController# 30258 */ 30259 function isTracksEqual(t1, t2) { 30260 var sameId = t1.id === t2.id; 30261 var sameViewpoint = t1.viewpoint === t2.viewpoint; 30262 var sameLang = t1.lang === t2.lang; 30263 var sameRoles = t1.roles.toString() === t2.roles.toString(); 30264 var sameAccessibility = t1.accessibility.toString() === t2.accessibility.toString(); 30265 var sameAudioChannelConfiguration = t1.audioChannelConfiguration.toString() === t2.audioChannelConfiguration.toString(); 30266 30267 return sameId && sameViewpoint && sameLang && sameRoles && sameAccessibility && sameAudioChannelConfiguration; 30268 } 30269 30270 function setConfig(config) { 30271 if (!config) return; 30272 30273 if (config.errHandler) { 30274 errHandler = config.errHandler; 30275 } 30276 30277 if (config.domStorage) { 30278 domStorage = config.domStorage; 30279 } 30280 } 30281 30282 /** 30283 * @memberof MediaController# 30284 */ 30285 function reset() { 30286 tracks = {}; 30287 resetInitialSettings();
30288 resetSwitchMode(); 30289 } 30290 30291 function extractSettings(mediaInfo) { 30292 var settings = { 30293 lang: mediaInfo.lang, 30294 viewpoint: mediaInfo.viewpoint, 30295 roles: mediaInfo.roles, 30296 accessibility: mediaInfo.accessibility, 30297 audioChannelConfiguration: mediaInfo.audioChannelConfiguration 30298 }; 30299 var notEmpty = settings.lang || settings.viewpoint || settings.role && settings.role.length > 0 || settings.accessibility && settings.accessibility.length > 0 || settings.audioChannelConfiguration && settings.audioChannelConfiguration.length > 0; 30300 30301 return notEmpty ? settings : null; 30302 } 30303 30304 function matchSettings(settings, track) { 30305 var matchLang = !settings.lang || settings.lang === track.lang; 30306 var matchViewPoint = !settings.viewpoint || settings.viewpoint === track.viewpoint; 30307 var matchRole = !settings.role || !!track.roles.filter(function (item) { 30308 return item === settings.role; 30309 })[0]; 30310 var matchAccessibility = !settings.accessibility || !!track.accessibility.filter(function (item) { 30311 return item === settings.accessibility; 30312 })[0]; 30313 var matchAudioChannelConfiguration = !settings.audioChannelConfiguration || !!track.audioChannelConfiguration.filter(function (item) { 30314 return item === settings.audioChannelConfiguration; 30315 })[0]; 30316 30317 return matchLang && matchViewPoint && matchRole && matchAccessibility && matchAudioChannelConfiguration; 30318 } 30319 30320 function resetSwitchMode() { 30321 switchMode = { 30322 audio: TRACK_SWITCH_MODE_ALWAYS_REPLACE, 30323 video: TRACK_SWITCH_MODE_NEVER_REPLACE 30324 }; 30325 } 30326 30327 function resetInitialSettings() { 30328 initialSettings = { 30329 audio: null, 30330 video: null 30331 }; 30332 } 30333 30334 function selectInitialTrack(tracks) { 30335 var mode = getSelectionModeForInitialTrack(); 30336 var tmpArr = []; 30337 var getTracksWithHighestBitrate = function getTracksWithHighestBitrate(trackArr) { 30338 var max = 0; 30339 var result = []; 30340 var tmp = undefined; 30341 30342 trackArr.forEach(function (track) { 30343 tmp = Math.max.apply(Math, track.bitrateList.map(function (obj) { 30344 return obj.bandwidth; 30345 })); 30346 30347 if (tmp > max) { 30348 max = tmp; 30349 result = [track]; 30350 } else if (tmp === max) { 30351 result.push(track); 30352 } 30353 }); 30354 30355 return result; 30356 }; 30357 var getTracksWithWidestRange = function getTracksWithWidestRange(trackArr) { 30358 var max = 0; 30359 var result = []; 30360 var tmp = undefined; 30361 30362 trackArr.forEach(function (track) { 30363 tmp = track.representationCount; 30364 30365 if (tmp > max) { 30366 max = tmp; 30367 result = [track]; 30368 } else if (tmp === max) { 30369 result.push(track); 30370 } 30371 }); 30372 30373 return result; 30374 }; 30375 30376 switch (mode) { 30377 case TRACK_SELECTION_MODE_HIGHEST_BITRATE: 30378 tmpArr = getTracksWithHighestBitrate(tracks); 30379 30380 if (tmpArr.length > 1) { 30381 tmpArr = getTracksWithWidestRange(tmpArr); 30382 } 30383 break; 30384 case TRACK_SELECTION_MODE_WIDEST_RANGE: 30385 tmpArr = getTracksWithWidestRange(tracks); 30386 30387 if (tmpArr.length > 1) { 30388 tmpArr = getTracksWithHighestBitrate(tracks); 30389 } 30390 break; 30391 default: 30392 log('track selection mode is not supported: ' + mode); 30393 break; 30394 } 30395 30396 return tmpArr[0]; 30397 } 30398 30399 function createTrackInfo() { 30400 return { 30401 audio: { 30402 list: [], 30403 storeLastSettings: true, 30404 current: null 30405 }, 30406 video: { 30407 list: [], 30408 storeLastSettings: true, 30409 current: null 30410 }, 30411 text: { 30412 list: [], 30413 storeLastSettings: true, 30414 current: null 30415 }, 30416 fragmentedText: { 30417 list: [], 30418 storeLastSettings: true, 30419 current: null 30420 } 30421 }; 30422 } 30423 30424 instance = { 30425 checkInitialMediaSettingsForType: checkInitialMediaSettingsForType, 30426 addTrack: addTrack, 30427 getTracksFor: getTracksFor, 30428 getCurrentTrackFor: getCurrentTrackFor, 30429 isCurrentTrack: isCurrentTrack, 30430 setTrack: setTrack, 30431 setInitialSettings: setInitialSettings, 30432 getInitialSettings: getInitialSettings, 30433 setSwitchMode: setSwitchMode, 30434 getSwitchMode: getSwitchMode, 30435 setSelectionModeForInitialTrack: setSelectionModeForInitialTrack, 30436 getSelectionModeForInitialTrack: getSelectionModeForInitialTrack, 30437 isMultiTrackSupportedByType: isMultiTrackSupportedByType, 30438 isTracksEqual: isTracksEqual, 30439 setConfig: setConfig, 30440 reset: reset 30441 }; 30442 30443 setup(); 30444 30445 return instance; 30446} 30447 30448MediaController.__dashjs_factory_name = 'MediaController'; 30449var factory = _coreFactoryMaker2['default'].getSingletonFactory(MediaController); 30450factory.TRACK_SWITCH_MODE_NEVER_REPLACE = TRACK_SWITCH_MODE_NEVER_REPLACE; 30451factory.TRACK_SWITCH_MODE_ALWAYS_REPLACE = TRACK_SWITCH_MODE_ALWAYS_REPLACE; 30452factory.TRACK_SELECTION_MODE_HIGHEST_BITRATE = TRACK_SELECTION_MODE_HIGHEST_BITRATE; 30453factory.TRACK_SELECTION_MODE_WIDEST_RANGE = TRACK_SELECTION_MODE_WIDEST_RANGE; 30454factory.DEFAULT_INIT_TRACK_SELECTION_MODE = DEFAULT_INIT_TRACK_SELECTION_MODE; 30455_coreFactoryMaker2['default'].updateSingletonFactory(MediaController.__dashjs_factory_name, factory); 30456exports['default'] = factory; 30457module.exports = exports['default']; 30458 30459},{"100":100,"49":49,"50":50,"51":51,"54":54}],109:[function(_dereq_,module,exports){ 30460/** 30461 * The copyright in this software is being made available under the BSD License, 30462 * included below. This software may be subject to other third party and contributor 30463 * rights, including patent rights, and no such rights are granted under this license. 30464 * 30465 * Copyright (c) 2013, Dash Industry Forum. 30466 * All rights reserved. 30467 * 30468 * Redistribution and use in source and binary forms, with or without modification, 30469 * are permitted provided that the following conditions are met: 30470 * * Redistributions of source code must retain the above copyright notice, this 30471 * list of conditions and the following disclaimer. 30472 * * Redistributions in binary form must reproduce the above copyright notice, 30473 * this list of conditions and the following disclaimer in the documentation and/or 30474 * other materials provided with the distribution. 30475 * * Neither the name of Dash Industry Forum nor the names of its 30476 * contributors may be used to endorse or promote products derived from this software 30477 * without specific prior written permission. 30478 * 30479 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 30480 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30481 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30482 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 30483 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
30483INCLUDING, BUT 30484 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30485 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30486 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30487 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30488 * POSSIBILITY OF SUCH DAMAGE. 30489 */ 30490'use strict'; 30491 30492Object.defineProperty(exports, '__esModule', { 30493 value: true 30494}); 30495 30496function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 30497 30498var _coreFactoryMaker = _dereq_(51); 30499 30500var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 30501 30502function MediaSourceController() { 30503 30504 var instance = undefined; 30505 30506 function createMediaSource() { 30507 30508 var hasWebKit = ('WebKitMediaSource' in window); 30509 var hasMediaSource = ('MediaSource' in window); 30510 30511 if (hasMediaSource) { 30512 return new MediaSource(); 30513 } else if (hasWebKit) { 30514 return new WebKitMediaSource(); 30515 } 30516 30517 return null; 30518 } 30519 30520 function attachMediaSource(source, videoModel) { 30521 30522 var objectURL = window.URL.createObjectURL(source); 30523 30524 videoModel.setSource(objectURL); 30525 30526 return objectURL; 30527 } 30528 30529 function detachMediaSource(videoModel) { 30530 videoModel.setSource(null); 30531 } 30532 30533 function setDuration(source, value) { 30534 30535 if (source.duration != value) source.duration = value; 30536 30537 return source.duration; 30538 } 30539 30540 function setSeekable(source, start, end) { 30541 if (typeof source.setLiveSeekableRange === 'function' && typeof source.clearLiveSeekableRange === 'function' && source.readyState === 'open' && start >= 0 && start < end) { 30542 source.clearLiveSeekableRange(); 30543 source.setLiveSeekableRange(start, end); 30544 } 30545 } 30546 30547 function signalEndOfStream(source) { 30548 30549 var buffers = source.sourceBuffers; 30550 var ln = buffers.length; 30551 30552 if (source.readyState !== 'open') return; 30553 30554 for (var i = 0; i < ln; i++) { 30555 if (buffers[i].updating) return; 30556 if (buffers[i].buffered.length === 0) return; 30557 } 30558 30559 source.endOfStream(); 30560 } 30561 30562 instance = { 30563 createMediaSource: createMediaSource, 30564 attachMediaSource: attachMediaSource, 30565 detachMediaSource: detachMediaSource, 30566 setDuration: setDuration, 30567 setSeekable: setSeekable, 30568 signalEndOfStream: signalEndOfStream 30569 }; 30570 30571 return instance; 30572} 30573 30574MediaSourceController.__dashjs_factory_name = 'MediaSourceController'; 30575exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(MediaSourceController); 30576module.exports = exports['default']; 30577 30578},{"51":51}],110:[function(_dereq_,module,exports){ 30579/** 30580 * The copyright in this software is being made available under the BSD License, 30581 * included below. This software may be subject to other third party and contributor 30582 * rights, including patent rights, and no such rights are granted under this license. 30583 * 30584 * Copyright (c) 2013, Dash Industry Forum. 30585 * All rights reserved. 30586 * 30587 * Redistribution and use in source and binary forms, with or without modification, 30588 * are permitted provided that the following conditions are met: 30589 * * Redistributions of source code must retain the above copyright notice, this 30590 * list of conditions and the following disclaimer. 30591 * * Redistributions in binary form must reproduce the above copyright notice, 30592 * this list of conditions and the following disclaimer in the documentation and/or 30593 * other materials provided with the distribution. 30594 * * Neither the name of Dash Industry Forum nor the names of its 30595 * contributors may be used to endorse or promote products derived from this software 30596 * without specific prior written permission. 30597 * 30598 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 30599 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30600 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30601 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 30602 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
30602INCLUDING, BUT 30603 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30604 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30605 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30606 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30607 * POSSIBILITY OF SUCH DAMAGE. 30608 */ 30609'use strict'; 30610 30611Object.defineProperty(exports, '__esModule', { 30612 value: true 30613}); 30614 30615function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 30616 30617var _constantsConstants = _dereq_(100); 30618 30619var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 30620 30621var _BufferController = _dereq_(105); 30622 30623var _BufferController2 = _interopRequireDefault(_BufferController); 30624 30625var _modelsURIQueryAndFragmentModel = _dereq_(144); 30626 30627var _modelsURIQueryAndFragmentModel2 = _interopRequireDefault(_modelsURIQueryAndFragmentModel); 30628 30629var _coreEventBus = _dereq_(50); 30630 30631var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 30632 30633var _coreEventsEvents = _dereq_(54); 30634 30635var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 30636 30637var _coreFactoryMaker = _dereq_(51); 30638 30639var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 30640 30641var _coreDebug = _dereq_(49); 30642 30643var _coreDebug2 = _interopRequireDefault(_coreDebug); 30644 30645function PlaybackController() { 30646 30647 var context = this.context; 30648 var log = (0, _coreDebug2['default'])(context).getInstance().log; 30649 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 30650 30651 var instance = undefined, 30652 streamController = undefined, 30653 metricsModel = undefined, 30654 dashMetrics = undefined, 30655 manifestModel = undefined, 30656 dashManifestModel = undefined, 30657 adapter = undefined, 30658 videoModel = undefined, 30659 currentTime = undefined, 30660 liveStartTime = undefined, 30661 wallclockTimeIntervalId = undefined, 30662 commonEarliestTime = undefined, 30663 bufferedRange = undefined, 30664 streamInfo = undefined, 30665 isDynamic = undefined, 30666 mediaPlayerModel = undefined, 30667 playOnceInitialized = undefined; 30668 30669 function setup() { 30670 reset(); 30671 } 30672 30673 function initialize(StreamInfo) { 30674 streamInfo = StreamInfo; 30675 addAllListeners(); 30676 isDynamic = streamInfo.manifestInfo.isDynamic; 30677 liveStartTime = streamInfo.start; 30678 eventBus.on(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, this); 30679 eventBus.on(_coreEventsEvents2['default'].BYTES_APPENDED, onBytesAppended, this); 30680 eventBus.on(_coreEventsEvents2['default'].BUFFER_LEVEL_STATE_CHANGED, onBufferLevelStateChanged, this); 30681 eventBus.on(_coreEventsEvents2['default'].PERIOD_SWITCH_STARTED, onPeriodSwitchStarted, this); 30682 30683 if (playOnceInitialized) { 30684 playOnceInitialized = false; 30685 play(); 30686 } 30687 } 30688 30689 function onPeriodSwitchStarted(e) { 30690 if (!isDynamic && e.fromStreamInfo && commonEarliestTime[e.fromStreamInfo.id] !== undefined) { 30691 delete bufferedRange[e.fromStreamInfo.id]; 30692 delete commonEarliestTime[e.fromStreamInfo.id]; 30693 } 30694 } 30695 30696 function getTimeToStreamEnd() { 30697 var startTime = getStreamStartTime(true); 30698 var offset = isDynamic ? startTime - streamInfo.start : 0; 30699 return startTime + (streamInfo.duration - offset) - getTime(); 30700 } 30701 30702 function play() { 30703 if (videoModel && videoModel.getElement()) { 30704 videoModel.play(); 30705 } else { 30706 playOnceInitialized = true; 30707 } 30708 } 30709 30710 function isPaused() { 30711 return videoModel ? videoModel.isPaused() : null; 30712 } 30713 30714 function pause() { 30715 if (videoModel) { 30716 videoModel.pause(); 30717 } 30718 } 30719 30720 function isSeeking() { 30721 return videoModel ? videoModel.isSeeking() : null; 30722 } 30723 30724 function seek(time) { 30725 if (videoModel) { 30726 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_SEEK_ASKED); 30727 log('Requesting seek to time: ' + time); 30728 videoModel.setCurrentTime(time); 30729 } 30730 } 30731 30732 function getTime() { 30733 return videoModel ? videoModel.getTime() : null; 30734 } 30735 30736 function getPlaybackRate() { 30737 return videoModel ? videoModel.getPlaybackRate() : null; 30738 } 30739 30740 function getPlayedRanges() { 30741 return videoModel ? videoModel.getPlayedRanges() : null; 30742 } 30743 30744 function getEnded() { 30745 return videoModel ? videoModel.getEnded() : null; 30746 } 30747 30748 function getIsDynamic() { 30749 return isDynamic; 30750 } 30751 30752 function getStreamController() { 30753 return streamController; 30754 } 30755 30756 function setLiveStartTime(value) { 30757 liveStartTime = value; 30758 } 30759 30760 function getLiveStartTime() { 30761 return liveStartTime; 30762 } 30763 30764 /** 30765 * Computes the desirable delay for the live edge to avoid a risk of getting 404 when playing at the bleeding edge 30766 * @param {number} fragmentDuration - seconds? 30767 * @param {number} dvrWindowSize - seconds? 30768 * @returns {number} object 30769 * @memberof PlaybackController# 30770 */ 30771 function computeLiveDelay(fragmentDuration, dvrWindowSize) { 30772 var mpd = dashManifestModel.getMpd(manifestModel.getValue()); 30773
30774 var delay = undefined; 30775 var END_OF_PLAYLIST_PADDING = 10; 30776 30777 if (mediaPlayerModel.getUseSuggestedPresentationDelay() && mpd.hasOwnProperty(_constantsConstants2['default'].SUGGESTED_PRESENTATION_DELAY)) { 30778 delay = mpd.suggestedPresentationDelay; 30779 } else if (mediaPlayerModel.getLiveDelay()) { 30780 delay = mediaPlayerModel.getLiveDelay(); // If set by user, this value takes precedence 30781 } else if (!isNaN(fragmentDuration)) { 30782 delay = fragmentDuration * mediaPlayerModel.getLiveDelayFragmentCount(); 30783 } else { 30784 delay = streamInfo.manifestInfo.minBufferTime * 2; 30785 } 30786 30787 if (dvrWindowSize > 0) { 30788 // cap target latency to: 30789 // - dvrWindowSize / 2 for short playlists 30790 // - dvrWindowSize - END_OF_PLAYLIST_PADDING for longer playlists 30791 var targetDelayCapping = Math.max(dvrWindowSize - END_OF_PLAYLIST_PADDING, dvrWindowSize / 2); 30792 return Math.min(delay, targetDelayCapping); 30793 } else { 30794 return delay; 30795 } 30796 } 30797 30798 function reset() { 30799 currentTime = 0; 30800 liveStartTime = NaN; 30801 wallclockTimeIntervalId = null; 30802 playOnceInitialized = false; 30803 commonEarliestTime = {}; 30804 bufferedRange = {}; 30805 if (videoModel) { 30806 eventBus.off(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, this); 30807 eventBus.off(_coreEventsEvents2['default'].BUFFER_LEVEL_STATE_CHANGED, onBufferLevelStateChanged, this); 30808 eventBus.off(_coreEventsEvents2['default'].BYTES_APPENDED, onBytesAppended, this); 30809 stopUpdatingWallclockTime(); 30810 removeAllListeners(); 30811 } 30812 videoModel = null; 30813 streamInfo = null; 30814 isDynamic = null; 30815 } 30816 30817 function setConfig(config) { 30818 if (!config) return; 30819 30820 if (config.streamController) { 30821 streamController = config.streamController; 30822 } 30823 if (config.metricsModel) { 30824 metricsModel = config.metricsModel; 30825 } 30826 if (config.dashMetrics) { 30827 dashMetrics = config.dashMetrics; 30828 } 30829 if (config.manifestModel) { 30830 manifestModel = config.manifestModel; 30831 } 30832 if (config.dashManifestModel) { 30833 dashManifestModel = config.dashManifestModel; 30834 } 30835 if (config.mediaPlayerModel) { 30836 mediaPlayerModel = config.mediaPlayerModel; 30837 } 30838 if (config.adapter) { 30839 adapter = config.adapter; 30840 } 30841 if (config.videoModel) { 30842 videoModel = config.videoModel; 30843 } 30844 } 30845 30846 /** 30847 * @param {boolean} ignoreStartOffset - ignore URL fragment start offset if true 30848 * @returns {number} object 30849 * @memberof PlaybackController# 30850 */ 30851 function getStreamStartTime(ignoreStartOffset) { 30852 var presentationStartTime = undefined; 30853 var fragData = (0, _modelsURIQueryAndFragmentModel2['default'])(context).getInstance().getURIFragmentData(); 30854 var startTimeOffset = NaN; 30855 30856 if (fragData) { 30857 var fragS = parseInt(fragData.s, 10); 30858 var fragT = parseInt(fragData.t, 10); 30859 if (!ignoreStartOffset) { 30860 startTimeOffset = !isNaN(fragS) ? fragS : fragT; 30861 } 30862 } else { 30863 // handle case where no media fragments are parsed from the manifest URL 30864 startTimeOffset = 0; 30865 } 30866 30867 if (isDynamic) { 30868 if (!isNaN(startTimeOffset) && startTimeOffset > 1262304000) { 30869 presentationStartTime = startTimeOffset - streamInfo.manifestInfo.availableFrom.getTime() / 1000; 30870 30871 if (presentationStartTime > liveStartTime || presentationStartTime < liveStartTime - streamInfo.manifestInfo.DVRWindowSize) { 30872 presentationStartTime = null; 30873 } 30874 } 30875 presentationStartTime = presentationStartTime || liveStartTime; 30876 } else { 30877 if (!isNaN(startTimeOffset) && startTimeOffset < Math.max(streamInfo.manifestInfo.duration, streamInfo.duration) && startTimeOffset >= 0) { 30878 presentationStartTime = startTimeOffset; 30879 } else { 30880 var earliestTime = commonEarliestTime[streamInfo.id]; //set by ready bufferStart after first onBytesAppended 30881 if (earliestTime === undefined) { 30882 earliestTime = streamController.getActiveStreamCommonEarliestTime(); //deal with calculated PST that is none 0 when streamInfo.start is 0 30883 } 30884 presentationStartTime = Math.max(earliestTime, streamInfo.start); 30885 } 30886 } 30887 30888 return presentationStartTime; 30889 } 30890 30891 function getActualPresentationTime(currentTime) {
30892 var metrics = metricsModel.getReadOnlyMetricsFor(_constantsConstants2['default'].VIDEO) || metricsModel.getReadOnlyMetricsFor(_constantsConstants2['default'].AUDIO); 30893 var DVRMetrics = dashMetrics.getCurrentDVRInfo(metrics); 30894 var DVRWindow = DVRMetrics ? DVRMetrics.range : null; 30895 var actualTime = undefined; 30896 30897 if (!DVRWindow) return NaN; 30898 if (currentTime > DVRWindow.end) { 30899 actualTime = Math.max(DVRWindow.end - streamInfo.manifestInfo.minBufferTime * 2, DVRWindow.start); 30900 } else if (currentTime < DVRWindow.start) { 30901 actualTime = DVRWindow.start; 30902 } else { 30903 return currentTime; 30904 } 30905 30906 return actualTime; 30907 } 30908 30909 function startUpdatingWallclockTime() { 30910 if (wallclockTimeIntervalId !== null) return; 30911 30912 var tick = function tick() { 30913 onWallclockTime(); 30914 }; 30915 30916 wallclockTimeIntervalId = setInterval(tick, mediaPlayerModel.getWallclockTimeUpdateInterval()); 30917 } 30918 30919 function stopUpdatingWallclockTime() { 30920 clearInterval(wallclockTimeIntervalId); 30921 wallclockTimeIntervalId = null; 30922 } 30923 30924 function updateCurrentTime() { 30925 if (isPaused() || !isDynamic || videoModel.getReadyState() === 0) return; 30926 var currentTime = getTime(); 30927 var actualTime = getActualPresentationTime(currentTime); 30928 var timeChanged = !isNaN(actualTime) && actualTime !== currentTime; 30929 if (timeChanged) { 30930 seek(actualTime); 30931 } 30932 } 30933 30934 function onDataUpdateCompleted(e) { 30935 if (e.error) return; 30936 30937 var representationInfo = adapter.convertDataToRepresentationInfo(e.currentRepresentation); 30938 var info = representationInfo.mediaInfo.streamInfo; 30939 30940 if (streamInfo.id !== info.id) return; 30941 streamInfo = info; 30942 30943 updateCurrentTime(); 30944 } 30945 30946 function onCanPlay() { 30947 eventBus.trigger(_coreEventsEvents2['default'].CAN_PLAY); 30948 } 30949 30950 function onPlaybackStart() { 30951 log('Native video element event: play'); 30952 updateCurrentTime(); 30953 startUpdatingWallclockTime(); 30954 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_STARTED, { 30955 startTime: getTime() 30956 }); 30957 } 30958 30959 function onPlaybackPlaying() { 30960 log('Native video element event: playing'); 30961 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_PLAYING, { 30962 playingTime: getTime() 30963 }); 30964 } 30965 30966 function onPlaybackPaused() { 30967 log('Native video element event: pause'); 30968 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_PAUSED, { 30969 ended: getEnded() 30970 }); 30971 } 30972 30973 function onPlaybackSeeking() { 30974 var seekTime = getTime(); 30975 log('Seeking to: ' + seekTime); 30976 startUpdatingWallclockTime(); 30977 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_SEEKING, { 30978 seekTime: seekTime 30979 }); 30980 } 30981 30982 function onPlaybackSeeked() { 30983 log('Native video element event: seeked'); 30984 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_SEEKED); 30985 } 30986 30987 function onPlaybackTimeUpdated() { 30988 var time = getTime(); 30989 if (time === currentTime) return; 30990 currentTime = time; 30991 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_TIME_UPDATED, { 30992 timeToEnd: getTimeToStreamEnd(), 30993 time: time 30994 }); 30995 } 30996 30997 function onPlaybackProgress() { 30998 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_PROGRESS); 30999 } 31000 31001 function onPlaybackRateChanged() { 31002 var rate = getPlaybackRate(); 31003 log('Native video element event: ratechange: ', rate); 31004 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_RATE_CHANGED, { 31005 playbackRate: rate 31006 }); 31007 } 31008 31009 function onPlaybackMetaDataLoaded() { 31010 log('Native video element event: loadedmetadata'); 31011 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_METADATA_LOADED);
31012 startUpdatingWallclockTime(); 31013 } 31014 31015 function onPlaybackEnded() { 31016 log('Native video element event: ended'); 31017 pause(); 31018 stopUpdatingWallclockTime(); 31019 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_ENDED); 31020 } 31021 31022 function onPlaybackError(event) { 31023 var target = event.target || event.srcElement; 31024 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_ERROR, { 31025 error: target.error 31026 }); 31027 } 31028 31029 function onWallclockTime() { 31030 eventBus.trigger(_coreEventsEvents2['default'].WALLCLOCK_TIME_UPDATED, { 31031 isDynamic: isDynamic, 31032 time: new Date() 31033 }); 31034 } 31035 31036 function checkTimeInRanges(time, ranges) { 31037 if (ranges && ranges.length > 0) { 31038 for (var i = 0, len = ranges.length; i < len; i++) { 31039 if (time >= ranges.start(i) && time < ranges.end(i)) { 31040 return true; 31041 } 31042 } 31043 } 31044 return false; 31045 } 31046 31047 function onBytesAppended(e) { 31048 var earliestTime = undefined, 31049 initialStartTime = undefined; 31050 var ranges = e.bufferedRanges; 31051 if (!ranges || !ranges.length) return; 31052 if (commonEarliestTime[streamInfo.id] === false) { 31053 //stream has already been started. 31054 return; 31055 } 31056 31057 var type = e.sender.getType(); 31058 31059 if (bufferedRange[streamInfo.id] === undefined) { 31060 bufferedRange[streamInfo.id] = []; 31061 } 31062 31063 bufferedRange[streamInfo.id][type] = ranges; 31064 31065 if (commonEarliestTime[streamInfo.id] === undefined) { 31066 commonEarliestTime[streamInfo.id] = []; 31067 } 31068 31069 if (commonEarliestTime[streamInfo.id][type] === undefined) { 31070 commonEarliestTime[streamInfo.id][type] = Math.max(ranges.start(0), streamInfo.start); 31071 } 31072 31073 var hasVideoTrack = streamController.isVideoTrackPresent(); 31074 var hasAudioTrack = streamController.isAudioTrackPresent(); 31075 31076 initialStartTime = getStreamStartTime(false); 31077 31078 if (hasAudioTrack && hasVideoTrack) { 31079 //current stream has audio and video contents 31080 if (!isNaN(commonEarliestTime[streamInfo.id].audio) && !isNaN(commonEarliestTime[streamInfo.id].video)) { 31081 31082 if (commonEarliestTime[streamInfo.id].audio < commonEarliestTime[streamInfo.id].video) { 31083 // common earliest is video time 31084 // check buffered audio range has video time, if ok, we seek, otherwise, we wait some other data 31085 earliestTime = commonEarliestTime[streamInfo.id].video > initialStartTime ? commonEarliestTime[streamInfo.id].video : initialStartTime; 31086 ranges = bufferedRange[streamInfo.id].audio; 31087 } else { 31088 // common earliest is audio time 31089 // check buffered video range has audio time, if ok, we seek, otherwise, we wait some other data 31090 earliestTime = commonEarliestTime[streamInfo.id].audio > initialStartTime ? commonEarliestTime[streamInfo.id].audio : initialStartTime; 31091 ranges = bufferedRange[streamInfo.id].video; 31092 } 31093 if (checkTimeInRanges(earliestTime, ranges)) { 31094 seek(earliestTime); 31095 commonEarliestTime[streamInfo.id] = false; 31096 } 31097 } 31098 } else { 31099 //current stream has only audio or only video content 31100 if (commonEarliestTime[streamInfo.id][type]) { 31101 earliestTime = commonEarliestTime[streamInfo.id][type] > initialStartTime ? commonEarliestTime[streamInfo.id][type] : initialStartTime; 31102 seek(earliestTime); 31103 commonEarliestTime[streamInfo.id] = false; 31104 } 31105 } 31106 } 31107 31108 function onBufferLevelStateChanged(e) { 31109 // do not stall playback when get an event from Stream that is not active 31110 if (e.streamInfo.id !== streamInfo.id) return; 31111 videoModel.setStallState(e.mediaType, e.state === _BufferController2['default'].BUFFER_EMPTY); 31112 } 31113 31114 function addAllListeners() { 31115 videoModel.addEventListener('canplay', onCanPlay); 31116 videoModel.addEventListener('play', onPlaybackStart); 31117 videoModel.addEventListener('playing', onPlaybackPlaying); 31118 videoModel.addEventListener('pause', onPlaybackPaused); 31119 videoModel.addEventListener('error', onPlaybackError); 31120 videoModel.addEventListener('seeking', onPlaybackSeeking); 31121 videoModel.addEventListener('seeked', onPlaybackSeeked); 31122 videoModel.addEventListener('timeupdate', onPlaybackTimeUpdated); 31123 videoModel.addEventListener('progress', onPlaybackProgress); 31124 videoModel.addEventListener('ratechange', onPlaybackRateChanged); 31125 videoModel.addEventListener('loadedmetadata', onPlaybackMetaDataLoaded); 31126 videoModel.addEventListener('ended', onPlaybackEnded);
31127 } 31128 31129 function removeAllListeners() { 31130 videoModel.removeEventListener('canplay', onCanPlay); 31131 videoModel.removeEventListener('play', onPlaybackStart); 31132 videoModel.removeEventListener('playing', onPlaybackPlaying); 31133 videoModel.removeEventListener('pause', onPlaybackPaused); 31134 videoModel.removeEventListener('error', onPlaybackError); 31135 videoModel.removeEventListener('seeking', onPlaybackSeeking); 31136 videoModel.removeEventListener('seeked', onPlaybackSeeked); 31137 videoModel.removeEventListener('timeupdate', onPlaybackTimeUpdated); 31138 videoModel.removeEventListener('progress', onPlaybackProgress); 31139 videoModel.removeEventListener('ratechange', onPlaybackRateChanged); 31140 videoModel.removeEventListener('loadedmetadata', onPlaybackMetaDataLoaded); 31141 videoModel.removeEventListener('ended', onPlaybackEnded); 31142 } 31143 31144 instance = { 31145 initialize: initialize, 31146 setConfig: setConfig, 31147 getStreamStartTime: getStreamStartTime, 31148 getTimeToStreamEnd: getTimeToStreamEnd, 31149 getTime: getTime, 31150 getPlaybackRate: getPlaybackRate, 31151 getPlayedRanges: getPlayedRanges, 31152 getEnded: getEnded, 31153 getIsDynamic: getIsDynamic, 31154 getStreamController: getStreamController, 31155 setLiveStartTime: setLiveStartTime, 31156 getLiveStartTime: getLiveStartTime, 31157 computeLiveDelay: computeLiveDelay, 31158 play: play, 31159 isPaused: isPaused, 31160 pause: pause, 31161 isSeeking: isSeeking, 31162 seek: seek, 31163 reset: reset 31164 }; 31165 31166 setup(); 31167 31168 return instance; 31169} 31170 31171PlaybackController.__dashjs_factory_name = 'PlaybackController'; 31172exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(PlaybackController); 31173module.exports = exports['default']; 31174 31175},{"100":100,"105":105,"144":144,"49":49,"50":50,"51":51,"54":54}],111:[function(_dereq_,module,exports){ 31176/** 31177 * The copyright in this software is being made available under the BSD License, 31178 * included below. This software may be subject to other third party and contributor 31179 * rights, including patent rights, and no such rights are granted under this license. 31180 * 31181 * Copyright (c) 2013, Dash Industry Forum. 31182 * All rights reserved. 31183 * 31184 * Redistribution and use in source and binary forms, with or without modification, 31185 * are permitted provided that the following conditions are met: 31186 * * Redistributions of source code must retain the above copyright notice, this 31187 * list of conditions and the following disclaimer. 31188 * * Redistributions in binary form must reproduce the above copyright notice, 31189 * this list of conditions and the following disclaimer in the documentation and/or 31190 * other materials provided with the distribution. 31191 * * Neither the name of Dash Industry Forum nor the names of its 31192 * contributors may be used to endorse or promote products derived from this software 31193 * without specific prior written permission. 31194 * 31195 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 31196 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 31197 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 31198 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 31199 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31200 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31201 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31202 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31203 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31204 * POSSIBILITY OF SUCH DAMAGE. 31205 */ 31206'use strict'; 31207 31208Object.defineProperty(exports, '__esModule', { 31209 value: true 31210}); 31211 31212function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 31213 31214var _constantsConstants = _dereq_(100); 31215 31216var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 31217 31218var _voMetricsPlayList = _dereq_(226); 31219 31220var _AbrController = _dereq_(102); 31221 31222var _AbrController2 = _interopRequireDefault(_AbrController); 31223 31224var _BufferController = _dereq_(105); 31225 31226var _BufferController2 = _interopRequireDefault(_BufferController); 31227 31228var _rulesSchedulingBufferLevelRule = _dereq_(181); 31229 31230var _rulesSchedulingBufferLevelRule2 = _interopRequireDefault(_rulesSchedulingBufferLevelRule); 31231 31232var _rulesSchedulingNextFragmentRequestRule = _dereq_(182); 31233 31234var _rulesSchedulingNextFragmentRequestRule2 = _interopRequireDefault(_rulesSchedulingNextFragmentRequestRule); 31235 31236var _modelsFragmentModel = _dereq_(140); 31237 31238var _modelsFragmentModel2 = _interopRequireDefault(_modelsFragmentModel); 31239 31240var _coreEventBus = _dereq_(50); 31241 31242var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 31243 31244var _coreEventsEvents = _dereq_(54); 31245 31246var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 31247 31248var _coreFactoryMaker = _dereq_(51); 31249 31250var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 31251 31252var _coreDebug = _dereq_(49); 31253 31254var _coreDebug2 = _interopRequireDefault(_coreDebug); 31255 31256function ScheduleController(config) { 31257 31258 var context = this.context; 31259 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 31260 var metricsModel = config.metricsModel; 31261 var adapter = config.adapter; 31262 var dashMetrics = config.dashMetrics; 31263 var dashManifestModel = config.dashManifestModel; 31264 var timelineConverter = config.timelineConverter; 31265 var mediaPlayerModel = config.mediaPlayerModel; 31266 var abrController = config.abrController; 31267 var playbackController = config.playbackController; 31268 var streamController = config.streamController; 31269 var textController = config.textController; 31270 var sourceBufferController = config.sourceBufferController; 31271 var type = config.type; 31272 var streamProcessor = config.streamProcessor; 31273 31274 var instance = undefined, 31275 log = undefined, 31276 fragmentModel = undefined, 31277 currentRepresentationInfo = undefined, 31278 initialRequest = undefined, 31279 isStopped = undefined, 31280 playListMetrics = undefined, 31281 playListTraceMetrics = undefined, 31282 playListTraceMetricsClosed = undefined, 31283 isFragmentProcessingInProgress = undefined, 31284 timeToLoadDelay = undefined, 31285 scheduleTimeout = undefined, 31286 seekTarget = undefined, 31287 bufferLevelRule = undefined, 31288 nextFragmentRequestRule = undefined, 31289 scheduleWhilePaused = undefined, 31290 lastQualityIndex = undefined, 31291 topQualityIndex = undefined, 31292 lastInitQuality = undefined, 31293 replaceRequestArray = undefined, 31294 switchTrack = undefined; 31295 31296 function setup() { 31297 log = (0, _coreDebug2['default'])(context).getInstance().log.bind(instance); 31298 31299 resetInitialSettings();
31300 } 31301 31302 function initialize() { 31303 fragmentModel = streamProcessor.getFragmentModel(); 31304 scheduleWhilePaused = mediaPlayerModel.getScheduleWhilePaused(); 31305 31306 bufferLevelRule = (0, _rulesSchedulingBufferLevelRule2['default'])(context).create({ 31307 abrController: abrController, 31308 dashMetrics: dashMetrics, 31309 metricsModel: metricsModel, 31310 mediaPlayerModel: mediaPlayerModel, 31311 textController: textController 31312 }); 31313 31314 nextFragmentRequestRule = (0, _rulesSchedulingNextFragmentRequestRule2['default'])(context).create({ 31315 adapter: adapter, 31316 sourceBufferController: sourceBufferController, 31317 textController: textController 31318 }); 31319 31320 if (dashManifestModel.getIsTextTrack(type)) { 31321 eventBus.on(_coreEventsEvents2['default'].TIMED_TEXT_REQUESTED, onTimedTextRequested, this); 31322 } 31323 31324 //eventBus.on(Events.LIVE_EDGE_SEARCH_COMPLETED, onLiveEdgeSearchCompleted, this); 31325 eventBus.on(_coreEventsEvents2['default'].QUALITY_CHANGE_REQUESTED, onQualityChanged, this); 31326 eventBus.on(_coreEventsEvents2['default'].DATA_UPDATE_STARTED, onDataUpdateStarted, this); 31327 eventBus.on(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, this); 31328 eventBus.on(_coreEventsEvents2['default'].FRAGMENT_LOADING_COMPLETED, onFragmentLoadingCompleted, this); 31329 eventBus.on(_coreEventsEvents2['default'].STREAM_COMPLETED, onStreamCompleted, this); 31330 eventBus.on(_coreEventsEvents2['default'].STREAM_INITIALIZED, onStreamInitialized, this); 31331 eventBus.on(_coreEventsEvents2['default'].BUFFER_LEVEL_STATE_CHANGED, onBufferLevelStateChanged, this); 31332 eventBus.on(_coreEventsEvents2['default'].BUFFER_CLEARED, onBufferCleared, this); 31333 eventBus.on(_coreEventsEvents2['default'].BYTES_APPENDED, onBytesAppended, this); 31334 eventBus.on(_coreEventsEvents2['default'].INIT_REQUESTED, onInitRequested, this); 31335 eventBus.on(_coreEventsEvents2['default'].QUOTA_EXCEEDED, onQuotaExceeded, this); 31336 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, this); 31337 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_STARTED, onPlaybackStarted, this); 31338 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_RATE_CHANGED, onPlaybackRateChanged, this); 31339 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_TIME_UPDATED, onPlaybackTimeUpdated, this); 31340 eventBus.on(_coreEventsEvents2['default'].URL_RESOLUTION_FAILED, onURLResolutionFailed, this); 31341 eventBus.on(_coreEventsEvents2['default'].FRAGMENT_LOADING_ABANDONED, onFragmentLoadingAbandoned, this); 31342 } 31343 31344 function isStarted() { 31345 return isStopped === false; 31346 } 31347 31348 function start() { 31349 if (!currentRepresentationInfo || streamProcessor.isBufferingCompleted()) { 31350 return; 31351 } 31352 31353 addPlaylistTraceMetrics(); 31354 isStopped = false; 31355 31356 if (initialRequest) { 31357 initialRequest = false; 31358 } 31359 31360 startScheduleTimer(0); 31361 31362 log('Schedule controller starting for ' + type); 31363 } 31364 31365 function stop() { 31366 if (isStopped) { 31367 return; 31368 } 31369 31370 isStopped = true; 31371 clearTimeout(scheduleTimeout); 31372 log('Schedule controller stopping for ' + type); 31373 } 31374 31375 function hasTopQualityChanged(type, id) { 31376 topQualityIndex[id] = topQualityIndex[id] || {}; 31377 var newTopQualityIndex = abrController.getTopQualityIndexFor(type, id); 31378 31379 if (topQualityIndex[id][type] != newTopQualityIndex) { 31380 log('Top quality' + type + ' index has changed from ' + topQualityIndex[id][type] + ' to ' + newTopQualityIndex); 31381 topQualityIndex[id][type] = newTopQualityIndex; 31382 return true; 31383 } 31384 return false; 31385 } 31386 31387 function schedule() { 31388 if (isStopped || isFragmentProcessingInProgress || !streamProcessor.getBufferController() || playbackController.isPaused() && !scheduleWhilePaused) { 31389 return; 31390 } 31391 31392 validateExecutedFragmentRequest(); 31393 31394 var isReplacement = replaceRequestArray.length > 0;
31395 if (switchTrack || isReplacement || hasTopQualityChanged(currentRepresentationInfo.mediaInfo.type, streamProcessor.getStreamInfo().id) || bufferLevelRule.execute(streamProcessor, type, streamController.isVideoTrackPresent())) { 31396 31397 var getNextFragment = function getNextFragment() { 31398 log('ScheduleController - getNextFragment'); 31399 var fragmentController = streamProcessor.getFragmentController(); 31400 if (switchTrack) { 31401 log('ScheduleController - switch track has been asked, get init request for ' + type + ' with representationid = ' + currentRepresentationInfo.id); 31402 streamProcessor.switchInitData(currentRepresentationInfo.id); 31403 switchTrack = false; 31404 } else if (currentRepresentationInfo.quality !== lastInitQuality) { 31405 log('ScheduleController - quality has changed, get init request'); 31406 lastInitQuality = currentRepresentationInfo.quality; 31407 31408 streamProcessor.switchInitData(currentRepresentationInfo.id); 31409 } else { 31410 var replacement = replaceRequestArray.shift(); 31411 31412 if (fragmentController.isInitializationRequest(replacement)) { 31413 //to be sure the specific init segment had not already been loaded. 31414 streamProcessor.switchInitData(replacement.representationId); 31415 } else { 31416 var request = nextFragmentRequestRule.execute(streamProcessor, replacement); 31417 if (request) { 31418 log('ScheduleController - getNextFragment - request is ' + request.url); 31419 fragmentModel.executeRequest(request); 31420 } else { 31421 //Use case - Playing at the bleeding live edge and frag is not available yet. Cycle back around. 31422 log('getNextFragment - Playing at the bleeding live edge and frag is not available yet'); 31423 isFragmentProcessingInProgress = false; 31424 startScheduleTimer(500); 31425 } 31426 } 31427 } 31428 }; 31429 31430 isFragmentProcessingInProgress = true; 31431 if (isReplacement || switchTrack) { 31432 getNextFragment(); 31433 } else { 31434 abrController.checkPlaybackQuality(type); 31435 getNextFragment(); 31436 } 31437 } else { 31438 startScheduleTimer(500); 31439 } 31440 } 31441 31442 function validateExecutedFragmentRequest() { 31443 //Validate that the fragment request executed and appended into the source buffer is as 31444 // good of quality as the current quality and is the correct media track. 31445 var safeBufferLevel = currentRepresentationInfo.fragmentDuration * 1.5; 31446 var request = fragmentModel.getRequests({ 31447 state: _modelsFragmentModel2['default'].FRAGMENT_MODEL_EXECUTED, 31448 time: playbackController.getTime() + safeBufferLevel, 31449 threshold: 0 31450 })[0]; 31451 31452 if (request && replaceRequestArray.indexOf(request) === -1 && !dashManifestModel.getIsTextTrack(type)) { 31453 var fastSwitchModeEnabled = mediaPlayerModel.getFastSwitchEnabled(); 31454 var bufferLevel = streamProcessor.getBufferLevel(); 31455 var abandonmentState = abrController.getAbandonmentStateFor(type); 31456 31457 if (fastSwitchModeEnabled && request.quality < currentRepresentationInfo.quality && bufferLevel >= safeBufferLevel && abandonmentState !== _AbrController2['default'].ABANDON_LOAD) { 31458 replaceRequest(request); 31459 log('Reloading outdated fragment at index: ', request.index); 31460 } else if (request.quality > currentRepresentationInfo.quality) { 31461 //The buffer has better quality it in then what we would request so set append point to end of buffer!! 31462 setSeekTarget(playbackController.getTime() + streamProcessor.getBufferLevel()); 31463 } 31464 } 31465 } 31466 31467 function startScheduleTimer(value) { 31468 clearTimeout(scheduleTimeout); 31469 scheduleTimeout = setTimeout(schedule, value); 31470 } 31471 31472 function onInitRequested(e) { 31473 if (!e.sender || e.sender.getStreamProcessor() !== streamProcessor) { 31474 return; 31475 } 31476 31477 getInitRequest(currentRepresentationInfo.quality); 31478 } 31479 31480 function getInitRequest(quality) { 31481 lastInitQuality = quality; 31482 31483 var request = adapter.getInitRequest(streamProcessor, quality); 31484 if (request) { 31485 isFragmentProcessingInProgress = true; 31486 fragmentModel.executeRequest(request); 31487 } 31488 } 31489 31490 function switchTrackAsked() { 31491 switchTrack = true; 31492 } 31493
31494 function replaceRequest(request) { 31495 replaceRequestArray.push(request); 31496 } 31497 31498 function onQualityChanged(e) { 31499 if (type !== e.mediaType || streamProcessor.getStreamInfo().id !== e.streamInfo.id) { 31500 return; 31501 } 31502 31503 currentRepresentationInfo = streamProcessor.getRepresentationInfoForQuality(e.newQuality); 31504 31505 if (currentRepresentationInfo === null || currentRepresentationInfo === undefined) { 31506 throw new Error('Unexpected error! - currentRepresentationInfo is null or undefined'); 31507 } 31508 31509 clearPlayListTraceMetrics(new Date(), _voMetricsPlayList.PlayListTrace.REPRESENTATION_SWITCH_STOP_REASON); 31510 addPlaylistTraceMetrics(); 31511 } 31512 31513 function completeQualityChange(trigger) { 31514 if (playbackController && fragmentModel) { 31515 var item = fragmentModel.getRequests({ 31516 state: _modelsFragmentModel2['default'].FRAGMENT_MODEL_EXECUTED, 31517 time: playbackController.getTime(), 31518 threshold: 0 31519 })[0]; 31520 if (item && playbackController.getTime() >= item.startTime) { 31521 if (item.quality !== lastQualityIndex && trigger) { 31522 eventBus.trigger(_coreEventsEvents2['default'].QUALITY_CHANGE_RENDERED, { 31523 mediaType: type, 31524 oldQuality: lastQualityIndex, 31525 newQuality: item.quality 31526 }); 31527 } 31528 lastQualityIndex = item.quality; 31529 } 31530 } 31531 } 31532 31533 function onDataUpdateCompleted(e) { 31534 if (e.error || e.sender.getStreamProcessor() !== streamProcessor) { 31535 return; 31536 } 31537 31538 currentRepresentationInfo = adapter.convertDataToRepresentationInfo(e.currentRepresentation); 31539 } 31540 31541 function onStreamInitialized(e) { 31542 if (e.error || streamProcessor.getStreamInfo().id !== e.streamInfo.id) { 31543 return; 31544 } 31545 31546 currentRepresentationInfo = streamProcessor.getCurrentRepresentationInfo(); 31547 31548 if (initialRequest) { 31549 if (playbackController.getIsDynamic()) { 31550 timelineConverter.setTimeSyncCompleted(true); 31551 setLiveEdgeSeekTarget(); 31552 } else { 31553 seekTarget = playbackController.getStreamStartTime(false); 31554 streamProcessor.getBufferController().setSeekStartTime(seekTarget); 31555 } 31556 } 31557 31558 if (isStopped) { 31559 start(); 31560 } 31561 } 31562 31563 function setLiveEdgeSeekTarget() { 31564 var liveEdgeFinder = streamProcessor.getLiveEdgeFinder(); 31565 if (liveEdgeFinder) { 31566 var liveEdge = liveEdgeFinder.getLiveEdge(); 31567 var dvrWindowSize = currentRepresentationInfo.mediaInfo.streamInfo.manifestInfo.DVRWindowSize / 2; 31568 var startTime = liveEdge - playbackController.computeLiveDelay(currentRepresentationInfo.fragmentDuration, dvrWindowSize); 31569 var request = adapter.getFragmentRequestForTime(streamProcessor, currentRepresentationInfo, startTime, { 31570 ignoreIsFinished: true 31571 }); 31572 seekTarget = playbackController.getLiveStartTime(); 31573 if (isNaN(seekTarget) || request.startTime > seekTarget) { 31574 //special use case for multi period stream. If the startTime is out of the current period, send a seek command. 31575 //in onPlaybackSeeking callback (StreamController), the detection of switch stream is done. 31576 if (request.startTime > currentRepresentationInfo.mediaInfo.streamInfo.start + currentRepresentationInfo.mediaInfo.streamInfo.duration) { 31577 playbackController.seek(request.startTime); 31578 } 31579 playbackController.setLiveStartTime(request.startTime); 31580 seekTarget = request.startTime; 31581 } 31582 31583 var manifestUpdateInfo = dashMetrics.getCurrentManifestUpdate(metricsModel.getMetricsFor(_constantsConstants2['default'].STREAM)); 31584 metricsModel.updateManifestUpdateInfo(manifestUpdateInfo, { 31585 currentTime: seekTarget, 31586 presentationStartTime: liveEdge, 31587 latency: liveEdge - seekTarget,
31588 clientTimeOffset: timelineConverter.getClientTimeOffset() 31589 }); 31590 } 31591 } 31592 31593 function onStreamCompleted(e) { 31594 if (e.fragmentModel !== fragmentModel) { 31595 return; 31596 } 31597 31598 stop(); 31599 isFragmentProcessingInProgress = false; 31600 log('Stream is complete'); 31601 } 31602 31603 function onFragmentLoadingCompleted(e) { 31604 if (e.sender !== fragmentModel) { 31605 return; 31606 } 31607 31608 if (dashManifestModel.getIsTextTrack(type)) { 31609 isFragmentProcessingInProgress = false; 31610 } 31611 31612 if (e.error && e.request.serviceLocation && !isStopped) { 31613 replaceRequest(e.request); 31614 isFragmentProcessingInProgress = false; 31615 startScheduleTimer(0); 31616 } 31617 } 31618 31619 function onPlaybackTimeUpdated() { 31620 completeQualityChange(true); 31621 } 31622 31623 function onBytesAppended(e) { 31624 if (e.sender.getStreamProcessor() !== streamProcessor) { 31625 return; 31626 } 31627 31628 isFragmentProcessingInProgress = false; 31629 startScheduleTimer(0); 31630 } 31631 31632 function onFragmentLoadingAbandoned(e) { 31633 if (e.streamProcessor !== streamProcessor) { 31634 return; 31635 } 31636 log('[ScheduleController][' + type + '] Request ' + e.request.url + ' has been aborted'); 31637 replaceRequest(e.request); 31638 isFragmentProcessingInProgress = false; 31639 startScheduleTimer(0); 31640 } 31641 31642 function onDataUpdateStarted(e) { 31643 if (e.sender.getStreamProcessor() !== streamProcessor) { 31644 return; 31645 } 31646 31647 stop(); 31648 } 31649 31650 function onBufferCleared(e) { 31651 if (e.sender.getStreamProcessor() !== streamProcessor) { 31652 return; 31653 } 31654 31655 // after the data has been removed from the buffer we should remove the requests from the list of 31656 // the executed requests for which playback time is inside the time interval that has been removed from the buffer 31657 fragmentModel.removeExecutedRequestsBeforeTime(e.to); 31658 31659 if (e.hasEnoughSpaceToAppend && isStopped) { 31660 start(); 31661 } 31662 } 31663 31664 function onBufferLevelStateChanged(e) { 31665 if (e.sender.getStreamProcessor() === streamProcessor && e.state === _BufferController2['default'].BUFFER_EMPTY && !playbackController.isSeeking()) { 31666 log('Buffer is empty! Stalling!'); 31667 clearPlayListTraceMetrics(new Date(), _voMetricsPlayList.PlayListTrace.REBUFFERING_REASON); 31668 } 31669 } 31670 31671 function onQuotaExceeded(e) { 31672 if (e.sender.getStreamProcessor() !== streamProcessor) { 31673 return; 31674 } 31675 31676 stop(); 31677 isFragmentProcessingInProgress = false; 31678 } 31679 31680 function onURLResolutionFailed() { 31681 fragmentModel.abortRequests(); 31682 stop(); 31683 } 31684 31685 function onTimedTextRequested(e) { 31686 if (e.sender.getStreamProcessor() !== streamProcessor) { 31687 return; 31688 } 31689 31690 getInitRequest(e.index); 31691 } 31692 31693 function onPlaybackStarted() { 31694 if (isStopped || !scheduleWhilePaused) { 31695 start(); 31696 } 31697 } 31698 31699 function onPlaybackSeeking(e) { 31700 seekTarget = e.seekTime; 31701 setTimeToLoadDelay(0); 31702 31703 if (isStopped) { 31704 start(); 31705 } 31706 31707 var manifestUpdateInfo = dashMetrics.getCurrentManifestUpdate(metricsModel.getMetricsFor(_constantsConstants2['default'].STREAM)); 31708 var latency = currentRepresentationInfo.DVRWindow && playbackController ? currentRepresentationInfo.DVRWindow.end - playbackController.getTime() : NaN; 31709 metricsModel.updateManifestUpdateInfo(manifestUpdateInfo, { 31710 latency: latency 31711 }); 31712 31713 //if, during the seek command, the scheduleController is waiting : stop waiting, request chunk as soon as possible 31714 if (!isFragmentProcessingInProgress) { 31715 startScheduleTimer(0); 31716 } 31717 } 31718 31719 function onPlaybackRateChanged(e) { 31720 if (playListTraceMetrics) { 31721 playListTraceMetrics.playbackspeed = e.playbackRate.toString(); 31722 } 31723 } 31724 31725 function getSeekTarget() { 31726 return seekTarget; 31727 } 31728 31729 function setSeekTarget(value) { 31730 seekTarget = value; 31731 } 31732 31733 function setTimeToLoadDelay(value) { 31734 timeToLoadDelay = value; 31735 } 31736 31737 function getTimeToLoadDelay() { 31738 return timeToLoadDelay; 31739 } 31740 31741 function getBufferTarget() { 31742 return bufferLevelRule.getBufferTarget(streamProcessor, type, streamController.isVideoTrackPresent()); 31743 } 31744 31745 function getType() { 31746 return type; 31747 } 31748 31749 function setPlayList(playList) { 31750 playListMetrics = playList; 31751 } 31752 31753 function finalisePlayList(time, reason) { 31754 clearPlayListTraceMetrics(time, reason); 31755 playListMetrics = null; 31756 } 31757 31758 function clearPlayListTraceMetrics(endTime, stopreason) { 31759 if (playListMetrics && playListTraceMetricsClosed === false) { 31760 var startTime = playListTraceMetrics.start; 31761 var duration = endTime.getTime() - startTime.getTime(); 31762 playListTraceMetrics.duration = duration; 31763 playListTraceMetrics.stopreason = stopreason; 31764 playListMetrics.trace.push(playListTraceMetrics); 31765 playListTraceMetricsClosed = true; 31766 } 31767 } 31768 31769 function addPlaylistTraceMetrics() { 31770 if (playListMetrics && playListTraceMetricsClosed === true && currentRepresentationInfo) { 31771 playListTraceMetricsClosed = false; 31772 playListTraceMetrics = new _voMetricsPlayList.PlayListTrace(); 31773 playListTraceMetrics.representationid = currentRepresentationInfo.id; 31774 playListTraceMetrics.start = new Date(); 31775 playListTraceMetrics.mstart = playbackController.getTime() * 1000; 31776 playListTraceMetrics.playbackspeed = playbackController.getPlaybackRate().toString(); 31777 } 31778 } 31779 31780 function resetInitialSettings() { 31781 isFragmentProcessingInProgress = false; 31782 timeToLoadDelay = 0; 31783 seekTarget = NaN; 31784 playListMetrics = null; 31785 playListTraceMetrics = null; 31786 playListTraceMetricsClosed = true; 31787 initialRequest = true;
31788 lastInitQuality = NaN; 31789 lastQualityIndex = NaN; 31790 topQualityIndex = {}; 31791 replaceRequestArray = []; 31792 isStopped = true; 31793 switchTrack = true; 31794 } 31795 31796 function reset() { 31797 //eventBus.off(Events.LIVE_EDGE_SEARCH_COMPLETED, onLiveEdgeSearchCompleted, this); 31798 eventBus.off(_coreEventsEvents2['default'].DATA_UPDATE_STARTED, onDataUpdateStarted, this); 31799 eventBus.off(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, this); 31800 eventBus.off(_coreEventsEvents2['default'].BUFFER_LEVEL_STATE_CHANGED, onBufferLevelStateChanged, this); 31801 eventBus.off(_coreEventsEvents2['default'].QUALITY_CHANGE_REQUESTED, onQualityChanged, this); 31802 eventBus.off(_coreEventsEvents2['default'].FRAGMENT_LOADING_COMPLETED, onFragmentLoadingCompleted, this); 31803 eventBus.off(_coreEventsEvents2['default'].STREAM_COMPLETED, onStreamCompleted, this); 31804 eventBus.off(_coreEventsEvents2['default'].STREAM_INITIALIZED, onStreamInitialized, this); 31805 eventBus.off(_coreEventsEvents2['default'].QUOTA_EXCEEDED, onQuotaExceeded, this); 31806 eventBus.off(_coreEventsEvents2['default'].BYTES_APPENDED, onBytesAppended, this); 31807 eventBus.off(_coreEventsEvents2['default'].BUFFER_CLEARED, onBufferCleared, this); 31808 eventBus.off(_coreEventsEvents2['default'].INIT_REQUESTED, onInitRequested, this); 31809 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_RATE_CHANGED, onPlaybackRateChanged, this); 31810 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, this); 31811 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_STARTED, onPlaybackStarted, this); 31812 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_TIME_UPDATED, onPlaybackTimeUpdated, this); 31813 eventBus.off(_coreEventsEvents2['default'].URL_RESOLUTION_FAILED, onURLResolutionFailed, this); 31814 eventBus.off(_coreEventsEvents2['default'].FRAGMENT_LOADING_ABANDONED, onFragmentLoadingAbandoned, this); 31815 if (dashManifestModel.getIsTextTrack(type)) { 31816 eventBus.off(_coreEventsEvents2['default'].TIMED_TEXT_REQUESTED, onTimedTextRequested, this); 31817 } 31818 31819 stop(); 31820 completeQualityChange(false); 31821 resetInitialSettings(); 31822 } 31823 31824 instance = { 31825 initialize: initialize, 31826 getType: getType, 31827 getSeekTarget: getSeekTarget, 31828 setSeekTarget: setSeekTarget, 31829 setTimeToLoadDelay: setTimeToLoadDelay, 31830 getTimeToLoadDelay: getTimeToLoadDelay, 31831 replaceRequest: replaceRequest, 31832 switchTrackAsked: switchTrackAsked, 31833 isStarted: isStarted, 31834 start: start, 31835 stop: stop, 31836 reset: reset, 31837 setPlayList: setPlayList, 31838 getBufferTarget: getBufferTarget, 31839 finalisePlayList: finalisePlayList 31840 }; 31841 31842 setup(); 31843 31844 return instance; 31845} 31846 31847ScheduleController.__dashjs_factory_name = 'ScheduleController'; 31848exports['default'] = _coreFactoryMaker2['default'].getClassFactory(ScheduleController); 31849module.exports = exports['default']; 31850 31851},{"100":100,"102":102,"105":105,"140":140,"181":181,"182":182,"226":226,"49":49,"50":50,"51":51,"54":54}],112:[function(_dereq_,module,exports){ 31852/** 31853 * The copyright in this software is being made available under the BSD License, 31854 * included below. This software may be subject to other third party and contributor 31855 * rights, including patent rights, and no such rights are granted under this license. 31856 * 31857 * Copyright (c) 2013, Dash Industry Forum. 31858 * All rights reserved. 31859 * 31860 * Redistribution and use in source and binary forms, with or without modification, 31861 * are permitted provided that the following conditions are met: 31862 * * Redistributions of source code must retain the above copyright notice, this 31863 * list of conditions and the following disclaimer. 31864 * * Redistributions in binary form must reproduce the above copyright notice, 31865 * this list of conditions and the following disclaimer in the documentation and/or 31866 * other materials provided with the distribution. 31867 * * Neither the name of Dash Industry Forum nor the names of its 31868 * contributors may be used to endorse or promote products derived from this software 31869 * without specific prior written permission. 31870 * 31871 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 31872 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 31873 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 31874 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 31875 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
31875INCLUDING, BUT 31876 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31877 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31878 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31879 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31880 * POSSIBILITY OF SUCH DAMAGE. 31881 */ 31882'use strict'; 31883 31884Object.defineProperty(exports, '__esModule', { 31885 value: true 31886}); 31887 31888function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 31889 31890var _voDashJSError = _dereq_(207); 31891 31892var _voDashJSError2 = _interopRequireDefault(_voDashJSError); 31893 31894var _coreEventBus = _dereq_(50); 31895 31896var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 31897 31898var _coreEventsEvents = _dereq_(54); 31899 31900var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 31901 31902var _coreFactoryMaker = _dereq_(51); 31903 31904var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 31905 31906var QUOTA_EXCEEDED_ERROR_CODE = 22; 31907 31908function SourceBufferController(config) { 31909 31910 var context = this.context; 31911 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 31912 var textController = config.textController; 31913 31914 var instance = undefined; 31915 31916 function createSourceBuffer(mediaSource, mediaInfo) { 31917 31918 var codec = mediaInfo.codec; 31919 var buffer = null; 31920 31921 try { 31922 // Safari claims to support anything starting 'application/mp4'. 31923 // it definitely doesn't understand 'application/mp4;codecs="stpp"' 31924 // - currently no browser does, so check for it and use our own 31925 // implementation. The same is true for codecs="wvtt". 31926 if (codec.match(/application\/mp4;\s*codecs="(stpp|wvtt).*"/i)) { 31927 throw new Error('not really supported'); 31928 } 31929 31930 buffer = mediaSource.addSourceBuffer(codec); 31931 } catch (ex) { 31932 // Note that in the following, the quotes are open to allow for extra text after stpp and wvtt 31933 if (mediaInfo.isText || codec.indexOf('codecs="stpp') !== -1 || codec.indexOf('codecs="wvtt') !== -1) { 31934 buffer = textController.getTextSourceBuffer(); 31935 } else { 31936 throw ex; 31937 } 31938 } 31939 31940 return buffer; 31941 } 31942 31943 function removeSourceBuffer(mediaSource, buffer) { 31944 try { 31945 mediaSource.removeSourceBuffer(buffer); 31946 } catch (ex) {} 31947 } 31948 31949 function getBufferRange(buffer, time, tolerance) { 31950 var ranges = null; 31951 var start = 0; 31952 var end = 0; 31953 var firstStart = null; 31954 var lastEnd = null; 31955 var gap = 0; 31956 31957 var len = undefined, 31958 i = undefined; 31959 31960 var toler = tolerance || 0.15; 31961 31962 try { 31963 ranges = buffer.buffered; 31964 } catch (ex) { 31965 return null; 31966 } 31967 31968 if (ranges !== null && ranges !== undefined) { 31969 for (i = 0, len = ranges.length; i < len; i++) { 31970 start = ranges.start(i); 31971 end = ranges.end(i); 31972 if (firstStart === null) { 31973 gap = Math.abs(start - time); 31974 if (time >= start && time < end) { 31975 // start the range 31976 firstStart = start; 31977 lastEnd = end; 31978 } else if (gap <= toler) { 31979 // start the range even though the buffer does not contain time 0 31980 firstStart = start; 31981 lastEnd = end; 31982 } 31983 } else { 31984 gap = start - lastEnd; 31985 if (gap <= toler) { 31986 // the discontinuity is smaller than the tolerance, combine the ranges 31987 lastEnd = end; 31988 } else { 31989 break; 31990 } 31991 } 31992 } 31993 31994 if (firstStart !== null) { 31995 return { 31996 start: firstStart, 31997 end: lastEnd 31998 }; 31999 } 32000 } 32001 32002 return null; 32003 } 32004 32005 function getAllRanges(buffer) { 32006 var ranges = null; 32007 32008 try { 32009 ranges = buffer.buffered; 32010 return ranges; 32011 } catch (ex) { 32012 return null; 32013 } 32014 } 32015 32016 function getTotalBufferedTime(buffer) { 32017 var ranges = getAllRanges(buffer); 32018 var totalBufferedTime = 0; 32019 var ln = undefined, 32020 i = undefined; 32021 32022 if (!ranges) return totalBufferedTime; 32023 32024 for (i = 0, ln = ranges.length; i < ln; i++) { 32025 totalBufferedTime += ranges.end(i) - ranges.start(i); 32026 } 32027 32028 return totalBufferedTime; 32029 } 32030 32031 function getBufferLength(buffer, time, tolerance) { 32032 32033 var range = undefined, 32034 length = undefined; 32035 32036 range = getBufferRange(buffer, time, tolerance); 32037 32038 if (range === null) { 32039 length = 0; 32040 } else { 32041 length = range.end - time; 32042 } 32043 32044 return length; 32045 } 32046 32047 function getRangeDifference(currentRanges, buffer) { 32048 if (!buffer) return null; 32049
32050 //TODO we may need to look for a more elegant and robust method 32051 // The logic below checks that is the difference between currentRanges and actual SourceBuffer ranges 32052 32053 var newRanges = getAllRanges(buffer); 32054 var newStart = undefined, 32055 newEnd = undefined, 32056 equalStart = undefined, 32057 equalEnd = undefined, 32058 currentRange = undefined, 32059 nextCurrentRange = undefined, 32060 nextNewRange = undefined, 32061 hasRange = undefined, 32062 diff = undefined; 32063 32064 if (!newRanges) return null; 32065 32066 for (var i = 0, ln = newRanges.length; i < ln; i++) { 32067 hasRange = currentRanges.length > i; 32068 currentRange = hasRange ? { 32069 start: currentRanges.start(i), 32070 end: currentRanges.end(i) 32071 } : null; 32072 newStart = newRanges.start(i); 32073 newEnd = newRanges.end(i); 32074 32075 // if there is no range with the same index it means that a new range has been added. This range is 32076 // the difference we are looking for 32077 // Example 32078 // current ranges 32079 // 0|---range1---|4 8|--range2--|12 32080 // new ranges 32081 // 0|---range1---|4| 8|--range2--|12 16|--range3--|20 32082 32083 if (!currentRange) { 32084 diff = { 32085 start: newStart, 32086 end: newEnd 32087 }; 32088 return diff; 32089 } 32090 32091 equalStart = currentRange.start === newStart; 32092 equalEnd = currentRange.end === newEnd; 32093 32094 // if ranges are equal do nothing here and go the next ranges 32095 if (equalStart && equalEnd) continue; 32096 32097 // start or/and end of the range has been changed 32098 if (equalStart) { 32099 diff = { 32100 start: currentRange.end, 32101 end: newEnd 32102 }; 32103 } else if (equalEnd) { 32104 diff = { 32105 start: newStart, 32106 end: currentRange.start 32107 }; 32108 } else { 32109 // new range has been added before the current one 32110 diff = { 32111 start: newStart, 32112 end: newEnd 32113 }; 32114 return diff; 32115 } 32116 32117 // if there is next current range but no next new range (it it is not equal the next current range) it means 32118 // that the ranges have been merged 32119 // Example 1 32120 // current ranges 32121 // 0|---range1---|4 8|--range2--|12 16|---range3---| 32122 // new ranges 32123 // 0|-----------range1-----------|12 16|---range3--| 32124 nextCurrentRange = currentRanges.length > i + 1 ? { 32125 start: currentRanges.start(i + 1), 32126 end: currentRanges.end(i + 1) 32127 } : null; 32128 nextNewRange = i + 1 < ln ? { 32129 start: newRanges.start(i + 1), 32130 end: newRanges.end(i + 1) 32131 } : null; 32132 32133 if (nextCurrentRange && (!nextNewRange || nextNewRange.start !== nextCurrentRange.start || nextNewRange.end !== nextCurrentRange.end)) { 32134 diff.end = nextCurrentRange.start; 32135 } 32136 32137 return diff; 32138 } 32139 32140 return null; 32141 } 32142 32143 function append(buffer, chunk) { 32144 var bytes = chunk.bytes; 32145 var appendMethod = 'append' in buffer ? 'append' : 'appendBuffer' in buffer ? 'appendBuffer' : null; 32146 // our user-defined sourcebuffer-like object has Object as its 32147 // prototype whereas built-in SourceBuffers will have something 32148 // more sensible. do not pass chunk to built-in append. 32149 var acceptsChunk = Object.prototype.toString.call(buffer).slice(8, -1) === 'Object'; 32150 32151 if (!appendMethod) return; 32152 32153 waitForUpdateEnd(buffer, function () { 32154 try { 32155 if (acceptsChunk) { 32156 // chunk.start is used in calculations by TextSourceBuffer 32157 buffer[appendMethod](bytes, chunk); 32158 } else { 32159 buffer[appendMethod](bytes); 32160 } 32161 // updating is in progress, we should wait for it to complete before signaling that this operation is done 32162 waitForUpdateEnd(buffer, function () { 32163 eventBus.trigger(_coreEventsEvents2['default'].SOURCEBUFFER_APPEND_COMPLETED, { 32164 buffer: buffer, 32165 bytes: bytes 32166 }); 32167 }); 32168 } catch (err) { 32169 eventBus.trigger(_coreEventsEvents2['default'].SOURCEBUFFER_APPEND_COMPLETED, { 32170 buffer: buffer, 32171 bytes: bytes, 32172 error: new _voDashJSError2['default'](err.code, err.message, null) 32173 }); 32174 } 32175 }); 32176 } 32177 32178 function remove(buffer, start, end, mediaSource) { 32179 32180 // make sure that the given time range is correct. Otherwise we will get InvalidAccessError 32181 waitForUpdateEnd(buffer, function () { 32182 try { 32183 if (start >= 0 && end > start && mediaSource.readyState !== 'ended') { 32184 buffer.remove(start, end); 32185 } 32186 // updating is in progress, we should wait for it to complete before signaling that this operation is done 32187 waitForUpdateEnd(buffer, function () { 32188 eventBus.trigger(_coreEventsEvents2['default'].SOURCEBUFFER_REMOVE_COMPLETED, { 32189 buffer: buffer, 32190 from: start, 32191 to: end 32192 }); 32193 }); 32194 } catch (err) { 32195 eventBus.trigger(_coreEventsEvents2['default'].SOURCEBUFFER_REMOVE_COMPLETED, { 32196 buffer: buffer, 32197 from: start, 32198 to: end, 32199 error: new _voDashJSError2['default'](err.code, err.message, null) 32200 }); 32201 } 32202 }); 32203 } 32204 32205 function abort(mediaSource, buffer) { 32206 try { 32207 if (mediaSource.readyState === 'open') { 32208 buffer.abort(); 32209 } else if (buffer.resetEmbedded && mediaSource.readyState === 'ended') { 32210 buffer.abort(); //The cues need to be removed from the TextSourceBuffer via a call to abort() 32211 } 32212 } catch (ex) {} 32213 } 32214 32215 function waitForUpdateEnd(buffer, callback) { 32216 var intervalId = undefined; 32217 var CHECK_INTERVAL = 50; 32218 32219 var checkIsUpdateEnded = function checkIsUpdateEnded() { 32220 // if updating is still in progress do nothing and wait for the next check again. 32221 if (buffer.updating) return; 32222 // updating is completed, now we can stop checking and resolve the promise 32223 clearInterval(intervalId); 32224 callback(); 32225 }; 32226 32227 var updateEndHandler = function updateEndHandler() { 32228 if (buffer.updating) return; 32229 32230 buffer.removeEventListener('updateend', updateEndHandler, false); 32231 callback(); 32232 }; 32233 32234 if (!buffer.updating) { 32235 callback(); 32236 return; 32237 } 32238 32239 // use updateend event if possible 32240 if (typeof buffer.addEventListener === 'function') { 32241 try { 32242 buffer.addEventListener('updateend', updateEndHandler, false); 32243 } catch (err) { 32244 // use setInterval to periodically check if updating has been completed 32245 intervalId = setInterval(checkIsUpdateEnded, CHECK_INTERVAL); 32246 } 32247 } else { 32248 // use setInterval to periodically check if updating has been completed 32249 intervalId = setInterval(checkIsUpdateEnded, CHECK_INTERVAL); 32250 } 32251 } 32252 32253 instance = { 32254 append: append, 32255 remove: remove, 32256 abort: abort, 32257 createSourceBuffer: createSourceBuffer, 32258 removeSourceBuffer: removeSourceBuffer, 32259 getBufferRange: getBufferRange, 32260 getAllRanges: getAllRanges, 32261 getTotalBufferedTime: getTotalBufferedTime, 32262 getBufferLength: getBufferLength, 32263 getRangeDifference: getRangeDifference 32264 }; 32265 32266 return instance; 32267} 32268 32269SourceBufferController.__dashjs_factory_name = 'SourceBufferController'; 32270var factory = _coreFactoryMaker2['default'].getSingletonFactory(SourceBufferController); 32271factory.QUOTA_EXCEEDED_ERROR_CODE = QUOTA_EXCEEDED_ERROR_CODE; 32272_coreFactoryMaker2['default'].updateSingletonFactory(SourceBufferController.__dashjs_factory_name, factory); 32273exports['default'] = factory; 32274module.exports = exports['default']; 32275 32276},{"207":207,"50":50,"51":51,"54":54}],113:[function(_dereq_,module,exports){ 32277/** 32278 * The copyright in this software is being made available under the BSD License, 32279 * included below. This software may be subject to other third party and contributor 32280 * rights, including patent rights, and no such rights are granted under this license. 32281 * 32282 * Copyright (c) 2013, Dash Industry Forum. 32283 * All rights reserved. 32284 * 32285 * Redistribution and use in source and binary forms, with or without modification, 32286 * are permitted provided that the following conditions are met: 32287 * * Redistributions of source code must retain the above copyright notice, this 32288 * list of conditions and the following disclaimer. 32289 * * Redistributions in binary form must reproduce the above copyright notice, 32290 * this list of conditions and the following disclaimer in the documentation and/or 32291 * other materials provided with the distribution. 32292 * * Neither the name of Dash Industry Forum nor the names of its 32293 * contributors may be used to endorse or promote products derived from this software 32294 * without specific prior written permission. 32295 * 32296 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 32297 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 32298 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 32299 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 32300 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
32300INCLUDING, BUT 32301 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32302 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32303 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32304 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32305 * POSSIBILITY OF SUCH DAMAGE. 32306 */ 32307'use strict'; 32308 32309Object.defineProperty(exports, '__esModule', { 32310 value: true 32311}); 32312 32313function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 32314 32315var _constantsConstants = _dereq_(100); 32316 32317var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 32318 32319var _constantsMetricsConstants = _dereq_(101); 32320 32321var _constantsMetricsConstants2 = _interopRequireDefault(_constantsMetricsConstants); 32322 32323var _Stream = _dereq_(96); 32324 32325var _Stream2 = _interopRequireDefault(_Stream); 32326 32327var _ManifestUpdater = _dereq_(92); 32328 32329var _ManifestUpdater2 = _interopRequireDefault(_ManifestUpdater); 32330 32331var _coreEventBus = _dereq_(50); 32332 32333var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 32334 32335var _coreEventsEvents = _dereq_(54); 32336 32337var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 32338 32339var _modelsURIQueryAndFragmentModel = _dereq_(144); 32340 32341var _modelsURIQueryAndFragmentModel2 = _interopRequireDefault(_modelsURIQueryAndFragmentModel); 32342 32343var _modelsMediaPlayerModel = _dereq_(142); 32344 32345var _modelsMediaPlayerModel2 = _interopRequireDefault(_modelsMediaPlayerModel); 32346 32347var _coreFactoryMaker = _dereq_(51); 32348 32349var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 32350 32351var _voMetricsPlayList = _dereq_(226); 32352 32353var _coreDebug = _dereq_(49); 32354 32355var _coreDebug2 = _interopRequireDefault(_coreDebug); 32356 32357var _utilsInitCache = _dereq_(196); 32358 32359var _utilsInitCache2 = _interopRequireDefault(_utilsInitCache); 32360 32361var _MediaPlayerEvents = _dereq_(94); 32362 32363var _MediaPlayerEvents2 = _interopRequireDefault(_MediaPlayerEvents); 32364 32365var _TimeSyncController = _dereq_(114); 32366 32367var _TimeSyncController2 = _interopRequireDefault(_TimeSyncController); 32368 32369var _BaseURLController = _dereq_(103); 32370 32371var _BaseURLController2 = _interopRequireDefault(_BaseURLController); 32372 32373var _MediaSourceController = _dereq_(109); 32374 32375var _MediaSourceController2 = _interopRequireDefault(_MediaSourceController); 32376 32377function StreamController() { 32378 32379 var STREAM_END_THRESHOLD = 0.5; 32380 var STREAM_END_TIMEOUT_DELAY = 0.1; 32381 32382 var context = this.context; 32383 var log = (0, _coreDebug2['default'])(context).getInstance().log; 32384 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 32385 32386 var instance = undefined, 32387 capabilities = undefined, 32388 manifestUpdater = undefined, 32389 manifestLoader = undefined, 32390 manifestModel = undefined, 32391 dashManifestModel = undefined, 32392 adapter = undefined, 32393 metricsModel = undefined, 32394 dashMetrics = undefined, 32395 mediaSourceController = undefined, 32396 timeSyncController = undefined, 32397 baseURLController = undefined, 32398 domStorage = undefined, 32399 abrController = undefined, 32400 mediaController = undefined, 32401 textController = undefined, 32402 sourceBufferController = undefined, 32403 initCache = undefined, 32404 errHandler = undefined, 32405 timelineConverter = undefined, 32406 streams = undefined, 32407 activeStream = undefined, 32408 protectionController = undefined, 32409 protectionData = undefined, 32410 autoPlay = undefined, 32411 isStreamSwitchingInProgress = undefined, 32412 hasMediaError = undefined, 32413 hasInitialisationError = undefined, 32414 mediaSource = undefined, 32415 videoModel = undefined, 32416 playbackController = undefined, 32417 mediaPlayerModel = undefined, 32418 isPaused = undefined, 32419 initialPlayback = undefined, 32420 playListMetrics = undefined, 32421 videoTrackDetected = undefined, 32422 audioTrackDetected = undefined, 32423 endedTimeout = undefined; 32424 32425 function setup() { 32426 timeSyncController = (0, _TimeSyncController2['default'])(context).getInstance(); 32427 baseURLController = (0, _BaseURLController2['default'])(context).getInstance(); 32428 mediaSourceController = (0, _MediaSourceController2['default'])(context).getInstance(); 32429 initCache = (0, _utilsInitCache2['default'])(context).getInstance(); 32430 32431 resetInitialSettings();
32432 } 32433 32434 function initialize(autoPl, protData) { 32435 checkSetConfigCall(); 32436 32437 autoPlay = autoPl; 32438 protectionData = protData; 32439 timelineConverter.initialize(); 32440 32441 manifestUpdater = (0, _ManifestUpdater2['default'])(context).create(); 32442 manifestUpdater.setConfig({ 32443 manifestModel: manifestModel, 32444 dashManifestModel: dashManifestModel, 32445 mediaPlayerModel: mediaPlayerModel, 32446 manifestLoader: manifestLoader 32447 }); 32448 manifestUpdater.initialize(); 32449 32450 baseURLController.setConfig({ 32451 dashManifestModel: dashManifestModel 32452 }); 32453 32454 eventBus.on(_coreEventsEvents2['default'].TIME_SYNCHRONIZATION_COMPLETED, onTimeSyncCompleted, this); 32455 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, this); 32456 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_TIME_UPDATED, onPlaybackTimeUpdated, this); 32457 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_ENDED, onEnded, this); 32458 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_ERROR, onPlaybackError, this); 32459 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_STARTED, onPlaybackStarted, this); 32460 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_PAUSED, onPlaybackPaused, this); 32461 eventBus.on(_coreEventsEvents2['default'].MANIFEST_UPDATED, onManifestUpdated, this); 32462 eventBus.on(_coreEventsEvents2['default'].STREAM_BUFFERING_COMPLETED, onStreamBufferingCompleted, this); 32463 eventBus.on(_MediaPlayerEvents2['default'].METRIC_ADDED, onMetricAdded, this); 32464 } 32465 32466 /* 32467 * Called when current playback position is changed. 32468 * Used to determine the time current stream is finished and we should switch to the next stream. 32469 */ 32470 function onPlaybackTimeUpdated(e) { 32471 32472 if (isVideoTrackPresent()) { 32473 var playbackQuality = videoModel.getPlaybackQuality(); 32474 if (playbackQuality) { 32475 metricsModel.addDroppedFrames(_constantsConstants2['default'].VIDEO, playbackQuality); 32476 } 32477 } 32478 32479 // Sometimes after seeking timeUpdateHandler is called before seekingHandler and a new stream starts 32480 // from beginning instead of from a chosen position. So we do nothing if the player is in the seeking state 32481 if (playbackController.isSeeking()) return; 32482 32483 if (e.timeToEnd <= STREAM_END_THRESHOLD) { 32484 // In some cases the ended event is not triggered at the end of the stream, do it artificially here. 32485 // This should only be a fallback, put an extra STREAM_END_TIMEOUT_DELAY to give the real ended event time to trigger. 32486 32487 if (endedTimeout) { 32488 clearTimeout(endedTimeout); 32489 endedTimeout = undefined; 32490 } 32491 endedTimeout = setTimeout(function () { 32492 endedTimeout = undefined; 32493 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_ENDED); 32494 }, 1000 * (e.timeToEnd + STREAM_END_TIMEOUT_DELAY)); 32495 } 32496 } 32497 32498 function onPlaybackSeeking(e) { 32499 var seekingStream = getStreamForTime(e.seekTime); 32500 32501 if (seekingStream && seekingStream !== activeStream) { 32502 flushPlaylistMetrics(_voMetricsPlayList.PlayListTrace.END_OF_PERIOD_STOP_REASON); 32503 switchStream(activeStream, seekingStream, e.seekTime); 32504 } else { 32505 flushPlaylistMetrics(_voMetricsPlayList.PlayListTrace.USER_REQUEST_STOP_REASON); 32506 } 32507 32508 addPlaylistMetrics(_voMetricsPlayList.PlayList.SEEK_START_REASON); 32509 } 32510 32511 function onPlaybackStarted() /*e*/{ 32512 if (initialPlayback) { 32513 initialPlayback = false; 32514 addPlaylistMetrics(_voMetricsPlayList.PlayList.INITIAL_PLAYOUT_START_REASON); 32515 } else { 32516 if (isPaused) { 32517 isPaused = false; 32518 addPlaylistMetrics(_voMetricsPlayList.PlayList.RESUME_FROM_PAUSE_START_REASON); 32519 } 32520 } 32521 } 32522 32523 function onPlaybackPaused(e) { 32524 if (!e.ended) { 32525 isPaused = true; 32526 flushPlaylistMetrics(_voMetricsPlayList.PlayListTrace.USER_REQUEST_STOP_REASON); 32527 } 32528 } 32529 32530 function onStreamBufferingCompleted() { 32531 var isLast = getActiveStreamInfo().isLast; 32532 if (mediaSource && isLast) { 32533 mediaSourceController.signalEndOfStream(mediaSource); 32534 } 32535 } 32536 32537 function getStreamForTime(time) { 32538 var duration = 0; 32539 var stream = null; 32540 32541 var ln = streams.length; 32542 32543 if (ln > 0) { 32544 duration += streams[0].getStartTime(); 32545 } 32546 32547 for (var i = 0; i < ln; i++) { 32548 stream = streams[i]; 32549 duration += stream.getDuration(); 32550 32551 if (time < duration) { 32552 return stream; 32553 } 32554 } 32555 32556 return null; 32557 } 32558 32559 /** 32560 * Returns a playhead time, in seconds, converted to be relative 32561 * to the start of an identified stream/period or null if no such stream 32562 * @param {number} time 32563 * @param {string} id 32564 * @returns {number|null} 32565 */ 32566 function getTimeRelativeToStreamId(time, id) { 32567 var stream = null; 32568 var baseStart = 0; 32569 var streamStart = 0; 32570 var streamDur = null; 32571 32572 var ln = streams.length; 32573 32574 for (var i = 0; i < ln; i++) { 32575 stream = streams[i]; 32576 streamStart = stream.getStartTime(); 32577 streamDur = stream.getDuration(); 32578 32579 // use start time, if not undefined or NaN or similar 32580 if (Number.isFinite(streamStart)) { 32581 baseStart = streamStart; 32582 } 32583 32584 if (stream.getId() === id) { 32585 return time - baseStart; 32586 } else { 32587 // use duration if not undefined or NaN or similar 32588 if (Number.isFinite(streamDur)) { 32589 baseStart += streamDur; 32590 } 32591 } 32592 } 32593 32594 return null; 32595 } 32596 32597 function getActiveStreamProcessors() { 32598 return activeStream ? activeStream.getProcessors() : []; 32599 } 32600 32601 function getActiveStreamCommonEarliestTime() { 32602 var commonEarliestTime = []; 32603 if (activeStream) {
32604 activeStream.getProcessors().forEach(function (p) { 32605 commonEarliestTime.push(p.getIndexHandler().getEarliestTime()); 32606 }); 32607 } 32608 return Math.min.apply(Math, commonEarliestTime); 32609 } 32610 32611 function onEnded() { 32612 if (endedTimeout) { 32613 clearTimeout(endedTimeout); 32614 endedTimeout = undefined; 32615 } 32616 32617 var nextStream = getNextStream(); 32618 if (nextStream) { 32619 switchStream(activeStream, nextStream, NaN); 32620 } 32621 flushPlaylistMetrics(nextStream ? _voMetricsPlayList.PlayListTrace.END_OF_PERIOD_STOP_REASON : _voMetricsPlayList.PlayListTrace.END_OF_CONTENT_STOP_REASON); 32622 } 32623 32624 function getNextStream() { 32625 if (activeStream) { 32626 var _ret = (function () { 32627 var start = activeStream.getStreamInfo().start; 32628 var duration = activeStream.getStreamInfo().duration; 32629 32630 return { 32631 v: streams.filter(function (stream) { 32632 return stream.getStreamInfo().start === start + duration; 32633 })[0] 32634 }; 32635 })(); 32636 32637 if (typeof _ret === 'object') return _ret.v; 32638 } 32639 } 32640 32641 function switchStream(oldStream, newStream, seekTime) { 32642 32643 if (isStreamSwitchingInProgress || !newStream || oldStream === newStream) return; 32644 isStreamSwitchingInProgress = true; 32645 32646 eventBus.trigger(_coreEventsEvents2['default'].PERIOD_SWITCH_STARTED, { 32647 fromStreamInfo: oldStream ? oldStream.getStreamInfo() : null, 32648 toStreamInfo: newStream.getStreamInfo() 32649 }); 32650 32651 if (oldStream) oldStream.deactivate(); 32652 activeStream = newStream; 32653 playbackController.initialize(activeStream.getStreamInfo()); 32654 32655 //TODO detect if we should close and repose or jump to activateStream. 32656 openMediaSource(seekTime); 32657 } 32658 32659 function openMediaSource(seekTime) { 32660 32661 var sourceUrl = undefined; 32662 32663 function onMediaSourceOpen() { 32664 log('MediaSource is open!'); 32665 window.URL.revokeObjectURL(sourceUrl); 32666 mediaSource.removeEventListener('sourceopen', onMediaSourceOpen); 32667 mediaSource.removeEventListener('webkitsourceopen', onMediaSourceOpen); 32668 setMediaDuration(); 32669 activateStream(seekTime); 32670 } 32671 32672 if (!mediaSource) { 32673 mediaSource = mediaSourceController.createMediaSource(); 32674 } else { 32675 mediaSourceController.detachMediaSource(videoModel); 32676 } 32677 32678 mediaSource.addEventListener('sourceopen', onMediaSourceOpen, false); 32679 mediaSource.addEventListener('webkitsourceopen', onMediaSourceOpen, false); 32680 sourceUrl = mediaSourceController.attachMediaSource(mediaSource, videoModel); 32681 log('MediaSource attached to element. Waiting on open...'); 32682 } 32683 32684 function activateStream(seekTime) { 32685 32686 activeStream.activate(mediaSource); 32687 32688 if (!initialPlayback) { 32689 if (!isNaN(seekTime)) { 32690 playbackController.seek(seekTime); //we only need to call seek here, IndexHandlerTime was set from seeking event 32691 } else { 32692 (function () { 32693 var startTime = playbackController.getStreamStartTime(true);
32694 activeStream.getProcessors().forEach(function (p) { 32695 adapter.setIndexHandlerTime(p, startTime); 32696 }); 32697 playbackController.seek(startTime); //seek to period start time 32698 })(); 32699 } 32700 } else { 32701 videoTrackDetected = checkTrackPresence(_constantsConstants2['default'].VIDEO); 32702 } 32703 32704 activeStream.startEventController(); 32705 if (autoPlay || !initialPlayback) { 32706 playbackController.play(); 32707 } 32708 32709 isStreamSwitchingInProgress = false; 32710 eventBus.trigger(_coreEventsEvents2['default'].PERIOD_SWITCH_COMPLETED, { 32711 toStreamInfo: activeStream.getStreamInfo() 32712 }); 32713 } 32714 32715 function setMediaDuration() { 32716 var manifestDuration = activeStream.getStreamInfo().manifestInfo.duration; 32717 var mediaDuration = mediaSourceController.setDuration(mediaSource, manifestDuration); 32718 log('Duration successfully set to: ' + mediaDuration); 32719 } 32720 32721 function getComposedStream(streamInfo) { 32722 for (var i = 0, ln = streams.length; i < ln; i++) { 32723 if (streams[i].getId() === streamInfo.id) { 32724 return streams[i]; 32725 } 32726 } 32727 return null; 32728 } 32729 32730 function composeStreams() { 32731 32732 try { 32733 var streamsInfo = adapter.getStreamsInfo(); 32734 if (streamsInfo.length === 0) { 32735 throw new Error('There are no streams'); 32736 } 32737 32738 var manifestUpdateInfo = dashMetrics.getCurrentManifestUpdate(metricsModel.getMetricsFor(_constantsConstants2['default'].STREAM)); 32739 metricsModel.updateManifestUpdateInfo(manifestUpdateInfo, { 32740 currentTime: playbackController.getTime(), 32741 buffered: videoModel.getBufferRange(), 32742 presentationStartTime: streamsInfo[0].start, 32743 clientTimeOffset: timelineConverter.getClientTimeOffset() 32744 }); 32745 32746 for (var i = 0, ln = streamsInfo.length; i < ln; i++) { 32747 32748 // If the Stream object does not exist we probably loaded the manifest the first time or it was 32749 // introduced in the updated manifest, so we need to create a new Stream and perform all the initialization operations 32750 var streamInfo = streamsInfo[i]; 32751 var stream = getComposedStream(streamInfo); 32752 32753 if (!stream) { 32754 32755 stream = (0, _Stream2['default'])(context).create({ 32756 manifestModel: manifestModel, 32757 dashManifestModel: dashManifestModel, 32758 mediaPlayerModel: mediaPlayerModel, 32759 metricsModel: metricsModel, 32760 dashMetrics: dashMetrics, 32761 manifestUpdater: manifestUpdater, 32762 adapter: adapter, 32763 timelineConverter: timelineConverter, 32764 capabilities: capabilities, 32765 errHandler: errHandler, 32766 baseURLController: baseURLController, 32767 domStorage: domStorage, 32768 abrController: abrController, 32769 playbackController: playbackController, 32770 mediaController: mediaController, 32771 textController: textController, 32772 sourceBufferController: sourceBufferController, 32773 videoModel: videoModel, 32774 streamController: instance 32775 }); 32776 streams.push(stream); 32777 stream.initialize(streamInfo, protectionController); 32778 } else { 32779 stream.updateData(streamInfo); 32780 } 32781 32782 metricsModel.addManifestUpdateStreamInfo(manifestUpdateInfo, streamInfo.id, streamInfo.index, streamInfo.start, streamInfo.duration); 32783 } 32784 32785 if (!activeStream) { 32786 //const initStream = streamsInfo[0].manifestInfo.isDynamic ? streams[streams.length -1] : streams[0]; 32787 //TODO we need to figure out what the correct starting period is here and not just go to first or last in array. 32788 switchStream(null, streams[0], NaN); 32789 } 32790 32791 eventBus.trigger(_coreEventsEvents2['default'].STREAMS_COMPOSED); 32792 } catch (e) { 32793 errHandler.manifestError(e.message, 'nostreamscomposed', manifestModel.getValue()); 32794 hasInitialisationError = true; 32795 reset(); 32796 } 32797 } 32798 32799 function onTimeSyncCompleted() /*e*/{ 32800 var manifest = manifestModel.getValue(); 32801 //TODO check if we can move this to initialize?? 32802 if (protectionController) { 32803 eventBus.trigger(_coreEventsEvents2['default'].PROTECTION_CREATED, { 32804 controller: protectionController, 32805 manifest: manifest 32806 }); 32807 protectionController.setMediaElement(videoModel.getElement()); 32808 if (protectionData) { 32809 protectionController.setProtectionData(protectionData); 32810 } 32811 } 32812 32813 composeStreams(); 32814 } 32815 32816 function onManifestUpdated(e) { 32817 if (!e.error) { 32818 (function () { 32819 //Since streams are not composed yet , need to manually look up useCalculatedLiveEdgeTime to detect if stream 32820 //is SegmentTimeline to avoid using time source 32821 var manifest = e.manifest; 32822 adapter.updatePeriods(manifest); 32823 var streamInfo = adapter.getStreamsInfo(manifest)[0]; 32824 var mediaInfo = adapter.getMediaInfoForType(streamInfo, _constantsConstants2['default'].VIDEO) || adapter.getMediaInfoForType(streamInfo, _constantsConstants2['default'].AUDIO); 32825 32826 var voAdaptation = undefined, 32827 useCalculatedLiveEdgeTime = undefined; 32828 32829 if (mediaInfo) { 32830 voAdaptation = adapter.getDataForMedia(mediaInfo); 32831 useCalculatedLiveEdgeTime = dashManifestModel.getRepresentationsForAdaptation(voAdaptation)[0].useCalculatedLiveEdgeTime; 32832 32833 if (useCalculatedLiveEdgeTime) { 32834 log('SegmentTimeline detected using calculated Live Edge Time'); 32835 mediaPlayerModel.setUseManifestDateHeaderTimeSource(false); 32836 } 32837 } 32838 32839 var manifestUTCTimingSources = dashManifestModel.getUTCTimingSources(e.manifest); 32840 var allUTCTimingSources = !dashManifestModel.getIsDynamic(manifest) || useCalculatedLiveEdgeTime ? manifestUTCTimingSources : manifestUTCTimingSources.concat(mediaPlayerModel.getUTCTimingSources()); 32841 var isHTTPS = (0, _modelsURIQueryAndFragmentModel2['default'])(context).getInstance().isManifestHTTPS(); 32842 32843 //If https is detected on manifest then lets apply that protocol to only the default time source(s). In the future we may find the need to apply this to more then just default so left code at this level instead of in MediaPlayer.
32844 allUTCTimingSources.forEach(function (item) { 32845 if (item.value.replace(/.*?:\/\//g, '') === _modelsMediaPlayerModel2['default'].DEFAULT_UTC_TIMING_SOURCE.value.replace(/.*?:\/\//g, '')) { 32846 item.value = item.value.replace(isHTTPS ? new RegExp(/^(http:)?\/\//i) : new RegExp(/^(https:)?\/\//i), isHTTPS ? 'https://' : 'http://'); 32847 log('Matching default timing source protocol to manifest protocol: ', item.value); 32848 } 32849 }); 32850 32851 baseURLController.initialize(manifest); 32852 32853 timeSyncController.setConfig({ 32854 metricsModel: metricsModel, 32855 dashMetrics: dashMetrics 32856 }); 32857 timeSyncController.initialize(allUTCTimingSources, mediaPlayerModel.getUseManifestDateHeaderTimeSource()); 32858 })(); 32859 } else { 32860 hasInitialisationError = true; 32861 reset(); 32862 } 32863 } 32864 32865 function isAudioTrackPresent() { 32866 if (audioTrackDetected === undefined) { 32867 audioTrackDetected = checkTrackPresence(_constantsConstants2['default'].AUDIO); 32868 } 32869 return audioTrackDetected; 32870 } 32871 32872 function isVideoTrackPresent() { 32873 if (videoTrackDetected === undefined) { 32874 videoTrackDetected = checkTrackPresence(_constantsConstants2['default'].VIDEO); 32875 } 32876 return videoTrackDetected; 32877 } 32878 32879 function checkTrackPresence(type) { 32880 var isDetected = false; 32881 if (activeStream) {
32882 activeStream.getProcessors().forEach(function (p) { 32883 if (p.getMediaInfo().type === type) { 32884 isDetected = true; 32885 } 32886 }); 32887 } 32888 return isDetected; 32889 } 32890 32891 function flushPlaylistMetrics(reason, time) { 32892 time = time || new Date(); 32893 32894 if (playListMetrics) { 32895 if (activeStream) { 32896 activeStream.getProcessors().forEach(function (p) { 32897 var ctrlr = p.getScheduleController(); 32898 if (ctrlr) { 32899 ctrlr.finalisePlayList(time, reason); 32900 } 32901 }); 32902 } 32903 metricsModel.addPlayList(playListMetrics); 32904 playListMetrics = null; 32905 } 32906 } 32907 32908 function addPlaylistMetrics(startReason) { 32909 playListMetrics = new _voMetricsPlayList.PlayList(); 32910 playListMetrics.start = new Date(); 32911 playListMetrics.mstart = playbackController.getTime() * 1000; 32912 playListMetrics.starttype = startReason; 32913 32914 if (activeStream) {
32915 activeStream.getProcessors().forEach(function (p) { 32916 var ctrlr = p.getScheduleController(); 32917 if (ctrlr) { 32918 ctrlr.setPlayList(playListMetrics); 32919 } 32920 }); 32921 } 32922 } 32923 32924 function onPlaybackError(e) { 32925 32926 if (!e.error) return; 32927 32928 var msg = ''; 32929 32930 switch (e.error.code) { 32931 case 1: 32932 msg = 'MEDIA_ERR_ABORTED'; 32933 break; 32934 case 2: 32935 msg = 'MEDIA_ERR_NETWORK'; 32936 break; 32937 case 3: 32938 msg = 'MEDIA_ERR_DECODE'; 32939 break; 32940 case 4: 32941 msg = 'MEDIA_ERR_SRC_NOT_SUPPORTED'; 32942 break; 32943 case 5: 32944 msg = 'MEDIA_ERR_ENCRYPTED'; 32945 break; 32946 default: 32947 msg = 'UNKNOWN'; 32948 break; 32949 } 32950 32951 hasMediaError = true; 32952 32953 if (e.error.message) { 32954 msg += ' (' + e.error.message + ')'; 32955 } 32956 32957 if (e.error.msExtendedCode) { 32958 msg += ' (0x' + (e.error.msExtendedCode >>> 0).toString(16).toUpperCase() + ')'; 32959 } 32960 32961 log('Video Element Error: ' + msg); 32962 if (e.error) { 32963 log(e.error); 32964 } 32965 errHandler.mediaSourceError(msg); 32966 reset(); 32967 } 32968 32969 function getActiveStreamInfo() { 32970 return activeStream ? activeStream.getStreamInfo() : null; 32971 } 32972 32973 function getStreamById(id) { 32974 return streams.filter(function (item) { 32975 return item.getId() === id; 32976 })[0]; 32977 } 32978 32979 function checkSetConfigCall() { 32980 if (!manifestLoader || !manifestLoader.hasOwnProperty('load') || !timelineConverter || !timelineConverter.hasOwnProperty('initialize') || !timelineConverter.hasOwnProperty('reset') || !timelineConverter.hasOwnProperty('getClientTimeOffset')) { 32981 throw new Error('setConfig function has to be called previously'); 32982 } 32983 } 32984 32985 function checkInitializeCall() { 32986 if (!manifestUpdater || !manifestUpdater.hasOwnProperty('setManifest')) { 32987 throw new Error('initialize function has to be called previously'); 32988 } 32989 } 32990 32991 function load(url) { 32992 checkSetConfigCall(); 32993 manifestLoader.load(url); 32994 } 32995 32996 function loadWithManifest(manifest) { 32997 checkInitializeCall(); 32998 manifestUpdater.setManifest(manifest); 32999 } 33000 33001 function setConfig(config) { 33002 if (!config) return; 33003 33004 if (config.capabilities) { 33005 capabilities = config.capabilities; 33006 } 33007 if (config.manifestLoader) { 33008 manifestLoader = config.manifestLoader; 33009 } 33010 if (config.manifestModel) { 33011 manifestModel = config.manifestModel; 33012 } 33013 if (config.dashManifestModel) { 33014 dashManifestModel = config.dashManifestModel; 33015 } 33016 if (config.mediaPlayerModel) { 33017 mediaPlayerModel = config.mediaPlayerModel; 33018 } 33019 if (config.protectionController) { 33020 protectionController = config.protectionController; 33021 } 33022 if (config.adapter) { 33023 adapter = config.adapter; 33024 } 33025 if (config.metricsModel) { 33026 metricsModel = config.metricsModel; 33027 } 33028 if (config.dashMetrics) { 33029 dashMetrics = config.dashMetrics; 33030 } 33031 if (config.errHandler) { 33032 errHandler = config.errHandler; 33033 } 33034 if (config.timelineConverter) { 33035 timelineConverter = config.timelineConverter; 33036 } 33037 if (config.videoModel) { 33038 videoModel = config.videoModel; 33039 } 33040 if (config.playbackController) { 33041 playbackController = config.playbackController; 33042 } 33043 if (config.domStorage) { 33044 domStorage = config.domStorage; 33045 } 33046 if (config.abrController) { 33047 abrController = config.abrController; 33048 } 33049 if (config.mediaController) { 33050 mediaController = config.mediaController; 33051 } 33052 if (config.textController) { 33053 textController = config.textController; 33054 } 33055 if (config.sourceBufferController) { 33056 sourceBufferController = config.sourceBufferController; 33057 } 33058 } 33059 33060 function resetInitialSettings() { 33061 streams = []; 33062 protectionController = null; 33063 isStreamSwitchingInProgress = false; 33064 activeStream = null; 33065 hasMediaError = false; 33066 hasInitialisationError = false; 33067 videoTrackDetected = undefined; 33068 initialPlayback = true; 33069 isPaused = false; 33070 autoPlay = true; 33071 playListMetrics = null; 33072 } 33073 33074 function reset() { 33075 checkSetConfigCall(); 33076 33077 timeSyncController.reset(); 33078 33079 flushPlaylistMetrics(hasMediaError || hasInitialisationError ? _voMetricsPlayList.PlayListTrace.FAILURE_STOP_REASON : _voMetricsPlayList.PlayListTrace.USER_REQUEST_STOP_REASON); 33080 33081 for (var i = 0, ln = streams ? streams.length : 0; i < ln; i++) { 33082 var stream = streams[i]; 33083 stream.reset(hasMediaError); 33084 } 33085 33086 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_TIME_UPDATED, onPlaybackTimeUpdated, this); 33087 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, this); 33088 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_ERROR, onPlaybackError, this); 33089 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_STARTED, onPlaybackStarted, this); 33090 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_PAUSED, onPlaybackPaused, this); 33091 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_ENDED, onEnded, this); 33092 eventBus.off(_coreEventsEvents2['default'].MANIFEST_UPDATED, onManifestUpdated, this); 33093 eventBus.off(_coreEventsEvents2['default'].STREAM_BUFFERING_COMPLETED, onStreamBufferingCompleted, this); 33094 eventBus.off(_MediaPlayerEvents2['default'].METRIC_ADDED, onMetricAdded, this); 33095 33096 baseURLController.reset(); 33097 manifestUpdater.reset(); 33098 metricsModel.clearAllCurrentMetrics(); 33099 manifestModel.setValue(null); 33100 manifestLoader.reset(); 33101 timelineConverter.reset(); 33102 initCache.reset(); 33103 33104 if (mediaSource) { 33105 mediaSourceController.detachMediaSource(videoModel); 33106 mediaSource = null; 33107 } 33108 videoModel = null; 33109 if (protectionController) { 33110 protectionController.setMediaElement(null); 33111 protectionController = null; 33112 protectionData = null; 33113 if (manifestModel.getValue()) { 33114 eventBus.trigger(_coreEventsEvents2['default'].PROTECTION_DESTROYED, { 33115 data: manifestModel.getValue().url 33116 }); 33117 } 33118 } 33119 33120 if (endedTimeout) { 33121 clearTimeout(endedTimeout); 33122 endedTimeout = undefined; 33123 } 33124 33125 eventBus.trigger(_coreEventsEvents2['default'].STREAM_TEARDOWN_COMPLETE); 33126 resetInitialSettings();
33127 } 33128 33129 function onMetricAdded(e) { 33130 if (e.metric === _constantsMetricsConstants2['default'].DVR_INFO) { 33131 //Match media type? How can DVR window be different for media types? 33132 //Should we normalize and union the two? 33133 if (e.mediaType === _constantsConstants2['default'].AUDIO) { 33134 mediaSourceController.setSeekable(mediaSource, e.value.range.start, e.value.range.end); 33135 } 33136 } 33137 } 33138 33139 instance = { 33140 initialize: initialize, 33141 getActiveStreamInfo: getActiveStreamInfo, 33142 isVideoTrackPresent: isVideoTrackPresent, 33143 isAudioTrackPresent: isAudioTrackPresent, 33144 getStreamById: getStreamById, 33145 getTimeRelativeToStreamId: getTimeRelativeToStreamId, 33146 load: load, 33147 loadWithManifest: loadWithManifest, 33148 getActiveStreamProcessors: getActiveStreamProcessors, 33149 getActiveStreamCommonEarliestTime: getActiveStreamCommonEarliestTime, 33150 setConfig: setConfig, 33151 reset: reset 33152 }; 33153 33154 setup(); 33155 33156 return instance; 33157} 33158 33159StreamController.__dashjs_factory_name = 'StreamController'; 33160 33161exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(StreamController); 33162module.exports = exports['default']; 33163 33164},{"100":100,"101":101,"103":103,"109":109,"114":114,"142":142,"144":144,"196":196,"226":226,"49":49,"50":50,"51":51,"54":54,"92":92,"94":94,"96":96}],114:[function(_dereq_,module,exports){ 33165/** 33166 * The copyright in this software is being made available under the BSD License, 33167 * included below. This software may be subject to other third party and contributor 33168 * rights, including patent rights, and no such rights are granted under this license. 33169 * 33170 * Copyright (c) 2013, Dash Industry Forum. 33171 * All rights reserved. 33172 * 33173 * Redistribution and use in source and binary forms, with or without modification, 33174 * are permitted provided that the following conditions are met: 33175 * * Redistributions of source code must retain the above copyright notice, this 33176 * list of conditions and the following disclaimer. 33177 * * Redistributions in binary form must reproduce the above copyright notice, 33178 * this list of conditions and the following disclaimer in the documentation and/or 33179 * other materials provided with the distribution. 33180 * * Neither the name of Dash Industry Forum nor the names of its 33181 * contributors may be used to endorse or promote products derived from this software 33182 * without specific prior written permission. 33183 * 33184 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 33185 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 33186 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 33187 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33188 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 33189 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33190 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 33191 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33192 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33193 * POSSIBILITY OF SUCH DAMAGE. 33194 */ 33195'use strict'; 33196 33197Object.defineProperty(exports, '__esModule', { 33198 value: true 33199}); 33200 33201function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 33202 33203var _constantsConstants = _dereq_(100); 33204 33205var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 33206 33207var _voDashJSError = _dereq_(207); 33208 33209var _voDashJSError2 = _interopRequireDefault(_voDashJSError); 33210 33211var _voMetricsHTTPRequest = _dereq_(224); 33212 33213var _coreEventBus = _dereq_(50); 33214 33215var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 33216 33217var _coreEventsEvents = _dereq_(54); 33218 33219var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 33220 33221var _coreFactoryMaker = _dereq_(51); 33222 33223var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 33224 33225var _coreDebug = _dereq_(49); 33226 33227var _coreDebug2 = _interopRequireDefault(_coreDebug); 33228 33229var TIME_SYNC_FAILED_ERROR_CODE = 1; 33230var HTTP_TIMEOUT_MS = 5000; 33231 33232function TimeSyncController() { 33233 33234 var context = this.context; 33235 var log = (0, _coreDebug2['default'])(context).getInstance().log; 33236 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 33237 33238 var instance = undefined, 33239 offsetToDeviceTimeMs = undefined, 33240 isSynchronizing = undefined,
33241 isInitialised = undefined, 33242 useManifestDateHeaderTimeSource = undefined, 33243 handlers = undefined, 33244 metricsModel = undefined, 33245 dashMetrics = undefined; 33246 33247 function initialize(timingSources, useManifestDateHeader) { 33248 useManifestDateHeaderTimeSource = useManifestDateHeader; 33249 offsetToDeviceTimeMs = 0; 33250 isSynchronizing = false; 33251 isInitialised = false; 33252 33253 // a list of known schemeIdUris and a method to call with @value 33254 handlers = { 33255 'urn:mpeg:dash:utc:http-head:2014': httpHeadHandler, 33256 'urn:mpeg:dash:utc:http-xsdate:2014': httpHandler.bind(null, xsdatetimeDecoder), 33257 'urn:mpeg:dash:utc:http-iso:2014': httpHandler.bind(null, iso8601Decoder), 33258 'urn:mpeg:dash:utc:direct:2014': directHandler, 33259 33260 // some specs referencing early ISO23009-1 drafts incorrectly use 33261 // 2012 in the URI, rather than 2014. support these for now. 33262 'urn:mpeg:dash:utc:http-head:2012': httpHeadHandler, 33263 'urn:mpeg:dash:utc:http-xsdate:2012': httpHandler.bind(null, xsdatetimeDecoder), 33264 'urn:mpeg:dash:utc:http-iso:2012': httpHandler.bind(null, iso8601Decoder), 33265 'urn:mpeg:dash:utc:direct:2012': directHandler, 33266 33267 // it isn't clear how the data returned would be formatted, and 33268 // no public examples available so http-ntp not supported for now. 33269 // presumably you would do an arraybuffer type xhr and decode the 33270 // binary data returned but I would want to see a sample first. 33271 'urn:mpeg:dash:utc:http-ntp:2014': notSupportedHandler, 33272 33273 // not clear how this would be supported in javascript (in browser) 33274 'urn:mpeg:dash:utc:ntp:2014': notSupportedHandler, 33275 'urn:mpeg:dash:utc:sntp:2014': notSupportedHandler 33276 }; 33277 33278 if (!getIsSynchronizing()) { 33279 attemptSync(timingSources); 33280 setIsInitialised(true); 33281 } 33282 } 33283 33284 function setConfig(config) { 33285 if (!config) return; 33286 33287 if (config.metricsModel) { 33288 metricsModel = config.metricsModel; 33289 } 33290 33291 if (config.dashMetrics) { 33292 dashMetrics = config.dashMetrics; 33293 } 33294 } 33295 33296 function getOffsetToDeviceTimeMs() { 33297 return getOffsetMs(); 33298 } 33299 33300 function setIsSynchronizing(value) { 33301 isSynchronizing = value; 33302 } 33303 33304 function getIsSynchronizing() { 33305 return isSynchronizing; 33306 } 33307 33308 function setIsInitialised(value) { 33309 isInitialised = value; 33310 } 33311 33312 function setOffsetMs(value) { 33313 offsetToDeviceTimeMs = value; 33314 } 33315 33316 function getOffsetMs() { 33317 return offsetToDeviceTimeMs; 33318 } 33319 33320 // takes xsdatetime and returns milliseconds since UNIX epoch 33321 // may not be necessary as xsdatetime is very similar to ISO 8601 33322 // which is natively understood by javascript Date parser 33323 function alternateXsdatetimeDecoder(xsdatetimeStr) { 33324 // taken from DashParser - should probably refactor both uses 33325 var SECONDS_IN_MIN = 60; 33326 var MINUTES_IN_HOUR = 60; 33327 var MILLISECONDS_IN_SECONDS = 1000; 33328 var datetimeRegex = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(?:([+\-])([0-9]{2})([0-9]{2}))?/; 33329 33330 var utcDate = undefined, 33331 timezoneOffset = undefined; 33332 33333 var match = datetimeRegex.exec(xsdatetimeStr); 33334 33335 // If the string does not contain a timezone offset different browsers can interpret it either 33336 // as UTC or as a local time so we have to parse the string manually to normalize the given date value for 33337 // all browsers 33338 utcDate = Date.UTC(parseInt(match[1], 10), parseInt(match[2], 10) - 1, // months start from zero 33339 parseInt(match[3], 10), parseInt(match[4], 10), parseInt(match[5], 10), match[6] && (parseInt(match[6], 10) || 0), match[7] && parseFloat(match[7]) * MILLISECONDS_IN_SECONDS || 0); 33340 // If the date has timezone offset take it into account as well 33341 if (match[9] && match[10]) { 33342 timezoneOffset = parseInt(match[9], 10) * MINUTES_IN_HOUR + parseInt(match[10], 10); 33343 utcDate += (match[8] === '+' ? -1 : +1) * timezoneOffset * SECONDS_IN_MIN * MILLISECONDS_IN_SECONDS; 33344 } 33345 33346 return new Date(utcDate).getTime(); 33347 } 33348 33349 // try to use the built in parser, since xsdate is a constrained ISO8601 33350 // which is supported natively by Date.parse. if that fails, try a 33351 // regex-based version used elsewhere in this application. 33352 function xsdatetimeDecoder(xsdatetimeStr) { 33353 var parsedDate = Date.parse(xsdatetimeStr); 33354 33355 if (isNaN(parsedDate)) { 33356 parsedDate = alternateXsdatetimeDecoder(xsdatetimeStr); 33357 } 33358 33359 return parsedDate; 33360 } 33361 33362 // takes ISO 8601 timestamp and returns milliseconds since UNIX epoch 33363 function iso8601Decoder(isoStr) { 33364 return Date.parse(isoStr); 33365 } 33366 33367 // takes RFC 1123 timestamp (which is same as ISO8601) and returns 33368 // milliseconds since UNIX epoch 33369 function rfc1123Decoder(dateStr) { 33370 return Date.parse(dateStr); 33371 } 33372 33373 function notSupportedHandler(url, onSuccessCB, onFailureCB) { 33374 onFailureCB(); 33375 } 33376 33377 function directHandler(xsdatetimeStr, onSuccessCB, onFailureCB) { 33378 var time = xsdatetimeDecoder(xsdatetimeStr); 33379 33380 if (!isNaN(time)) { 33381 onSuccessCB(time); 33382 return; 33383 } 33384 33385 onFailureCB(); 33386 } 33387 33388 function httpHandler(decoder, url, onSuccessCB, onFailureCB, isHeadRequest) { 33389 var oncomplete = undefined, 33390 onload = undefined; 33391 var complete = false; 33392 var req = new XMLHttpRequest(); 33393 33394 var verb = isHeadRequest ? _voMetricsHTTPRequest.HTTPRequest.HEAD : _voMetricsHTTPRequest.HTTPRequest.GET; 33395 var urls = url.match(/\S+/g); 33396 33397 // according to ISO 23009-1, url could be a white-space 33398 // separated list of URLs. just handle one at a time. 33399 url = urls.shift(); 33400 33401 oncomplete = function () { 33402 if (complete) { 33403 return; 33404 } 33405 33406 // we only want to pass through here once per xhr, 33407 // regardless of whether the load was successful. 33408 complete = true; 33409 33410 // if there are more urls to try, call self. 33411 if (urls.length) { 33412 httpHandler(decoder, urls.join(' '), onSuccessCB, onFailureCB, isHeadRequest); 33413 } else { 33414 onFailureCB(); 33415 } 33416 }; 33417 33418 onload = function () { 33419 var time = undefined, 33420 result = undefined; 33421 33422 if (req.status === 200) { 33423 time = isHeadRequest ? req.getResponseHeader('Date') : req.response; 33424 33425 result = decoder(time); 33426 33427 // decoder returns NaN if non-standard input 33428 if (!isNaN(result)) { 33429 onSuccessCB(result); 33430 complete = true; 33431 } 33432 } 33433 }; 33434 33435 req.open(verb, url); 33436 req.timeout = HTTP_TIMEOUT_MS || 0; 33437 req.onload = onload; 33438 req.onloadend = oncomplete; 33439 req.send(); 33440 } 33441 33442 function httpHeadHandler(url, onSuccessCB, onFailureCB) { 33443 httpHandler(rfc1123Decoder, url, onSuccessCB, onFailureCB, true); 33444 } 33445 33446 function checkForDateHeader() {
33447 var metrics = metricsModel.getReadOnlyMetricsFor(_constantsConstants2['default'].STREAM); 33448 var dateHeaderValue = dashMetrics.getLatestMPDRequestHeaderValueByID(metrics, 'Date'); 33449 var dateHeaderTime = dateHeaderValue !== null ? new Date(dateHeaderValue).getTime() : Number.NaN; 33450 33451 if (!isNaN(dateHeaderTime)) { 33452 setOffsetMs(dateHeaderTime - new Date().getTime()); 33453 completeTimeSyncSequence(false, dateHeaderTime / 1000, offsetToDeviceTimeMs); 33454 } else { 33455 completeTimeSyncSequence(true); 33456 } 33457 } 33458 33459 function completeTimeSyncSequence(failed, time, offset) { 33460 setIsSynchronizing(false); 33461 eventBus.trigger(_coreEventsEvents2['default'].TIME_SYNCHRONIZATION_COMPLETED, { time: time, offset: offset, error: failed ? new _voDashJSError2['default'](TIME_SYNC_FAILED_ERROR_CODE) : null }); 33462 } 33463 33464 function attemptSync(sources, sourceIndex) { 33465 33466 // if called with no sourceIndex, use zero (highest priority) 33467 var index = sourceIndex || 0; 33468 33469 // the sources should be ordered in priority from the manifest. 33470 // try each in turn, from the top, until either something 33471 // sensible happens, or we run out of sources to try. 33472 var source = sources[index]; 33473 33474 // callback to emit event to listeners 33475 var onComplete = function onComplete(time, offset) { 33476 var failed = !time || !offset; 33477 if (failed && useManifestDateHeaderTimeSource) { 33478 //Before falling back to binary search , check if date header exists on MPD. if so, use for a time source. 33479 checkForDateHeader(); 33480 } else { 33481 completeTimeSyncSequence(failed, time, offset); 33482 } 33483 }; 33484 33485 setIsSynchronizing(true); 33486 33487 if (source) { 33488 // check if there is a handler for this @schemeIdUri 33489 if (handlers.hasOwnProperty(source.schemeIdUri)) { 33490 // if so, call it with its @value 33491 handlers[source.schemeIdUri](source.value, function (serverTime) { 33492 // the timing source returned something useful 33493 var deviceTime = new Date().getTime(); 33494 var offset = serverTime - deviceTime; 33495 33496 setOffsetMs(offset); 33497 33498 log('Local time: ' + new Date(deviceTime)); 33499 log('Server time: ' + new Date(serverTime)); 33500 log('Difference (ms): ' + offset); 33501 33502 onComplete(serverTime, offset); 33503 }, function () { 33504 // the timing source was probably uncontactable 33505 // or returned something we can't use - try again 33506 // with the remaining sources 33507 attemptSync(sources, index + 1); 33508 }); 33509 } else { 33510 // an unknown schemeIdUri must have been found 33511 // try again with the remaining sources 33512 attemptSync(sources, index + 1); 33513 } 33514 } else { 33515 // no valid time source could be found, just use device time 33516 setOffsetMs(0); 33517 onComplete(); 33518 } 33519 } 33520 33521 function reset() { 33522 setIsInitialised(false); 33523 setIsSynchronizing(false); 33524 } 33525 33526 instance = { 33527 initialize: initialize, 33528 getOffsetToDeviceTimeMs: getOffsetToDeviceTimeMs, 33529 setConfig: setConfig, 33530 reset: reset 33531 }; 33532 33533 return instance; 33534} 33535 33536TimeSyncController.__dashjs_factory_name = 'TimeSyncController'; 33537var factory = _coreFactoryMaker2['default'].getSingletonFactory(TimeSyncController); 33538factory.TIME_SYNC_FAILED_ERROR_CODE = TIME_SYNC_FAILED_ERROR_CODE; 33539factory.HTTP_TIMEOUT_MS = HTTP_TIMEOUT_MS; 33540_coreFactoryMaker2['default'].updateSingletonFactory(TimeSyncController.__dashjs_factory_name, factory); 33541exports['default'] = factory; 33542module.exports = exports['default']; 33543 33544},{"100":100,"207":207,"224":224,"49":49,"50":50,"51":51,"54":54}],115:[function(_dereq_,module,exports){ 33545/** 33546 * The copyright in this software is being made available under the BSD License, 33547 * included below. This software may be subject to other third party and contributor 33548 * rights, including patent rights, and no such rights are granted under this license. 33549 * 33550 * Copyright (c) 2013, Dash Industry Forum. 33551 * All rights reserved. 33552 * 33553 * Redistribution and use in source and binary forms, with or without modification, 33554 * are permitted provided that the following conditions are met: 33555 * * Redistributions of source code must retain the above copyright notice, this 33556 * list of conditions and the following disclaimer. 33557 * * Redistributions in binary form must reproduce the above copyright notice, 33558 * this list of conditions and the following disclaimer in the documentation and/or 33559 * other materials provided with the distribution. 33560 * * Neither the name of Dash Industry Forum nor the names of its 33561 * contributors may be used to endorse or promote products derived from this software 33562 * without specific prior written permission. 33563 * 33564 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 33565 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 33566 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 33567 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33568 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
33568INCLUDING, BUT 33569 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33570 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 33571 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33572 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33573 * POSSIBILITY OF SUCH DAMAGE. 33574 */ 33575'use strict'; 33576 33577Object.defineProperty(exports, '__esModule', { 33578 value: true 33579}); 33580 33581function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 33582 33583var _XlinkLoader = _dereq_(99); 33584 33585var _XlinkLoader2 = _interopRequireDefault(_XlinkLoader); 33586 33587var _coreEventBus = _dereq_(50); 33588 33589var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 33590 33591var _coreEventsEvents = _dereq_(54); 33592 33593var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 33594 33595var _coreFactoryMaker = _dereq_(51); 33596 33597var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 33598 33599var _externalsXml2json = _dereq_(4); 33600 33601var _externalsXml2json2 = _interopRequireDefault(_externalsXml2json); 33602 33603var _utilsURLUtils = _dereq_(202); 33604 33605var _utilsURLUtils2 = _interopRequireDefault(_utilsURLUtils); 33606 33607var RESOLVE_TYPE_ONLOAD = 'onLoad'; 33608var RESOLVE_TYPE_ONACTUATE = 'onActuate'; 33609var ELEMENT_TYPE_PERIOD = 'Period'; 33610var ELEMENT_TYPE_ADAPTATIONSET = 'AdaptationSet'; 33611var ELEMENT_TYPE_EVENTSTREAM = 'EventStream'; 33612var RESOLVE_TO_ZERO = 'urn:mpeg:dash:resolve-to-zero:2013'; 33613 33614function XlinkController(config) { 33615 33616 var context = this.context; 33617 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 33618 var urlUtils = (0, _utilsURLUtils2['default'])(context).getInstance(); 33619 33620 var instance = undefined, 33621 matchers = undefined, 33622 iron = undefined, 33623 manifest = undefined, 33624 converter = undefined, 33625 xlinkLoader = undefined; 33626 33627 function setup() { 33628 eventBus.on(_coreEventsEvents2['default'].XLINK_ELEMENT_LOADED, onXlinkElementLoaded, instance); 33629 33630 xlinkLoader = (0, _XlinkLoader2['default'])(context).create({ 33631 errHandler: config.errHandler, 33632 metricsModel: config.metricsModel, 33633 mediaPlayerModel: config.mediaPlayerModel, 33634 requestModifier: config.requestModifier 33635 }); 33636 } 33637 33638 function setMatchers(value) { 33639 if (value) { 33640 matchers = value; 33641 } 33642 } 33643 33644 function setIron(value) { 33645 if (value) { 33646 iron = value; 33647 } 33648 } 33649 33650 /** 33651 * <p>Triggers the resolution of the xlink.onLoad attributes in the manifest file </p> 33652 * @param {Object} mpd - the manifest 33653 */ 33654 function resolveManifestOnLoad(mpd) { 33655 var elements = undefined; 33656 // First resolve all periods, so unnecessary requests inside onLoad Periods with Default content are avoided 33657 converter = new _externalsXml2json2['default']({ 33658 escapeMode: false, 33659 attributePrefix: '', 33660 arrayAccessForm: 'property', 33661 emptyNodeForm: 'object', 33662 stripWhitespaces: false, 33663 enableToStringFunc: false, 33664 ignoreRoot: true, 33665 matchers: matchers 33666 }); 33667 33668 manifest = mpd; 33669 elements = getElementsToResolve(manifest.Period_asArray, manifest, ELEMENT_TYPE_PERIOD, RESOLVE_TYPE_ONLOAD); 33670 resolve(elements, ELEMENT_TYPE_PERIOD, RESOLVE_TYPE_ONLOAD); 33671 } 33672 33673 function reset() { 33674 eventBus.off(_coreEventsEvents2['default'].XLINK_ELEMENT_LOADED, onXlinkElementLoaded, instance); 33675 33676 if (xlinkLoader) { 33677 xlinkLoader.reset(); 33678 xlinkLoader = null; 33679 } 33680 } 33681 33682 function resolve(elements, type, resolveType) { 33683 var resolveObject = {}; 33684 var element = undefined, 33685 url = undefined; 33686 33687 resolveObject.elements = elements; 33688 resolveObject.type = type; 33689 resolveObject.resolveType = resolveType; 33690 // If nothing to resolve, directly call allElementsLoaded 33691 if (resolveObject.elements.length === 0) { 33692 onXlinkAllElementsLoaded(resolveObject); 33693 } 33694 for (var i = 0; i < resolveObject.elements.length; i++) { 33695 element = resolveObject.elements[i]; 33696 if (urlUtils.isHTTPURL(element.url)) { 33697 url = element.url; 33698 } else { 33699 url = element.originalContent.BaseURL + element.url; 33700 } 33701 xlinkLoader.load(url, element, resolveObject); 33702 } 33703 } 33704
33705 function onXlinkElementLoaded(event) { 33706 var element = undefined, 33707 resolveObject = undefined; 33708 33709 var openingTag = '<response>'; 33710 var closingTag = '</response>'; 33711 var mergedContent = ''; 33712 33713 element = event.element; 33714 resolveObject = event.resolveObject; 33715 // if the element resolved into content parse the content 33716 if (element.resolvedContent) { 33717 var index = 0; 33718 // we add a parent elements so the converter is able to parse multiple elements of the same type which are not wrapped inside a container 33719 if (element.resolvedContent.indexOf('<?xml') === 0) { 33720 index = element.resolvedContent.indexOf('?>') + 2; //find the closing position of the xml declaration, if it exists. 33721 } 33722 mergedContent = element.resolvedContent.substr(0, index) + openingTag + element.resolvedContent.substr(index) + closingTag; 33723 element.resolvedContent = converter.xml_str2json(mergedContent); 33724 } 33725 if (isResolvingFinished(resolveObject)) { 33726 onXlinkAllElementsLoaded(resolveObject); 33727 } 33728 } 33729 33730 // We got to wait till all elements of the current queue are resolved before merging back 33731 function onXlinkAllElementsLoaded(resolveObject) { 33732 var elements = []; 33733 var i = undefined, 33734 obj = undefined; 33735 33736 mergeElementsBack(resolveObject); 33737 if (resolveObject.resolveType === RESOLVE_TYPE_ONACTUATE) { 33738 eventBus.trigger(_coreEventsEvents2['default'].XLINK_READY, { manifest: manifest }); 33739 } 33740 if (resolveObject.resolveType === RESOLVE_TYPE_ONLOAD) { 33741 switch (resolveObject.type) { 33742 // Start resolving the other elements. We can do Adaptation Set and EventStream in parallel 33743 case ELEMENT_TYPE_PERIOD: 33744 for (i = 0; i < manifest[ELEMENT_TYPE_PERIOD + '_asArray'].length; i++) { 33745 obj = manifest[ELEMENT_TYPE_PERIOD + '_asArray'][i]; 33746 if (obj.hasOwnProperty(ELEMENT_TYPE_ADAPTATIONSET + '_asArray')) { 33747 elements = elements.concat(getElementsToResolve(obj[ELEMENT_TYPE_ADAPTATIONSET + '_asArray'], obj, ELEMENT_TYPE_ADAPTATIONSET, RESOLVE_TYPE_ONLOAD)); 33748 } 33749 if (obj.hasOwnProperty(ELEMENT_TYPE_EVENTSTREAM + '_asArray')) { 33750 elements = elements.concat(getElementsToResolve(obj[ELEMENT_TYPE_EVENTSTREAM + '_asArray'], obj, ELEMENT_TYPE_EVENTSTREAM, RESOLVE_TYPE_ONLOAD)); 33751 } 33752 } 33753 resolve(elements, ELEMENT_TYPE_ADAPTATIONSET, RESOLVE_TYPE_ONLOAD); 33754 break; 33755 case ELEMENT_TYPE_ADAPTATIONSET: 33756 // TODO: Resolve SegmentList here 33757 eventBus.trigger(_coreEventsEvents2['default'].XLINK_READY, { manifest: manifest }); 33758 break; 33759 } 33760 } 33761 } 33762 33763 // Returns the elements with the specific resolve Type 33764 function getElementsToResolve(elements, parentElement, type, resolveType) { 33765 var toResolve = []; 33766 var element = undefined, 33767 i = undefined, 33768 xlinkObject = undefined; 33769 // first remove all the resolve-to-zero elements 33770 for (i = elements.length - 1; i >= 0; i--) { 33771 element = elements[i]; 33772 if (element.hasOwnProperty('xlink:href') && element['xlink:href'] === RESOLVE_TO_ZERO) { 33773 elements.splice(i, 1); 33774 } 33775 } 33776 // now get the elements with the right resolve type 33777 for (i = 0; i < elements.length; i++) { 33778 element = elements[i]; 33779 if (element.hasOwnProperty('xlink:href') && element.hasOwnProperty('xlink:actuate') && element['xlink:actuate'] === resolveType) { 33780 xlinkObject = createXlinkObject(element['xlink:href'], parentElement, type, i, resolveType, element); 33781 toResolve.push(xlinkObject); 33782 } 33783 } 33784 return toResolve; 33785 } 33786 33787 function mergeElementsBack(resolveObject) { 33788 var resolvedElements = []; 33789 var element = undefined, 33790 type = undefined, 33791 obj = undefined, 33792 i = undefined, 33793 j = undefined, 33794 k = undefined; 33795 // Start merging back from the end because of index shifting. Note that the elements with the same parent have to be ordered by index ascending 33796 for (i = resolveObject.elements.length - 1; i >= 0; i--) { 33797 element = resolveObject.elements[i]; 33798 type = element.type + '_asArray'; 33799 33800 // Element couldn't be resolved or is TODO Inappropriate target: Remove all Xlink attributes 33801 if (!element.resolvedContent || isInappropriateTarget()) { 33802 delete element.originalContent['xlink:actuate']; 33803 delete element.originalContent['xlink:href']; 33804 resolvedElements.push(element.originalContent); 33805 } 33806 // Element was successfully resolved 33807 else if (element.resolvedContent) { 33808 for (j = 0; j < element.resolvedContent[type].length; j++) { 33809 //TODO Contains another Xlink attribute with xlink:actuate set to onload. Remove all xLink attributes 33810 obj = element.resolvedContent[type][j]; 33811 resolvedElements.push(obj); 33812 } 33813 } 33814 // Replace the old elements in the parent with the resolved ones 33815 element.parentElement[type].splice(element.index, 1); 33816 for (k = 0; k < resolvedElements.length; k++) { 33817 element.parentElement[type].splice(element.index + k, 0, resolvedElements[k]); 33818 } 33819 resolvedElements = []; 33820 } 33821 if (resolveObject.elements.length > 0) { 33822 iron.run(manifest); 33823 } 33824 } 33825 33826 function createXlinkObject(url, parentElement, type, index, resolveType, originalContent) { 33827 return { 33828 url: url, 33829 parentElement: parentElement, 33830 type: type, 33831 index: index, 33832 resolveType: resolveType, 33833 originalContent: originalContent, 33834 resolvedContent: null, 33835 resolved: false 33836 }; 33837 } 33838 33839 // Check if all pending requests are finished
33840 function isResolvingFinished(elementsToResolve) { 33841 var i = undefined, 33842 obj = undefined; 33843 for (i = 0; i < elementsToResolve.elements.length; i++) { 33844 obj = elementsToResolve.elements[i]; 33845 if (obj.resolved === false) { 33846 return false; 33847 } 33848 } 33849 return true; 33850 } 33851 33852 // TODO : Do some syntax check here if the target is valid or not 33853 function isInappropriateTarget() { 33854 return false; 33855 } 33856 33857 instance = { 33858 resolveManifestOnLoad: resolveManifestOnLoad, 33859 setMatchers: setMatchers, 33860 setIron: setIron, 33861 reset: reset 33862 }; 33863 33864 setup(); 33865 return instance; 33866} 33867 33868XlinkController.__dashjs_factory_name = 'XlinkController'; 33869exports['default'] = _coreFactoryMaker2['default'].getClassFactory(XlinkController); 33870module.exports = exports['default']; 33871 33872},{"202":202,"4":4,"50":50,"51":51,"54":54,"99":99}],116:[function(_dereq_,module,exports){ 33873/** 33874 * The copyright in this software is being made available under the BSD License, 33875 * included below. This software may be subject to other third party and contributor 33876 * rights, including patent rights, and no such rights are granted under this license. 33877 * 33878 * Copyright (c) 2013, Dash Industry Forum. 33879 * All rights reserved. 33880 * 33881 * Redistribution and use in source and binary forms, with or without modification, 33882 * are permitted provided that the following conditions are met: 33883 * * Redistributions of source code must retain the above copyright notice, this 33884 * list of conditions and the following disclaimer. 33885 * * Redistributions in binary form must reproduce the above copyright notice, 33886 * this list of conditions and the following disclaimer in the documentation and/or 33887 * other materials provided with the distribution. 33888 * * Neither the name of Dash Industry Forum nor the names of its 33889 * contributors may be used to endorse or promote products derived from this software 33890 * without specific prior written permission. 33891 * 33892 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 33893 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 33894 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 33895 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33896 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 33897 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33898 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 33899 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33900 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33901 * POSSIBILITY OF SUCH DAMAGE. 33902 */ 33903 33904'use strict'; 33905 33906Object.defineProperty(exports, '__esModule', { 33907 value: true 33908}); 33909 33910function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 33911 33912var _utilsDVBErrorsTranslator = _dereq_(130); 33913 33914var _utilsDVBErrorsTranslator2 = _interopRequireDefault(_utilsDVBErrorsTranslator); 33915 33916var _MetricsReportingEvents = _dereq_(117); 33917 33918var _MetricsReportingEvents2 = _interopRequireDefault(_MetricsReportingEvents); 33919 33920var _controllersMetricsCollectionController = _dereq_(118); 33921 33922var _controllersMetricsCollectionController2 = _interopRequireDefault(_controllersMetricsCollectionController); 33923 33924var _metricsMetricsHandlerFactory = _dereq_(123); 33925 33926var _metricsMetricsHandlerFactory2 = _interopRequireDefault(_metricsMetricsHandlerFactory); 33927 33928var _reportingReportingFactory = _dereq_(128); 33929 33930var _reportingReportingFactory2 = _interopRequireDefault(_reportingReportingFactory); 33931 33932function MetricsReporting() { 33933 33934 var context = this.context; 33935 var instance = undefined; 33936 33937 var dvbErrorsTranslator = undefined; 33938 33939 /** 33940 * Create a MetricsCollectionController, and a DVBErrorsTranslator 33941 * @param {Object} config - dependancies from owner 33942 * @return {MetricsCollectionController} Metrics Collection Controller 33943 */ 33944 function createMetricsReporting(config) { 33945 dvbErrorsTranslator = (0, _utilsDVBErrorsTranslator2['default'])(context).getInstance({ 33946 eventBus: config.eventBus, 33947 metricsModel: config.metricsModel, 33948 metricsConstants: config.metricsConstants, 33949 events: config.events 33950 }); 33951 33952 return (0, _controllersMetricsCollectionController2['default'])(context).create(config); 33953 } 33954 33955 /** 33956 * Get the ReportingFactory to allow new reporters to be registered 33957 * @return {ReportingFactory} Reporting Factory 33958 */ 33959 function getReportingFactory() { 33960 return (0, _reportingReportingFactory2['default'])(context).getInstance(); 33961 } 33962 33963 /** 33964 * Get the MetricsHandlerFactory to allow new handlers to be registered 33965 * @return {MetricsHandlerFactory} Metrics Handler Factory 33966 */ 33967 function getMetricsHandlerFactory() { 33968 return (0, _metricsMetricsHandlerFactory2['default'])(context).getInstance(); 33969 } 33970 33971 instance = { 33972 createMetricsReporting: createMetricsReporting, 33973 getReportingFactory: getReportingFactory, 33974 getMetricsHandlerFactory: getMetricsHandlerFactory 33975 }; 33976 33977 return instance; 33978} 33979 33980MetricsReporting.__dashjs_factory_name = 'MetricsReporting'; 33981var factory = dashjs.FactoryMaker.getClassFactory(MetricsReporting); /* jshint ignore:line */ 33982factory.events = _MetricsReportingEvents2['default']; 33983dashjs.FactoryMaker.updateClassFactory(MetricsReporting.__dashjs_factory_name, factory); /* jshint ignore:line */ 33984exports['default'] = factory; 33985module.exports = exports['default']; 33986 33987},{"117":117,"118":118,"123":123,"128":128,"130":130}],117:[function(_dereq_,module,exports){ 33988/** 33989 * The copyright in this software is being made available under the BSD License, 33990 * included below. This software may be subject to other third party and contributor 33991 * rights, including patent rights, and no such rights are granted under this license. 33992 * 33993 * Copyright (c) 2013, Dash Industry Forum. 33994 * All rights reserved. 33995 * 33996 * Redistribution and use in source and binary forms, with or without modification, 33997 * are permitted provided that the following conditions are met: 33998 * * Redistributions of source code must retain the above copyright notice, this 33999 * list of conditions and the following disclaimer. 34000 * * Redistributions in binary form must reproduce the above copyright notice, 34001 * this list of conditions and the following disclaimer in the documentation and/or 34002 * other materials provided with the distribution. 34003 * * Neither the name of Dash Industry Forum nor the names of its 34004 * contributors may be used to endorse or promote products derived from this software 34005 * without specific prior written permission. 34006 * 34007 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34008 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34009 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34010 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34011 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
34011INCLUDING, BUT 34012 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34013 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34014 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34015 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34016 * POSSIBILITY OF SUCH DAMAGE. 34017 */ 34018'use strict'; 34019 34020Object.defineProperty(exports, '__esModule', { 34021 value: true 34022}); 34023 34024var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 34025 34026function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 34027 34028function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 34029 34030function _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; } 34031 34032var _coreEventsEventsBase = _dereq_(55); 34033 34034var _coreEventsEventsBase2 = _interopRequireDefault(_coreEventsEventsBase); 34035 34036var MetricsReportingEvents = (function (_EventsBase) { 34037 _inherits(MetricsReportingEvents, _EventsBase); 34038 34039 function MetricsReportingEvents() { 34040 _classCallCheck(this, MetricsReportingEvents); 34041 34042 _get(Object.getPrototypeOf(MetricsReportingEvents.prototype), 'constructor', this).call(this); 34043 34044 this.METRICS_INITIALISATION_COMPLETE = 'internal_metricsReportingInitialized'; 34045 this.BECAME_REPORTING_PLAYER = 'internal_becameReportingPlayer'; 34046 } 34047 34048 return MetricsReportingEvents; 34049})(_coreEventsEventsBase2['default']); 34050 34051var metricsReportingEvents = new MetricsReportingEvents(); 34052exports['default'] = metricsReportingEvents; 34053module.exports = exports['default']; 34054 34055},{"55":55}],118:[function(_dereq_,module,exports){ 34056/** 34057 * The copyright in this software is being made available under the BSD License, 34058 * included below. This software may be subject to other third party and contributor 34059 * rights, including patent rights, and no such rights are granted under this license. 34060 * 34061 * Copyright (c) 2013, Dash Industry Forum. 34062 * All rights reserved. 34063 * 34064 * Redistribution and use in source and binary forms, with or without modification, 34065 * are permitted provided that the following conditions are met: 34066 * * Redistributions of source code must retain the above copyright notice, this 34067 * list of conditions and the following disclaimer. 34068 * * Redistributions in binary form must reproduce the above copyright notice, 34069 * this list of conditions and the following disclaimer in the documentation and/or 34070 * other materials provided with the distribution. 34071 * * Neither the name of Dash Industry Forum nor the names of its 34072 * contributors may be used to endorse or promote products derived from this software 34073 * without specific prior written permission. 34074 * 34075 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34076 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34077 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34078 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34079 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
34079INCLUDING, BUT 34080 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34081 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34082 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34083 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34084 * POSSIBILITY OF SUCH DAMAGE. 34085 */ 34086 34087'use strict'; 34088 34089Object.defineProperty(exports, '__esModule', { 34090 value: true 34091}); 34092 34093function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 34094 34095var _MetricsController = _dereq_(119); 34096 34097var _MetricsController2 = _interopRequireDefault(_MetricsController); 34098 34099var _utilsManifestParsing = _dereq_(132); 34100 34101var _utilsManifestParsing2 = _interopRequireDefault(_utilsManifestParsing); 34102 34103var _MetricsReportingEvents = _dereq_(117); 34104 34105var _MetricsReportingEvents2 = _interopRequireDefault(_MetricsReportingEvents); 34106 34107function MetricsCollectionController(config) { 34108 34109 var metricsControllers = {}; 34110 34111 var context = this.context; 34112 var eventBus = config.eventBus; 34113 var events = config.events; 34114 34115 function update(e) { 34116 if (e.error) { 34117 return; 34118 } 34119 34120 // start by assuming all existing controllers need removing 34121 var controllersToRemove = Object.keys(metricsControllers); 34122 34123 var metrics = (0, _utilsManifestParsing2['default'])(context).getInstance({ 34124 dashManifestModel: config.dashManifestModel, 34125 constants: config.constants 34126 }).getMetrics(e.manifest); 34127 34128 metrics.forEach(function (m) { 34129 var key = JSON.stringify(m); 34130 34131 if (!metricsControllers.hasOwnProperty(key)) { 34132 try { 34133 var controller = (0, _MetricsController2['default'])(context).create(config); 34134 controller.initialize(m); 34135 metricsControllers[key] = controller; 34136 } catch (e) { 34137 // fail quietly 34138 } 34139 } else { 34140 // we still need this controller - delete from removal list 34141 controllersToRemove.splice(key, 1); 34142 } 34143 }); 34144 34145 // now remove the unwanted controllers 34146 controllersToRemove.forEach(function (c) { 34147 metricsControllers[c].reset(); 34148 delete metricsControllers[c]; 34149 }); 34150 34151 eventBus.trigger(_MetricsReportingEvents2['default'].METRICS_INITIALISATION_COMPLETE); 34152 } 34153 34154 function resetMetricsControllers() { 34155 Object.keys(metricsControllers).forEach(function (key) { 34156 metricsControllers[key].reset(); 34157 }); 34158 34159 metricsControllers = {}; 34160 } 34161 34162 function setup() { 34163 eventBus.on(events.MANIFEST_UPDATED, update); 34164 eventBus.on(events.STREAM_TEARDOWN_COMPLETE, resetMetricsControllers); 34165 } 34166 34167 function reset() { 34168 eventBus.off(events.MANIFEST_UPDATED, update); 34169 eventBus.off(events.STREAM_TEARDOWN_COMPLETE, resetMetricsControllers); 34170 } 34171 34172 setup(); 34173 34174 return { 34175 reset: reset 34176 }; 34177} 34178 34179MetricsCollectionController.__dashjs_factory_name = 'MetricsCollectionController'; 34180exports['default'] = dashjs.FactoryMaker.getClassFactory(MetricsCollectionController); 34181/* jshint ignore:line */ 34182module.exports = exports['default']; 34183 34184},{"117":117,"119":119,"132":132}],119:[function(_dereq_,module,exports){ 34185/** 34186 * The copyright in this software is being made available under the BSD License, 34187 * included below. This software may be subject to other third party and contributor 34188 * rights, including patent rights, and no such rights are granted under this license. 34189 * 34190 * Copyright (c) 2013, Dash Industry Forum. 34191 * All rights reserved. 34192 * 34193 * Redistribution and use in source and binary forms, with or without modification, 34194 * are permitted provided that the following conditions are met: 34195 * * Redistributions of source code must retain the above copyright notice, this 34196 * list of conditions and the following disclaimer. 34197 * * Redistributions in binary form must reproduce the above copyright notice, 34198 * this list of conditions and the following disclaimer in the documentation and/or 34199 * other materials provided with the distribution. 34200 * * Neither the name of Dash Industry Forum nor the names of its 34201 * contributors may be used to endorse or promote products derived from this software 34202 * without specific prior written permission. 34203 * 34204 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34205 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34206 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34207 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34208 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
34208INCLUDING, BUT 34209 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34210 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34211 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34212 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34213 * POSSIBILITY OF SUCH DAMAGE. 34214 */ 34215 34216'use strict'; 34217 34218Object.defineProperty(exports, '__esModule', { 34219 value: true 34220}); 34221 34222function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 34223 34224var _RangeController = _dereq_(121); 34225 34226var _RangeController2 = _interopRequireDefault(_RangeController); 34227 34228var _ReportingController = _dereq_(122); 34229 34230var _ReportingController2 = _interopRequireDefault(_ReportingController); 34231 34232var _MetricsHandlersController = _dereq_(120); 34233 34234var _MetricsHandlersController2 = _interopRequireDefault(_MetricsHandlersController); 34235 34236function MetricsController(config) { 34237 34238 var metricsHandlersController = undefined, 34239 reportingController = undefined, 34240 rangeController = undefined, 34241 instance = undefined; 34242 34243 var context = this.context; 34244 34245 function initialize(metricsEntry) { 34246 try { 34247 rangeController = (0, _RangeController2['default'])(context).create({ 34248 mediaElement: config.mediaElement 34249 }); 34250 34251 rangeController.initialize(metricsEntry.Range); 34252 34253 reportingController = (0, _ReportingController2['default'])(context).create({ 34254 log: config.log 34255 }); 34256 34257 reportingController.initialize(metricsEntry.Reporting, rangeController); 34258 34259 metricsHandlersController = (0, _MetricsHandlersController2['default'])(context).create({ 34260 log: config.log, 34261 eventBus: config.eventBus, 34262 metricsConstants: config.metricsConstants, 34263 events: config.events 34264 }); 34265 34266 metricsHandlersController.initialize(metricsEntry.metrics, reportingController); 34267 } catch (e) { 34268 reset(); 34269 throw e; 34270 } 34271 } 34272 34273 function reset() { 34274 if (metricsHandlersController) { 34275 metricsHandlersController.reset(); 34276 } 34277 34278 if (reportingController) { 34279 reportingController.reset(); 34280 } 34281 34282 if (rangeController) { 34283 rangeController.reset(); 34284 } 34285 } 34286 34287 instance = { 34288 initialize: initialize, 34289 reset: reset 34290 }; 34291 34292 return instance; 34293} 34294 34295MetricsController.__dashjs_factory_name = 'MetricsController'; 34296exports['default'] = dashjs.FactoryMaker.getClassFactory(MetricsController); 34297/* jshint ignore:line */ 34298module.exports = exports['default']; 34299 34300},{"120":120,"121":121,"122":122}],120:[function(_dereq_,module,exports){ 34301/** 34302 * The copyright in this software is being made available under the BSD License, 34303 * included below. This software may be subject to other third party and contributor 34304 * rights, including patent rights, and no such rights are granted under this license. 34305 * 34306 * Copyright (c) 2013, Dash Industry Forum. 34307 * All rights reserved. 34308 * 34309 * Redistribution and use in source and binary forms, with or without modification, 34310 * are permitted provided that the following conditions are met: 34311 * * Redistributions of source code must retain the above copyright notice, this 34312 * list of conditions and the following disclaimer. 34313 * * Redistributions in binary form must reproduce the above copyright notice, 34314 * this list of conditions and the following disclaimer in the documentation and/or 34315 * other materials provided with the distribution. 34316 * * Neither the name of Dash Industry Forum nor the names of its 34317 * contributors may be used to endorse or promote products derived from this software 34318 * without specific prior written permission. 34319 * 34320 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34321 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34322 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34323 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34324 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
34324INCLUDING, BUT 34325 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34326 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34327 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34328 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34329 * POSSIBILITY OF SUCH DAMAGE. 34330 */ 34331 34332'use strict'; 34333 34334Object.defineProperty(exports, '__esModule', { 34335 value: true 34336}); 34337 34338function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 34339 34340var _metricsMetricsHandlerFactory = _dereq_(123); 34341 34342var _metricsMetricsHandlerFactory2 = _interopRequireDefault(_metricsMetricsHandlerFactory); 34343 34344function MetricsHandlersController(config) { 34345 var handlers = []; 34346 34347 var instance = undefined; 34348 var context = this.context; 34349 var eventBus = config.eventBus; 34350 var Events = config.events; 34351 34352 var metricsHandlerFactory = (0, _metricsMetricsHandlerFactory2['default'])(context).getInstance({ 34353 log: config.log, 34354 eventBus: config.eventBus, 34355 metricsConstants: config.metricsConstants 34356 }); 34357 34358 function handle(e) { 34359 handlers.forEach(function (handler) { 34360 handler.handleNewMetric(e.metric, e.value, e.mediaType); 34361 }); 34362 } 34363 34364 function initialize(metrics, reportingController) { 34365 metrics.split(',').forEach(function (m, midx, ms) { 34366 var handler = undefined; 34367 34368 // there is a bug in ISO23009-1 where the metrics attribute 34369 // is a comma-separated list but HttpList key can contain a 34370 // comma enclosed by (). 34371 if (m.indexOf('(') !== -1 && m.indexOf(')') === -1) { 34372 var nextm = ms[midx + 1]; 34373 34374 if (nextm && nextm.indexOf('(') === -1 && nextm.indexOf(')') !== -1) { 34375 m += ',' + nextm; 34376 34377 // delete the next metric so forEach does not visit. 34378 delete ms[midx + 1]; 34379 } 34380 } 34381 34382 handler = metricsHandlerFactory.create(m, reportingController); 34383 34384 if (handler) { 34385 handlers.push(handler); 34386 } 34387 }); 34388 34389 eventBus.on(Events.METRIC_ADDED, handle, instance); 34390 34391 eventBus.on(Events.METRIC_UPDATED, handle, instance); 34392 } 34393 34394 function reset() { 34395 eventBus.off(Events.METRIC_ADDED, handle, instance); 34396 34397 eventBus.off(Events.METRIC_UPDATED, handle, instance); 34398 34399 handlers.forEach(function (handler) { 34400 return handler.reset(); 34401 }); 34402 34403 handlers = []; 34404 } 34405 34406 instance = { 34407 initialize: initialize, 34408 reset: reset 34409 }; 34410 34411 return instance; 34412} 34413 34414MetricsHandlersController.__dashjs_factory_name = 'MetricsHandlersController'; 34415exports['default'] = dashjs.FactoryMaker.getClassFactory(MetricsHandlersController); 34416/* jshint ignore:line */ 34417module.exports = exports['default']; 34418 34419},{"123":123}],121:[function(_dereq_,module,exports){ 34420/** 34421 * The copyright in this software is being made available under the BSD License, 34422 * included below. This software may be subject to other third party and contributor 34423 * rights, including patent rights, and no such rights are granted under this license. 34424 * 34425 * Copyright (c) 2013, Dash Industry Forum. 34426 * All rights reserved. 34427 * 34428 * Redistribution and use in source and binary forms, with or without modification, 34429 * are permitted provided that the following conditions are met: 34430 * * Redistributions of source code must retain the above copyright notice, this 34431 * list of conditions and the following disclaimer. 34432 * * Redistributions in binary form must reproduce the above copyright notice, 34433 * this list of conditions and the following disclaimer in the documentation and/or 34434 * other materials provided with the distribution. 34435 * * Neither the name of Dash Industry Forum nor the names of its 34436 * contributors may be used to endorse or promote products derived from this software 34437 * without specific prior written permission. 34438 * 34439 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34440 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34441 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34442 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34443 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
34443INCLUDING, BUT 34444 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34445 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34446 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34447 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34448 * POSSIBILITY OF SUCH DAMAGE. 34449 */ 34450 34451'use strict'; 34452 34453Object.defineProperty(exports, '__esModule', { 34454 value: true 34455}); 34456 34457function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 34458 34459var _utilsCustomTimeRanges = _dereq_(192); 34460 34461var _utilsCustomTimeRanges2 = _interopRequireDefault(_utilsCustomTimeRanges); 34462 34463function RangeController(config) { 34464 34465 var useWallClockTime = false; 34466 var context = this.context; 34467 var instance = undefined, 34468 ranges = undefined; 34469 34470 var mediaElement = config.mediaElement; 34471 34472 function initialize(rs) { 34473 if (rs && rs.length) { 34474 rs.forEach(function (r) { 34475 var start = r.starttime; 34476 var end = start + r.duration; 34477 34478 ranges.add(start, end); 34479 }); 34480 34481 useWallClockTime = !!rs[0]._useWallClockTime; 34482 } 34483 } 34484 34485 function reset() { 34486 ranges.clear(); 34487 } 34488 34489 function setup() { 34490 ranges = (0, _utilsCustomTimeRanges2['default'])(context).create(); 34491 } 34492 34493 function isEnabled() { 34494 var numRanges = ranges.length; 34495 var time = undefined; 34496 34497 if (!numRanges) { 34498 return true; 34499 } 34500 34501 // When not present, DASH Metrics reporting is requested 34502 // for the whole duration of the content. 34503 time = useWallClockTime ? new Date().getTime() / 1000 : mediaElement.currentTime; 34504 34505 for (var i = 0; i < numRanges; i += 1) { 34506 var start = ranges.start(i); 34507 var end = ranges.end(i); 34508 34509 if (start <= time && time < end) { 34510 return true; 34511 } 34512 } 34513 34514 return false; 34515 } 34516 34517 instance = { 34518 initialize: initialize, 34519 reset: reset, 34520 isEnabled: isEnabled 34521 }; 34522 34523 setup(); 34524 34525 return instance; 34526} 34527 34528RangeController.__dashjs_factory_name = 'RangeController'; 34529exports['default'] = dashjs.FactoryMaker.getClassFactory(RangeController); 34530/* jshint ignore:line */ 34531module.exports = exports['default']; 34532 34533},{"192":192}],122:[function(_dereq_,module,exports){ 34534/** 34535 * The copyright in this software is being made available under the BSD License, 34536 * included below. This software may be subject to other third party and contributor 34537 * rights, including patent rights, and no such rights are granted under this license. 34538 * 34539 * Copyright (c) 2013, Dash Industry Forum. 34540 * All rights reserved. 34541 * 34542 * Redistribution and use in source and binary forms, with or without modification, 34543 * are permitted provided that the following conditions are met: 34544 * * Redistributions of source code must retain the above copyright notice, this 34545 * list of conditions and the following disclaimer. 34546 * * Redistributions in binary form must reproduce the above copyright notice, 34547 * this list of conditions and the following disclaimer in the documentation and/or 34548 * other materials provided with the distribution. 34549 * * Neither the name of Dash Industry Forum nor the names of its 34550 * contributors may be used to endorse or promote products derived from this software 34551 * without specific prior written permission. 34552 * 34553 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34554 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34555 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34556 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34557 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 34558 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34559 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34560 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34561 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34562 * POSSIBILITY OF SUCH DAMAGE. 34563 */ 34564 34565'use strict'; 34566 34567Object.defineProperty(exports, '__esModule', { 34568 value: true 34569}); 34570 34571function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 34572 34573var _reportingReportingFactory = _dereq_(128); 34574 34575var _reportingReportingFactory2 = _interopRequireDefault(_reportingReportingFactory); 34576 34577function ReportingController(config) { 34578 34579 var reporters = []; 34580 var instance = undefined; 34581 34582 var reportingFactory = (0, _reportingReportingFactory2['default'])(this.context).getInstance({ 34583 log: config.log 34584 });
34585 34586 function initialize(reporting, rangeController) { 34587 // "if multiple Reporting elements are present, it is expected that 34588 // the client processes one of the recognized reporting schemes." 34589 // to ignore this, and support multiple Reporting per Metric, 34590 // simply change the 'some' below to 'forEach' 34591 reporting.some(function (r) { 34592 var reporter = reportingFactory.create(r, rangeController); 34593 34594 if (reporter) { 34595 reporters.push(reporter); 34596 return true; 34597 } 34598 }); 34599 } 34600 34601 function reset() { 34602 reporters.forEach(function (r) { 34603 return r.reset(); 34604 }); 34605 reporters = []; 34606 } 34607 34608 function report(type, vos) { 34609 reporters.forEach(function (r) { 34610 return r.report(type, vos); 34611 }); 34612 } 34613 34614 instance = { 34615 initialize: initialize, 34616 reset: reset, 34617 report: report 34618 }; 34619 34620 return instance; 34621} 34622 34623ReportingController.__dashjs_factory_name = 'ReportingController'; 34624exports['default'] = dashjs.FactoryMaker.getClassFactory(ReportingController); 34625/* jshint ignore:line */ 34626module.exports = exports['default']; 34627 34628},{"128":128}],123:[function(_dereq_,module,exports){ 34629/** 34630 * The copyright in this software is being made available under the BSD License, 34631 * included below. This software may be subject to other third party and contributor 34632 * rights, including patent rights, and no such rights are granted under this license. 34633 * 34634 * Copyright (c) 2013, Dash Industry Forum. 34635 * All rights reserved. 34636 * 34637 * Redistribution and use in source and binary forms, with or without modification, 34638 * are permitted provided that the following conditions are met: 34639 * * Redistributions of source code must retain the above copyright notice, this 34640 * list of conditions and the following disclaimer. 34641 * * Redistributions in binary form must reproduce the above copyright notice, 34642 * this list of conditions and the following disclaimer in the documentation and/or 34643 * other materials provided with the distribution. 34644 * * Neither the name of Dash Industry Forum nor the names of its 34645 * contributors may be used to endorse or promote products derived from this software 34646 * without specific prior written permission. 34647 * 34648 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34649 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34650 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34651 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34652 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 34653 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34654 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34655 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34656 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34657 * POSSIBILITY OF SUCH DAMAGE. 34658 */ 34659 34660'use strict'; 34661 34662Object.defineProperty(exports, '__esModule', { 34663 value: true 34664}); 34665 34666function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 34667 34668var _handlersBufferLevelHandler = _dereq_(124); 34669 34670var _handlersBufferLevelHandler2 = _interopRequireDefault(_handlersBufferLevelHandler); 34671 34672var _handlersDVBErrorsHandler = _dereq_(125); 34673 34674var _handlersDVBErrorsHandler2 = _interopRequireDefault(_handlersDVBErrorsHandler); 34675 34676var _handlersHttpListHandler = _dereq_(127); 34677 34678var _handlersHttpListHandler2 = _interopRequireDefault(_handlersHttpListHandler); 34679 34680var _handlersGenericMetricHandler = _dereq_(126); 34681 34682var _handlersGenericMetricHandler2 = _interopRequireDefault(_handlersGenericMetricHandler); 34683 34684function MetricsHandlerFactory(config) { 34685 34686 var instance = undefined; 34687 var log = config.log; 34688 34689 // group 1: key, [group 3: n [, group 5: type]] 34690 var keyRegex = /([a-zA-Z]*)(\(([0-9]*)(\,\s*([a-zA-Z]*))?\))?/; 34691 34692 var context = this.context; 34693 var knownFactoryProducts = { 34694 BufferLevel: _handlersBufferLevelHandler2['default'], 34695 DVBErrors: _handlersDVBErrorsHandler2['default'], 34696 HttpList: _handlersHttpListHandler2['default'], 34697 PlayList: _handlersGenericMetricHandler2['default'], 34698 RepSwitchList: _handlersGenericMetricHandler2['default'], 34699 TcpList: _handlersGenericMetricHandler2['default'] 34700 }; 34701 34702 function create(listType, reportingController) { 34703 var matches = listType.match(keyRegex); 34704 var handler; 34705 34706 if (!matches) { 34707 return; 34708 } 34709 34710 try { 34711 handler = knownFactoryProducts[matches[1]](context).create({ 34712 eventBus: config.eventBus, 34713 metricsConstants: config.metricsConstants 34714 }); 34715 34716 handler.initialize(matches[1], reportingController, matches[3], matches[5]); 34717 } catch (e) { 34718 handler = null; 34719 34720 log('MetricsHandlerFactory: Could not create handler for type ' + matches[1] + ' with args ' + matches[3] + ', ' + matches[5] + ' (' + e.message + ')'); 34721 } 34722 34723 return handler; 34724 } 34725 34726 function register(key, handler) { 34727 knownFactoryProducts[key] = handler; 34728 } 34729 34730 function unregister(key) { 34731 delete knownFactoryProducts[key]; 34732 } 34733 34734 instance = { 34735 create: create, 34736 register: register, 34737 unregister: unregister 34738 }; 34739 34740 return instance; 34741} 34742 34743MetricsHandlerFactory.__dashjs_factory_name = 'MetricsHandlerFactory'; 34744exports['default'] = dashjs.FactoryMaker.getSingletonFactory(MetricsHandlerFactory); 34745/* jshint ignore:line */ 34746module.exports = exports['default']; 34747 34748},{"124":124,"125":125,"126":126,"127":127}],124:[function(_dereq_,module,exports){ 34749/** 34750 * The copyright in this software is being made available under the BSD License, 34751 * included below. This software may be subject to other third party and contributor 34752 * rights, including patent rights, and no such rights are granted under this license. 34753 * 34754 * Copyright (c) 2013, Dash Industry Forum. 34755 * All rights reserved. 34756 * 34757 * Redistribution and use in source and binary forms, with or without modification, 34758 * are permitted provided that the following conditions are met: 34759 * * Redistributions of source code must retain the above copyright notice, this 34760 * list of conditions and the following disclaimer. 34761 * * Redistributions in binary form must reproduce the above copyright notice, 34762 * this list of conditions and the following disclaimer in the documentation and/or 34763 * other materials provided with the distribution. 34764 * * Neither the name of Dash Industry Forum nor the names of its 34765 * contributors may be used to endorse or promote products derived from this software 34766 * without specific prior written permission. 34767 * 34768 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34769 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34770 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34771 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34772 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
34772INCLUDING, BUT 34773 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34774 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34775 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34776 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34777 * POSSIBILITY OF SUCH DAMAGE. 34778 */ 34779 34780'use strict'; 34781 34782Object.defineProperty(exports, '__esModule', { 34783 value: true 34784}); 34785 34786function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 34787 34788var _utilsHandlerHelpers = _dereq_(131); 34789 34790var _utilsHandlerHelpers2 = _interopRequireDefault(_utilsHandlerHelpers); 34791 34792function BufferLevelHandler(config) { 34793 34794 var instance = undefined, 34795 reportingController = undefined, 34796 n = undefined, 34797 name = undefined, 34798 interval = undefined, 34799 lastReportedTime = undefined; 34800 34801 var context = this.context; 34802 var handlerHelpers = (0, _utilsHandlerHelpers2['default'])(context).getInstance(); 34803 34804 var storedVOs = []; 34805 34806 var metricsConstants = config.metricsConstants; 34807 34808 function getLowestBufferLevelVO() { 34809 try { 34810 return Object.keys(storedVOs).map(function (key) { 34811 return storedVOs[key]; 34812 }).reduce(function (a, b) { 34813 return a.level < b.level ? a : b; 34814 }); 34815 } catch (e) { 34816 return; 34817 } 34818 } 34819 34820 function intervalCallback() { 34821 var vo = getLowestBufferLevelVO(); 34822 34823 if (vo) { 34824 if (lastReportedTime !== vo.t) { 34825 lastReportedTime = vo.t; 34826 reportingController.report(name, vo); 34827 } 34828 } 34829 } 34830 34831 function initialize(basename, rc, n_ms) { 34832 if (rc) {
34833 // this will throw if n is invalid, to be 34834 // caught by the initialize caller. 34835 n = handlerHelpers.validateN(n_ms); 34836 reportingController = rc; 34837 name = handlerHelpers.reconstructFullMetricName(basename, n_ms); 34838 interval = setInterval(intervalCallback, n); 34839 } 34840 } 34841 34842 function reset() { 34843 clearInterval(interval); 34844 interval = null; 34845 n = 0; 34846 reportingController = null; 34847 lastReportedTime = null; 34848 } 34849 34850 function handleNewMetric(metric, vo, type) { 34851 if (metric === metricsConstants.BUFFER_LEVEL) { 34852 storedVOs[type] = vo; 34853 } 34854 } 34855 34856 instance = { 34857 initialize: initialize, 34858 reset: reset, 34859 handleNewMetric: handleNewMetric 34860 }; 34861 34862 return instance; 34863} 34864 34865BufferLevelHandler.__dashjs_factory_name = 'BufferLevelHandler'; 34866exports['default'] = dashjs.FactoryMaker.getClassFactory(BufferLevelHandler); 34867/* jshint ignore:line */ 34868module.exports = exports['default']; 34869 34870},{"131":131}],125:[function(_dereq_,module,exports){ 34871/** 34872 * The copyright in this software is being made available under the BSD License, 34873 * included below. This software may be subject to other third party and contributor 34874 * rights, including patent rights, and no such rights are granted under this license. 34875 * 34876 * Copyright (c) 2013, Dash Industry Forum. 34877 * All rights reserved. 34878 * 34879 * Redistribution and use in source and binary forms, with or without modification, 34880 * are permitted provided that the following conditions are met: 34881 * * Redistributions of source code must retain the above copyright notice, this 34882 * list of conditions and the following disclaimer. 34883 * * Redistributions in binary form must reproduce the above copyright notice, 34884 * this list of conditions and the following disclaimer in the documentation and/or 34885 * other materials provided with the distribution. 34886 * * Neither the name of Dash Industry Forum nor the names of its 34887 * contributors may be used to endorse or promote products derived from this software 34888 * without specific prior written permission. 34889 * 34890 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34891 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34892 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34893 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34894 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 34895 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34896 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34897 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34898 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34899 * POSSIBILITY OF SUCH DAMAGE. 34900 */ 34901 34902'use strict'; 34903 34904Object.defineProperty(exports, '__esModule', { 34905 value: true 34906}); 34907 34908function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 34909 34910var _MetricsReportingEvents = _dereq_(117); 34911 34912var _MetricsReportingEvents2 = _interopRequireDefault(_MetricsReportingEvents); 34913 34914function DVBErrorsHandler(config) { 34915 34916 var instance = undefined, 34917 reportingController = undefined; 34918 34919 var eventBus = config.eventBus; 34920 var metricsConstants = config.metricsConstants; 34921 34922 function onInitialisationComplete() { 34923 // we only want to report this once per call to initialize 34924 eventBus.off(_MetricsReportingEvents2['default'].METRICS_INITIALISATION_COMPLETE, onInitialisationComplete, this); 34925 34926 // Note: A Player becoming a reporting Player is itself 34927 // something which is recorded by the DVBErrors metric. 34928 eventBus.trigger(_MetricsReportingEvents2['default'].BECAME_REPORTING_PLAYER); 34929 } 34930 34931 function initialize(unused, rc) { 34932 if (rc) { 34933 reportingController = rc; 34934 34935 eventBus.on(_MetricsReportingEvents2['default'].METRICS_INITIALISATION_COMPLETE, onInitialisationComplete, this); 34936 } 34937 } 34938 34939 function reset() { 34940 reportingController = null; 34941 } 34942 34943 function handleNewMetric(metric, vo) { 34944 // simply pass metric straight through 34945 if (metric === metricsConstants.DVB_ERRORS) { 34946 if (reportingController) { 34947 reportingController.report(metric, vo); 34948 } 34949 } 34950 } 34951 34952 instance = { 34953 initialize: initialize, 34954 reset: reset, 34955 handleNewMetric: handleNewMetric 34956 }; 34957 34958 return instance; 34959} 34960 34961exports['default'] = dashjs.FactoryMaker.getClassFactory(DVBErrorsHandler); 34962/* jshint ignore:line */ 34963module.exports = exports['default']; 34964 34965},{"117":117}],126:[function(_dereq_,module,exports){ 34966/** 34967 * The copyright in this software is being made available under the BSD License, 34968 * included below. This software may be subject to other third party and contributor 34969 * rights, including patent rights, and no such rights are granted under this license. 34970 * 34971 * Copyright (c) 2013, Dash Industry Forum. 34972 * All rights reserved. 34973 * 34974 * Redistribution and use in source and binary forms, with or without modification, 34975 * are permitted provided that the following conditions are met: 34976 * * Redistributions of source code must retain the above copyright notice, this 34977 * list of conditions and the following disclaimer. 34978 * * Redistributions in binary form must reproduce the above copyright notice, 34979 * this list of conditions and the following disclaimer in the documentation and/or 34980 * other materials provided with the distribution. 34981 * * Neither the name of Dash Industry Forum nor the names of its 34982 * contributors may be used to endorse or promote products derived from this software 34983 * without specific prior written permission. 34984 * 34985 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 34986 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34987 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34988 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34989 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
34989INCLUDING, BUT 34990 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34991 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34992 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34993 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34994 * POSSIBILITY OF SUCH DAMAGE. 34995 */ 34996 34997'use strict'; 34998 34999Object.defineProperty(exports, '__esModule', { 35000 value: true 35001}); 35002function GenericMetricHandler() { 35003 35004 var instance = undefined, 35005 metricName = undefined, 35006 reportingController = undefined; 35007 35008 function initialize(name, rc) { 35009 metricName = name; 35010 reportingController = rc; 35011 } 35012 35013 function reset() { 35014 reportingController = null; 35015 metricName = undefined; 35016 } 35017 35018 function handleNewMetric(metric, vo) { 35019 // simply pass metric straight through 35020 if (metric === metricName) { 35021 if (reportingController) { 35022 reportingController.report(metricName, vo); 35023 } 35024 } 35025 } 35026 35027 instance = { 35028 initialize: initialize, 35029 reset: reset, 35030 handleNewMetric: handleNewMetric 35031 }; 35032 35033 return instance; 35034} 35035 35036GenericMetricHandler.__dashjs_factory_name = 'GenericMetricHandler'; 35037exports['default'] = dashjs.FactoryMaker.getClassFactory(GenericMetricHandler); 35038/* jshint ignore:line */ 35039module.exports = exports['default']; 35040 35041},{}],127:[function(_dereq_,module,exports){ 35042/** 35043 * The copyright in this software is being made available under the BSD License, 35044 * included below. This software may be subject to other third party and contributor 35045 * rights, including patent rights, and no such rights are granted under this license. 35046 * 35047 * Copyright (c) 2013, Dash Industry Forum. 35048 * All rights reserved. 35049 * 35050 * Redistribution and use in source and binary forms, with or without modification, 35051 * are permitted provided that the following conditions are met: 35052 * * Redistributions of source code must retain the above copyright notice, this 35053 * list of conditions and the following disclaimer. 35054 * * Redistributions in binary form must reproduce the above copyright notice, 35055 * this list of conditions and the following disclaimer in the documentation and/or 35056 * other materials provided with the distribution. 35057 * * Neither the name of Dash Industry Forum nor the names of its 35058 * contributors may be used to endorse or promote products derived from this software 35059 * without specific prior written permission. 35060 * 35061 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 35062 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35063 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35064 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35065 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35066 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35067 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35068 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35069 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35070 * POSSIBILITY OF SUCH DAMAGE. 35071 */ 35072 35073'use strict'; 35074 35075Object.defineProperty(exports, '__esModule', { 35076 value: true 35077}); 35078 35079function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 35080 35081var _utilsHandlerHelpers = _dereq_(131); 35082 35083var _utilsHandlerHelpers2 = _interopRequireDefault(_utilsHandlerHelpers); 35084 35085function HttpListHandler(config) { 35086 35087 var instance = undefined, 35088 reportingController = undefined, 35089 n = undefined, 35090 type = undefined, 35091 name = undefined, 35092 interval = undefined; 35093 35094 var storedVos = []; 35095 35096 var handlerHelpers = (0, _utilsHandlerHelpers2['default'])(this.context).getInstance(); 35097 35098 var metricsConstants = config.metricsConstants; 35099 35100 function intervalCallback() { 35101 var vos = storedVos; 35102 35103 if (vos.length) { 35104 if (reportingController) { 35105 reportingController.report(name, vos); 35106 } 35107 } 35108 35109 storedVos = []; 35110 } 35111 35112 function initialize(basename, rc, n_ms, requestType) { 35113 if (rc) { 35114
35115 // this will throw if n is invalid, to be 35116 // caught by the initialize caller. 35117 n = handlerHelpers.validateN(n_ms); 35118 35119 reportingController = rc; 35120 35121 if (requestType && requestType.length) { 35122 type = requestType; 35123 } 35124 35125 name = handlerHelpers.reconstructFullMetricName(basename, n_ms, requestType); 35126 35127 interval = setInterval(intervalCallback, n); 35128 } 35129 } 35130 35131 function reset() { 35132 clearInterval(interval); 35133 interval = null; 35134 n = null; 35135 type = null; 35136 storedVos = []; 35137 reportingController = null; 35138 } 35139 35140 function handleNewMetric(metric, vo) { 35141 if (metric === metricsConstants.HTTP_REQUEST) { 35142 if (!type || type === vo.type) { 35143 storedVos.push(vo); 35144 } 35145 } 35146 } 35147 35148 instance = { 35149 initialize: initialize, 35150 reset: reset, 35151 handleNewMetric: handleNewMetric 35152 }; 35153 35154 return instance; 35155} 35156 35157HttpListHandler.__dashjs_factory_name = 'HttpListHandler'; 35158exports['default'] = dashjs.FactoryMaker.getClassFactory(HttpListHandler); 35159/* jshint ignore:line */ 35160module.exports = exports['default']; 35161 35162},{"131":131}],128:[function(_dereq_,module,exports){ 35163/** 35164 * The copyright in this software is being made available under the BSD License, 35165 * included below. This software may be subject to other third party and contributor 35166 * rights, including patent rights, and no such rights are granted under this license. 35167 * 35168 * Copyright (c) 2013, Dash Industry Forum. 35169 * All rights reserved. 35170 * 35171 * Redistribution and use in source and binary forms, with or without modification, 35172 * are permitted provided that the following conditions are met: 35173 * * Redistributions of source code must retain the above copyright notice, this 35174 * list of conditions and the following disclaimer. 35175 * * Redistributions in binary form must reproduce the above copyright notice, 35176 * this list of conditions and the following disclaimer in the documentation and/or 35177 * other materials provided with the distribution. 35178 * * Neither the name of Dash Industry Forum nor the names of its 35179 * contributors may be used to endorse or promote products derived from this software 35180 * without specific prior written permission. 35181 * 35182 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 35183 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35184 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35185 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35186 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35187 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35188 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35189 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35190 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35191 * POSSIBILITY OF SUCH DAMAGE. 35192 */ 35193 35194'use strict'; 35195 35196Object.defineProperty(exports, '__esModule', { 35197 value: true 35198}); 35199 35200function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 35201 35202var _reportersDVBReporting = _dereq_(129); 35203 35204var _reportersDVBReporting2 = _interopRequireDefault(_reportersDVBReporting); 35205 35206function ReportingFactory(config) { 35207 35208 var knownReportingSchemeIdUris = { 35209 'urn:dvb:dash:reporting:2014': _reportersDVBReporting2['default'] 35210 }; 35211 35212 var context = this.context; 35213 var log = config.log; 35214 var instance = undefined; 35215 35216 function create(entry, rangeController) { 35217 var reporting = undefined; 35218 35219 try { 35220 reporting = knownReportingSchemeIdUris[entry.schemeIdUri](context).create(); 35221 35222 reporting.initialize(entry, rangeController); 35223 } catch (e) { 35224 reporting = null; 35225 35226 log('ReportingFactory: could not create Reporting with schemeIdUri ' + entry.schemeIdUri + ' (' + e.message + ')'); 35227 } 35228 35229 return reporting; 35230 } 35231 35232 function register(schemeIdUri, moduleName) { 35233 knownReportingSchemeIdUris[schemeIdUri] = moduleName; 35234 } 35235 35236 function unregister(schemeIdUri) { 35237 delete knownReportingSchemeIdUris[schemeIdUri]; 35238 } 35239 35240 instance = { 35241 create: create, 35242 register: register, 35243 unregister: unregister 35244 }; 35245 35246 return instance; 35247} 35248 35249ReportingFactory.__dashjs_factory_name = 'ReportingFactory'; 35250exports['default'] = dashjs.FactoryMaker.getSingletonFactory(ReportingFactory); 35251/* jshint ignore:line */ 35252module.exports = exports['default']; 35253 35254},{"129":129}],129:[function(_dereq_,module,exports){ 35255/** 35256 * The copyright in this software is being made available under the BSD License, 35257 * included below. This software may be subject to other third party and contributor 35258 * rights, including patent rights, and no such rights are granted under this license. 35259 * 35260 * Copyright (c) 2013, Dash Industry Forum. 35261 * All rights reserved. 35262 * 35263 * Redistribution and use in source and binary forms, with or without modification, 35264 * are permitted provided that the following conditions are met: 35265 * * Redistributions of source code must retain the above copyright notice, this 35266 * list of conditions and the following disclaimer. 35267 * * Redistributions in binary form must reproduce the above copyright notice, 35268 * this list of conditions and the following disclaimer in the documentation and/or 35269 * other materials provided with the distribution. 35270 * * Neither the name of Dash Industry Forum nor the names of its 35271 * contributors may be used to endorse or promote products derived from this software 35272 * without specific prior written permission. 35273 * 35274 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 35275 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35276 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35277 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35278 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
35278INCLUDING, BUT 35279 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35280 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35281 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35282 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35283 * POSSIBILITY OF SUCH DAMAGE. 35284 */ 35285 35286'use strict'; 35287 35288Object.defineProperty(exports, '__esModule', { 35289 value: true 35290}); 35291 35292function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 35293 35294var _utilsMetricSerialiser = _dereq_(133); 35295 35296var _utilsMetricSerialiser2 = _interopRequireDefault(_utilsMetricSerialiser); 35297 35298var _utilsRNG = _dereq_(134); 35299 35300var _utilsRNG2 = _interopRequireDefault(_utilsRNG); 35301 35302function DVBReporting(config) { 35303 var instance = undefined; 35304 35305 var context = this.context; 35306 var metricSerialiser = (0, _utilsMetricSerialiser2['default'])(context).getInstance(); 35307 var randomNumberGenerator = (0, _utilsRNG2['default'])(context).getInstance(); 35308 35309 var USE_DRAFT_DVB_SPEC = true; 35310 var isReportingPlayer = false; 35311 var reportingPlayerStatusDecided = false; 35312 var reportingUrl = null; 35313 var rangeController = null; 35314 var allowPendingRequestsToCompleteOnReset = true; 35315 var pendingRequests = []; 35316 35317 var metricsConstants = config.metricsConstants; 35318 35319 function doGetRequest(url, successCB, failureCB) { 35320 var req = new XMLHttpRequest(); 35321 var oncomplete = function oncomplete() { 35322 var reqIndex = pendingRequests.indexOf(req); 35323 35324 if (reqIndex === -1) { 35325 return; 35326 } else { 35327 pendingRequests.splice(reqIndex, 1); 35328 } 35329 35330 if (req.status >= 200 && req.status < 300) { 35331 if (successCB) { 35332 successCB(); 35333 } 35334 } else { 35335 if (failureCB) { 35336 failureCB(); 35337 } 35338 } 35339 }; 35340 35341 pendingRequests.push(req); 35342 35343 try { 35344 req.open('GET', url); 35345 req.onloadend = oncomplete; 35346 req.onerror = oncomplete; 35347 req.send(); 35348 } catch (e) { 35349 req.onerror(); 35350 } 35351 } 35352 35353 function report(type, vos) { 35354 if (!Array.isArray(vos)) { 35355 vos = [vos]; 35356 } 35357 35358 // If the Player is not a reporting Player, then the Player shall 35359 // not report any errors. 35360 // ... In addition to any time restrictions specified by a Range 35361 // element within the Metrics element. 35362 if (isReportingPlayer && rangeController.isEnabled()) { 35363 35364 // This reporting mechanism operates by creating one HTTP GET 35365 // request for every entry in the top level list of the metric. 35366 vos.forEach(function (vo) { 35367 var url = metricSerialiser.serialise(vo); 35368 35369 // this has been proposed for errata 35370 if (USE_DRAFT_DVB_SPEC && type !== metricsConstants.DVB_ERRORS) { 35371 url = 'metricname=' + type + '&' + url; 35372 } 35373 35374 // Take the value of the @reportingUrl attribute, append a 35375 // question mark ('?') character and then append the string 35376 // created in the previous step. 35377 url = reportingUrl + '?' + url; 35378 35379 // Make an HTTP GET request to the URL contained within the 35380 // string created in the previous step. 35381 doGetRequest(url, null, function () { 35382 // If the Player is unable to make the report, for 35383 // example because the @reportingUrl is invalid, the 35384 // host cannot be reached, or an HTTP status code other 35385 // than one in the 200 series is received, the Player 35386 // shall cease being a reporting Player for the 35387 // duration of the MPD. 35388 isReportingPlayer = false; 35389 }); 35390 }); 35391 } 35392 } 35393 35394 function initialize(entry, rc) { 35395 var probability = undefined; 35396 35397 rangeController = rc; 35398
35399 reportingUrl = entry['dvb:reportingUrl']; 35400 35401 // If a required attribute is missing, the Reporting descriptor may 35402 // be ignored by the Player 35403 if (!reportingUrl) { 35404 throw new Error('required parameter missing (dvb:reportingUrl)'); 35405 } 35406 35407 // A Player's status, as a reporting Player or not, shall remain 35408 // static for the duration of the MPD, regardless of MPD updates. 35409 // (i.e. only calling reset (or failure) changes this state) 35410 if (!reportingPlayerStatusDecided) { 35411 // NOTE: DVB spec has a typo where it incorrectly references the 35412 // priority attribute, which should be probability 35413 probability = entry['dvb:probability'] || entry['dvb:priority'] || 0; 35414 // If the @priority attribute is set to 1000, it shall be a reporting Player. 35415 // If the @priority attribute is missing, the Player shall not be a reporting Player. 35416 // For any other value of the @probability attribute, it shall decide at random whether to be a 35417 // reporting Player, such that the probability of being one is @probability/1000. 35418 if (probability && (probability === 1000 || probability / 1000 >= randomNumberGenerator.random())) { 35419 isReportingPlayer = true; 35420 } 35421 35422 reportingPlayerStatusDecided = true; 35423 } 35424 } 35425 35426 function reset() { 35427 if (!allowPendingRequestsToCompleteOnReset) { 35428 pendingRequests.forEach(function (req) { 35429 return req.abort(); 35430 }); 35431 pendingRequests = []; 35432 } 35433 35434 reportingPlayerStatusDecided = false; 35435 isReportingPlayer = false; 35436 reportingUrl = null; 35437 rangeController = null; 35438 } 35439 35440 instance = { 35441 report: report, 35442 initialize: initialize, 35443 reset: reset 35444 }; 35445 35446 return instance; 35447} 35448 35449DVBReporting.__dashjs_factory_name = 'DVBReporting'; 35450exports['default'] = dashjs.FactoryMaker.getClassFactory(DVBReporting); 35451/* jshint ignore:line */ 35452module.exports = exports['default']; 35453 35454},{"133":133,"134":134}],130:[function(_dereq_,module,exports){ 35455/** 35456 * The copyright in this software is being made available under the BSD License, 35457 * included below. This software may be subject to other third party and contributor 35458 * rights, including patent rights, and no such rights are granted under this license. 35459 * 35460 * Copyright (c) 2013, Dash Industry Forum. 35461 * All rights reserved. 35462 * 35463 * Redistribution and use in source and binary forms, with or without modification, 35464 * are permitted provided that the following conditions are met: 35465 * * Redistributions of source code must retain the above copyright notice, this 35466 * list of conditions and the following disclaimer. 35467 * * Redistributions in binary form must reproduce the above copyright notice, 35468 * this list of conditions and the following disclaimer in the documentation and/or 35469 * other materials provided with the distribution. 35470 * * Neither the name of Dash Industry Forum nor the names of its 35471 * contributors may be used to endorse or promote products derived from this software 35472 * without specific prior written permission. 35473 * 35474 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 35475 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35476 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35477 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35478 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35479 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35480 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35481 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35482 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35483 * POSSIBILITY OF SUCH DAMAGE. 35484 */ 35485 35486'use strict'; 35487 35488Object.defineProperty(exports, '__esModule', { 35489 value: true 35490}); 35491 35492function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 35493 35494var _voDVBErrors = _dereq_(135); 35495 35496var _voDVBErrors2 = _interopRequireDefault(_voDVBErrors); 35497 35498var _MetricsReportingEvents = _dereq_(117); 35499 35500var _MetricsReportingEvents2 = _interopRequireDefault(_MetricsReportingEvents); 35501 35502function DVBErrorsTranslator(config) { 35503 35504 var instance = undefined; 35505 var eventBus = config.eventBus; 35506 var metricModel = config.metricsModel; 35507 var mpd = undefined; 35508 35509 var metricsConstants = config.metricsConstants; 35510 //MediaPlayerEvents have been added to Events in MediaPlayer class 35511 var Events = config.events; 35512 35513 function report(vo) { 35514 var o = new _voDVBErrors2['default'](); 35515 35516 if (!mpd) { 35517 return; 35518 } 35519 35520 for (var key in vo) { 35521 if (vo.hasOwnProperty(key)) { 35522 o[key] = vo[key]; 35523 } 35524 } 35525 35526 if (!o.mpdurl) { 35527 o.mpdurl = mpd.originalUrl || mpd.url; 35528 } 35529 35530 if (!o.terror) { 35531 o.terror = new Date(); 35532 } 35533 35534 metricModel.addDVBErrors(o); 35535 } 35536 35537 function onManifestUpdate(e) { 35538 if (e.error) { 35539 return; 35540 } 35541 35542 mpd = e.manifest; 35543 } 35544 35545 function onServiceLocationChanged(e) { 35546 report({ 35547 errorcode: _voDVBErrors2['default'].BASE_URL_CHANGED, 35548 servicelocation: e.entry 35549 }); 35550 } 35551 35552 function onBecameReporter() { 35553 report({ 35554 errorcode: _voDVBErrors2['default'].BECAME_REPORTER 35555 }); 35556 } 35557 35558 function handleHttpMetric(vo) { 35559 if (vo.responsecode === 0 || // connection failure - unknown 35560 vo.responsecode >= 400 || // HTTP error status code 35561 vo.responsecode < 100 || // unknown status codes 35562 vo.responsecode >= 600) { 35563 // unknown status codes 35564 report({ 35565 errorcode: vo.responsecode || _voDVBErrors2['default'].CONNECTION_ERROR, 35566 url: vo.url, 35567 terror: vo.tresponse, 35568 servicelocation: vo._serviceLocation 35569 }); 35570 } 35571 } 35572 35573 function onMetricEvent(e) { 35574 switch (e.metric) { 35575 case metricsConstants.HTTP_REQUEST: 35576 handleHttpMetric(e.value); 35577 break; 35578 default: 35579 break; 35580 } 35581 } 35582 35583 function onPlaybackError(e) { 35584 var reason = e.error ? e.error.code : 0; 35585 var errorcode = undefined; 35586 35587 switch (reason) { 35588 case MediaError.MEDIA_ERR_NETWORK: 35589 errorcode = _voDVBErrors2['default'].CONNECTION_ERROR; 35590 break; 35591 case MediaError.MEDIA_ERR_DECODE: 35592 errorcode = _voDVBErrors2['default'].CORRUPT_MEDIA_OTHER;
vendor: 4,729 bytes, lines 35593-35716
35593 break; 35594 default: 35595 return; 35596 } 35597 35598 report({ 35599 errorcode: errorcode 35600 }); 35601 } 35602 35603 function initialise() { 35604 eventBus.on(Events.MANIFEST_UPDATED, onManifestUpdate, instance); 35605 eventBus.on(Events.SERVICE_LOCATION_BLACKLIST_CHANGED, onServiceLocationChanged, instance); 35606 eventBus.on(Events.METRIC_ADDED, onMetricEvent, instance); 35607 eventBus.on(Events.METRIC_UPDATED, onMetricEvent, instance); 35608 eventBus.on(Events.PLAYBACK_ERROR, onPlaybackError, instance); 35609 eventBus.on(_MetricsReportingEvents2['default'].BECAME_REPORTING_PLAYER, onBecameReporter, instance); 35610 } 35611 35612 function reset() { 35613 eventBus.off(Events.MANIFEST_UPDATED, onManifestUpdate, instance); 35614 eventBus.off(Events.SERVICE_LOCATION_BLACKLIST_CHANGED, onServiceLocationChanged, instance); 35615 eventBus.off(Events.METRIC_ADDED, onMetricEvent, instance); 35616 eventBus.off(Events.METRIC_UPDATED, onMetricEvent, instance); 35617 eventBus.off(Events.PLAYBACK_ERROR, onPlaybackError, instance); 35618 eventBus.off(_MetricsReportingEvents2['default'].BECAME_REPORTING_PLAYER, onBecameReporter, instance); 35619 } 35620 35621 instance = { 35622 initialise: initialise, 35623 reset: reset 35624 }; 35625 35626 initialise(); 35627 35628 return instance; 35629} 35630 35631DVBErrorsTranslator.__dashjs_factory_name = 'DVBErrorsTranslator'; 35632exports['default'] = dashjs.FactoryMaker.getSingletonFactory(DVBErrorsTranslator); 35633/* jshint ignore:line */ 35634module.exports = exports['default']; 35635 35636},{"117":117,"135":135}],131:[function(_dereq_,module,exports){ 35637/** 35638 * The copyright in this software is being made available under the BSD License, 35639 * included below. This software may be subject to other third party and contributor 35640 * rights, including patent rights, and no such rights are granted under this license. 35641 * 35642 * Copyright (c) 2013, Dash Industry Forum. 35643 * All rights reserved. 35644 * 35645 * Redistribution and use in source and binary forms, with or without modification, 35646 * are permitted provided that the following conditions are met: 35647 * * Redistributions of source code must retain the above copyright notice, this 35648 * list of conditions and the following disclaimer. 35649 * * Redistributions in binary form must reproduce the above copyright notice, 35650 * this list of conditions and the following disclaimer in the documentation and/or 35651 * other materials provided with the distribution. 35652 * * Neither the name of Dash Industry Forum nor the names of its 35653 * contributors may be used to endorse or promote products derived from this software 35654 * without specific prior written permission. 35655 * 35656 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 35657 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35658 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35659 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35660 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35661 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35662 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35663 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35664 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35665 * POSSIBILITY OF SUCH DAMAGE. 35666 */ 35667 35668'use strict'; 35669 35670Object.defineProperty(exports, '__esModule', { 35671 value: true 35672}); 35673function HandlerHelpers() { 35674 return { 35675 reconstructFullMetricName: function reconstructFullMetricName(key, n, type) { 35676 var mn = key; 35677 35678 if (n) { 35679 mn += '(' + n; 35680 35681 if (type && type.length) { 35682 mn += ',' + type; 35683 } 35684 35685 mn += ')'; 35686 } 35687 35688 return mn; 35689 }, 35690 35691 validateN: function validateN(n_ms) { 35692 if (!n_ms) { 35693 throw new Error('missing n'); 35694 } 35695 35696 if (isNaN(n_ms)) { 35697 throw new Error('n is NaN'); 35698 } 35699 35700 // n is a positive integer is defined to refer to the metric 35701 // in which the buffer level is recorded every n ms. 35702 if (n_ms < 0) { 35703 throw new Error('n must be positive'); 35704 } 35705 35706 return n_ms; 35707 } 35708 }; 35709} 35710 35711HandlerHelpers.__dashjs_factory_name = 'HandlerHelpers'; 35712exports['default'] = dashjs.FactoryMaker.getSingletonFactory(HandlerHelpers); 35713/* jshint ignore:line */ 35714module.exports = exports['default']; 35715 35716},{}
35716],132:[function(_dereq_,module,exports){ 35717'use strict'; 35718 35719Object.defineProperty(exports, '__esModule', { 35720 value: true 35721}); 35722 35723function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 35724 35725var _voMetrics = _dereq_(136); 35726 35727var _voMetrics2 = _interopRequireDefault(_voMetrics); 35728 35729var _voRange = _dereq_(137); 35730 35731var _voRange2 = _interopRequireDefault(_voRange); 35732 35733var _voReporting = _dereq_(138); 35734 35735var _voReporting2 = _interopRequireDefault(_voReporting); 35736 35737function ManifestParsing(config) { 35738 var instance = undefined; 35739 var dashManifestModel = config.dashManifestModel; 35740 var constants = config.constants; 35741 35742 function getMetricsRangeStartTime(manifest, dynamic, range) { 35743 var mpd = dashManifestModel.getMpd(manifest); 35744 var voPeriods; 35745 var presentationStartTime = 0; 35746 var reportingStartTime; 35747 35748 if (dynamic) { 35749 // For services with MPD@type='dynamic', the start time is 35750 // indicated in wall clock time by adding the value of this 35751 // attribute to the value of the MPD@availabilityStartTime 35752 // attribute. 35753 presentationStartTime = mpd.availabilityStartTime.getTime() / 1000; 35754 } else { 35755 // For services with MPD@type='static', the start time is indicated 35756 // in Media Presentation time and is relative to the PeriodStart 35757 // time of the first Period in this MPD. 35758 voPeriods = this.getRegularPeriods(mpd); 35759 35760 if (voPeriods.length) { 35761 presentationStartTime = voPeriods[0].start; 35762 } 35763 } 35764 35765 // When not present, DASH Metrics collection is 35766 // requested from the beginning of content 35767 // consumption. 35768 reportingStartTime = presentationStartTime; 35769 35770 if (range && range.hasOwnProperty(constants.START_TIME)) { 35771 reportingStartTime += range.starttime; 35772 } 35773 35774 return reportingStartTime; 35775 } 35776 35777 function getMetrics(manifest) { 35778 var metrics = []; 35779 35780 if (manifest.Metrics_asArray) { 35781 manifest.Metrics_asArray.forEach(function (metric) { 35782 var metricEntry = new _voMetrics2['default'](); 35783 var isDynamic = dashManifestModel.getIsDynamic(manifest); 35784 35785 if (metric.hasOwnProperty('metrics')) { 35786 metricEntry.metrics = metric.metrics; 35787 } else { 35788 //console.log("Invalid Metrics. metrics must be set. Ignoring."); 35789 return; 35790 } 35791 35792 if (metric.Range_asArray) { 35793 metric.Range_asArray.forEach(function (range) { 35794 var rangeEntry = new _voRange2['default'](); 35795 35796 rangeEntry.starttime = getMetricsRangeStartTime(manifest, isDynamic, range); 35797 35798 if (range.hasOwnProperty('duration')) { 35799 rangeEntry.duration = range.duration; 35800 } else { 35801 // if not present, the value is identical to the 35802 // Media Presentation duration. 35803 rangeEntry.duration = dashManifestModel.getDuration(manifest); 35804 } 35805 35806 rangeEntry._useWallClockTime = isDynamic; 35807 35808 metricEntry.Range.push(rangeEntry); 35809 }); 35810 } 35811 35812 if (metric.Reporting_asArray) { 35813 metric.Reporting_asArray.forEach(function (reporting) { 35814 var reportingEntry = new _voReporting2['default'](); 35815 35816 if (reporting.hasOwnProperty(constants.SCHEME_ID_URI)) { 35817 reportingEntry.schemeIdUri = reporting.schemeIdUri; 35818 } else { 35819 // Invalid Reporting. schemeIdUri must be set. Ignore. 35820 return; 35821 } 35822 35823 for (var prop in reporting) { 35824 if (reporting.hasOwnProperty(prop)) { 35825 reportingEntry[prop] = reporting[prop]; 35826 } 35827 } 35828 35829 metricEntry.Reporting.push(reportingEntry); 35830 }); 35831 } else { 35832 // Invalid Metrics. At least one reporting must be present. Ignore 35833 return; 35834 } 35835 35836 metrics.push(metricEntry); 35837 }); 35838 } 35839 35840 return metrics; 35841 } 35842 35843 instance = { 35844 getMetrics: getMetrics 35845 }; 35846 35847 return instance; 35848} 35849 35850ManifestParsing.__dashjs_factory_name = 'ManifestParsing'; 35851exports['default'] = dashjs.FactoryMaker.getSingletonFactory(ManifestParsing); 35852/* jshint ignore:line */ 35853module.exports = exports['default']; 35854 35855},{"136":136,"137":137,"138":138}],133:[function(_dereq_,module,exports){ 35856/** 35857 * The copyright in this software is being made available under the BSD License, 35858 * included below. This software may be subject to other third party and contributor 35859 * rights, including patent rights, and no such rights are granted under this license. 35860 * 35861 * Copyright (c) 2013, Dash Industry Forum. 35862 * All rights reserved. 35863 * 35864 * Redistribution and use in source and binary forms, with or without modification, 35865 * are permitted provided that the following conditions are met: 35866 * * Redistributions of source code must retain the above copyright notice, this 35867 * list of conditions and the following disclaimer. 35868 * * Redistributions in binary form must reproduce the above copyright notice, 35869 * this list of conditions and the following disclaimer in the documentation and/or 35870 * other materials provided with the distribution. 35871 * * Neither the name of Dash Industry Forum nor the names of its 35872 * contributors may be used to endorse or promote products derived from this software 35873 * without specific prior written permission. 35874 * 35875 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 35876 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35877 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35878 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35879 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
35879INCLUDING, BUT 35880 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35881 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35882 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35883 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35884 * POSSIBILITY OF SUCH DAMAGE. 35885 */ 35886 35887'use strict'; 35888 35889Object.defineProperty(exports, '__esModule', { 35890 value: true 35891}); 35892function MetricSerialiser() { 35893 35894 // For each entry in the top level list within the metric (in the case 35895 // of the DVBErrors metric each entry corresponds to an "error event" 35896 // described in clause 10.8.4) the Player shall: 35897 function serialise(metric) { 35898 var pairs = []; 35899 var obj = []; 35900 var key = undefined, 35901 value = undefined; 35902 35903 // Take each (key, value) pair from the metric entry and create a 35904 // string consisting of the name of the key, followed by an equals 35905 // ('=') character, followed by the string representation of the 35906 // value. The string representation of the value is created based 35907 // on the type of the value following the instructions in Table 22. 35908 for (key in metric) { 35909 if (metric.hasOwnProperty(key) && key.indexOf('_') !== 0) { 35910 value = metric[key]; 35911 35912 // we want to ensure that keys still end up in the report 35913 // even if there is no value 35914 if (value === undefined || value === null) { 35915 value = ''; 35916 } 35917 35918 // DVB A168 10.12.4 Table 22 35919 if (Array.isArray(value)) { 35920 // if trace or similar is null, do not include in output 35921 if (!value.length) { 35922 continue; 35923 } 35924 35925 obj = []; 35926 35927 value.forEach(function (v) { 35928 var isBuiltIn = Object.prototype.toString.call(v).slice(8, -1) !== 'Object'; 35929 35930 obj.push(isBuiltIn ? v : serialise(v)); 35931 }); 35932 35933 value = obj.map(encodeURIComponent).join(','); 35934 } else if (typeof value === 'string') { 35935 value = encodeURIComponent(value); 35936 } else if (value instanceof Date) { 35937 value = value.toISOString(); 35938 } else if (typeof value === 'number') { 35939 value = Math.round(value); 35940 } 35941 35942 pairs.push(key + '=' + value); 35943 } 35944 } 35945 35946 // Concatenate the strings created in the previous step with an 35947 // ampersand ('&') character between each one. 35948 return pairs.join('&'); 35949 } 35950 35951 return { 35952 serialise: serialise 35953 }; 35954} 35955 35956MetricSerialiser.__dashjs_factory_name = 'MetricSerialiser'; 35957exports['default'] = dashjs.FactoryMaker.getSingletonFactory(MetricSerialiser); 35958/* jshint ignore:line */ 35959module.exports = exports['default']; 35960 35961},{}],134:[function(_dereq_,module,exports){ 35962/** 35963 * The copyright in this software is being made available under the BSD License, 35964 * included below. This software may be subject to other third party and contributor 35965 * rights, including patent rights, and no such rights are granted under this license. 35966 * 35967 * Copyright (c) 2013, Dash Industry Forum. 35968 * All rights reserved. 35969 * 35970 * Redistribution and use in source and binary forms, with or without modification, 35971 * are permitted provided that the following conditions are met: 35972 * * Redistributions of source code must retain the above copyright notice, this 35973 * list of conditions and the following disclaimer. 35974 * * Redistributions in binary form must reproduce the above copyright notice, 35975 * this list of conditions and the following disclaimer in the documentation and/or 35976 * other materials provided with the distribution. 35977 * * Neither the name of Dash Industry Forum nor the names of its 35978 * contributors may be used to endorse or promote products derived from this software 35979 * without specific prior written permission. 35980 * 35981 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 35982 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35983 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35984 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35985 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
35985INCLUDING, BUT 35986 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35987 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35988 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35989 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35990 * POSSIBILITY OF SUCH DAMAGE. 35991 */ 35992 35993'use strict'; 35994 35995Object.defineProperty(exports, '__esModule', { 35996 value: true 35997}); 35998function RNG() { 35999 36000 // check whether secure random numbers are available. if not, revert to 36001 // using Math.random 36002 var crypto = window.crypto || window.msCrypto; 36003 36004 // could just as easily use any other array type by changing line below 36005 var ArrayType = Uint32Array; 36006 var MAX_VALUE = Math.pow(2, ArrayType.BYTES_PER_ELEMENT * 8) - 1; 36007 36008 // currently there is only one client for this code, and that only uses 36009 // a single random number per initialisation. may want to increase this 36010 // number if more consumers in the future 36011 var NUM_RANDOM_NUMBERS = 10; 36012 36013 var randomNumbers = undefined, 36014 index = undefined, 36015 instance = undefined; 36016 36017 function initialise() { 36018 if (crypto) { 36019 if (!randomNumbers) { 36020 randomNumbers = new ArrayType(NUM_RANDOM_NUMBERS); 36021 } 36022 crypto.getRandomValues(randomNumbers); 36023 index = 0; 36024 } 36025 } 36026 36027 function rand(min, max) { 36028 var r = undefined; 36029 36030 if (!min) { 36031 min = 0; 36032 } 36033 36034 if (!max) { 36035 max = 1; 36036 } 36037 36038 if (crypto) { 36039 if (index === randomNumbers.length) { 36040 initialise(); 36041 } 36042 36043 r = randomNumbers[index] / MAX_VALUE; 36044 index += 1; 36045 } else { 36046 r = Math.random(); 36047 } 36048 36049 return r * (max - min) + min; 36050 } 36051 36052 instance = { 36053 random: rand 36054 }; 36055 36056 initialise(); 36057 36058 return instance; 36059} 36060 36061RNG.__dashjs_factory_name = 'RNG'; 36062exports['default'] = dashjs.FactoryMaker.getSingletonFactory(RNG); 36063/* jshint ignore:line */ 36064module.exports = exports['default']; 36065 36066},{}],135:[function(_dereq_,module,exports){ 36067/** 36068 * The copyright in this software is being made available under the BSD License, 36069 * included below. This software may be subject to other third party and contributor 36070 * rights, including patent rights, and no such rights are granted under this license. 36071 * 36072 * Copyright (c) 2013, Dash Industry Forum. 36073 * All rights reserved. 36074 * 36075 * Redistribution and use in source and binary forms, with or without modification, 36076 * are permitted provided that the following conditions are met: 36077 * * Redistributions of source code must retain the above copyright notice, this 36078 * list of conditions and the following disclaimer. 36079 * * Redistributions in binary form must reproduce the above copyright notice, 36080 * this list of conditions and the following disclaimer in the documentation and/or 36081 * other materials provided with the distribution. 36082 * * Neither the name of Dash Industry Forum nor the names of its 36083 * contributors may be used to endorse or promote products derived from this software 36084 * without specific prior written permission. 36085 * 36086 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 36087 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36088 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36089 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36090 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36091 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36092 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36093 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36094 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36095 * POSSIBILITY OF SUCH DAMAGE. 36096 */ 36097/** 36098 * @class 36099 * @ignore 36100 */ 36101'use strict'; 36102 36103Object.defineProperty(exports, '__esModule', { 36104 value: true 36105}); 36106 36107function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 36108 36109var DVBErrors = function DVBErrors() { 36110 _classCallCheck(this, DVBErrors); 36111 36112 this.mpdurl = null; 36113 // String - Absolute URL from which the MPD was originally 36114 // retrieved (MPD updates will not change this value). 36115 36116 this.errorcode = null; 36117 // String - The value of errorcode depends upon the type 36118 // of error being reported. For an error listed in the
36119 // ErrorType column below the value is as described in the 36120 // Value column. 36121 // 36122 // ErrorType Value 36123 // --------- ----- 36124 // HTTP error status code HTTP status code 36125 // Unknown HTTP status code HTTP status code 36126 // SSL connection failed "SSL" followed by SSL alert value 36127 // DNS resolution failed "C00" 36128 // Host unreachable "C01" 36129 // Connection refused "C02" 36130 // Connection error – Not otherwise specified "C03" 36131 // Corrupt media – ISO BMFF container cannot be parsed "M00" 36132 // Corrupt media – Not otherwise specified "M01" 36133 // Changing Base URL in use due to errors "F00" 36134 // Becoming an error reporting Player "S00" 36135 36136 this.terror = null; 36137 // Real-Time - Date and time at which error occurred in UTC, 36138 // formatted as a combined date and time according to ISO 8601. 36139 36140 this.url = null; 36141 // String - Absolute URL from which data was being requested 36142 // when this error occurred. If the error report is in relation 36143 // to corrupt media or changing BaseURL, this may be a null 36144 // string if the URL from which the media was obtained or 36145 // which led to the change of BaseURL is no longer known. 36146 36147 this.ipaddress = null; 36148 // String - IP Address which the host name in "url" resolved to. 36149 // If the error report is in relation to corrupt media or 36150 // changing BaseURL, this may be a null string if the URL 36151 // from which the media was obtained or which led to the 36152 // change of BaseURL is no longer known. 36153 36154 this.servicelocation = null; 36155 // String - The value of the serviceLocation field in the 36156 // BaseURL being used. In the event of this report indicating 36157 // a change of BaseURL this is the value from the BaseURL 36158 // being moved from. 36159}; 36160 36161DVBErrors.SSL_CONNECTION_FAILED_PREFIX = 'SSL'; 36162DVBErrors.DNS_RESOLUTION_FAILED = 'C00'; 36163DVBErrors.HOST_UNREACHABLE = 'C01'; 36164DVBErrors.CONNECTION_REFUSED = 'C02'; 36165DVBErrors.CONNECTION_ERROR = 'C03'; 36166DVBErrors.CORRUPT_MEDIA_ISOBMFF = 'M00'; 36167DVBErrors.CORRUPT_MEDIA_OTHER = 'M01'; 36168DVBErrors.BASE_URL_CHANGED = 'F00'; 36169DVBErrors.BECAME_REPORTER = 'S00'; 36170 36171exports['default'] = DVBErrors; 36172module.exports = exports['default']; 36173 36174},{}],136:[function(_dereq_,module,exports){ 36175/** 36176 * The copyright in this software is being made available under the BSD License, 36177 * included below. This software may be subject to other third party and contributor 36178 * rights, including patent rights, and no such rights are granted under this license. 36179 * 36180 * Copyright (c) 2013, Dash Industry Forum. 36181 * All rights reserved. 36182 * 36183 * Redistribution and use in source and binary forms, with or without modification, 36184 * are permitted provided that the following conditions are met: 36185 * * Redistributions of source code must retain the above copyright notice, this 36186 * list of conditions and the following disclaimer. 36187 * * Redistributions in binary form must reproduce the above copyright notice, 36188 * this list of conditions and the following disclaimer in the documentation and/or 36189 * other materials provided with the distribution. 36190 * * Neither the name of Dash Industry Forum nor the names of its 36191 * contributors may be used to endorse or promote products derived from this software 36192 * without specific prior written permission. 36193 * 36194 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 36195 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36196 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36197 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36198 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
36198INCLUDING, BUT 36199 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36200 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36201 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36202 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36203 * POSSIBILITY OF SUCH DAMAGE. 36204 */ 36205/** 36206 * @class 36207 * @ignore 36208 */ 36209'use strict'; 36210 36211Object.defineProperty(exports, '__esModule', { 36212 value: true 36213}); 36214 36215function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 36216 36217var Metrics = function Metrics() { 36218 _classCallCheck(this, Metrics); 36219 36220 this.metrics = ''; 36221 this.Range = []; 36222 this.Reporting = []; 36223}; 36224 36225exports['default'] = Metrics; 36226module.exports = exports['default']; 36227 36228},{}],137:[function(_dereq_,module,exports){ 36229/** 36230 * The copyright in this software is being made available under the BSD License, 36231 * included below. This software may be subject to other third party and contributor 36232 * rights, including patent rights, and no such rights are granted under this license. 36233 * 36234 * Copyright (c) 2013, Dash Industry Forum. 36235 * All rights reserved. 36236 * 36237 * Redistribution and use in source and binary forms, with or without modification, 36238 * are permitted provided that the following conditions are met: 36239 * * Redistributions of source code must retain the above copyright notice, this 36240 * list of conditions and the following disclaimer. 36241 * * Redistributions in binary form must reproduce the above copyright notice, 36242 * this list of conditions and the following disclaimer in the documentation and/or 36243 * other materials provided with the distribution. 36244 * * Neither the name of Dash Industry Forum nor the names of its 36245 * contributors may be used to endorse or promote products derived from this software 36246 * without specific prior written permission. 36247 * 36248 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 36249 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36250 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36251 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36252 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36253 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36254 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36255 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36256 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36257 * POSSIBILITY OF SUCH DAMAGE. 36258 */ 36259/** 36260 * @class 36261 * @ignore 36262 */ 36263"use strict"; 36264 36265Object.defineProperty(exports, "__esModule", { 36266 value: true 36267}); 36268 36269function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 36270 36271var Range = function Range() { 36272 _classCallCheck(this, Range); 36273 36274 // as defined in ISO23009-1 36275 this.starttime = 0; 36276 this.duration = Infinity; 36277 36278 // for internal use 36279 this._useWallClockTime = false; 36280}; 36281 36282exports["default"] = Range; 36283module.exports = exports["default"]; 36284 36285},{}],138:[function(_dereq_,module,exports){ 36286/** 36287 * The copyright in this software is being made available under the BSD License, 36288 * included below. This software may be subject to other third party and contributor 36289 * rights, including patent rights, and no such rights are granted under this license. 36290 * 36291 * Copyright (c) 2013, Dash Industry Forum. 36292 * All rights reserved. 36293 * 36294 * Redistribution and use in source and binary forms, with or without modification, 36295 * are permitted provided that the following conditions are met: 36296 * * Redistributions of source code must retain the above copyright notice, this 36297 * list of conditions and the following disclaimer. 36298 * * Redistributions in binary form must reproduce the above copyright notice, 36299 * this list of conditions and the following disclaimer in the documentation and/or 36300 * other materials provided with the distribution. 36301 * * Neither the name of Dash Industry Forum nor the names of its 36302 * contributors may be used to endorse or promote products derived from this software 36303 * without specific prior written permission. 36304 * 36305 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 36306 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36307 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36308 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36309 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
36309INCLUDING, BUT 36310 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36311 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36312 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36313 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36314 * POSSIBILITY OF SUCH DAMAGE. 36315 */ 36316/** 36317 * @class 36318 * @ignore 36319 */ 36320'use strict'; 36321 36322Object.defineProperty(exports, '__esModule', { 36323 value: true 36324}); 36325 36326function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 36327 36328var Reporting = function Reporting() { 36329 _classCallCheck(this, Reporting); 36330 36331 // Reporting is a DescriptorType and doesn't have any additional fields 36332 this.schemeIdUri = ''; 36333 this.value = ''; 36334}; 36335 36336exports['default'] = Reporting; 36337module.exports = exports['default']; 36338 36339},{}],139:[function(_dereq_,module,exports){ 36340/** 36341 * The copyright in this software is being made available under the BSD License, 36342 * included below. This software may be subject to other third party and contributor 36343 * rights, including patent rights, and no such rights are granted under this license. 36344 * 36345 * Copyright (c) 2013, Dash Industry Forum. 36346 * All rights reserved. 36347 * 36348 * Redistribution and use in source and binary forms, with or without modification, 36349 * are permitted provided that the following conditions are met: 36350 * * Redistributions of source code must retain the above copyright notice, this 36351 * list of conditions and the following disclaimer. 36352 * * Redistributions in binary form must reproduce the above copyright notice, 36353 * this list of conditions and the following disclaimer in the documentation and/or 36354 * other materials provided with the distribution. 36355 * * Neither the name of Dash Industry Forum nor the names of its 36356 * contributors may be used to endorse or promote products derived from this software 36357 * without specific prior written permission. 36358 * 36359 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 36360 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36361 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36362 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36363 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36364 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36365 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36366 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36367 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36368 * POSSIBILITY OF SUCH DAMAGE. 36369 */ 36370 36371'use strict'; 36372 36373Object.defineProperty(exports, '__esModule', { 36374 value: true 36375}); 36376 36377function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 36378 36379function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 36380 36381var _utilsObjectUtils = _dereq_(199); 36382 36383var _utilsObjectUtils2 = _interopRequireDefault(_utilsObjectUtils); 36384 36385var _coreFactoryMaker = _dereq_(51); 36386 36387var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 36388 36389var DEFAULT_INDEX = NaN; 36390 36391var Node = function Node(_baseUrls, _selectedIdx) { 36392 _classCallCheck(this, Node); 36393 36394 this.data = { 36395 baseUrls: _baseUrls || null, 36396 selectedIdx: _selectedIdx || DEFAULT_INDEX 36397 }; 36398 this.children = []; 36399}; 36400 36401function BaseURLTreeModel() { 36402 36403 var instance = undefined; 36404 var root = undefined; 36405 var dashManifestModel = undefined; 36406 36407 var context = this.context; 36408 var objectUtils = (0, _utilsObjectUtils2['default'])(context).getInstance(); 36409 36410 function setup() { 36411 reset(); 36412 } 36413 36414 function setConfig(config) { 36415 if (config.dashManifestModel) { 36416 dashManifestModel = config.dashManifestModel; 36417 } 36418 } 36419 36420 function updateChildData(node, index, element) { 36421 var baseUrls = dashManifestModel.getBaseURLsFromElement(element); 36422 36423 if (!node[index]) { 36424 node[index] = new Node(baseUrls); 36425 } else { 36426 if (!objectUtils.areEqual(baseUrls, node[index].data.baseUrls)
vendor: 1,548 bytes, lines 36426-36471
36426) { 36427 node[index].data.baseUrls = baseUrls; 36428 node[index].data.selectedIdx = DEFAULT_INDEX; 36429 } 36430 } 36431 } 36432 36433 function getBaseURLCollectionsFromManifest(manifest) { 36434 var baseUrls = dashManifestModel.getBaseURLsFromElement(manifest); 36435 36436 if (!objectUtils.areEqual(baseUrls, root.data.baseUrls)) { 36437 root.data.baseUrls = baseUrls; 36438 root.data.selectedIdx = DEFAULT_INDEX; 36439 } 36440 36441 if (manifest.Period_asArray) { 36442 manifest.Period_asArray.forEach(function (p, pi) { 36443 updateChildData(root.children, pi, p); 36444 36445 if (p.AdaptationSet_asArray) { 36446 p.AdaptationSet_asArray.forEach(function (a, ai) { 36447 updateChildData(root.children[pi].children, ai, a); 36448 36449 if (a.Representation_asArray) { 36450 a.Representation_asArray.sort(dashManifestModel.getRepresentationSortFunction()).forEach(function (r, ri) { 36451 updateChildData(root.children[pi].children[ai].children, ri, r); 36452 }); 36453 } 36454 }); 36455 } 36456 }); 36457 } 36458 } 36459 36460 function walk(callback, node) { 36461 var target = node || root; 36462 36463 callback(target.data); 36464 36465 if (target.children) { 36466 target.children.forEach(function (child) { 36467 return walk(callback, child); 36468 }); 36469 } 36470 } 36471
36472 function invalidateSelectedIndexes(serviceLocation) { 36473 walk(function (data) { 36474 if (!isNaN(data.selectedIdx)) { 36475 if (serviceLocation === data.baseUrls[data.selectedIdx].serviceLocation) { 36476 data.selectedIdx = DEFAULT_INDEX; 36477 } 36478 } 36479 }); 36480 } 36481 36482 function update(manifest) { 36483 getBaseURLCollectionsFromManifest(manifest); 36484 } 36485 36486 function reset() { 36487 root = new Node(); 36488 } 36489 36490 function getForPath(path) { 36491 var target = root; 36492 var nodes = [target.data]; 36493 36494 path.forEach(function (p) { 36495 target = target.children[p]; 36496 36497 if (target) { 36498 nodes.push(target.data); 36499 } 36500 }); 36501 36502 return nodes.filter(function (n) { 36503 return n.baseUrls.length; 36504 }); 36505 } 36506 36507 instance = { 36508 reset: reset, 36509 update: update, 36510 getForPath: getForPath, 36511 invalidateSelectedIndexes: invalidateSelectedIndexes, 36512 setConfig: setConfig 36513 }; 36514 36515 setup(); 36516 36517 return instance; 36518} 36519 36520BaseURLTreeModel.__dashjs_factory_name = 'BaseURLTreeModel'; 36521exports['default'] = _coreFactoryMaker2['default'].getClassFactory(BaseURLTreeModel); 36522module.exports = exports['default']; 36523 36524},{"199":199,"51":51}],140:[function(_dereq_,module,exports){ 36525/** 36526 * The copyright in this software is being made available under the BSD License, 36527 * included below. This software may be subject to other third party and contributor 36528 * rights, including patent rights, and no such rights are granted under this license. 36529 * 36530 * Copyright (c) 2013, Dash Industry Forum. 36531 * All rights reserved. 36532 * 36533 * Redistribution and use in source and binary forms, with or without modification, 36534 * are permitted provided that the following conditions are met: 36535 * * Redistributions of source code must retain the above copyright notice, this 36536 * list of conditions and the following disclaimer. 36537 * * Redistributions in binary form must reproduce the above copyright notice, 36538 * this list of conditions and the following disclaimer in the documentation and/or 36539 * other materials provided with the distribution. 36540 * * Neither the name of Dash Industry Forum nor the names of its 36541 * contributors may be used to endorse or promote products derived from this software 36542 * without specific prior written permission. 36543 * 36544 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 36545 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36546 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36547 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36548 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36549 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36550 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36551 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36552 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36553 * POSSIBILITY OF SUCH DAMAGE. 36554 */ 36555 36556'use strict'; 36557 36558Object.defineProperty(exports, '__esModule', { 36559 value: true 36560}); 36561 36562function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 36563 36564var _coreEventBus = _dereq_(50); 36565 36566var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 36567 36568var _coreEventsEvents = _dereq_(54); 36569 36570var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 36571 36572var _coreFactoryMaker = _dereq_(51); 36573 36574var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 36575 36576var _voFragmentRequest = _dereq_(209); 36577 36578var _voFragmentRequest2 = _interopRequireDefault(_voFragmentRequest); 36579 36580var _coreDebug = _dereq_(49); 36581 36582var _coreDebug2 = _interopRequireDefault(_coreDebug); 36583 36584var FRAGMENT_MODEL_LOADING = 'loading'; 36585var FRAGMENT_MODEL_EXECUTED = 'executed'; 36586var FRAGMENT_MODEL_CANCELED = 'canceled'; 36587var FRAGMENT_MODEL_FAILED = 'failed'; 36588 36589function FragmentModel(config) { 36590 36591 var context = this.context; 36592 var log = (0, _coreDebug2['default'])(context).getInstance().log; 36593 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 36594 var metricsModel = config.metricsModel; 36595 var fragmentLoader = config.fragmentLoader; 36596 36597 var instance = undefined, 36598 streamProcessor = undefined, 36599 executedRequests = undefined, 36600 loadingRequests = undefined; 36601 36602 function setup() { 36603 resetInitialSettings();
vendor: 2,894 bytes, lines 36604-36683
36604 eventBus.on(_coreEventsEvents2['default'].LOADING_COMPLETED, onLoadingCompleted, instance); 36605 eventBus.on(_coreEventsEvents2['default'].LOADING_ABANDONED, onLoadingAborted, instance); 36606 } 36607 36608 function setStreamProcessor(value) { 36609 streamProcessor = value; 36610 } 36611 36612 function getStreamProcessor() { 36613 return streamProcessor; 36614 } 36615 36616 function isFragmentLoaded(request) { 36617 var isEqualComplete = function isEqualComplete(req1, req2) { 36618 return req1.action === _voFragmentRequest2['default'].ACTION_COMPLETE && req1.action === req2.action; 36619 }; 36620 36621 var isEqualMedia = function isEqualMedia(req1, req2) { 36622 return !isNaN(req1.index) && req1.startTime === req2.startTime && req1.adaptationIndex === req2.adaptationIndex; 36623 }; 36624 36625 var isEqualInit = function isEqualInit(req1, req2) { 36626 return isNaN(req1.index) && isNaN(req2.index) && req1.quality === req2.quality; 36627 }; 36628 36629 var check = function check(requests) { 36630 var isLoaded = false; 36631 requests.some(function (req) { 36632 if (isEqualMedia(request, req) || isEqualInit(request, req) || isEqualComplete(request, req)) { 36633 isLoaded = true; 36634 return isLoaded; 36635 } 36636 }); 36637 return isLoaded; 36638 }; 36639 36640 if (!request) { 36641 return false; 36642 } 36643 36644 return check(executedRequests); 36645 } 36646 36647 function isFragmentLoadedOrPending(request) { 36648 var isLoaded = false; 36649 var i = 0; 36650 var req = undefined; 36651 36652 // First, check if the fragment has already been loaded 36653 isLoaded = isFragmentLoaded(request); 36654 36655 // Then, check if the fragment is about to be loeaded 36656 if (!isLoaded) { 36657 for (i = 0; i < loadingRequests.length; i++) { 36658 req = loadingRequests[i]; 36659 if (request.url === req.url && request.startTime === req.startTime) { 36660 isLoaded = true; 36661 } 36662 } 36663 } 36664 36665 return isLoaded; 36666 } 36667 36668 /** 36669 * 36670 * Gets an array of {@link FragmentRequest} objects 36671 * 36672 * @param {Object} filter The object with properties by which the method filters the requests to be returned. 36673 * the only mandatory property is state, which must be a value from 36674 * other properties should match the properties of {@link FragmentRequest}. E.g.: 36675 * getRequests({state: FragmentModel.FRAGMENT_MODEL_EXECUTED, quality: 0}) - returns 36676 * all the requests from executedRequests array where requests.quality = filter.quality 36677 * 36678 * @returns {Array} 36679 * @memberof FragmentModel# 36680 */ 36681 function getRequests(filter) { 36682 36683 var states = filter ? filter.state instanceof Array ? filter.state : [filter.state]
36683: []; 36684 36685 var filteredRequests = []; 36686 states.forEach(function (state) { 36687 var requests = getRequestsForState(state); 36688 filteredRequests = filteredRequests.concat(filterRequests(requests, filter)); 36689 }); 36690 36691 return filteredRequests; 36692 } 36693 36694 function removeExecutedRequestsBeforeTime(time) { 36695 executedRequests = executedRequests.filter(function (req) { 36696 return isNaN(req.startTime) || req.startTime >= time; 36697 }); 36698 } 36699 36700 function abortRequests() { 36701 fragmentLoader.abort(); 36702 loadingRequests = []; 36703 } 36704 36705 function executeRequest(request) { 36706 36707 switch (request.action) { 36708 case _voFragmentRequest2['default'].ACTION_COMPLETE: 36709 executedRequests.push(request); 36710 addSchedulingInfoMetrics(request, FRAGMENT_MODEL_EXECUTED); 36711 eventBus.trigger(_coreEventsEvents2['default'].STREAM_COMPLETED, { 36712 request: request, 36713 fragmentModel: this 36714 }); 36715 break; 36716 case _voFragmentRequest2['default'].ACTION_DOWNLOAD: 36717 addSchedulingInfoMetrics(request, FRAGMENT_MODEL_LOADING); 36718 loadingRequests.push(request); 36719 loadCurrentFragment(request); 36720 break; 36721 default: 36722 log('Unknown request action.'); 36723 } 36724 } 36725 36726 function loadCurrentFragment(request) { 36727 eventBus.trigger(_coreEventsEvents2['default'].FRAGMENT_LOADING_STARTED, { 36728 sender: instance, 36729 request: request 36730 }); 36731 fragmentLoader.load(request); 36732 } 36733 36734 function getRequestForTime(arr, time, threshold) { 36735 // loop through the executed requests and pick the one for which the playback interval matches the given time 36736 var lastIdx = arr.length - 1; 36737 for (var i = lastIdx; i >= 0; i--) { 36738 var req = arr[i]; 36739 var start = req.startTime; 36740 var end = start + req.duration; 36741 threshold = threshold !== undefined ? threshold : req.duration / 2; 36742 if (!isNaN(start) && !isNaN(end) && time + threshold >= start && time - threshold < end || isNaN(start) && isNaN(time)) { 36743 return req; 36744 } 36745 } 36746 return null; 36747 } 36748 36749 function filterRequests(arr, filter) { 36750 // for time use a specific filtration function 36751 if (filter.hasOwnProperty('time')) { 36752 return [getRequestForTime(arr, filter.time, filter.threshold)]; 36753 } 36754 36755 return arr.filter(function (request) { 36756 for (var prop in filter) { 36757 if (prop === 'state') continue; 36758 if (filter.hasOwnProperty(prop) && request[prop] != filter[prop]) return false; 36759 } 36760 36761 return true; 36762 }); 36763 } 36764 36765 function getRequestsForState(state) { 36766 36767 var requests = undefined; 36768 switch (state) { 36769 case FRAGMENT_MODEL_LOADING: 36770 requests = loadingRequests; 36771 break; 36772 case FRAGMENT_MODEL_EXECUTED: 36773 requests = executedRequests; 36774 break; 36775 default: 36776 requests = []; 36777 } 36778 return requests; 36779 } 36780 36781 function addSchedulingInfoMetrics(request, state) { 36782 36783 metricsModel.addSchedulingInfo(request.mediaType, new Date(), request.type, request.startTime, request.availabilityStartTime, request.duration, request.quality, request.range, state); 36784 36785 metricsModel.addRequestsQueue(request.mediaType, loadingRequests, executedRequests); 36786 } 36787 36788 function onLoadingCompleted(e) { 36789 if (e.sender !== fragmentLoader) return; 36790 36791 loadingRequests.splice(loadingRequests.indexOf(e.request), 1); 36792 36793 if (e.response && !e.error) { 36794 executedRequests.push(e.request); 36795 } 36796 36797 addSchedulingInfoMetrics(e.request, e.error ? FRAGMENT_MODEL_FAILED : FRAGMENT_MODEL_EXECUTED); 36798 36799 eventBus.trigger(_coreEventsEvents2['default'].FRAGMENT_LOADING_COMPLETED, { 36800 request: e.request, 36801 response: e.response, 36802 error: e.error, 36803 sender: this 36804 }); 36805 } 36806 36807 function onLoadingAborted(e) { 36808 if (e.sender !== fragmentLoader) return; 36809 36810 eventBus.trigger(_coreEventsEvents2['default'].FRAGMENT_LOADING_ABANDONED, { streamProcessor: this.get
36810StreamProcessor(), request: e.request, mediaType: e.mediaType }); 36811 } 36812 36813 function resetInitialSettings() { 36814 executedRequests = []; 36815 loadingRequests = []; 36816 } 36817 36818 function reset() { 36819 eventBus.off(_coreEventsEvents2['default'].LOADING_COMPLETED, onLoadingCompleted, this); 36820 eventBus.off(_coreEventsEvents2['default'].LOADING_ABANDONED, onLoadingAborted, this); 36821 36822 if (fragmentLoader) { 36823 fragmentLoader.reset(); 36824 } 36825 resetInitialSettings(); 36826 } 36827 36828 instance = { 36829 setStreamProcessor: setStreamProcessor, 36830 getStreamProcessor: getStreamProcessor, 36831 getRequests: getRequests, 36832 isFragmentLoaded: isFragmentLoaded, 36833 isFragmentLoadedOrPending: isFragmentLoadedOrPending, 36834 removeExecutedRequestsBeforeTime: removeExecutedRequestsBeforeTime, 36835 abortRequests: abortRequests, 36836 executeRequest: executeRequest, 36837 reset: reset 36838 }; 36839 36840 setup(); 36841 return instance; 36842} 36843 36844FragmentModel.__dashjs_factory_name = 'FragmentModel'; 36845var factory = _coreFactoryMaker2['default'].getClassFactory(FragmentModel); 36846factory.FRAGMENT_MODEL_LOADING = FRAGMENT_MODEL_LOADING; 36847factory.FRAGMENT_MODEL_EXECUTED = FRAGMENT_MODEL_EXECUTED; 36848factory.FRAGMENT_MODEL_CANCELED = FRAGMENT_MODEL_CANCELED; 36849factory.FRAGMENT_MODEL_FAILED = FRAGMENT_MODEL_FAILED; 36850_coreFactoryMaker2['default'].updateClassFactory(FragmentModel.__dashjs_factory_name, factory); 36851exports['default'] = factory; 36852module.exports = exports['default']; 36853 36854},{"209":209,"49":49,"50":50,"51":51,"54":54}],141:[function(_dereq_,module,exports){ 36855/** 36856 * The copyright in this software is being made available under the BSD License, 36857 * included below. This software may be subject to other third party and contributor 36858 * rights, including patent rights, and no such rights are granted under this license. 36859 * 36860 * Copyright (c) 2013, Dash Industry Forum. 36861 * All rights reserved. 36862 * 36863 * Redistribution and use in source and binary forms, with or without modification, 36864 * are permitted provided that the following conditions are met: 36865 * * Redistributions of source code must retain the above copyright notice, this 36866 * list of conditions and the following disclaimer. 36867 * * Redistributions in binary form must reproduce the above copyright notice, 36868 * this list of conditions and the following disclaimer in the documentation and/or 36869 * other materials provided with the distribution. 36870 * * Neither the name of Dash Industry Forum nor the names of its 36871 * contributors may be used to endorse or promote products derived from this software 36872 * without specific prior written permission. 36873 * 36874 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 36875 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36876 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36877 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36878 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36879 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36880 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36881 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36882 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36883 * POSSIBILITY OF SUCH DAMAGE. 36884 */ 36885'use strict'; 36886 36887Object.defineProperty(exports, '__esModule', { 36888 value: true 36889}); 36890 36891function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 36892 36893var _coreEventBus = _dereq_(50); 36894 36895var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 36896 36897var _coreEventsEvents = _dereq_(54); 36898 36899var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 36900 36901var _coreFactoryMaker = _dereq_(51); 36902 36903var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 36904 36905function ManifestModel() { 36906 36907 var context = this.context; 36908 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 36909 36910 var instance = undefined, 36911 manifest = undefined; 36912 36913 function getValue() { 36914 return manifest; 36915 } 36916 36917 function setValue(value) { 36918 manifest = value; 36919 if (value) { 36920 eventBus.trigger(_coreEventsEvents2['default'].MANIFEST_LOADED, { data: value });
36921 } 36922 } 36923 36924 instance = { 36925 getValue: getValue, 36926 setValue: setValue 36927 }; 36928 36929 return instance; 36930} 36931 36932ManifestModel.__dashjs_factory_name = 'ManifestModel'; 36933exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(ManifestModel); 36934module.exports = exports['default']; 36935 36936},{"50":50,"51":51,"54":54}],142:[function(_dereq_,module,exports){ 36937/** 36938 * The copyright in this software is being made available under the BSD License, 36939 * included below. This software may be subject to other third party and contributor 36940 * rights, including patent rights, and no such rights are granted under this license. 36941 * 36942 * Copyright (c) 2013, Dash Industry Forum. 36943 * All rights reserved. 36944 * 36945 * Redistribution and use in source and binary forms, with or without modification, 36946 * are permitted provided that the following conditions are met: 36947 * * Redistributions of source code must retain the above copyright notice, this 36948 * list of conditions and the following disclaimer. 36949 * * Redistributions in binary form must reproduce the above copyright notice, 36950 * this list of conditions and the following disclaimer in the documentation and/or 36951 * other materials provided with the distribution. 36952 * * Neither the name of Dash Industry Forum nor the names of its 36953 * contributors may be used to endorse or promote products derived from this software 36954 * without specific prior written permission. 36955 * 36956 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 36957 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36958 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36959 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 36960 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36961 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36962 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 36963 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36964 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36965 * POSSIBILITY OF SUCH DAMAGE. 36966 */ 36967'use strict'; 36968 36969Object.defineProperty(exports, '__esModule', { 36970 value: true 36971}); 36972 36973function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 36974 36975function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 36976 36977var _coreFactoryMaker = _dereq_(51); 36978 36979var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 36980 36981var _voMetricsHTTPRequest = _dereq_(224); 36982 36983var _constantsConstants = _dereq_(100); 36984 36985var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 36986 36987var DEFAULT_UTC_TIMING_SOURCE = { 36988 scheme: 'urn:mpeg:dash:utc:http-xsdate:2014', 36989 value: 'http://time.akamai.com/?iso' 36990}; 36991var LIVE_DELAY_FRAGMENT_COUNT = 4; 36992 36993var DEFAULT_LOCAL_STORAGE_BITRATE_EXPIRATION = 360000; 36994var DEFAULT_LOCAL_STORAGE_MEDIA_SETTINGS_EXPIRATION = 360000; 36995 36996var BANDWIDTH_SAFETY_FACTOR = 0.9; 36997var ABANDON_LOAD_TIMEOUT = 10000; 36998 36999var BUFFER_TO_KEEP = 30; 37000var BUFFER_PRUNING_INTERVAL = 30; 37001var DEFAULT_MIN_BUFFER_TIME = 12; 37002var DEFAULT_MIN_BUFFER_TIME_FAST_SWITCH = 20; 37003var BUFFER_TIME_AT_TOP_QUALITY = 30; 37004var BUFFER_TIME_AT_TOP_QUALITY_LONG_FORM = 60; 37005var LONG_FORM_CONTENT_DURATION_THRESHOLD = 600; 37006 37007var FRAGMENT_RETRY_ATTEMPTS = 3; 37008var FRAGMENT_RETRY_INTERVAL = 1000; 37009 37010var MANIFEST_RETRY_ATTEMPTS = 3; 37011var MANIFEST_RETRY_INTERVAL = 500; 37012 37013var XLINK_RETRY_ATTEMPTS = 1; 37014var XLINK_RETRY_INTERVAL = 500; 37015 37016//This value influences the startup time for live (in ms). 37017var WALLCLOCK_TIME_UPDATE_INTERVAL = 50; 37018 37019var DEFAULT_XHR_WITH_CREDENTIALS = false; 37020 37021function MediaPlayerModel() { 37022 37023 var instance = undefined, 37024 useManifestDateHeaderTimeSource = undefined, 37025 useSuggestedPresentationDelay = undefined, 37026 UTCTimingSources = undefined, 37027 liveDelayFragmentCount = undefined,
37028 liveDelay = undefined, 37029 scheduleWhilePaused = undefined, 37030 bufferToKeep = undefined, 37031 bufferPruningInterval = undefined, 37032 lastBitrateCachingInfo = undefined, 37033 lastMediaSettingsCachingInfo = undefined, 37034 stableBufferTime = undefined, 37035 bufferTimeAtTopQuality = undefined, 37036 bufferTimeAtTopQualityLongForm = undefined, 37037 longFormContentDurationThreshold = undefined, 37038 bandwidthSafetyFactor = undefined, 37039 abandonLoadTimeout = undefined, 37040 retryAttempts = undefined, 37041 retryIntervals = undefined, 37042 wallclockTimeUpdateInterval = undefined, 37043 ABRStrategy = undefined, 37044 useDefaultABRRules = undefined, 37045 xhrWithCredentials = undefined, 37046 fastSwitchEnabled = undefined, 37047 customABRRule = undefined, 37048 movingAverageMethod = undefined; 37049 37050 function setup() { 37051 var _retryAttempts, _retryIntervals; 37052 37053 UTCTimingSources = []; 37054 useSuggestedPresentationDelay = false; 37055 useManifestDateHeaderTimeSource = true; 37056 scheduleWhilePaused = true; 37057 ABRStrategy = _constantsConstants2['default'].ABR_STRATEGY_DYNAMIC; 37058 useDefaultABRRules = true; 37059 fastSwitchEnabled = false; 37060 lastBitrateCachingInfo = { 37061 enabled: true, 37062 ttl: DEFAULT_LOCAL_STORAGE_BITRATE_EXPIRATION 37063 }; 37064 lastMediaSettingsCachingInfo = { 37065 enabled: true, 37066 ttl: DEFAULT_LOCAL_STORAGE_MEDIA_SETTINGS_EXPIRATION 37067 }; 37068 liveDelayFragmentCount = LIVE_DELAY_FRAGMENT_COUNT; 37069 liveDelay = undefined; // Explicitly state that default is undefined 37070 bufferToKeep = BUFFER_TO_KEEP; 37071 bufferPruningInterval = BUFFER_PRUNING_INTERVAL; 37072 stableBufferTime = NaN; 37073 bufferTimeAtTopQuality = BUFFER_TIME_AT_TOP_QUALITY; 37074 bufferTimeAtTopQualityLongForm = BUFFER_TIME_AT_TOP_QUALITY_LONG_FORM; 37075 longFormContentDurationThreshold = LONG_FORM_CONTENT_DURATION_THRESHOLD; 37076 bandwidthSafetyFactor = BANDWIDTH_SAFETY_FACTOR; 37077 abandonLoadTimeout = ABANDON_LOAD_TIMEOUT; 37078 wallclockTimeUpdateInterval = WALLCLOCK_TIME_UPDATE_INTERVAL; 37079 xhrWithCredentials = { 37080 'default': DEFAULT_XHR_WITH_CREDENTIALS 37081 }; 37082 customABRRule = []; 37083 movingAverageMethod = _constantsConstants2['default'].MOVING_AVERAGE_SLIDING_WINDOW; 37084 37085 retryAttempts = (_retryAttempts = {}, _defineProperty(_retryAttempts, _voMetricsHTTPRequest.HTTPRequest.MPD_TYPE, MANIFEST_RETRY_ATTEMPTS), _defineProperty(_retryAttempts, _voMetricsHTTPRequest.HTTPRequest.XLINK_EXPANSION_TYPE, XLINK_RETRY_ATTEMPTS), _defineProperty(_retryAttempts, _voMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE, FRAGMENT_RETRY_ATTEMPTS), _defineProperty(_retryAttempts, _voMetricsHTTPRequest.HTTPRequest.INIT_SEGMENT_TYPE, FRAGMENT_RETRY_ATTEMPTS), _defineProperty(_retryAttempts, _voMetricsHTTPRequest.HTTPRequest.BITSTREAM_SWITCHING_SEGMENT_TYPE, FRAGMENT_RETRY_ATTEMPTS), _defineProperty(_retryAttempts, _voMetricsHTTPRequest.HTTPRequest.INDEX_SEGMENT_TYPE, FRAGMENT_RETRY_ATTEMPTS), _defineProperty(_retryAttempts, _voMetricsHTTPRequest.HTTPRequest.OTHER_TYPE, FRAGMENT_RETRY_ATTEMPTS), _retryAttempts); 37086 37087 retryIntervals = (_retryIntervals = {}, _defineProperty(_retryIntervals, _voMetricsHTTPRequest.HTTPRequest.MPD_TYPE, MANIFEST_RETRY_INTERVAL), _defineProperty(_retryIntervals, _voMetricsHTTPRequest.HTTPRequest.XLINK_EXPANSION_TYPE, XLINK_RETRY_INTERVAL), _defineProperty(_retryIntervals, _voMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE, FRAGMENT_RETRY_INTERVAL), _defineProperty(_retryIntervals, _voMetricsHTTPRequest.HTTPRequest.INIT_SEGMENT_TYPE, FRAGMENT_RETRY_INTERVAL), _defineProperty(_retryIntervals, _voMetricsHTTPRequest.HTTPRequest.BITSTREAM_SWITCHING_SEGMENT_TYPE, FRAGMENT_RETRY_INTERVAL), _defineProperty(_retryIntervals, _voMetricsHTTPRequest.HTTPRequest.INDEX_SEGMENT_TYPE, FRAGMENT_RETRY_INTERVAL), _defineProperty(_retryIntervals, _voMetricsHTTPRequest.HTTPRequest.OTHER_TYPE, FRAGMENT_RETRY_INTERVAL), _retryIntervals); 37088 } 37089 37090 //TODO Should we use Object.define to have setters/getters? makes more readable code on other side. 37091 37092 function setABRStrategy(value) { 37093 ABRStrategy = value; 37094 } 37095 37096 function getABRStrategy() { 37097 return ABRStrategy; 37098 } 37099 37100 function setUseDefaultABRRules(value) { 37101 useDefaultABRRules = value; 37102 } 37103 37104 function getUseDefaultABRRules() { 37105 return useDefaultABRRules; 37106 } 37107 37108 function findABRCustomRule(rulename) { 37109 var i = undefined; 37110 for (i = 0; i < customABRRule.length; i++) { 37111 if (customABRRule[i].rulename === rulename) { 37112 return i; 37113 } 37114 } 37115 return -1; 37116 } 37117 37118 function getABRCustomRules() { 37119 return customABRRule; 37120 } 37121 37122 function addABRCustomRule(type, rulename, rule) { 37123 37124 var index = findABRCustomRule(rulename); 37125 if (index === -1) { 37126 // add rule 37127 customABRRule.push({ 37128 type: type, 37129 rulename: rulename, 37130 rule: rule 37131 }); 37132 } else { 37133 // update rule 37134 customABRRule[index].type = type; 37135 customABRRule[index].rule = rule; 37136 } 37137 } 37138 37139 function removeABRCustomRule(rulename) { 37140 var index = findABRCustomRule(rulename); 37141 if (index !== -1) { 37142 // remove rule 37143 customABRRule.splice(index, 1); 37144 } 37145 } 37146 37147 function removeAllABRCustomRule() { 37148 customABRRule = []; 37149 } 37150 37151 function setBandwidthSafetyFactor(value) { 37152 bandwidthSafetyFactor = value; 37153 } 37154 37155 function getBandwidthSafetyFactor() { 37156 return bandwidthSafetyFactor; 37157 } 37158 37159 function setAbandonLoadTimeout(value) { 37160 abandonLoadTimeout = value; 37161 } 37162 37163 function getAbandonLoadTimeout() { 37164 return abandonLoadTimeout; 37165 } 37166 37167 function setStableBufferTime(value) { 37168 stableBufferTime = value; 37169 } 37170 37171 function getStableBufferTime() { 37172 return !isNaN(stableBufferTime) ? stableBufferTime : fastSwitchEnabled ? DEFAULT_MIN_BUFFER_TIME_FAST_SWITCH : DEFAULT_MIN_BUFFER_TIME; 37173 } 37174 37175 function setBufferTimeAtTopQuality(value) { 37176 bufferTimeAtTopQuality = value; 37177 } 37178 37179 function getBufferTimeAtTopQuality() { 37180 return bufferTimeAtTopQuality;
37181 } 37182 37183 function setBufferTimeAtTopQualityLongForm(value) { 37184 bufferTimeAtTopQualityLongForm = value; 37185 } 37186 37187 function getBufferTimeAtTopQualityLongForm() { 37188 return bufferTimeAtTopQualityLongForm; 37189 } 37190 37191 function setLongFormContentDurationThreshold(value) { 37192 longFormContentDurationThreshold = value; 37193 } 37194 37195 function getLongFormContentDurationThreshold() { 37196 return longFormContentDurationThreshold; 37197 } 37198 37199 function setBufferToKeep(value) { 37200 bufferToKeep = value; 37201 } 37202 37203 function getBufferToKeep() { 37204 return bufferToKeep; 37205 } 37206 37207 function setLastBitrateCachingInfo(enable, ttl) { 37208 lastBitrateCachingInfo.enabled = enable; 37209 if (ttl !== undefined && !isNaN(ttl) && typeof ttl === 'number') { 37210 lastBitrateCachingInfo.ttl = ttl; 37211 } 37212 } 37213 37214 function getLastBitrateCachingInfo() { 37215 return lastBitrateCachingInfo; 37216 } 37217 37218 function setLastMediaSettingsCachingInfo(enable, ttl) { 37219 lastMediaSettingsCachingInfo.enabled = enable; 37220 if (ttl !== undefined && !isNaN(ttl) && typeof ttl === 'number') { 37221 lastMediaSettingsCachingInfo.ttl = ttl; 37222 } 37223 } 37224 37225 function getLastMediaSettingsCachingInfo() { 37226 return lastMediaSettingsCachingInfo; 37227 } 37228 37229 function setBufferPruningInterval(value) { 37230 bufferPruningInterval = value; 37231 } 37232 37233 function getBufferPruningInterval() { 37234 return bufferPruningInterval; 37235 } 37236 37237 function setFragmentRetryAttempts(value) { 37238 retryAttempts[_voMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE] = value; 37239 } 37240 37241 function setManifestRetryAttempts(value) { 37242 retryAttempts[_voMetricsHTTPRequest.HTTPRequest.MPD_TYPE] = value; 37243 } 37244 37245 function setRetryAttemptsForType(type, value) { 37246 retryAttempts[type] = value; 37247 } 37248 37249 function getFragmentRetryAttempts() { 37250 return retryAttempts[_voMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE]; 37251 } 37252 37253 function getManifestRetryAttempts() { 37254 return retryAttempts[_voMetricsHTTPRequest.HTTPRequest.MPD_TYPE]; 37255 } 37256 37257 function getRetryAttemptsForType(type) { 37258 return retryAttempts[type]; 37259 } 37260 37261 function setFragmentRetryInterval(value) { 37262 retryIntervals[_voMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE] = value; 37263 } 37264 37265 function setManifestRetryInterval(value) { 37266 retryIntervals[_voMetricsHTTPRequest.HTTPRequest.MPD_TYPE] = value; 37267 } 37268 37269 function setRetryIntervalForType(type, value) { 37270 retryIntervals[type] = value; 37271 } 37272 37273 function getFragmentRetryInterval() { 37274 return retryIntervals[_voMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE]; 37275 } 37276 37277 function getManifestRetryInterval() { 37278 return retryIntervals[_voMetricsHTTPRequest.HTTPRequest.MPD_TYPE]; 37279 } 37280 37281 function getRetryIntervalForType(type) { 37282 return retryIntervals[type]; 37283 } 37284 37285 function setWallclockTimeUpdateInterval(value) { 37286 wallclockTimeUpdateInterval = value; 37287 } 37288 37289 function getWallclockTimeUpdateInterval() { 37290 return wallclockTimeUpdateInterval; 37291 } 37292 37293 function setScheduleWhilePaused(value) { 37294 scheduleWhilePaused = value; 37295 } 37296 37297 function getScheduleWhilePaused() { 37298 return scheduleWhilePaused; 37299 } 37300 37301 function setLiveDelayFragmentCount(value) { 37302 liveDelayFragmentCount = value; 37303 } 37304 37305 function setLiveDelay(value) { 37306 liveDelay = value; 37307 } 37308 37309 function getLiveDelayFragmentCount() { 37310 return liveDelayFragmentCount; 37311 } 37312 37313 function getLiveDelay() { 37314 return liveDelay; 37315 } 37316 37317 function setUseManifestDateHeaderTimeSource(value) { 37318 useManifestDateHeaderTimeSource = value; 37319 } 37320 37321 function getUseManifestDateHeaderTimeSource() { 37322 return useManifestDateHeaderTimeSource; 37323 } 37324 37325 function setUseSuggestedPresentationDelay(value) { 37326 useSuggestedPresentationDelay = value; 37327 } 37328 37329 function getUseSuggestedPresentationDelay() { 37330 return useSuggestedPresentationDelay; 37331 } 37332 37333 function setUTCTimingSources(value) { 37334 UTCTimingSources = value; 37335 } 37336 37337 function getUTCTimingSources() { 37338 return UTCTimingSources; 37339 } 37340 37341 function setXHRWithCredentialsForType(type, value) { 37342 if (!type) {
37343 Object.keys(xhrWithCredentials).forEach(function (key) { 37344 setXHRWithCredentialsForType(key, value); 37345 }); 37346 } else { 37347 xhrWithCredentials[type] = !!value; 37348 } 37349 } 37350 37351 function getXHRWithCredentialsForType(type) { 37352 var useCreds = xhrWithCredentials[type]; 37353 37354 if (useCreds === undefined) { 37355 return xhrWithCredentials['default']; 37356 } 37357 37358 return useCreds; 37359 } 37360 37361 function getFastSwitchEnabled() { 37362 return fastSwitchEnabled; 37363 } 37364 37365 function setFastSwitchEnabled(value) { 37366 fastSwitchEnabled = value; 37367 } 37368 37369 function setMovingAverageMethod(value) { 37370 movingAverageMethod = value; 37371 } 37372 37373 function getMovingAverageMethod() { 37374 return movingAverageMethod; 37375 } 37376 37377 function reset() { 37378 //TODO need to figure out what props to persist across sessions and which to reset if any. 37379 //setup(); 37380 } 37381 37382 instance = { 37383 setABRStrategy: setABRStrategy, 37384 getABRStrategy: getABRStrategy, 37385 setUseDefaultABRRules: setUseDefaultABRRules, 37386 getUseDefaultABRRules: getUseDefaultABRRules, 37387 getABRCustomRules: getABRCustomRules, 37388 addABRCustomRule: addABRCustomRule, 37389 removeABRCustomRule: removeABRCustomRule, 37390 removeAllABRCustomRule: removeAllABRCustomRule, 37391 setBandwidthSafetyFactor: setBandwidthSafetyFactor, 37392 getBandwidthSafetyFactor: getBandwidthSafetyFactor, 37393 setAbandonLoadTimeout: setAbandonLoadTimeout, 37394 getAbandonLoadTimeout: getAbandonLoadTimeout, 37395 setLastBitrateCachingInfo: setLastBitrateCachingInfo, 37396 getLastBitrateCachingInfo: getLastBitrateCachingInfo, 37397 setLastMediaSettingsCachingInfo: setLastMediaSettingsCachingInfo, 37398 getLastMediaSettingsCachingInfo: getLastMediaSettingsCachingInfo, 37399 setStableBufferTime: setStableBufferTime, 37400 getStableBufferTime: getStableBufferTime, 37401 setBufferTimeAtTopQuality: setBufferTimeAtTopQuality, 37402 getBufferTimeAtTopQuality: getBufferTimeAtTopQuality, 37403 setBufferTimeAtTopQualityLongForm: setBufferTimeAtTopQualityLongForm, 37404 getBufferTimeAtTopQualityLongForm: getBufferTimeAtTopQualityLongForm, 37405 setLongFormContentDurationThreshold: setLongFormContentDurationThreshold, 37406 getLongFormContentDurationThreshold: getLongFormContentDurationThreshold, 37407 setBufferToKeep: setBufferToKeep, 37408 getBufferToKeep: getBufferToKeep, 37409 setBufferPruningInterval: setBufferPruningInterval, 37410 getBufferPruningInterval: getBufferPruningInterval, 37411 setFragmentRetryAttempts: setFragmentRetryAttempts, 37412 getFragmentRetryAttempts: getFragmentRetryAttempts, 37413 setManifestRetryAttempts: setManifestRetryAttempts, 37414 getManifestRetryAttempts: getManifestRetryAttempts, 37415 setRetryAttemptsForType: setRetryAttemptsForType, 37416 getRetryAttemptsForType: getRetryAttemptsForType, 37417 setFragmentRetryInterval: setFragmentRetryInterval, 37418 getFragmentRetryInterval: getFragmentRetryInterval, 37419 setManifestRetryInterval: setManifestRetryInterval, 37420 getManifestRetryInterval: getManifestRetryInterval, 37421 setRetryIntervalForType: setRetryIntervalForType, 37422 getRetryIntervalForType: getRetryIntervalForType, 37423 setWallclockTimeUpdateInterval: setWallclockTimeUpdateInterval, 37424 getWallclockTimeUpdateInterval: getWallclockTimeUpdateInterval, 37425 setScheduleWhilePaused: setScheduleWhilePaused, 37426 getScheduleWhilePaused: getScheduleWhilePaused, 37427 getUseSuggestedPresentationDelay: getUseSuggestedPresentationDelay, 37428 setUseSuggestedPresentationDelay: setUseSuggestedPresentationDelay, 37429 setLiveDelayFragmentCount: setLiveDelayFragmentCount, 37430 getLiveDelayFragmentCount: getLiveDelayFragmentCount, 37431 getLiveDelay: getLiveDelay, 37432 setLiveDelay: setLiveDelay, 37433 setUseManifestDateHeaderTimeSource: setUseManifestDateHeaderTimeSource, 37434 getUseManifestDateHeaderTimeSource: getUseManifestDateHeaderTimeSource, 37435 setUTCTimingSources: setUTCTimingSources, 37436 getUTCTimingSources: getUTCTimingSources, 37437 setXHRWithCredentialsForType: setXHRWithCredentialsForType, 37438 getXHRWithCredentialsForType: getXHRWithCredentialsForType, 37439 setFastSwitchEnabled: setFastSwitchEnabled, 37440 getFastSwitchEnabled: getFastSwitchEnabled, 37441 setMovingAverageMethod: setMovingAverageMethod, 37442 getMovingAverageMethod: getMovingAverageMethod, 37443 reset: reset 37444 }; 37445 37446 setup(); 37447 37448 return instance; 37449} 37450 37451//TODO see if you can move this and not export and just getter to get default value. 37452MediaPlayerModel.__dashjs_factory_name = 'MediaPlayerModel'; 37453var factory = _coreFactoryMaker2['default'].getSingletonFactory(MediaPlayerModel); 37454factory.DEFAULT_UTC_TIMING_SOURCE = DEFAULT_UTC_TIMING_SOURCE; 37455_coreFactoryMaker2['default'].updateSingletonFactory(MediaPlayerModel.__dashjs_factory_name, factory); 37456exports['default'] = factory; 37457module.exports = exports['default']; 37458 37459},{"100":100,"224":224,"51":51}],143:[function(_dereq_,module,exports){ 37460/** 37461 * The copyright in this software is being made available under the BSD License, 37462 * included below. This software may be subject to other third party and contributor 37463 * rights, including patent rights, and no such rights are granted under this license. 37464 * 37465 * Copyright (c) 2013, Dash Industry Forum. 37466 * All rights reserved. 37467 * 37468 * Redistribution and use in source and binary forms, with or without modification, 37469 * are permitted provided that the following conditions are met: 37470 * * Redistributions of source code must retain the above copyright notice, this 37471 * list of conditions and the following disclaimer. 37472 * * Redistributions in binary form must reproduce the above copyright notice, 37473 * this list of conditions and the following disclaimer in the documentation and/or 37474 * other materials provided with the distribution. 37475 * * Neither the name of Dash Industry Forum nor the names of its 37476 * contributors may be used to endorse or promote products derived from this software 37477 * without specific prior written permission. 37478 * 37479 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 37480 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 37481 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 37482 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 37483 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
37483INCLUDING, BUT 37484 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 37485 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 37486 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37487 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37488 * POSSIBILITY OF SUCH DAMAGE. 37489 */ 37490'use strict'; 37491 37492Object.defineProperty(exports, '__esModule', { 37493 value: true 37494}); 37495 37496function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 37497 37498var _constantsConstants = _dereq_(100); 37499 37500var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 37501 37502var _constantsMetricsConstants = _dereq_(101); 37503 37504var _constantsMetricsConstants2 = _interopRequireDefault(_constantsMetricsConstants); 37505 37506var _voMetricsList = _dereq_(214); 37507 37508var _voMetricsList2 = _interopRequireDefault(_voMetricsList); 37509 37510var _voMetricsTCPConnection = _dereq_(230); 37511 37512var _voMetricsTCPConnection2 = _interopRequireDefault(_voMetricsTCPConnection); 37513 37514var _voMetricsHTTPRequest = _dereq_(224); 37515 37516var _voMetricsRepresentationSwitch = _dereq_(227); 37517 37518var _voMetricsRepresentationSwitch2 = _interopRequireDefault(_voMetricsRepresentationSwitch); 37519 37520var _voMetricsBufferLevel = _dereq_(220); 37521 37522var _voMetricsBufferLevel2 = _interopRequireDefault(_voMetricsBufferLevel); 37523 37524var _voMetricsBufferState = _dereq_(221); 37525 37526var _voMetricsBufferState2 = _interopRequireDefault(_voMetricsBufferState); 37527 37528var _voMetricsDVRInfo = _dereq_(222); 37529 37530var _voMetricsDVRInfo2 = _interopRequireDefault(_voMetricsDVRInfo); 37531 37532var _voMetricsDroppedFrames = _dereq_(223); 37533 37534var _voMetricsDroppedFrames2 = _interopRequireDefault(_voMetricsDroppedFrames); 37535 37536var _voMetricsManifestUpdate = _dereq_(225); 37537 37538var _voMetricsSchedulingInfo = _dereq_(229); 37539 37540var _voMetricsSchedulingInfo2 = _interopRequireDefault(_voMetricsSchedulingInfo); 37541 37542var _coreEventBus = _dereq_(50); 37543 37544var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 37545 37546var _voMetricsRequestsQueue = _dereq_(228); 37547 37548var _voMetricsRequestsQueue2 = _interopRequireDefault(_voMetricsRequestsQueue); 37549 37550var _coreEventsEvents = _dereq_(54); 37551 37552var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 37553 37554var _coreFactoryMaker = _dereq_(51); 37555 37556var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 37557 37558function MetricsModel() { 37559 37560 var MAXIMUM_LIST_DEPTH = 1000; 37561 37562 var context = this.context; 37563 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 37564 37565 var instance = undefined, 37566 adapter = undefined, 37567 streamMetrics = undefined; 37568 37569 function setup() { 37570 streamMetrics = {}; 37571 } 37572 37573 function setConfig(config) { 37574 if (!config) return; 37575 37576 if (config.adapter) { 37577 adapter = config.adapter; 37578 } 37579 } 37580 37581 function metricsChanged() { 37582 eventBus.trigger(_coreEventsEvents2['default'].METRICS_CHANGED); 37583 } 37584 37585 function metricChanged(mediaType) { 37586 eventBus.trigger(_coreEventsEvents2['default'].METRIC_CHANGED, { mediaType: mediaType }); 37587 metricsChanged(); 37588 } 37589 37590 function metricUpdated(mediaType, metricType, vo) { 37591 eventBus.trigger(_coreEventsEvents2['default'].METRIC_UPDATED, { mediaType: mediaType, metric: metricType, value: vo }); 37592 metricChanged(mediaType); 37593 } 37594 37595 function metricAdded(mediaType, metricType, vo) { 37596 eventBus.trigger(_coreEventsEvents2['default'].METRIC_ADDED, { mediaType: mediaType, metric: metricType, value: vo }); 37597 metricChanged(mediaType); 37598 } 37599 37600 function clearCurrentMetricsForType(type) { 37601 delete streamMetrics[type]; 37602 metricChanged(type); 37603 } 37604 37605 function clearAllCurrentMetrics() { 37606 streamMetrics = {}; 37607 metricsChanged(); 37608 } 37609 37610 function getReadOnlyMetricsFor(type) { 37611 if (streamMetrics.hasOwnProperty(type)) { 37612 return streamMetrics[type]; 37613 } 37614 37615 return null; 37616 } 37617 37618 function getMetricsFor(type) { 37619 var metrics = undefined; 37620 37621 if (streamMetrics.hasOwnProperty(type)) { 37622 metrics = streamMetrics[type]; 37623 } else { 37624 metrics = new _voMetricsList2['default'](); 37625 streamMetrics[type] = metrics; 37626 } 37627 37628 return metrics; 37629 } 37630 37631 function pushMetrics(type, list, value) { 37632 var metrics = getMetricsFor(type); 37633 metrics[list].push(value); 37634 if (metrics[list].length > MAXIMUM_LIST_DEPTH) { 37635 metrics[list].shift(); 37636 } 37637 } 37638 37639 function addTcpConnection(mediaType, tcpid, dest, topen, tclose, tconnect) { 37640 var vo = new _voMetricsTCPConnection2['default'](); 37641 37642 vo.tcpid = tcpid; 37643 vo.dest = dest; 37644 vo.topen = topen; 37645 vo.tclose = tclose; 37646 vo.tconnect = tconnect; 37647 37648 pushAndNotify(mediaType, _constantsMetricsConstants2['default'].TCP_CONNECTION, vo); 37649 37650 return vo; 37651 } 37652 37653 function appendHttpTrace(httpRequest, s, d, b) { 37654 var vo = new _voMetricsHTTPRequest.HTTPRequestTrace(); 37655 37656 vo.s = s; 37657 vo.d = d; 37658 vo.b = b; 37659 37660 httpRequest.trace.push(vo); 37661 37662 if (!httpRequest.interval) { 37663 httpRequest.interval = 0; 37664 } 37665 37666 httpRequest.interval += d; 37667 37668 return vo; 37669 } 37670 37671 function addHttpRequest(mediaType, tcpid, type, url, actualurl, serviceLocation, range, trequest, tresponse, tfinish, responsecode, mediaduration, responseHeaders, traces) {
37672 var vo = new _voMetricsHTTPRequest.HTTPRequest(); 37673 37674 // ISO 23009-1 D.4.3 NOTE 2: 37675 // All entries for a given object will have the same URL and range 37676 // and so can easily be correlated. If there were redirects or 37677 // failures there will be one entry for each redirect/failure. 37678 // The redirect-to URL or alternative url (where multiple have been 37679 // provided in the MPD) will appear as the actualurl of the next 37680 // entry with the same url value. 37681 if (actualurl && actualurl !== url) { 37682 37683 // given the above, add an entry for the original request 37684 addHttpRequest(mediaType, null, type, url, null, null, range, trequest, null, // unknown 37685 null, // unknown 37686 null, // unknown, probably a 302 37687 mediaduration, null, null); 37688 37689 vo.actualurl = actualurl; 37690 } 37691 37692 vo.tcpid = tcpid; 37693 vo.type = type; 37694 vo.url = url; 37695 vo.range = range; 37696 vo.trequest = trequest; 37697 vo.tresponse = tresponse; 37698 vo.responsecode = responsecode; 37699 37700 vo._tfinish = tfinish; 37701 vo._stream = mediaType; 37702 vo._mediaduration = mediaduration; 37703 vo._responseHeaders = responseHeaders; 37704 vo._serviceLocation = serviceLocation; 37705 37706 if (traces) { 37707 traces.forEach(function (trace) { 37708 appendHttpTrace(vo, trace.s, trace.d, trace.b); 37709 }); 37710 } else { 37711 // The interval and trace shall be absent for redirect and failure records. 37712 delete vo.interval; 37713 delete vo.trace; 37714 } 37715 37716 pushAndNotify(mediaType, _constantsMetricsConstants2['default'].HTTP_REQUEST, vo); 37717 37718 return vo; 37719 } 37720 37721 function addRepresentationSwitch(mediaType, t, mt, to, lto) { 37722 var vo = new _voMetricsRepresentationSwitch2['default'](); 37723 37724 vo.t = t; 37725 vo.mt = mt; 37726 vo.to = to; 37727 37728 if (lto) { 37729 vo.lto = lto; 37730 } else { 37731 delete vo.lto; 37732 } 37733 37734 pushAndNotify(mediaType, _constantsMetricsConstants2['default'].TRACK_SWITCH, vo); 37735 37736 return vo; 37737 } 37738 37739 function pushAndNotify(mediaType, metricType, metricObject) { 37740 pushMetrics(mediaType, metricType, metricObject); 37741 metricAdded(mediaType, metricType, metricObject); 37742 } 37743 37744 function addBufferLevel(mediaType, t, level) { 37745 var vo = new _voMetricsBufferLevel2['default'](); 37746 vo.t = t; 37747 vo.level = level; 37748 37749 pushAndNotify(mediaType, _constantsMetricsConstants2['default'].BUFFER_LEVEL, vo); 37750 37751 return vo; 37752 } 37753 37754 function addBufferState(mediaType, state, target) { 37755 var vo = new _voMetricsBufferState2['default'](); 37756 vo.target = target; 37757 vo.state = state; 37758 37759 pushAndNotify(mediaType, _constantsMetricsConstants2['default'].BUFFER_STATE, vo); 37760 37761 return vo; 37762 } 37763 37764 function addDVRInfo(mediaType, currentTime, mpd, range) { 37765 var vo = new _voMetricsDVRInfo2['default'](); 37766 vo.time = currentTime; 37767 vo.range = range; 37768 vo.manifestInfo = mpd; 37769 37770 pushAndNotify(mediaType, _constantsMetricsConstants2['default'].DVR_INFO, vo); 37771 37772 return vo; 37773 } 37774 37775 function addDroppedFrames(mediaType, quality) { 37776 var vo = new _voMetricsDroppedFrames2['default'](); 37777 var list = getMetricsFor(mediaType).DroppedFrames; 37778 37779 vo.time = quality.creationTime; 37780 vo.droppedFrames = quality.droppedVideoFrames; 37781 37782 if (list.length > 0 && list[list.length - 1] == vo) { 37783 return list[list.length - 1]; 37784 } 37785 37786 pushAndNotify(mediaType, _constantsMetricsConstants2['default'].DROPPED_FRAMES, vo); 37787 37788 return vo; 37789 } 37790 37791 function addSchedulingInfo(mediaType, t, type, startTime, availabilityStartTime, duration, quality, range, state) { 37792 var vo = new _voMetricsSchedulingInfo2['default'](); 37793 37794 vo.mediaType = mediaType; 37795 vo.t = t; 37796 37797 vo.type = type; 37798 vo.startTime = startTime; 37799 vo.availabilityStartTime = availabilityStartTime; 37800 vo.duration = duration; 37801 vo.quality = quality; 37802 vo.range = range; 37803 37804 vo.state = state; 37805 37806 pushAndNotify(mediaType, _constantsMetricsConstants2['default'].SCHEDULING_INFO, vo); 37807 37808 return vo; 37809 } 37810 37811 function addRequestsQueue(mediaType, loadingRequests, executedRequests) { 37812 var vo = new _voMetricsRequestsQueue2['default'](); 37813 vo.loadingRequests = loadingRequests; 37814 vo.executedRequests = executedRequests; 37815 37816 getMetricsFor(mediaType).RequestsQueue = vo; 37817 metricAdded(mediaType, _constantsMetricsConstants2['default'].REQUESTS_QUEUE, vo); 37818 } 37819 37820 function addManifestUpdate(mediaType, type, requestTime, fetchTime, availabilityStartTime, presentationStartTime, clientTimeOff
37820set, currentTime, buffered, latency) { 37821 var vo = new _voMetricsManifestUpdate.ManifestUpdate(); 37822 37823 vo.mediaType = mediaType; 37824 vo.type = type; 37825 vo.requestTime = requestTime; // when this manifest update was requested 37826 vo.fetchTime = fetchTime; // when this manifest update was received 37827 vo.availabilityStartTime = availabilityStartTime; 37828 vo.presentationStartTime = presentationStartTime; // the seek point (liveEdge for dynamic, Stream[0].startTime for static) 37829 vo.clientTimeOffset = clientTimeOffset; // the calculated difference between the server and client wall clock time 37830 vo.currentTime = currentTime; // actual element.currentTime 37831 vo.buffered = buffered; // actual element.ranges 37832 vo.latency = latency; // (static is fixed value of zero. dynamic should be ((Now-@availabilityStartTime) - currentTime) 37833 37834 pushMetrics(_constantsConstants2['default'].STREAM, _constantsMetricsConstants2['default'].MANIFEST_UPDATE, vo); 37835 metricAdded(mediaType, _constantsMetricsConstants2['default'].MANIFEST_UPDATE, vo); 37836 37837 return vo; 37838 } 37839 37840 function updateManifestUpdateInfo(manifestUpdate, updatedFields) { 37841 if (manifestUpdate) { 37842 for (var field in updatedFields) { 37843 manifestUpdate[field] = updatedFields[field]; 37844 } 37845 37846 metricUpdated(manifestUpdate.mediaType, _constantsMetricsConstants2['default'].MANIFEST_UPDATE, manifestUpdate); 37847 } 37848 } 37849 37850 function addManifestUpdateStreamInfo(manifestUpdate, id, index, start, duration) { 37851 if (manifestUpdate) { 37852 var vo = new _voMetricsManifestUpdate.ManifestUpdateStreamInfo(); 37853 37854 vo.id = id; 37855 vo.index = index; 37856 vo.start = start; 37857 vo.duration = duration; 37858 37859 manifestUpdate.streamInfo.push(vo); 37860 metricUpdated(manifestUpdate.mediaType, _constantsMetricsConstants2['default'].MANIFEST_UPDATE_STREAM_INFO, manifestUpdate); 37861 37862 return vo; 37863 } 37864 return null; 37865 } 37866 37867 function addManifestUpdateRepresentationInfo(manifestUpdate, id, index, streamIndex, mediaType, presentationTimeOffset, startNumber, fragmentInfoType) { 37868 if (manifestUpdate) { 37869 37870 var vo = new _voMetricsManifestUpdate.ManifestUpdateRepresentationInfo(); 37871 vo.id = id; 37872 vo.index = index; 37873 vo.streamIndex = streamIndex; 37874 vo.mediaType = mediaType; 37875 vo.startNumber = startNumber; 37876 vo.fragmentInfoType = fragmentInfoType; 37877 vo.presentationTimeOffset = presentationTimeOffset; 37878 37879 manifestUpdate.representationInfo.push(vo); 37880 metricUpdated(manifestUpdate.mediaType, _constantsMetricsConstants2['default'].MANIFEST_UPDATE_TRACK_INFO, manifestUpdate); 37881 37882 return vo; 37883 } 37884 return null; 37885 } 37886 37887 function addPlayList(vo) { 37888 var type = _constantsConstants2['default'].STREAM; 37889 37890 if (vo.trace && Array.isArray(vo.trace)) { 37891 vo.trace.forEach(function (trace) { 37892 if (trace.hasOwnProperty('subreplevel') && !trace.subreplevel) { 37893 delete trace.subreplevel; 37894 } 37895 }); 37896 } else { 37897 delete vo.trace; 37898 } 37899 37900 pushAndNotify(type, _constantsMetricsConstants2['default'].PLAY_LIST, vo); 37901 37902 return vo; 37903 } 37904 37905 function addDVBErrors(vo) { 37906 var type = _constantsConstants2['default'].STREAM; 37907 37908 pushAndNotify(type, _constantsMetricsConstants2['default'].DVB_ERRORS, vo); 37909 37910 return vo; 37911 } 37912 37913 instance = { 37914 clearCurrentMetricsForType: clearCurrentMetricsForType, 37915 clearAllCurrentMetrics: clearAllCurrentMetrics, 37916 getReadOnlyMetricsFor: getReadOnlyMetricsFor, 37917 getMetricsFor: getMetricsFor, 37918 addTcpConnection: addTcpConnection, 37919 addHttpRequest: addHttpRequest, 37920 addRepresentationSwitch: addRepresentationSwitch, 37921 addBufferLevel: addBufferLevel, 37922 addBufferState: addBufferState, 37923 addDVRInfo: addDVRInfo, 37924 addDroppedFrames: addDroppedFrames, 37925 addSchedulingInfo: addSchedulingInfo, 37926 addRequestsQueue: addRequestsQueue, 37927 addManifestUpdate: addManifestUpdate, 37928 updateManifestUpdateInfo: updateManifestUpdateInfo, 37929 addManifestUpdateStreamInfo: addManifestUpdateStreamInfo, 37930 addManifestUpdateRepresentationInfo: addManifestUpdateRepresentationInfo, 37931 addPlayList: addPlayList, 37932 addDVBErrors: addDVBErrors, 37933 setConfig: setConfig 37934 }; 37935 37936 setup(); 37937 return instance; 37938} 37939 37940MetricsModel.__dashjs_factory_name = 'MetricsModel'; 37941exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(MetricsModel); 37942module.exports = exports['default']; 37943 37944},{"100":100,"101":101,"214":214,"220":220,"221":221,"222":222,"223":223,"224":224,"225":225,"227":227,"228":228,"229":229,"230":230,"50":50,"51":51,"54":54}],144:[function(_dereq_,module,exports){ 37945/** 37946 * The copyright in this software is being made available under the BSD License, 37947 * included below. This software may be subject to other third party and contributor 37948 * rights, including patent rights, and no such rights are granted under this license. 37949 * 37950 * Copyright (c) 2013, Dash Industry Forum. 37951 * All rights reserved. 37952 * 37953 * Redistribution and use in source and binary forms, with or without modification, 37954 * are permitted provided that the following conditions are met: 37955 * * Redistributions of source code must retain the above copyright notice, this 37956 * list of conditions and the following disclaimer. 37957 * * Redistributions in binary form must reproduce the above copyright notice, 37958 * this list of conditions and the following disclaimer in the documentation and/or 37959 * other materials provided with the distribution. 37960 * * Neither the name of Dash Industry Forum nor the names of its 37961 * contributors may be used to endorse or promote products derived from this software 37962 * without specific prior written permission. 37963 * 37964 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 37965 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 37966 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 37967 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 37968 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
37968INCLUDING, BUT 37969 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 37970 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 37971 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37972 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37973 * POSSIBILITY OF SUCH DAMAGE. 37974 */ 37975 37976'use strict'; 37977 37978Object.defineProperty(exports, '__esModule', { 37979 value: true 37980}); 37981 37982function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 37983 37984var _voURIFragmentData = _dereq_(219); 37985 37986var _voURIFragmentData2 = _interopRequireDefault(_voURIFragmentData); 37987 37988var _coreFactoryMaker = _dereq_(51); 37989 37990var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 37991 37992function URIQueryAndFragmentModel() { 37993 37994 var instance = undefined, 37995 URIFragmentDataVO = undefined, 37996 URIQueryData = undefined, 37997 isHTTPS = undefined; 37998 37999 function initialize() { 38000 URIFragmentDataVO = new _voURIFragmentData2['default'](); 38001 URIQueryData = []; 38002 isHTTPS = false; 38003 } 38004 38005 function getURIFragmentData() { 38006 return URIFragmentDataVO; 38007 } 38008 38009 function getURIQueryData() { 38010 return URIQueryData; 38011 } 38012 38013 function isManifestHTTPS() { 38014 return isHTTPS; 38015 } 38016 38017 function parseURI(uri) { 38018 if (!uri) return null; 38019 38020 var URIFragmentData = []; 38021 var mappedArr = undefined; 38022 38023 var testQuery = new RegExp(/[?]/); 38024 var testFragment = new RegExp(/[#]/); 38025 var testHTTPS = new RegExp(/^(https:)?\/\//i); 38026 var isQuery = testQuery.test(uri); 38027 var isFragment = testFragment.test(uri); 38028 38029 isHTTPS = testHTTPS.test(uri); 38030 38031 function reduceArray(previousValue, currentValue, index, array) { 38032 var arr = array[0].split(/[=]/); 38033 array.push({ key: arr[0], value: arr[1] }); 38034 array.shift(); 38035 return array; 38036 } 38037 38038 function mapArray(currentValue, index, array) { 38039 if (index > 0) { 38040 if (isQuery && URIQueryData.length === 0) { 38041 URIQueryData = array[index].split(/[&]/); 38042 } else if (isFragment) { 38043 URIFragmentData = array[index].split(/[&]/); 38044 } 38045 } 38046 38047 return array; 38048 } 38049 38050 mappedArr = uri.split(/[?#]/).map(mapArray); 38051 38052 if (URIQueryData.length > 0) { 38053 URIQueryData = URIQueryData.reduce(reduceArray, null); 38054 } 38055 38056 if (URIFragmentData.length > 0) { 38057 URIFragmentData = URIFragmentData.reduce(reduceArray, null); 38058 URIFragmentData.forEach(function (object) { 38059 URIFragmentDataVO[object.key] = object.value; 38060 }); 38061 } 38062 38063 return uri; 38064 } 38065 38066 instance = { 38067 initialize: initialize, 38068 parseURI: parseURI, 38069 getURIFragmentData: getURIFragmentData, 38070 getURIQueryData: getURIQueryData, 38071 isManifestHTTPS: isManifestHTTPS 38072 }; 38073 38074 return instance; 38075} 38076 38077URIQueryAndFragmentModel.__dashjs_factory_name = 'URIQueryAndFragmentModel'; 38078exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(URIQueryAndFragmentModel); 38079module.exports = exports['default']; 38080 38081},{"219":219,"51":51}],145:[function(_dereq_,module,exports){ 38082/** 38083 * The copyright in this software is being made available under the BSD License, 38084 * included below. This software may be subject to other third party and contributor 38085 * rights, including patent rights, and no such rights are granted under this license. 38086 * 38087 * Copyright (c) 2013, Dash Industry Forum. 38088 * All rights reserved. 38089 * 38090 * Redistribution and use in source and binary forms, with or without modification, 38091 * are permitted provided that the following conditions are met: 38092 * * Redistributions of source code must retain the above copyright notice, this 38093 * list of conditions and the following disclaimer. 38094 * * Redistributions in binary form must reproduce the above copyright notice, 38095 * this list of conditions and the following disclaimer in the documentation and/or 38096 * other materials provided with the distribution. 38097 * * Neither the name of Dash Industry Forum nor the names of its 38098 * contributors may be used to endorse or promote products derived from this software 38099 * without specific prior written permission. 38100 * 38101 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 38102 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 38103 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 38104 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 38105 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
38105INCLUDING, BUT 38106 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 38107 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 38108 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38109 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38110 * POSSIBILITY OF SUCH DAMAGE. 38111 */ 38112 38113'use strict'; 38114 38115Object.defineProperty(exports, '__esModule', { 38116 value: true 38117}); 38118 38119function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 38120 38121var _coreFactoryMaker = _dereq_(51); 38122 38123var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 38124 38125var _coreEventBus = _dereq_(50); 38126 38127var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 38128 38129var _coreEventsEvents = _dereq_(54); 38130 38131var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 38132 38133var _coreDebug = _dereq_(49); 38134 38135var _coreDebug2 = _interopRequireDefault(_coreDebug); 38136 38137function VideoModel() { 38138 38139 var instance = undefined, 38140 element = undefined, 38141 TTMLRenderingDiv = undefined, 38142 videoContainer = undefined,
38143 stalledStreams = undefined, 38144 previousPlaybackRate = undefined; 38145 38146 var context = this.context; 38147 var log = (0, _coreDebug2['default'])(context).getInstance().log; 38148 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 38149 38150 function initialize() { 38151 stalledStreams = []; 38152 } 38153 38154 function onPlaybackCanPlay() { 38155 element.playbackRate = previousPlaybackRate || 1; 38156 element.removeEventListener('canplay', onPlaybackCanPlay); 38157 } 38158 38159 function setPlaybackRate(value) { 38160 if (!element) return; 38161 if (element.readyState <= 2 && value > 0) { 38162 // If media element hasn't loaded enough data to play yet, wait until it has 38163 element.addEventListener('canplay', onPlaybackCanPlay); 38164 } else { 38165 element.playbackRate = value; 38166 } 38167 } 38168 38169 //TODO Move the DVR window calculations from MediaPlayer to Here. 38170 function setCurrentTime(currentTime) { 38171 //_currentTime = currentTime; 38172 38173 // We don't set the same currentTime because it can cause firing unexpected Pause event in IE11 38174 // providing playbackRate property equals to zero. 38175 if (element.currentTime == currentTime) return; 38176 38177 // TODO Despite the fact that MediaSource 'open' event has been fired IE11 cannot set videoElement.currentTime 38178 // immediately (it throws InvalidStateError). It seems that this is related to videoElement.readyState property 38179 // Initially it is 0, but soon after 'open' event it goes to 1 and setting currentTime is allowed. Chrome allows to 38180 // set currentTime even if readyState = 0. 38181 // setTimeout is used to workaround InvalidStateError in IE11 38182 try { 38183 element.currentTime = currentTime; 38184 } catch (e) { 38185 if (element.readyState === 0 && e.code === e.INVALID_STATE_ERR) { 38186 setTimeout(function () { 38187 element.currentTime = currentTime; 38188 }, 400); 38189 } 38190 } 38191 } 38192 38193 function getElement() { 38194 return element; 38195 } 38196 38197 function setElement(value) { 38198 element = value; 38199 // Workaround to force Firefox to fire the canplay event. 38200 element.preload = 'auto'; 38201 } 38202 38203 function setSource(source) { 38204 if (source) { 38205 element.src = source; 38206 } else { 38207 element.removeAttribute('src'); 38208 element.load(); 38209 } 38210 } 38211 38212 function getSource() { 38213 return element.src; 38214 } 38215 38216 function getVideoContainer() { 38217 return videoContainer; 38218 } 38219 38220 function setVideoContainer(value) { 38221 videoContainer = value; 38222 } 38223 38224 function getTTMLRenderingDiv() { 38225 return TTMLRenderingDiv; 38226 } 38227 38228 function setTTMLRenderingDiv(div) { 38229 TTMLRenderingDiv = div; 38230 // The styling will allow the captions to match the video window size and position. 38231 TTMLRenderingDiv.style.position = 'absolute'; 38232 TTMLRenderingDiv.style.display = 'flex'; 38233 TTMLRenderingDiv.style.overflow = 'hidden'; 38234 TTMLRenderingDiv.style.pointerEvents = 'none'; 38235 TTMLRenderingDiv.style.top = 0; 38236 TTMLRenderingDiv.style.left = 0; 38237 } 38238 38239 function setStallState(type, state) { 38240 stallStream(type, state); 38241 } 38242 38243 function isStalled() {
38244 return stalledStreams.length > 0; 38245 } 38246 38247 function addStalledStream(type) { 38248 38249 var event = undefined; 38250 38251 if (type === null || element.seeking || stalledStreams.indexOf(type) !== -1) { 38252 return; 38253 } 38254 38255 stalledStreams.push(type); 38256 if (stalledStreams.length === 1) { 38257 // Halt playback until nothing is stalled. 38258 event = document.createEvent('Event'); 38259 event.initEvent('waiting', true, false); 38260 previousPlaybackRate = element.playbackRate; 38261 setPlaybackRate(0); 38262 element.dispatchEvent(event); 38263 } 38264 } 38265 38266 function removeStalledStream(type) { 38267 var index = stalledStreams.indexOf(type); 38268 var event = undefined; 38269 38270 if (type === null) { 38271 return; 38272 } 38273 if (index !== -1) { 38274 stalledStreams.splice(index, 1); 38275 } 38276 // If nothing is stalled resume playback. 38277 if (isStalled() === false && element.playbackRate === 0) { 38278 setPlaybackRate(previousPlaybackRate || 1); 38279 if (!element.paused) { 38280 event = document.createEvent('Event'); 38281 event.initEvent('playing', true, false); 38282 element.dispatchEvent(event); 38283 } 38284 } 38285 } 38286 38287 function stallStream(type, isStalled) { 38288 if (isStalled) { 38289 addStalledStream(type); 38290 } else { 38291 removeStalledStream(type); 38292 } 38293 } 38294 38295 function getPlaybackQuality() { 38296 var hasWebKit = 'webkitDroppedFrameCount' in element && 'webkitDecodedFrameCount' in element; 38297 var hasQuality = ('getVideoPlaybackQuality' in element); 38298 var result = null; 38299 38300 if (hasQuality) { 38301 result = element.getVideoPlaybackQuality(); 38302 } else if (hasWebKit) { 38303 result = { 38304 droppedVideoFrames: element.webkitDroppedFrameCount, 38305 totalVideoFrames: element.webkitDroppedFrameCount + element.webkitDecodedFrameCount, 38306 creationTime: new Date() 38307 }; 38308 } 38309 38310 return result; 38311 } 38312 38313 function play() { 38314 if (element) { 38315 element.autoplay = true; 38316 var p = element.play(); 38317 if (p && typeof Promise !== 'undefined' && p instanceof Promise) { 38318 p['catch'](function (e) { 38319 if (e.name === 'NotAllowedError') { 38320 eventBus.trigger(_coreEventsEvents2['default'].PLAYBACK_NOT_ALLOWED); 38321 } 38322 log('Caught pending play exception - continuing (' + e + ')'); 38323 }); 38324 } 38325 } 38326 } 38327 38328 function isPaused() { 38329 return element ? element.paused : null; 38330 } 38331 38332 function pause() { 38333 if (element) { 38334 element.pause(); 38335 element.autoplay = false; 38336 } 38337 } 38338 38339 function isSeeking() { 38340 return element ? element.seeking : null; 38341 } 38342 38343 function getTime() { 38344 return element ? element.currentTime : null; 38345 } 38346 38347 function getPlaybackRate() { 38348 return element ? element.playbackRate : null; 38349 } 38350 38351 function getPlayedRanges() { 38352 return element ? element.played : null; 38353 } 38354 38355 function getEnded() { 38356 return element ? element.ended : null; 38357 } 38358 38359 function addEventListener(eventName, eventCallBack) { 38360 if (element) { 38361 element.addEventListener(eventName, eventCallBack); 38362 } 38363 } 38364 38365 function removeEventListener(eventName, eventCallBack) { 38366 if (element) { 38367 element.removeEventListener(eventName, eventCallBack); 38368 } 38369 } 38370 38371 function getReadyState() { 38372 return element ? element.readyState : NaN; 38373 } 38374 38375 function getBufferRange() { 38376 return element ? element.buffered : null; 38377 } 38378 38379 function getClientWidth() { 38380 return element ? element.clientWidth : NaN; 38381 } 38382 38383 function getClientHeight() { 38384 return element ? element.clientHeight : NaN; 38385 } 38386 38387 function getVideoWidth() { 38388 return element ? element.videoWidth : NaN; 38389 } 38390 38391 function getVideoHeight() { 38392 return element ? element.videoHeight : NaN; 38393 } 38394 38395 function getTextTracks() { 38396 return element ? element.textTracks : []; 38397 } 38398 38399 function getTextTrack(kind, label, lang) { 38400 if (element) { 38401 for (var i = 0; i < element.textTracks.length; i++) { 38402 //label parameter could be a number (due to adaptationSet), but label, the attribute of textTrack, is a string => to modify... 38403 //label could also be undefined (due to adaptationSet) 38404 if (element.textTracks[i].kind === kind && (label ? element.textTracks[i].label == label : true) && element.textTracks[i].language === lang) { 38405 return element.textTracks[i]; 38406 } 38407 } 38408 } 38409 38410 return null; 38411 } 38412 38413 function addTextTrack(kind, label, lang) { 38414 if (element) { 38415 return element.addTextTrack(kind, label, lang); 38416 } 38417 return null; 38418 } 38419 38420 function appendChild(childElement) { 38421 if (element) { 38422 element.appendChild(childElement); 38423 } 38424 } 38425 38426 function removeChild(childElement) { 38427 if (element) { 38428 element.removeChild(childElement); 38429 } 38430 } 38431 38432 instance = { 38433 initialize: initialize, 38434 setCurrentTime: setCurrentTime, 38435 play: play, 38436 isPaused: isPaused, 38437 pause: pause, 38438 isSeeking: isSeeking, 38439 getTime: getTime, 38440 getPlaybackRate: getPlaybackRate, 38441 getPlayedRanges: getPlayedRanges, 38442 getEnded: getEnded, 38443 setStallState: setStallState, 38444 getElement: getElement, 38445 setElement: setElement, 38446 setSource: setSource, 38447 getSource: getSource, 38448 getVideoContainer: getVideoContainer, 38449 setVideoContainer: setVideoContainer, 38450 getTTMLRenderingDiv: getTTMLRenderingDiv, 38451 setTTMLRenderingDiv: setTTMLRenderingDiv, 38452 getPlaybackQuality: getPlaybackQuality, 38453 addEventListener: addEventListener, 38454 removeEventListener: removeEventListener, 38455 getReadyState: getReadyState, 38456 getBufferRange: getBufferRange, 38457 getClientWidth: getClientWidth, 38458 getClientHeight: getClientHeight, 38459 getTextTracks: getTextTracks, 38460 getTextTrack: getTextTrack, 38461 addTextTrack: addTextTrack, 38462 appendChild: appendChild, 38463 removeChild: removeChild, 38464 getVideoWidth: getVideoWidth, 38465 getVideoHeight: getVideoHeight 38466 }; 38467 38468 return instance; 38469} 38470 38471VideoModel.__dashjs_factory_name = 'VideoModel'; 38472exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(VideoModel); 38473module.exports = exports['default']; 38474 38475},{"49":49,"50":50,"51":51,"54":54}],146:[function(_dereq_,module,exports){ 38476/** 38477 * The copyright in this software is being made available under the BSD License, 38478 * included below. This software may be subject to other third party and contributor 38479 * rights, including patent rights, and no such rights are granted under this license. 38480 * 38481 * Copyright (c) 2013, Dash Industry Forum. 38482 * All rights reserved. 38483 * 38484 * Redistribution and use in source and binary forms, with or without modification, 38485 * are permitted provided that the following conditions are met: 38486 * * Redistributions of source code must retain the above copyright notice, this 38487 * list of conditions and the following disclaimer. 38488 * * Redistributions in binary form must reproduce the above copyright notice, 38489 * this list of conditions and the following disclaimer in the documentation and/or 38490 * other materials provided with the distribution. 38491 * * Neither the name of Dash Industry Forum nor the names of its 38492 * contributors may be used to endorse or promote products derived from this software 38493 * without specific prior written permission. 38494 * 38495 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 38496 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 38497 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 38498 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 38499 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
38499INCLUDING, BUT 38500 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 38501 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 38502 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38503 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38504 * POSSIBILITY OF SUCH DAMAGE. 38505 */ 38506 38507'use strict'; 38508 38509Object.defineProperty(exports, '__esModule', { 38510 value: true 38511}); 38512 38513var _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; }; })(); 38514 38515function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 38516 38517var CommonEncryption = (function () { 38518 function CommonEncryption() { 38519 _classCallCheck(this, CommonEncryption); 38520 } 38521 38522 _createClass(CommonEncryption, null, [{ 38523 key: 'findCencContentProtection', 38524 38525 /**
38526 * Find and return the ContentProtection element in the given array 38527 * that indicates support for MPEG Common Encryption 38528 * 38529 * @param {Array} cpArray array of content protection elements 38530 * @returns {Object|null} the Common Encryption content protection element or 38531 * null if one was not found 38532 */ 38533 value: function findCencContentProtection(cpArray) { 38534 var retVal = null; 38535 for (var i = 0; i < cpArray.length; ++i) { 38536 var cp = cpArray[i]; 38537 if (cp.schemeIdUri.toLowerCase() === 'urn:mpeg:dash:mp4protection:2011' && cp.value.toLowerCase() === 'cenc') retVal = cp; 38538 } 38539 return retVal; 38540 } 38541 38542 /** 38543 * Returns just the data portion of a single PSSH 38544 * 38545 * @param {ArrayBuffer} pssh - the PSSH 38546 * @return {ArrayBuffer} data portion of the PSSH 38547 */ 38548 }, { 38549 key: 'getPSSHData', 38550 value: function getPSSHData(pssh) { 38551 var offset = 8; // Box size and type fields 38552 var view = new DataView(pssh); 38553 38554 // Read version 38555 var version = view.getUint8(offset); 38556 38557 offset += 20; // Version (1), flags (3), system ID (16) 38558 38559 if (version > 0) { 38560 offset += 4 + 16 * view.getUint32(offset); // Key ID count (4) and All key IDs (16*count) 38561 } 38562 38563 offset += 4; // Data size 38564 return pssh.slice(offset); 38565 } 38566 38567 /** 38568 * Returns the PSSH associated with the given key system from the concatenated 38569 * list of PSSH boxes in the given initData 38570 * 38571 * @param {KeySystem} keySystem the desired 38572 * key system 38573 * @param {ArrayBuffer} initData 'cenc' initialization data. Concatenated list of PSSH. 38574 * @returns {ArrayBuffer|null} The PSSH box data corresponding to the given key system, null if not found 38575 * or null if a valid association could not be found. 38576 */ 38577 }, { 38578 key: 'getPSSHForKeySystem', 38579 value: function getPSSHForKeySystem(keySystem, initData) { 38580 var psshList = CommonEncryption.parsePSSHList(initData); 38581 if (psshList.hasOwnProperty(keySystem.uuid.toLowerCase())) { 38582 return psshList[keySystem.uuid.toLowerCase()]; 38583 } 38584 return null; 38585 } 38586 38587 /** 38588 * Parse a standard common encryption PSSH which contains a simple 38589 * base64-encoding of the init data 38590 * 38591 * @param {Object} cpData the ContentProtection element 38592 * @param {BASE64} BASE64 reference 38593 * @returns {ArrayBuffer|null} the init data or null if not found 38594 */ 38595 }, { 38596 key: 'parseInitDataFromContentProtection', 38597 value: function parseInitDataFromContentProtection(cpData, BASE64) { 38598 if ('pssh' in cpData) { 38599 return BASE64.decodeArray(cpData.pssh.__text).buffer; 38600 } 38601 return null; 38602 } 38603 38604 /** 38605 * Parses list of PSSH boxes into keysystem-specific PSSH data 38606 * 38607 * @param {ArrayBuffer} data - the concatenated list of PSSH boxes as provided by 38608 * CDM as initialization data when CommonEncryption content is detected 38609 * @returns {Object|Array} an object that has a property named according to each of 38610 * the detected key system UUIDs (e.g. 00000000-0000-0000-0000-0000000000) 38611 * and a ArrayBuffer (the entire PSSH box) as the property value 38612 */ 38613 }, { 38614 key: 'parsePSSHList', 38615 value: function parsePSSHList(data) { 38616 38617 if (data === null) return []; 38618 38619 var dv = new DataView(data); 38620 var done = false; 38621 var pssh = {}; 38622 38623 // TODO: Need to check every data read for end of buffer 38624 var byteCursor = 0; 38625 while (!done) { 38626 38627 var size = undefined, 38628 nextBox = undefined, 38629 version = undefined, 38630 systemID = undefined, 38631 psshDataSize = undefined; 38632 var boxStart = byteCursor; 38633 38634 if (byteCursor >= dv.buffer.byteLength) break; 38635 38636 /* Box size */ 38637 size = dv.getUint32(byteCursor); 38638 nextBox = byteCursor + size; 38639 byteCursor += 4; 38640 38641 /* Verify PSSH */ 38642 if (dv.getUint32(byteCursor) !== 0x70737368) { 38643 byteCursor = nextBox; 38644 continue; 38645 } 38646 byteCursor += 4; 38647 38648 /* Version must be 0 or 1 */ 38649 version = dv.getUint8(byteCursor); 38650 if (version !== 0 && version !== 1) { 38651 byteCursor = nextBox; 38652 continue; 38653 } 38654 byteCursor++; 38655 38656 byteCursor += 3; /* skip flags */ 38657 38658 // 16-byte UUID/SystemID 38659 systemID = ''; 38660 var i = undefined, 38661 val = undefined; 38662 for (i = 0; i < 4; i++) { 38663 val = dv.getUint8(byteCursor + i).toString(16); 38664 systemID += val.length === 1 ? '0' + val : val; 38665 } 38666 byteCursor += 4; 38667 systemID += '-'; 38668 for (i = 0; i < 2; i++) { 38669 val = dv.getUint8(byteCursor + i).toString(16); 38670 systemID += val.length === 1 ? '0' + val : val; 38671 } 38672 byteCursor += 2; 38673 systemID += '-'; 38674 for (i = 0; i < 2; i++) { 38675 val = dv.getUint8(byteCursor + i).toString(16); 38676 systemID += val.length === 1 ? '0' + val : val; 38677 } 38678 byteCursor += 2; 38679 systemID += '-'; 38680 for (i = 0; i < 2; i++) { 38681 val = dv.getUint8(byteCursor + i).toString(16); 38682 systemID += val.length === 1 ? '0' + val : val; 38683 } 38684 byteCursor += 2; 38685 systemID += '-'; 38686 for (i = 0; i < 6; i++) { 38687 val = dv.getUint8(byteCursor + i).toString(16); 38688 systemID += val.length === 1 ? '0' + val : val; 38689 } 38690 byteCursor += 6; 38691 38692 systemID = systemID.toLowerCase(); 38693 38694 /* PSSH Data Size */ 38695 psshDataSize = dv.getUint32(byteCursor); 38696 byteCursor += 4; 38697 38698 /* PSSH Data */ 38699 pssh[systemID] = dv.buffer.slice(boxStart, nextBox); 38700 byteCursor = nextBox; 38701 } 38702 38703 return pssh; 38704 } 38705 }]); 38706 38707 return CommonEncryption; 38708})(); 38709 38710exports['default'] = CommonEncryption; 38711module.exports = exports['default']; 38712 38713},{}],147:[function(_dereq_,module,exports){ 38714/** 38715 * The copyright in this software is being made available under the BSD License, 38716 * included below. This software may be subject to other third party and contributor 38717 * rights, including patent rights, and no such rights are granted under this license. 38718 * 38719 * Copyright (c) 2013, Dash Industry Forum. 38720 * All rights reserved. 38721 * 38722 * Redistribution and use in source and binary forms, with or without modification, 38723 * are permitted provided that the following conditions are met: 38724 * * Redistributions of source code must retain the above copyright notice, this 38725 * list of conditions and the following disclaimer. 38726 * * Redistributions in binary form must reproduce the above copyright notice, 38727 * this list of conditions and the following disclaimer in the documentation and/or 38728 * other materials provided with the distribution. 38729 * * Neither the name of Dash Industry Forum nor the names of its 38730 * contributors may be used to endorse or promote products derived from this software 38731 * without specific prior written permission. 38732 * 38733 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 38734 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 38735 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 38736 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 38737 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
38737INCLUDING, BUT 38738 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 38739 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 38740 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38741 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38742 * POSSIBILITY OF SUCH DAMAGE. 38743 */ 38744'use strict'; 38745 38746Object.defineProperty(exports, '__esModule', { 38747 value: true 38748}); 38749 38750function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 38751 38752var _controllersProtectionController = _dereq_(149); 38753 38754var _controllersProtectionController2 = _interopRequireDefault(_controllersProtectionController); 38755 38756var _controllersProtectionKeyController = _dereq_(150); 38757 38758var _controllersProtectionKeyController2 = _interopRequireDefault(_controllersProtectionKeyController); 38759 38760var _ProtectionEvents = _dereq_(148); 38761 38762var _ProtectionEvents2 = _interopRequireDefault(_ProtectionEvents); 38763 38764var _modelsProtectionModel_21Jan2015 = _dereq_(155); 38765 38766var _modelsProtectionModel_21Jan20152 = _interopRequireDefault(_modelsProtectionModel_21Jan2015); 38767 38768var _modelsProtectionModel_3Feb2014 = _dereq_(156); 38769 38770var _modelsProtectionModel_3Feb20142 = _interopRequireDefault(_modelsProtectionModel_3Feb2014); 38771 38772var _modelsProtectionModel_01b = _dereq_(154); 38773 38774var _modelsProtectionModel_01b2 = _interopRequireDefault(_modelsProtectionModel_01b); 38775 38776var APIS_ProtectionModel_01b = [ 38777// Un-prefixed as per spec 38778{ 38779 // Video Element 38780 generateKeyRequest: 'generateKeyRequest', 38781 addKey: 'addKey', 38782 cancelKeyRequest: 'cancelKeyRequest', 38783 38784 // Events 38785 needkey: 'needkey', 38786 keyerror: 'keyerror', 38787 keyadded: 'keyadded', 38788 keymessage: 'keymessage' 38789}, 38790// Webkit-prefixed (early Chrome versions and Chrome with EME disabled in chrome://flags) 38791{ 38792 // Video Element 38793 generateKeyRequest: 'webkitGenerateKeyRequest', 38794 addKey: 'webkitAddKey', 38795 cancelKeyRequest: 'webkitCancelKeyRequest', 38796 38797 // Events 38798 needkey: 'webkitneedkey', 38799 keyerror: 'webkitkeyerror', 38800 keyadded: 'webkitkeyadded', 38801 keymessage: 'webkitkeymessage' 38802}]; 38803 38804var APIS_ProtectionModel_3Feb2014 = [ 38805// Un-prefixed as per spec 38806// Chrome 38-39 (and some earlier versions) with chrome://flags -- Enable Encrypted Media Extensions 38807{ 38808 // Video Element 38809 setMediaKeys: 'setMediaKeys', 38810 // MediaKeys 38811 MediaKeys: 'MediaKeys', 38812 // MediaKeySession 38813 release: 'close', 38814 38815 // Events 38816 needkey: 'needkey', 38817 error: 'keyerror', 38818 message: 'keymessage', 38819 ready: 'keyadded', 38820 close: 'keyclose' 38821}, 38822// MS-prefixed (IE11, Windows 8.1) 38823{ 38824 // Video Element 38825 setMediaKeys: 'msSetMediaKeys', 38826 // MediaKeys 38827 MediaKeys: 'MSMediaKeys', 38828 // MediaKeySession 38829 release: 'close', 38830 // Events 38831 needkey: 'msneedkey', 38832 error: 'mskeyerror', 38833 message: 'mskeymessage', 38834 ready: 'mskeyadded', 38835 close: 'mskeyclose' 38836}]; 38837 38838function Protection() { 38839 38840 var instance = undefined; 38841 var context = this.context; 38842 38843 /** 38844 * Create a ProtectionController and associated ProtectionModel for use with 38845 * a single piece of content. 38846 * 38847 * @param {Object} config 38848 * @return {ProtectionController} protection controller 38849 * 38850 */ 38851 function createProtectionSystem(config) { 38852 38853 var controller = null; 38854 38855 var protectionKeyController = (0, _controllersProtectionKeyController2['default'])(context).getInstance(); 38856 protectionKeyController.setConfig({ log: config.log, BASE64: config.BASE64 }); 38857 protectionKeyController.initialize(); 38858 38859 var protectionModel = getProtectionModel(config); 38860 38861 if (!controller && protectionModel) { 38862 //TODO add ability to set external controller if still needed at all? 38863 controller = (0, _controllersProtectionController2['default'])(context).create({ 38864 protectionModel: protectionModel, 38865 protectionKeyController: protectionKeyController, 38866 adapter: config.adapter, 38867 eventBus: config.eventBus, 38868 log: config.log, 38869 events: config.events, 38870 BASE64: config.BASE64, 38871 Constants: config.Constants 38872 }); 38873 config.capabilities.setEncryptedMediaSupported(true); 38874 } 38875 return controller; 38876 } 38877 38878 function getProtectionModel(config) { 38879 38880 var log = config.log; 38881 var eventBus = config.eventBus; 38882 var errHandler = config.errHandler; 38883 var videoElement = config.videoModel.getElement(); 38884 38885 if (videoElement.onencrypted !== undefined && videoElement.mediaKeys !== undefined && navigator.requestMediaKeySystemAccess !== undefined && typeof navigator.requestMediaKeySystemAccess === 'function') { 38886 38887 log('EME detected on this user agent! (ProtectionModel_21Jan2015)'); 38888 return (0, _modelsProtectionModel_21Jan20152['default'])(context).create({ log: log, eventBus: eventBus, events: config.events }); 38889 } else if (getAPI(videoElement, APIS_ProtectionModel_3Feb2014)) { 38890 38891 log('EME detected on this user agent! (ProtectionModel_3Feb2014)'); 38892 return (0, _modelsProtectionModel_3Feb20142['default'])(context).create({ log: log, eventBus: eventBus, events: config.events, api: getAPI(videoElement, APIS_ProtectionModel_3Feb2014) }); 38893 } else if (getAPI(videoElement, APIS_ProtectionModel_01b)) { 38894 38895 log('EME detected on this user agent! (ProtectionModel_01b)'); 38896 return (0, _modelsProtectionModel_01b2['default'])(context).create({ log: log, eventBus: eventBus, errHandler: errHandler, events: config.events, api: getAPI(videoElement, APIS_ProtectionModel_01b) }); 38897 } else { 38898 38899 log('No supported version of EME detected on this user agent! - Attempts to play encrypted content will fail!'); 38900 return null; 38901 } 38902 } 38903 38904 function getAPI(videoElement, apis) { 38905 38906 for (var i = 0; i < apis.length; i++) { 38907 var api = apis[i]; 38908 // detect if api is supported by browser 38909 // check only first function in api -> should be fine 38910 if (typeof videoElement[api[Object.keys(api)[0]]] !== 'function') { 38911 continue; 38912 } 38913 38914 return api; 38915 } 38916 38917 return null; 38918 } 38919 38920 instance = { 38921 createProtectionSystem: createProtectionSystem 38922 }; 38923 38924 return instance; 38925} 38926 38927Protection.__dashjs_factory_name = 'Protection'; 38928var factory = dashjs.FactoryMaker.getClassFactory(Protection); /* jshint ignore:line */ 38929factory.events = _ProtectionEvents2['default']; 38930dashjs.FactoryMaker.updateClassFactory(Protection.__dashjs_factory_name, factory); /* jshint ignore:line */ 38931exports['default'] = factory; 38932module.exports = exports['default']; 38933 38934},{"148":148,"149":149,"150":150,"154":154,"155":155,"156":156}],148:[function(_dereq_,module,exports){ 38935/** 38936 * The copyright in this software is being made available under the BSD License, 38937 * included below. This software may be subject to other third party and contributor 38938 * rights, including patent rights, and no such rights are granted under this license. 38939 * 38940 * Copyright (c) 2013, Dash Industry Forum. 38941 * All rights reserved. 38942 * 38943 * Redistribution and use in source and binary forms, with or without modification, 38944 * are permitted provided that the following conditions are met: 38945 * * Redistributions of source code must retain the above copyright notice, this 38946 * list of conditions and the following disclaimer. 38947 * * Redistributions in binary form must reproduce the above copyright notice, 38948 * this list of conditions and the following disclaimer in the documentation and/or 38949 * other materials provided with the distribution. 38950 * * Neither the name of Dash Industry Forum nor the names of its 38951 * contributors may be used to endorse or promote products derived from this software 38952 * without specific prior written permission. 38953 * 38954 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 38955 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 38956 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 38957 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 38958 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
38958INCLUDING, BUT 38959 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 38960 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 38961 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38962 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38963 * POSSIBILITY OF SUCH DAMAGE. 38964 */ 38965'use strict'; 38966 38967Object.defineProperty(exports, '__esModule', { 38968 value: true 38969}); 38970 38971var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 38972 38973function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 38974 38975function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 38976 38977function _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; } 38978 38979var _coreEventsEventsBase = _dereq_(55); 38980 38981var _coreEventsEventsBase2 = _interopRequireDefault(_coreEventsEventsBase); 38982 38983/** 38984 * @class 38985 * 38986 */ 38987 38988var ProtectionEvents = (function (_EventsBase) { 38989 _inherits(ProtectionEvents, _EventsBase); 38990 38991 /** 38992 * @description Public facing external events to be used when including protection package. 38993 * All public events will be aggregated into the MediaPlayerEvents Class and can be accessed 38994 * via MediaPlayer.events. public_ is the prefix that we use to move event names to MediaPlayerEvents. 38995 */ 38996 38997 function ProtectionEvents() { 38998 _classCallCheck(this, ProtectionEvents); 38999 39000 _get(Object.getPrototypeOf(ProtectionEvents.prototype), 'constructor', this).call(this); 39001 39002 /** 39003 * Event ID for events delivered when the protection set receives 39004 * a key message from the CDM 39005 * 39006 * @ignore 39007 */ 39008 this.INTERNAL_KEY_MESSAGE = 'internalKeyMessage'; 39009 39010 /** 39011 * Event ID for events delivered when a key system selection procedure 39012 * completes 39013 * @ignore 39014 */ 39015 this.INTERNAL_KEY_SYSTEM_SELECTED = 'internalKeySystemSelected'; 39016 39017 /** 39018 * Event ID for events delivered when a new key has been added 39019 * 39020 * @constant 39021 * @deprecated The latest versions of the EME specification no longer 39022 * use this event. {@MediaPlayer.models.protectionModel.eventList.KEY_STATUSES_CHANGED} 39023 * is preferred. 39024 * @event ProtectionEvents#KEY_ADDED 39025 */ 39026 this.KEY_ADDED = 'public_keyAdded'; 39027 /** 39028 * Event ID for events delivered when an error is encountered by the CDM 39029 * while processing a license server response message 39030 * @event ProtectionEvents#KEY_ERROR 39031 */ 39032 this.KEY_ERROR = 'public_keyError'; 39033 39034 /** 39035 * Event ID for events delivered when the protection set receives 39036 * a key message from the CDM 39037 * @event ProtectionEvents#KEY_MESSAGE 39038 */ 39039 this.KEY_MESSAGE = 'public_keyMessage'; 39040 39041 /** 39042 * Event ID for events delivered when a key session close 39043 * process has completed 39044 * @event ProtectionEvents#KEY_SESSION_CLOSED 39045 */ 39046 this.KEY_SESSION_CLOSED = 'public_keySessionClosed'; 39047 39048 /** 39049 * Event ID for events delivered when a new key sessions creation 39050 * process has completed 39051 * @event ProtectionEvents#KEY_SESSION_CREATED 39052 */ 39053 this.KEY_SESSION_CREATED = 'public_keySessionCreated'; 39054 39055 /** 39056 * Event ID for events delivered when a key session removal 39057 * process has completed 39058 * @event ProtectionEvents#KEY_SESSION_REMOVED 39059 */ 39060 this.KEY_SESSION_REMOVED = 'public_keySessionRemoved'; 39061 39062 /** 39063 * Event ID for events delivered when the status of one or more 39064 * decryption keys has changed 39065 * @event ProtectionEvents#KEY_STATUSES_CHANGED 39066 */ 39067 this.KEY_STATUSES_CHANGED = 'public_keyStatusesChanged'; 39068 39069 /** 39070 * Event ID for events delivered when a key system access procedure 39071 * has completed 39072 * @ignore 39073 */ 39074 this.KEY_SYSTEM_ACCESS_COMPLETE = 'keySystemAccessComplete'; 39075 39076 /** 39077 * Event ID for events delivered when a key system selection procedure 39078 * completes 39079 * @event ProtectionEvents#KEY_SYSTEM_SELECTED 39080 */ 39081 this.KEY_SYSTEM_SELECTED = 'public_keySystemSelected'; 39082 39083 /** 39084 * Event ID for events delivered when a license request procedure 39085 * has completed 39086 * @event ProtectionEvents#LICENSE_REQUEST_COMPLETE 39087 */ 39088 this.LICENSE_REQUEST_COMPLETE = 'public_licenseRequestComplete'; 39089 39090 /** 39091 * Event ID for needkey/encrypted events 39092 * @ignore 39093 */ 39094 this.NEED_KEY = 'needkey'; 39095 39096 /** 39097 * Event ID for events delivered when the Protection system is detected and created. 39098 * @event ProtectionEvents#PROTECTION_CREATED 39099 */ 39100 this.PROTECTION_CREATED = 'public_protectioncreated'; 39101 39102 /** 39103 * Event ID for events delivered when the Protection system is destroyed. 39104 * @event ProtectionEvents#PROTECTION_DESTROYED 39105 */ 39106 this.PROTECTION_DESTROYED = 'public_protectiondestroyed'; 39107 39108 /** 39109 * Event ID for events delivered when a new server certificate has 39110 * been delivered to the CDM 39111 * @ignore 39112 */ 39113 this.SERVER_CERTIFICATE_UPDATED = 'serverCertificateUpdated'; 39114 39115 /** 39116 * Event ID for events delivered when the process of shutting down 39117 * a protection set has completed 39118 * @ignore 39119 */ 39120 this.TEARDOWN_COMPLETE = 'protectionTeardownComplete'; 39121 39122 /** 39123 * Event ID for events delivered when a HTMLMediaElement has been 39124 * associated with the protection set 39125 * @ignore 39126 */ 39127 this.VIDEO_ELEMENT_SELECTED = 'videoElementSelected'; 39128 } 39129 39130 return ProtectionEvents; 39131})(_coreEventsEventsBase2['default']); 39132 39133var protectionEvents = new ProtectionEvents(); 39134exports['default'] = protectionEvents; 39135module.exports = exports['default']; 39136 39137},{"55":55}],149:[function(_dereq_,module,exports){ 39138/** 39139 * The copyright in this software is being made available under the BSD License, 39140 * included below. This software may be subject to other third party and contributor 39141 * rights, including patent rights, and no such rights are granted under this license. 39142 * 39143 * Copyright (c) 2013, Dash Industry Forum. 39144 * All rights reserved. 39145 * 39146 * Redistribution and use in source and binary forms, with or without modification, 39147 * are permitted provided that the following conditions are met: 39148 * * Redistributions of source code must retain the above copyright notice, this 39149 * list of conditions and the following disclaimer. 39150 * * Redistributions in binary form must reproduce the above copyright notice, 39151 * this list of conditions and the following disclaimer in the documentation and/or 39152 * other materials provided with the distribution. 39153 * * Neither the name of Dash Industry Forum nor the names of its 39154 * contributors may be used to endorse or promote products derived from this software 39155 * without specific prior written permission. 39156 * 39157 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 39158 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 39159 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 39160 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 39161 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
39161INCLUDING, BUT 39162 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 39163 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 39164 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39165 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39166 * POSSIBILITY OF SUCH DAMAGE. 39167 */ 39168 39169'use strict'; 39170 39171Object.defineProperty(exports, '__esModule', { 39172 value: true 39173}); 39174 39175function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 39176 39177var _CommonEncryption = _dereq_(146); 39178 39179var _CommonEncryption2 = _interopRequireDefault(_CommonEncryption); 39180 39181var _voMediaCapability = _dereq_(167); 39182 39183var _voMediaCapability2 = _interopRequireDefault(_voMediaCapability); 39184 39185var _voKeySystemConfiguration = _dereq_(166); 39186 39187var _voKeySystemConfiguration2 = _interopRequireDefault(_voKeySystemConfiguration); 39188 39189/** 39190 * @module ProtectionController 39191 * @description Provides access to media protection information and functionality. Each 39192 * ProtectionController manages a single {@link MediaPlayer.models.ProtectionModel} 39193 * which encapsulates a set of protection information (EME APIs, selected key system, 39194 * key sessions). The APIs of ProtectionController mostly align with the latest EME 39195 * APIs. Key system selection is mostly automated when combined with app-overrideable 39196 * functionality provided in {@link ProtectionKeyController}. 39197 * @todo ProtectionController does almost all of its tasks automatically after init() is 39198 * called. Applications might want more control over this process and want to go through 39199 * each step manually (key system selection, session creation, session maintenance). 39200 * @param {Object} config 39201 */ 39202 39203function ProtectionController(config) { 39204 39205 var protectionKeyController = config.protectionKeyController; 39206 var protectionModel = config.protectionModel; 39207 var adapter = config.adapter; 39208 var eventBus = config.eventBus; 39209 var events = config.events; 39210 var log = config.log; 39211 var BASE64 = config.BASE64; 39212 var Constants = config.Constants; 39213 39214 var instance = undefined, 39215 pendingNeedKeyData = undefined, 39216 audioInfo = undefined, 39217 videoInfo = undefined, 39218 protDataSet = undefined, 39219 initialized = undefined, 39220 sessionType = undefined, 39221 robustnessLevel = undefined, 39222 keySystem = undefined; 39223 39224 function setup() { 39225 pendingNeedKeyData = []; 39226 initialized = false; 39227 sessionType = 'temporary'; 39228 robustnessLevel = ''; 39229 } 39230 39231 /** 39232 * Initialize this protection system with a given manifest and optional audio 39233 * and video stream information. 39234 * 39235 * @param {Object} manifest the json version of the manifest XML document for the 39236 * desired content. Applications can download their manifest using 39237 * {@link module:MediaPlayer#retrieveManifest} 39238 * @param {StreamInfo} [aInfo] audio stream information 39239 * @param {StreamInfo} [vInfo] video stream information 39240 * @memberof module:ProtectionController 39241 * @instance 39242 * @todo This API will change when we have better support for allowing applications 39243 * to select different adaptation sets for playback. Right now it is clunky for 39244 * applications to create {@link StreamInfo} with the right information, 39245 */ 39246 function initialize(manifest, aInfo, vInfo) { 39247 // TODO: We really need to do much more here... We need to be smarter about knowing 39248 // which adaptation sets for which we have initialized, including the default key ID 39249 // value from the ContentProtection elements so we know whether or not we still need to 39250 // select key systems and acquire keys. 39251 if (!initialized) { 39252 var streamInfo = undefined; 39253 39254 if (!aInfo && !vInfo) { 39255 // Look for ContentProtection elements. InitData can be provided by either the 39256 // dash264drm:Pssh ContentProtection format or a DRM-specific format. 39257 streamInfo = adapter.getStreamsInfo()[0]; // TODO: Single period only for now. See TODO above 39258 } 39259 39260 audioInfo = aInfo || (streamInfo ? adapter.getMediaInfoForType(streamInfo, Constants.AUDIO) : null); 39261 videoInfo = vInfo || (streamInfo ? adapter.getMediaInfoForType(streamInfo, Constants.VIDEO) : null);
39262 var mediaInfo = videoInfo ? videoInfo : audioInfo; // We could have audio or video only 39263 39264 // ContentProtection elements are specified at the AdaptationSet level, so the CP for audio 39265 // and video will be the same. Just use one valid MediaInfo object 39266 var supportedKS = protectionKeyController.getSupportedKeySystemsFromContentProtection(mediaInfo.contentProtection); 39267 if (supportedKS && supportedKS.length > 0) { 39268 selectKeySystem(supportedKS, true); 39269 } 39270 39271 initialized = true; 39272 } 39273 } 39274 39275 /** 39276 * Returns a set of supported key systems and CENC initialization data 39277 * from the given array of ContentProtection elements. Only 39278 * key systems that are supported by this player will be returned. 39279 * Key systems are returned in priority order (highest first). 39280 * 39281 * @param {Array.<Object>} cps - array of content protection elements parsed 39282 * from the manifest 39283 * @returns {Array.<Object>} array of objects indicating which supported key 39284 * systems were found. Empty array is returned if no 39285 * supported key systems were found 39286 * @memberof module:ProtectionKeyController 39287 * @instance 39288 */ 39289 function getSupportedKeySystemsFromContentProtection(cps) { 39290 return protectionKeyController.getSupportedKeySystemsFromContentProtection(cps); 39291 } 39292 39293 /** 39294 * Create a new key session associated with the given initialization data from 39295 * the MPD or from the PSSH box in the media 39296 * 39297 * @param {ArrayBuffer} initData the initialization data 39298 * @memberof module:ProtectionController 39299 * @instance 39300 * @fires ProtectionController#KeySessionCreated 39301 * @todo In older versions of the EME spec, there was a one-to-one relationship between 39302 * initialization data and key sessions. That is no longer true in the latest APIs. This 39303 * API will need to modified (and a new "generateRequest(keySession, initData)" API created) 39304 * to come up to speed with the latest EME standard 39305 */ 39306 function createKeySession(initData) { 39307 var initDataForKS = _CommonEncryption2['default'].getPSSHForKeySystem(keySystem, initData); 39308 if (initDataForKS) { 39309 39310 // Check for duplicate initData 39311 var currentInitData = protectionModel.getAllInitData(); 39312 for (var i = 0; i < currentInitData.length; i++) { 39313 if (protectionKeyController.initDataEquals(initDataForKS, currentInitData[i])) { 39314 log('DRM: Ignoring initData because we have already seen it!'); 39315 return; 39316 } 39317 } 39318 try { 39319 protectionModel.createKeySession(initDataForKS, sessionType); 39320 } catch (error) { 39321 eventBus.trigger(events.KEY_SESSION_CREATED, { data: null, error: 'Error creating key session! ' + error.message }); 39322 } 39323 } else { 39324 eventBus.trigger(events.KEY_SESSION_CREATED, { data: null, error: 'Selected key system is ' + keySystem.systemString + '. needkey/encrypted event contains no initData corresponding to that key system!' }); 39325 } 39326 } 39327 39328 /** 39329 * Loads a key session with the given session ID from persistent storage. This 39330 * essentially creates a new key session 39331 * 39332 * @param {string} sessionID 39333 * @memberof module:ProtectionController 39334 * @instance 39335 * @fires ProtectionController#KeySessionCreated 39336 */ 39337 function loadKeySession(sessionID) { 39338 protectionModel.loadKeySession(sessionID); 39339 } 39340 39341 /** 39342 * Removes the given key session from persistent storage and closes the session 39343 * as if {@link ProtectionController#closeKeySession} 39344 * was called 39345 * 39346 * @param {SessionToken} sessionToken the session 39347 * token 39348 * @memberof module:ProtectionController 39349 * @instance 39350 * @fires ProtectionController#KeySessionRemoved 39351 * @fires ProtectionController#KeySessionClosed 39352 */ 39353 function removeKeySession(sessionToken) { 39354 protectionModel.removeKeySession(sessionToken); 39355 } 39356 39357 /** 39358 * Closes the key session and releases all associated decryption keys. These 39359 * keys will no longer be available for decrypting media 39360 * 39361 * @param {SessionToken} sessionToken the session 39362 * token 39363 * @memberof module:ProtectionController 39364 * @instance 39365 * @fires ProtectionController#KeySessionClosed 39366 */ 39367 function closeKeySession(sessionToken) { 39368 protectionModel.closeKeySession(sessionToken); 39369 } 39370 39371 /** 39372 * Sets a server certificate for use by the CDM when signing key messages 39373 * intended for a particular license server. This will fire 39374 * an error event if a key system has not yet been selected. 39375 * 39376 * @param {ArrayBuffer} serverCertificate a CDM-specific license server 39377 * certificate 39378 * @memberof module:ProtectionController 39379 * @instance 39380 * @fires ProtectionController#ServerCertificateUpdated 39381 */ 39382 function setServerCertificate(serverCertificate) { 39383 protectionModel.setServerCertificate(serverCertificate); 39384 } 39385 39386 /** 39387 * Associate this protection system with the given HTMLMediaElement. This 39388 * causes the system to register for needkey/encrypted events from the given
39389 * element and provides a destination for setting of MediaKeys 39390 * 39391 * @param {HTMLMediaElement} element the media element to which the protection 39392 * system should be associated 39393 * @memberof module:ProtectionController 39394 * @instance 39395 */ 39396 function setMediaElement(element) { 39397 if (element) { 39398 protectionModel.setMediaElement(element); 39399 eventBus.on(events.NEED_KEY, onNeedKey, this); 39400 eventBus.on(events.INTERNAL_KEY_MESSAGE, onKeyMessage, this); 39401 } else if (element === null) { 39402 protectionModel.setMediaElement(element); 39403 eventBus.off(events.NEED_KEY, onNeedKey, this); 39404 eventBus.off(events.INTERNAL_KEY_MESSAGE, onKeyMessage, this); 39405 } 39406 } 39407 39408 /** 39409 * Sets the session type to use when creating key sessions. Either "temporary" or 39410 * "persistent-license". Default is "temporary". 39411 * 39412 * @param {string} value the session type 39413 * @memberof module:ProtectionController 39414 * @instance 39415 */ 39416 function setSessionType(value) { 39417 sessionType = value; 39418 } 39419 39420 /** 39421 * Sets the robustness level for video and audio capabilities. Optional to remove Chrome warnings. 39422 * Possible values are SW_SECURE_CRYPTO, SW_SECURE_DECODE, HW_SECURE_CRYPTO, HW_SECURE_CRYPTO, HW_SECURE_DECODE, HW_SECURE_ALL. 39423 * 39424 * @param {string} level the robustness level 39425 * @memberof module:ProtectionController 39426 * @instance 39427 */ 39428 function setRobustnessLevel(level) { 39429 robustnessLevel = level; 39430 } 39431 39432 /** 39433 * Attach KeySystem-specific data to use for license acquisition with EME 39434 * 39435 * @param {Object}
39435 data an object containing property names corresponding to 39436 * key system name strings (e.g. "org.w3.clearkey") and associated values 39437 * being instances of {@link ProtectionData} 39438 * @memberof module:ProtectionController 39439 * @instance 39440 */ 39441 function setProtectionData(data) { 39442 protDataSet = data; 39443 protectionKeyController.setProtectionData(data); 39444 } 39445 39446 /** 39447 * Destroys all protection data associated with this protection set. This includes 39448 * deleting all key sessions. In the case of persistent key sessions, the sessions 39449 * will simply be unloaded and not deleted. Additionally, if this protection set is 39450 * associated with a HTMLMediaElement, it will be detached from that element. 39451 * 39452 * @memberof module:ProtectionController 39453 * @instance 39454 */ 39455 function reset() { 39456 setMediaElement(null); 39457 39458 keySystem = undefined; //TODO-Refactor look at why undefined is needed for this. refactor 39459 39460 if (protectionModel) { 39461 protectionModel.reset(); 39462 protectionModel = null; 39463 } 39464 } 39465 39466 /////////////// 39467 // Private 39468 /////////////// 39469 39470 function getProtData(keySystem) { 39471 var protData = null; 39472 var keySystemString = keySystem.systemString; 39473 39474 if (protDataSet) { 39475 protData = keySystemString in protDataSet ? protDataSet[keySystemString] : null; 39476 } 39477 return protData; 39478 } 39479 39480 function getKeySystemConfiguration(keySystem) { 39481 var protData = getProtData(keySystem); 39482 var audioCapabilities = []; 39483 var videoCapabilities = []; 39484 var audioRobustness = protData && protData.audioRobustness && protData.audioRobustness.length > 0 ? protData.audioRobustness : robustnessLevel; 39485 var videoRobustness = protData && protData.videoRobustness && protData.videoRobustness.length > 0 ? protData.videoRobustness : robustnessLevel; 39486 39487 if (audioInfo) { 39488 audioCapabilities.push(new _voMediaCapability2['default'](audioInfo.codec, audioRobustness)); 39489 } 39490 if (videoInfo) { 39491 videoCapabilities.push(new _voMediaCapability2['default'](videoInfo.codec, videoRobustness)); 39492 } 39493 39494 return new _voKeySystemConfiguration2['default'](audioCapabilities, videoCapabilities, 'optional', sessionType === 'temporary' ? 'optional' : 'required', [sessionType]); 39495 } 39496 39497 function selectKeySystem(supportedKS, fromManifest) { 39498 var self = this; 39499 var requestedKeySystems = []; 39500 39501 var ksIdx = undefined; 39502 if (keySystem) { 39503 // We have a key system 39504 for (ksIdx = 0; ksIdx < supportedKS.length; ksIdx++) { 39505 if (keySystem === supportedKS[ksIdx].ks) { 39506 var _ret = (function () { 39507 39508 requestedKeySystems.push({ ks: supportedKS[ksIdx].ks, configs: [getKeySystemConfiguration(keySystem)] }); 39509 39510 // Ensure that we would be granted key system access using the key 39511 // system and codec information 39512 var onKeySystemAccessComplete = function onKeySystemAccessComplete(event) { 39513 eventBus.off(events.KEY_SYSTEM_ACCESS_COMPLETE, onKeySystemAccessComplete, self); 39514 if (event.error) { 39515 if (!fromManifest) { 39516 eventBus.trigger(events.KEY_SYSTEM_SELECTED, { error: 'DRM: KeySystem Access Denied! -- ' + event.error }); 39517 } 39518 } else { 39519 log('DRM: KeySystem Access Granted'); 39520 eventBus.trigger(events.KEY_SYSTEM_SELECTED, { data: event.data }); 39521 createKeySession(supportedKS[ksIdx].initData); 39522 } 39523 }; 39524 eventBus.on(events.KEY_SYSTEM_ACCESS_COMPLETE, onKeySystemAccessComplete, self); 39525 protectionModel.requestKeySystemAccess(requestedKeySystems); 39526 return 'break'; 39527 })(); 39528 39529 if (_ret === 'break') break; 39530 } 39531 } 39532 } else if (keySystem === undefined) { 39533 var onKeySystemSelected; 39534 39535 (function () { 39536 // First time through, so we need to select a key system 39537 keySystem = null; 39538 pendingNeedKeyData.push(supportedKS); 39539 39540 // Add all key systems to our request list since we have yet to select a key system 39541 for (var i = 0; i < supportedKS.length; i++) {
39542 requestedKeySystems.push({ ks: supportedKS[i].ks, configs: [getKeySystemConfiguration(supportedKS[i].ks)] }); 39543 } 39544 39545 var keySystemAccess = undefined; 39546 var onKeySystemAccessComplete = function onKeySystemAccessComplete(event) { 39547 eventBus.off(events.KEY_SYSTEM_ACCESS_COMPLETE, onKeySystemAccessComplete, self); 39548 if (event.error) { 39549 keySystem = undefined; 39550 eventBus.off(events.INTERNAL_KEY_SYSTEM_SELECTED, onKeySystemSelected, self); 39551 39552 if (!fromManifest) { 39553 eventBus.trigger(events.KEY_SYSTEM_SELECTED, { data: null, error: 'DRM: KeySystem Access Denied! -- ' + event.error }); 39554 } 39555 } else { 39556 keySystemAccess = event.data; 39557 log('DRM: KeySystem Access Granted (' + keySystemAccess.keySystem.systemString + ')! Selecting key system...'); 39558 protectionModel.selectKeySystem(keySystemAccess); 39559 } 39560 }; 39561 39562 onKeySystemSelected = function onKeySystemSelected(event) { 39563 eventBus.off(events.INTERNAL_KEY_SYSTEM_SELECTED, onKeySystemSelected, self); 39564 eventBus.off(events.KEY_SYSTEM_ACCESS_COMPLETE, onKeySystemAccessComplete, self); 39565 if (!event.error) { 39566 keySystem = protectionModel.getKeySystem(); 39567 eventBus.trigger(events.KEY_SYSTEM_SELECTED, { data: keySystemAccess }); 39568 // Set server certificate from protData 39569 var protData = getProtData(keySystem); 39570 if (protData && protData.serverCertificate && protData.serverCertificate.length > 0) { 39571 protectionModel.setServerCertificate(BASE64.decodeArray(protData.serverCertificate).buffer); 39572 } 39573 for (var i = 0; i < pendingNeedKeyData.length; i++) { 39574 for (ksIdx = 0; ksIdx < pendingNeedKeyData[i].length; ksIdx++) { 39575 if (keySystem === pendingNeedKeyData[i][ksIdx].ks) { 39576 createKeySession(pendingNeedKeyData[i][ksIdx].initData); 39577 break; 39578 } 39579 } 39580 } 39581 } else { 39582 keySystem = undefined; 39583 if (!fromManifest) { 39584 eventBus.trigger(events.KEY_SYSTEM_SELECTED, { data: null, error: 'DRM: Error selecting key system! -- ' + event.error }); 39585 } 39586 } 39587 }; 39588 39589 eventBus.on(events.INTERNAL_KEY_SYSTEM_SELECTED, onKeySystemSelected, self); 39590 eventBus.on(events.KEY_SYSTEM_ACCESS_COMPLETE, onKeySystemAccessComplete, self); 39591 protectionModel.requestKeySystemAccess(requestedKeySystems); 39592 })(); 39593 } else { 39594 // We are in the process of selecting a key system, so just save the data 39595 pendingNeedKeyData.push(supportedKS); 39596 } 39597 } 39598 39599 function sendLicenseRequestCompleteEvent(data, error) { 39600 eventBus.trigger(events.LICENSE_REQUEST_COMPLETE, { data: data, error: error }); 39601 } 39602 39603 function onKeyMessage(e) { 39604 log('DRM: onKeyMessage'); 39605 if (e.error) { 39606 log(e.error); 39607 return; 39608 } 39609 39610 // Dispatch event to applications indicating we received a key message 39611 var keyMessage = e.data; 39612 eventBus.trigger(events.KEY_MESSAGE, { data: keyMessage }); 39613 var messageType = keyMessage.messageType ? keyMessage.messageType : 'license-request'; 39614 var message = keyMessage.message; 39615 var sessionToken = keyMessage.sessionToken; 39616 var protData = getProtData(keySystem); 39617 var keySystemString = keySystem.systemString; 39618 var licenseServerData = protectionKeyController.getLicenseServer(keySystem, protData, messageType); 39619 var eventData = { sessionToken: sessionToken, messageType: messageType }; 39620 39621 // Message not destined for license server 39622 if (!licenseServerData) { 39623 log('DRM: License server request not required for this message (type = ' + e.data.messageType + '). Session ID = ' + sessionToken.getSessionID()); 39624 sendLicenseRequestCompleteEvent(eventData); 39625 return; 39626 } 39627 39628 // Perform any special handling for ClearKey 39629 if (protectionKeyController.isClearKey(keySystem)) { 39630 var clearkeys = protectionKeyController.processClearKeyLicenseRequest
39630(protData, message); 39631 if (clearkeys) { 39632 log('DRM: ClearKey license request handled by application!'); 39633 sendLicenseRequestCompleteEvent(eventData); 39634 protectionModel.updateKeySession(sessionToken, clearkeys); 39635 return; 39636 } 39637 } 39638 39639 // All remaining key system scenarios require a request to a remote license server 39640 var xhr = new XMLHttpRequest(); 39641 39642 // Determine license server URL 39643 var url = null; 39644 if (protData && protData.serverURL) { 39645 var serverURL = protData.serverURL; 39646 if (typeof serverURL === 'string' && serverURL !== '') { 39647 url = serverURL; 39648 } else if (typeof serverURL === 'object' && serverURL.hasOwnProperty(messageType)) { 39649 url = serverURL[messageType]; 39650 } 39651 } else if (protData && protData.laURL && protData.laURL !== '') { 39652 // TODO: Deprecated! 39653 url = protData.laURL; 39654 } else { 39655 url = keySystem.getLicenseServerURLFromInitData(_CommonEncryption2['default'].getPSSHData(sessionToken.initData)); 39656 if (!url) { 39657 url = e.data.laURL; 39658 } 39659 } 39660 // Possibly update or override the URL based on the message 39661 url = licenseServerData.getServerURLFromMessage(url, message, messageType); 39662 39663 // Ensure valid license server URL 39664 if (!url) { 39665 sendLicenseRequestCompleteEvent(eventData, 'DRM: No license server URL specified!'); 39666 return; 39667 } 39668 39669 var reportError = function reportError(xhr, eventData, keySystemString, messageType) { 39670 var errorMsg = xhr.response ? licenseServerData.getErrorResponse(xhr.response, keySystemString, messageType) : 'NONE'; 39671 sendLicenseRequestCompleteEvent(eventData, 'DRM: ' + keySystemString + ' update, XHR complete. status is "' + xhr.statusText + '" (' + xhr.status + '), readyState is ' + xhr.readyState + '. Response is ' + errorMsg); 39672 }; 39673 39674 xhr.open(licenseServerData.getHTTPMethod(messageType), url, true); 39675 xhr.responseType = licenseServerData.getResponseType(keySystemString, messageType); 39676 xhr.onload = function () { 39677 if (this.status == 200) { 39678 var licenseMessage = licenseServerData.getLicenseMessage(this.response, keySystemString, messageType); 39679 if (licenseMessage !== null) { 39680 sendLicenseRequestCompleteEvent(eventData); 39681 protectionModel.updateKeySession(sessionToken, licenseMessage); 39682 } else { 39683 reportError(this, eventData, keySystemString, messageType); 39684 } 39685 } else { 39686 reportError(this, eventData, keySystemString, messageType); 39687 } 39688 }; 39689 xhr.onabort = function () { 39690 sendLicenseRequestCompleteEvent(eventData, 'DRM: ' + keySystemString + ' update, XHR aborted. status is "' + this.statusText + '" (' + this.status + '), readyState is ' + this.readyState); 39691 }; 39692 xhr.onerror = function () { 39693 sendLicenseRequestCompleteEvent(eventData, 'DRM: ' + keySystemString + ' update, XHR error. status is "' + this.statusText + '" (' + this.status + '), readyState is ' + this.readyState); 39694 }; 39695 39696 // Set optional XMLHttpRequest headers from protection data and message 39697 var updateHeaders = function updateHeaders(headers) { 39698 if (headers) { 39699 for (var key in headers) { 39700 if ('authorization' === key.toLowerCase()) { 39701 xhr.withCredentials = true; 39702 } 39703 xhr.setRequestHeader(key, headers[key]); 39704 } 39705 } 39706 }; 39707 if (protData) { 39708 updateHeaders(protData.httpRequestHeaders); 39709 } 39710 updateHeaders(keySystem.getRequestHeadersFromMessage(message)); 39711 39712 // Set withCredentials property from protData 39713 if (protData && protData.withCredentials) { 39714 xhr.withCredentials = true; 39715 } 39716 39717 xhr.send(keySystem.getLicenseRequestFromMessage(message)); 39718 } 39719 39720 function onNeedKey(event) { 39721 log('DRM: onNeedKey'); 39722 // Ignore non-cenc initData 39723 if (event.key.initDataType !== 'cenc') { 39724 log('DRM: Only \'cenc\' initData is supported! Ignoring initData of type: ' + event.key.initDataType); 39725 return; 39726 } 39727 39728 // Some browsers return initData as Uint8Array (IE), some as ArrayBuffer (Chrome). 39729 // Convert to ArrayBuffer 39730 var abInitData = event.key.initData; 39731 if (ArrayBuffer.isView(abInitData)) { 39732 abInitData = abInitData.buffer; 39733 } 39734 39735 // If key system has already been selected and initData already seen, then do nothing 39736 if (keySystem) { 39737 var initDataForKS = _CommonEncryption2['default'].getPSSHForKeySystem(keySystem, abInitData); 39738 if (initDataForKS) { 39739 39740 // Check for duplicate initData 39741 var currentInitData = protectionModel.getAllInitData(); 39742 for (var i = 0; i < currentInitData.length; i++) { 39743 if (protectionKeyController.initDataEquals(initDataForKS, currentInitData[i])) { 39744 log('DRM: Ignoring initData because we have already seen it!'); 39745 return; 39746 } 39747 } 39748 } 39749 } 39750 39751 log('DRM: initData:', String.fromCharCode.apply(null, new Uint8Array(abInitData))); 39752
39753 var supportedKS = protectionKeyController.getSupportedKeySystems(abInitData, protDataSet); 39754 if (supportedKS.length === 0) { 39755 log('DRM: Received needkey event with initData, but we don\'t support any of the key systems!'); 39756 return; 39757 } 39758 39759 selectKeySystem(supportedKS, false); 39760 } 39761 39762 function getKeySystems() { 39763 return protectionKeyController ? protectionKeyController.getKeySystems() : []; 39764 } 39765 39766 instance = { 39767 initialize: initialize, 39768 createKeySession: createKeySession, 39769 loadKeySession: loadKeySession, 39770 removeKeySession: removeKeySession, 39771 closeKeySession: closeKeySession, 39772 setServerCertificate: setServerCertificate, 39773 setMediaElement: setMediaElement, 39774 setSessionType: setSessionType, 39775 setRobustnessLevel: setRobustnessLevel, 39776 setProtectionData: setProtectionData, 39777 getSupportedKeySystemsFromContentProtection: getSupportedKeySystemsFromContentProtection, 39778 getKeySystems: getKeySystems, 39779 reset: reset 39780 }; 39781 39782 setup(); 39783 return instance; 39784} 39785 39786ProtectionController.__dashjs_factory_name = 'ProtectionController'; 39787exports['default'] = dashjs.FactoryMaker.getClassFactory(ProtectionController); 39788/* jshint ignore:line */ 39789module.exports = exports['default']; 39790 39791},{"146":146,"166":166,"167":167}],150:[function(_dereq_,module,exports){ 39792/** 39793 * The copyright in this software is being made available under the BSD License, 39794 * included below. This software may be subject to other third party and contributor 39795 * rights, including patent rights, and no such rights are granted under this license. 39796 * 39797 * Copyright (c) 2013, Dash Industry Forum. 39798 * All rights reserved. 39799 * 39800 * Redistribution and use in source and binary forms, with or without modification, 39801 * are permitted provided that the following conditions are met: 39802 * * Redistributions of source code must retain the above copyright notice, this 39803 * list of conditions and the following disclaimer. 39804 * * Redistributions in binary form must reproduce the above copyright notice, 39805 * this list of conditions and the following disclaimer in the documentation and/or 39806 * other materials provided with the distribution. 39807 * * Neither the name of Dash Industry Forum nor the names of its 39808 * contributors may be used to endorse or promote products derived from this software 39809 * without specific prior written permission. 39810 * 39811 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 39812 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 39813 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 39814 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 39815 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 39816 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 39817 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 39818 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39819 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39820 * POSSIBILITY OF SUCH DAMAGE. 39821 */ 39822'use strict'; 39823 39824Object.defineProperty(exports, '__esModule', { 39825 value: true 39826}); 39827 39828function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 39829 39830var _CommonEncryption = _dereq_(146); 39831 39832var _CommonEncryption2 = _interopRequireDefault(_CommonEncryption); 39833 39834var _drmKeySystemClearKey = _dereq_(151); 39835 39836var _drmKeySystemClearKey2 = _interopRequireDefault(_drmKeySystemClearKey); 39837 39838var _drmKeySystemWidevine = _dereq_(153); 39839 39840var _drmKeySystemWidevine2 = _interopRequireDefault(_drmKeySystemWidevine); 39841 39842var _drmKeySystemPlayReady = _dereq_(152); 39843 39844var _drmKeySystemPlayReady2 = _interopRequireDefault(_drmKeySystemPlayReady); 39845 39846var _serversDRMToday = _dereq_(158); 39847 39848var _serversDRMToday2 = _interopRequireDefault(_serversDRMToday); 39849 39850var _serversPlayReady = _dereq_(159); 39851 39852var _serversPlayReady2 = _interopRequireDefault(_serversPlayReady); 39853 39854var _serversWidevine = _dereq_(160); 39855 39856var _serversWidevine2 = _interopRequireDefault(_serversWidevine); 39857 39858var _serversClearKey = _dereq_(157); 39859 39860var _serversClearKey2 = _interopRequireDefault(_serversClearKey); 39861 39862/** 39863 * @module ProtectionKeyController 39864 * @description Media protection key system functionality that can be modified/overridden by applications 39865 */ 39866function ProtectionKeyController() { 39867 39868 var context = this.context; 39869 39870 var instance = undefined, 39871 log = undefined, 39872 keySystems = undefined, 39873 BASE64 = undefined, 39874 clearkeyKeySystem = undefined; 39875 39876 function setConfig(config) { 39877 if (!config) return; 39878 39879 if (config.log) { 39880 log = config.log; 39881 } 39882 39883 if (config.BASE64) { 39884 BASE64 = config.BASE64; 39885 } 39886 } 39887 39888 function initialize() { 39889 keySystems = []; 39890 39891 var keySystem = undefined; 39892 39893 // PlayReady 39894 keySystem = (0, _drmKeySystemPlayReady2['default'])(context).getInstance({ BASE64: BASE64 }); 39895 keySystems.push(keySystem); 39896
39897 // Widevine 39898 keySystem = (0, _drmKeySystemWidevine2['default'])(context).getInstance({ BASE64: BASE64 }); 39899 keySystems.push(keySystem); 39900 39901 // ClearKey 39902 keySystem = (0, _drmKeySystemClearKey2['default'])(context).getInstance({ BASE64: BASE64 }); 39903 keySystems.push(keySystem); 39904 clearkeyKeySystem = keySystem; 39905 } 39906 39907 /** 39908 * Returns a prioritized list of key systems supported 39909 * by this player (not necessarily those supported by the 39910 * user agent) 39911 * 39912 * @returns {Array.<KeySystem>} a prioritized 39913 * list of key systems 39914 * @memberof module:ProtectionKeyController 39915 * @instance 39916 */ 39917 function getKeySystems() { 39918 return keySystems; 39919 } 39920 39921 /** 39922 * Returns the key system associated with the given key system string 39923 * name (i.e. 'org.w3.clearkey') 39924 * 39925 * @param {string} systemString the system string 39926 * @returns {KeySystem|null} the key system 39927 * or null if no supported key system is associated with the given key 39928 * system string 39929 * @memberof module:ProtectionKeyController 39930 * @instance 39931 */ 39932 function getKeySystemBySystemString(systemString) { 39933 for (var i = 0; i < keySystems.length; i++) { 39934 if (keySystems[i].systemString === systemString) { 39935 return keySystems[i]; 39936 } 39937 } 39938 return null; 39939 } 39940 39941 /** 39942 * Determines whether the given key system is ClearKey. This is 39943 * necessary because the EME spec defines ClearKey and its method 39944 * for providing keys to the key session; and this method has changed 39945 * between the various API versions. Our EME-specific ProtectionModels 39946 * must know if the system is ClearKey so that it can format the keys 39947 * according to the particular spec version. 39948 * 39949 * @param {Object} keySystem the key 39950 * @returns {boolean} true if this is the ClearKey key system, false 39951 * otherwise 39952 * @memberof module:ProtectionKeyController 39953 * @instance 39954 */ 39955 function isClearKey(keySystem) { 39956 return keySystem === clearkeyKeySystem; 39957 } 39958 39959 /** 39960 * Check equality of initData array buffers. 39961 * 39962 * @param {ArrayBuffer} initData1 - first initData 39963 * @param {ArrayBuffer} initData2 - second initData 39964 * @returns {boolean} true if the initData arrays are equal in size and 39965 * contents, false otherwise 39966 * @memberof module:ProtectionKeyController 39967 * @instance 39968 */ 39969 function initDataEquals(initData1, initData2) { 39970 if (initData1.byteLength === initData2.byteLength) { 39971 var data1 = new Uint8Array(initData1); 39972 var data2 = new Uint8Array(initData2); 39973 39974 for (var j = 0; j < data1.length; j++) { 39975 if (data1[j] !== data2[j]) { 39976 return false; 39977 } 39978 } 39979 return true; 39980 } 39981 return false; 39982 } 39983 39984 /** 39985 * Returns a set of supported key systems and CENC initialization data 39986 * from the given array of ContentProtection elements. Only 39987 * key systems that are supported by this player will be returned. 39988 * Key systems are returned in priority order (highest first). 39989 * 39990 * @param {Array.<Object>} cps - array of content protection elements parsed 39991 * from the manifest 39992 * @returns {Array.<Object>} array of objects indicating which supported key 39993 * systems were found. Empty array is returned if no 39994 * supported key systems were found 39995 * @memberof module:ProtectionKeyController 39996 * @instance 39997 */ 39998 function getSupportedKeySystemsFromContentProtection(cps) { 39999 var cp = undefined, 40000 ks = undefined, 40001 ksIdx = undefined, 40002 cpIdx = undefined; 40003 var supportedKS = []; 40004 40005 if (cps) { 40006 for (ksIdx = 0; ksIdx < keySystems.length; ++ksIdx) { 40007 ks = keySystems[ksIdx]; 40008 for (cpIdx = 0; cpIdx < cps.length; ++cpIdx) { 40009 cp = cps[cpIdx]; 40010 if (cp.schemeIdUri.toLowerCase() === ks.schemeIdURI) { 40011 40012 // Look for DRM-specific ContentProtection 40013 var initData = ks.getInitData(cp); 40014 if (!!initData) { 40015 supportedKS.push({ 40016 ks: keySystems[ksIdx], 40017 initData: initData 40018 }); 40019 } 40020 } 40021 } 40022 } 40023 } 40024 return supportedKS; 40025 } 40026 40027 /** 40028 * Returns key systems supported by this player for the given PSSH 40029 * initializationData. Only key systems supported by this player 40030 * that have protection data present will be returned. Key systems are returned in priority order 40031 * (highest priority first) 40032 * 40033 * @param {ArrayBuffer} initData Concatenated PSSH data for all DRMs 40034 * supported by the content 40035 * @param {ProtectionData} protDataSet user specified protection data - license server url etc 40036 * supported by the content 40037 * @returns {Array.<Object>} array of objects indicating which supported key 40038 * systems were found. Empty array is returned if no 40039 * supported key systems were found 40040 * @memberof module:ProtectionKeyController 40041 * @instance 40042 */
40043 function getSupportedKeySystems(initData, protDataSet) { 40044 var supportedKS = []; 40045 var pssh = _CommonEncryption2['default'].parsePSSHList(initData); 40046 40047 for (var ksIdx = 0; ksIdx < keySystems.length; ++ksIdx) { 40048 var keySystemString = keySystems[ksIdx].systemString; 40049 var shouldNotFilterOutKeySystem = protDataSet ? keySystemString in protDataSet : true; 40050 40051 if (keySystems[ksIdx].uuid in pssh && shouldNotFilterOutKeySystem) { 40052 supportedKS.push({ 40053 ks: keySystems[ksIdx], 40054 initData: pssh[keySystems[ksIdx].uuid] 40055 }); 40056 } 40057 } 40058 return supportedKS; 40059 } 40060 40061 /** 40062 * Returns the license server implementation data that should be used for this request. 40063 * 40064 * @param {KeySystem} keySystem the key system 40065 * associated with this license request 40066 * @param {ProtectionData} protData protection data to use for the 40067 * request 40068 * @param {string} [messageType="license-request"] the message type associated with this 40069 * request. Supported message types can be found 40070 * {@link https://w3c.github.io/encrypted-media/#idl-def-MediaKeyMessageType|here}. 40071 * @returns {LicenseServer|null} the license server 40072 * implementation that should be used for this request or null if the player should not 40073 * pass messages of the given type to a license server 40074 * @memberof module:ProtectionKeyController 40075 * @instance 40076 * 40077 */ 40078 function getLicenseServer(keySystem, protData, messageType) { 40079 40080 // Our default server implementations do not do anything with "license-release" or 40081 // "individualization-request" messages, so we just send a success event 40082 if (messageType === 'license-release' || messageType === 'individualization-request') { 40083 return null; 40084 } 40085 40086 var licenseServerData = null; 40087 if (protData && protData.hasOwnProperty('drmtoday')) { 40088 licenseServerData = (0, _serversDRMToday2['default'])(context).getInstance({ BASE64: BASE64 }); 40089 } else if (keySystem.systemString === 'com.widevine.alpha') { 40090 licenseServerData = (0, _serversWidevine2['default'])(context).getInstance(); 40091 } else if (keySystem.systemString === 'com.microsoft.playready') { 40092 licenseServerData = (0, _serversPlayReady2['default'])(context).getInstance(); 40093 } else if (keySystem.systemString === 'org.w3.clearkey') { 40094 licenseServerData = (0, _serversClearKey2['default'])(context).getInstance(); 40095 } 40096 40097 return licenseServerData; 40098 } 40099 40100 /** 40101 * Allows application-specific retrieval of ClearKey keys. 40102 * 40103 * @param {ProtectionData} protData protection data to use for the 40104 * request 40105 * @param {ArrayBuffer} message the key message from the CDM 40106 * @return {ClearKeyKeySet|null} the clear keys associated with 40107 * the request or null if no keys can be returned by this function 40108 * @memberof module:ProtectionKeyController 40109 * @instance 40110 */
40111 function processClearKeyLicenseRequest(protData, message) { 40112 try { 40113 return clearkeyKeySystem.getClearKeysFromProtectionData(protData, message); 40114 } catch (error) { 40115 log('Failed to retrieve clearkeys from ProtectionData'); 40116 return null; 40117 } 40118 } 40119 40120 function setProtectionData(protectionDataSet) { 40121 var getProtectionData = function getProtectionData(keySystemString) { 40122 var protData = null; 40123 if (protectionDataSet) { 40124 protData = keySystemString in protectionDataSet ? protectionDataSet[keySystemString] : null; 40125 } 40126 return protData; 40127 }; 40128 40129 for (var i = 0; i < keySystems.length; i++) { 40130 var keySystem = keySystems[i]; 40131 if (keySystem.hasOwnProperty('init')) { 40132 keySystem.init(getProtectionData(keySystem.systemString)); 40133 } 40134 } 40135 } 40136 40137 instance = { 40138 initialize: initialize, 40139 setProtectionData: setProtectionData, 40140 isClearKey: isClearKey, 40141 initDataEquals: initDataEquals, 40142 getKeySystems: getKeySystems, 40143 getKeySystemBySystemString: getKeySystemBySystemString, 40144 getSupportedKeySystemsFromContentProtection: getSupportedKeySystemsFromContentProtection, 40145 getSupportedKeySystems: getSupportedKeySystems, 40146 getLicenseServer: getLicenseServer, 40147 processClearKeyLicenseRequest: processClearKeyLicenseRequest, 40148 setConfig: setConfig 40149 }; 40150 40151 return instance; 40152} 40153 40154ProtectionKeyController.__dashjs_factory_name = 'ProtectionKeyController'; 40155exports['default'] = dashjs.FactoryMaker.getSingletonFactory(ProtectionKeyController); 40156/* jshint ignore:line */ 40157module.exports = exports['default']; 40158 40159},{"146":146,"151":151,"152":152,"153":153,"157":157,"158":158,"159":159,"160":160}],151:[function(_dereq_,module,exports){ 40160/** 40161 * The copyright in this software is being made available under the BSD License, 40162 * included below. This software may be subject to other third party and contributor 40163 * rights, including patent rights, and no such rights are granted under this license. 40164 * 40165 * Copyright (c) 2013, Dash Industry Forum. 40166 * All rights reserved. 40167 * 40168 * Redistribution and use in source and binary forms, with or without modification, 40169 * are permitted provided that the following conditions are met: 40170 * * Redistributions of source code must retain the above copyright notice, this 40171 * list of conditions and the following disclaimer. 40172 * * Redistributions in binary form must reproduce the above copyright notice, 40173 * this list of conditions and the following disclaimer in the documentation and/or 40174 * other materials provided with the distribution. 40175 * * Neither the name of Dash Industry Forum nor the names of its 40176 * contributors may be used to endorse or promote products derived from this software 40177 * without specific prior written permission. 40178 * 40179 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 40180 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 40181 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 40182 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 40183 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 40184 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 40185 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 40186 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40187 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40188 * POSSIBILITY OF SUCH DAMAGE. 40189 */ 40190 40191'use strict'; 40192 40193Object.defineProperty(exports, '__esModule', { 40194 value: true 40195}); 40196 40197function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 40198 40199var _voKeyPair = _dereq_(164); 40200 40201var _voKeyPair2 = _interopRequireDefault(_voKeyPair); 40202 40203var _voClearKeyKeySet = _dereq_(161); 40204 40205var _voClearKeyKeySet2 = _interopRequireDefault(_voClearKeyKeySet); 40206 40207var _CommonEncryption = _dereq_(146); 40208 40209var _CommonEncryption2 = _interopRequireDefault(_CommonEncryption); 40210 40211var uuid = '1077efec-c0b2-4d02-ace3-3c1e52e2fb4b'; 40212var systemString = 'org.w3.clearkey'; 40213var schemeIdURI = 'urn:uuid:' + uuid; 40214 40215function KeySystemClearKey(config) { 40216 40217 var instance = undefined; 40218 var BASE64 = config.BASE64; 40219 /** 40220 * Returns desired clearkeys (as specified in the CDM message) from protection data 40221 * 40222 * @param {ProtectionData} protectionData the protection data 40223 * @param {ArrayBuffer} message the ClearKey CDM message 40224 * @returns {ClearKeyKeySet} the key set or null if none found 40225 * @throws {Error} if a keyID specified in the CDM message was not found in the 40226 * protection data 40227 * @memberof KeySystemClearKey 40228 */ 40229 function getClearKeysFromProtectionData(protectionData, message) { 40230 var clearkeySet = null; 40231 if (protectionData) { 40232 // ClearKey is the only system that does not require a license server URL, so we 40233 // handle it here when keys are specified in protection data 40234 var jsonMsg = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(message))); 40235 var keyPairs = []; 40236 for (var i = 0; i < jsonMsg.kids.length; i++) { 40237 var clearkeyID = jsonMsg.kids[i]; 40238 var clearkey = protectionData.clearkeys.hasOwnProperty(clearkeyID) ? protectionData.clearkeys[clearkeyID] : null; 40239 if (!clearkey) { 40240 throw new Error('DRM: ClearKey keyID (' + clearkeyID + ') is not known!'); 40241 } 40242 // KeyIDs from CDM are not base64 padded. Keys may or may not be padded 40243 keyPairs.push(new _voKeyPair2['default'](clearkeyID, clearkey)); 40244 } 40245 clearkeySet = new _voClearKeyKeySet2['default'](keyPairs); 40246 } 40247 return clearkeySet; 40248 } 40249 40250 function getInitData(cp) { 40251 return _CommonEncryption2['default'].parseInitDataFromContentProtection(cp, BASE64); 40252 } 40253 40254 function getRequestHeadersFromMessage() /*message*/{ 40255 return null; 40256 } 40257 40258 function getLicenseRequestFromMessage(message) { 40259 return new Uint8Array(message); 40260 } 40261 40262 function getLicenseServerURLFromInitData() /*initData*/{ 40263 return null; 40264 } 40265 40266 instance = { 40267 uuid: uuid, 40268 schemeIdURI: schemeIdURI, 40269 systemString: systemString, 40270 getInitData: getInitData, 40271 getRequestHeadersFromMessage: getRequestHeadersFromMessage, 40272 getLicenseRequestFromMessage: getLicenseRequestFromMessage, 40273 getLicenseServerURLFromInitData: getLicenseServerURLFromInitData, 40274 getClearKeysFromProtectionData: getClearKeysFromProtectionData 40275 }; 40276 40277 return instance; 40278} 40279 40280KeySystemClearKey.__dashjs_factory_name = 'KeySystemClearKey'; 40281exports['default'] = dashjs.FactoryMaker.getSingletonFactory(KeySystemClearKey); 40282/* jshint ignore:line */ 40283module.exports = exports['default']; 40284 40285},{"146":146,"161":161,"164":164}],152:[function(_dereq_,module,exports){ 40286/** 40287 * The copyright in this software is being made available under the BSD License, 40288 * included below. This software may be subject to other third party and contributor 40289 * rights, including patent rights, and no such rights are granted under this license. 40290 * 40291 * Copyright (c) 2013, Dash Industry Forum. 40292 * All rights reserved. 40293 * 40294 * Redistribution and use in source and binary forms, with or without modification, 40295 * are permitted provided that the following conditions are met: 40296 * * Redistributions of source code must retain the above copyright notice, this 40297 * list of conditions and the following disclaimer. 40298 * * Redistributions in binary form must reproduce the above copyright notice, 40299 * this list of conditions and the following disclaimer in the documentation and/or 40300 * other materials provided with the distribution. 40301 * * Neither the name of Dash Industry Forum nor the names of its 40302 * contributors may be used to endorse or promote products derived from this software 40303 * without specific prior written permission. 40304 * 40305 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 40306 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 40307 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 40308 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 40309 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
40309INCLUDING, BUT 40310 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 40311 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 40312 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40313 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40314 * POSSIBILITY OF SUCH DAMAGE. 40315 */ 40316 40317/** 40318 * Microsoft PlayReady DRM 40319 * 40320 * @class 40321 * @implements KeySystem 40322 */ 40323'use strict'; 40324 40325Object.defineProperty(exports, '__esModule', { 40326 value: true 40327}); 40328 40329function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 40330 40331var _CommonEncryption = _dereq_(146); 40332 40333var _CommonEncryption2 = _interopRequireDefault(_CommonEncryption); 40334 40335var uuid = '9a04f079-9840-4286-ab92-e65be0885f95'; 40336var systemString = 'com.microsoft.playready'; 40337var schemeIdURI = 'urn:uuid:' + uuid; 40338 40339function KeySystemPlayReady(config) { 40340 40341 var instance = undefined; 40342 var messageFormat = 'utf16'; 40343 var BASE64 = config.BASE64; 40344 40345 function getRequestHeadersFromMessage(message) { 40346 var msg = undefined, 40347 xmlDoc = undefined; 40348 var headers = {}; 40349 var parser = new DOMParser(); 40350 var dataview = messageFormat === 'utf16' ? new Uint16Array(message) : new Uint8Array(message); 40351 40352 msg = String.fromCharCode.apply(null, dataview); 40353 xmlDoc = parser.parseFromString(msg, 'application/xml'); 40354 40355 var headerNameList = xmlDoc.getElementsByTagName('name'); 40356 var headerValueList = xmlDoc.getElementsByTagName('value'); 40357 for (var i = 0; i < headerNameList.length; i++) { 40358 headers[headerNameList[i].childNodes[0].nodeValue] = headerValueList[i].childNodes[0].nodeValue; 40359 } 40360 // some versions of the PlayReady CDM return 'Content' instead of 'Content-Type'. 40361 // this is NOT w3c conform and license servers may reject the request! 40362 // -> rename it to proper w3c definition! 40363 if (headers.hasOwnProperty('Content')) { 40364 headers['Content-Type'] = headers.Content; 40365 delete headers.Content; 40366 } 40367 return headers; 40368 } 40369 40370 function getLicenseRequestFromMessage(message) { 40371 var msg = undefined, 40372 xmlDoc = undefined; 40373 var licenseRequest = null; 40374 var parser = new DOMParser(); 40375 var dataview = messageFormat === 'utf16' ? new Uint16Array(message) : new Uint8Array(message); 40376 40377 msg = String.fromCharCode.apply(null, dataview); 40378 xmlDoc = parser.parseFromString(msg, 'application/xml'); 40379 40380 if (xmlDoc.getElementsByTagName('Challenge')[0]) { 40381 var Challenge = xmlDoc.getElementsByTagName('Challenge')[0].childNodes[0].nodeValue; 40382 if (Challenge) { 40383 licenseRequest = BASE64.decode(Challenge); 40384 } 40385 } 40386 return licenseRequest; 40387 } 40388 40389 function getLicenseServerURLFromInitData(initData) { 40390 if (initData) { 40391 var data = new DataView(initData); 40392 var numRecords = data.getUint16(4, true); 40393 var offset = 6; 40394 var parser = new DOMParser(); 40395 40396 for (var i = 0; i < numRecords; i++) { 40397 // Parse the PlayReady Record header 40398 var recordType = data.getUint16(offset, true); 40399 offset += 2; 40400 var recordLength = data.getUint16(offset, true); 40401 offset += 2; 40402 if (recordType !== 0x0001) { 40403 offset += recordLength; 40404 continue; 40405 } 40406 40407 var recordData = initData.slice(offset, offset + recordLength); 40408 var record = String.fromCharCode.apply(null, new Uint16Array(recordData)); 40409 var xmlDoc = parser.parseFromString(record, 'application/xml'); 40410 40411 // First try <LA_URL> 40412 if (xmlDoc.getElementsByTagName('LA_URL')[0]) { 40413 var laurl = xmlDoc.getElementsByTagName('LA_URL')[0].childNodes[0].nodeValue; 40414 if (laurl) { 40415 return laurl; 40416 } 40417 } 40418 40419 // Optionally, try <LUI_URL> 40420 if (xmlDoc.getElementsByTagName('LUI_URL')[0]) { 40421 var luiurl = xmlDoc.getElementsByTagName('LUI_URL')[0].childNodes[0].nodeValue; 40422 if (luiurl) { 40423 return luiurl; 40424 } 40425 } 40426 } 40427 } 40428 40429 return null; 40430 } 40431 40432 function getInitData(cpData) { 40433 // * desc@ getInitData 40434 // * generate PSSH data from PROHeader defined in MPD file 40435 // * PSSH format: 40436 // * size (4) 40437 // * box type(PSSH) (8) 40438 // * Protection SystemID (16) 40439 // * protection system data size (4) - length of decoded PROHeader 40440 // * decoded PROHeader data from MPD file
40441 var PSSHBoxType = new Uint8Array([0x70, 0x73, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00]); //'PSSH' 8 bytes 40442 var playreadySystemID = new Uint8Array([0x9a, 0x04, 0xf0, 0x79, 0x98, 0x40, 0x42, 0x86, 0xab, 0x92, 0xe6, 0x5b, 0xe0, 0x88, 0x5f, 0x95]); 40443 40444 var byteCursor = 0; 40445 var uint8arraydecodedPROHeader = null; 40446 40447 var PROSize = undefined, 40448 PSSHSize = undefined, 40449 PSSHBoxBuffer = undefined, 40450 PSSHBox = undefined, 40451 PSSHData = undefined; 40452 40453 // Handle common encryption PSSH 40454 if ('pssh' in cpData) { 40455 return _CommonEncryption2['default'].parseInitDataFromContentProtection(cpData, BASE64); 40456 } 40457 // Handle native MS PlayReady ContentProtection elements 40458 if ('pro' in cpData) { 40459 uint8arraydecodedPROHeader = BASE64.decodeArray(cpData.pro.__text); 40460 } else if ('prheader' in cpData) { 40461 uint8arraydecodedPROHeader = BASE64.decodeArray(cpData.prheader.__text); 40462 } else { 40463 return null; 40464 } 40465 40466 PROSize = uint8arraydecodedPROHeader.length; 40467 PSSHSize = 0x4 + PSSHBoxType.length + playreadySystemID.length + 0x4 + PROSize; 40468 40469 PSSHBoxBuffer = new ArrayBuffer(PSSHSize); 40470 40471 PSSHBox = new Uint8Array(PSSHBoxBuffer); 40472 PSSHData = new DataView(PSSHBoxBuffer); 40473
40474 PSSHData.setUint32(byteCursor, PSSHSize); 40475 byteCursor += 0x4; 40476 40477 PSSHBox.set(PSSHBoxType, byteCursor); 40478 byteCursor += PSSHBoxType.length; 40479 40480 PSSHBox.set(playreadySystemID, byteCursor); 40481 byteCursor += playreadySystemID.length; 40482 40483 PSSHData.setUint32(byteCursor, PROSize); 40484 byteCursor += 0x4; 40485 40486 PSSHBox.set(uint8arraydecodedPROHeader, byteCursor); 40487 byteCursor += PROSize; 40488 40489 return PSSHBox.buffer; 40490 } 40491 40492 /** 40493 * It seems that some PlayReady implementations return their XML-based CDM 40494 * messages using UTF16, while others return them as UTF8. Use this function 40495 * to modify the message format to expect when parsing CDM messages. 40496 * 40497 * @param {string} format the expected message format. Either "utf8" or "utf16". 40498 * @throws {Error} Specified message format is not one of "utf8" or "utf16" 40499 */ 40500 function setPlayReadyMessageFormat(format) { 40501 if (format !== 'utf8' && format !== 'utf16') { 40502 throw new Error('Illegal PlayReady message format! -- ' + format); 40503 } 40504 messageFormat = format; 40505 } 40506 40507 instance = { 40508 uuid: uuid, 40509 schemeIdURI: schemeIdURI, 40510 systemString: systemString, 40511 getInitData: getInitData, 40512 getRequestHeadersFromMessage: getRequestHeadersFromMessage, 40513 getLicenseRequestFromMessage: getLicenseRequestFromMessage, 40514 getLicenseServerURLFromInitData: getLicenseServerURLFromInitData, 40515 setPlayReadyMessageFormat: setPlayReadyMessageFormat 40516 }; 40517 40518 return instance; 40519} 40520 40521KeySystemPlayReady.__dashjs_factory_name = 'KeySystemPlayReady'; 40522exports['default'] = dashjs.FactoryMaker.getSingletonFactory(KeySystemPlayReady); 40523/* jshint ignore:line */ 40524module.exports = exports['default']; 40525 40526},{"146":146}],153:[function(_dereq_,module,exports){ 40527/** 40528 * The copyright in this software is being made available under the BSD License, 40529 * included below. This software may be subject to other third party and contributor 40530 * rights, including patent rights, and no such rights are granted under this license. 40531 * 40532 * Copyright (c) 2013, Dash Industry Forum. 40533 * All rights reserved. 40534 * 40535 * Redistribution and use in source and binary forms, with or without modification, 40536 * are permitted provided that the following conditions are met: 40537 * * Redistributions of source code must retain the above copyright notice, this 40538 * list of conditions and the following disclaimer. 40539 * * Redistributions in binary form must reproduce the above copyright notice, 40540 * this list of conditions and the following disclaimer in the documentation and/or 40541 * other materials provided with the distribution. 40542 * * Neither the name of Dash Industry Forum nor the names of its 40543 * contributors may be used to endorse or promote products derived from this software 40544 * without specific prior written permission. 40545 * 40546 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 40547 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 40548 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 40549 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 40550 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 40551 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 40552 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 40553 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40554 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40555 * POSSIBILITY OF SUCH DAMAGE. 40556 */ 40557 40558/** 40559 * Google Widevine DRM 40560 * 40561 * @class 40562 * @implements MediaPlayer.dependencies.protection.KeySystem 40563 */ 40564 40565'use strict'; 40566 40567Object.defineProperty(exports, '__esModule', { 40568 value: true 40569}); 40570 40571function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 40572 40573var _CommonEncryption = _dereq_(146); 40574 40575var _CommonEncryption2 = _interopRequireDefault(_CommonEncryption); 40576 40577var uuid = 'edef8ba9-79d6-4ace-a3c8-27dcd51d21ed'; 40578var systemString = 'com.widevine.alpha'; 40579var schemeIdURI = 'urn:uuid:' + uuid; 40580 40581function KeySystemWidevine(config) { 40582 40583 var instance = undefined; 40584 var protData = null; 40585 var BASE64 = config.BASE64; 40586 40587 function init(protectionData) { 40588 if (protectionData) { 40589 protData = protectionData; 40590 } 40591 } 40592 40593 function replaceKID(pssh, KID) { 40594 var pssh_array = undefined; 40595 var replace = true; 40596 var kidLen = 16; 40597 var pos = undefined; 40598 var i = undefined, 40599 j = undefined; 40600 40601 pssh_array = new Uint8Array(pssh); 40602 40603 for (i = 0; i <= pssh_array.length - (kidLen + 2); i++) { 40604 if (pssh_array[i] === 0x12 && pssh_array[i + 1] === 0x10) { 40605 pos = i + 2; 40606 for (j = pos; j < pos + kidLen; j++) { 40607 if (pssh_array[j] !== 0xFF) { 40608 replace = false; 40609 break; 40610 } 40611 } 40612 break; 40613 } 40614 } 40615 40616 if (replace) { 40617 pssh_array.set(KID, pos); 40618 } 40619 40620 return pssh_array.buffer; 40621 } 40622 40623 function getInitData(cp) { 40624 var pssh = null;
40625 // Get pssh from protectionData or from manifest 40626 if (protData && protData.pssh) { 40627 pssh = BASE64.decodeArray(protData.pssh).buffer; 40628 } else { 40629 pssh = _CommonEncryption2['default'].parseInitDataFromContentProtection(cp, BASE64); 40630 } 40631 40632 // Check if KID within pssh is empty, in that case set KID value according to 'cenc:default_KID' value 40633 if (pssh) { 40634 pssh = replaceKID(pssh, cp['cenc:default_KID']); 40635 } 40636 40637 return pssh; 40638 } 40639 40640 function getRequestHeadersFromMessage() /*message*/{ 40641 return null; 40642 } 40643 40644 function getLicenseRequestFromMessage(message) { 40645 return new Uint8Array(message); 40646 } 40647 40648 function getLicenseServerURLFromInitData() /*initData*/{ 40649 return null; 40650 } 40651 40652 instance = { 40653 uuid: uuid, 40654 schemeIdURI: schemeIdURI, 40655 systemString: systemString, 40656 init: init, 40657 getInitData: getInitData, 40658 getRequestHeadersFromMessage: getRequestHeadersFromMessage, 40659 getLicenseRequestFromMessage: getLicenseRequestFromMessage, 40660 getLicenseServerURLFromInitData: getLicenseServerURLFromInitData 40661 }; 40662 40663 return instance; 40664} 40665 40666KeySystemWidevine.__dashjs_factory_name = 'KeySystemWidevine'; 40667exports['default'] = dashjs.FactoryMaker.getSingletonFactory(KeySystemWidevine); 40668/* jshint ignore:line */ 40669module.exports = exports['default']; 40670 40671},{"146":146}],154:[function(_dereq_,module,exports){ 40672/** 40673 * The copyright in this software is being made available under the BSD License, 40674 * included below. This software may be subject to other third party and contributor 40675 * rights, including patent rights, and no such rights are granted under this license. 40676 * 40677 * Copyright (c) 2013, Dash Industry Forum. 40678 * All rights reserved. 40679 * 40680 * Redistribution and use in source and binary forms, with or without modification, 40681 * are permitted provided that the following conditions are met: 40682 * * Redistributions of source code must retain the above copyright notice, this 40683 * list of conditions and the following disclaimer. 40684 * * Redistributions in binary form must reproduce the above copyright notice, 40685 * this list of conditions and the following disclaimer in the documentation and/or 40686 * other materials provided with the distribution. 40687 * * Neither the name of Dash Industry Forum nor the names of its 40688 * contributors may be used to endorse or promote products derived from this software 40689 * without specific prior written permission. 40690 * 40691 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 40692 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 40693 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 40694 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 40695 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 40696 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 40697 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 40698 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40699 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40700 * POSSIBILITY OF SUCH DAMAGE. 40701 */ 40702 40703/** 40704 * Initial implementation of EME 40705 * 40706 * Implemented by Google Chrome prior to v36 40707 * 40708 * @implements ProtectionModel 40709 * @class 40710 */ 40711'use strict'; 40712 40713Object.defineProperty(exports, '__esModule', { 40714 value: true 40715}); 40716 40717function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 40718 40719var _controllersProtectionKeyController = _dereq_(150); 40720 40721var _controllersProtectionKeyController2 = _interopRequireDefault(_controllersProtectionKeyController); 40722 40723var _voNeedKey = _dereq_(168); 40724 40725var _voNeedKey2 = _interopRequireDefault(_voNeedKey); 40726 40727var _voKeyError = _dereq_(162); 40728 40729var _voKeyError2 = _interopRequireDefault(_voKeyError); 40730 40731var _voKeyMessage = _dereq_(163); 40732 40733var _voKeyMessage2 = _interopRequireDefault(_voKeyMessage); 40734 40735var _voKeySystemConfiguration = _dereq_(166); 40736 40737var _voKeySystemConfiguration2 = _interopRequireDefault(_voKeySystemConfiguration); 40738 40739var _voKeySystemAccess = _dereq_(165); 40740 40741var _voKeySystemAccess2 = _interopRequireDefault(_voKeySystemAccess); 40742 40743function ProtectionModel_01b(config) { 40744 40745 var context = this.context; 40746 var eventBus = config.eventBus; //Need to pass in here so we can use same instance since this is optional module 40747 var events = config.events; 40748 var log = config.log; 40749 var api = config.api; 40750 var errHandler = config.errHandler; 40751 40752 var instance = undefined, 40753 videoElement = undefined, 40754 keySystem = undefined, 40755 protectionKeyController = undefined, 40756 40757 // With this version of the EME APIs, sessionIDs are not assigned to 40758 // sessions until the first key message is received. We are assuming 40759 // that in the case of multiple sessions, key messages will be received 40760 // in the order that generateKeyRequest() is called. 40761 // Holding spot for newly-created sessions until we determine whether or 40762 // not the CDM supports sessionIDs 40763 pendingSessions = undefined, 40764 40765 // List of sessions that have been initialized. Only the first position will 40766 // be used in the case that the CDM does not support sessionIDs 40767 sessions = undefined, 40768 40769 // Not all CDMs support the notion of sessionIDs. Without sessionIDs 40770 // there is no way for us to differentiate between sessions, therefore 40771 // we must only allow a single session. Once we receive the first key 40772 // message we can set this flag to determine if more sessions are allowed 40773 moreSessionsAllowed = undefined, 40774 40775 // This is our main event handler for all desired HTMLMediaElement events 40776 // related to EME. These events are translated into our API-independent 40777 // versions of the same events 40778 eventHandler = undefined; 40779 40780 function setup() { 40781 videoElement = null; 40782 keySystem = null; 40783 pendingSessions = []; 40784 sessions = []; 40785 protectionKeyController = (0, _controllersProtectionKeyController2['default'])(context).getInstance(); 40786 eventHandler = createEventHandler(); 40787 } 40788 40789 function reset() { 40790 if (videoElement) { 40791 removeEventListeners(); 40792 } 40793 for (var i = 0; i < sessions.length; i++) { 40794 closeKeySession(sessions[i]); 40795 } 40796 eventBus.trigger(events.TEARDOWN_COMPLETE); 40797 } 40798 40799 function getKeySystem() { 40800 return keySystem; 40801 } 40802 40803 function getAllInitData() { 40804 var retVal = []; 40805 for (var i = 0; i < pendingSessions.length; i++) { 40806 retVal.push(pendingSessions[i].initData); 40807 } 40808 for (var i = 0; i < sessions.length; i++) { 40809 retVal.push(sessions[i].initData); 40810 } 40811 return retVal; 40812 } 40813 40814 function requestKeySystemAccess(ksConfigurations) { 40815 var ve = videoElement; 40816 if (!ve) { 40817 // Must have a video element to do this capability tests 40818 ve = document.createElement('video'); 40819 } 40820 40821 // Try key systems in order, first one with supported key system configuration 40822 // is used 40823 var found = false; 40824 for (var ksIdx = 0; ksIdx < ksConfigurations.length; ksIdx++) { 40825 var systemString = ksConfigurations[ksIdx].ks.systemString; 40826 var configs = ksConfigurations[ksIdx].configs; 40827 var supportedAudio = null; 40828 var supportedVideo = null; 40829 40830 // Try key system configs in order, first one with supported audio/video 40831 // is used 40832 for (var configIdx = 0; configIdx < configs.length; configIdx++) { 40833 //let audios = configs[configIdx].audioCapabilities; 40834 var videos = configs[configIdx].videoCapabilities; 40835 // Look for supported video container/codecs 40836 if (videos && videos.length !== 0) { 40837 supportedVideo = []; // Indicates that we have a requested video config 40838 for (var videoIdx = 0; videoIdx < videos.length; videoIdx++) { 40839 if (ve.canPlayType(videos[videoIdx].contentType, systemString) !== '') { 40840 supportedVideo.push(videos[videoIdx]); 40841 } 40842 } 40843 } 40844 40845 // No supported audio or video in this configuration OR we have 40846 // requested audio or video configuration that is not supported 40847 if (!supportedAudio && !supportedVideo || supportedAudio && supportedAudio.length === 0 || supportedVideo && supportedVideo.length === 0) { 40848 continue; 40849 } 40850 40851 // This configuration is supported 40852 found = true; 40853 var ksConfig = new _voKeySystemConfiguration2['default'](supportedAudio, supportedVideo); 40854 var ks = protectionKeyController.getKeySystemBySystemString(systemString); 40855 eventBus.trigger(events.KEY_SYSTEM_ACCESS_COMPLETE, { data: new _voKeySystemAccess2['default'](ks, ksConfig) }); 40856 break; 40857 } 40858 } 40859 if (!found) { 40860 eventBus.trigger(events.KEY_SYSTEM_ACCESS_COMPLETE, { error: 'Key system access denied! -- No valid audio/video content configurations detected!' }); 40861 } 40862 } 40863 40864 function selectKeySystem(keySystemAccess) { 40865 keySystem = keySystemAccess.keySystem; 40866 eventBus.trigger(events.INTERNAL_KEY_SYSTEM_SELECTED); 40867 } 40868 40869 function setMediaElement(mediaElement) { 40870 if (videoElement === mediaElement) { 40871 return; 40872 } 40873 40874 // Replacing the previous element 40875 if (videoElement) { 40876 removeEventListeners(); 40877 } 40878 40879 videoElement = mediaElement; 40880 40881 // Only if we are not detaching from the existing element 40882 if (videoElement) { 40883 videoElement.addEventListener(api.keyerror, eventHandler); 40884 videoElement.addEventListener(api.needkey, eventHandler); 40885 videoElement.addEventListener(api.keymessage, eventHandler); 40886 videoElement.addEventListener(api.keyadded, eventHandler); 40887 eventBus.trigger(events.VIDEO_ELEMENT_SELECTED); 40888 } 40889 } 40890 40891 function createKeySession(initData /*, keySystemType */) { 40892 40893 if (!keySystem) { 40894 throw new Error('Can not create sessions until you have selected a key system'); 40895 } 40896 40897 // Determine if creating a new session is allowed 40898 if (moreSessionsAllowed || sessions.length === 0) { 40899 40900 var newSession = { // Implements SessionToken 40901 sessionID: null, 40902 initData: initData, 40903 getSessionID: function getSessionID() { 40904 return this.sessionID; 40905 }, 40906 40907 getExpirationTime: function getExpirationTime() { 40908 return NaN; 40909 }, 40910 40911 getSessionType: function getSessionType() { 40912 return 'temporary'; 40913 } 40914 }; 40915 pendingSessions.push(newSession); 40916 40917 // Send our request to the CDM 40918 videoElement[api.generateKeyRequest](keySystem.systemString, new Uint8Array(initData)); 40919 40920 return newSession; 40921 } else { 40922 throw new Error('Multiple sessions not allowed!'); 40923 } 40924 } 40925 40926 function updateKeySession(sessionToken, message) { 40927 var sessionID = sessionToken.sessionID; 40928 if (!protectionKeyController.isClearKey(keySystem)) { 40929 // Send our request to the CDM 40930 videoElement[api.addKey](keySystem.systemString, new Uint8Array(message), new Uint8Array(sessionToken.initData), sessionID); 40931 } else { 40932 // For clearkey, message is a ClearKeyKeySet 40933 for (var i = 0; i < message.keyPairs.length; i++) { 40934 videoElement[api.addKey](keySystem.systemString, message.keyPairs[i].key, message.keyPairs[i].keyID, sessionID); 40935 } 40936 } 40937 } 40938 40939 function closeKeySession(sessionToken) { 40940 // Send our request to the CDM 40941 videoElement[api.cancelKeyRequest](keySystem.systemString, sessionToken.sessionID); 40942 } 40943 40944 function setServerCertificate() /*serverCertificate*/{/* Not supported */} 40945 function loadKeySession() /*sessionID*/{/* Not supported */} 40946 function removeKeySession() /*sessionToken*/{/* Not supported */} 40947 40948 function createEventHandler() { 40949 return { 40950 handleEvent: function handleEvent(event) { 40951 var sessionToken = null; 40952 switch (event.type) { 40953 40954 case api.needkey: 40955 var initData = ArrayBuffer.isView(event.initData) ? event.initData.buffer : event.initData; 40956 eventBus.trigger(events.NEED_KEY, { key: new _voNeedKey2['default'](initData, 'cenc') }); 40957 break; 40958 40959 case api.keyerror: 40960 sessionToken = findSessionByID(sessions, event.sessionId); 40961 if (!sessionToken) { 40962 sessionToken = findSessionByID(pendingSessions, event.sessionId); 40963 } 40964 40965 if (sessionToken) { 40966 var msg = ''; 40967 switch (event.errorCode.code) { 40968 case 1: 40969 msg += 'MEDIA_KEYERR_UNKNOWN - An unspecified error occurred. This value is used for errors that don\'t match any of the other codes.'; 40970 break; 40971 case 2: 40972 msg += 'MEDIA_KEYERR_CLIENT - The Ke
40972y System could not be installed or updated.'; 40973 break; 40974 case 3: 40975 msg += 'MEDIA_KEYERR_SERVICE - The message passed into update indicated an error from the license service.'; 40976 break; 40977 case 4: 40978 msg += 'MEDIA_KEYERR_OUTPUT - There is no available output device with the required characteristics for the content protection system.'; 40979 break; 40980 case 5: 40981 msg += 'MEDIA_KEYERR_HARDWARECHANGE - A hardware configuration change caused a content protection error.'; 40982 break; 40983 case 6: 40984 msg += 'MEDIA_KEYERR_DOMAIN - An error occurred in a multi-device domain licensing configuration. The most common error is a failure to join the domain.'; 40985 break; 40986 } 40987 msg += ' System Code = ' + event.systemCode; 40988 // TODO: Build error string based on key error 40989 eventBus.trigger(events.KEY_ERROR, { data: new _voKeyError2['default'](sessionToken, msg) }); 40990 } else { 40991 log('No session token found for key error'); 40992 } 40993 break; 40994 40995 case api.keyadded: 40996 sessionToken = findSessionByID(sessions, event.sessionId); 40997 if (!sessionToken) { 40998 sessionToken = findSessionByID(pendingSessions, event.sessionId); 40999 } 41000 41001 if (sessionToken) { 41002 log('DRM: Key added.'); 41003 eventBus.trigger(events.KEY_ADDED, { data: sessionToken }); //TODO not sure anything is using sessionToken? why there? 41004 } else { 41005 log('No session token found for key added'); 41006 } 41007 break; 41008 41009 case api.keymessage: 41010 41011 // If this CDM does not support session IDs, we will be limited 41012 // to a single session 41013 moreSessionsAllowed = event.sessionId !== null && event.sessionId !== undefined; 41014 41015 // SessionIDs supported 41016 if (moreSessionsAllowed) { 41017 41018 // Attempt to find an uninitialized token with this sessionID 41019 sessionToken = findSessionByID(sessions, event.sessionId); 41020 if (!sessionToken && pendingSessions.length > 0) { 41021 41022 // This is the first message for our latest session, so set the 41023 // sessionID and add it to our list 41024 sessionToken = pendingSessions.shift(); 41025 sessions.push(sessionToken); 41026 sessionToken.sessionID = event.sessionId; 41027 } 41028 } else if (pendingSessions.length > 0) { 41029 // SessionIDs not supported 41030 41031 sessionToken = pendingSessions.shift(); 41032 sessions.push(sessionToken); 41033 41034 if (pendingSessions.length !== 0) { 41035 errHandler.mediaKeyMessageError('Multiple key sessions were creates with a user-agent that does not support sessionIDs!! Unpredictable behavior ahead!'); 41036 } 41037 } 41038 41039 if (sessionToken) { 41040 var message = ArrayBuffer.isView(event.message) ? event.message.buffer : event.message; 41041 41042 // For ClearKey, the spec mandates that you pass this message to the 41043 // addKey method, so we always save it to the token since there is no 41044 // way to tell which key system is in use 41045 sessionToken.keyMessage = message; 41046 eventBus.trigger(events.INTERNAL_KEY_MESSAGE, { data: new _voKeyMessage2['default'](sessionToken, message, event.defaultURL) }); 41047 } else { 41048 log('No session token found for key message'); 41049 } 41050 break; 41051 } 41052 } 41053 }; 41054 } 41055 41056 /** 41057 * Helper function to retrieve the stored session token based on a given 41058 * sessionID value 41059 * 41060 * @param {Array} sessionArray - the array of sessions to search 41061 * @param {*}
41061 sessionID - the sessionID to search for 41062 * @returns {*} the session token with the given sessionID 41063 */ 41064 function findSessionByID(sessionArray, sessionID) { 41065 41066 if (!sessionID || !sessionArray) { 41067 return null; 41068 } else { 41069 var len = sessionArray.length; 41070 for (var i = 0; i < len; i++) { 41071 if (sessionArray[i].sessionID == sessionID) { 41072 return sessionArray[i]; 41073 } 41074 } 41075 return null; 41076 } 41077 } 41078 41079 function removeEventListeners() { 41080 videoElement.removeEventListener(api.keyerror, eventHandler); 41081 videoElement.removeEventListener(api.needkey, eventHandler); 41082 videoElement.removeEventListener(api.keymessage, eventHandler); 41083 videoElement.removeEventListener(api.keyadded, eventHandler); 41084 } 41085 41086 instance = { 41087 getAllInitData: getAllInitData, 41088 requestKeySystemAccess: requestKeySystemAccess, 41089 getKeySystem: getKeySystem, 41090 selectKeySystem: selectKeySystem, 41091 setMediaElement: setMediaElement, 41092 createKeySession: createKeySession, 41093 updateKeySession: updateKeySession, 41094 closeKeySession: closeKeySession, 41095 setServerCertificate: setServerCertificate, 41096 loadKeySession: loadKeySession, 41097 removeKeySession: removeKeySession, 41098 reset: reset 41099 }; 41100 41101 setup(); 41102 41103 return instance; 41104} 41105 41106ProtectionModel_01b.__dashjs_factory_name = 'ProtectionModel_01b'; 41107exports['default'] = dashjs.FactoryMaker.getClassFactory(ProtectionModel_01b); 41108/* jshint ignore:line */ 41109module.exports = exports['default']; 41110 41111},{"150":150,"162":162,"163":163,"165":165,"166":166,"168":168}],155:[function(_dereq_,module,exports){ 41112/** 41113 * The copyright in this software is being made available under the BSD License, 41114 * included below. This software may be subject to other third party and contributor 41115 * rights, including patent rights, and no such rights are granted under this license. 41116 * 41117 * Copyright (c) 2013, Dash Industry Forum. 41118 * All rights reserved. 41119 * 41120 * Redistribution and use in source and binary forms, with or without modification, 41121 * are permitted provided that the following conditions are met: 41122 * * Redistributions of source code must retain the above copyright notice, this 41123 * list of conditions and the following disclaimer. 41124 * * Redistributions in binary form must reproduce the above copyright notice, 41125 * this list of conditions and the following disclaimer in the documentation and/or 41126 * other materials provided with the distribution. 41127 * * Neither the name of Dash Industry Forum nor the names of its 41128 * contributors may be used to endorse or promote products derived from this software 41129 * without specific prior written permission. 41130 * 41131 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 41132 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 41133 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 41134 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 41135 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41136 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 41137 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 41138 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 41139 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41140 * POSSIBILITY OF SUCH DAMAGE. 41141 */ 41142 41143/** 41144 * Most recent EME implementation 41145 * 41146 * Implemented by Google Chrome v36+ (Windows, OSX, Linux) 41147 * 41148 * @implements ProtectionModel 41149 * @class 41150 */ 41151'use strict'; 41152 41153Object.defineProperty(exports, '__esModule', { 41154 value: true 41155}); 41156 41157function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 41158 41159var _controllersProtectionKeyController = _dereq_(150); 41160 41161var _controllersProtectionKeyController2 = _interopRequireDefault(_controllersProtectionKeyController); 41162 41163var _voNeedKey = _dereq_(168); 41164 41165var _voNeedKey2 = _interopRequireDefault(_voNeedKey); 41166 41167var _voKeyError = _dereq_(162); 41168 41169var _voKeyError2 = _interopRequireDefault(_voKeyError); 41170 41171var _voKeyMessage = _dereq_(163); 41172 41173var _voKeyMessage2 = _interopRequireDefault(_voKeyMessage); 41174 41175var _voKeySystemAccess = _dereq_(165); 41176 41177var _voKeySystemAccess2 = _interopRequireDefault(_voKeySystemAccess); 41178 41179function ProtectionModel_21Jan2015(config) { 41180 41181 var context = this.context; 41182 var eventBus = config.eventBus; //Need to pass in here so we can use same instance since this is optional module 41183 var events = config.events; 41184 var log = config.log; 41185 41186 var instance = undefined, 41187 keySystem = undefined, 41188 videoElement = undefined, 41189 mediaKeys = undefined, 41190 sessions = undefined, 41191 eventHandler = undefined, 41192 protectionKeyController = undefined; 41193 41194 function setup() { 41195 keySystem = null; 41196 videoElement = null; 41197 mediaKeys = null; 41198 sessions = []; 41199 protectionKeyController = (0, _controllersProtectionKeyController2['default'])(context).getInstance(); 41200 eventHandler = createEventHandler(); 41201 } 41202 41203 function reset() { 41204 var numSessions = sessions.length; 41205 var session = undefined; 41206 41207 if (numSessions !== 0) { 41208 (function () { 41209 // Called when we are done closing a session. Success or fail 41210 var done = function done(session) { 41211 removeSession(session); 41212 if (sessions.length === 0) { 41213 if (videoElement) { 41214 videoElement.removeEventListener('encrypted', eventHandler); 41215 videoElement.setMediaKeys(null).then(function () { 41216 eventBus.trigger(events.TEARDOWN_COMPLETE); 41217 }); 41218 } else { 41219 eventBus.trigger(events.TEARDOWN_COMPLETE); 41220 } 41221 } 41222 }; 41223 for (var i = 0; i < numSessions; i++) { 41224 session = sessions[i]; 41225 (function (s) { 41226 // Override closed promise resolver 41227 session.session.closed.then(function () { 41228 done(s); 41229 }); 41230 // Close the session and handle errors, otherwise promise 41231 // resolver above will be called 41232 closeKeySessionInternal(session)['catch'](function () { 41233 done(s); 41234 }); 41235 })(session); 41236 } 41237 })(); 41238 } else { 41239 eventBus.trigger(events.TEARDOWN_COMPLETE); 41240 } 41241 } 41242 41243 function getKeySystem() { 41244 return keySystem; 41245 } 41246 41247 function getAllInitData() { 41248 var retVal = []; 41249 for (var i = 0; i < sessions.length; i++) { 41250 retVal.push(sessions[i].initData); 41251 } 41252 return retVal; 41253 } 41254 41255 function requestKeySystemAccess(ksConfigurations) { 41256 requestKeySystemAccessInternal(ksConfigurations, 0); 41257 } 41258 41259 function selectKeySystem(keySystemAccess) { 41260 keySystemAccess.mksa.createMediaKeys().then(function (mkeys) { 41261 keySystem = keySystemAccess.keySystem; 41262 mediaKeys = mkeys; 41263 if (videoElement) { 41264 videoElement.setMediaKeys(mediaKeys).then(function () { 41265 eventBus.trigger(events.INTERNAL_KEY_SYSTEM_SELECTED); 41266 }); 41267 } 41268 })['catch'](function () { 41269 eventBus.trigger(events.INTERNAL_KEY_SYSTEM_SELECTED, { error: 'Error selecting keys system (' + keySystemAccess.keySystem.systemString + ')! Could not create MediaKeys -- TODO' }); 41270 }); 41271 } 41272 41273 function setMediaElement(mediaElement) { 41274 if (videoElement === mediaElement) return; 41275 41276 // Replacing the previous element 41277 if (videoElement) { 41278 videoElement.removeEventListener('encrypted', eventHandler); 41279 videoElement.setMediaKeys(null); 41280 } 41281 41282 videoElement = mediaElement; 41283 41284 // Only if we are not detaching from the existing element 41285 if (videoElement) { 41286 videoElement.addEventListener('encrypted', eventHandler); 41287 if (mediaKeys) { 41288 videoElement.setMediaKeys(mediaKeys); 41289 } 41290 } 41291 } 41292 41293 function setServerCertificate(serverCertificate) { 41294 if (!keySystem || !mediaKeys) { 41295 throw new Error('Can not set server certificate until you have selected a key system'); 41296 } 41297 mediaKeys.setServerCertificate(serverCertificate).then(function () { 41298 log('DRM: License server certificate successfully updated.'); 41299 eventBus.trigger(events.SERVER_CERTIFICATE_UPDATED); 41300 })['catch'](function (error) { 41301 eventBus.trigger(events.SERVER_CERTIFICATE_UPDATED, { error: 'Error updating server certificate -- ' + error.name }); 41302 }); 41303 } 41304 41305 function createKeySession(initData, sessionType) { 41306 41307 if (!keySystem || !mediaKeys) { 41308 throw new Error('Can not create sessions until you have selected a key system'); 41309 } 41310 41311 var session = mediaKeys.createSession(sessionType); 41312 var sessionToken = createSessionToken(session, initData, sessionType); 41313 41314 // Generate initial key request 41315 session.generateRequest('cenc', initData).then(function () { 41316 log('DRM: Session created. SessionID = ' + sessionToken.getSessionID()); 41317 eventBus.trigger(events.KEY_SESSION_CREATED, { data: sessionToken }); 41318 })['catch'](function (error) { 41319 // TODO: Better error string 41320 removeSession(sessionToken); 41321 eventBus.trigger(events.KEY_SESSION_CREATED, { data: null, error: 'Error generating key request -- ' + error.name }); 41322 }); 41323 } 41324 41325 function updateKeySession(sessionToken, message) { 41326 41327 var session = sessionToken.session; 41328 41329 // Send our request to the key session 41330 if (protectionKeyController.isClearKey(keySystem)) { 41331 message = message.toJWK(); 41332 } 41333 session.update(message)['catch'](function (error) { 41334 eventBus.trigger(events.KEY_ERROR, { data: new _voKeyError2['default'](sessionToken, 'Error sending update() message! ' + error.name) }); 41335 }); 41336 } 41337 41338 function loadKeySession(sessionID) { 41339 if (!keySystem || !mediaKeys) { 41340 throw new Error('Can not load sessions until you have selected a key system'); 41341 } 41342 41343 var session = mediaKeys.createSession(); 41344 41345 // Load persisted session data into our newly created session object 41346 session.load(sessionID).then(function (success) { 41347 if (success) { 41348 var sessionToken = createSessionToken(session); 41349 log('DRM: Session created. SessionID = ' + sessionToken.getSessionID()); 41350 eventBus.trigger(events.KEY_SESSION_CREATED, { data: sessionToken }); 41351 } else { 41352 eventBus.trigger(events.KEY_SESSION_CREATED, { data: null, error: 'Could not load session! Invalid Session ID (' + sessionID + ')' });
41353 } 41354 })['catch'](function (error) { 41355 eventBus.trigger(events.KEY_SESSION_CREATED, { data: null, error: 'Could not load session (' + sessionID + ')! ' + error.name }); 41356 }); 41357 } 41358 41359 function removeKeySession(sessionToken) { 41360 var session = sessionToken.session; 41361 41362 session.remove().then(function () { 41363 log('DRM: Session removed. SessionID = ' + sessionToken.getSessionID()); 41364 eventBus.trigger(events.KEY_SESSION_REMOVED, { data: sessionToken.getSessionID() }); 41365 }, function (error) { 41366 eventBus.trigger(events.KEY_SESSION_REMOVED, { data: null, error: 'Error removing session (' + sessionToken.getSessionID() + '). ' + error.name }); 41367 }); 41368 } 41369 41370 function closeKeySession(sessionToken) { 41371 // Send our request to the key session 41372 closeKeySessionInternal(sessionToken)['catch'](function (error) { 41373 removeSession(sessionToken); 41374 eventBus.trigger(events.KEY_SESSION_CLOSED, { data: null, error: 'Error closing session (' + sessionToken.getSessionID() + ') ' + error.name }); 41375 }); 41376 } 41377 41378 function requestKeySystemAccessInternal(ksConfigurations, idx) { 41379 (function (i) { 41380 var keySystem = ksConfigurations[i].ks; 41381 var configs = ksConfigurations[i].configs; 41382 navigator.requestMediaKeySystemAccess(keySystem.systemString, configs).then(function (mediaKeySystemAccess) { 41383 41384 // Chrome 40 does not currently implement MediaKeySystemAccess.getConfiguration() 41385 var configuration = typeof mediaKeySystemAccess.getConfiguration === 'function' ? mediaKeySystemAccess.getConfiguration() : null; 41386 var keySystemAccess = new _voKeySystemAccess2['default'](keySystem, configuration); 41387 keySystemAccess.mksa = mediaKeySystemAccess; 41388 eventBus.trigger(events.KEY_SYSTEM_ACCESS_COMPLETE, { data: keySystemAccess }); 41389 })['catch'](function () { 41390 if (++i < ksConfigurations.length) { 41391 requestKeySystemAccessInternal(ksConfigurations, i); 41392 } else { 41393 eventBus.trigger(events.KEY_SYSTEM_ACCESS_COMPLETE, { error: 'Key system access denied!' }); 41394 } 41395 }); 41396 })(idx); 41397 } 41398 41399 function closeKeySessionInternal(sessionToken) { 41400 var session = sessionToken.session; 41401 41402 // Remove event listeners 41403 session.removeEventListener('keystatuseschange', sessionToken); 41404 session.removeEventListener('message', sessionToken); 41405 41406 // Send our request to the key session 41407 return session.close(); 41408 } 41409 41410 // This is our main event handler for all desired HTMLMediaElement events 41411 // related to EME. These events are translated into our API-independent 41412 // versions of the same events 41413 function createEventHandler() { 41414 return { 41415 handleEvent: function handleEvent(event) { 41416 switch (event.type) { 41417 41418 case 'encrypted': 41419 if (event.initData) { 41420 var initData = ArrayBuffer.isView(event.initData) ? event.initData.buffer : event.initData; 41421 eventBus.trigger(events.NEED_KEY, { key: new _voNeedKey2['default'](initData, event.initDataType) }); 41422 } 41423 break; 41424 } 41425 } 41426 }; 41427 } 41428 41429 function removeSession(token) { 41430 // Remove from our session list 41431 for (var i = 0; i < sessions.length; i++) { 41432 if (sessions[i] === token) { 41433 sessions.splice(i, 1); 41434 break; 41435 } 41436 } 41437 } 41438 41439 // Function to create our session token objects which manage the EME 41440 // MediaKeySession and session-specific event handler 41441 function createSessionToken(session, initData, sessionType) { 41442 41443 var token = { // Implements SessionToken 41444 session: session, 41445 initData: initData, 41446 41447 // This is our main event handler for all desired MediaKeySession events 41448 // These events are translated into our API-independent versions of the 41449 // same events 41450 handleEvent: function handleEvent(event) { 41451 switch (event.type) { 41452 case 'keystatuseschange': 41453 eventBus.trigger(events.KEY_STATUSES_CHANGED, { data: this }); 41454 break; 41455 41456 case 'message': 41457 var message = ArrayBuffer.isView(event.message) ? event.message.buffer : event.message; 41458 eventBus.trigger(events.INTERNAL_KEY_MESSAGE, { data: new _voKeyMessage2['default'](this, message, undefined, event.messageType) }); 41459 break; 41460 } 41461 }, 41462 41463 getSessionID: function getSessionID() { 41464 return session.sessionId; 41465 }, 41466 41467 getExpirationTime: function getExpirationTime() { 41468 return session.expiration; 41469 }, 41470 41471 getKeyStatuses: function getKeyStatuses() { 41472 return session.keyStatuses; 41473 }, 41474 41475 getSessionType: function getSessionType() { 41476 return sessionType; 41477 } 41478 }; 41479 41480 // Add all event listeners 41481 session.addEventListener('keystatuseschange', token); 41482 session.addEventListener('message', token); 41483 41484 // Register callback for session closed Promise 41485 session.closed.then(function () { 41486 removeSession(token); 41487 log('DRM: Session closed. SessionID = ' + token.getSessionID()); 41488 eventBus.trigger(events.KEY_SESSION_CLOSED, { data: token.getSessionID() }); 41489 }); 41490 41491 // Add to our session list 41492 sessions.push(token); 41493 41494 return token; 41495 } 41496 41497 instance = { 41498 getAllInitData: getAllInitData, 41499 requestKeySystemAccess: requestKeySystemAccess, 41500 getKeySystem: getKeySystem, 41501 selectKeySystem: selectKeySystem, 41502 setMediaElement: setMediaElement, 41503 setServerCertificate: setServerCertificate, 41504 createKeySession: createKeySession, 41505 updateKeySession: updateKeySession, 41506 loadKeySession: loadKeySession, 41507 removeKeySession: removeKeySession, 41508 closeKeySession: closeKeySession, 41509 reset: reset 41510 }; 41511 41512 setup(); 41513 41514 return instance; 41515} 41516 41517ProtectionModel_21Jan2015.__dashjs_factory_name = 'ProtectionModel_21Jan2015'; 41518exports['default'] = dashjs.FactoryMaker.getClassFactory(ProtectionModel_21Jan2015); 41519/* jshint ignore:line */ 41520module.exports = exports['default']; 41521 41522},{"150":150,"162":162,"163":163,"165":165,"168":168}],156:[function(_dereq_,module,exports){ 41523/** 41524 * The copyright in this software is being made available under the BSD License, 41525 * included below. This software may be subject to other third party and contributor 41526 * rights, including patent rights, and no such rights are granted under this license. 41527 * 41528 * Copyright (c) 2013, Dash Industry Forum. 41529 * All rights reserved. 41530 * 41531 * Redistribution and use in source and binary forms, with or without modification, 41532 * are permitted provided that the following conditions are met: 41533 * * Redistributions of source code must retain the above copyright notice, this 41534 * list of conditions and the following disclaimer. 41535 * * Redistributions in binary form must reproduce the above copyright notice, 41536 * this list of conditions and the following disclaimer in the documentation and/or 41537 * other materials provided with the distribution. 41538 * * Neither the name of Dash Industry Forum nor the names of its 41539 * contributors may be used to endorse or promote products derived from this software 41540 * without specific prior written permission. 41541 * 41542 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 41543 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 41544 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 41545 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 41546 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
41546INCLUDING, BUT 41547 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 41548 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 41549 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 41550 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41551 * POSSIBILITY OF SUCH DAMAGE. 41552 */ 41553 41554/** 41555 * Implementation of the EME APIs as of the 3 Feb 2014 state of the specification. 41556 * 41557 * Implemented by Internet Explorer 11 (Windows 8.1) 41558 * 41559 * @implements ProtectionModel 41560 * @class 41561 */ 41562 41563'use strict'; 41564 41565Object.defineProperty(exports, '__esModule', { 41566 value: true 41567}); 41568 41569function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 41570 41571var _controllersProtectionKeyController = _dereq_(150); 41572 41573var _controllersProtectionKeyController2 = _interopRequireDefault(_controllersProtectionKeyController); 41574 41575var _voNeedKey = _dereq_(168); 41576 41577var _voNeedKey2 = _interopRequireDefault(_voNeedKey); 41578 41579var _voKeyError = _dereq_(162); 41580 41581var _voKeyError2 = _interopRequireDefault(_voKeyError); 41582 41583var _voKeyMessage = _dereq_(163); 41584 41585var _voKeyMessage2 = _interopRequireDefault(_voKeyMessage); 41586 41587var _voKeySystemConfiguration = _dereq_(166); 41588 41589var _voKeySystemConfiguration2 = _interopRequireDefault(_voKeySystemConfiguration); 41590 41591var _voKeySystemAccess = _dereq_(165); 41592 41593var _voKeySystemAccess2 = _interopRequireDefault(_voKeySystemAccess); 41594 41595function ProtectionModel_3Feb2014(config) { 41596 41597 var context = this.context; 41598 var eventBus = config.eventBus; //Need to pass in here so we can use same instance since this is optional module 41599 var events = config.events; 41600 var log = config.log; 41601 var api = config.api; 41602 41603 var instance = undefined, 41604 videoElement = undefined, 41605 keySystem = undefined, 41606 mediaKeys = undefined, 41607 keySystemAccess = undefined, 41608 sessions = undefined, 41609 eventHandler = undefined, 41610 protectionKeyController = undefined; 41611 41612 function setup() { 41613 videoElement = null; 41614 keySystem = null; 41615 mediaKeys = null; 41616 keySystemAccess = null; 41617 sessions = []; 41618 protectionKeyController = (0, _controllersProtectionKeyController2['default'])(context).getInstance(); 41619 eventHandler = createEventHandler(); 41620 } 41621 41622 function reset() { 41623 try { 41624 for (var i = 0; i < sessions.length; i++) { 41625 closeKeySession(sessions[i]); 41626 } 41627 if (videoElement) { 41628 videoElement.removeEventListener(api.needkey, eventHandler); 41629 } 41630 eventBus.trigger(events.TEARDOWN_COMPLETE); 41631 } catch (error) { 41632 eventBus.trigger(events.TEARDOWN_COMPLETE, { error: 'Error tearing down key sessions and MediaKeys! -- ' + error.message }); 41633 } 41634 } 41635 41636 function getKeySystem() { 41637 return keySystem; 41638 } 41639 41640 function getAllInitData() { 41641 var retVal = []; 41642 for (var i = 0; i < sessions.length; i++) { 41643 retVal.push(sessions[i].initData); 41644 } 41645 return retVal; 41646 } 41647 41648 function requestKeySystemAccess(ksConfigurations) { 41649 41650 // Try key systems in order, first one with supported key system configuration 41651 // is used 41652 var found = false; 41653 for (var ksIdx = 0; ksIdx < ksConfigurations.length; ksIdx++) { 41654 var systemString = ksConfigurations[ksIdx].ks.systemString; 41655 var configs = ksConfigurations[ksIdx].configs; 41656 var supportedAudio = null; 41657 var supportedVideo = null; 41658 41659 // Try key system configs in order, first one with supported audio/video 41660 // is used 41661 for (var configIdx = 0; configIdx < configs.length; configIdx++) { 41662 var audios = configs[configIdx].audioCapabilities; 41663 var videos = configs[configIdx].videoCapabilities; 41664 41665 // Look for supported audio container/codecs 41666 if (audios && audios.length !== 0) { 41667 supportedAudio = []; // Indicates that we have a requested audio config 41668 for (var audioIdx = 0; audioIdx < audios.length; audioIdx++) {
vendor: 9,593 bytes, lines 41669-41889
41669 if (window[api.MediaKeys].isTypeSupported(systemString, audios[audioIdx].contentType)) { 41670 supportedAudio.push(audios[audioIdx]); 41671 } 41672 } 41673 } 41674 41675 // Look for supported video container/codecs 41676 if (videos && videos.length !== 0) { 41677 supportedVideo = []; // Indicates that we have a requested video config 41678 for (var videoIdx = 0; videoIdx < videos.length; videoIdx++) { 41679 if (window[api.MediaKeys].isTypeSupported(systemString, videos[videoIdx].contentType)) { 41680 supportedVideo.push(videos[videoIdx]); 41681 } 41682 } 41683 } 41684 41685 // No supported audio or video in this configuration OR we have 41686 // requested audio or video configuration that is not supported 41687 if (!supportedAudio && !supportedVideo || supportedAudio && supportedAudio.length === 0 || supportedVideo && supportedVideo.length === 0) { 41688 continue; 41689 } 41690 41691 // This configuration is supported 41692 found = true; 41693 var ksConfig = new _voKeySystemConfiguration2['default'](supportedAudio, supportedVideo); 41694 var ks = protectionKeyController.getKeySystemBySystemString(systemString); 41695 eventBus.trigger(events.KEY_SYSTEM_ACCESS_COMPLETE, { data: new _voKeySystemAccess2['default'](ks, ksConfig) }); 41696 break; 41697 } 41698 } 41699 if (!found) { 41700 eventBus.trigger(events.KEY_SYSTEM_ACCESS_COMPLETE, { error: 'Key system access denied! -- No valid audio/video content configurations detected!' }); 41701 } 41702 } 41703 41704 function selectKeySystem(ksAccess) { 41705 try { 41706 mediaKeys = ksAccess.mediaKeys = new window[api.MediaKeys](ksAccess.keySystem.systemString); 41707 keySystem = ksAccess.keySystem; 41708 keySystemAccess = ksAccess; 41709 if (videoElement) { 41710 setMediaKeys(); 41711 } 41712 eventBus.trigger(events.INTERNAL_KEY_SYSTEM_SELECTED); 41713 } catch (error) { 41714 eventBus.trigger(events.INTERNAL_KEY_SYSTEM_SELECTED, { error: 'Error selecting keys system (' + keySystem.systemString + ')! Could not create MediaKeys -- TODO' }); 41715 } 41716 } 41717 41718 function setMediaElement(mediaElement) { 41719 if (videoElement === mediaElement) return; 41720 41721 // Replacing the previous element 41722 if (videoElement) { 41723 videoElement.removeEventListener(api.needkey, eventHandler); 41724 } 41725 41726 videoElement = mediaElement; 41727 41728 // Only if we are not detaching from the existing element 41729 if (videoElement) { 41730 videoElement.addEventListener(api.needkey, eventHandler); 41731 if (mediaKeys) { 41732 setMediaKeys(); 41733 } 41734 } 41735 } 41736 41737 function createKeySession(initData /*, keySystemType */) { 41738 41739 if (!keySystem || !mediaKeys || !keySystemAccess) { 41740 throw new Error('Can not create sessions until you have selected a key system'); 41741 } 41742 41743 // Use the first video capability for the contentType. 41744 // TODO: Not sure if there is a way to concatenate all capability data into a RFC6386-compatible format 41745 41746 // If player is trying to playback Audio only stream - don't error out. 41747 var capabilities = null; 41748 41749 if (keySystemAccess.ksConfiguration.videoCapabilities !== null && keySystemAccess.ksConfiguration.videoCapabilities.length > 0) capabilities = keySystemAccess.ksConfiguration.videoCapabilities[0]; 41750 41751 if (capabilities === null && keySystemAccess.ksConfiguration.audioCapabilities !== null && keySystemAccess.ksConfiguration.audioCapabilities.length > 0) capabilities = keySystemAccess.ksConfiguration.audioCapabilities[0]; 41752 41753 if (capabilities === null) throw new Error('Can not create sessions for unknown content types.'); 41754 41755 var contentType = capabilities.contentType; 41756 var session = mediaKeys.createSession(contentType, new Uint8Array(initData)); 41757 var sessionToken = createSessionToken(session, initData); 41758 41759 // Add all event listeners 41760 session.addEventListener(api.error, sessionToken); 41761 session.addEventListener(api.message, sessionToken); 41762 session.addEventListener(api.ready, sessionToken); 41763 session.addEventListener(api.close, sessionToken); 41764 41765 // Add to our session list 41766 sessions.push(sessionToken); 41767 log('DRM: Session created. SessionID = ' + sessionToken.getSessionID()); 41768 eventBus.trigger(events.KEY_SESSION_CREATED, { data: sessionToken }); 41769 } 41770 41771 function updateKeySession(sessionToken, message) { 41772 41773 var session = sessionToken.session; 41774 41775 if (!protectionKeyController.isClearKey(keySystem)) { 41776 // Send our request to the key session 41777 session.update(new Uint8Array(message)); 41778 } else { 41779 // For clearkey, message is a ClearKeyKeySet 41780 session.update(new Uint8Array(message.toJWK())); 41781 } 41782 } 41783 41784 /** 41785 * Close the given session and release all associated keys. Following 41786 * this call, the sessionToken becomes invalid 41787 * 41788 * @param {Object} sessionToken - the session token 41789 */ 41790 function closeKeySession(sessionToken) { 41791 41792 var session = sessionToken.session; 41793 41794 // Remove event listeners 41795 session.removeEventListener(api.error, sessionToken); 41796 session.removeEventListener(api.message, sessionToken); 41797 session.removeEventListener(api.ready, sessionToken); 41798 session.removeEventListener(api.close, sessionToken); 41799 41800 // Remove from our session list 41801 for (var i = 0; i < sessions.length; i++) { 41802 if (sessions[i] === sessionToken) { 41803 sessions.splice(i, 1); 41804 break; 41805 } 41806 } 41807 41808 // Send our request to the key session 41809 session[api.release](); 41810 } 41811 41812 function setServerCertificate() /*serverCertificate*/{/* Not supported */} 41813 function loadKeySession() /*sessionID*/{/* Not supported */} 41814 function removeKeySession() /*sessionToken*/{/* Not supported */} 41815 41816 function createEventHandler() { 41817 return { 41818 handleEvent: function handleEvent(event) { 41819 switch (event.type) { 41820 41821 case api.needkey: 41822 if (event.initData) { 41823 var initData = ArrayBuffer.isView(event.initData) ? event.initData.buffer : event.initData; 41824 eventBus.trigger(events.NEED_KEY, { key: new _voNeedKey2['default'](initData, 'cenc') }); 41825 } 41826 break; 41827 } 41828 } 41829 }; 41830 } 41831 41832 // IE11 does not let you set MediaKeys until it has entered a certain 41833 // readyState, so we need this logic to ensure we don't set the keys 41834 // too early 41835 function setMediaKeys() { 41836 var boundDoSetKeys = null; 41837 var doSetKeys = function doSetKeys() { 41838 videoElement.removeEventListener('loadedmetadata', boundDoSetKeys); 41839 videoElement[api.setMediaKeys](mediaKeys); 41840 eventBus.trigger(events.VIDEO_ELEMENT_SELECTED); 41841 }; 41842 if (videoElement.readyState >= 1) { 41843 doSetKeys(); 41844 } else { 41845 boundDoSetKeys = doSetKeys.bind(this); 41846 videoElement.addEventListener('loadedmetadata', boundDoSetKeys); 41847 } 41848 } 41849 41850 // Function to create our session token objects which manage the EME 41851 // MediaKeySession and session-specific event handler 41852 function createSessionToken(keySession, initData) { 41853 return { 41854 // Implements SessionToken 41855 session: keySession, 41856 initData: initData, 41857 41858 getSessionID: function getSessionID() { 41859 return this.session.sessionId; 41860 }, 41861 41862 getExpirationTime: function getExpirationTime() { 41863 return NaN; 41864 }, 41865 41866 getSessionType: function getSessionType() { 41867 return 'temporary'; 41868 }, 41869 // This is our main event handler for all desired MediaKeySession events 41870 // These events are translated into our API-independent versions of the 41871 // same events 41872 handleEvent: function handleEvent(event) { 41873 switch (event.type) { 41874 41875 case api.error: 41876 var errorStr = 'KeyError'; // TODO: Make better string from event 41877 eventBus.trigger(events.KEY_ERROR, { data: new _voKeyError2['default'](this, errorStr) }); 41878 break; 41879 case api.message: 41880 var message = ArrayBuffer.isView(event.message) ? event.message.buffer : event.message; 41881 eventBus.trigger(events.INTERNAL_KEY_MESSAGE, { data: new _voKeyMessage2['default'](this, message, event.destinationURL) }); 41882 break; 41883 case api.ready: 41884 log('DRM: Key added.'); 41885 eventBus.trigger(events.KEY_ADDED); 41886 break; 41887 41888 case api.close: 41889 log('DRM: Session closed. SessionID = ' + this.get
41889SessionID()); 41890 eventBus.trigger(events.KEY_SESSION_CLOSED, { data: this.getSessionID() }); 41891 break; 41892 } 41893 } 41894 }; 41895 } 41896 41897 instance = { 41898 getAllInitData: getAllInitData, 41899 requestKeySystemAccess: requestKeySystemAccess, 41900 getKeySystem: getKeySystem, 41901 selectKeySystem: selectKeySystem, 41902 setMediaElement: setMediaElement, 41903 createKeySession: createKeySession, 41904 updateKeySession: updateKeySession, 41905 closeKeySession: closeKeySession, 41906 setServerCertificate: setServerCertificate, 41907 loadKeySession: loadKeySession, 41908 removeKeySession: removeKeySession, 41909 reset: reset 41910 }; 41911 41912 setup(); 41913 41914 return instance; 41915} 41916 41917ProtectionModel_3Feb2014.__dashjs_factory_name = 'ProtectionModel_3Feb2014'; 41918exports['default'] = dashjs.FactoryMaker.getClassFactory(ProtectionModel_3Feb2014); 41919/* jshint ignore:line */ 41920module.exports = exports['default']; 41921 41922},{"150":150,"162":162,"163":163,"165":165,"166":166,"168":168}],157:[function(_dereq_,module,exports){ 41923/** 41924 * The copyright in this software is being made available under the BSD License, 41925 * included below. This software may be subject to other third party and contributor 41926 * rights, including patent rights, and no such rights are granted under this license. 41927 * 41928 * Copyright (c) 2013, Dash Industry Forum. 41929 * All rights reserved. 41930 * 41931 * Redistribution and use in source and binary forms, with or without modification, 41932 * are permitted provided that the following conditions are met: 41933 * * Redistributions of source code must retain the above copyright notice, this 41934 * list of conditions and the following disclaimer. 41935 * * Redistributions in binary form must reproduce the above copyright notice, 41936 * this list of conditions and the following disclaimer in the documentation and/or 41937 * other materials provided with the distribution. 41938 * * Neither the name of Dash Industry Forum nor the names of its 41939 * contributors may be used to endorse or promote products derived from this software 41940 * without specific prior written permission. 41941 * 41942 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 41943 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 41944 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 41945 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 41946 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41947 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 41948 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 41949 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 41950 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41951 * POSSIBILITY OF SUCH DAMAGE. 41952 */ 41953 41954/** 41955 * CableLabs ClearKey license server implementation 41956 * 41957 * For testing purposes and evaluating potential uses for ClearKey, we have developed 41958 * a dirt-simple API for requesting ClearKey licenses from a remote server. 41959 * 41960 * @implements LicenseServer 41961 * @class 41962 */ 41963'use strict'; 41964 41965Object.defineProperty(exports, '__esModule', { 41966 value: true 41967}); 41968 41969function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 41970 41971var _voKeyPair = _dereq_(164); 41972 41973var _voKeyPair2 = _interopRequireDefault(_voKeyPair); 41974 41975var _voClearKeyKeySet = _dereq_(161); 41976 41977var _voClearKeyKeySet2 = _interopRequireDefault(_voClearKeyKeySet); 41978 41979function ClearKey() { 41980 41981 var instance = undefined; 41982 41983 function getServerURLFromMessage(url, message /*, messageType*/) { 41984 // Build ClearKey server query string 41985 var jsonMsg = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(message))); 41986 url += '/?'; 41987 for (var i = 0; i < jsonMsg.kids.length; i++) { 41988 url += jsonMsg.kids[i] + '&'; 41989 } 41990 url = url.substring(0, url.length - 1); 41991 return url; 41992 } 41993 41994 function getHTTPMethod() /*messageType*/{ 41995 return 'GET'; 41996 } 41997 41998 function getResponseType() /*keySystemStr*/{ 41999 return 'json'; 42000 } 42001 42002 function getLicenseMessage(serverResponse /*, keySystemStr, messageType*/) { 42003 if (!serverResponse.hasOwnProperty('keys')) { 42004 return null; 42005 } 42006 var keyPairs = []; 42007 for (var i = 0; i < serverResponse.keys.length; i++) { 42008 var keypair = serverResponse.keys[i]; 42009 var keyid = keypair.kid.replace(/=/g, ''); 42010 var key = keypair.k.replace(/=/g, ''); 42011 42012 keyPairs.push(new _voKeyPair2['default'](keyid, key)); 42013 } 42014 return new _voClearKeyKeySet2['default'](keyPairs); 42015 } 42016 42017 function getErrorResponse(serverResponse /*, keySystemStr, messageType*/) { 42018 return String.fromCharCode.apply(null, new Uint8Array(serverResponse)); 42019 } 42020 42021 instance = { 42022 getServerURLFromMessage: getServerURLFromMessage, 42023 getHTTPMethod: getHTTPMethod, 42024 getResponseType: getResponseType, 42025 getLicenseMessage: getLicenseMessage, 42026 getErrorResponse: getErrorResponse 42027 }; 42028 42029 return instance; 42030} 42031 42032ClearKey.__dashjs_factory_name = 'ClearKey'; 42033exports['default'] = dashjs.FactoryMaker.getSingletonFactory(ClearKey); 42034/* jshint ignore:line */ 42035module.exports = exports['default']; 42036 42037},{"161":161,"164":164}],158:[function(_dereq_,module,exports){ 42038/** 42039 * The copyright in this software is being made available under the BSD License, 42040 * included below. This software may be subject to other third party and contributor 42041 * rights, including patent rights, and no such rights are granted under this license. 42042 * 42043 * Copyright (c) 2013, Dash Industry Forum. 42044 * All rights reserved. 42045 * 42046 * Redistribution and use in source and binary forms, with or without modification, 42047 * are permitted provided that the following conditions are met: 42048 * * Redistributions of source code must retain the above copyright notice, this 42049 * list of conditions and the following disclaimer. 42050 * * Redistributions in binary form must reproduce the above copyright notice, 42051 * this list of conditions and the following disclaimer in the documentation and/or 42052 * other materials provided with the distribution. 42053 * * Neither the name of Dash Industry Forum nor the names of its 42054 * contributors may be used to endorse or promote products derived from this software 42055 * without specific prior written permission. 42056 * 42057 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42058 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42059 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42060 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42061 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
42061INCLUDING, BUT 42062 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42063 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42064 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42065 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42066 * POSSIBILITY OF SUCH DAMAGE. 42067 */ 42068 42069/** 42070 * CastLabs DRMToday License Server implementation 42071 * 42072 * @implements LicenseServer 42073 * @class 42074 */ 42075 42076'use strict'; 42077 42078Object.defineProperty(exports, '__esModule', { 42079 value: true 42080}); 42081function DRMToday(config) { 42082 42083 var BASE64 = config.BASE64; 42084 42085 var keySystems = { 42086 'com.widevine.alpha': { 42087 responseType: 'json', 42088 getLicenseMessage: function getLicenseMessage(response) { 42089 return BASE64.decodeArray(response.license); 42090 }, 42091 getErrorResponse: function getErrorResponse(response) { 42092 return response; 42093 } 42094 }, 42095 'com.microsoft.playready': { 42096 responseType: 'arraybuffer', 42097 getLicenseMessage: function getLicenseMessage(response) { 42098 return response; 42099 }, 42100 getErrorResponse: function getErrorResponse(response) { 42101 return String.fromCharCode.apply(null, new Uint8Array(response)); 42102 } 42103 } 42104 }; 42105 42106 var instance = undefined; 42107 42108 function checkConfig() { 42109 if (!BASE64 || !BASE64.hasOwnProperty('decodeArray')) { 42110 throw new Error('Missing config parameter(s)'); 42111 } 42112 } 42113 42114 function getServerURLFromMessage(url /*, message, messageType*/) { 42115 return url; 42116 } 42117 42118 function getHTTPMethod() /*messageType*/{ 42119 return 'POST'; 42120 } 42121 42122 function getResponseType(keySystemStr /*, messageType*/) { 42123 return keySystems[keySystemStr].responseType; 42124 } 42125 42126 function getLicenseMessage(serverResponse, keySystemStr /*, messageType*/) { 42127 checkConfig(); 42128 return keySystems[keySystemStr].getLicenseMessage(serverResponse); 42129 } 42130 42131 function getErrorResponse(serverResponse, keySystemStr /*, messageType*/) { 42132 return keySystems[keySystemStr].getErrorResponse(serverResponse); 42133 } 42134 42135 instance = { 42136 getServerURLFromMessage: getServerURLFromMessage, 42137 getHTTPMethod: getHTTPMethod, 42138 getResponseType: getResponseType, 42139 getLicenseMessage: getLicenseMessage, 42140 getErrorResponse: getErrorResponse 42141 }; 42142 42143 return instance; 42144} 42145 42146DRMToday.__dashjs_factory_name = 'DRMToday'; 42147exports['default'] = dashjs.FactoryMaker.getSingletonFactory(DRMToday); 42148/* jshint ignore:line */ 42149module.exports = exports['default']; 42150 42151},{}],159:[function(_dereq_,module,exports){ 42152/** 42153 * The copyright in this software is being made available under the BSD License, 42154 * included below. This software may be subject to other third party and contributor 42155 * rights, including patent rights, and no such rights are granted under this license. 42156 * 42157 * Copyright (c) 2013, Dash Industry Forum. 42158 * All rights reserved. 42159 * 42160 * Redistribution and use in source and binary forms, with or without modification, 42161 * are permitted provided that the following conditions are met: 42162 * * Redistributions of source code must retain the above copyright notice, this 42163 * list of conditions and the following disclaimer. 42164 * * Redistributions in binary form must reproduce the above copyright notice, 42165 * this list of conditions and the following disclaimer in the documentation and/or 42166 * other materials provided with the distribution. 42167 * * Neither the name of Dash Industry Forum nor the names of its 42168 * contributors may be used to endorse or promote products derived from this software 42169 * without specific prior written permission. 42170 * 42171 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42172 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42173 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42174 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42175 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
42175INCLUDING, BUT 42176 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42177 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42178 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42179 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42180 * POSSIBILITY OF SUCH DAMAGE. 42181 */ 42182 42183/* global escape: true */ 42184 42185/** 42186 * Microsoft PlayReady Test License Server 42187 * 42188 * For testing content that uses the PlayReady test server at 42189 * 42190 * @implements LicenseServer 42191 * @class 42192 */ 42193 42194'use strict'; 42195 42196Object.defineProperty(exports, '__esModule', { 42197 value: true 42198}); 42199function PlayReady() { 42200 42201 var instance = undefined; 42202 42203 var soap = 'http://schemas.xmlsoap.org/soap/envelope/'; 42204 42205 function uintToString(arrayBuffer) { 42206 var encodedString = String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)); 42207 var decodedString = decodeURIComponent(escape(encodedString)); 42208 return decodedString; 42209 } 42210 42211 function parseServerResponse(serverResponse) { 42212 if (window.DOMParser) { 42213 var stringResponse = uintToString(serverResponse); 42214 var parser = new window.DOMParser(); 42215 var xmlDoc = parser.parseFromString(stringResponse, 'text/xml'); 42216 var envelope = xmlDoc ? xmlDoc.getElementsByTagNameNS(soap, 'Envelope')[0] : null; 42217 var body = envelope ? envelope.getElementsByTagNameNS(soap, 'Body')[0] : null; 42218 var fault = body ? body.getElementsByTagNameNS(soap, 'Fault')[0] : null; 42219 42220 if (fault) { 42221 return null; 42222 } 42223 } 42224 return serverResponse; 42225 } 42226 42227 function parseErrorResponse(serverResponse) { 42228 var faultstring = ''; 42229 var statusCode = ''; 42230 var message = ''; 42231 var idStart = -1; 42232 var idEnd = -1; 42233 42234 if (window.DOMParser) { 42235 var stringResponse = uintToString(serverResponse); 42236 var parser = new window.DOMParser(); 42237 var xmlDoc = parser.parseFromString(stringResponse, 'text/xml'); 42238 var envelope = xmlDoc ? xmlDoc.getElementsByTagNameNS(soap, 'Envelope')[0] : null; 42239 var body = envelope ? envelope.getElementsByTagNameNS(soap, 'Body')[0] : null; 42240 var fault = body ? body.getElementsByTagNameNS(soap, 'Fault')[0] : null; 42241 var detail = fault ? fault.getElementsByTagName('detail')[0] : null; 42242 var exception = detail ? detail.getElementsByTagName('Exception')[0] : null; 42243 var node = null; 42244 42245 if (fault === null) { 42246 return stringResponse; 42247 } 42248 42249 node = fault.getElementsByTagName('faultstring')[0].firstChild; 42250 faultstring = node ? node.nodeValue : null; 42251 42252 if (exception !== null) { 42253 node = exception.getElementsByTagName('StatusCode')[0]; 42254 statusCode = node ? node.firstChild.nodeValue : null; 42255 node = exception.getElementsByTagName('Message')[0]; 42256 message = node ? node.firstChild.nodeValue : null; 42257 idStart = message ? message.lastIndexOf('[') + 1 : -1; 42258 idEnd = message ? message.indexOf(']') : -1; 42259 message = message ? message.substring(idStart, idEnd) : ''; 42260 } 42261 } 42262 42263 var errorString = 'code: ' + statusCode + ', name: ' + faultstring; 42264 if (message) { 42265 errorString += ', message: ' + message; 42266 } 42267 42268 return errorString; 42269 } 42270 42271 function getServerURLFromMessage(url /*, message, messageType*/) { 42272 return url; 42273 } 42274 42275 function getHTTPMethod() /*messageType*/{ 42276 return 'POST'; 42277 } 42278 42279 function getResponseType() /*keySystemStr, messageType*/{ 42280 return 'arraybuffer'; 42281 } 42282 42283 function getLicenseMessage(serverResponse /*, keySystemStr, messageType*/) { 42284 return parseServerResponse.call(this, serverResponse); 42285 } 42286 42287 function getErrorResponse(serverResponse /*, keySystemStr, messageType*/) { 42288 return parseErrorResponse.call(this, serverResponse); 42289 } 42290 42291 instance = { 42292 getServerURLFromMessage: getServerURLFromMessage, 42293 getHTTPMethod: getHTTPMethod, 42294 getResponseType: getResponseType, 42295 getLicenseMessage: getLicenseMessage, 42296 getErrorResponse: getErrorResponse 42297 }; 42298 42299 return instance; 42300} 42301 42302PlayReady.__dashjs_factory_name = 'PlayReady'; 42303exports['default'] = dashjs.FactoryMaker.getSingletonFactory(PlayReady);
42304/* jshint ignore:line */ 42305module.exports = exports['default']; 42306 42307},{}],160:[function(_dereq_,module,exports){ 42308/** 42309 * The copyright in this software is being made available under the BSD License, 42310 * included below. This software may be subject to other third party and contributor 42311 * rights, including patent rights, and no such rights are granted under this license. 42312 * 42313 * Copyright (c) 2013, Dash Industry Forum. 42314 * All rights reserved. 42315 * 42316 * Redistribution and use in source and binary forms, with or without modification, 42317 * are permitted provided that the following conditions are met: 42318 * * Redistributions of source code must retain the above copyright notice, this 42319 * list of conditions and the following disclaimer. 42320 * * Redistributions in binary form must reproduce the above copyright notice, 42321 * this list of conditions and the following disclaimer in the documentation and/or 42322 * other materials provided with the distribution. 42323 * * Neither the name of Dash Industry Forum nor the names of its 42324 * contributors may be used to endorse or promote products derived from this software 42325 * without specific prior written permission. 42326 * 42327 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42328 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42329 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42330 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42331 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42332 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42333 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42334 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42335 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42336 * POSSIBILITY OF SUCH DAMAGE. 42337 */ 42338 42339'use strict'; 42340 42341Object.defineProperty(exports, '__esModule', { 42342 value: true 42343}); 42344function Widevine() { 42345 42346 var instance = undefined; 42347 42348 function getServerURLFromMessage(url /*, message, messageType*/) { 42349 return url; 42350 } 42351 42352 function getHTTPMethod() /*messageType*/{ 42353 return 'POST'; 42354 } 42355 42356 function getResponseType() /*keySystemStr, messageType*/{ 42357 return 'arraybuffer'; 42358 } 42359 42360 function getLicenseMessage(serverResponse /*, keySystemStr, messageType*/) { 42361 return serverResponse; 42362 } 42363 42364 function getErrorResponse(serverResponse /*, keySystemStr, messageType*/) { 42365 return String.fromCharCode.apply(null, new Uint8Array(serverResponse)); 42366 } 42367 42368 instance = { 42369 getServerURLFromMessage: getServerURLFromMessage, 42370 getHTTPMethod: getHTTPMethod, 42371 getResponseType: getResponseType, 42372 getLicenseMessage: getLicenseMessage, 42373 getErrorResponse: getErrorResponse 42374 }; 42375 42376 return instance; 42377} 42378 42379Widevine.__dashjs_factory_name = 'Widevine'; 42380exports['default'] = dashjs.FactoryMaker.getSingletonFactory(Widevine); 42381/* jshint ignore:line */ 42382module.exports = exports['default']; 42383 42384},{}],161:[function(_dereq_,module,exports){ 42385/** 42386 * The copyright in this software is being made available under the BSD License, 42387 * included below. This software may be subject to other third party and contributor 42388 * rights, including patent rights, and no such rights are granted under this license. 42389 * 42390 * Copyright (c) 2013, Dash Industry Forum. 42391 * All rights reserved. 42392 * 42393 * Redistribution and use in source and binary forms, with or without modification, 42394 * are permitted provided that the following conditions are met: 42395 * * Redistributions of source code must retain the above copyright notice, this 42396 * list of conditions and the following disclaimer. 42397 * * Redistributions in binary form must reproduce the above copyright notice, 42398 * this list of conditions and the following disclaimer in the documentation and/or 42399 * other materials provided with the distribution. 42400 * * Neither the name of Dash Industry Forum nor the names of its 42401 * contributors may be used to endorse or promote products derived from this software 42402 * without specific prior written permission. 42403 * 42404 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42405 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42406 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42407 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42408 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
42408INCLUDING, BUT 42409 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42410 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42411 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42412 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42413 * POSSIBILITY OF SUCH DAMAGE. 42414 */ 42415 42416/** 42417 * @classdesc A collection of ClearKey encryption keys with an (optional) associated 42418 * type 42419 * @ignore 42420 */ 42421'use strict'; 42422 42423Object.defineProperty(exports, '__esModule', { 42424 value: true 42425}); 42426 42427var _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; }; })(); 42428 42429function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 42430 42431var ClearKeyKeySet = (function () { 42432 /** 42433 * @param {Array.<KeyPair>} keyPairs 42434 * @param {string} type the type of keys in this set. One of either 'persistent' 42435 * or 'temporary'. Can also be null or undefined. 42436 * @class 42437 * @ignore 42438 */ 42439 42440 function ClearKeyKeySet(keyPairs, type) { 42441 _classCallCheck(this, ClearKeyKeySet); 42442 42443 if (type && type !== 'persistent' && type !== 'temporary') throw new Error('Invalid ClearKey key set type! Must be one of \'persistent\' or \'temporary\''); 42444 this.keyPairs = keyPairs; 42445 this.type = type; 42446 } 42447 42448 /** 42449 * Convert this key set to its JSON Web Key (JWK) representation 42450 * 42451 * @return {ArrayBuffer} JWK object UTF-8 encoded as ArrayBuffer 42452 */ 42453 42454 _createClass(ClearKeyKeySet, [{ 42455 key: 'toJWK', 42456 value: function toJWK() { 42457 var i = undefined; 42458 var numKeys = this.keyPairs.length; 42459 var jwk = { keys: [] }; 42460 42461 for (i = 0; i < numKeys; i++) { 42462 var key = { 42463 kty: 'oct', 42464 alg: 'A128KW', 42465 kid: this.keyPairs[i].keyID, 42466 k: this.keyPairs[i].key 42467 }; 42468 jwk.keys.push(key); 42469 } 42470 if (this.type) { 42471 jwk.type = this.type; 42472 } 42473 var jwkString = JSON.stringify(jwk); 42474 var len = jwkString.length; 42475 42476 // Convert JSON string to ArrayBuffer 42477 var buf = new ArrayBuffer(len); 42478 var bView = new Uint8Array(buf); 42479 for (i = 0; i < len; i++) bView[i] = jwkString.charCodeAt(i); 42480 return buf; 42481 } 42482 }]); 42483 42484 return ClearKeyKeySet; 42485})(); 42486 42487exports['default'] = ClearKeyKeySet; 42488module.exports = exports['default']; 42489 42490},{}],162:[function(_dereq_,module,exports){ 42491/** 42492 * The copyright in this software is being made available under the BSD License, 42493 * included below. This software may be subject to other third party and contributor 42494 * rights, including patent rights, and no such rights are granted under this license. 42495 * 42496 * Copyright (c) 2013, Dash Industry Forum. 42497 * All rights reserved. 42498 * 42499 * Redistribution and use in source and binary forms, with or without modification, 42500 * are permitted provided that the following conditions are met: 42501 * * Redistributions of source code must retain the above copyright notice, this 42502 * list of conditions and the following disclaimer. 42503 * * Redistributions in binary form must reproduce the above copyright notice, 42504 * this list of conditions and the following disclaimer in the documentation and/or 42505 * other materials provided with the distribution. 42506 * * Neither the name of Dash Industry Forum nor the names of its 42507 * contributors may be used to endorse or promote products derived from this software 42508 * without specific prior written permission. 42509 * 42510 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42511 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42512 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42513 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42514 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
42514INCLUDING, BUT 42515 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42516 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42517 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42518 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42519 * POSSIBILITY OF SUCH DAMAGE. 42520 */ 42521 42522/** 42523 * @classdesc EME-independent KeyError 42524 * @ignore 42525 */ 42526"use strict"; 42527 42528Object.defineProperty(exports, "__esModule", { 42529 value: true 42530}); 42531 42532function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 42533 42534var KeyError = 42535/** 42536 * @param {Object} sessionToken the key session to which this error is associated 42537 * @param {string} errorString an informational error message 42538 * @class 42539 * @deprecated Newest versions of EME APIs will not use this error object 42540 */ 42541function KeyError(sessionToken, errorString) { 42542 _classCallCheck(this, KeyError); 42543 42544 this.sessionToken = sessionToken; 42545 this.error = errorString; 42546}; 42547 42548exports["default"] = KeyError; 42549module.exports = exports["default"]; 42550 42551},{}],163:[function(_dereq_,module,exports){ 42552/** 42553 * The copyright in this software is being made available under the BSD License, 42554 * included below. This software may be subject to other third party and contributor 42555 * rights, including patent rights, and no such rights are granted under this license. 42556 * 42557 * Copyright (c) 2013, Dash Industry Forum. 42558 * All rights reserved. 42559 * 42560 * Redistribution and use in source and binary forms, with or without modification, 42561 * are permitted provided that the following conditions are met: 42562 * * Redistributions of source code must retain the above copyright notice, this 42563 * list of conditions and the following disclaimer. 42564 * * Redistributions in binary form must reproduce the above copyright notice, 42565 * this list of conditions and the following disclaimer in the documentation and/or 42566 * other materials provided with the distribution. 42567 * * Neither the name of Dash Industry Forum nor the names of its 42568 * contributors may be used to endorse or promote products derived from this software 42569 * without specific prior written permission. 42570 * 42571 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42572 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42573 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42574 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42575 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42576 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42577 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42578 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42579 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42580 * POSSIBILITY OF SUCH DAMAGE. 42581 */ 42582/** 42583 * @classdesc EME-independent KeyMessage 42584 * @ignore 42585 */ 42586'use strict'; 42587 42588Object.defineProperty(exports, '__esModule', { 42589 value: true 42590}); 42591 42592function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 42593 42594var KeyMessage = 42595/** 42596 * @param {SessionToken} sessionToken the session 42597 * to which the key message is associated 42598 * @param {ArrayBuffer} message the key message 42599 * @param {string} defaultURL license acquisition URL provided by the CDM 42600 * @param {string} messageType Supported message types can be found 42601 * {@link https://w3c.github.io/encrypted-media/#idl-def-MediaKeyMessageType|here}. 42602 * @class 42603 */ 42604function KeyMessage(sessionToken, message, defaultURL, messageType) { 42605 _classCallCheck(this, KeyMessage); 42606 42607 this.sessionToken = sessionToken; 42608 this.message = message; 42609 this.defaultURL = defaultURL; 42610 this.messageType = messageType ? messageType : 'license-request'; 42611}; 42612 42613exports['default'] = KeyMessage; 42614module.exports = exports['default']; 42615 42616},{}],164:[function(_dereq_,module,exports){ 42617/** 42618 * The copyright in this software is being made available under the BSD License, 42619 * included below. This software may be subject to other third party and contributor 42620 * rights, including patent rights, and no such rights are granted under this license. 42621 * 42622 * Copyright (c) 2013, Dash Industry Forum. 42623 * All rights reserved. 42624 * 42625 * Redistribution and use in source and binary forms, with or without modification, 42626 * are permitted provided that the following conditions are met: 42627 * * Redistributions of source code must retain the above copyright notice, this 42628 * list of conditions and the following disclaimer. 42629 * * Redistributions in binary form must reproduce the above copyright notice, 42630 * this list of conditions and the following disclaimer in the documentation and/or 42631 * other materials provided with the distribution. 42632 * * Neither the name of Dash Industry Forum nor the names of its 42633 * contributors may be used to endorse or promote products derived from this software 42634 * without specific prior written permission. 42635 * 42636 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42637 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42638 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42639 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42640 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
42640INCLUDING, BUT 42641 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42642 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42643 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42644 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42645 * POSSIBILITY OF SUCH DAMAGE. 42646 */ 42647/** 42648 * @classdesc Represents a 128-bit keyID and 128-bit encryption key 42649 * @ignore 42650 */ 42651"use strict"; 42652 42653Object.defineProperty(exports, "__esModule", { 42654 value: true 42655}); 42656 42657function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 42658 42659var KeyPair = 42660/** 42661 * @param {string} keyID 128-bit key ID, base64 encoded, with no padding 42662 * @param {string} key 128-bit encryption key, base64 encoded, with no padding 42663 * @class 42664 * @ignore 42665 */ 42666function KeyPair(keyID, key) { 42667 _classCallCheck(this, KeyPair); 42668 42669 this.keyID = keyID; 42670 this.key = key; 42671}; 42672 42673exports["default"] = KeyPair; 42674module.exports = exports["default"]; 42675 42676},{}],165:[function(_dereq_,module,exports){ 42677/** 42678 * The copyright in this software is being made available under the BSD License, 42679 * included below. This software may be subject to other third party and contributor 42680 * rights, including patent rights, and no such rights are granted under this license. 42681 * 42682 * Copyright (c) 2013, Dash Industry Forum. 42683 * All rights reserved. 42684 * 42685 * Redistribution and use in source and binary forms, with or without modification, 42686 * are permitted provided that the following conditions are met: 42687 * * Redistributions of source code must retain the above copyright notice, this 42688 * list of conditions and the following disclaimer. 42689 * * Redistributions in binary form must reproduce the above copyright notice, 42690 * this list of conditions and the following disclaimer in the documentation and/or 42691 * other materials provided with the distribution. 42692 * * Neither the name of Dash Industry Forum nor the names of its 42693 * contributors may be used to endorse or promote products derived from this software 42694 * without specific prior written permission. 42695 * 42696 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42697 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42698 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42699 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42700 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42701 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42702 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42703 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42704 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42705 * POSSIBILITY OF SUCH DAMAGE. 42706 */ 42707/** 42708 * @classdesc Creates a new key system access token. Represents a valid key system for 42709 * given piece of content and key system requirements. Used to initialize license 42710 * acquisition operations. 42711 * @ignore 42712 */ 42713"use strict"; 42714 42715Object.defineProperty(exports, "__esModule", { 42716 value: true 42717}); 42718 42719function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 42720 42721var KeySystemAccess = 42722/** 42723 * @param {MediaPlayer.dependencies.protection.KeySystem} keySystem the key system 42724 * @param {KeySystemConfiguration} ksConfiguration the 42725 * subset of configurations passed to the key system access request that are supported 42726 * by this user agent 42727 * @class 42728 * @ignore 42729 */ 42730function KeySystemAccess(keySystem, ksConfiguration) { 42731 _classCallCheck(this, KeySystemAccess); 42732 42733 this.keySystem = keySystem; 42734 this.ksConfiguration = ksConfiguration; 42735}; 42736 42737exports["default"] = KeySystemAccess; 42738module.exports = exports["default"]; 42739 42740},{}],166:[function(_dereq_,module,exports){ 42741/** 42742 * The copyright in this software is being made available under the BSD License, 42743 * included below. This software may be subject to other third party and contributor 42744 * rights, including patent rights, and no such rights are granted under this license. 42745 * 42746 * Copyright (c) 2013, Dash Industry Forum. 42747 * All rights reserved. 42748 * 42749 * Redistribution and use in source and binary forms, with or without modification, 42750 * are permitted provided that the following conditions are met: 42751 * * Redistributions of source code must retain the above copyright notice, this 42752 * list of conditions and the following disclaimer. 42753 * * Redistributions in binary form must reproduce the above copyright notice, 42754 * this list of conditions and the following disclaimer in the documentation and/or 42755 * other materials provided with the distribution. 42756 * * Neither the name of Dash Industry Forum nor the names of its 42757 * contributors may be used to endorse or promote products derived from this software 42758 * without specific prior written permission. 42759 * 42760 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42761 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42762 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42763 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42764 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
42764INCLUDING, BUT 42765 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42766 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42767 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42768 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42769 * POSSIBILITY OF SUCH DAMAGE. 42770 */ 42771 42772/** 42773 * @classdesc Represents a set of configurations that describe the capabilities desired for 42774 * support by a given CDM 42775 * @ignore 42776 */ 42777'use strict'; 42778 42779Object.defineProperty(exports, '__esModule', { 42780 value: true 42781}); 42782 42783function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 42784 42785var KeySystemConfiguration = 42786/** 42787 * @param {Array.<MediaCapability>} audioCapabilities array of 42788 * desired audio capabilities. Higher preference capabilities should be placed earlier 42789 * in the array. 42790 * @param {Array.<MediaCapability>} videoCapabilities array of 42791 * desired video capabilities. Higher preference capabilities should be placed earlier 42792 * in the array. 42793 * @param {string} distinctiveIdentifier desired use of distinctive identifiers. 42794 * One of "required", "optional", or "not-allowed" 42795 * @param {string} persistentState desired support for persistent storage of 42796 * key systems. One of "required", "optional", or "not-allowed" 42797 * @param {Array.<string>} sessionTypes List of session types that must 42798 * be supported by the key system 42799 * @class 42800 */ 42801function KeySystemConfiguration(audioCapabilities, videoCapabilities, distinctiveIdentifier, persistentState, sessionTypes) { 42802 _classCallCheck(this, KeySystemConfiguration); 42803 42804 this.initDataTypes = ['cenc']; 42805 if (audioCapabilities && audioCapabilities.length) { 42806 this.audioCapabilities = audioCapabilities; 42807 } 42808 if (videoCapabilities && videoCapabilities.length) { 42809 this.videoCapabilities = videoCapabilities; 42810 } 42811 this.distinctiveIdentifier = distinctiveIdentifier; 42812 this.persistentState = persistentState; 42813 this.sessionTypes = sessionTypes; 42814}; 42815 42816exports['default'] = KeySystemConfiguration; 42817module.exports = exports['default']; 42818 42819},{}],167:[function(_dereq_,module,exports){ 42820/** 42821 * The copyright in this software is being made available under the BSD License, 42822 * included below. This software may be subject to other third party and contributor 42823 * rights, including patent rights, and no such rights are granted under this license. 42824 * 42825 * Copyright (c) 2013, Dash Industry Forum. 42826 * All rights reserved. 42827 * 42828 * Redistribution and use in source and binary forms, with or without modification, 42829 * are permitted provided that the following conditions are met: 42830 * * Redistributions of source code must retain the above copyright notice, this 42831 * list of conditions and the following disclaimer. 42832 * * Redistributions in binary form must reproduce the above copyright notice, 42833 * this list of conditions and the following disclaimer in the documentation and/or 42834 * other materials provided with the distribution. 42835 * * Neither the name of Dash Industry Forum nor the names of its 42836 * contributors may be used to endorse or promote products derived from this software 42837 * without specific prior written permission. 42838 * 42839 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42840 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42841 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42842 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42843 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42844 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42845 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42846 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42847 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42848 * POSSIBILITY OF SUCH DAMAGE. 42849 */ 42850/** 42851 * @classdesc A media capability 42852 * @ignore 42853 */ 42854"use strict"; 42855 42856Object.defineProperty(exports, "__esModule", { 42857 value: true 42858}); 42859 42860function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 42861 42862var MediaCapability = 42863/** 42864 * @param {string} contentType MIME type and codecs (RFC6386) 42865 * @param {string} robustness 42866 * @class 42867 * @ignore 42868 */ 42869function MediaCapability(contentType, robustness) { 42870 _classCallCheck(this, MediaCapability); 42871 42872 this.contentType = contentType; 42873 this.robustness = robustness; 42874}; 42875 42876exports["default"] = MediaCapability; 42877module.exports = exports["default"]; 42878 42879},{}],168:[function(_dereq_,module,exports){ 42880/** 42881 * The copyright in this software is being made available under the BSD License, 42882 * included below. This software may be subject to other third party and contributor 42883 * rights, including patent rights, and no such rights are granted under this license. 42884 * 42885 * Copyright (c) 2013, Dash Industry Forum. 42886 * All rights reserved. 42887 * 42888 * Redistribution and use in source and binary forms, with or without modification, 42889 * are permitted provided that the following conditions are met: 42890 * * Redistributions of source code must retain the above copyright notice, this 42891 * list of conditions and the following disclaimer. 42892 * * Redistributions in binary form must reproduce the above copyright notice, 42893 * this list of conditions and the following disclaimer in the documentation and/or 42894 * other materials provided with the distribution. 42895 * * Neither the name of Dash Industry Forum nor the names of its 42896 * contributors may be used to endorse or promote products derived from this software 42897 * without specific prior written permission. 42898 * 42899 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 42900 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 42901 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42902 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 42903 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
42903INCLUDING, BUT 42904 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 42905 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42906 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42907 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42908 * POSSIBILITY OF SUCH DAMAGE. 42909 */ 42910/** 42911 * @classdesc NeedKey 42912 * @ignore 42913 */ 42914"use strict"; 42915 42916Object.defineProperty(exports, "__esModule", { 42917 value: true 42918}); 42919 42920function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 42921 42922var NeedKey = 42923/** 42924 * @param {ArrayBuffer} initData the initialization data 42925 * @param {string} initDataType initialization data type 42926 * @class 42927 */ 42928function NeedKey(initData, initDataType) { 42929 _classCallCheck(this, NeedKey); 42930 42931 this.initData = initData; 42932 this.initDataType = initDataType; 42933}; 42934 42935exports["default"] = NeedKey; 42936module.exports = exports["default"]; 42937 42938},{}],169:[function(_dereq_,module,exports){ 42939'use strict'; 42940 42941Object.defineProperty(exports, '__esModule', { 42942 value: true 42943}); 42944 42945function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 42946 42947var _coreFactoryMakerJs = _dereq_(51); 42948 42949var _coreFactoryMakerJs2 = _interopRequireDefault(_coreFactoryMakerJs); 42950 42951function DroppedFramesHistory() { 42952 42953 var values = []; 42954 var lastDroppedFrames = 0; 42955 var lastTotalFrames = 0; 42956 42957 function push(index, playbackQuality) { 42958 var intervalDroppedFrames = playbackQuality.droppedVideoFrames - lastDroppedFrames; 42959 lastDroppedFrames = playbackQuality.droppedVideoFrames; 42960 42961 var intervalTotalFrames = playbackQuality.totalVideoFrames - lastTotalFrames; 42962 lastTotalFrames = playbackQuality.totalVideoFrames; 42963 42964 if (!isNaN(index)) { 42965 if (!values[index]) { 42966 values[index] = { droppedVideoFrames: intervalDroppedFrames, totalVideoFrames: intervalTotalFrames }; 42967 } else { 42968 values[index].droppedVideoFrames += intervalDroppedFrames; 42969 values[index].totalVideoFrames += intervalTotalFrames; 42970 } 42971 } 42972 } 42973 42974 function getDroppedFrameHistory() { 42975 return values; 42976 } 42977 42978 function reset(playbackQuality) { 42979 values = []; 42980 lastDroppedFrames = playbackQuality.droppedVideoFrames; 42981 lastTotalFrames = playbackQuality.totalVideoFrames; 42982 } 42983 42984 return { 42985 push: push, 42986 getFrameHistory: getDroppedFrameHistory, 42987 reset: reset 42988 }; 42989} 42990 42991DroppedFramesHistory.__dashjs_factory_name = 'DroppedFramesHistory'; 42992var factory = _coreFactoryMakerJs2['default'].getClassFactory(DroppedFramesHistory); 42993exports['default'] = factory; 42994module.exports = exports['default']; 42995 42996},{"51":51}],170:[function(_dereq_,module,exports){ 42997/** 42998 * The copyright in this software is being made available under the BSD License, 42999 * included below. This software may be subject to other third party and contributor 43000 * rights, including patent rights, and no such rights are granted under this license. 43001 * 43002 * Copyright (c) 2013, Dash Industry Forum. 43003 * All rights reserved. 43004 * 43005 * Redistribution and use in source and binary forms, with or without modification, 43006 * are permitted provided that the following conditions are met: 43007 * * Redistributions of source code must retain the above copyright notice, this 43008 * list of conditions and the following disclaimer. 43009 * * Redistributions in binary form must reproduce the above copyright notice, 43010 * this list of conditions and the following disclaimer in the documentation and/or 43011 * other materials provided with the distribution. 43012 * * Neither the name of Dash Industry Forum nor the names of its 43013 * contributors may be used to endorse or promote products derived from this software 43014 * without specific prior written permission. 43015 * 43016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 43017 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 43018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 43019 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 43020 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
43020INCLUDING, BUT 43021 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 43022 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43023 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43024 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43025 * POSSIBILITY OF SUCH DAMAGE. 43026 */ 43027 43028'use strict'; 43029 43030Object.defineProperty(exports, '__esModule', { 43031 value: true 43032}); 43033 43034function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 43035 43036var _coreFactoryMaker = _dereq_(51); 43037 43038var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 43039 43040function RulesContext(config) { 43041 43042 var instance = undefined; 43043 var abrController = config.abrController; 43044 var streamProcessor = config.streamProcessor; 43045 var representationInfo = config.streamProcessor.getCurrentRepresentationInfo(); 43046 var switchHistory = config.switchHistory; 43047 var droppedFramesHistory = config.droppedFramesHistory; 43048 var currentRequest = config.currentRequest; 43049 var bufferOccupancyABR = config.useBufferOccupancyABR; 43050 43051 function getMediaType() { 43052 return representationInfo.mediaInfo.type; 43053 } 43054 43055 function getStreamInfo() { 43056 return representationInfo.mediaInfo.streamInfo; 43057 } 43058 43059 function getMediaInfo() { 43060 return representationInfo.mediaInfo; 43061 } 43062 43063 function getRepresentationInfo() { 43064 return representationInfo; 43065 } 43066 43067 function getStreamProcessor() { 43068 return streamProcessor; 43069 } 43070 43071 function getAbrController() { 43072 return abrController; 43073 } 43074 43075 function getSwitchHistory() { 43076 return switchHistory; 43077 } 43078 43079 function getDroppedFramesHistory() { 43080 return droppedFramesHistory; 43081 } 43082 43083 function getCurrentRequest() { 43084 return currentRequest; 43085 } 43086 43087 function useBufferOccupancyABR() { 43088 return bufferOccupancyABR; 43089 } 43090 43091 instance = { 43092 getMediaType: getMediaType, 43093 getMediaInfo: getMediaInfo, 43094 getDroppedFramesHistory: getDroppedFramesHistory, 43095 getCurrentRequest: getCurrentRequest, 43096 getSwitchHistory: getSwitchHistory, 43097 getStreamInfo: getStreamInfo, 43098 getStreamProcessor: getStreamProcessor, 43099 getAbrController: getAbrController, 43100 getRepresentationInfo: getRepresentationInfo, 43101 useBufferOccupancyABR: useBufferOccupancyABR 43102 }; 43103 43104 return instance; 43105} 43106 43107RulesContext.__dashjs_factory_name = 'RulesContext'; 43108exports['default'] = _coreFactoryMaker2['default'].getClassFactory(RulesContext); 43109module.exports = exports['default']; 43110 43111},{"51":51}],171:[function(_dereq_,module,exports){ 43112/** 43113 * The copyright in this software is being made available under the BSD License, 43114 * included below. This software may be subject to other third party and contributor 43115 * rights, including patent rights, and no such rights are granted under this license. 43116 * 43117 * Copyright (c) 2013, Dash Industry Forum. 43118 * All rights reserved. 43119 * 43120 * Redistribution and use in source and binary forms, with or without modification, 43121 * are permitted provided that the following conditions are met: 43122 * * Redistributions of source code must retain the above copyright notice, this 43123 * list of conditions and the following disclaimer. 43124 * * Redistributions in binary form must reproduce the above copyright notice, 43125 * this list of conditions and the following disclaimer in the documentation and/or 43126 * other materials provided with the distribution. 43127 * * Neither the name of Dash Industry Forum nor the names of its 43128 * contributors may be used to endorse or promote products derived from this software 43129 * without specific prior written permission. 43130 * 43131 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 43132 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 43133 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 43134 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 43135 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
43135INCLUDING, BUT 43136 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 43137 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43138 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43139 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43140 * POSSIBILITY OF SUCH DAMAGE. 43141 */ 43142 43143'use strict'; 43144 43145Object.defineProperty(exports, '__esModule', { 43146 value: true 43147}); 43148 43149function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 43150 43151var _coreFactoryMaker = _dereq_(51); 43152 43153var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 43154 43155var NO_CHANGE = -1; 43156var PRIORITY = { 43157 DEFAULT: 0.5, 43158 STRONG: 1, 43159 WEAK: 0 43160}; 43161 43162function SwitchRequest(q, r, p) { 43163 //TODO refactor all the calls to this to use config to be like everything else. 43164 var instance = undefined; 43165 var quality = undefined; 43166 var priority = undefined; 43167 var reason = undefined; 43168 43169 // check priority value 43170 function getPriority(p) { 43171 var ret = PRIORITY.DEFAULT; 43172 43173 // check that p is one of declared priority value 43174 if (p === PRIORITY.DEFAULT || p === PRIORITY.STRONG || p === PRIORITY.WEAK) { 43175 ret = p; 43176 } 43177 return ret; 43178 } 43179 43180 // init attributes 43181 quality = q === undefined ? NO_CHANGE : q; 43182 priority = getPriority(p); 43183 reason = r === undefined ? null : r; 43184 43185 instance = { 43186 quality: quality, 43187 reason: reason, 43188 priority: priority 43189 }; 43190 43191 return instance; 43192} 43193 43194SwitchRequest.__dashjs_factory_name = 'SwitchRequest'; 43195var factory = _coreFactoryMaker2['default'].getClassFactory(SwitchRequest); 43196factory.NO_CHANGE = NO_CHANGE; 43197factory.PRIORITY = PRIORITY; 43198_coreFactoryMaker2['default'].updateClassFactory(SwitchRequest.__dashjs_factory_name, factory); 43199 43200exports['default'] = factory; 43201module.exports = exports['default']; 43202 43203},{"51":51}],172:[function(_dereq_,module,exports){ 43204/** 43205 * The copyright in this software is being made available under the BSD License, 43206 * included below. This software may be subject to other third party and contributor 43207 * rights, including patent rights, and no such rights are granted under this license. 43208 * 43209 * Copyright (c) 2013, Dash Industry Forum. 43210 * All rights reserved. 43211 * 43212 * Redistribution and use in source and binary forms, with or without modification, 43213 * are permitted provided that the following conditions are met: 43214 * * Redistributions of source code must retain the above copyright notice, this 43215 * list of conditions and the following disclaimer. 43216 * * Redistributions in binary form must reproduce the above copyright notice, 43217 * this list of conditions and the following disclaimer in the documentation and/or 43218 * other materials provided with the distribution. 43219 * * Neither the name of Dash Industry Forum nor the names of its 43220 * contributors may be used to endorse or promote products derived from this software 43221 * without specific prior written permission. 43222 * 43223 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 43224 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 43225 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 43226 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 43227 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 43228 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 43229 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43230 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43231 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43232 * POSSIBILITY OF SUCH DAMAGE. 43233 */ 43234 43235'use strict'; 43236 43237Object.defineProperty(exports, '__esModule', { 43238 value: true 43239}); 43240 43241function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 43242 43243var _coreFactoryMakerJs = _dereq_(51); 43244 43245var _coreFactoryMakerJs2 = _interopRequireDefault(_coreFactoryMakerJs); 43246 43247var _SwitchRequestJs = _dereq_(171); 43248 43249var _SwitchRequestJs2 = _interopRequireDefault(_SwitchRequestJs); 43250 43251var SWITCH_REQUEST_HISTORY_DEPTH = 8; // must be > SwitchHistoryRule SAMPLE_SIZE to enable rule 43252 43253function SwitchRequestHistory() { 43254 var switchRequests = []; // running total 43255 var srHistory = []; // history of each switch 43256 43257 function push(switchRequest) { 43258 if (switchRequest.newValue === _SwitchRequestJs2['default'].NO_CHANGE) { 43259 switchRequest.newValue = switchRequest.oldValue; 43260 } 43261 if (!switchRequests[switchRequest.oldValue]) { 43262 switchRequests[switchRequest.oldValue] = { noDrops: 0, drops: 0, dropSize: 0 }; 43263 } 43264 43265 // Set switch details 43266 var indexDiff = switchRequest.newValue - switchRequest.oldValue; 43267 var drop = indexDiff < 0 ? 1 : 0; 43268 var dropSize = drop ? -indexDiff : 0; 43269 var noDrop = drop ? 0 : 1; 43270 43271 // Update running totals 43272 switchRequests[switchRequest.oldValue].drops += drop; 43273 switchRequests[switchRequest.oldValue].dropSize += dropSize; 43274 switchRequests[switchRequest.oldValue].noDrops += noDrop; 43275 43276 // Save to history 43277 srHistory.push({ idx: switchRequest.oldValue, noDrop: noDrop, drop: drop, dropSize: dropSize }); 43278 43279 // Shift earliest switch off srHistory and readjust to keep depth of running totals constant 43280 if (srHistory.length > SWITCH_REQUEST_HISTORY_DEPTH) { 43281 var srHistoryFirst = srHistory.shift(); 43282 switchRequests[srHistoryFirst.idx].drops -= srHistoryFirst.drop; 43283 switchRequests[srHistoryFirst.idx].dropSize -= srHistoryFirst.dropSize; 43284 switchRequests[srHistoryFirst.idx].noDrops -= srHistoryFirst.noDrop; 43285 } 43286 } 43287 43288 function getSwitchRequests() { 43289 return switchRequests; 43290 } 43291 43292 function reset() { 43293 switchRequests = []; 43294 srHistory = []; 43295 } 43296 43297 return { 43298 push: push, 43299 getSwitchRequests: getSwitchRequests, 43300 reset: reset 43301 }; 43302} 43303 43304SwitchRequestHistory.__dashjs_factory_name = 'SwitchRequestHistory'; 43305var factory = _coreFactoryMakerJs2['default'].getClassFactory(SwitchRequestHistory); 43306exports['default'] = factory; 43307module.exports = exports['default']; 43308 43309},{"171":171,"51":51}],173:[function(_dereq_,module,exports){ 43310/** 43311 * The copyright in this software is being made available under the BSD License, 43312 * included below. This software may be subject to other third party and contributor 43313 * rights, including patent rights, and no such rights are granted under this license. 43314 * 43315 * Copyright (c) 2017, Dash Industry Forum. 43316 * All rights reserved. 43317 * 43318 * Redistribution and use in source and binary forms, with or without modification, 43319 * are permitted provided that the following conditions are met: 43320 * * Redistributions of source code must retain the above copyright notice, this 43321 * list of conditions and the following disclaimer. 43322 * * Redistributions in binary form must reproduce the above copyright notice, 43323 * this list of conditions and the following disclaimer in the documentation and/or 43324 * other materials provided with the distribution. 43325 * * Neither the name of Dash Industry Forum nor the names of its 43326 * contributors may be used to endorse or promote products derived from this software 43327 * without specific prior written permission. 43328 * 43329 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 43330 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 43331 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 43332 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 43333 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
43333INCLUDING, BUT 43334 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 43335 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43336 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43337 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43338 * POSSIBILITY OF SUCH DAMAGE. 43339 */ 43340 43341'use strict'; 43342 43343Object.defineProperty(exports, '__esModule', { 43344 value: true 43345}); 43346 43347function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 43348 43349var _constantsConstants = _dereq_(100); 43350 43351var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 43352 43353var _coreFactoryMakerJs = _dereq_(51); 43354 43355var _coreFactoryMakerJs2 = _interopRequireDefault(_coreFactoryMakerJs); 43356 43357// throughput generally stored in kbit/s 43358// latency generally stored in ms 43359 43360function ThroughputHistory(config) { 43361 43362 // sliding window constants 43363 var MAX_MEASUREMENTS_TO_KEEP = 20; 43364 var AVERAGE_THROUGHPUT_SAMPLE_AMOUNT_LIVE = 3; 43365 var AVERAGE_THROUGHPUT_SAMPLE_AMOUNT_VOD = 4; 43366 var AVERAGE_LATENCY_SAMPLE_AMOUNT = 4; 43367 var THROUGHPUT_DECREASE_SCALE = 1.3; 43368 var THROUGHPUT_INCREASE_SCALE = 1.3; 43369 43370 // EWMA constants 43371 var EWMA_THROUGHPUT_SLOW_HALF_LIFE_SECONDS = 8; 43372 var EWMA_THROUGHPUT_FAST_HALF_LIFE_SECONDS = 3; 43373 var EWMA_LATENCY_SLOW_HALF_LIFE_COUNT = 2; 43374 var EWMA_LATENCY_FAST_HALF_LIFE_COUNT = 1; 43375 43376 var CACHE_LOAD_THRESHOLD_VIDEO = 50; 43377 var CACHE_LOAD_THRESHOLD_AUDIO = 5; 43378 43379 var mediaPlayerModel = config.mediaPlayerModel; 43380 43381 var throughputDict = undefined, 43382 latencyDict = undefined, 43383 ewmaThroughputDict = undefined, 43384 ewmaLatencyDict = undefined, 43385 ewmaHalfLife = undefined; 43386 43387 function setup() { 43388 ewmaHalfLife = { 43389 throughputHalfLife: { fast: EWMA_THROUGHPUT_FAST_HALF_LIFE_SECONDS, slow: EWMA_THROUGHPUT_SLOW_HALF_LIFE_SECONDS }, 43390 latencyHalfLife: { fast: EWMA_LATENCY_FAST_HALF_LIFE_COUNT, slow: EWMA_LATENCY_SLOW_HALF_LIFE_COUNT } 43391 }; 43392 43393 reset(); 43394 } 43395 43396 function isCachedResponse(mediaType, latencyMs, downloadTimeMs) { 43397 if (mediaType === _constantsConstants2['default'].VIDEO) { 43398 return downloadTimeMs < CACHE_LOAD_THRESHOLD_VIDEO; 43399 } else if (mediaType === _constantsConstants2['default'].AUDIO) { 43400 return downloadTimeMs < CACHE_LOAD_THRESHOLD_AUDIO; 43401 } 43402 } 43403 43404 function push(mediaType, httpRequest, useDeadTimeLatency) { 43405 if (!httpRequest.trace || !httpRequest.trace.length) { 43406 return; 43407 } 43408 43409 var latencyTimeInMilliseconds = httpRequest.tresponse.getTime() - httpRequest.trequest.getTime() || 1; 43410 var downloadTimeInMilliseconds = httpRequest._tfinish.getTime() - httpRequest.tresponse.getTime() || 1; //Make sure never 0 we divide by this value. Avoid infinity! 43411 var downloadBytes = httpRequest.trace.reduce(function (a, b) { 43412 return a + b.b[0]; 43413 }, 0); 43414 var throughputMeasureTime = useDeadTimeLatency ? downloadTimeInMilliseconds : latencyTimeInMilliseconds + downloadTimeInMilliseconds; 43415 var throughput = Math.round(8 * downloadBytes / throughputMeasureTime); // bits/ms = kbits/s 43416 43417 checkSettingsForMediaType(mediaType); 43418 43419 if (isCachedResponse(mediaType, latencyTimeInMilliseconds, downloadTimeInMilliseconds)) { 43420 if (throughputDict[mediaType].length > 0 && !throughputDict[mediaType].hasCachedEntries) { 43421 // already have some entries which are not cached entries 43422 // prevent cached fragment loads from skewing the average values 43423 return; 43424 } else { 43425 // have no entries || have cached entries 43426 // no uncached entries yet, rely on cached entries because ABR rules need something to go by 43427 throughputDict[mediaType].hasCachedEntries = true; 43428 } 43429 } else if (throughputDict[mediaType] && throughputDict[mediaType].hasCachedEntries) { 43430 // if we are here then we have some entries already, but they are cached, and now we have a new uncached entry 43431 clearSettingsForMediaType(mediaType); 43432 } 43433 43434 throughputDict[mediaType].push(throughput); 43435 if (throughputDict[mediaType].length > MAX_MEASUREMENTS_TO_KEEP) { 43436 throughputDict[mediaType].shift(); 43437 } 43438 43439 latencyDict[mediaType].push(latencyTimeInMilliseconds); 43440 if (latencyDict[mediaType].length > MAX_MEASUREMENTS_TO_KEEP) { 43441 latencyDict[mediaType].shift(); 43442 } 43443 43444 updateEwmaEstimate(ewmaThroughputDict[mediaType], throughput, 0.001 * downloadTimeInMilliseconds, ewmaHalfLife.throughputHalfLife); 43445 updateEwmaEstimate(ewmaLatencyDict[mediaType], latencyTimeInMilliseconds, 1, ewmaHalfLife.latencyHalfLife); 43446 } 43447 43448 function updateEwmaEstimate(ewmaObj, value, weight, halfLife) { 43449 // Note about startup: 43450 // Estimates start at 0, so early values are underestimated. 43451 // This effect is countered in getAverageEwma() by dividing the estimates by: 43452 // 1 - Math.pow(0.5, ewmaObj.totalWeight / halfLife) 43453 43454 var fastAlpha = Math.pow(0.5, weight / halfLife.fast); 43455 ewmaObj.fastEstimate = (1 - fastAlpha) * value + fastAlpha * ewmaObj.fastEstimate; 43456 43457 var slowAlpha = Math.pow(0.5, weight / halfLife.slow); 43458 ewmaObj.slowEstimate = (1 - slowAlpha) * value + slowAlpha * ewmaObj.slowEstimate; 43459 43460 ewmaObj.totalWeight += weight; 43461 } 43462 43463 function getSampleSize(isThroughput, mediaType, isLive) { 43464 var arr = undefined; 43465 var sampleSize = undefined; 43466 43467 if (isThroughput) { 43468 arr = throughputDict[mediaType]; 43469 sampleSize = isLive ? AVERAGE_THROUGHPUT_SAMPLE_AMOUNT_LIVE : AVERAGE_THROUGHPUT_SAMPLE_AMOUNT_VOD; 43470 } else { 43471 arr = latencyDict[mediaType]; 43472 sampleSize = AVERAGE_LATENCY_SAMPLE_AMOUNT; 43473 } 43474 43475 if (!arr) { 43476 sampleSize = 0; 43477 } else if (sampleSize >= arr.length) { 43478 sampleSize = arr.length; 43479 } else if (isThroughput) { 43480 // if throughput samples vary a lot, average over a wider sample 43481 for (var i = 1; i < sampleSize; ++i) { 43482 var ratio = arr[-i] / arr[-i - 1]; 43483 if (ratio >= THROUGHPUT_INCREASE_SCALE || ratio <= 1 / THROUGHPUT_DECREASE_SCALE) { 43484 sampleSize += 1; 43485 if (sampleSize === arr.length) { 43486 // cannot increase sampleSize beyond arr.length 43487 break; 43488 } 43489 } 43490 } 43491 } 43492 43493 return sampleSize; 43494 } 43495 43496 function getAverage(isThroughput, mediaType, isDynamic) { 43497 // only two moving average methods defined at the moment 43498 return mediaPlayerModel.getMovingAverageMethod() !== _constantsConstants2['default'].MOVING_AVERAGE_SLIDING_WINDOW ? getAverageEwma(isThroughput, mediaType) : getAverageSlidingWindow(isThroughput, mediaType, isDynamic); 43499 } 43500 43501 function getAverageSlidingWindow(isThroughput, mediaType, isDynamic) { 43502 var sampleSize = getSampleSize(isThroughput, mediaType, isDynamic); 43503 var dict = isThroughput ? throughputDict : latencyDict; 43504 var arr = dict[mediaType]; 43505 43506 if (sampleSize === 0 || !arr || arr.length === 0) { 43507 return NaN; 43508 } 43509 43510 arr = arr.slice(-sampleSize); // still works if sampleSize too large 43511 // arr.length >= 1 43512 return arr.reduce(function (total, elem) { 43513 return total + elem; 43514 }) / arr.length; 43515 } 43516 43517 function getAverageEwma(isThroughput, mediaType) { 43518 var halfLife = isThroughput ? ewmaHalfLife.throughputHalfLife : ewmaHalfLife.latencyHalfLife; 43519 var ewmaObj = isThroughput ? ewmaThroughputDict[mediaType] : ewmaLatencyDict[mediaType]; 43520 43521 if (!ewmaObj || ewmaObj.totalWeight <= 0) { 43522 return NaN; 43523 } 43524 43525 // to correct for startup, divide by zero factor = 1 - Math.pow(0.5, ewmaObj.totalWeight / halfLife) 43526 var fastEstimate = ewmaObj.fastEstimate / (1 - Math.pow(0.5, ewmaObj.totalWeight / halfLife.fast)); 43527 var slowEstimate = ewmaObj.slowEstimate / (1 - Math.pow(0.5, ewmaObj.totalWeight / halfLife.slow)); 43528 return isThroughput ? Math.min(fastEstimate, slowEstimate) : Math.max(fastEstimate, slowEstimate); 43529 } 43530 43531 function getAverageThroughput(mediaType, isDynamic) { 43532 return getAverage(true, mediaType, isDynamic); 43533 } 43534 43535 function getSafeAverageThroughput(mediaType, isDynamic) { 43536 var average = getAverageThroughput(mediaType, isDynamic); 43537 if (!isNaN(average)) { 43538 average *= mediaPlayerModel.getBandwidthSafetyFactor(); 43539 } 43540 return average; 43541 } 43542 43543 function getAverageLatency(mediaType) { 43544 return getAverage(false, mediaType); 43545 } 43546 43547 function checkSettingsForMediaType(mediaType) { 43548 throughputDict[mediaType] = throughputDict[mediaType] || []; 43549 latencyDict[mediaType] = latencyDict[mediaType] || []; 43550 ewmaThroughputDict[mediaType] = ewmaThroughputDict[mediaType] || { fastEstimate: 0, slowEstimate: 0, totalWeight: 0 }; 43551 ewmaLatencyDict[mediaType] = ewmaLatencyDict[mediaType] || { fastEstimate: 0, slowEstimate: 0, totalWeight: 0 }; 43552 } 43553 43554 function clearSettingsForMediaType(mediaType) { 43555 delete throughputDict[mediaType]; 43556 delete latencyDict[mediaType]; 43557 delete ewmaThroughputDict[mediaType]; 43558 delete ewmaLatencyDict[mediaType]; 43559 checkSettingsForMediaType(mediaType); 43560 } 43561 43562 function reset() { 43563 throughputDict = {}; 43564 latencyDict = {}; 43565 ewmaThroughputDict = {}; 43566 ewmaLatencyDict = {}; 43567 } 43568 43569 var instance = { 43570 push: push, 43571 getAverageThroughput: getAverageThroughput, 43572 getSafeAverageThroughput: getSafeAverageThroughput, 43573 getAverageLatency: getAverageLatency, 43574 reset: reset 43575 }; 43576 43577 setup(); 43578 return instance; 43579} 43580 43581ThroughputHistory.__dashjs_factory_name = 'ThroughputHistory'; 43582exports['default'] = _coreFactoryMakerJs2['default'].getClassFactory(ThroughputHistory); 43583module.exports = exports['default']; 43584 43585},{"100":100,"51":51}],174:[function(_dereq_,module,exports){ 43586/** 43587 * The copyright in this software is being made available under the BSD License, 43588 * included below. This software may be subject to other third party and contributor 43589 * rights, including patent rights, and no such rights are granted under this license. 43590 * 43591 * Copyright (c) 2013, Dash Industry Forum. 43592 * All rights reserved. 43593 * 43594 * Redistribution and use in source and binary forms, with or without modification, 43595 * are permitted provided that the following conditions are met: 43596 * * Redistributions of source code must retain the above copyright notice, this 43597 * list of conditions and the following disclaimer. 43598 * * Redistributions in binary form must reproduce the above copyright notice, 43599 * this list of conditions and the following disclaimer in the documentation and/or 43600 * other materials provided with the distribution. 43601 * * Neither the name of Dash Industry Forum nor the names of its 43602 * contributors may be used to endorse or promote products derived from this software 43603 * without specific prior written permission. 43604 * 43605 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 43606 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 43607 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 43608 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 43609 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
43609INCLUDING, BUT 43610 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 43611 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43612 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43613 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43614 * POSSIBILITY OF SUCH DAMAGE. 43615 */ 43616'use strict'; 43617 43618Object.defineProperty(exports, '__esModule', { 43619 value: true 43620}); 43621 43622function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 43623 43624var _ThroughputRule = _dereq_(180); 43625 43626var _ThroughputRule2 = _interopRequireDefault(_ThroughputRule); 43627 43628var _InsufficientBufferRule = _dereq_(178); 43629 43630var _InsufficientBufferRule2 = _interopRequireDefault(_InsufficientBufferRule); 43631 43632var _AbandonRequestsRule = _dereq_(175); 43633 43634var _AbandonRequestsRule2 = _interopRequireDefault(_AbandonRequestsRule); 43635 43636var _DroppedFramesRuleJs = _dereq_(177); 43637 43638var _DroppedFramesRuleJs2 = _interopRequireDefault(_DroppedFramesRuleJs); 43639 43640var _SwitchHistoryRuleJs = _dereq_(179); 43641 43642var _SwitchHistoryRuleJs2 = _interopRequireDefault(_SwitchHistoryRuleJs); 43643 43644var _BolaRule = _dereq_(176); 43645 43646var _BolaRule2 = _interopRequireDefault(_BolaRule); 43647 43648var _coreFactoryMaker = _dereq_(51); 43649 43650var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 43651 43652var _SwitchRequestJs = _dereq_(171); 43653 43654var _SwitchRequestJs2 = _interopRequireDefault(_SwitchRequestJs); 43655 43656var QUALITY_SWITCH_RULES = 'qualitySwitchRules'; 43657var ABANDON_FRAGMENT_RULES = 'abandonFragmentRules'; 43658 43659function ABRRulesCollection(config) { 43660 43661 var context = this.context; 43662 43663 var mediaPlayerModel = config.mediaPlayerModel; 43664 var metricsModel = config.metricsModel; 43665 var dashMetrics = config.dashMetrics; 43666 43667 var instance = undefined, 43668 qualitySwitchRules = undefined, 43669 abandonFragmentRules = undefined; 43670 43671 function initialize() { 43672 qualitySwitchRules = []; 43673 abandonFragmentRules = []; 43674 43675 if (mediaPlayerModel.getUseDefaultABRRules()) { 43676 43677 // Only one of BolaRule and ThroughputRule will give a switchRequest.quality !== SwitchRequest.NO_CHANGE. 43678 // This is controlled by useBufferOccupancyABR mechanism in AbrController. 43679 qualitySwitchRules.push((0, _BolaRule2['default'])(context).create({ 43680 metricsModel: metricsModel, 43681 dashMetrics: dashMetrics, 43682 mediaPlayerModel: mediaPlayerModel 43683 })); 43684 qualitySwitchRules.push((0, _ThroughputRule2['default'])(context).create({ 43685 metricsModel: metricsModel, 43686 dashMetrics: dashMetrics 43687 })); 43688 43689 qualitySwitchRules.push((0, _InsufficientBufferRule2['default'])(context).create({ 43690 metricsModel: metricsModel, 43691 dashMetrics: dashMetrics 43692 })); 43693 qualitySwitchRules.push((0, _SwitchHistoryRuleJs2['default'])(context).create()); 43694 qualitySwitchRules.push((0, _DroppedFramesRuleJs2['default'])(context).create()); 43695 43696 abandonFragmentRules.push((0, _AbandonRequestsRule2['default'])(context).create({ 43697 metricsModel: metricsModel, 43698 dashMetrics: dashMetrics, 43699 mediaPlayerModel: mediaPlayerModel 43700 })); 43701 } 43702 43703 // add custom ABR rules if any 43704 var customRules = mediaPlayerModel.getABRCustomRules(); 43705 customRules.forEach(function (rule) { 43706 if (rule.type === QUALITY_SWITCH_RULES) { 43707 qualitySwitchRules.push(rule.rule(context).create()); 43708 } 43709 43710 if (rule.type === ABANDON_FRAGMENT_RULES) { 43711 abandonFragmentRules.push(rule.rule(context).create()); 43712 } 43713 }); 43714 } 43715 43716 function getActiveRules(srArray) { 43717 return srArray.filter(function (sr) { 43718 return sr.quality > _SwitchRequestJs2['default'].NO_CHANGE; 43719 }); 43720 } 43721 43722 function getMinSwitchRequest(srArray) { 43723 43724 var values = {}; 43725 var i = undefined, 43726 len = undefined, 43727 req = undefined, 43728 newQuality = undefined, 43729 quality = undefined; 43730 43731 if (srArray.length === 0) { 43732 return; 43733 } 43734 43735 values[_SwitchRequestJs2['default'].PRIORITY.STRONG] = _SwitchRequestJs2['default'].NO_CHANGE; 43736 values[_SwitchRequestJs2['default'].PRIORITY.WEAK] = _SwitchRequestJs2['default'].NO_CHANGE; 43737 values[_SwitchRequestJs2['default'].PRIORITY.DEFAULT] = _SwitchRequestJs2['default'].NO_CHANGE; 43738 43739 for (i = 0, len = srArray.length; i < len; i += 1) { 43740 req = srArray[i]; 43741 if (req.quality !== _SwitchRequestJs2['default'].NO_CHANGE) { 43742 values[req.priority] = values[req.priority] > _SwitchRequestJs2['default'].NO_CHANGE ? Math.min(values[req.priority], req.quality) : req.quality; 43743 } 43744 } 43745 43746 if (values[_SwitchRequestJs2['default'].PRIORITY.WEAK] !== _SwitchRequestJs2['default'].NO_CHANGE) { 43747 newQuality = values[_SwitchRequestJs2['default'].PRIORITY.WEAK]; 43748 } 43749 43750 if (values[_SwitchRequestJs2['default'].PRIORITY.DEFAULT] !== _SwitchRequestJs2['default'].NO_CHANGE) { 43751 newQuality = values[_SwitchRequestJs2['default'].PRIORITY.DEFAULT]; 43752 } 43753 43754 if (values[_SwitchRequestJs2['default'].PRIORITY.STRONG] !== _SwitchRequestJs2['default'].NO_CHANGE) { 43755 newQuality = values[_SwitchRequestJs2['default'].PRIORITY.STRONG]; 43756 } 43757 43758 if (newQuality !== _SwitchRequestJs2['default'].NO_CHANGE) { 43759 quality = newQuality;
43760 } 43761 43762 return (0, _SwitchRequestJs2['default'])(context).create(quality); 43763 } 43764 43765 function getMaxQuality(rulesContext) { 43766 var switchRequestArray = qualitySwitchRules.map(function (rule) { 43767 return rule.getMaxIndex(rulesContext); 43768 }); 43769 var activeRules = getActiveRules(switchRequestArray); 43770 var maxQuality = getMinSwitchRequest(activeRules); 43771 43772 return maxQuality || (0, _SwitchRequestJs2['default'])(context).create(); 43773 } 43774 43775 function shouldAbandonFragment(rulesContext) { 43776 var abandonRequestArray = abandonFragmentRules.map(function (rule) { 43777 return rule.shouldAbandon(rulesContext); 43778 }); 43779 var activeRules = getActiveRules(abandonRequestArray); 43780 var shouldAbandon = getMinSwitchRequest(activeRules); 43781 43782 return shouldAbandon || (0, _SwitchRequestJs2['default'])(context).create(); 43783 } 43784 43785 function reset() { 43786 [qualitySwitchRules, abandonFragmentRules].forEach(function (rules) { 43787 if (rules && rules.length) {
43788 rules.forEach(function (rule) { 43789 return rule.reset && rule.reset(); 43790 }); 43791 } 43792 }); 43793 qualitySwitchRules = []; 43794 abandonFragmentRules = []; 43795 } 43796 43797 instance = { 43798 initialize: initialize, 43799 reset: reset, 43800 getMaxQuality: getMaxQuality, 43801 shouldAbandonFragment: shouldAbandonFragment 43802 }; 43803 43804 return instance; 43805} 43806 43807ABRRulesCollection.__dashjs_factory_name = 'ABRRulesCollection'; 43808var factory = _coreFactoryMaker2['default'].getClassFactory(ABRRulesCollection); 43809factory.QUALITY_SWITCH_RULES = QUALITY_SWITCH_RULES; 43810factory.ABANDON_FRAGMENT_RULES = ABANDON_FRAGMENT_RULES; 43811_coreFactoryMaker2['default'].updateSingletonFactory(ABRRulesCollection.__dashjs_factory_name, factory); 43812 43813exports['default'] = factory; 43814module.exports = exports['default']; 43815 43816},{"171":171,"175":175,"176":176,"177":177,"178":178,"179":179,"180":180,"51":51}],175:[function(_dereq_,module,exports){ 43817/** 43818 * The copyright in this software is being made available under the BSD License, 43819 * included below. This software may be subject to other third party and contributor 43820 * rights, including patent rights, and no such rights are granted under this license. 43821 * 43822 * Copyright (c) 2013, Dash Industry Forum. 43823 * All rights reserved. 43824 * 43825 * Redistribution and use in source and binary forms, with or without modification, 43826 * are permitted provided that the following conditions are met: 43827 * * Redistributions of source code must retain the above copyright notice, this 43828 * list of conditions and the following disclaimer. 43829 * * Redistributions in binary form must reproduce the above copyright notice, 43830 * this list of conditions and the following disclaimer in the documentation and/or 43831 * other materials provided with the distribution. 43832 * * Neither the name of Dash Industry Forum nor the names of its 43833 * contributors may be used to endorse or promote products derived from this software 43834 * without specific prior written permission. 43835 * 43836 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 43837 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 43838 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 43839 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 43840 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 43841 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 43842 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43843 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43844 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43845 * POSSIBILITY OF SUCH DAMAGE. 43846 */ 43847'use strict'; 43848 43849Object.defineProperty(exports, '__esModule', { 43850 value: true 43851}); 43852 43853function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 43854 43855var _SwitchRequest = _dereq_(171); 43856 43857var _SwitchRequest2 = _interopRequireDefault(_SwitchRequest); 43858 43859var _coreFactoryMaker = _dereq_(51); 43860 43861var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 43862 43863var _coreDebug = _dereq_(49); 43864 43865var _coreDebug2 = _interopRequireDefault(_coreDebug); 43866 43867function AbandonRequestsRule(config) { 43868 43869 var ABANDON_MULTIPLIER = 1.8; 43870 var GRACE_TIME_THRESHOLD = 500; 43871 var MIN_LENGTH_TO_AVERAGE = 5; 43872 43873 var context = this.context; 43874 var log = (0, _coreDebug2['default'])(context).getInstance().log; 43875 43876 var mediaPlayerModel = config.mediaPlayerModel; 43877 var metricsModel = config.metricsModel; 43878 var dashMetrics = config.dashMetrics; 43879 43880 var fragmentDict = undefined, 43881 abandonDict = undefined, 43882 throughputArray = undefined; 43883 43884 function setup() { 43885 reset(); 43886 } 43887 43888 function setFragmentRequestDict(type, id) { 43889 fragmentDict[type] = fragmentDict[type] || {}; 43890 fragmentDict[type][id] = fragmentDict[type][id] || {}; 43891 } 43892 43893 function storeLastRequestThroughputByType(type, throughput) { 43894 throughputArray[type] = throughputArray[type] || []; 43895 throughputArray[type].push(throughput); 43896 } 43897 43898 function shouldAbandon(rulesContext) { 43899 var switchRequest = (0, _SwitchRequest2['default'])(context).create(_SwitchRequest2['default'].NO_CHANGE, { name: AbandonRequestsRule.__dashjs_factory_name }); 43900 43901 if (!rulesContext || !rulesContext.hasOwnProperty('getMediaInfo') || !rulesContext.hasOwnProperty('getMediaType') || !rulesContext.hasOwnProperty('getCurrentRequest') || !rulesContext.hasOwnProperty('getTrackInfo') || !rulesContext.hasOwnProperty('getAbrController')) { 43902 return switchRequest; 43903 } 43904 43905 var mediaInfo = rulesContext.getMediaInfo(); 43906 var mediaType = rulesContext.getMediaType(); 43907 var req = rulesContext.getCurrentRequest(); 43908 43909 if (!isNaN(req.index)) { 43910 43911 setFragmentRequestDict(mediaType, req.index); 43912 43913 var stableBufferTime = mediaPlayerModel.getStableBufferTime(); 43914 var bufferLevel = dashMetrics.getCurrentBufferLevel(metricsModel.getReadOnlyMetricsF
vendor: 5,772 bytes, lines 43914-44019
43914or(mediaType)); 43915 if (bufferLevel > stableBufferTime) { 43916 return switchRequest; 43917 } 43918 43919 var fragmentInfo = fragmentDict[mediaType][req.index]; 43920 if (fragmentInfo === null || req.firstByteDate === null || abandonDict.hasOwnProperty(fragmentInfo.id)) { 43921 return switchRequest; 43922 } 43923 43924 //setup some init info based on first progress event 43925 if (fragmentInfo.firstByteTime === undefined) { 43926 throughputArray[mediaType] = []; 43927 fragmentInfo.firstByteTime = req.firstByteDate.getTime(); 43928 fragmentInfo.segmentDuration = req.duration; 43929 fragmentInfo.bytesTotal = req.bytesTotal; 43930 fragmentInfo.id = req.index; 43931 } 43932 fragmentInfo.bytesLoaded = req.bytesLoaded; 43933 fragmentInfo.elapsedTime = new Date().getTime() - fragmentInfo.firstByteTime; 43934 43935 if (fragmentInfo.bytesLoaded > 0 && fragmentInfo.elapsedTime > 0) { 43936 storeLastRequestThroughputByType(mediaType, Math.round(fragmentInfo.bytesLoaded * 8 / fragmentInfo.elapsedTime)); 43937 } 43938 43939 if (throughputArray[mediaType].length >= MIN_LENGTH_TO_AVERAGE && fragmentInfo.elapsedTime > GRACE_TIME_THRESHOLD && fragmentInfo.bytesLoaded < fragmentInfo.bytesTotal) { 43940 43941 var totalSampledValue = throughputArray[mediaType].reduce(function (a, b) { 43942 return a + b; 43943 }, 0); 43944 fragmentInfo.measuredBandwidthInKbps = Math.round(totalSampledValue / throughputArray[mediaType].length); 43945 fragmentInfo.estimatedTimeOfDownload = +(fragmentInfo.bytesTotal * 8 / fragmentInfo.measuredBandwidthInKbps / 1000).toFixed(2); 43946 //log("id:",fragmentInfo.id, "kbps:", fragmentInfo.measuredBandwidthInKbps, "etd:",fragmentInfo.estimatedTimeOfDownload, fragmentInfo.bytesLoaded); 43947 43948 if (fragmentInfo.estimatedTimeOfDownload < fragmentInfo.segmentDuration * ABANDON_MULTIPLIER || rulesContext.getRepresentationInfo().quality === 0) { 43949 return switchRequest; 43950 } else if (!abandonDict.hasOwnProperty(fragmentInfo.id)) { 43951 43952 var abrController = rulesContext.getAbrController(); 43953 var bytesRemaining = fragmentInfo.bytesTotal - fragmentInfo.bytesLoaded; 43954 var bitrateList = abrController.getBitrateList(mediaInfo); 43955 var newQuality = abrController.getQualityForBitrate(mediaInfo, fragmentInfo.measuredBandwidthInKbps * mediaPlayerModel.getBandwidthSafetyFactor()); 43956 var estimateOtherBytesTotal = fragmentInfo.bytesTotal * bitrateList[newQuality].bitrate / bitrateList[abrController.getQualityFor(mediaType, mediaInfo.streamInfo)].bitrate; 43957 43958 if (bytesRemaining > estimateOtherBytesTotal) { 43959 switchRequest.quality = newQuality; 43960 switchRequest.reason.throughput = fragmentInfo.measuredBandwidthInKbps; 43961 switchRequest.reason.fragmentID = fragmentInfo.id; 43962 abandonDict[fragmentInfo.id] = fragmentInfo; 43963 log('AbandonRequestsRule ( ', mediaType, 'frag id', fragmentInfo.id, ') is asking to abandon and switch to quality to ', newQuality, ' measured bandwidth was', fragmentInfo.measuredBandwidthInKbps); 43964 delete fragmentDict[mediaType][fragmentInfo.id]; 43965 } 43966 } 43967 } else if (fragmentInfo.bytesLoaded === fragmentInfo.bytesTotal) { 43968 delete fragmentDict[mediaType][fragmentInfo.id]; 43969 } 43970 } 43971 43972 return switchRequest; 43973 } 43974 43975 function reset() { 43976 fragmentDict = {}; 43977 abandonDict = {}; 43978 throughputArray = []; 43979 } 43980 43981 var instance = { 43982 shouldAbandon: shouldAbandon, 43983 reset: reset 43984 }; 43985 43986 setup(); 43987 43988 return instance; 43989} 43990 43991AbandonRequestsRule.__dashjs_factory_name = 'AbandonRequestsRule'; 43992exports['default'] = _coreFactoryMaker2['default'].getClassFactory(AbandonRequestsRule); 43993module.exports = exports['default']; 43994 43995},{"171":171,"49":49,"51":51}],176:[function(_dereq_,module,exports){ 43996/** 43997 * The copyright in this software is being made available under the BSD License, 43998 * included below. This software may be subject to other third party and contributor 43999 * rights, including patent rights, and no such rights are granted under this license. 44000 * 44001 * Copyright (c) 2016, Dash Industry Forum. 44002 * All rights reserved. 44003 * 44004 * Redistribution and use in source and binary forms, with or without modification, 44005 * are permitted provided that the following conditions are met: 44006 * * Redistributions of source code must retain the above copyright notice, this 44007 * list of conditions and the following disclaimer. 44008 * * Redistributions in binary form must reproduce the above copyright notice, 44009 * this list of conditions and the following disclaimer in the documentation and/or 44010 * other materials provided with the distribution. 44011 * * Neither the name of Dash Industry Forum nor the names of its 44012 * contributors may be used to endorse or promote products derived from this software 44013 * without specific prior written permission. 44014 * 44015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 44016 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 44017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 44018 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 44019 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
44019INCLUDING, BUT 44020 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 44021 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 44022 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44023 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 44024 * POSSIBILITY OF SUCH DAMAGE. 44025 */ 44026 44027// For a description of the BOLA adaptive bitrate (ABR) algorithm, see http://arxiv.org/abs/1601.06748 44028 44029'use strict'; 44030 44031Object.defineProperty(exports, '__esModule', { 44032 value: true 44033}); 44034 44035function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 44036 44037var _constantsMetricsConstants = _dereq_(101); 44038 44039var _constantsMetricsConstants2 = _interopRequireDefault(_constantsMetricsConstants); 44040 44041var _SwitchRequest = _dereq_(171); 44042 44043var _SwitchRequest2 = _interopRequireDefault(_SwitchRequest); 44044 44045var _coreFactoryMaker = _dereq_(51); 44046 44047var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 44048 44049var _voMetricsHTTPRequest = _dereq_(224); 44050 44051var _coreEventBus = _dereq_(50); 44052 44053var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 44054 44055var _coreEventsEvents = _dereq_(54); 44056 44057var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 44058 44059var _coreDebug = _dereq_(49); 44060 44061var _coreDebug2 = _interopRequireDefault(_coreDebug); 44062 44063// BOLA_STATE_ONE_BITRATE : If there is only one bitrate (or initialization failed), always return NO_CHANGE. 44064// BOLA_STATE_STARTUP : Set placeholder buffer such that we download fragments at most recently measured throughput. 44065// BOLA_STATE_STEADY : Buffer primed, we switch to steady operation. 44066// TODO: add BOLA_STATE_SEEK and tune BOLA behavior on seeking 44067var BOLA_STATE_ONE_BITRATE = 0; 44068var BOLA_STATE_STARTUP = 1; 44069var BOLA_STATE_STEADY = 2; 44070 44071var MINIMUM_BUFFER_S = 10; // BOLA should never add artificial delays if buffer is less than MINIMUM_BUFFER_S. 44072var MINIMUM_BUFFER_PER_BITRATE_LEVEL_S = 2; 44073// E.g. if there are 5 bitrates, BOLA switches to top bitrate at buffer = 10 + 5 * 2 = 20s. 44074// If Schedule Controller does not allow buffer to reach that level, it can be achieved through the placeholder buffer level. 44075 44076var PLACEHOLDER_BUFFER_DECAY = 0.99; // Make sure placeholder buffer does not stick around too long. 44077 44078function BolaRule(config) { 44079 44080 var context = this.context; 44081 var log = (0, _coreDebug2['default'])(context).getInstance().log; 44082 var dashMetrics = config.dashMetrics; 44083 var metricsModel = config.metricsModel; 44084 var mediaPlayerModel = config.mediaPlayerModel; 44085 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 44086 44087 var instance = undefined, 44088 bolaStateDict = undefined; 44089 44090 function setup() { 44091 resetInitialSettings(); 44092 44093 eventBus.on(_coreEventsEvents2['default'].BUFFER_EMPTY, onBufferEmpty, instance); 44094 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, instance); 44095 eventBus.on(_coreEventsEvents2['default'].PERIOD_SWITCH_STARTED, onPeriodSwitchStarted, instance); 44096 eventBus.on(_coreEventsEvents2['default'].MEDIA_FRAGMENT_LOADED, onMediaFragmentLoaded, instance); 44097 eventBus.on(_coreEventsEvents2['default'].METRIC_ADDED, onMetricAdded, instance); 44098 eventBus.on(_coreEventsEvents2['default'].QUALITY_CHANGE_REQUESTED, onQualityChangeRequested, instance); 44099 eventBus.on(_coreEventsEvents2['default'].FRAGMENT_LOADING_ABANDONED, onFragmentLoadingAbandoned, instance); 44100 } 44101 44102 function utilitiesFromBitrates(bitrates) { 44103 return bitrates.map(function (b) { 44104 return Math.log(b); 44105 }); 44106 // no need to worry about offset, utilities will be offset (uniformly) anyway later 44107 } 44108 44109 // NOTE: in live streaming, the real buffer level can drop below minimumBufferS, but bola should not stick to lowest bitrate by using a placeholder buffer level 44110 function calculateBolaParameters(stableBufferTime, bitrates, utilities) { 44111 var highestUtilityIndex = utilities.reduce(function (highestIndex, u, uIndex) { 44112 return u > utilities[highestIndex] ? uIndex : highestIndex; 44113 }, 0); 44114 44115 if (highestUtilityIndex === 0) { 44116 // if highestUtilityIndex === 0, then always use lowest bitrate 44117 return null; 44118 } 44119 44120 var bufferTime = Math.max(stableBufferTime, MINIMUM_BUFFER_S + MINIMUM_BUFFER_PER_BITRATE_LEVEL_S * bitrates.length); 44121 44122 // TODO: Investigate if following can be better if utilities are not the default Math.log utilities. 44123 // If using Math.log utilities, we can choose Vp and gp to always prefer bitrates[0] at minimumBufferS and bitrates[max] at bufferTarget. 44124 // (Vp * (utility + gp) - bufferLevel) / bitrate has the maxima described when: 44125 // Vp * (utilities[0] + gp - 1) === minimumBufferS and Vp * (utilities[max] + gp - 1) === bufferTarget
vendor: 11,827 bytes, lines 44126-44365
44126 // giving: 44127 var gp = (utilities[highestUtilityIndex] - 1) / (bufferTime / MINIMUM_BUFFER_S - 1); 44128 var Vp = MINIMUM_BUFFER_S / gp; 44129 // note that expressions for gp and Vp assume utilities[0] === 1, which is true because of normalization 44130 44131 return { gp: gp, Vp: Vp }; 44132 } 44133 44134 function getInitialBolaState(rulesContext) { 44135 var initialState = {}; 44136 44137 var mediaInfo = rulesContext.getMediaInfo(); 44138 var bitrates = mediaInfo.bitrateList.map(function (b) { 44139 return b.bandwidth; 44140 }); 44141 var utilities = utilitiesFromBitrates(bitrates); 44142 utilities = utilities.map(function (u) { 44143 return u - utilities[0] + 1; 44144 }); // normalize 44145 var stableBufferTime = mediaPlayerModel.getStableBufferTime(); 44146 var params = calculateBolaParameters(stableBufferTime, bitrates, utilities); 44147 44148 if (!params) { 44149 // only happens when there is only one bitrate level 44150 initialState.state = BOLA_STATE_ONE_BITRATE; 44151 } else { 44152 initialState.state = BOLA_STATE_STARTUP; 44153 44154 initialState.bitrates = bitrates; 44155 initialState.utilities = utilities; 44156 initialState.stableBufferTime = stableBufferTime; 44157 initialState.Vp = params.Vp; 44158 initialState.gp = params.gp; 44159 44160 initialState.lastQuality = 0; 44161 clearBolaStateOnSeek(initialState); 44162 } 44163 44164 return initialState; 44165 } 44166 44167 function clearBolaStateOnSeek(bolaState) { 44168 bolaState.placeholderBuffer = 0; 44169 bolaState.mostAdvancedSegmentStart = NaN; 44170 bolaState.lastSegmentWasReplacement = false; 44171 bolaState.lastSegmentStart = NaN; 44172 bolaState.lastSegmentDurationS = NaN; 44173 bolaState.lastSegmentRequestTimeMs = NaN; 44174 bolaState.lastSegmentFinishTimeMs = NaN; 44175 } 44176 44177 // If the buffer target is changed (can this happen mid-stream?), then adjust BOLA parameters accordingly. 44178 function checkBolaStateStableBufferTime(bolaState, mediaType) { 44179 var stableBufferTime = mediaPlayerModel.getStableBufferTime(); 44180 if (bolaState.stableBufferTime !== stableBufferTime) { 44181 var params = calculateBolaParameters(stableBufferTime, bolaState.bitrates, bolaState.utilities); 44182 if (params.Vp !== bolaState.Vp || params.gp !== bolaState.gp) { 44183 // correct placeholder buffer using two criteria: 44184 // 1. do not change effective buffer level at effectiveBufferLevel === MINIMUM_BUFFER_S ( === Vp * gp ) 44185 // 2. scale placeholder buffer by Vp subject to offset indicated in 1. 44186 44187 var bufferLevel = dashMetrics.getCurrentBufferLevel(metricsModel.getReadOnlyMetricsFor(mediaType)); 44188 var effectiveBufferLevel = bufferLevel + bolaState.placeholderBuffer; 44189 44190 effectiveBufferLevel -= MINIMUM_BUFFER_S; 44191 effectiveBufferLevel *= params.Vp / bolaState.Vp; 44192 effectiveBufferLevel += MINIMUM_BUFFER_S; 44193 44194 bolaState.stableBufferTime = stableBufferTime; 44195 bolaState.Vp = params.Vp; 44196 bolaState.gp = params.gp; 44197 bolaState.placeholderBuffer = Math.max(0, effectiveBufferLevel - bufferLevel); 44198 } 44199 } 44200 } 44201 44202 function getBolaState(rulesContext) { 44203 var mediaType = rulesContext.getMediaType(); 44204 var bolaState = bolaStateDict[mediaType]; 44205 if (!bolaState) { 44206 bolaState = getInitialBolaState(rulesContext); 44207 bolaStateDict[mediaType] = bolaState; 44208 } else if (bolaState.state !== BOLA_STATE_ONE_BITRATE) { 44209 checkBolaStateStableBufferTime(bolaState, mediaType); 44210 } 44211 return bolaState; 44212 } 44213 44214 // The core idea of BOLA. 44215 function getQualityFromBufferLevel(bolaState, bufferLevel) { 44216 var bitrateCount = bolaState.bitrates.length; 44217 var quality = NaN; 44218 var score = NaN; 44219 for (var i = 0; i < bitrateCount; ++i) { 44220 var s = (bolaState.Vp * (bolaState.utilities[i] + bolaState.gp) - bufferLevel) / bolaState.bitrates[i]; 44221 if (isNaN(score) || s >= score) { 44222 score = s; 44223 quality = i; 44224 } 44225 } 44226 return quality; 44227 } 44228 44229 // maximum buffer level which prefers to download at quality rather than wait 44230 function maxBufferLevelForQuality(bolaState, quality) { 44231 return bolaState.Vp * (bolaState.utilities[quality] + bolaState.gp); 44232 } 44233 44234 // the minimum buffer level that would cause BOLA to choose quality rather than a lower bitrate 44235 function minBufferLevelForQuality(bolaState, quality) { 44236 var qBitrate = bolaState.bitrates[quality]; 44237 var qUtility = bolaState.utilities[quality]; 44238 44239 var min = 0; 44240 for (var i = quality - 1; i >= 0; --i) { 44241 // for each bitrate less than bitrates[quality], BOLA should prefer quality (unless other bitrate has higher utility) 44242 if (bolaState.utilities[i] < bolaState.utilities[quality]) { 44243 var iBitrate = bolaState.bitrates[i]; 44244 var iUtility = bolaState.utilities[i]; 44245 44246 var level = bolaState.Vp * (bolaState.gp + (qBitrate * iUtility - iBitrate * qUtility) / (qBitrate - iBitrate)); 44247 min = Math.max(min, level); // we want min to be small but at least level(i) for all i 44248 } 44249 } 44250 return min; 44251 } 44252 44253 /* 44254 * The placeholder buffer increases the effective buffer that is used to calculate the bitrate. 44255 * There are two main reasons we might want to increase the placeholder buffer: 44256 * 44257 * 1. When a segment finishes downloading, we would expect to get a call on getMaxIndex() regarding the quality for 44258 * the next segment. However, there might be a delay before the next call. E.g. when streaming live content, the 44259 * next segment might not be available yet. If the call to getMaxIndex() does happens after a delay, we don't 44260 * want the delay to change the BOLA decision - we only want to factor download time to decide on bitrate level. 44261 * 44262 * 2. It is possible to get a call to getMaxIndex() without having a segment download. The buffer target in dash.js 44263 * is different for top-quality segments and lower-quality segments. If getMaxIndex() returns a lower-than-top 44264 * quality, then the buffer controller might decide not to download a segment. When dash.js is ready for the next 44265 * segment, getMaxIndex() will be called again. We don't want this extra delay to factor in the bitrate decision. 44266 */ 44267 function updatePlaceholderBuffer(bolaState, mediaType) { 44268 var nowMs = Date.now(); 44269 44270 if (!isNaN(bolaState.lastSegmentFinishTimeMs)) { 44271 // compensate for non-bandwidth-derived delays, e.g., live streaming availability, buffer controller 44272 var delay = 0.001 * (nowMs - bolaState.lastSegmentFinishTimeMs); 44273 bolaState.placeholderBuffer += Math.max(0, delay); 44274 } else if (!isNaN(bolaState.lastCallTimeMs)) { 44275 // no download after last call, compensate for delay between calls 44276 var delay = 0.001 * (nowMs - bolaState.lastCallTimeMs); 44277 bolaState.placeholderBuffer += Math.max(0, delay); 44278 } 44279 44280 bolaState.lastCallTimeMs = nowMs; 44281 bolaState.lastSegmentStart = NaN; 44282 bolaState.lastSegmentRequestTimeMs = NaN; 44283 bolaState.lastSegmentFinishTimeMs = NaN; 44284 44285 checkBolaStateStableBufferTime(bolaState, mediaType); 44286 } 44287 44288 function onBufferEmpty() { 44289 // if we rebuffer, we don't want the placeholder buffer to artificially raise BOLA quality 44290 for (var mediaType in bolaStateDict) { 44291 if (bolaStateDict.hasOwnProperty(mediaType) && bolaStateDict[mediaType].state === BOLA_STATE_STEADY) { 44292 bolaStateDict[mediaType].placeholderBuffer = 0; 44293 } 44294 } 44295 } 44296 44297 function onPlaybackSeeking() { 44298 // TODO: 1. Verify what happens if we seek mid-fragment. 44299 // TODO: 2. If e.g. we have 10s fragments and seek, we might want to download the first fragment at a lower quality to restart playback quickly. 44300 for (var mediaType in bolaStateDict) { 44301 if (bolaStateDict.hasOwnProperty(mediaType)) { 44302 var bolaState = bolaStateDict[mediaType]; 44303 if (bolaState.state !== BOLA_STATE_ONE_BITRATE) { 44304 bolaState.state = BOLA_STATE_STARTUP; // TODO: BOLA_STATE_SEEK? 44305 clearBolaStateOnSeek(bolaState); 44306 } 44307 } 44308 } 44309 } 44310 44311 function onPeriodSwitchStarted() { 44312 // TODO: does this have to be handled here? 44313 } 44314 44315 function onMediaFragmentLoaded(e) { 44316 if (e && e.chunk && e.chunk.mediaInfo) { 44317 var bolaState = bolaStateDict[e.chunk.mediaInfo.type]; 44318 if (bolaState && bolaState.state !== BOLA_STATE_ONE_BITRATE) { 44319 var start = e.chunk.start; 44320 if (isNaN(bolaState.mostAdvancedSegmentStart) || start > bolaState.mostAdvancedSegmentStart) { 44321 bolaState.mostAdvancedSegmentStart = start; 44322 bolaState.lastSegmentWasReplacement = false; 44323 } else { 44324 bolaState.lastSegmentWasReplacement = true; 44325 } 44326 44327 bolaState.lastSegmentStart = start; 44328 bolaState.lastSegmentDurationS = e.chunk.duration; 44329 bolaState.lastQuality = e.chunk.quality; 44330 44331 checkNewSegment(bolaState, e.chunk.mediaInfo.type); 44332 } 44333 } 44334 } 44335 44336 function onMetricAdded(e) { 44337 if (e && e.metric === _constantsMetricsConstants2['default'].HTTP_REQUEST && e.value && e.value.type === _voMetricsHTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE && e.value.trace && e.value.trace.length) { 44338 var bolaState = bolaStateDict[e.mediaType]; 44339 if (bolaState && bolaState.state !== BOLA_STATE_ONE_BITRATE) { 44340 bolaState.lastSegmentRequestTimeMs = e.value.trequest.getTime(); 44341 bolaState.lastSegmentFinishTimeMs = e.value._tfinish.getTime(); 44342 44343 checkNewSegment(bolaState, e.mediaType); 44344 } 44345 } 44346 } 44347 44348 /* 44349 * When a new segment is downloaded, we get two notifications: onMediaFragmentLoaded() and onMetricAdded(). It is 44350 * possible that the quality for the downloaded segment was lower (not higher) than the quality indicated by BOLA. 44351 * This might happen because of other rules such as the DroppedFramesRule. When this happens, we trim the 44352 * placeholder buffer to make BOLA more stable. This mechanism also avoids inflating the buffer when BOLA itself 44353 * decides not to increase the quality to avoid oscillations. 44354 * 44355 * We should also check for replacement segments (fast switching). In this case, a segment is downloaded but does 44356 * not grow the actual buffer. Fast switching might cause the buffer to deplete, causing BOLA to drop the bitrate. 44357 * We avoid this by growing the placeholder buffer. 44358 */ 44359 function checkNewSegment(bolaState, mediaType) { 44360 if (!isNaN(bolaState.lastSegmentStart) && !isNaN(bolaState.lastSegmentRequestTimeMs) && !isNaN(bolaState.placeholderBuffer)) { 44361 bolaState.placeholderBuffer *= PLACEHOLDER_BUFFER_DECAY; 44362 44363 // Find what maximum buffer corresponding to last segment was, and ensure placeholder is not relatively larger. 44364 if (!isNaN(bolaState.lastSegmentFinishTimeMs)) { 44365 var bufferLevel = dashMetrics.getCurrentBufferLevel(metricsModel.getReadOnlyMetricsF
44365or(mediaType)); 44366 var bufferAtLastSegmentRequest = bufferLevel + 0.001 * (bolaState.lastSegmentFinishTimeMs - bolaState.lastSegmentRequestTimeMs); // estimate 44367 var maxEffectiveBufferForLastSegment = maxBufferLevelForQuality(bolaState, bolaState.lastQuality); 44368 var maxPlaceholderBuffer = Math.max(0, maxEffectiveBufferForLastSegment - bufferAtLastSegmentRequest); 44369 bolaState.placeholderBuffer = Math.min(maxPlaceholderBuffer, bolaState.placeholderBuffer); 44370 } 44371 44372 // then see if we should grow placeholder buffer 44373 44374 if (bolaState.lastSegmentWasReplacement && !isNaN(bolaState.lastSegmentDurationS)) { 44375 // compensate for segments that were downloaded but did not grow the buffer 44376 bolaState.placeholderBuffer += bolaState.lastSegmentDurationS; 44377 } 44378 44379 bolaState.lastSegmentStart = NaN; 44380 bolaState.lastSegmentRequestTimeMs = NaN; 44381 } 44382 } 44383 44384 function onQualityChangeRequested(e) { 44385 // Useful to store change requests when abandoning a download. 44386 if (e) { 44387 var bolaState = bolaStateDict[e.mediaType]; 44388 if (bolaState && bolaState.state !== BOLA_STATE_ONE_BITRATE) { 44389 bolaState.abrQuality = e.newQuality; 44390 } 44391 } 44392 } 44393 44394 function onFragmentLoadingAbandoned(e) { 44395 if (e) { 44396 var bolaState = bolaStateDict[e.mediaType]; 44397 if (bolaState && bolaState.state !== BOLA_STATE_ONE_BITRATE) { 44398 // deflate placeholderBuffer - note that we want to be conservative when abandoning 44399 var bufferLevel = dashMetrics.getCurrentBufferLevel(metricsModel.getReadOnlyMetricsFor(e.mediaType)); 44400 var wantEffectiveBufferLevel = undefined; 44401 if (bolaState.abrQuality > 0) { 44402 // deflate to point where BOLA just chooses newQuality over newQuality-1 44403 wantEffectiveBufferLevel = minBufferLevelForQuality(bolaState, bolaState.abrQuality); 44404 } else { 44405 wantEffectiveBufferLevel = MINIMUM_BUFFER_S; 44406 } 44407 var maxPlaceholderBuffer = Math.max(0, wantEffectiveBufferLevel - bufferLevel); 44408 bolaState.placeholderBuffer = Math.min(bolaState.placeholderBuffer, maxPlaceholderBuffer); 44409 } 44410 } 44411 } 44412 44413 function getMaxIndex(rulesContext) { 44414 var mediaInfo = rulesContext.getMediaInfo(); 44415 var mediaType = rulesContext.getMediaType(); 44416 var metrics = metricsModel.getReadOnlyMetricsFor(mediaType); 44417 var streamProcessor = rulesContext.getStreamProcessor(); 44418 var streamInfo = rulesContext.getStreamInfo(); 44419 var abrController = rulesContext.getAbrController(); 44420 var throughputHistory = abrController.getThroughputHistory(); 44421 var streamId = streamInfo ? streamInfo.id : null; 44422 var isDynamic = streamInfo && streamInfo.manifestInfo && streamInfo.manifestInfo.isDynamic; 44423 var useBufferOccupancyABR = rulesContext.useBufferOccupancyABR(); 44424 var switchRequest = (0, _SwitchRequest2['default'])(context).create(); 44425 switchRequest.reason = switchRequest.reason || {}; 44426 44427 if (!useBufferOccupancyABR) { 44428 return switchRequest; 44429 } 44430 44431 streamProcessor.getScheduleController().setTimeToLoadDelay(0); 44432 44433 var bolaState = getBolaState(rulesContext); 44434 44435 if (bolaState.state === BOLA_STATE_ONE_BITRATE) { 44436 // shouldn't even have been called 44437 log('BOLA ABR rule invoked for media type \'' + mediaType + '\' with only one bitrate.'); 44438 return switchRequest; 44439 } 44440 44441 var bufferLevel = dashMetrics.getCurrentBufferLevel(metrics); 44442 var throughput = throughputHistory.getAverageThroughput(mediaType, isDynamic); 44443 var safeThroughput = throughputHistory.getSafeAverageThroughput(mediaType, isDynamic); 44444 var latency = throughputHistory.getAverageLatency(mediaType); 44445 var quality = undefined; 44446 44447 switchRequest.reason.state = bolaState.state; 44448 switchRequest.reason.throughput = throughput; 44449 switchRequest.reason.latency = latency; 44450 44451 if (isNaN(throughput)) {
vendor: 4,205 bytes, lines 44452-44529
44452 // isNaN(throughput) === isNaN(safeThroughput) === isNaN(latency) 44453 // still starting up - not enough information 44454 return switchRequest; 44455 } 44456 44457 switch (bolaState.state) { 44458 case BOLA_STATE_STARTUP: 44459 quality = abrController.getQualityForBitrate(mediaInfo, safeThroughput, latency); 44460 44461 switchRequest.quality = quality; 44462 switchRequest.reason.throughput = safeThroughput; 44463 44464 bolaState.placeholderBuffer = Math.max(0, minBufferLevelForQuality(bolaState, quality) - bufferLevel); 44465 bolaState.lastQuality = quality; 44466 44467 if (!isNaN(bolaState.lastSegmentDurationS) && bufferLevel >= bolaState.lastSegmentDurationS) { 44468 bolaState.state = BOLA_STATE_STEADY; 44469 } 44470 44471 break; // BOLA_STATE_STARTUP 44472 44473 case BOLA_STATE_STEADY: 44474 44475 // NB: The placeholder buffer is added to bufferLevel to come up with a bitrate. 44476 // This might lead BOLA to be too optimistic and to choose a bitrate that would lead to rebuffering - 44477 // if the real buffer bufferLevel runs out, the placeholder buffer cannot prevent rebuffering. 44478 // However, the InsufficientBufferRule takes care of this scenario. 44479 44480 updatePlaceholderBuffer(bolaState, mediaType); 44481 44482 quality = getQualityFromBufferLevel(bolaState, bufferLevel + bolaState.placeholderBuffer); 44483 44484 // we want to avoid oscillations 44485 // We implement the "BOLA-O" variant: when network bandwidth lies between two encoded bitrate levels, stick to the lowest level. 44486 var qualityForThroughput = abrController.getQualityForBitrate(mediaInfo, safeThroughput, latency); 44487 if (quality > bolaState.lastQuality && quality > qualityForThroughput) { 44488 // only intervene if we are trying to *increase* quality to an *unsustainable* level 44489 // we are only avoid oscillations - do not drop below last quality 44490 44491 quality = Math.max(qualityForThroughput, bolaState.lastQuality); 44492 } 44493 44494 // We do not want to overfill buffer with low quality chunks. 44495 // Note that there will be no delay if buffer level is below MINIMUM_BUFFER_S, probably even with some margin higher than MINIMUM_BUFFER_S. 44496 var delayS = Math.max(0, bufferLevel + bolaState.placeholderBuffer - maxBufferLevelForQuality(bolaState, quality)); 44497 44498 // First reduce placeholder buffer, then tell schedule controller to pause. 44499 if (delayS <= bolaState.placeholderBuffer) { 44500 bolaState.placeholderBuffer -= delayS; 44501 delayS = 0; 44502 } else { 44503 delayS -= bolaState.placeholderBuffer; 44504 bolaState.placeholderBuffer = 0; 44505 44506 if (quality < abrController.getTopQualityIndexFor(mediaType, streamId)) { 44507 // At top quality, allow schedule controller to decide how far to fill buffer. 44508 streamProcessor.getScheduleController().setTimeToLoadDelay(1000 * delayS); 44509 } else { 44510 delayS = 0; 44511 } 44512 } 44513 44514 switchRequest.quality = quality; 44515 switchRequest.reason.throughput = throughput; 44516 switchRequest.reason.latency = latency; 44517 switchRequest.reason.bufferLevel = bufferLevel; 44518 switchRequest.reason.placeholderBuffer = bolaState.placeholderBuffer; 44519 switchRequest.reason.delay = delayS; 44520 44521 bolaState.lastQuality = quality; 44522 // keep bolaState.state === BOLA_STATE_STEADY 44523 44524 break; // BOLA_STATE_STEADY 44525 44526 default: 44527 log('BOLA ABR rule invoked in bad state.'); 44528 // should not arrive here, try to recover 44529 switchRequest.quality = abrController.getQualityForBitrate(mediaInfo, safeThroughput, latency);
44530 switchRequest.reason.state = bolaState.state; 44531 switchRequest.reason.throughput = safeThroughput; 44532 switchRequest.reason.latency = latency; 44533 bolaState.state = BOLA_STATE_STARTUP; 44534 clearBolaStateOnSeek(bolaState); 44535 } 44536 44537 return switchRequest; 44538 } 44539 44540 function resetInitialSettings() { 44541 bolaStateDict = {}; 44542 } 44543 44544 function reset() { 44545 resetInitialSettings(); 44546 44547 eventBus.off(_coreEventsEvents2['default'].BUFFER_EMPTY, onBufferEmpty, instance); 44548 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, instance); 44549 eventBus.off(_coreEventsEvents2['default'].PERIOD_SWITCH_STARTED, onPeriodSwitchStarted, instance); 44550 eventBus.off(_coreEventsEvents2['default'].MEDIA_FRAGMENT_LOADED, onMediaFragmentLoaded, instance); 44551 eventBus.off(_coreEventsEvents2['default'].METRIC_ADDED, onMetricAdded, instance); 44552 eventBus.off(_coreEventsEvents2['default'].QUALITY_CHANGE_REQUESTED, onQualityChangeRequested, instance); 44553 eventBus.off(_coreEventsEvents2['default'].FRAGMENT_LOADING_ABANDONED, onFragmentLoadingAbandoned, instance); 44554 } 44555 44556 instance = { 44557 getMaxIndex: getMaxIndex, 44558 reset: reset 44559 }; 44560 44561 setup(); 44562 return instance; 44563} 44564 44565BolaRule.__dashjs_factory_name = 'BolaRule'; 44566exports['default'] = _coreFactoryMaker2['default'].getClassFactory(BolaRule); 44567module.exports = exports['default']; 44568 44569},{"101":101,"171":171,"224":224,"49":49,"50":50,"51":51,"54":54}],177:[function(_dereq_,module,exports){ 44570'use strict'; 44571 44572Object.defineProperty(exports, '__esModule', { 44573 value: true 44574}); 44575 44576function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 44577 44578var _coreFactoryMakerJs = _dereq_(51); 44579 44580var _coreFactoryMakerJs2 = _interopRequireDefault(_coreFactoryMakerJs); 44581 44582var _SwitchRequestJs = _dereq_(171); 44583 44584var _SwitchRequestJs2 = _interopRequireDefault(_SwitchRequestJs); 44585 44586var _coreDebug = _dereq_(49); 44587 44588var _coreDebug2 = _interopRequireDefault(_coreDebug); 44589 44590function DroppedFramesRule() { 44591 var context = this.context; 44592 var log = (0, _coreDebug2['default'])(context).getInstance().log; 44593 44594 var DROPPED_PERCENTAGE_FORBID = 0.15; 44595 var GOOD_SAMPLE_SIZE = 375; //Don't apply the rule until this many frames have been rendered(and counted under those indices). 44596 44597 function getMaxIndex(rulesContext) { 44598 var droppedFramesHistory = rulesContext.getDroppedFramesHistory(); 44599 if (droppedFramesHistory) { 44600 var dfh = droppedFramesHistory.getFrameHistory(); 44601 var droppedFrames = 0; 44602 var totalFrames = 0; 44603 var maxIndex = _SwitchRequestJs2['default'].NO_CHANGE; 44604 for (var i = 1; i < dfh.length; i++) { 44605 //No point in measuring dropped frames for the zeroeth index. 44606 if (dfh[i]) { 44607 droppedFrames = dfh[i].droppedVideoFrames; 44608 totalFrames = dfh[i].totalVideoFrames; 44609 44610 if (totalFrames > GOOD_SAMPLE_SIZE && droppedFrames / totalFrames > DROPPED_PERCENTAGE_FORBID) { 44611 maxIndex = i - 1; 44612 log('DroppedFramesRule, index: ' + maxIndex + ' Dropped Frames: ' + droppedFrames + ' Total Frames: ' + totalFrames); 44613 break; 44614 } 44615 } 44616 } 44617 return (0, _SwitchRequestJs2['default'])(context).create(maxIndex, { droppedFrames: droppedFrames }); 44618 } 44619 44620 return (0, _SwitchRequestJs2['default'])(context).create(); 44621 } 44622 44623 return { 44624 getMaxIndex: getMaxIndex 44625 }; 44626} 44627 44628DroppedFramesRule.__dashjs_factory_name = 'DroppedFramesRule'; 44629var factory = _coreFactoryMakerJs2['default'].getClassFactory(DroppedFramesRule); 44630 44631exports['default'] = factory; 44632module.exports = exports['default']; 44633 44634},{"171":171,"49":49,"51":51}],178:[function(_dereq_,module,exports){ 44635/** 44636 * The copyright in this software is being made available under the BSD License, 44637 * included below. This software may be subject to other third party and contributor 44638 * rights, including patent rights, and no such rights are granted under this license. 44639 * 44640 * Copyright (c) 2013, Dash Industry Forum. 44641 * All rights reserved. 44642 * 44643 * Redistribution and use in source and binary forms, with or without modification, 44644 * are permitted provided that the following conditions are met: 44645 * * Redistributions of source code must retain the above copyright notice, this 44646 * list of conditions and the following disclaimer. 44647 * * Redistributions in binary form must reproduce the above copyright notice, 44648 * this list of conditions and the following disclaimer in the documentation and/or 44649 * other materials provided with the distribution. 44650 * * Neither the name of Dash Industry Forum nor the names of its 44651 * contributors may be used to endorse or promote products derived from this software 44652 * without specific prior written permission. 44653 * 44654 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 44655 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 44656 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 44657 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 44658 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
44658INCLUDING, BUT 44659 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 44660 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 44661 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44662 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 44663 * POSSIBILITY OF SUCH DAMAGE. 44664 */ 44665'use strict'; 44666 44667Object.defineProperty(exports, '__esModule', { 44668 value: true 44669}); 44670 44671function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 44672 44673var _controllersBufferController = _dereq_(105); 44674 44675var _controllersBufferController2 = _interopRequireDefault(_controllersBufferController); 44676 44677var _coreEventBus = _dereq_(50); 44678 44679var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 44680 44681var _coreEventsEvents = _dereq_(54); 44682 44683var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 44684 44685var _coreFactoryMaker = _dereq_(51); 44686 44687var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 44688 44689var _coreDebug = _dereq_(49); 44690 44691var _coreDebug2 = _interopRequireDefault(_coreDebug); 44692 44693var _SwitchRequestJs = _dereq_(171); 44694 44695var _SwitchRequestJs2 = _interopRequireDefault(_SwitchRequestJs); 44696 44697function InsufficientBufferRule(config) { 44698 44699 var INSUFFICIENT_BUFFER_SAFETY_FACTOR = 0.5; 44700 44701 var context = this.context; 44702 var log = (0, _coreDebug2['default'])(context).getInstance().log; 44703 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 44704 44705 var metricsModel = config.metricsModel; 44706 var dashMetrics = config.dashMetrics; 44707 44708 var instance = undefined, 44709 bufferStateDict = undefined; 44710 44711 function setup() { 44712 resetInitialSettings(); 44713 eventBus.on(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, instance); 44714 } 44715 44716 function checkConfig() { 44717 if (!metricsModel || !metricsModel.hasOwnProperty('getReadOnlyMetricsFor') || !dashMetrics || !dashMetrics.hasOwnProperty('getCurrentBufferLevel')) { 44718 throw new Error('Missing config parameter(s)'); 44719 } 44720 } 44721 /* 44722 * InsufficientBufferRule does not kick in before the first BUFFER_LOADED event happens. This is reset at every seek. 44723 * 44724 * If a BUFFER_EMPTY event happens, then InsufficientBufferRule returns switchRequest.quality=0 until BUFFER_LOADED happens. 44725 * 44726 * Otherwise InsufficientBufferRule gives a maximum bitrate depending on throughput and bufferLevel such that 44727 * a whole fragment can be downloaded before the buffer runs out, subject to a conservative safety factor of 0.5. 44728 * If the bufferLevel is low, then InsufficientBufferRule avoids rebuffering risk. 44729 * If the bufferLevel is high, then InsufficientBufferRule give a high MaxIndex allowing other rules to take over. 44730 */ 44731 function getMaxIndex(rulesContext) { 44732 var switchRequest = (0, _SwitchRequestJs2['default'])(context).create(); 44733 44734 if (!rulesContext || !rulesContext.hasOwnProperty('getMediaType')) { 44735 return switchRequest; 44736 } 44737 44738 checkConfig(); 44739 44740 var mediaType = rulesContext.getMediaType(); 44741 var metrics = metricsModel.getReadOnlyMetricsFor(mediaType); 44742 var lastBufferStateVO = metrics.BufferState.length > 0 ? metrics.BufferState[metrics.BufferState.length - 1] : null; 44743 44744 if (!lastBufferStateVO || !wasFirstBufferLoadedEventTriggered(mediaType, lastBufferStateVO)) { 44745 return switchRequest; 44746 } 44747 44748 if (lastBufferStateVO.state === _controllersBufferController2['default'].BUFFER_EMPTY) { 44749 log('Switch to index 0; buffer is empty.'); 44750 switchRequest.quality = 0; 44751 switchRequest.reason = 'InsufficientBufferRule: Buffer is empty'; 44752 } else { 44753 var mediaInfo = rulesContext.getMediaInfo(); 44754 var abrController = rulesContext.getAbrController(); 44755 var throughputHistory = abrController.getThroughputHistory(); 44756 var representationInfo = rulesContext.getRepresentationInfo(); 44757 var fragmentDuration = representationInfo.fragmentDuration; 44758 44759 var bufferLevel = dashMetrics.getCurrentBufferLevel(metrics); 44760 44761 var throughput = throughputHistory.getAverageThroughput(mediaType); 44762 var latency = throughputHistory.getAverageLatency(mediaType); 44763 44764 var bitrate = throughput * (bufferLevel / fragmentDuration) * INSUFFICIENT_BUFFER_SAFETY_FACTOR; 44765 44766 switchRequest.quality = abrController.getQualityForBitrate(mediaInfo, bitrate, latency);
44767 switchRequest.reason = 'InsufficientBufferRule: being conservative to avoid immediate rebuffering'; 44768 } 44769 44770 return switchRequest; 44771 } 44772 44773 function wasFirstBufferLoadedEventTriggered(mediaType, currentBufferState) { 44774 bufferStateDict[mediaType] = bufferStateDict[mediaType] || {}; 44775 44776 var wasTriggered = false; 44777 if (bufferStateDict[mediaType].firstBufferLoadedEvent) { 44778 wasTriggered = true; 44779 } else if (currentBufferState && currentBufferState.state === _controllersBufferController2['default'].BUFFER_LOADED) { 44780 bufferStateDict[mediaType].firstBufferLoadedEvent = true; 44781 wasTriggered = true; 44782 } 44783 return wasTriggered; 44784 } 44785 44786 function resetInitialSettings() { 44787 bufferStateDict = {}; 44788 } 44789 44790 function onPlaybackSeeking() { 44791 resetInitialSettings(); 44792 } 44793 44794 function reset() { 44795 resetInitialSettings(); 44796 eventBus.off(_coreEventsEvents2['default'].PLAYBACK_SEEKING, onPlaybackSeeking, instance); 44797 } 44798 44799 instance = { 44800 getMaxIndex: getMaxIndex, 44801 reset: reset 44802 }; 44803 44804 setup(); 44805 44806 return instance; 44807} 44808 44809InsufficientBufferRule.__dashjs_factory_name = 'InsufficientBufferRule'; 44810exports['default'] = _coreFactoryMaker2['default'].getClassFactory(InsufficientBufferRule); 44811module.exports = exports['default']; 44812 44813},{"105":105,"171":171,"49":49,"50":50,"51":51,"54":54}],179:[function(_dereq_,module,exports){ 44814'use strict'; 44815 44816Object.defineProperty(exports, '__esModule', { 44817 value: true 44818}); 44819 44820function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 44821 44822var _coreFactoryMakerJs = _dereq_(51); 44823 44824var _coreFactoryMakerJs2 = _interopRequireDefault(_coreFactoryMakerJs); 44825 44826var _coreDebug = _dereq_(49); 44827 44828var _coreDebug2 = _interopRequireDefault(_coreDebug); 44829 44830var _SwitchRequestJs = _dereq_(171); 44831 44832var _SwitchRequestJs2 = _interopRequireDefault(_SwitchRequestJs); 44833 44834function SwitchHistoryRule() { 44835 var context = this.context; 44836 var log = (0, _coreDebug2['default'])(context).getInstance().log; 44837 44838 //MAX_SWITCH is the number of drops made. It doesn't consider the size of the drop. 44839 var MAX_SWITCH = 0.075; 44840 44841 //Before this number of switch requests(no switch or actual), don't apply the rule. 44842 //must be < SwitchRequestHistory SWITCH_REQUEST_HISTORY_DEPTH to enable rule 44843 var SAMPLE_SIZE = 6; 44844 44845 function getMaxIndex(rulesContext) { 44846 var switchRequestHistory = rulesContext ? rulesContext.getSwitchHistory() : null; 44847 var switchRequests = switchRequestHistory ? switchRequestHistory.getSwitchRequests() : []; 44848 var drops = 0; 44849 var noDrops = 0; 44850 var dropSize = 0; 44851 var switchRequest = (0, _SwitchRequestJs2['default'])(context).create(); 44852 44853 for (var i = 0; i < switchRequests.length; i++) { 44854 if (switchRequests[i] !== undefined) { 44855 drops += switchRequests[i].drops; 44856 noDrops += switchRequests[i].noDrops; 44857 dropSize += switchRequests[i].dropSize; 44858 44859 if (drops + noDrops >= SAMPLE_SIZE && drops / noDrops > MAX_SWITCH) { 44860 switchRequest.quality = i > 0 && switchRequests[i].drops > 0 ? i - 1 : i; 44861 switchRequest.reason = { index: switchRequest.quality, drops: drops, noDrops: noDrops, dropSize: dropSize }; 44862 log('Switch history rule index: ' + switchRequest.quality + ' samples: ' + (drops + noDrops) + ' drops: ' + drops); 44863 break; 44864 } 44865 } 44866 } 44867 44868 return switchRequest; 44869 } 44870 44871 return { 44872 getMaxIndex: getMaxIndex 44873 }; 44874} 44875 44876SwitchHistoryRule.__dashjs_factory_name = 'SwitchHistoryRule'; 44877var factory = _coreFactoryMakerJs2['default'].getClassFactory(SwitchHistoryRule); 44878 44879exports['default'] = factory; 44880module.exports = exports['default']; 44881 44882},{"171":171,"49":49,"51":51}],180:[function(_dereq_,module,exports){ 44883/** 44884 * The copyright in this software is being made available under the BSD License, 44885 * included below. This software may be subject to other third party and contributor 44886 * rights, including patent rights, and no such rights are granted under this license. 44887 * 44888 * Copyright (c) 2013, Dash Industry Forum. 44889 * All rights reserved. 44890 * 44891 * Redistribution and use in source and binary forms, with or without modification, 44892 * are permitted provided that the following conditions are met: 44893 * * Redistributions of source code must retain the above copyright notice, this 44894 * list of conditions and the following disclaimer. 44895 * * Redistributions in binary form must reproduce the above copyright notice, 44896 * this list of conditions and the following disclaimer in the documentation and/or 44897 * other materials provided with the distribution. 44898 * * Neither the name of Dash Industry Forum nor the names of its 44899 * contributors may be used to endorse or promote products derived from this software 44900 * without specific prior written permission. 44901 * 44902 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 44903 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 44904 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 44905 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 44906 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
44906INCLUDING, BUT 44907 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 44908 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 44909 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44910 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 44911 * POSSIBILITY OF SUCH DAMAGE. 44912 */ 44913'use strict'; 44914 44915Object.defineProperty(exports, '__esModule', { 44916 value: true 44917}); 44918 44919function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 44920 44921var _controllersBufferController = _dereq_(105); 44922 44923var _controllersBufferController2 = _interopRequireDefault(_controllersBufferController); 44924 44925var _controllersAbrController = _dereq_(102); 44926 44927var _controllersAbrController2 = _interopRequireDefault(_controllersAbrController); 44928 44929var _coreFactoryMaker = _dereq_(51); 44930 44931var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 44932 44933var _coreDebug = _dereq_(49); 44934 44935var _coreDebug2 = _interopRequireDefault(_coreDebug); 44936 44937var _SwitchRequestJs = _dereq_(171); 44938 44939var _SwitchRequestJs2 = _interopRequireDefault(_SwitchRequestJs); 44940 44941function ThroughputRule(config) { 44942 44943 var context = this.context; 44944 var log = (0, _coreDebug2['default'])(context).getInstance().log; 44945 var metricsModel = config.metricsModel; 44946 44947 function checkConfig() { 44948 if (!metricsModel || !metricsModel.hasOwnProperty('getReadOnlyMetricsFor')) { 44949 throw new Error('Missing config parameter(s)'); 44950 } 44951 } 44952 44953 function getMaxIndex(rulesContext) { 44954 var switchRequest = (0, _SwitchRequestJs2['default'])(context).create(); 44955 44956 if (!rulesContext || !rulesContext.hasOwnProperty('getMediaInfo') || !rulesContext.hasOwnProperty('getMediaType') || !rulesContext.hasOwnProperty('useBufferOccupancyABR') || !rulesContext.hasOwnProperty('getAbrController') || !rulesContext.hasOwnProperty('getStreamProcessor')) { 44957 return switchRequest; 44958 } 44959 44960 checkConfig(); 44961 44962 var mediaInfo = rulesContext.getMediaInfo(); 44963 var mediaType = rulesContext.getMediaType(); 44964 var metrics = metricsModel.getReadOnlyMetricsFor(mediaType); 44965 var streamProcessor = rulesContext.getStreamProcessor(); 44966 var abrController = rulesContext.getAbrController(); 44967 var streamInfo = rulesContext.getStreamInfo(); 44968 var isDynamic = streamInfo && streamInfo.manifestInfo ? streamInfo.manifestInfo.isDynamic : null; 44969 var throughputHistory = abrController.getThroughputHistory(); 44970 var throughput = throughputHistory.getSafeAverageThroughput(mediaType, isDynamic); 44971 var latency = throughputHistory.getAverageLatency(mediaType); 44972 var bufferStateVO = metrics.BufferState.length > 0 ? metrics.BufferState[metrics.BufferState.length - 1] : null; 44973 var useBufferOccupancyABR = rulesContext.useBufferOccupancyABR(); 44974 44975 if (!metrics || isNaN(throughput) || !bufferStateVO || useBufferOccupancyABR) { 44976 return switchRequest; 44977 } 44978 44979 if (abrController.getAbandonmentStateFor(mediaType) !== _controllersAbrController2['default'].ABANDON_LOAD) { 44980 44981 if (bufferStateVO.state === _controllersBufferController2['default'].BUFFER_LOADED || isDynamic) { 44982 switchRequest.quality = abrController.getQualityForBitrate(mediaInfo, throughput, latency); 44983 streamProcessor.getScheduleController().setTimeToLoadDelay(0); 44984 log('ThroughputRule requesting switch to index: ', switchRequest.quality, 'type: ', mediaType, 'Average throughput', Math.round(throughput), 'kbps'); 44985 switchRequest.reason = { throughput: throughput, latency: latency }; 44986 } 44987 } 44988 44989 return switchRequest; 44990 } 44991 44992 function reset() { 44993 // no persistent information to reset 44994 } 44995 44996 var instance = { 44997 getMaxIndex: getMaxIndex, 44998 reset: reset 44999 }; 45000 45001 return instance; 45002} 45003 45004ThroughputRule.__dashjs_factory_name = 'ThroughputRule'; 45005exports['default'] = _coreFactoryMaker2['default'].getClassFactory(ThroughputRule); 45006module.exports = exports['default']; 45007 45008},{"102":102,"105":105,"171":171,"49":49,"51":51}],181:[function(_dereq_,module,exports){ 45009/** 45010 * The copyright in this software is being made available under the BSD License, 45011 * included below. This software may be subject to other third party and contributor 45012 * rights, including patent rights, and no such rights are granted under this license. 45013 * 45014 * Copyright (c) 2013, Dash Industry Forum. 45015 * All rights reserved. 45016 * 45017 * Redistribution and use in source and binary forms, with or without modification, 45018 * are permitted provided that the following conditions are met: 45019 * * Redistributions of source code must retain the above copyright notice, this 45020 * list of conditions and the following disclaimer. 45021 * * Redistributions in binary form must reproduce the above copyright notice, 45022 * this list of conditions and the following disclaimer in the documentation and/or 45023 * other materials provided with the distribution. 45024 * * Neither the name of Dash Industry Forum nor the names of its 45025 * contributors may be used to endorse or promote products derived from this software 45026 * without specific prior written permission. 45027 * 45028 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 45029 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 45030 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45031 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 45032 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
45032INCLUDING, BUT 45033 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 45034 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 45035 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45037 * POSSIBILITY OF SUCH DAMAGE. 45038 */ 45039'use strict'; 45040 45041Object.defineProperty(exports, '__esModule', { 45042 value: true 45043}); 45044 45045function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 45046 45047var _constantsConstants = _dereq_(100); 45048 45049var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 45050 45051var _coreFactoryMaker = _dereq_(51); 45052 45053var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 45054 45055function BufferLevelRule(config) { 45056 45057 var dashMetrics = config.dashMetrics; 45058 var metricsModel = config.metricsModel; 45059 var mediaPlayerModel = config.mediaPlayerModel; 45060 var textController = config.textController; 45061 var abrController = config.abrController; 45062 45063 function setup() {} 45064 45065 function execute(streamProcessor, type, videoTrackPresent) { 45066 var bufferLevel = dashMetrics.getCurrentBufferLevel(metricsModel.getReadOnlyMetricsFor(type)); 45067 return bufferLevel < getBufferTarget(streamProcessor, type, videoTrackPresent); 45068 } 45069 45070 function getBufferTarget(streamProcessor, type, videoTrackPresent) { 45071 var bufferTarget = NaN; 45072 var representationInfo = streamProcessor.getCurrentRepresentationInfo(); 45073 if (type === _constantsConstants2['default'].FRAGMENTED_TEXT) { 45074 bufferTarget = textController.getAllTracksAreDisabled() ? 0 : representationInfo.fragmentDuration; 45075 } else if (type === _constantsConstants2['default'].AUDIO && videoTrackPresent) { 45076 var videoBufferLevel = dashMetrics.getCurrentBufferLevel(metricsModel.getReadOnlyMetricsFor(_constantsConstants2['default'].VIDEO)); 45077 if (isNaN(representationInfo.fragmentDuration)) { 45078 bufferTarget = videoBufferLevel; 45079 } else { 45080 bufferTarget = Math.max(videoBufferLevel, representationInfo.fragmentDuration); 45081 } 45082 // console.log('videoBufferLevel - ' + videoBufferLevel + ' target : ' + bufferTarget); 45083 } else { 45084 var streamInfo = representationInfo.mediaInfo.streamInfo; 45085 if (abrController.isPlayingAtTopQuality(streamInfo)) { 45086 var isLongFormContent = streamInfo.manifestInfo.duration >= mediaPlayerModel.getLongFormContentDurationThreshold(); 45087 bufferTarget = isLongFormContent ? mediaPlayerModel.getBufferTimeAtTopQualityLongForm() : mediaPlayerModel.getBufferTimeAtTopQuality(); 45088 } else { 45089 bufferTarget = mediaPlayerModel.getStableBufferTime(); 45090 } 45091 } 45092 45093 return bufferTarget; 45094 } 45095 45096 var instance = { 45097 execute: execute, 45098 getBufferTarget: getBufferTarget 45099 }; 45100 45101 setup(); 45102 return instance; 45103} 45104 45105BufferLevelRule.__dashjs_factory_name = 'BufferLevelRule'; 45106exports['default'] = _coreFactoryMaker2['default'].getClassFactory(BufferLevelRule); 45107module.exports = exports['default']; 45108 45109},{"100":100,"51":51}],182:[function(_dereq_,module,exports){ 45110/** 45111 * The copyright in this software is being made available under the BSD License, 45112 * included below. This software may be subject to other third party and contributor 45113 * rights, including patent rights, and no such rights are granted under this license. 45114 * 45115 * Copyright (c) 2013, Dash Industry Forum. 45116 * All rights reserved. 45117 * 45118 * Redistribution and use in source and binary forms, with or without modification, 45119 * are permitted provided that the following conditions are met: 45120 * * Redistributions of source code must retain the above copyright notice, this 45121 * list of conditions and the following disclaimer. 45122 * * Redistributions in binary form must reproduce the above copyright notice, 45123 * this list of conditions and the following disclaimer in the documentation and/or 45124 * other materials provided with the distribution. 45125 * * Neither the name of Dash Industry Forum nor the names of its 45126 * contributors may be used to endorse or promote products derived from this software 45127 * without specific prior written permission. 45128 * 45129 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 45130 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 45131 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45132 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 45133 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
45133INCLUDING, BUT 45134 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 45135 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 45136 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45137 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45138 * POSSIBILITY OF SUCH DAMAGE. 45139 */ 45140'use strict'; 45141 45142Object.defineProperty(exports, '__esModule', { 45143 value: true 45144}); 45145 45146function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 45147 45148var _constantsConstants = _dereq_(100); 45149 45150var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 45151 45152var _coreDebug = _dereq_(49); 45153 45154var _coreDebug2 = _interopRequireDefault(_coreDebug); 45155 45156var _coreFactoryMaker = _dereq_(51); 45157 45158var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 45159 45160function NextFragmentRequestRule(config) { 45161 45162 var context = this.context; 45163 var log = (0, _coreDebug2['default'])(context).getInstance().log; 45164 var adapter = config.adapter; 45165 var sourceBufferController = config.sourceBufferController; 45166 var textController = config.textController; 45167 45168 function execute(streamProcessor, requestToReplace) { 45169 45170 var representationInfo = streamProcessor.getCurrentRepresentationInfo(); 45171 var mediaInfo = representationInfo.mediaInfo; 45172 var mediaType = mediaInfo.type; 45173 var scheduleController = streamProcessor.getScheduleController(); 45174 var seekTarget = scheduleController.getSeekTarget(); 45175 var hasSeekTarget = !isNaN(seekTarget); 45176 var buffer = streamProcessor.getBuffer(); 45177 45178 var time = hasSeekTarget ? seekTarget : adapter.getIndexHandlerTime(streamProcessor); 45179 45180 if (isNaN(time) || mediaType === _constantsConstants2['default'].FRAGMENTED_TEXT && textController.getAllTracksAreDisabled()) { 45181 return null; 45182 } 45183 45184 if (hasSeekTarget) { 45185 scheduleController.setSeekTarget(NaN); 45186 } 45187 45188 /** 45189 * This is critical for IE/Safari/EDGE 45190 * */ 45191 if (buffer) { 45192 var range = sourceBufferController.getBufferRange(buffer, time); 45193 if (range !== null) { 45194 log('Prior to making a request for time, NextFragmentRequestRule is aligning index handler\'s currentTime with bufferedRange.end.', time, ' was changed to ', range.end); 45195 time = range.end; 45196 } 45197 } 45198 45199 var request = undefined; 45200 if (requestToReplace) { 45201 // log('requestToReplace :' + requestToReplace.url); 45202 time = requestToReplace.startTime + requestToReplace.duration / 2; 45203 request = adapter.getFragmentRequestForTime(streamProcessor, representationInfo, time, { 45204 timeThreshold: 0, 45205 ignoreIsFinished: true 45206 }); 45207 } else { 45208 request = adapter.getFragmentRequestForTime(streamProcessor, representationInfo, time, { 45209 keepIdx: !hasSeekTarget 45210 }); 45211 while (streamProcessor.getFragmentModel().isFragmentLoaded(request)) { 45212 // loop until we found not loaded fragment, or no fragment 45213 request = adapter.getNextFragmentRequest(streamProcessor, representationInfo); 45214 } 45215 if (request) { 45216 adapter.setIndexHandlerTime(streamProcessor, request.startTime + request.duration); 45217 request.delayLoadingTime = new Date().getTime() + scheduleController.getTimeToLoadDelay(); 45218 scheduleController.setTimeToLoadDelay(0); 45219 } 45220 } 45221 45222 /* 45223 if (request) { 45224 log('Return request :' + request.url); 45225 } else { 45226 log('no request'); 45227 }*/ 45228 45229 return request; 45230 } 45231 45232 var instance = { 45233 execute: execute 45234 }; 45235 45236 return instance; 45237} 45238 45239NextFragmentRequestRule.__dashjs_factory_name = 'NextFragmentRequestRule'; 45240exports['default'] = _coreFactoryMaker2['default'].getClassFactory(NextFragmentRequestRule); 45241module.exports = exports['default']; 45242 45243},{"100":100,"49":49,"51":51}],183:[function(_dereq_,module,exports){ 45244/** 45245 * The copyright in this software is being made available under the BSD License, 45246 * included below. This software may be subject to other third party and contributor 45247 * rights, including patent rights, and no such rights are granted under this license. 45248 * 45249 * Copyright (c) 2013, Dash Industry Forum. 45250 * All rights reserved. 45251 * 45252 * Redistribution and use in source and binary forms, with or without modification, 45253 * are permitted provided that the following conditions are met: 45254 * * Redistributions of source code must retain the above copyright notice, this 45255 * list of conditions and the following disclaimer. 45256 * * Redistributions in binary form must reproduce the above copyright notice, 45257 * this list of conditions and the following disclaimer in the documentation and/or 45258 * other materials provided with the distribution. 45259 * * Neither the name of Dash Industry Forum nor the names of its 45260 * contributors may be used to endorse or promote products derived from this software 45261 * without specific prior written permission. 45262 * 45263 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 45264 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 45265 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45266 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 45267 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
vendor: 14,910 bytes, lines 45267-45606
45267INCLUDING, BUT 45268 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 45269 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 45270 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45271 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45272 * POSSIBILITY OF SUCH DAMAGE. 45273 */ 45274'use strict'; 45275 45276Object.defineProperty(exports, '__esModule', { 45277 value: true 45278}); 45279 45280function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 45281 45282var _coreFactoryMaker = _dereq_(51); 45283 45284var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 45285 45286function EmbeddedTextHtmlRender() { 45287 45288 var captionId = 0; 45289 var instance = undefined; 45290 45291 /* HTML Rendering functions */ 45292 function checkIndent(chars) { 45293 var line = ''; 45294 45295 for (var c = 0; c < chars.length; ++c) { 45296 var uc = chars[c]; 45297 line += uc.uchar; 45298 } 45299 45300 var l = line.length; 45301 var ll = line.replace(/^\s+/, '').length; 45302 return l - ll; 45303 } 45304 45305 function getRegionProperties(region) { 45306 return 'left: ' + region.x * 3.125 + '%; top: ' + region.y1 * 6.66 + '%; width: ' + (100 - region.x * 3.125) + '%; height: ' + Math.max(region.y2 - 1 - region.y1, 1) * 6.66 + '%; align-items: flex-start; overflow: visible; -webkit-writing-mode: horizontal-tb;'; 45307 } 45308 45309 function createRGB(color) { 45310 if (color === 'red') { 45311 return 'rgb(255, 0, 0)'; 45312 } else if (color === 'green') { 45313 return 'rgb(0, 255, 0)'; 45314 } else if (color === 'blue') { 45315 return 'rgb(0, 0, 255)'; 45316 } else if (color === 'cyan') { 45317 return 'rgb(0, 255, 255)'; 45318 } else if (color === 'magenta') { 45319 return 'rgb(255, 0, 255)'; 45320 } else if (color === 'yellow') { 45321 return 'rgb(255, 255, 0)'; 45322 } else if (color === 'white') { 45323 return 'rgb(255, 255, 255)'; 45324 } else if (color === 'black') { 45325 return 'rgb(0, 0, 0)'; 45326 } 45327 return color; 45328 } 45329 45330 function getStyle(videoElement, style) { 45331 var fontSize = videoElement.videoHeight / 15.0; 45332 if (style) { 45333 return 'font-size: ' + fontSize + 'px; font-family: Menlo, Consolas, \'Cutive Mono\', monospace; color: ' + (style.foreground ? createRGB(style.foreground) : 'rgb(255, 255, 255)') + '; font-style: ' + (style.italics ? 'italic' : 'normal') + '; text-decoration: ' + (style.underline ? 'underline' : 'none') + '; white-space: pre; background-color: ' + (style.background ? createRGB(style.background) : 'transparent') + ';'; 45334 } else { 45335 return 'font-size: ' + fontSize + 'px; font-family: Menlo, Consolas, \'Cutive Mono\', monospace; justify-content: flex-start; text-align: left; color: rgb(255, 255, 255); font-style: normal; white-space: pre; line-height: normal; font-weight: normal; text-decoration: none; width: 100%; display: flex;'; 45336 } 45337 } 45338 45339 function ltrim(s) { 45340 var trimmed = s.replace(/^\s+/g, ''); 45341 return trimmed; 45342 } 45343 function rtrim(s) { 45344 var trimmed = s.replace(/\s+$/g, ''); 45345 return trimmed; 45346 } 45347 45348 function createHTMLCaptionsFromScreen(videoElement, startTime, endTime, captionScreen) { 45349 45350 var currRegion = null; 45351 var existingRegion = null; 45352 var lastRowHasText = false; 45353 var lastRowIndentL = -1; 45354 var currP = { start: startTime, end: endTime, spans: [] }; 45355 var currentStyle = 'style_cea608_white_black'; 45356 var seenRegions = {}; 45357 var styleStates = {}; 45358 var regions = []; 45359 var r = undefined, 45360 s = undefined; 45361 45362 for (r = 0; r < 15; ++r) { 45363 var row = captionScreen.rows[r]; 45364 var line = ''; 45365 var prevPenState = null; 45366 45367 if (false === row.isEmpty()) { 45368 /* Row is not empty */ 45369 45370 /* Get indentation of this row */ 45371 var rowIndent = checkIndent(row.chars); 45372 45373 /* Create a new region is there is none */ 45374 if (currRegion === null) { 45375 currRegion = { x: rowIndent, y1: r, y2: r + 1, p: [] }; 45376 } 45377 45378 /* Check if indentation has changed and we had text of last row */ 45379 if (rowIndent !== lastRowIndentL && lastRowHasText) { 45380 currRegion.p.push(currP); 45381 currP = { start: startTime, end: endTime, spans: [] }; 45382 currRegion.y2 = r; 45383 currRegion.name = 'region_' + currRegion.x + '_' + currRegion.y1 + '_' + currRegion.y2; 45384 if (false === seenRegions.hasOwnProperty(currRegion.name)) { 45385 regions.push(currRegion); 45386 seenRegions[currRegion.name] = currRegion; 45387 } else { 45388 existingRegion = seenRegions[currRegion.name]; 45389 existingRegion.p.contat(currRegion.p); 45390 } 45391 45392 currRegion = { x: rowIndent, y1: r, y2: r + 1, p: [] }; 45393 } 45394 45395 for (var c = 0; c < row.chars.length; ++c) { 45396 var uc = row.chars[c]; 45397 var currPenState = uc.penState; 45398 if (prevPenState === null || !currPenState.equals(prevPenState)) { 45399 if (line.trim().length > 0) { 45400 currP.spans.push({ name: currentStyle, line: line, row: r }); 45401 line = ''; 45402 } 45403 45404 var currPenStateString = 'style_cea608_' + currPenState.foreground + '_' + currPenState.background; 45405 if (currPenState.underline) { 45406 currPenStateString += '_underline'; 45407 } 45408 if (currPenState.italics) { 45409 currPenStateString += '_italics'; 45410 } 45411 45412 if (!styleStates.hasOwnProperty(currPenStateString)) { 45413 styleStates[currPenStateString] = JSON.parse(JSON.stringify(currPenState)); 45414 } 45415 45416 prevPenState = currPenState; 45417 45418 currentStyle = currPenStateString; 45419 } 45420 45421 line += uc.uchar; 45422 } 45423 45424 if (line.trim().length > 0) { 45425 currP.spans.push({ name: currentStyle, line: line, row: r }); 45426 } 45427 45428 lastRowHasText = true; 45429 lastRowIndentL = rowIndent; 45430 } else { 45431 /* Row is empty */ 45432 lastRowHasText = false; 45433 lastRowIndentL = -1; 45434 45435 if (currRegion) { 45436 currRegion.p.push(currP); 45437 currP = { start: startTime, end: endTime, spans: [] }; 45438 currRegion.y2 = r; 45439 currRegion.name = 'region_' + currRegion.x + '_' + currRegion.y1 + '_' + currRegion.y2; 45440 if (false === seenRegions.hasOwnProperty(currRegion.name)) { 45441 regions.push(currRegion); 45442 seenRegions[currRegion.name] = currRegion; 45443 } else { 45444 existingRegion = seenRegions[currRegion.name]; 45445 existingRegion.p.contat(currRegion.p); 45446 } 45447 45448 currRegion = null; 45449 } 45450 } 45451 } 45452 45453 if (currRegion) { 45454 currRegion.p.push(currP); 45455 currRegion.y2 = r + 1; 45456 currRegion.name = 'region_' + currRegion.x + '_' + currRegion.y1 + '_' + currRegion.y2; 45457 if (false === seenRegions.hasOwnProperty(currRegion.name)) { 45458 regions.push(currRegion); 45459 seenRegions[currRegion.name] = currRegion; 45460 } else { 45461 existingRegion = seenRegions[currRegion.name]; 45462 existingRegion.p.contat(currRegion.p); 45463 } 45464 45465 currRegion = null; 45466 } 45467 45468 //log(styleStates); 45469 //log(regions); 45470 45471 var captionsArray = []; 45472 45473 /* Loop thru regions */ 45474 for (r = 0; r < regions.length; ++r) { 45475 var region = regions[r]; 45476 45477 var cueID = 'sub_cea608_' + captionId++; 45478 var finalDiv = document.createElement('div'); 45479 finalDiv.id = cueID; 45480 var cueRegionProperties = getRegionProperties(region); 45481 finalDiv.style.cssText = 'position: absolute; margin: 0; display: flex; box-sizing: border-box; pointer-events: none;' + cueRegionProperties; 45482 45483 var bodyDiv = document.createElement('div'); 45484 bodyDiv.className = 'paragraph bodyStyle'; 45485 bodyDiv.style.cssText = getStyle(videoElement); 45486 45487 var cueUniWrapper = document.createElement('div'); 45488 cueUniWrapper.className = 'cueUniWrapper'; 45489 cueUniWrapper.style.cssText = 'unicode-bidi: normal; direction: ltr;'; 45490 45491 for (var p = 0; p < region.p.length; ++p) { 45492 var ptag = region.p[p]; 45493 var lastSpanRow = 0; 45494 for (s = 0; s < ptag.spans.length; ++s) { 45495 var span = ptag.spans[s]; 45496 if (span.line.length > 0) { 45497 if (s !== 0 && lastSpanRow != span.row) { 45498 var brElement = document.createElement('br'); 45499 brElement.className = 'lineBreak'; 45500 cueUniWrapper.appendChild(brElement); 45501 } 45502 var sameRow = false; 45503 if (lastSpanRow === span.row) { 45504 sameRow = true; 45505 } 45506 lastSpanRow = span.row; 45507 var spanStyle = styleStates[span.name]; 45508 var spanElement = document.createElement('span'); 45509 spanElement.className = 'spanPadding ' + span.name + ' customSpanColor'; 45510 spanElement.style.cssText = getStyle(videoElement, spanStyle); 45511 /* If this is not the first span, and it's on the same 45512 * row as the last one */ 45513 if (s !== 0 && sameRow) { 45514 /* and it's the last span on this row */ 45515 if (s === ptag.spans.length - 1) { 45516 /* trim only the right side */ 45517 spanElement.textContent = rtrim(span.line); 45518 } else { 45519 /* don't trim at all */ 45520 spanElement.textContent = span.line; 45521 } 45522 } else { 45523 /* if there is more than 1 span and this isn't the last span */ 45524 if (ptag.spans.length > 1 && s < ptag.spans.length - 1) { 45525 /* Check if next text is on same row */ 45526 if (span.row === ptag.spans[s + 1].row) { 45527 /* Next element on same row, trim start */ 45528 spanElement.textContent = ltrim(span.line); 45529 } else { 45530 /* Different rows, trim both */ 45531 spanElement.textContent = span.line.trim(); 45532 } 45533 } else { 45534 spanElement.textContent = span.line.trim(); 45535 } 45536 } 45537 cueUniWrapper.appendChild(spanElement); 45538 } 45539 } 45540 } 45541 45542 bodyDiv.appendChild(cueUniWrapper); 45543 45544 finalDiv.appendChild(bodyDiv); 45545 45546 var fontSize = { 'bodyStyle': ['%', 90] }; 45547 for (s in styleStates) { 45548 if (styleStates.hasOwnProperty(s)) { 45549 fontSize[s] = ['%', 90]; 45550 } 45551 } 45552 45553 captionsArray.push({ type: 'html', 45554 start: startTime, 45555 end: endTime, 45556 cueHTMLElement: finalDiv, 45557 cueID: cueID, 45558 cellResolution: [32, 15], 45559 isFromCEA608: true, 45560 regions: regions, 45561 regionID: region.name, 45562 videoHeight: videoElement.videoHeight, 45563 videoWidth: videoElement.videoWidth, 45564 fontSize: fontSize, 45565 lineHeight: {}, 45566 linePadding: {} 45567 }); 45568 } 45569 return captionsArray; 45570 } 45571 45572 instance = { 45573 createHTMLCaptionsFromScreen: createHTMLCaptionsFromScreen 45574 }; 45575 return instance; 45576} 45577 45578EmbeddedTextHtmlRender.__dashjs_factory_name = 'EmbeddedTextHtmlRender'; 45579exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(EmbeddedTextHtmlRender); 45580module.exports = exports['default']; 45581 45582},{"51":51}],184:[function(_dereq_,module,exports){ 45583/** 45584 * The copyright in this software is being made available under the BSD License, 45585 * included below. This software may be subject to other third party and contributor 45586 * rights, including patent rights, and no such rights are granted under this license. 45587 * 45588 * Copyright (c) 2013, Dash Industry Forum. 45589 * All rights reserved. 45590 * 45591 * Redistribution and use in source and binary forms, with or without modification, 45592 * are permitted provided that the following conditions are met: 45593 * * Redistributions of source code must retain the above copyright notice, this 45594 * list of conditions and the following disclaimer. 45595 * * Redistributions in binary form must reproduce the above copyright notice, 45596 * this list of conditions and the following disclaimer in the documentation and/or 45597 * other materials provided with the distribution. 45598 * * Neither the name of Dash Industry Forum nor the names of its 45599 * contributors may be used to endorse or promote products derived from this software 45600 * without specific prior written permission. 45601 * 45602 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 45603 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 45604 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45605 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 45606 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
45606INCLUDING, BUT 45607 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 45608 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 45609 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45610 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45611 * POSSIBILITY OF SUCH DAMAGE. 45612 */ 45613'use strict'; 45614 45615Object.defineProperty(exports, '__esModule', { 45616 value: true 45617}); 45618 45619function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 45620 45621var _constantsConstants = _dereq_(100); 45622 45623var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 45624 45625var _coreEventBus = _dereq_(50); 45626 45627var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 45628 45629var _coreEventsEvents = _dereq_(54); 45630 45631var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 45632 45633var _coreFactoryMaker = _dereq_(51); 45634 45635var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 45636 45637var _utilsInitCache = _dereq_(196); 45638 45639var _utilsInitCache2 = _interopRequireDefault(_utilsInitCache); 45640 45641var BUFFER_CONTROLLER_TYPE = 'NotFragmentedTextBufferController'; 45642function NotFragmentedTextBufferController(config) { 45643 45644 var context = this.context; 45645 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 45646 45647 var sourceBufferController = config.sourceBufferController; 45648 var errHandler = config.errHandler; 45649 var type = config.type; 45650 var streamProcessor = config.streamProcessor; 45651 45652 var instance = undefined, 45653 isBufferingCompleted = undefined, 45654 initialized = undefined, 45655 mediaSource = undefined, 45656 buffer = undefined, 45657 seekStartTime = undefined, 45658 representationController = undefined, 45659 initCache = undefined; 45660 45661 function setup() { 45662 45663 initialized = false; 45664 mediaSource = null; 45665 buffer = null; 45666 representationController = null; 45667 isBufferingCompleted = false; 45668 45669 eventBus.on(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, this); 45670 eventBus.on(_coreEventsEvents2['default'].INIT_FRAGMENT_LOADED, onInitFragmentLoaded, this); 45671 } 45672 45673 function getBufferControllerType() { 45674 return BUFFER_CONTROLLER_TYPE; 45675 } 45676 45677 function initialize(source) { 45678 setMediaSource(source); 45679 representationController = streamProcessor.getRepresentationController(); 45680 initCache = (0, _utilsInitCache2['default'])(context).getInstance(); 45681 } 45682 45683 /** 45684 * @param {MediaInfo }mediaInfo 45685 * @returns {Object} SourceBuffer object 45686 * @memberof BufferController# 45687 */ 45688 function createBuffer(mediaInfo) { 45689 try { 45690 buffer = sourceBufferController.createSourceBuffer(mediaSource, mediaInfo); 45691 45692 if (!initialized) { 45693 if (buffer.hasOwnProperty(_constantsConstants2['default'].INITIALIZE)) { 45694 buffer.initialize(type, streamProcessor); 45695 } 45696 initialized = true; 45697 } 45698 } catch (e) { 45699 errHandler.mediaSourceError('Error creating ' + type + ' source buffer.'); 45700 } 45701 45702 return buffer; 45703 } 45704 45705 function getType() { 45706 return type; 45707 } 45708 45709 function getBuffer() { 45710 return buffer; 45711 } 45712 45713 function setBuffer(value) { 45714 buffer = value; 45715 } 45716 45717 function setMediaSource(value) { 45718 mediaSource = value; 45719 } 45720 45721 function getMediaSource() { 45722 return mediaSource; 45723 } 45724 45725 function getStreamProcessor() { 45726 return streamProcessor; 45727 } 45728 45729 function setSeekStartTime(value) { 45730 seekStartTime = value; 45731 } 45732 45733 function getSeekStartTime() { 45734 return seekStartTime; 45735 } 45736 45737 function getBufferLevel() { 45738 return 0; 45739 } 45740 45741 function getIsBufferingCompleted() { 45742 return isBufferingCompleted; 45743 } 45744 45745 function reset(errored) { 45746 45747 eventBus.off(_coreEventsEvents2['default'].DATA_UPDATE_COMPLETED, onDataUpdateCompleted, this); 45748 eventBus.off(_coreEventsEvents2['default'].INIT_FRAGMENT_LOADED, onInitFragmentLoaded, this); 45749 45750 if (!errored) { 45751 sourceBufferController.abort(mediaSource, buffer); 45752 sourceBufferController.removeSourceBuffer(mediaSource, buffer); 45753 } 45754 } 45755 45756 function onDataUpdateCompleted(e) { 45757 if (e.sender.getStreamProcessor() !== streamProcessor) { 45758 return; 45759 } 45760 45761 eventBus.trigger(_coreEventsEvents2['default'].TIMED_TEXT_REQUESTED, { 45762 index: 0, 45763 sender: e.sender 45764 }); //TODO make index dynamic if referring to MP? 45765 } 45766 45767 function onInitFragmentLoaded(e) { 45768 if (e.fragmentModel !== streamProcessor.getFragmentModel() || !e.chunk.bytes) { 45769 return; 45770 } 45771 initCache.save(e.chunk); 45772 sourceBufferController.append(buffer, e.chunk); 45773 } 45774 45775 function switchInitData(streamId, representationId) { 45776 var chunk = initCache.extract(streamId, representationId); 45777 if (chunk) { 45778 sourceBufferController.append(buffer, chunk); 45779 } else { 45780 eventBus.trigger(_coreEventsEvents2['default'].INIT_REQUESTED, { 45781 sender: instance 45782 }); 45783 } 45784 } 45785 45786 instance = { 45787 getBufferControllerType: getBufferControllerType, 45788 initialize: initialize, 45789 createBuffer: createBuffer, 45790 getType: getType, 45791 getStreamProcessor: getStreamProcessor, 45792 setSeekStartTime: setSeekStartTime, 45793 getSeekStartTime: getSeekStartTime, 45794 getBuffer: getBuffer, 45795 setBuffer: setBuffer, 45796 getBufferLevel: getBufferLevel, 45797 setMediaSource: setMediaSource, 45798 getMediaSource: getMediaSource, 45799 getIsBufferingCompleted: getIsBufferingCompleted, 45800 switchInitData: switchInitData, 45801 reset: reset 45802 }; 45803 45804 setup(); 45805 45806 return instance; 45807} 45808 45809NotFragmentedTextBufferController.__dashjs_factory_name = BUFFER_CONTROLLER_TYPE; 45810exports['default'] = _coreFactoryMaker2['default'].getClassFactory(NotFragmentedTextBufferController); 45811module.exports = exports['default']; 45812 45813},{"100":100,"196":196,"50":50,"51":51,"54":54}],185:[function(_dereq_,module,exports){ 45814/** 45815 * The copyright in this software is being made available under the BSD License, 45816 * included below. This software may be subject to other third party and contributor 45817 * rights, including patent rights, and no such rights are granted under this license. 45818 * 45819 * Copyright (c) 2013, Dash Industry Forum. 45820 * All rights reserved. 45821 * 45822 * Redistribution and use in source and binary forms, with or without modification, 45823 * are permitted provided that the following conditions are met: 45824 * * Redistributions of source code must retain the above copyright notice, this 45825 * list of conditions and the following disclaimer. 45826 * * Redistributions in binary form must reproduce the above copyright notice, 45827 * this list of conditions and the following disclaimer in the documentation and/or 45828 * other materials provided with the distribution. 45829 * * Neither the name of Dash Industry Forum nor the names of its 45830 * contributors may be used to endorse or promote products derived from this software 45831 * without specific prior written permission. 45832 * 45833 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 45834 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 45835 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45836 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 45837 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
45837INCLUDING, BUT 45838 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 45839 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 45840 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45841 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45842 * POSSIBILITY OF SUCH DAMAGE. 45843 */ 45844'use strict'; 45845 45846Object.defineProperty(exports, '__esModule', { 45847 value: true 45848}); 45849 45850function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 45851 45852var _constantsConstants = _dereq_(100); 45853 45854var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 45855 45856var _coreFactoryMaker = _dereq_(51); 45857 45858var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 45859 45860var _controllersBufferController = _dereq_(105); 45861 45862var _controllersBufferController2 = _interopRequireDefault(_controllersBufferController); 45863 45864var _NotFragmentedTextBufferController = _dereq_(184); 45865 45866var _NotFragmentedTextBufferController2 = _interopRequireDefault(_NotFragmentedTextBufferController); 45867 45868function TextBufferController(config) { 45869 45870 var context = this.context; 45871 45872 var _BufferControllerImpl = undefined; 45873 45874 var instance = undefined; 45875 45876 function setup() { 45877 45878 // according to text type, we create corresponding buffer controller 45879 if (config.type === _constantsConstants2['default'].FRAGMENTED_TEXT) { 45880 45881 // in this case, internal buffer ocntroller is a classical BufferController object 45882 _BufferControllerImpl = (0, _controllersBufferController2['default'])(context).create({ 45883 type: config.type, 45884 metricsModel: config.metricsModel, 45885 mediaPlayerModel: config.mediaPlayerModel, 45886 manifestModel: config.manifestModel, 45887 sourceBufferController: config.sourceBufferController, 45888 errHandler: config.errHandler, 45889 streamController: config.streamController, 45890 mediaController: config.mediaController, 45891 adapter: config.adapter, 45892 textController: config.textController, 45893 abrController: config.abrController, 45894 playbackController: config.playbackController, 45895 streamProcessor: config.streamProcessor 45896 }); 45897 } else { 45898 45899 // in this case, internal buffer controller is a not fragmented text controller object 45900 _BufferControllerImpl = (0, _NotFragmentedTextBufferController2['default'])(context).create({ 45901 type: config.type, 45902 errHandler: config.errHandler, 45903 sourceBufferController: config.sourceBufferController, 45904 streamProcessor: config.streamProcessor 45905 }); 45906 } 45907 } 45908 45909 function getBufferControllerType() { 45910 return _BufferControllerImpl.getBufferControllerType(); 45911 } 45912 45913 function initialize(source, StreamProcessor) { 45914 return _BufferControllerImpl.initialize(source, StreamProcessor); 45915 } 45916 45917 /** 45918 * @param {MediaInfo }mediaInfo 45919 * @returns {Object} SourceBuffer object 45920 * @memberof BufferController# 45921 */ 45922 function createBuffer(mediaInfo) { 45923 return _BufferControllerImpl.createBuffer(mediaInfo); 45924 } 45925 45926 function getType() { 45927 return _BufferControllerImpl.getType(); 45928 } 45929 45930 function getBuffer() { 45931 return _BufferControllerImpl.getBuffer(); 45932 } 45933 45934 function setBuffer(value) { 45935 _BufferControllerImpl.setBuffer(value); 45936 } 45937 45938 function getMediaSource() { 45939 return _BufferControllerImpl.getMediaSource(); 45940 } 45941 45942 function setMediaSource(value) { 45943 _BufferControllerImpl.setMediaSource(value); 45944 } 45945 45946 function getStreamProcessor() { 45947 _BufferControllerImpl.getStreamProcessor(); 45948 } 45949 45950 function setSeekStartTime(value) { 45951 _BufferControllerImpl.setSeekStartTime(value); 45952 } 45953 45954 function getBufferLevel() { 45955 return _BufferControllerImpl.getBufferLevel(); 45956 } 45957 45958 function reset(errored) { 45959 _BufferControllerImpl.reset(errored); 45960 } 45961 45962 function getIsBufferingCompleted() { 45963 return _BufferControllerImpl.getIsBufferingCompleted(); 45964 } 45965 45966 function switchInitData(streamId, representationId) { 45967 _BufferControllerImpl.switchInitData(streamId, representationId); 45968 } 45969 45970 instance = { 45971 getBufferControllerType: getBufferControllerType, 45972 initialize: initialize, 45973 createBuffer: createBuffer, 45974 getType: getType, 45975 getStreamProcessor: getStreamProcessor, 45976 setSeekStartTime: setSeekStartTime, 45977 getBuffer: getBuffer, 45978 setBuffer: setBuffer, 45979 getBufferLevel: getBufferLevel, 45980 setMediaSource: setMediaSource, 45981 getMediaSource: getMediaSource, 45982 getIsBufferingCompleted: getIsBufferingCompleted, 45983 switchInitData: switchInitData, 45984 reset: reset 45985 }; 45986 45987 setup(); 45988 45989 return instance; 45990} 45991 45992TextBufferController.__dashjs_factory_name = 'TextBufferController'; 45993exports['default'] = _coreFactoryMaker2['default'].getClassFactory(TextBufferController); 45994module.exports = exports['default']; 45995 45996},{"100":100,"105":105,"184":184,"51":51}],186:[function(_dereq_,module,exports){ 45997/** 45998 * The copyright in this software is being made available under the BSD License, 45999 * included below. This software may be subject to other third party and contributor 46000 * rights, including patent rights, and no such rights are granted under this license. 46001 * 46002 * Copyright (c) 2013, Dash Industry Forum. 46003 * All rights reserved. 46004 * 46005 * Redistribution and use in source and binary forms, with or without modification, 46006 * are permitted provided that the following conditions are met: 46007 * * Redistributions of source code must retain the above copyright notice, this 46008 * list of conditions and the following disclaimer. 46009 * * Redistributions in binary form must reproduce the above copyright notice, 46010 * this list of conditions and the following disclaimer in the documentation and/or 46011 * other materials provided with the distribution. 46012 * * Neither the name of Dash Industry Forum nor the names of its 46013 * contributors may be used to endorse or promote products derived from this software 46014 * without specific prior written permission. 46015 * 46016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 46017 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 46018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 46019 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 46020 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
46020INCLUDING, BUT 46021 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 46022 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 46023 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46024 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 46025 * POSSIBILITY OF SUCH DAMAGE. 46026 */ 46027'use strict'; 46028 46029Object.defineProperty(exports, '__esModule', { 46030 value: true 46031}); 46032 46033function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 46034 46035var _constantsConstants = _dereq_(100); 46036 46037var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 46038 46039var _coreFactoryMaker = _dereq_(51); 46040 46041var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 46042 46043var _TextSourceBuffer = _dereq_(187); 46044 46045var _TextSourceBuffer2 = _interopRequireDefault(_TextSourceBuffer); 46046 46047var _TextTracks = _dereq_(188); 46048 46049var _TextTracks2 = _interopRequireDefault(_TextTracks); 46050 46051var _utilsVTTParser = _dereq_(203); 46052 46053var _utilsVTTParser2 = _interopRequireDefault(_utilsVTTParser); 46054 46055var _utilsTTMLParser = _dereq_(201); 46056 46057var _utilsTTMLParser2 = _interopRequireDefault(_utilsTTMLParser); 46058 46059function TextController() { 46060 46061 var context = this.context; 46062 var instance = undefined; 46063 var textSourceBuffer = undefined; 46064 46065 var allTracksAreDisabled = undefined, 46066 errHandler = undefined, 46067 dashManifestModel = undefined, 46068 manifestModel = undefined, 46069 mediaController = undefined, 46070 videoModel = undefined, 46071 streamController = undefined, 46072 textTracks = undefined, 46073 vttParser = undefined, 46074 ttmlParser = undefined; 46075 46076 function setup() { 46077 46078 textTracks = (0, _TextTracks2['default'])(context).getInstance(); 46079 vttParser = (0, _utilsVTTParser2['default'])(context).getInstance(); 46080 ttmlParser = (0, _utilsTTMLParser2['default'])(context).getInstance(); 46081 textSourceBuffer = (0, _TextSourceBuffer2['default'])(context).getInstance(); 46082 46083 textTracks.initialize(); 46084 46085 resetInitialSettings(); 46086 } 46087 46088 function setConfig(config) { 46089 if (!config) { 46090 return; 46091 } 46092 if (config.errHandler) { 46093 errHandler = config.errHandler; 46094 } 46095 if (config.dashManifestModel) { 46096 dashManifestModel = config.dashManifestModel; 46097 } 46098 if (config.manifestModel) { 46099 manifestModel = config.manifestModel; 46100 } 46101 if (config.mediaController) { 46102 mediaController = config.mediaController; 46103 } 46104 if (config.videoModel) { 46105 videoModel = config.videoModel; 46106 } 46107 if (config.streamController) { 46108 streamController = config.streamController; 46109 } 46110 if (config.textTracks) { 46111 textTracks = config.textTracks; 46112 } 46113 if (config.vttParser) { 46114 vttParser = config.vttParser; 46115 } 46116 if (config.ttmlParser) { 46117 ttmlParser = config.ttmlParser; 46118 } 46119 46120 // create config for source buffer 46121 textSourceBuffer.setConfig({ 46122 errHandler: errHandler, 46123 dashManifestModel: dashManifestModel, 46124 manifestModel: manifestModel, 46125 mediaController: mediaController, 46126 videoModel: videoModel, 46127 streamController: streamController, 46128 textTracks: textTracks, 46129 vttParser: vttParser, 46130 ttmlParser: ttmlParser 46131 }); 46132 } 46133 46134 function getTextSourceBuffer() { 46135 return textSourceBuffer; 46136 } 46137 46138 function getAllTracksAreDisabled() { 46139 return allTracksAreDisabled; 46140 } 46141 46142 function addEmbeddedTrack(mediaInfo) { 46143 textSourceBuffer.addEmbeddedTrack(mediaInfo); 46144 } 46145 46146 function setTextTrack(idx) { 46147 //For external time text file, the only action needed to change a track is marking the track mode to showing. 46148 // Fragmented text tracks need the additional step of calling TextController.setTextTrack(); 46149 46150 var config = textSourceBuffer.getConfig(); 46151 var fragmentModel = config.fragmentModel; 46152 var fragmentedTracks = config.fragmentedTracks; 46153 46154 var oldTrackIdx = textTracks.getCurrentTrackIdx(); 46155 if (oldTrackIdx !== idx) { 46156 textTracks.setModeForTrackIdx(oldTrackIdx, _constantsConstants2['default'].TEXT_HIDDEN); 46157 textTracks.setCurrentTrackIdx(idx); 46158 textTracks.setModeForTrackIdx(idx, _constantsConstants2['default'].TEXT_SHOWING); 46159 46160 var currentTrackInfo = textTracks.getCurrentTrackInfo(); 46161 46162 if (currentTrackInfo && currentTrackInfo.isFragmented && !currentTrackInfo.isEmbedded) { 46163 for (var i = 0; i < fragmentedTracks.length; i++) { 46164 var mediaInfo = fragmentedTracks[i]; 46165 if (currentTrackInfo.lang === mediaInfo.lang && currentTrackInfo.index === mediaInfo.index && (currentTrackInfo.label ? currentTrackInfo.label === mediaInfo.id : true)) { 46166 var currentFragTrack = mediaController.getCurrentTrackFor(_constantsConstants2['default'].FRAGMENTED_TEXT, streamController.getActiveStreamInfo()); 46167 if (mediaInfo !== currentFragTrack) { 46168 fragmentModel.abortRequests(); 46169 textTracks.deleteCuesFromTrackIdx(oldTrackIdx); 46170 mediaController.setTrack(mediaInfo); 46171 textSourceBuffer.setCurrentFragmentedTrackIdx(i); 46172 } 46173 } 46174 } 46175 } 46176 } 46177 46178 allTracksAreDisabled = idx === -1 ? true : false; 46179 } 46180 46181 function getCurrentTrackIdx() { 46182 var textTracks = textSourceBuffer.getConfig().textTracks; 46183 return textTracks.getCurrentTrackIdx(); 46184 } 46185 46186 function resetInitialSettings() { 46187 allTracksAreDisabled = false; 46188 } 46189 46190 function reset() { 46191 resetInitialSettings();
46192 textSourceBuffer.resetEmbedded(); 46193 } 46194 46195 instance = { 46196 setConfig: setConfig, 46197 getTextSourceBuffer: getTextSourceBuffer, 46198 getAllTracksAreDisabled: getAllTracksAreDisabled, 46199 addEmbeddedTrack: addEmbeddedTrack, 46200 setTextTrack: setTextTrack, 46201 getCurrentTrackIdx: getCurrentTrackIdx, 46202 reset: reset 46203 }; 46204 setup(); 46205 return instance; 46206} 46207 46208TextController.__dashjs_factory_name = 'TextController'; 46209exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(TextController); 46210module.exports = exports['default']; 46211 46212},{"100":100,"187":187,"188":188,"201":201,"203":203,"51":51}],187:[function(_dereq_,module,exports){ 46213/** 46214 * The copyright in this software is being made available under the BSD License, 46215 * included below. This software may be subject to other third party and contributor 46216 * rights, including patent rights, and no such rights are granted under this license. 46217 * 46218 * Copyright (c) 2013, Dash Industry Forum. 46219 * All rights reserved. 46220 * 46221 * Redistribution and use in source and binary forms, with or without modification, 46222 * are permitted provided that the following conditions are met: 46223 * * Redistributions of source code must retain the above copyright notice, this 46224 * list of conditions and the following disclaimer. 46225 * * Redistributions in binary form must reproduce the above copyright notice, 46226 * this list of conditions and the following disclaimer in the documentation and/or 46227 * other materials provided with the distribution. 46228 * * Neither the name of Dash Industry Forum nor the names of its 46229 * contributors may be used to endorse or promote products derived from this software 46230 * without specific prior written permission. 46231 * 46232 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 46233 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 46234 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 46235 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 46236 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46237 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 46238 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 46239 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46240 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 46241 * POSSIBILITY OF SUCH DAMAGE. 46242 */ 46243'use strict'; 46244 46245Object.defineProperty(exports, '__esModule', { 46246 value: true 46247}); 46248 46249function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 46250 46251var _constantsConstants = _dereq_(100); 46252 46253var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 46254 46255var _voMetricsHTTPRequest = _dereq_(224); 46256 46257var _voTextTrackInfo = _dereq_(218); 46258 46259var _voTextTrackInfo2 = _interopRequireDefault(_voTextTrackInfo); 46260 46261var _dashUtilsFragmentedTextBoxParser = _dereq_(74); 46262 46263var _dashUtilsFragmentedTextBoxParser2 = _interopRequireDefault(_dashUtilsFragmentedTextBoxParser); 46264 46265var _utilsBoxParser = _dereq_(190); 46266 46267var _utilsBoxParser2 = _interopRequireDefault(_utilsBoxParser); 46268 46269var _utilsCustomTimeRanges = _dereq_(192); 46270 46271var _utilsCustomTimeRanges2 = _interopRequireDefault(_utilsCustomTimeRanges); 46272 46273var _coreFactoryMaker = _dereq_(51); 46274 46275var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 46276 46277var _coreDebug = _dereq_(49); 46278 46279var _coreDebug2 = _interopRequireDefault(_coreDebug); 46280 46281var _TextTracks = _dereq_(188); 46282 46283var _TextTracks2 = _interopRequireDefault(_TextTracks); 46284 46285var _EmbeddedTextHtmlRender = _dereq_(183); 46286 46287var _EmbeddedTextHtmlRender2 = _interopRequireDefault(_EmbeddedTextHtmlRender); 46288 46289var _codemIsoboxer = _dereq_(11); 46290 46291var _codemIsoboxer2 = _interopRequireDefault(_codemIsoboxer); 46292 46293var _externalsCea608Parser = _dereq_(2); 46294 46295var _externalsCea608Parser2 = _interopRequireDefault(_externalsCea608Parser); 46296 46297var _coreEventBus = _dereq_(50); 46298 46299var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 46300 46301var _coreEventsEvents = _dereq_(54); 46302 46303var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 46304 46305function TextSourceBuffer() { 46306 46307 var context = this.context; 46308 var log = (0, _coreDebug2['default'])(context).getInstance().log; 46309 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 46310 var embeddedInitialized = false; 46311 46312 var instance = undefined, 46313 boxParser = undefined, 46314 errHandler = undefined, 46315 dashManifestModel = undefined, 46316 manifestModel = undefined, 46317 mediaController = undefined, 46318 parser = undefined, 46319 vttParser = undefined, 46320 ttmlParser = undefined, 46321 fragmentedTextBoxParser = undefined, 46322 mediaInfos = undefined, 46323 textTracks = undefined, 46324 isFragmented = undefined, 46325 fragmentModel = undefined, 46326 initializationSegmentReceived = undefined, 46327 timescale = undefined, 46328 fragmentedTracks = undefined, 46329 videoModel = undefined, 46330 streamController = undefined, 46331 firstSubtitleStart = undefined, 46332 currFragmentedTrackIdx = undefined, 46333 embeddedTracks = undefined, 46334 embeddedInitializationSegmentReceived = undefined, 46335 embeddedTimescale = undefined, 46336 embeddedLastSequenceNumber = undefined, 46337 embeddedSequenceNumbers = undefined, 46338 embeddedCea608FieldParsers = undefined, 46339 embeddedTextHtmlRender = undefined; 46340 46341 function initialize(type, streamProcessor) { 46342 parser = null; 46343 fragmentModel = null; 46344 initializationSegmentReceived = false; 46345 timescale = NaN; 46346 fragmentedTracks = []; 46347 firstSubtitleStart = null; 46348 46349 if (!embeddedInitialized) { 46350 initEmbedded(); 46351 } 46352 46353 mediaInfos = streamProcessor.getMediaInfoArr(); 46354 textTracks.setConfig({ 46355 videoModel: videoModel 46356 }); 46357 textTracks.initialize(); 46358 isFragmented = !dashManifestModel.getIsTextTrack(type); 46359 boxParser = (0, _utilsBoxParser2['default'])(context).getInstance(); 46360 fragmentedTextBoxParser = (0, _dashUtilsFragmentedTextBoxParser2['default'])(context).getInstance(); 46361 fragmentedTextBoxParser.setConfig({ 46362 boxParser: boxParser 46363 }); 46364 46365 if (isFragmented) { 46366 fragmentModel = streamProcessor.getFragmentModel(); 46367 this.buffered = (0, _utilsCustomTimeRanges2['default'])(context).create(); 46368 fragmentedTracks = mediaController.getTracksFor(_constantsConstants2['default'].FRAGMENTED_TEXT, streamController.getActiveStreamInfo()); 46369 var currFragTrack = mediaController.getCurrentTrackFor(_constantsConstants2['default'].FRAGMENTED_TEXT, streamController.getActiveStreamInfo()); 46370 for (var i = 0; i < fragmentedTracks.length; i++) { 46371 if (fragmentedTracks[i] === currFragTrack) { 46372 currFragmentedTrackIdx = i; 46373 break; 46374 } 46375 } 46376 } 46377 } 46378 46379 function abort() { 46380 textTracks.deleteAllTextTracks(); 46381 parser = null; 46382 fragmentedTextBoxParser = null; 46383 mediaInfos = null; 46384 textTracks = null; 46385 isFragmented = false; 46386 fragmentModel = null; 46387 initializationSegmentReceived = false; 46388 timescale = NaN; 46389 fragmentedTracks = []; 46390 videoModel = null; 46391 streamController = null; 46392 embeddedInitialized = false; 46393 embeddedTracks = null; 46394 } 46395 46396 function onVideoChunkReceived(e) { 46397 var chunk = e.chunk; 46398 46399 if (chunk.mediaInfo.embeddedCaptions) { 46400 append(chunk.bytes, chunk); 46401 } 46402 } 46403 46404 function initEmbedded() { 46405 embeddedTracks = []; 46406 mediaInfos = []; 46407 textTracks = (0, _TextTracks2['default'])(context).getInstance(); 46408 textTracks.setConfig({ 46409 videoModel: videoModel 46410 }); 46411 textTracks.initialize(); 46412 boxParser = (0, _utilsBoxParser2['default'])(context).getInstance(); 46413 fragmentedTextBoxParser = (0, _dashUtilsFragmentedTextBoxParser2['default'])(context).getInstance(); 46414 fragmentedTextBoxParser.setConfig({ 46415 boxParser: boxParser 46416 }); 46417 isFragmented = false; 46418 currFragmentedTrackIdx = null; 46419 embeddedInitializationSegmentReceived = false; 46420 embeddedTimescale = 0; 46421 embeddedCea608FieldParsers = []; 46422 embeddedSequenceNumbers = []; 46423 embeddedLastSequenceNumber = null; 46424 embeddedInitialized = true; 46425 embeddedTextHtmlRender = (0, _EmbeddedTextHtmlRender2['default'])(context).getInstance(); 46426 46427 eventBus.on(_coreEventsEvents2['default'].VIDEO_CHUNK_RECEIVED, onVideoChunkReceived, this); 46428 } 46429 46430 function resetEmbedded() { 46431 eventBus.off(_coreEventsEvents2['default'].VIDEO_CHUNK_RECEIVED, onVideoChunkReceived, this); 46432 if (textTracks) { 46433 textTracks.deleteAllTextTracks(); 46434 } 46435 embeddedInitialized = false; 46436 embeddedTracks = []; 46437 embeddedCea608FieldParsers = [null, null]; 46438 embeddedSequenceNumbers = []; 46439 embeddedLastSequenceNumber = null; 46440 } 46441 46442 function addEmbeddedTrack(mediaInfo) { 46443 if (!embeddedInitialized) { 46444 initEmbedded(); 46445 } 46446 if (mediaInfo.id === _constantsConstants2['default'].CC1 || mediaInfo.id === _constantsConstants2['default'].CC3) { 46447 embeddedTracks.push(mediaInfo); 46448 } else { 46449 log('Warning: Embedded track ' + mediaInfo.id + ' not supported!'); 46450 } 46451 } 46452 46453 function setConfig(config) { 46454 if (!config) { 46455 return; 46456 } 46457 if (config.errHandler) { 46458 errHandler = config.errHandler; 46459 } 46460 if (config.dashManifestModel) { 46461 dashManifestModel = config.dashManifestModel; 46462 } 46463 if (config.manifestModel) { 46464 manifestModel = config.manifestModel; 46465 } 46466 if (config.mediaController) { 46467 mediaController = config.mediaController; 46468 } 46469 if (config.videoModel) { 46470 videoModel = config.videoModel; 46471 } 46472 if (config.streamController) { 46473 streamController = config.streamController; 46474 } 46475 if (config.textTracks) { 46476 textTracks = config.textTracks; 46477 } 46478 if (config.vttParser) { 46479 vttParser = config.vttParser; 46480 } 46481 if (config.ttmlParser) { 46482 ttmlParser = config.ttmlParser; 46483 } 46484 } 46485 46486 function getConfig() { 46487 var config = { 46488 errHandler: errHandler, 46489 dashManifestModel: dashManifestModel, 46490 mediaController: mediaController, 46491 videoModel: videoModel, 46492 fragmentModel: fragmentModel, 46493 streamController: streamController, 46494 textTracks: textTracks, 46495 isFragmented: isFragmented, 46496 embeddedTracks: embeddedTracks, 46497 fragmentedTracks: fragmentedTracks 46498 }; 46499 46500 return config; 46501 } 46502 46503 function setCurrentFragmentedTrackIdx(idx) { 46504 currFragmentedTrackIdx = idx; 46505 } 46506 46507 function append(bytes, chunk) { 46508 var result = undefined, 46509 sampleList = undefined, 46510 i = undefined, 46511 j = undefined, 46512 k = undefined, 46513 samplesInfo = undefined, 46514 ccContent = undefined; 46515 var mediaInfo = chunk.mediaInfo; 46516 var mediaType = mediaInfo.type; 46517 var mimeType = mediaInfo.mimeType; 46518 var codecType = mediaInfo.codec || mimeType; 46519 if (!codecType) { 46520 log('No text type defined'); 46521 return; 46522 } 46523 46524 function createTextTrackFromMediaInfo(captionData, mediaInfo) { 46525 var textTrackInfo = new _voTextTrackInfo2['default'](); 46526 var trackKindMap = { subtitle: 'subtitles', caption: 'captions' }; //Dash Spec has no "s" on end of KIND but HTML needs plural.
46527 var getKind = function getKind() { 46528 var kind = mediaInfo.roles.length > 0 ? trackKindMap[mediaInfo.roles[0]] : trackKindMap.caption; 46529 kind = kind === trackKindMap.caption || kind === trackKindMap.subtitle ? kind : trackKindMap.caption; 46530 return kind; 46531 }; 46532 46533 var checkTTML = function checkTTML() { 46534 var ttml = false; 46535 if (mediaInfo.codec && mediaInfo.codec.search(_constantsConstants2['default'].STPP) >= 0) { 46536 ttml = true; 46537 } 46538 if (mediaInfo.mimeType && mediaInfo.mimeType.search(_constantsConstants2['default'].TTML) >= 0) { 46539 ttml = true; 46540 } 46541 return ttml; 46542 }; 46543 46544 textTrackInfo.captionData = captionData; 46545 textTrackInfo.lang = mediaInfo.lang; 46546 textTrackInfo.label = mediaInfo.id; // AdaptationSet id (an unsigned int) 46547 textTrackInfo.index = mediaInfo.index; // AdaptationSet index in manifest 46548 textTrackInfo.isTTML = checkTTML(); 46549 textTrackInfo.defaultTrack = getIsDefault(mediaInfo); 46550 textTrackInfo.isFragmented = isFragmented; 46551 textTrackInfo.isEmbedded = mediaInfo.isEmbedded ? true : false; 46552 textTrackInfo.kind = getKind(); 46553 textTrackInfo.roles = mediaInfo.roles; 46554 var totalNrTracks = (mediaInfos ? mediaInfos.length : 0) + embeddedTracks.length; 46555 textTracks.addTextTrack(textTrackInfo, totalNrTracks); 46556 } 46557 46558 if (mediaType === _constantsConstants2['default'].FRAGMENTED_TEXT) { 46559 if (!initializationSegmentReceived) { 46560 initializationSegmentReceived = true; 46561 for (i = 0; i < mediaInfos.length; i++) { 46562 createTextTrackFromMediaInfo(null, mediaInfos[i]); 46563 } 46564 timescale = fragmentedTextBoxParser.getMediaTimescaleFromMoov(bytes); 46565 } else { 46566 samplesInfo = fragmentedTextBoxParser.getSamplesInfo(bytes); 46567 sampleList = samplesInfo.sampleList; 46568 if (!firstSubtitleStart && sampleList.length > 0) { 46569 firstSubtitleStart = sampleList[0].cts - chunk.start * timescale; 46570 } 46571 if (codecType.search(_constantsConstants2['default'].STPP) >= 0) { 46572 parser = parser !== null ? parser : getParser(codecType); 46573 for (i = 0; i < sampleList.length; i++) { 46574 var sample = sampleList[i]; 46575 var sampleStart = sample.cts; 46576 var sampleRelStart = sampleStart - firstSubtitleStart; 46577 this.buffered.add(sampleRelStart / timescale, (sampleRelStart + sample.duration) / timescale); 46578 var dataView = new DataView(bytes, sample.offset, sample.subSizes[0]); 46579 ccContent = _codemIsoboxer2['default'].Utils.dataViewToString(dataView, _constantsConstants2['default'].UTF8); 46580 var images = []; 46581 var subOffset = sample.offset + sample.subSizes[0]; 46582 for (j = 1; j < sample.subSizes.length; j++) { 46583 var inData = new Uint8Array(bytes, subOffset, sample.subSizes[j]); 46584 var raw = String.fromCharCode.apply(null, inData); 46585 images.push(raw); 46586 subOffset += sample.subSizes[j]; 46587 } 46588 try { 46589 // Only used for Miscrosoft Smooth Streaming support - caption time is relative to sample time. In this case, we apply an offset. 46590 var manifest = manifestModel.getValue(); 46591 var offsetTime = manifest.ttmlTimeIsRelative ? sampleStart / timescale : 0; 46592 result = parser.parse(ccContent, offsetTime, sampleStart / timescale, (sampleStart + sample.duration) / timescale, images); 46593 textTracks.addCaptions(currFragmentedTrackIdx, firstSubtitleStart / timescale, result); 46594 } catch (e) { 46595 log('TTML parser error: ' + e.message); 46596 } 46597 } 46598 } else { 46599 // WebVTT case 46600 var captionArray = []; 46601 for (i = 0; i < sampleList.length; i++) { 46602 var sample = sampleList[i]; 46603 sample.cts -= firstSubtitleStart; 46604 this.buffered.add(sample.cts / timescale, (sample.cts + sample.duration) / timescale); 46605 var sampleData = bytes.slice(sample.offset, sample.offset + sample.size); 46606 // There are boxes inside the sampleData, so we need a ISOBoxer to get at it. 46607 var sampleBoxes = _codemIsoboxer2['default'].parseBuffer(sampleData); 46608 46609 for (j = 0; j < sampleBoxes.boxes.length; j++) { 46610 var box1 = sampleBoxes.boxes[j]; 46611 log('VTT box1: ' + box1.type); 46612 if (box1.type === 'vtte') { 46613 continue; //Empty box 46614 } 46615 if (box1.type === 'vttc') { 46616 log('VTT vttc boxes.length = ' + box1.boxes.length); 46617 for (k = 0; k < box1.boxes.length; k++) { 46618 var box2 = box1.boxes[k]; 46619 log('VTT box2: ' + box2.type); 46620 if (box2.type === 'payl') { 46621 var cue_text = box2.cue_text; 46622 log('VTT cue_text = ' + cue_text); 46623 var start_time = sample.cts / timescale; 46624 var end_time = (sample.cts + sample.duration) / timescale; 46625 captionArray.push({ 46626 start: start_time, 46627 end: end_time, 46628 data: cue_text, 46629 styles: {} 46630 }); 46631 log('VTT ' + start_time + '-' + end_time + ' : ' + cue_text); 46632 } 46633 } 46634 } 46635 } 46636 } 46637 if (captionArray.length > 0) { 46638 textTracks.addCaptions(currFragmentedTrackIdx, 0, captionArray);
46639 } 46640 } 46641 } 46642 } else if (mediaType === _constantsConstants2['default'].TEXT) { 46643 var dataView = new DataView(bytes, 0, bytes.byteLength); 46644 ccContent = _codemIsoboxer2['default'].Utils.dataViewToString(dataView, _constantsConstants2['default'].UTF8); 46645 46646 try { 46647 result = getParser(codecType).parse(ccContent, 0); 46648 createTextTrackFromMediaInfo(result, mediaInfo); 46649 } catch (e) { 46650 errHandler.timedTextError(e, 'parse', ccContent); 46651 } 46652 } else if (mediaType === _constantsConstants2['default'].VIDEO) { 46653 //embedded text 46654 if (chunk.segmentType === _voMetricsHTTPRequest.HTTPRequest.INIT_SEGMENT_TYPE) { 46655 if (embeddedTimescale === 0) { 46656 embeddedTimescale = fragmentedTextBoxParser.getMediaTimescaleFromMoov(bytes); 46657 for (i = 0; i < embeddedTracks.length; i++) { 46658 createTextTrackFromMediaInfo(null, embeddedTracks[i]); 46659 } 46660 } 46661 } else { 46662 // MediaSegment 46663 if (embeddedTimescale === 0) { 46664 log('CEA-608: No timescale for embeddedTextTrack yet'); 46665 return; 46666 } 46667 var makeCueAdderForIndex = function makeCueAdderForIndex(self, trackIndex) { 46668 function newCue(startTime, endTime, captionScreen) { 46669 var captionsArray = null; 46670 if (videoModel.getTTMLRenderingDiv()) { 46671 captionsArray = embeddedTextHtmlRender.createHTMLCaptionsFromScreen(videoModel.getElement(), startTime, endTime, captionScreen); 46672 } else { 46673 var text = captionScreen.getDisplayText(); 46674 //log("CEA text: " + startTime + "-" + endTime + " '" + text + "'"); 46675 captionsArray = [{ 46676 start: startTime, 46677 end: endTime, 46678 data: text, 46679 styles: {} 46680 }]; 46681 } 46682 if (captionsArray) { 46683 textTracks.addCaptions(trackIndex, 0, captionsArray); 46684 } 46685 } 46686 return newCue; 46687 }; 46688 46689 samplesInfo = fragmentedTextBoxParser.getSamplesInfo(bytes); 46690 46691 var sequenceNumber = samplesInfo.lastSequenceNumber; 46692 46693 if (!embeddedCea608FieldParsers[0] && !embeddedCea608FieldParsers[1]) { 46694 // Time to setup the CEA-608 parsing 46695 var field = undefined, 46696 handler = undefined, 46697 trackIdx = undefined; 46698 for (i = 0; i < embeddedTracks.length; i++) { 46699 if (embeddedTracks[i].id === _constantsConstants2['default'].CC1) { 46700 field = 0; 46701 trackIdx = textTracks.getTrackIdxForId(_constantsConstants2['default'].CC1); 46702 } else if (embeddedTracks[i].id === _constantsConstants2['default'].CC3) { 46703 field = 1; 46704 trackIdx = textTracks.getTrackIdxForId(_constantsConstants2['default'].CC3); 46705 } 46706 if (trackIdx === -1) { 46707 log('CEA-608: data before track is ready.'); 46708 return; 46709 } 46710 handler = makeCueAdderForIndex(this, trackIdx); 46711 embeddedCea608FieldParsers[i] = new _externalsCea608Parser2['default'].Cea608Parser(i, { 46712 'newCue': handler 46713 }, null); 46714 } 46715 } 46716 46717 if (embeddedTimescale && embeddedSequenceNumbers.indexOf(sequenceNumber) == -1) { 46718 if (embeddedLastSequenceNumber !== null && sequenceNumber !== embeddedLastSequenceNumber + samplesInfo.numSequences) { 46719 for (i = 0; i < embeddedCea608FieldParsers.length; i++) { 46720 if (embeddedCea608FieldParsers[i]) { 46721 embeddedCea608FieldParsers[i].reset(); 46722 } 46723 } 46724 } 46725 46726 var allCcData = extractCea608Data(bytes, samplesInfo.sampleList); 46727 46728 for (var fieldNr = 0; fieldNr < embeddedCea608FieldParsers.length; fieldNr++) { 46729 var ccData = allCcData.fields[fieldNr]; 46730 var fieldParser = embeddedCea608FieldParsers[fieldNr]; 46731 if (fieldParser) { 46732 /*if (ccData.length > 0 ) { 46733 log("CEA-608 adding Data to field " + fieldNr + " " + ccData.length + "bytes"); 46734 }*/ 46735 for (i = 0; i < ccData.length; i++) { 46736 fieldParser.addData(ccData[i][0] / embeddedTimescale, ccData[i][1]); 46737 } 46738 } 46739 } 46740 embeddedLastSequenceNumber = sequenceNumber; 46741 embeddedSequenceNumbers.push(sequenceNumber); 46742 } 46743 } 46744 } 46745 } 46746 /** 46747 * Extract CEA-608 data from a buffer of data. 46748 * @param {ArrayBuffer} data 46749 * @param {Array} samples cue information 46750 * @returns {Object|null} ccData corresponding to one segment. 46751 */ 46752 function extractCea608Data(data, samples) { 46753 46754 if (samples.length === 0) { 46755 return null; 46756 } 46757 46758 var allCcData = { 46759 splits: [], 46760 fields: [[], []] 46761 }; 46762 var raw = new DataView(data); 46763 for (var i = 0; i < samples.length; i++) { 46764 var sample = samples[i]; 46765 var cea608Ranges = _externalsCea608Parser2['default'].findCea608Nalus(raw, sample.offset, sample.
46765size); 46766 var lastSampleTime = null; 46767 var idx = 0; 46768 for (var j = 0; j < cea608Ranges.length; j++) { 46769 var ccData = _externalsCea608Parser2['default'].extractCea608DataFromRange(raw, cea608Ranges[j]); 46770 for (var k = 0; k < 2; k++) { 46771 if (ccData[k].length > 0) { 46772 if (sample.cts !== lastSampleTime) { 46773 idx = 0; 46774 } else { 46775 idx += 1; 46776 } 46777 allCcData.fields[k].push([sample.cts, ccData[k], idx]); 46778 lastSampleTime = sample.cts; 46779 } 46780 } 46781 } 46782 } 46783 46784 // Sort by sampleTime ascending order 46785 // If two packets have the same sampleTime, use them in the order 46786 // they were received 46787 allCcData.fields.forEach(function sortField(field) { 46788 field.sort(function (a, b) { 46789 if (a[0] === b[0]) { 46790 return a[2] - b[2]; 46791 } 46792 return a[0] - b[0]; 46793 }); 46794 }); 46795 46796 return allCcData; 46797 } 46798 46799 function getIsDefault(mediaInfo) { 46800 //TODO How to tag default. currently same order as listed in manifest. 46801 // Is there a way to mark a text adaptation set as the default one? DASHIF meeting talk about using role which is being used for track KIND 46802 // Eg subtitles etc. You can have multiple role tags per adaptation Not defined in the spec yet. 46803 var isDefault = false; 46804 if (embeddedTracks.length > 1 && mediaInfo.isEmbedded) { 46805 isDefault = mediaInfo.id && mediaInfo.id === _constantsConstants2['default'].CC1; // CC1 if both CC1 and CC3 exist 46806 } else if (embeddedTracks.length === 1) { 46807 if (mediaInfo.id && mediaInfo.id.substring(0, 2) === 'CC') { 46808 // Either CC1 or CC3 46809 isDefault = true; 46810 } 46811 } else if (embeddedTracks.length === 0) { 46812 isDefault = mediaInfo.index === mediaInfos[0].index; 46813 } 46814 return isDefault; 46815 } 46816 46817 function getParser(codecType) { 46818 var parser = undefined; 46819 if (codecType.search(_constantsConstants2['default'].VTT) >= 0) { 46820 parser = vttParser; 46821 } else if (codecType.search(_constantsConstants2['default'].TTML) >= 0 || codecType.search(_constantsConstants2['default'].STPP) >= 0) { 46822 parser = ttmlParser; 46823 } 46824 return parser; 46825 } 46826 46827 instance = { 46828 initialize: initialize, 46829 append: append, 46830 abort: abort, 46831 addEmbeddedTrack: addEmbeddedTrack, 46832 resetEmbedded: resetEmbedded, 46833 setConfig: setConfig, 46834 getConfig: getConfig, 46835 setCurrentFragmentedTrackIdx: setCurrentFragmentedTrackIdx 46836 }; 46837 46838 return instance; 46839} 46840 46841TextSourceBuffer.__dashjs_factory_name = 'TextSourceBuffer'; 46842exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(TextSourceBuffer); 46843module.exports = exports['default']; 46844 46845},{"100":100,"11":11,"183":183,"188":188,"190":190,"192":192,"2":2,"218":218,"224":224,"49":49,"50":50,"51":51,"54":54,"74":74}],188:[function(_dereq_,module,exports){ 46846/** 46847 * The copyright in this software is being made available under the BSD License, 46848 * included below. This software may be subject to other third party and contributor 46849 * rights, including patent rights, and no such rights are granted under this license. 46850 * 46851 * Copyright (c) 2013, Dash Industry Forum. 46852 * All rights reserved. 46853 * 46854 * Redistribution and use in source and binary forms, with or without modification, 46855 * are permitted provided that the following conditions are met: 46856 * * Redistributions of source code must retain the above copyright notice, this 46857 * list of conditions and the following disclaimer. 46858 * * Redistributions in binary form must reproduce the above copyright notice, 46859 * this list of conditions and the following disclaimer in the documentation and/or 46860 * other materials provided with the distribution. 46861 * * Neither the name of Dash Industry Forum nor the names of its 46862 * contributors may be used to endorse or promote products derived from this software 46863 * without specific prior written permission. 46864 * 46865 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 46866 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 46867 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 46868 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 46869 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
46869INCLUDING, BUT 46870 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 46871 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 46872 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46873 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 46874 * POSSIBILITY OF SUCH DAMAGE. 46875 */ 46876'use strict'; 46877 46878Object.defineProperty(exports, '__esModule', { 46879 value: true 46880}); 46881 46882function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 46883 46884var _constantsConstants = _dereq_(100); 46885 46886var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 46887 46888var _coreEventBus = _dereq_(50); 46889 46890var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 46891 46892var _coreEventsEvents = _dereq_(54); 46893 46894var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 46895 46896var _coreFactoryMaker = _dereq_(51); 46897 46898var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 46899 46900var _coreDebug = _dereq_(49); 46901 46902var _coreDebug2 = _interopRequireDefault(_coreDebug); 46903 46904var _imsc = _dereq_(21); 46905 46906function TextTracks() { 46907 46908 var context = this.context; 46909 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 46910 var log = (0, _coreDebug2['default'])(context).getInstance().log; 46911 46912 var instance = undefined, 46913 Cue = undefined, 46914 videoModel = undefined, 46915 textTrackQueue = undefined, 46916 trackElementArr = undefined, 46917 currentTrackIdx = undefined, 46918 actualVideoLeft = undefined, 46919 actualVideoTop = undefined, 46920 actualVideoWidth = undefined, 46921 actualVideoHeight = undefined, 46922 captionContainer = undefined, 46923 videoSizeCheckInterval = undefined, 46924 isChrome = undefined, 46925 fullscreenAttribute = undefined, 46926 displayCCOnTop = undefined, 46927 topZIndex = undefined; 46928 46929 function initialize() { 46930 if (typeof window === 'undefined' || typeof navigator === 'undefined') { 46931 return; 46932 } 46933 46934 Cue = window.VTTCue || window.TextTrackCue; 46935 textTrackQueue = []; 46936 trackElementArr = []; 46937 currentTrackIdx = -1; 46938 actualVideoLeft = 0; 46939 actualVideoTop = 0; 46940 actualVideoWidth = 0; 46941 actualVideoHeight = 0; 46942 captionContainer = null; 46943 videoSizeCheckInterval = null; 46944 displayCCOnTop = false; 46945 topZIndex = 2147483647; 46946
46947 //TODO Check if IE has resolved issues: Then revert to not using the addTextTrack API for all browsers. 46948 // https://connect.microsoft.com/IE/feedbackdetail/view/1660701/text-tracks-do-not-fire-change-addtrack-or-removetrack-events 46949 // https://connect.microsoft.com/IE/feedback/details/1573380/htmltrackelement-track-addcue-throws-invalidstateerror-when-adding-new-cue 46950 // Same issue with Firefox. 46951 //isIE11orEdge = !!navigator.userAgent.match(/Trident.*rv[ :]*11\./) || navigator.userAgent.match(/Edge/); 46952 //isFirefox = !!navigator.userAgent.match(/Firefox/); 46953 isChrome = !!navigator.userAgent.match(/Chrome/) && !navigator.userAgent.match(/Edge/); 46954 if (document.fullscreenElement !== undefined) { 46955 fullscreenAttribute = 'fullscreenElement'; // Standard and Edge 46956 } else if (document.webkitIsFullScreen !== undefined) { 46957 fullscreenAttribute = 'webkitIsFullScreen'; // Chrome and Safari (and Edge) 46958 } else if (document.msFullscreenElement) { 46959 // IE11 46960 fullscreenAttribute = 'msFullscreenElement'; 46961 } else if (document.mozFullScreen) { 46962 // Firefox 46963 fullscreenAttribute = 'mozFullScreen'; 46964 } 46965 } 46966 46967 function createTrackForUserAgent(i) { 46968 var kind = textTrackQueue[i].kind; 46969 var label = textTrackQueue[i].label !== undefined ? textTrackQueue[i].label : textTrackQueue[i].lang; 46970 var lang = textTrackQueue[i].lang; 46971 var track = isChrome ? document.createElement('track') : videoModel.addTextTrack(kind, label, lang); 46972 46973 if (isChrome) { 46974 track.kind = kind; 46975 track.label = label; 46976 track.srclang = lang; 46977 } 46978 46979 return track; 46980 } 46981 46982 function displayCConTop(value) { 46983 displayCCOnTop = value; 46984 if (!captionContainer || document[fullscreenAttribute]) { 46985 return; 46986 } 46987 captionContainer.style.zIndex = value ? topZIndex : null; 46988 } 46989 46990 function addTextTrack(textTrackInfoVO, totalTextTracks) { 46991 if (textTrackQueue.length === totalTextTracks) { 46992 log('Trying to add too many tracks.'); 46993 return; 46994 } 46995 46996 textTrackQueue.push(textTrackInfoVO); 46997 46998 if (textTrackQueue.length === totalTextTracks) { 46999 textTrackQueue.sort(function (a, b) { 47000 //Sort in same order as in manifest 47001 return a.index - b.index; 47002 }); 47003 captionContainer = videoModel.getTTMLRenderingDiv(); 47004 var defaultIndex = -1; 47005 for (var i = 0; i < textTrackQueue.length; i++) { 47006 var track = createTrackForUserAgent.call(this, i); 47007 trackElementArr.push(track); //used to remove tracks from video element when added manually 47008 47009 if (textTrackQueue[i].defaultTrack) { 47010 // track.default is an object property identifier that is a reserved word 47011 // The following jshint directive is used to suppressed the warning "Expected an identifier and instead saw 'default' (a reserved word)" 47012 /*jshint -W024 */ 47013 track['default'] = true; 47014 defaultIndex = i; 47015 } 47016 if (isChrome) { 47017 videoModel.appendChild(track); 47018 } 47019 47020 var textTrack = getTrackByIdx(i); 47021 if (textTrack) { 47022 //each time a track is created, its mode should be showing by default 47023 //sometime, it's not on Chrome 47024 textTrack.mode = _constantsConstants2['default'].TEXT_SHOWING; 47025 if (captionContainer && (textTrackQueue[i].isTTML || textTrackQueue[i].isEmbedded)) { 47026 textTrack.renderingType = 'html'; 47027 } else { 47028 textTrack.renderingType = 'default'; 47029 } 47030 } 47031 this.addCaptions(i, 0, textTrackQueue[i].captionData); 47032 eventBus.trigger(_coreEventsEvents2['default'].TEXT_TRACK_ADDED); 47033 } 47034 47035 //set current track index in textTrackQueue array 47036 setCurrentTrackIdx.call(this, defaultIndex); 47037 47038 if (defaultIndex >= 0) { 47039 for (var idx = 0; idx < textTrackQueue.length; idx++) { 47040 var videoTextTrack = getTrackByIdx(idx); 47041 if (videoTextTrack) { 47042 videoTextTrack.mode = idx === defaultIndex ? _constantsConstants2['default'].TEXT_SHOWING : _constantsConstants2['default'].TEXT_HIDDEN; 47043 } 47044 } 47045 } 47046 47047 eventBus.trigger(_coreEventsEvents2['default'].TEXT_TRACKS_ADDED, { 47048 index: currentTrackIdx, 47049 tracks: textTrackQueue 47050 }); //send default idx. 47051 } 47052 } 47053 47054 function getVideoVisibleVideoSize(viewWidth, viewHeight, videoWidth, videoHeight, aspectRatio, use80Percent) { 47055 var viewAspectRatio = viewWidth / viewHeight; 47056 var videoAspectRatio = videoWidth / videoHeight; 47057 47058 var videoPictureWidth = 0; 47059 var videoPictureHeight = 0; 47060 47061 if (viewAspectRatio > videoAspectRatio) { 47062 videoPictureHeight = viewHeight; 47063 videoPictureWidth = videoPictureHeight / videoHeight * videoWidth; 47064 } else { 47065 videoPictureWidth = viewWidth; 47066 videoPictureHeight = videoPictureWidth / videoWidth * videoHeight; 47067 } 47068 47069 var videoPictureXAspect = 0; 47070 var videoPictureYAspect = 0; 47071 var videoPictureWidthAspect = 0; 47072 var videoPictureHeightAspect = 0; 47073 var videoPictureAspect = videoPictureWidth / videoPictureHeight; 47074 47075 if (videoPictureAspect > aspectRatio) { 47076 videoPictureHeightAspect = videoPictureHeight; 47077 videoPictureWidthAspect = videoPictureHeight / (1 / aspectRatio); 47078 videoPictureXAspect = (viewWidth - videoPictureWidthAspect) / 2; 47079 videoPictureYAspect = 0; 47080 } else { 47081 videoPictureWidthAspect = videoPictureWidth; 47082 videoPictureHeightAspect = videoPictureWidth / aspectRatio; 47083 videoPictureXAspect = 0; 47084 videoPictureYAspect = (viewHeight - videoPictureHeightAspect) / 2; 47085 } 47086 47087 if (use80Percent) { 47088 return { 47089 x: videoPictureXAspect + videoPictureWidthAspect * 0.1, 47090 y: videoPictureYAspect + videoPictureHeightAspect * 0.1, 47091 w: videoPictureWidthAspect * 0.8, 47092 h: videoPictureHeightAspect * 0.8 47093 }; /* Maximal picture size in videos aspect ratio */ 47094 } else { 47095 return { 47096 x: videoPictureXAspect, 47097 y: videoPictureYAspect, 47098 w: videoPictureWidthAspect, 47099 h: videoPictureHeightAspect 47100 }; /* Maximal picture size in videos aspect ratio */ 47101 } 47102 } 47103 47104 function checkVideoSize(track) { 47105 var clientWidth = videoModel.getClientWidth(); 47106 var clientHeight = videoModel.getClientHeight(); 47107 var videoWidth = videoModel.getVideoWidth(); 47108 var videoHeight = videoModel.getVideoHeight(); 47109 var aspectRatio = clientWidth / clientHeight; 47110 var use80Percent = false; 47111 if (track.isFromCEA608) { 47112 // If this is CEA608 then use predefined aspect ratio 47113 aspectRatio = 3.5 / 3.0; 47114 use80Percent = true; 47115 } 47116 47117 var realVideoSize = getVideoVisibleVideoSize.call(this, clientWidth, clientHeight, videoWidth, videoHeight, aspectRatio, use80Percent); 47118
47119 var newVideoWidth = realVideoSize.w; 47120 var newVideoHeight = realVideoSize.h; 47121 47122 if (newVideoWidth != actualVideoWidth || newVideoHeight != actualVideoHeight) { 47123 actualVideoLeft = realVideoSize.x; 47124 actualVideoTop = realVideoSize.y; 47125 actualVideoWidth = newVideoWidth; 47126 actualVideoHeight = newVideoHeight; 47127 captionContainer.style.left = actualVideoLeft + 'px'; 47128 captionContainer.style.top = actualVideoTop + 'px'; 47129 captionContainer.style.width = actualVideoWidth + 'px'; 47130 captionContainer.style.height = actualVideoHeight + 'px'; 47131 47132 // Video view has changed size, so resize any active cues 47133 for (var i = 0; track.activeCues && i < track.activeCues.length; ++i) { 47134 var cue = track.activeCues[i]; 47135 cue.scaleCue(cue); 47136 } 47137 47138 if (fullscreenAttribute && document[fullscreenAttribute] || displayCCOnTop) { 47139 captionContainer.style.zIndex = topZIndex; 47140 } else { 47141 captionContainer.style.zIndex = null; 47142 } 47143 } 47144 } 47145 47146 function scaleCue(activeCue) { 47147 var videoWidth = actualVideoWidth; 47148 var videoHeight = actualVideoHeight; 47149 var key = undefined, 47150 replaceValue = undefined, 47151 valueFontSize = undefined, 47152 valueLineHeight = undefined, 47153 elements = undefined; 47154 47155 if (activeCue.cellResolution) { 47156 var cellUnit = [videoWidth / activeCue.cellResolution[0], videoHeight / activeCue.cellResolution[1]]; 47157 if (activeCue.linePadding) { 47158 for (key in activeCue.linePadding) { 47159 if (activeCue.linePadding.hasOwnProperty(key)) { 47160 var valueLinePadding = activeCue.linePadding[key]; 47161 replaceValue = (valueLinePadding * cellUnit[0]).toString(); 47162 // Compute the CellResolution unit in order to process properties using sizing (fontSize, linePadding, etc). 47163 var elementsSpan = document.getElementsByClassName('spanPadding'); 47164 for (var i = 0; i < elementsSpan.length; i++) { 47165 elementsSpan[i].style.cssText = elementsSpan[i].style.cssText.replace(/(padding-left\s*:\s*)[\d.,]+(?=\s*px)/gi, '$1' + replaceValue); 47166 elementsSpan[i].style.cssText = elementsSpan[i].style.cssText.replace(/(padding-right\s*:\s*)[\d.,]+(?=\s*px)/gi, '$1' + replaceValue); 47167 } 47168 } 47169 } 47170 } 47171 47172 if (activeCue.fontSize) { 47173 for (key in activeCue.fontSize) { 47174 if (activeCue.fontSize.hasOwnProperty(key)) { 47175 if (activeCue.fontSize[key][0] === '%') { 47176 valueFontSize = activeCue.fontSize[key][1] / 100; 47177 } else if (activeCue.fontSize[key][0] === 'c') { 47178 valueFontSize = activeCue.fontSize[key][1]; 47179 } 47180 47181 replaceValue = (valueFontSize * cellUnit[1]).toString(); 47182 47183 if (key !== 'defaultFontSize') { 47184 elements = document.getElementsByClassName(key); 47185 } else { 47186 elements = document.getElementsByClassName('paragraph'); 47187 } 47188 47189 for (var j = 0; j < elements.length; j++) { 47190 elements[j].style.cssText = elements[j].style.cssText.replace(/(font-size\s*:\s*)[\d.,]+(?=\s*px)/gi, '$1' + replaceValue); 47191 } 47192 } 47193 } 47194 47195 if (activeCue.lineHeight) { 47196 for (key in activeCue.lineHeight) { 47197 if (activeCue.lineHeight.hasOwnProperty(key)) { 47198 if (activeCue.lineHeight[key][0] === '%') { 47199 valueLineHeight = activeCue.lineHeight[key][1] / 100; 47200 } else if (activeCue.fontSize[key][0] === 'c') { 47201 valueLineHeight = activeCue.lineHeight[key][1]; 47202 } 47203 47204 replaceValue = (valueLineHeight * cellUnit[1]).toString(); 47205 elements = document.getElementsByClassName(key); 47206 for (var k = 0; k < elements.length; k++) { 47207 elements[k].style.cssText = elements[k].style.cssText.replace(/(line-height\s*:\s*)[\d.,]+(?=\s*px)/gi, '$1' + replaceValue); 47208 } 47209 } 47210 } 47211 } 47212 } 47213 } 47214 } 47215 47216 /* 47217 * Add captions to track, store for later adding, or add captions added before 47218 */ 47219 function addCaptions(trackIdx, timeOffset, captionData) { 47220 var track = getTrackByIdx(trackIdx); 47221 var self = this; 47222 47223 if (!track) { 47224 return; 47225 } 47226 47227 if (!captionData || captionData.length === 0) { 47228 return; 47229 } 47230 47231 var _loop = function (item) { 47232 var cue = undefined; 47233 var currentItem = captionData[item]; 47234 47235 track.cellResolution = currentItem.cellResolution; 47236 track.isFromCEA608 = currentItem.isFromCEA608; 47237 47238 if (currentItem.type === 'html') { 47239 cue = new Cue(currentItem.start - timeOffset, currentItem.end - timeOffset, ''); 47240 cue.cueHTMLElement = currentItem.cueHTMLElement; 47241 cue.isd = currentItem.isd; 47242 cue.images = currentItem.images; 47243 cue.embeddedImages = currentItem.embeddedImages; 47244 cue.cueID = currentItem.cueID; 47245 cue.scaleCue = scaleCue.bind(self); 47246 //useful parameters for cea608 subtitles, not for TTML one. 47247 cue.cellResolution = currentItem.cellResolution; 47248 cue.lineHeight = currentItem.lineHeight; 47249 cue.linePadding = currentItem.linePadding; 47250 cue.fontSize = currentItem.fontSize; 47251 47252 captionContainer.style.left = actualVideoLeft + 'px'; 47253 captionContainer.style.top = actualVideoTop + 'px'; 47254 captionContainer.style.width = actualVideoWidth + 'px'; 47255 captionContainer.style.height = actualVideoHeight + 'px'; 47256 47257 cue.onenter = function () { 47258 if (track.mode === _constantsConstants2['default'].TEXT_SHOWING) { 47259 if (this.isd) { 47260 var finalCue = document.createElement('div'); 47261 log('Cue enter id:' + this.cueID); 47262 captionContainer.appendChild(finalCue); 47263 (0, _imsc.renderHTML)(this.isd, finalCue, function (uri) { 47264 var imsc1ImgUrnTester = /^(urn:)(mpeg:[a-z0-9][a-z0-9-]{0,31}:)(subs:)([0-9])$/; 47265 var smpteImgUrnTester = /^#(.*)$/; 47266 if (imsc1ImgUrnTester.test(uri)) { 47267 var match = imsc1ImgUrnTester.exec(uri); 47268 var imageId = parseInt(match[4], 10) - 1; 47269 var imageData = btoa(cue.images[imageId]); 47270 var dataUrl = 'data:image/png;base64,' + imageData; 47271 return dataUrl; 47272 } else if (smpteImgUrnTester.test(uri)) { 47273 var match = smpteImgUrnTester.exec(uri); 47274 var imageId = match[1]; 47275 var dataUrl = 'data:image/png;base64,' + cue.embeddedImages[imageId];
47276 return dataUrl; 47277 } else { 47278 return null; 47279 } 47280 }, captionContainer.clientHeight, captionContainer.clientWidth); 47281 finalCue.id = this.cueID; 47282 } else { 47283 captionContainer.appendChild(this.cueHTMLElement); 47284 scaleCue.call(self, this); 47285 } 47286 } 47287 }; 47288 47289 cue.onexit = function () { 47290 var divs = captionContainer.childNodes; 47291 for (var i = 0; i < divs.length; ++i) { 47292 if (divs[i].id === this.cueID) { 47293 log('Cue exit id:' + divs[i].id); 47294 captionContainer.removeChild(divs[i]); 47295 } 47296 } 47297 }; 47298 } else { 47299 cue = new Cue(currentItem.start - timeOffset, currentItem.end - timeOffset, currentItem.data); 47300 if (currentItem.styles) { 47301 if (currentItem.styles.align !== undefined && 'align' in cue) { 47302 cue.align = currentItem.styles.align; 47303 } 47304 if (currentItem.styles.line !== undefined && 'line' in cue) { 47305 cue.line = currentItem.styles.line; 47306 } 47307 if (currentItem.styles.position !== undefined && 'position' in cue) { 47308 cue.position = currentItem.styles.position; 47309 } 47310 if (currentItem.styles.size !== undefined && 'size' in cue) { 47311 cue.size = currentItem.styles.size; 47312 } 47313 } 47314 } 47315 47316 track.addCue(cue); 47317 }; 47318 47319 for (var item in captionData) { 47320 _loop(item); 47321 } 47322 } 47323 47324 function getTrackByIdx(idx) { 47325 return idx >= 0 && textTrackQueue[idx] ? videoModel.getTextTrack(textTrackQueue[idx].kind, textTrackQueue[idx].label, textTrackQueue[idx].lang) : null; 47326 } 47327 47328 function getCurrentTrackIdx() { 47329 return currentTrackIdx; 47330 } 47331 47332 function getTrackIdxForId(trackId) { 47333 var idx = -1; 47334 for (var i = 0; i < textTrackQueue.length; i++) { 47335 if (textTrackQueue[i].label === trackId) { 47336 idx = i; 47337 break; 47338 } 47339 } 47340 47341 return idx; 47342 } 47343 47344 function setCurrentTrackIdx(idx) { 47345 if (idx === currentTrackIdx) { 47346 return; 47347 } 47348 currentTrackIdx = idx; 47349 var track = getTrackByIdx(currentTrackIdx); 47350 setCueStyleOnTrack.call(this, track); 47351 47352 if (videoSizeCheckInterval) { 47353 clearInterval(videoSizeCheckInterval); 47354 videoSizeCheckInterval = null; 47355 } 47356 47357 if (track && track.renderingType === 'html') { 47358 checkVideoSize.call(this, track); 47359 videoSizeCheckInterval = setInterval(checkVideoSize.bind(this, track), 500); 47360 } 47361 } 47362 47363 function setCueStyleOnTrack(track) { 47364 clearCaptionContainer.call(this); 47365 if (track) { 47366 if (track.renderingType === 'html') { 47367 setNativeCueStyle.call(this); 47368 } else { 47369 removeNativeCueStyle.call(this); 47370 } 47371 } else { 47372 removeNativeCueStyle.call(this); 47373 } 47374 } 47375 47376 function deleteTrackCues(track) { 47377 if (track.cues) { 47378 var cues = track.cues; 47379 var lastIdx = cues.length - 1; 47380 47381 for (var r = lastIdx; r >= 0; r--) { 47382 track.removeCue(cues[r]); 47383 } 47384 } 47385 } 47386 47387 function deleteCuesFromTrackIdx(trackIdx) { 47388 var track = getTrackByIdx(trackIdx); 47389 if (track) { 47390 deleteTrackCues(track); 47391 } 47392 } 47393 47394 function deleteAllTextTracks() { 47395 var ln = trackElementArr ? trackElementArr.length : 0; 47396 for (var i = 0; i < ln; i++) { 47397 if (isChrome) { 47398 videoModel.removeChild(trackElementArr[i]); 47399 } else { 47400 var track = getTrackByIdx(i); 47401 if (track) { 47402 deleteTrackCues.call(this, track); 47403 track.mode = 'disabled'; 47404 } 47405 } 47406 } 47407 trackElementArr = []; 47408 textTrackQueue = []; 47409 if (videoSizeCheckInterval) { 47410 clearInterval(videoSizeCheckInterval); 47411 videoSizeCheckInterval = null; 47412 } 47413 currentTrackIdx = -1; 47414 clearCaptionContainer.call(this); 47415 } 47416 47417 function deleteTextTrack(idx) { 47418 videoModel.removeChild(trackElementArr[idx]); 47419 trackElementArr.splice(idx, 1); 47420 } 47421 47422 /* Set native cue style to transparent background to avoid it being displayed. */ 47423 function setNativeCueStyle() { 47424 if (!isChrome) { 47425 return; 47426 } 47427 var styleElement = document.getElementById('native-cue-style'); 47428 if (styleElement) { 47429 return; //Already set 47430 } 47431 47432 styleElement = document.createElement('style'); 47433 styleElement.id = 'native-cue-style'; 47434 document.head.appendChild(styleElement); 47435 var stylesheet = styleElement.sheet; 47436 var video = videoModel.getElement(); 47437 if (video) { 47438 if (video.id) { 47439 stylesheet.insertRule('#' + video.id + '::cue {background: transparent}', 0); 47440 } else if (video.classList.length !== 0) { 47441 stylesheet.insertRule('.' + video.className + '::cue {background: transparent}', 0); 47442 } else { 47443 stylesheet.insertRule('video::cue {background: transparent}', 0); 47444 } 47445 } 47446 } 47447 47448 /* Remove the extra cue style with transparent background for native cues. */ 47449 function removeNativeCueStyle() { 47450 if (!isChrome) { 47451 return; 47452 } 47453 var styleElement = document.getElementById('native-cue-style'); 47454 if (styleElement) { 47455 document.head.removeChild(styleElement); 47456 } 47457 } 47458 47459 function clearCaptionContainer() { 47460 if (captionContainer) { 47461 while (captionContainer.firstChild) { 47462 captionContainer.removeChild(captionContainer.firstChild); 47463 } 47464 } 47465 } 47466 47467 function setConfig(config) { 47468 if (!config) { 47469 return; 47470 } 47471 if (config.videoModel) { 47472 videoModel = config.videoModel; 47473 } 47474 } 47475 47476 function setModeForTrackIdx(idx, mode) { 47477 var track = getTrackByIdx(idx); 47478 if (track && track.mode !== mode) { 47479 track.mode = mode; 47480 } 47481 } 47482 47483 function getCurrentTrackInfo() { 47484 return textTrackQueue[currentTrackIdx]; 47485 } 47486 47487 instance = { 47488 initialize: initialize, 47489 displayCConTop: displayCConTop, 47490 addTextTrack: addTextTrack, 47491 addCaptions: addCaptions, 47492 getCurrentTrackIdx: getCurrentTrackIdx, 47493 setCurrentTrackIdx: setCurrentTrackIdx, 47494 getTrackIdxForId: getTrackIdxForId, 47495 getCurrentTrackInfo: getCurrentTrackInfo, 47496 setModeForTrackIdx: setModeForTrackIdx, 47497 deleteCuesFromTrackIdx: deleteCuesFromTrackIdx, 47498 deleteAllTextTracks: deleteAllTextTracks, 47499 deleteTextTrack: deleteTextTrack, 47500 setConfig: setConfig 47501 }; 47502 47503 return instance; 47504} 47505 47506TextTracks.__dashjs_factory_name = 'TextTracks'; 47507exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(TextTracks); 47508module.exports = exports['default']; 47509 47510},{"100":100,"21":21,"49":49,"50":50,"51":51,"54":54}],189:[function(_dereq_,module,exports){ 47511/** 47512 * The copyright in this software is being made available under the BSD License, 47513 * included below. This software may be subject to other third party and contributor 47514 * rights, including patent rights, and no such rights are granted under this license. 47515 * 47516 * Copyright (c) 2013, Dash Industry Forum. 47517 * All rights reserved. 47518 * 47519 * Redistribution and use in source and binary forms, with or without modification, 47520 * are permitted provided that the following conditions are met: 47521 * * Redistributions of source code must retain the above copyright notice, this 47522 * list of conditions and the following disclaimer. 47523 * * Redistributions in binary form must reproduce the above copyright notice, 47524 * this list of conditions and the following disclaimer in the documentation and/or 47525 * other materials provided with the distribution. 47526 * * Neither the name of Dash Industry Forum nor the names of its 47527 * contributors may be used to endorse or promote products derived from this software 47528 * without specific prior written permission. 47529 * 47530 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 47531 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 47532 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47533 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 47534 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
47534INCLUDING, BUT 47535 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 47536 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 47537 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 47538 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47539 * POSSIBILITY OF SUCH DAMAGE. 47540 */ 47541 47542'use strict'; 47543 47544Object.defineProperty(exports, '__esModule', { 47545 value: true 47546}); 47547 47548function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 47549 47550var _coreEventBus = _dereq_(50); 47551 47552var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 47553 47554var _coreEventsEvents = _dereq_(54); 47555 47556var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 47557 47558var _controllersBlacklistController = _dereq_(104); 47559 47560var _controllersBlacklistController2 = _interopRequireDefault(_controllersBlacklistController); 47561 47562var _baseUrlResolutionDVBSelector = _dereq_(205); 47563 47564var _baseUrlResolutionDVBSelector2 = _interopRequireDefault(_baseUrlResolutionDVBSelector); 47565 47566var _baseUrlResolutionBasicSelector = _dereq_(204); 47567 47568var _baseUrlResolutionBasicSelector2 = _interopRequireDefault(_baseUrlResolutionBasicSelector); 47569 47570var _coreFactoryMaker = _dereq_(51); 47571 47572var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 47573 47574var URL_RESOLUTION_FAILED_GENERIC_ERROR_CODE = 1; 47575var URL_RESOLUTION_FAILED_GENERIC_ERROR_MESSAGE = 'Failed to resolve a valid URL'; 47576 47577function BaseURLSelector() { 47578 47579 var context = this.context; 47580 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 47581 var dashManifestModel = undefined; 47582 47583 var instance = undefined, 47584 serviceLocationBlacklistController = undefined, 47585 basicSelector = undefined, 47586 dvbSelector = undefined, 47587 selector = undefined; 47588 47589 function setup() { 47590 serviceLocationBlacklistController = (0, _controllersBlacklistController2['default'])(context).create({ 47591 updateEventName: _coreEventsEvents2['default'].SERVICE_LOCATION_BLACKLIST_CHANGED, 47592 addBlacklistEventName: _coreEventsEvents2['default'].SERVICE_LOCATION_BLACKLIST_ADD 47593 }); 47594 47595 basicSelector = (0, _baseUrlResolutionBasicSelector2['default'])(context).create({ 47596 blacklistController: serviceLocationBlacklistController 47597 }); 47598 47599 dvbSelector = (0, _baseUrlResolutionDVBSelector2['default'])(context).create({ 47600 blacklistController: serviceLocationBlacklistController 47601 }); 47602 47603 selector = basicSelector; 47604 } 47605 47606 function setConfig(config) { 47607 if (config.selector) { 47608 selector = config.selector; 47609 } 47610 if (config.dashManifestModel) { 47611 dashManifestModel = config.dashManifestModel; 47612 } 47613 } 47614 47615 function checkConfig() { 47616 if (!dashManifestModel || !dashManifestModel.hasOwnProperty('getIsDVB')) { 47617 throw new Error('Missing config parameter(s)'); 47618 } 47619 } 47620 47621 function chooseSelectorFromManifest(manifest) { 47622 checkConfig(); 47623 if (dashManifestModel.getIsDVB(manifest)) { 47624 selector = dvbSelector; 47625 } else { 47626 selector = basicSelector; 47627 } 47628 } 47629 47630 function select(data) { 47631 var baseUrls = data.baseUrls; 47632 var selectedIdx = data.selectedIdx; 47633 47634 // Once a random selection has been carried out amongst a group of BaseURLs with the same 47635 // @priority attribute value, then that choice should be re-used if the selection needs to be made again 47636 // unless the blacklist has been modified or the available BaseURLs have changed. 47637 if (!isNaN(selectedIdx)) { 47638 return baseUrls[selectedIdx]; 47639 } 47640 47641 var selectedBaseUrl = selector.select(baseUrls); 47642 47643 if (!selectedBaseUrl) { 47644 eventBus.trigger(_coreEventsEvents2['default'].URL_RESOLUTION_FAILED, { 47645 error: new Error(URL_RESOLUTION_FAILED_GENERIC_ERROR_CODE, URL_RESOLUTION_FAILED_GENERIC_ERROR_MESSAGE) 47646 }); 47647 47648 return; 47649 } 47650 47651 data.selectedIdx = baseUrls.indexOf(selectedBaseUrl); 47652 47653 return selectedBaseUrl; 47654 } 47655 47656 function reset() { 47657 serviceLocationBlacklistController.reset(); 47658 } 47659 47660 instance = { 47661 chooseSelectorFromManifest: chooseSelectorFromManifest, 47662 select: select, 47663 reset: reset, 47664 setConfig: setConfig 47665 }; 47666 47667 setup(); 47668 47669 return instance; 47670} 47671 47672BaseURLSelector.__dashjs_factory_name = 'BaseURLSelector'; 47673var factory = _coreFactoryMaker2['default'].getClassFactory(BaseURLSelector); 47674factory.URL_RESOLUTION_FAILED_GENERIC_ERROR_CODE = URL_RESOLUTION_FAILED_GENERIC_ERROR_CODE; 47675factory.URL_RESOLUTION_FAILED_GENERIC_ERROR_MESSAGE = URL_RESOLUTION_FAILED_GENERIC_ERROR_MESSAGE; 47676_coreFactoryMaker2['default'].updateClassFactory(BaseURLSelector.__dashjs_factory_name, factory); 47677exports['default'] = factory; 47678module.exports = exports['default']; 47679 47680},{"104":104,"204":204,"205":205,"50":50,"51":51,"54":54}],190:[function(_dereq_,module,exports){ 47681/** 47682 * The copyright in this software is being made available under the BSD License, 47683 * included below. This software may be subject to other third party and contributor 47684 * rights, including patent rights, and no such rights are granted under this license. 47685 * 47686 * Copyright (c) 2013, Dash Industry Forum. 47687 * All rights reserved. 47688 * 47689 * Redistribution and use in source and binary forms, with or without modification, 47690 * are permitted provided that the following conditions are met: 47691 * * Redistributions of source code must retain the above copyright notice, this 47692 * list of conditions and the following disclaimer. 47693 * * Redistributions in binary form must reproduce the above copyright notice, 47694 * this list of conditions and the following disclaimer in the documentation and/or 47695 * other materials provided with the distribution. 47696 * * Neither the name of Dash Industry Forum nor the names of its 47697 * contributors may be used to endorse or promote products derived from this software 47698 * without specific prior written permission. 47699 * 47700 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 47701 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 47702 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47703 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 47704 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
47704INCLUDING, BUT 47705 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 47706 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 47707 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 47708 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47709 * POSSIBILITY OF SUCH DAMAGE. 47710 */ 47711 47712'use strict'; 47713 47714Object.defineProperty(exports, '__esModule', { 47715 value: true 47716}); 47717 47718function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 47719 47720var _IsoFile = _dereq_(197); 47721 47722var _IsoFile2 = _interopRequireDefault(_IsoFile); 47723 47724var _coreFactoryMaker = _dereq_(51); 47725 47726var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 47727 47728var _codemIsoboxer = _dereq_(11); 47729 47730var _codemIsoboxer2 = _interopRequireDefault(_codemIsoboxer); 47731 47732function BoxParser() /*config*/{ 47733 47734 var instance = undefined; 47735 var context = this.context; 47736 47737 /** 47738 * @param {ArrayBuffer} data 47739 * @returns {IsoFile|null} 47740 * @memberof BoxParser# 47741 */ 47742 function parse(data) { 47743 if (!data) return null; 47744 47745 if (data.fileStart === undefined) { 47746 data.fileStart = 0; 47747 } 47748 47749 var parsedFile = _codemIsoboxer2['default'].parseBuffer(data); 47750 var dashIsoFile = (0, _IsoFile2['default'])(context).create(); 47751 47752 dashIsoFile.setData(parsedFile); 47753 47754 return dashIsoFile; 47755 } 47756 47757 instance = { 47758 parse: parse 47759 }; 47760 47761 return instance; 47762} 47763BoxParser.__dashjs_factory_name = 'BoxParser'; 47764exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(BoxParser); 47765module.exports = exports['default']; 47766 47767},{"11":11,"197":197,"51":51}],191:[function(_dereq_,module,exports){ 47768/** 47769 * The copyright in this software is being made available under the BSD License, 47770 * included below. This software may be subject to other third party and contributor 47771 * rights, including patent rights, and no such rights are granted under this license. 47772 * 47773 * Copyright (c) 2013, Dash Industry Forum. 47774 * All rights reserved. 47775 * 47776 * Redistribution and use in source and binary forms, with or without modification, 47777 * are permitted provided that the following conditions are met: 47778 * * Redistributions of source code must retain the above copyright notice, this 47779 * list of conditions and the following disclaimer. 47780 * * Redistributions in binary form must reproduce the above copyright notice, 47781 * this list of conditions and the following disclaimer in the documentation and/or 47782 * other materials provided with the distribution. 47783 * * Neither the name of Dash Industry Forum nor the names of its 47784 * contributors may be used to endorse or promote products derived from this software 47785 * without specific prior written permission. 47786 * 47787 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 47788 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 47789 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47790 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 47791 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47792 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 47793 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 47794 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 47795 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47796 * POSSIBILITY OF SUCH DAMAGE. 47797 */ 47798'use strict'; 47799 47800Object.defineProperty(exports, '__esModule', { 47801 value: true 47802}); 47803 47804function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 47805 47806var _coreFactoryMaker = _dereq_(51); 47807 47808var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 47809 47810function Capabilities() { 47811 47812 var instance = undefined, 47813 encryptedMediaSupported = undefined; 47814 47815 function setup() { 47816 encryptedMediaSupported = false; 47817 } 47818 47819 function supportsMediaSource() { 47820 var hasWebKit = ('WebKitMediaSource' in window); 47821 var hasMediaSource = ('MediaSource' in window); 47822 47823 return hasWebKit || hasMediaSource; 47824 } 47825 47826 /** 47827 * Returns whether Encrypted Media Extensions are supported on this 47828 * user agent 47829 * 47830 * @return {boolean} true if EME is supported, false otherwise 47831 */ 47832 function supportsEncryptedMedia() { 47833 return encryptedMediaSupported; 47834 } 47835 47836 function setEncryptedMediaSupported(value) { 47837 encryptedMediaSupported = value; 47838 } 47839 47840 function supportsCodec(codec) {
vendor: 9,886 bytes, lines 47841-48070
47841 if ('MediaSource' in window && MediaSource.isTypeSupported(codec)) { 47842 return true; 47843 } 47844 47845 if ('WebKitMediaSource' in window && WebKitMediaSource.isTypeSupported(codec)) { 47846 return true; 47847 } 47848 47849 return false; 47850 } 47851 47852 instance = { 47853 supportsMediaSource: supportsMediaSource, 47854 supportsEncryptedMedia: supportsEncryptedMedia, 47855 supportsCodec: supportsCodec, 47856 setEncryptedMediaSupported: setEncryptedMediaSupported 47857 }; 47858 47859 setup(); 47860 47861 return instance; 47862} 47863Capabilities.__dashjs_factory_name = 'Capabilities'; 47864exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(Capabilities); 47865module.exports = exports['default']; 47866 47867},{"51":51}],192:[function(_dereq_,module,exports){ 47868/** 47869* The copyright in this software is being made available under the BSD License, 47870* included below. This software may be subject to other third party and contributor 47871* rights, including patent rights, and no such rights are granted under this license. 47872* 47873* Copyright (c) 2013, Dash Industry Forum. 47874* All rights reserved. 47875* 47876* Redistribution and use in source and binary forms, with or without modification, 47877* are permitted provided that the following conditions are met: 47878* * Redistributions of source code must retain the above copyright notice, this 47879* list of conditions and the following disclaimer. 47880* * Redistributions in binary form must reproduce the above copyright notice, 47881* this list of conditions and the following disclaimer in the documentation and/or 47882* other materials provided with the distribution. 47883* * Neither the name of Dash Industry Forum nor the names of its 47884* contributors may be used to endorse or promote products derived from this software 47885* without specific prior written permission. 47886* 47887* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 47888* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 47889* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47890* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 47891* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47892* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 47893* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 47894* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 47895* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47896* POSSIBILITY OF SUCH DAMAGE. 47897*/ 47898'use strict'; 47899 47900Object.defineProperty(exports, '__esModule', { 47901 value: true 47902}); 47903 47904function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 47905 47906var _coreFactoryMaker = _dereq_(51); 47907 47908var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 47909 47910function CustomTimeRanges() /*config*/{ 47911 var customTimeRangeArray = []; 47912 var length = 0; 47913 47914 function add(start, end) { 47915 var i = 0; 47916 47917 for (i = 0; i < this.customTimeRangeArray.length && start > this.customTimeRangeArray[i].start; i++); 47918 47919 this.customTimeRangeArray.splice(i, 0, { start: start, end: end }); 47920 47921 for (i = 0; i < this.customTimeRangeArray.length - 1; i++) { 47922 if (this.mergeRanges(i, i + 1)) { 47923 i--; 47924 } 47925 } 47926 this.length = this.customTimeRangeArray.length; 47927 } 47928 47929 function clear() { 47930 this.customTimeRangeArray = []; 47931 this.length = 0; 47932 } 47933 47934 function remove(start, end) { 47935 for (var i = 0; i < this.customTimeRangeArray.length; i++) { 47936 if (start <= this.customTimeRangeArray[i].start && end >= this.customTimeRangeArray[i].end) { 47937 // |--------------Range i-------| 47938 //|---------------Range to remove ---------------| 47939 // or 47940 //|--------------Range i-------| 47941 //|--------------Range to remove ---------------| 47942 // or 47943 // |--------------Range i-------| 47944 //|--------------Range to remove ---------------| 47945 this.customTimeRangeArray.splice(i, 1); 47946 i--; 47947 } else if (start > this.customTimeRangeArray[i].start && end < this.customTimeRangeArray[i].end) { 47948 //|-----------------Range i----------------| 47949 // |-------Range to remove -----| 47950 this.customTimeRangeArray.splice(i + 1, 0, { start: end, end: this.customTimeRangeArray[i].end }); 47951 this.customTimeRangeArray[i].end = start; 47952 break; 47953 } else if (start > this.customTimeRangeArray[i].start && start < this.customTimeRangeArray[i].end) { 47954 //|-----------Range i----------| 47955 // |---------Range to remove --------| 47956 // or 47957 //|-----------------Range i----------------| 47958 // |-------Range to remove -----| 47959 this.customTimeRangeArray[i].end = start; 47960 } else if (end > this.customTimeRangeArray[i].start && end < this.customTimeRangeArray[i].end) { 47961 // |-----------Range i----------| 47962 //|---------Range to remove --------| 47963 // or 47964 //|-----------------Range i----------------| 47965 //|-------Range to remove -----| 47966 this.customTimeRangeArray[i].start = end; 47967 } 47968 } 47969 47970 this.length = this.customTimeRangeArray.length; 47971 } 47972 47973 function mergeRanges(rangeIndex1, rangeIndex2) { 47974 var range1 = this.customTimeRangeArray[rangeIndex1]; 47975 var range2 = this.customTimeRangeArray[rangeIndex2]; 47976 47977 if (range1.start <= range2.start && range2.start <= range1.end && range1.end <= range2.end) { 47978 //|-----------Range1----------| 47979 // |-----------Range2----------| 47980 range1.end = range2.end; 47981 this.customTimeRangeArray.splice(rangeIndex2, 1); 47982 return true; 47983 } else if (range2.start <= range1.start && range1.start <= range2.end && range2.end <= range1.end) { 47984 // |-----------Range1----------| 47985 //|-----------Range2----------| 47986 range1.start = range2.start; 47987 this.customTimeRangeArray.splice(rangeIndex2, 1); 47988 return true; 47989 } else if (range2.start <= range1.start && range1.start <= range2.end && range1.end <= range2.end) { 47990 // |--------Range1-------| 47991 //|---------------Range2--------------| 47992 this.customTimeRangeArray.splice(rangeIndex1, 1); 47993 return true; 47994 } else if (range1.start <= range2.start && range2.start <= range1.end && range2.end <= range1.end) { 47995 //|-----------------Range1--------------| 47996 // |-----------Range2----------| 47997 this.customTimeRangeArray.splice(rangeIndex2, 1); 47998 return true; 47999 } 48000 return false; 48001 } 48002 48003 function checkIndex(index) { 48004 var isInt = index !== null && !isNaN(index) && index % 1 === 0; 48005 48006 if (!isInt) { 48007 throw new Error('index argument is not an integer'); 48008 } 48009 } 48010 48011 function start(index) { 48012 checkIndex(index); 48013 48014 if (index >= this.customTimeRangeArray.length || index < 0) { 48015 return NaN; 48016 } 48017 48018 return this.customTimeRangeArray[index].start; 48019 } 48020 48021 function end(index) { 48022 checkIndex(index); 48023 48024 if (index >= this.customTimeRangeArray.length || index < 0) { 48025 return NaN; 48026 } 48027 48028 return this.customTimeRangeArray[index].end; 48029 } 48030 48031 return { 48032 customTimeRangeArray: customTimeRangeArray, 48033 length: length, 48034 add: add, 48035 clear: clear, 48036 remove: remove, 48037 mergeRanges: mergeRanges, 48038 start: start, 48039 end: end 48040 }; 48041} 48042CustomTimeRanges.__dashjs_factory_name = 'CustomTimeRanges'; 48043exports['default'] = _coreFactoryMaker2['default'].getClassFactory(CustomTimeRanges); 48044module.exports = exports['default']; 48045 48046},{"51":51}],193:[function(_dereq_,module,exports){ 48047/** 48048 * The copyright in this software is being made available under the BSD License, 48049 * included below. This software may be subject to other third party and contributor 48050 * rights, including patent rights, and no such rights are granted under this license. 48051 * 48052 * Copyright (c) 2013, Dash Industry Forum. 48053 * All rights reserved. 48054 * 48055 * Redistribution and use in source and binary forms, with or without modification, 48056 * are permitted provided that the following conditions are met: 48057 * * Redistributions of source code must retain the above copyright notice, this 48058 * list of conditions and the following disclaimer. 48059 * * Redistributions in binary form must reproduce the above copyright notice, 48060 * this list of conditions and the following disclaimer in the documentation and/or 48061 * other materials provided with the distribution. 48062 * * Neither the name of Dash Industry Forum nor the names of its 48063 * contributors may be used to endorse or promote products derived from this software 48064 * without specific prior written permission. 48065 * 48066 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 48067 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 48068 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48069 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 48070 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
48070INCLUDING, BUT 48071 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 48072 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 48073 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48074 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 48075 * POSSIBILITY OF SUCH DAMAGE. 48076 */ 48077'use strict'; 48078 48079Object.defineProperty(exports, '__esModule', { 48080 value: true 48081}); 48082 48083function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 48084 48085var _coreFactoryMaker = _dereq_(51); 48086 48087var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 48088 48089var _coreDebug = _dereq_(49); 48090 48091var _coreDebug2 = _interopRequireDefault(_coreDebug); 48092 48093var legacyKeysAndReplacements = [{ oldKey: 'dashjs_vbitrate', newKey: 'dashjs_video_bitrate' }, { oldKey: 'dashjs_abitrate', newKey: 'dashjs_audio_bitrate' }, { oldKey: 'dashjs_vsettings', newKey: 'dashjs_video_settings' }, { oldKey: 'dashjs_asettings', newKey: 'dashjs_audio_settings' }]; 48094 48095var LOCAL_STORAGE_BITRATE_KEY_TEMPLATE = 'dashjs_?_bitrate'; 48096var LOCAL_STORAGE_SETTINGS_KEY_TEMPLATE = 'dashjs_?_settings'; 48097 48098var STORAGE_TYPE_LOCAL = 'localStorage'; 48099var STORAGE_TYPE_SESSION = 'sessionStorage'; 48100var LAST_BITRATE = 'LastBitrate'; 48101var LAST_MEDIA_SETTINGS = 'LastMediaSettings'; 48102 48103function DOMStorage(config) { 48104 48105 var context = this.context; 48106 var log = (0, _coreDebug2['default'])(context).getInstance().log; 48107 var mediaPlayerModel = config.mediaPlayerModel; 48108 48109 var instance = undefined, 48110 supported = undefined; 48111 48112 //type can be local, session 48113 function isSupported(type) { 48114 if (supported !== undefined) return supported; 48115 48116 supported = false; 48117 48118 var testKey = '1'; 48119 var testValue = '1'; 48120 var storage = undefined; 48121 48122 try { 48123 if (typeof window !== 'undefined') { 48124 storage = window[type]; 48125 } 48126 } catch (error) { 48127 log('Warning: DOMStorage access denied: ' + error.message); 48128 return supported; 48129 } 48130 48131 if (!storage || type !== STORAGE_TYPE_LOCAL && type !== STORAGE_TYPE_SESSION) { 48132 return supported; 48133 } 48134 48135 /* When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage is available, but trying to call setItem throws an exception. 48136 http://stackoverflow.com/questions/14555347/html5-localstorage-error-with-safari-quota-exceeded-err-dom-exception-22-an 48137 Check if the storage can be used 48138 */ 48139 try { 48140 storage.setItem(testKey, testValue); 48141 storage.removeItem(testKey); 48142 supported = true; 48143 } catch (error) { 48144 log('Warning: DOMStorage is supported, but cannot be used: ' + error.message); 48145 } 48146 48147 return supported; 48148 } 48149 48150 function translateLegacyKeys() { 48151 if (isSupported(STORAGE_TYPE_LOCAL)) { 48152 legacyKeysAndReplacements.forEach(function (entry) { 48153 var value = localStorage.getItem(entry.oldKey); 48154 48155 if (value) { 48156 localStorage.removeItem(entry.oldKey); 48157 48158 try { 48159 localStorage.setItem(entry.newKey, value); 48160 } catch (e) { 48161 log(e.message); 48162 } 48163 } 48164 }); 48165 } 48166 } 48167 48168 function setup() { 48169 translateLegacyKeys(); 48170 } 48171 48172 // Return current epoch time, ms, rounded to the nearest 10m to avoid fingerprinting user 48173 function getTimestamp() { 48174 var ten_minutes_ms = 60 * 1000 * 10; 48175 return Math.round(new Date().getTime() / ten_minutes_ms) * ten_minutes_ms; 48176 } 48177 48178 function canStore(storageType, key) { 48179 return isSupported(storageType) && mediaPlayerModel['get' + key + 'CachingInfo']().enabled; 48180 } 48181 48182 function checkConfig() { 48183 if (!mediaPlayerModel || !mediaPlayerModel.hasOwnProperty('getLastMediaSettingsCachingInfo')) { 48184 throw new Error('Missing config parameter(s)'); 48185 } 48186 } 48187 48188 function getSavedMediaSettings(type) { 48189 checkConfig(); 48190 //Checks local storage to see if there is valid, non-expired media settings 48191 if (!canStore(STORAGE_TYPE_LOCAL, LAST_MEDIA_SETTINGS)) return null; 48192 48193 var settings = null; 48194 var key = LOCAL_STORAGE_SETTINGS_KEY_TEMPLATE.replace(/\?/, type); 48195 try { 48196 var obj = JSON.parse(localStorage.getItem(key)) || {}; 48197 var isExpired = new Date().getTime() - parseInt(obj.timestamp, 10) >= mediaPlayerModel.getLastMediaSettingsCachingInfo().ttl || false; 48198 settings = obj.settings; 48199 48200 if (isExpired) { 48201 localStorage.removeItem(key); 48202 settings = null; 48203 } 48204 } catch (e) { 48205 return null; 48206 } 48207 return settings; 48208 } 48209 48210 function getSavedBitrateSettings(type) { 48211 var savedBitrate = NaN; 48212 48213 checkConfig(); 48214 48215 //Checks local storage to see if there is valid, non-expired bit rate 48216 //hinting from the last play session to use as a starting bit rate. 48217 if (canStore(STORAGE_TYPE_LOCAL, LAST_BITRATE)) { 48218 var key = LOCAL_STORAGE_BITRATE_KEY_TEMPLATE.replace(/\?/, type); 48219 try { 48220 var obj = JSON.parse(localStorage.getItem(key)) || {}; 48221 var isExpired = new Date().getTime() - parseInt(obj.timestamp, 10) >= mediaPlayerModel.getLastMediaSettingsCachingInfo().ttl || false; 48222 var bitrate = parseFloat(obj.bitrate); 48223 48224 if (!isNaN(bitrate) && !isExpired) { 48225 savedBitrate = bitrate; 48226 log('Last saved bitrate for ' + type + ' was ' + bitrate); 48227 } else if (isExpired) { 48228 localStorage.removeItem(key); 48229 } 48230 } catch (e) { 48231 return null; 48232 } 48233 } 48234 return savedBitrate; 48235 } 48236 48237 function setSavedMediaSettings(type, value) { 48238 if (canStore(STORAGE_TYPE_LOCAL, LAST_MEDIA_SETTINGS)) { 48239 var key = LOCAL_STORAGE_SETTINGS_KEY_TEMPLATE.replace(/\?/, type); 48240 try { 48241 localStorage.setItem(key, JSON.stringify({ settings: value, timestamp: getTimestamp() })); 48242 } catch (e) { 48243 log(e.message); 48244 } 48245 } 48246 } 48247 48248 function setSavedBitrateSettings(type, bitrate) { 48249 if (canStore(STORAGE_TYPE_LOCAL, LAST_BITRATE) && bitrate) { 48250 var key = LOCAL_STORAGE_BITRATE_KEY_TEMPLATE.replace(/\?/, type); 48251 try { 48252 localStorage.setItem(key, JSON.stringify({ bitrate: bitrate.toFixed(3), timestamp: getTimestamp() })); 48253 } catch (e) { 48254 log(e.message); 48255 } 48256 } 48257 } 48258 48259 instance = { 48260 getSavedBitrateSettings: getSavedBitrateSettings, 48261 setSavedBitrateSettings: setSavedBitrateSettings, 48262 getSavedMediaSettings: getSavedMediaSettings, 48263 setSavedMediaSettings: setSavedMediaSettings 48264 }; 48265 48266 setup(); 48267 return instance; 48268} 48269 48270DOMStorage.__dashjs_factory_name = 'DOMStorage'; 48271var factory = _coreFactoryMaker2['default'].getSingletonFactory(DOMStorage); 48272exports['default'] = factory; 48273module.exports = exports['default']; 48274 48275},{"49":49,"51":51}],194:[function(_dereq_,module,exports){ 48276'use strict'; 48277 48278Object.defineProperty(exports, '__esModule', { 48279 value: true 48280}); 48281 48282function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 48283 48284var _coreFactoryMaker = _dereq_(51); 48285 48286var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 48287 48288/** 48289 * Creates an instance of an EBMLParser class which implements a large subset 48290 * of the functionality required to parse Matroska EBML 48291 * 48292 * @param {Object} config object with data member which is the buffer to parse 48293 */ 48294function EBMLParser(config) { 48295 48296 var instance = undefined; 48297 48298 var data = new DataView(config.data); 48299 var pos = 0; 48300 48301 function getPos() { 48302 return pos; 48303 } 48304 48305 function setPos(value) { 48306 pos = value; 48307 } 48308 48309 /** 48310 * Consumes an EBML tag from the data stream. 48311 * 48312 * @param {Object} tag to parse, A tag is an object with at least a {number} tag and 48313 * {boolean} required flag. 48314 * @param {boolean} test whether or not the function should throw if a required 48315 * tag is not found 48316 * @return {boolean} whether or not the tag was found 48317 * @throws will throw an exception if a required tag is not found and test 48318 * param is false or undefined, or if the stream is malformed. 48319 * @memberof EBMLParser 48320 */ 48321 function consumeTag(tag, test) { 48322 var found = true; 48323 var bytesConsumed = 0; 48324 var p1 = undefined, 48325 p2 = undefined; 48326 48327 if (test === undefined) { 48328 test = false; 48329 } 48330 48331 if (tag.tag > 0xFFFFFF) { 48332 if (data.getUint32(pos) !== tag.tag) { 48333 found = false; 48334 } 48335 bytesConsumed = 4; 48336 } else if (tag.tag > 0xFFFF) { 48337 // 3 bytes 48338 p1 = data.getUint16(pos); 48339 p2 = data.getUint8(pos + 2); 48340 48341 // shift p1 over a byte and add p2 48342 if (p1 * 256 + p2 !== tag.tag) { 48343 found = false; 48344 } 48345 bytesConsumed = 3; 48346 } else if (tag.tag > 0xFF) { 48347 if (data.getUint16(pos) !== tag.tag) { 48348 found = false; 48349 } 48350 bytesConsumed = 2; 48351 } else { 48352 if (data.getUint8(pos) !== tag.tag) { 48353 found = false; 48354 } 48355 bytesConsumed = 1; 48356 } 48357 48358 if (!found && tag.required && !test) { 48359 throw new Error('required tag not found'); 48360 } 48361 48362 if (found) { 48363 pos += bytesConsumed; 48364 } 48365 48366 return found; 48367 } 48368 48369 /** 48370 * Consumes an EBML tag from the data stream. If the tag is found then this 48371 * function will also remove the size field which follows the tag from the 48372 * data stream. 48373 * 48374 * @param {Object} tag to parse, A tag is an object with at least a {number} tag and 48375 * {boolean} required flag. 48376 * @param {boolean} test whether or not the function should throw if a required 48377 * tag is not found 48378 * @return {boolean} whether or not the tag was found 48379 * @throws will throw an exception if a required tag is not found and test 48380 * param is false or undefined, or if the stream is malformedata. 48381 * @memberof EBMLParser 48382 */ 48383 function consumeTagAndSize(tag, test) { 48384 var found = consumeTag(tag, test); 48385 48386 if (found) { 48387 getMatroskaCodedNum(); 48388 } 48389 48390 return found; 48391 } 48392 48393 /** 48394 * Consumes an EBML tag from the data stream. If the tag is found then this 48395 * function will also remove the size field which follows the tag from the 48396 * data stream. It will use the value of the size field to parse a binary 48397 * field, using a parser defined in the tag itself 48398 * 48399 * @param {Object} tag to parse, A tag is an object with at least a {number} tag, 48400 * {boolean} required flag, and a parse function which takes a size parameter 48401 * @return {boolean} whether or not the tag was found 48402 * @throws will throw an exception if a required tag is not found, 48403 * or if the stream is malformed 48404 * @memberof EBMLParser 48405 */ 48406 function parseTag(tag) { 48407 var size = undefined; 48408 48409 consumeTag(tag); 48410 size = getMatroskaCodedNum(); 48411 return instance[tag.parse](size); 48412 } 48413 48414 /** 48415 * Consumes an EBML tag from the data stream. If the tag is found then this 48416 * function will also remove the size field which follows the tag from the 48417 * data stream. It will use the value of the size field to skip over the 48418 * entire section of EBML encapsulated by the tag. 48419 * 48420 * @param {Object} tag to parse, A tag is an object with at least a {number} tag, and 48421 * {boolean} required flag 48422 * @param {boolean} test a flag to indicate if an exception should be thrown 48423 * if a required tag is not found 48424 * @return {boolean} whether or not the tag was found 48425 * @throws will throw an exception if a required tag is not found and test is 48426 * false or undefined or if the stream is malformed 48427 * @memberof EBMLParser 48428 */ 48429 function skipOverElement(tag, test) { 48430 var found = consumeTag(tag, test); 48431 var headerSize = undefined; 48432 48433 if (found) { 48434 headerSize = getMatroskaCodedNum(); 48435 pos += headerSize; 48436 } 48437 48438 return found; 48439 } 48440 48441 /** 48442 * Returns and consumes a number encoded according to the Matroska EBML 48443 * specification from the bitstream. 48444 * 48445 * @param {boolean} retainMSB whether or not to retain the Most Significant Bit (the 48446 * first 1). this is usually true when reading Tag IDs. 48447 * @return {number} the decoded number 48448 * @throws will throw an exception if the bit stream is malformed or there is 48449 * not enough data 48450 * @memberof EBMLParser 48451 */ 48452 function getMatroskaCodedNum(retainMSB) { 48453 var bytesUsed = 1; 48454 var mask = 0x80; 48455 var maxBytes = 8; 48456 var extraBytes = -1; 48457 var num = 0; 48458 var ch = data.getUint8(pos); 48459 var i = 0; 48460 48461 for (i = 0; i < maxBytes; i += 1) { 48462 if ((ch & mask) === mask) { 48463 num = retainMSB === undefined ? ch & ~mask : ch; 48464 extraBytes = i; 48465 break; 48466 } 48467 mask >>= 1; 48468 } 48469 48470 for (i = 0; i < extraBytes; i += 1, bytesUsed += 1) { 48471 num = num << 8 | 0xff & data.getUint8(pos + bytesUsed); 48472 } 48473 48474 pos += bytesUsed; 48475 48476 return num; 48477 } 48478 48479 /** 48480 * Returns and consumes a float from the bitstream. 48481 * 48482 * @param {number} size 4 or 8 byte floats are supported 48483 * @return {number} the decoded number 48484 * @throws will throw an exception if the bit stream is malformed or there is 48485 * not enough data 48486 * @memberof EBMLParser 48487 */ 48488 function getMatroskaFloat(size) { 48489 var outFloat = undefined; 48490 48491 switch (size) { 48492 case 4: 48493 outFloat = data.getFloat32(pos); 48494 pos += 4; 48495 break; 48496 case 8: 48497 outFloat = data.getFloat64(pos); 48498 pos += 8; 48499 break; 48500 } 48501 return outFloat; 48502 } 48503 48504 /** 48505 * Consumes and returns an unsigned int from the bitstream. 48506 * 48507 * @param {number} size 1 to 8 bytes 48508 * @return {number} the decoded number 48509 * @throws will throw an exception if the bit stream is malformed or there is 48510 * not enough data 48511 * @memberof EBMLParser 48512 */ 48513 function getMatroskaUint(size) { 48514 var val = 0; 48515 48516 for (var i = 0; i < size; i += 1) { 48517 val <<= 8; 48518 val |= data.getUint8(pos + i) & 0xff; 48519 } 48520 48521 pos += size; 48522 return val; 48523 } 48524 48525 /** 48526 * Tests whether there is more data in the bitstream for parsing 48527 * 48528 * @return {boolean} whether there is more data to parse 48529 * @memberof EBMLParser 48530 */ 48531 function moreData() { 48532 return pos < data.byteLength; 48533 } 48534 48535 instance = { 48536 getPos: getPos, 48537 setPos: setPos, 48538 consumeTag: consumeTag, 48539 consumeTagAndSize: consumeTagAndSize, 48540 parseTag: parseTag,
48541 skipOverElement: skipOverElement, 48542 getMatroskaCodedNum: getMatroskaCodedNum, 48543 getMatroskaFloat: getMatroskaFloat, 48544 getMatroskaUint: getMatroskaUint, 48545 moreData: moreData 48546 }; 48547 48548 return instance; 48549} 48550 48551EBMLParser.__dashjs_factory_name = 'EBMLParser'; 48552exports['default'] = _coreFactoryMaker2['default'].getClassFactory(EBMLParser); 48553module.exports = exports['default']; 48554 48555},{"51":51}],195:[function(_dereq_,module,exports){ 48556/** 48557 * The copyright in this software is being made available under the BSD License, 48558 * included below. This software may be subject to other third party and contributor 48559 * rights, including patent rights, and no such rights are granted under this license. 48560 * 48561 * Copyright (c) 2013, Dash Industry Forum. 48562 * All rights reserved. 48563 * 48564 * Redistribution and use in source and binary forms, with or without modification, 48565 * are permitted provided that the following conditions are met: 48566 * * Redistributions of source code must retain the above copyright notice, this 48567 * list of conditions and the following disclaimer. 48568 * * Redistributions in binary form must reproduce the above copyright notice, 48569 * this list of conditions and the following disclaimer in the documentation and/or 48570 * other materials provided with the distribution. 48571 * * Neither the name of Dash Industry Forum nor the names of its 48572 * contributors may be used to endorse or promote products derived from this software 48573 * without specific prior written permission. 48574 * 48575 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 48576 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 48577 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48578 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 48579 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 48580 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 48581 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 48582 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48583 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 48584 * POSSIBILITY OF SUCH DAMAGE. 48585 */ 48586'use strict'; 48587 48588Object.defineProperty(exports, '__esModule', { 48589 value: true 48590}); 48591 48592function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 48593 48594var _coreEventBus = _dereq_(50); 48595 48596var _coreEventBus2 = _interopRequireDefault(_coreEventBus); 48597 48598var _coreEventsEvents = _dereq_(54); 48599 48600var _coreEventsEvents2 = _interopRequireDefault(_coreEventsEvents); 48601 48602var _coreFactoryMaker = _dereq_(51); 48603 48604var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 48605 48606var CAPABILITY_ERROR_MEDIASOURCE = 'mediasource'; 48607var CAPABILITY_ERROR_MEDIAKEYS = 'mediakeys'; 48608 48609var DOWNLOAD_ERROR_ID_MANIFEST = 'manifest'; 48610var DOWNLOAD_ERROR_ID_SIDX = 'SIDX'; 48611var DOWNLOAD_ERROR_ID_CONTENT = 'content'; 48612var DOWNLOAD_ERROR_ID_INITIALIZATION = 'initialization'; 48613var DOWNLOAD_ERROR_ID_XLINK = 'xlink'; 48614 48615var MANIFEST_ERROR_ID_CODEC = 'codec'; 48616var MANIFEST_ERROR_ID_PARSE = 'parse'; 48617var MANIFEST_ERROR_ID_NOSTREAMS = 'nostreams'; 48618 48619var TIMED_TEXT_ERROR_ID_PARSE = 'parse'; 48620 48621function ErrorHandler() { 48622 48623 var instance = undefined; 48624 var context = this.context; 48625 var eventBus = (0, _coreEventBus2['default'])(context).getInstance(); 48626 48627 // "mediasource"|"mediakeys" 48628 function capabilityError(err) { 48629 eventBus.trigger(_coreEventsEvents2['default'].ERROR, { error: 'capability', event: err }); 48630 } 48631 48632 // {id: "manifest"|"SIDX"|"content"|"initialization"|"xlink", url: "", request: {XMLHttpRequest instance}} 48633 function downloadError(id, url, request) { 48634 eventBus.trigger(_coreEventsEvents2['default'].ERROR, { error: 'download', event: { id: id, url: url, request: request } }); 48635 } 48636 48637 // {message: "", id: "codec"|"parse"|"nostreams", manifest: {parsed manifest}} 48638 function manifestError(message, id, manifest, err) { 48639 eventBus.trigger(_coreEventsEvents2['default'].ERROR, { error: 'manifestError', event: { message: message, id: id, manifest: manifest, event: err } }); 48640 } 48641 48642 // {message: '', id: 'parse', cc: ''} 48643 function timedTextError(message, id, ccContent) { 48644 eventBus.trigger(_coreEventsEvents2['default'].ERROR, { error: 'cc', event: { message: message, id: id, cc: ccContent } }); 48645 } 48646 48647 function mediaSourceError(err) { 48648 eventBus.trigger(_coreEventsEvents2['default'].ERROR, { error: 'mediasource', event: err }); 48649 } 48650 48651 function mediaKeySessionError(err) { 48652 eventBus.trigger(_coreEventsEvents2['default'].ERROR, { error: 'key_session', event: err }); 48653 } 48654 48655 function mediaKeyMessageError(err) { 48656 eventBus.trigger(_coreEventsEvents2['default'].ERROR, { error: 'key_message', event: err }); 48657 } 48658 48659 instance = { 48660 capabilityError: capabilityError, 48661 downloadError: downloadError, 48662 manifestError: manifestError, 48663 timedTextError: timedTextError, 48664 mediaSourceError: mediaSourceError, 48665 mediaKeySessionError: mediaKeySessionError, 48666 mediaKeyMessageError: mediaKeyMessageError 48667 }; 48668 48669 return instance; 48670} 48671 48672ErrorHandler.__dashjs_factory_name = 'ErrorHandler'; 48673 48674var factory = _coreFactoryMaker2['default'].getSingletonFactory(ErrorHandler); 48675 48676factory.CAPABILITY_ERROR_MEDIASOURCE = CAPABILITY_ERROR_MEDIASOURCE; 48677factory.CAPABILITY_ERROR_MEDIAKEYS = CAPABILITY_ERROR_MEDIAKEYS; 48678factory.DOWNLOAD_ERROR_ID_MANIFEST = DOWNLOAD_ERROR_ID_MANIFEST; 48679factory.DOWNLOAD_ERROR_ID_SIDX = DOWNLOAD_ERROR_ID_SIDX; 48680factory.DOWNLOAD_ERROR_ID_CONTENT = DOWNLOAD_ERROR_ID_CONTENT; 48681factory.DOWNLOAD_ERROR_ID_INITIALIZATION = DOWNLOAD_ERROR_ID_INITIALIZATION; 48682factory.DOWNLOAD_ERROR_ID_XLINK = DOWNLOAD_ERROR_ID_XLINK; 48683factory.MANIFEST_ERROR_ID_CODEC = MANIFEST_ERROR_ID_CODEC; 48684factory.MANIFEST_ERROR_ID_PARSE = MANIFEST_ERROR_ID_PARSE; 48685factory.MANIFEST_ERROR_ID_NOSTREAMS = MANIFEST_ERROR_ID_NOSTREAMS; 48686factory.TIMED_TEXT_ERROR_ID_PARSE = TIMED_TEXT_ERROR_ID_PARSE; 48687 48688_coreFactoryMaker2['default'].updateSingletonFactory(ErrorHandler.__dashjs_factory_name, factory); 48689 48690exports['default'] = factory; 48691module.exports = exports['default']; 48692 48693},{"50":50,"51":51,"54":54}],196:[function(_dereq_,module,exports){ 48694/** 48695 * The copyright in this software is being made available under the BSD License, 48696 * included below. This software may be subject to other third party and contributor 48697 * rights, including patent rights, and no such rights are granted under this license. 48698 * 48699 * Copyright (c) 2013, Dash Industry Forum. 48700 * All rights reserved. 48701 * 48702 * Redistribution and use in source and binary forms, with or without modification, 48703 * are permitted provided that the following conditions are met: 48704 * * Redistributions of source code must retain the above copyright notice, this 48705 * list of conditions and the following disclaimer. 48706 * * Redistributions in binary form must reproduce the above copyright notice, 48707 * this list of conditions and the following disclaimer in the documentation and/or 48708 * other materials provided with the distribution. 48709 * * Neither the name of Dash Industry Forum nor the names of its 48710 * contributors may be used to endorse or promote products derived from this software 48711 * without specific prior written permission. 48712 * 48713 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 48714 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 48715 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48716 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 48717 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
48717INCLUDING, BUT 48718 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 48719 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 48720 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48721 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 48722 * POSSIBILITY OF SUCH DAMAGE. 48723 */ 48724 48725/** 48726 * Represents data structure to keep and drive {DataChunk} 48727 */ 48728 48729'use strict'; 48730 48731Object.defineProperty(exports, '__esModule', { 48732 value: true 48733}); 48734 48735function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 48736 48737var _coreFactoryMaker = _dereq_(51); 48738 48739var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 48740 48741function InitCache() { 48742 48743 var data = {}; 48744 48745 function save(chunk) { 48746 var id = chunk.streamId; 48747 var representationId = chunk.representationId; 48748 48749 data[id] = data[id] || {}; 48750 data[id][representationId] = chunk; 48751 } 48752 48753 function extract(streamId, representationId) { 48754 if (data && data[streamId] && data[streamId][representationId]) { 48755 return data[streamId][representationId]; 48756 } else { 48757 return null; 48758 } 48759 } 48760 48761 function reset() { 48762 data = {}; 48763 } 48764 48765 var instance = { 48766 save: save, 48767 extract: extract, 48768 reset: reset 48769 }; 48770 48771 return instance; 48772} 48773 48774InitCache.__dashjs_factory_name = 'InitCache'; 48775exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(InitCache); 48776module.exports = exports['default']; 48777 48778},{"51":51}],197:[function(_dereq_,module,exports){ 48779/** 48780 * The copyright in this software is being made available under the BSD License, 48781 * included below. This software may be subject to other third party and contributor 48782 * rights, including patent rights, and no such rights are granted under this license. 48783 * 48784 * Copyright (c) 2013, Dash Industry Forum. 48785 * All rights reserved. 48786 * 48787 * Redistribution and use in source and binary forms, with or without modification, 48788 * are permitted provided that the following conditions are met: 48789 * * Redistributions of source code must retain the above copyright notice, this 48790 * list of conditions and the following disclaimer. 48791 * * Redistributions in binary form must reproduce the above copyright notice, 48792 * this list of conditions and the following disclaimer in the documentation and/or 48793 * other materials provided with the distribution. 48794 * * Neither the name of Dash Industry Forum nor the names of its 48795 * contributors may be used to endorse or promote products derived from this software 48796 * without specific prior written permission. 48797 * 48798 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 48799 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 48800 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48801 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 48802 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 48803 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 48804 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 48805 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48806 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 48807 * POSSIBILITY OF SUCH DAMAGE. 48808 */ 48809 48810'use strict'; 48811 48812Object.defineProperty(exports, '__esModule', { 48813 value: true 48814}); 48815 48816function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 48817 48818var _voIsoBox = _dereq_(211); 48819 48820var _voIsoBox2 = _interopRequireDefault(_voIsoBox); 48821 48822var _coreFactoryMaker = _dereq_(51); 48823 48824var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 48825 48826function IsoFile() { 48827 48828 var instance = undefined, 48829 parsedIsoFile = undefined; 48830 48831 /** 48832 * @param {string} type 48833 * @returns {IsoBox|null} 48834 * @memberof IsoFile# 48835 */ 48836 function getBox(type) { 48837 if (!type || !parsedIsoFile || !parsedIsoFile.boxes || parsedIsoFile.boxes.length === 0 || typeof parsedIsoFile.fetch !== 'function') return null; 48838 48839 return convertToDashIsoBox(parsedIsoFile.fetch(type)); 48840 } 48841 48842 /** 48843 * @param {string} type 48844 * @returns {Array|null} array of {@link IsoBox} 48845 * @memberof IsoFile# 48846 */ 48847 function getBoxes(type) { 48848 var boxes = []; 48849 48850 if (!type || !parsedIsoFile || typeof parsedIsoFile.fetchAll !== 'function') { 48851 return boxes; 48852 } 48853 48854 var boxData = parsedIsoFile.fetchAll(type); 48855 var box = undefined; 48856 48857 for (var i = 0, ln = boxData.length; i < ln; i++) { 48858 box = convertToDashIsoBox(boxData[i]); 48859 48860 if (box) { 48861 boxes.push(box); 48862 } 48863 } 48864 48865 return boxes; 48866 } 48867 48868 /** 48869 * @param {string} value 48870 * @memberof IsoFile# 48871 */ 48872 function setData(value) { 48873 parsedIsoFile = value; 48874 } 48875 48876 /** 48877 * @returns {IsoBox|null} 48878 * @memberof IsoFile# 48879 */ 48880 function getLastBox() { 48881 if (!parsedIsoFile || !parsedIsoFile.boxes || !parsedIsoFile.boxes.length) return null; 48882 48883 var type = parsedIsoFile.boxes[parsedIsoFile.boxes.length - 1].type; 48884 var boxes = getBoxes(type); 48885 48886 return boxes.length > 0 ? boxes[boxes.length - 1] : null; 48887 } 48888 48889 function convertToDashIsoBox(boxData) { 48890 if (!boxData) return null; 48891 48892 var box = new _voIsoBox2['default'](boxData); 48893 48894 if (boxData.hasOwnProperty('_incomplete')) { 48895 box.isComplete = !boxData._incomplete; 48896 } 48897 48898 return box; 48899 } 48900 48901 instance = { 48902 getBox: getBox, 48903 getBoxes: getBoxes, 48904 setData: setData, 48905 getLastBox: getLastBox 48906 }; 48907 48908 return instance; 48909} 48910IsoFile.__dashjs_factory_name = 'IsoFile'; 48911exports['default'] = _coreFactoryMaker2['default'].getClassFactory(IsoFile); 48912module.exports = exports['default']; 48913 48914},{"211":211,"51":51}],198:[function(_dereq_,module,exports){ 48915/** 48916 * The copyright in this software is being made available under the BSD License, 48917 * included below. This software may be subject to other third party and contributor 48918 * rights, including patent rights, and no such rights are granted under this license. 48919 * 48920 * Copyright (c) 2013, Dash Industry Forum. 48921 * All rights reserved. 48922 * 48923 * Redistribution and use in source and binary forms, with or without modification, 48924 * are permitted provided that the following conditions are met: 48925 * * Redistributions of source code must retain the above copyright notice, this 48926 * list of conditions and the following disclaimer. 48927 * * Redistributions in binary form must reproduce the above copyright notice, 48928 * this list of conditions and the following disclaimer in the documentation and/or 48929 * other materials provided with the distribution. 48930 * * Neither the name of Dash Industry Forum nor the names of its 48931 * contributors may be used to endorse or promote products derived from this software 48932 * without specific prior written permission. 48933 * 48934 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 48935 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 48936 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48937 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 48938 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
48938INCLUDING, BUT 48939 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 48940 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 48941 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48942 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 48943 * POSSIBILITY OF SUCH DAMAGE. 48944 */ 48945'use strict'; 48946 48947Object.defineProperty(exports, '__esModule', { 48948 value: true 48949}); 48950 48951function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 48952 48953var _coreFactoryMaker = _dereq_(51); 48954 48955var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 48956 48957/** 48958 * @param {Object} config 48959 * @returns {{initialize: initialize, getLiveEdge: getLiveEdge, reset: reset}|*} 48960 * @constructor 48961 */ 48962function LiveEdgeFinder(config) { 48963 48964 var instance = undefined; 48965 var timelineConverter = config.timelineConverter; 48966 var streamProcessor = config.streamProcessor; 48967 48968 function checkConfig() { 48969 if (!timelineConverter || !timelineConverter.hasOwnProperty('getExpectedLiveEdge') || !streamProcessor || !streamProcessor.hasOwnProperty('getCurrentRepresentationInfo')) { 48970 throw new Error('Missing config parameter(s)'); 48971 } 48972 } 48973 48974 function getLiveEdge() { 48975 checkConfig(); 48976 var representationInfo = streamProcessor.getCurrentRepresentationInfo(); 48977 var liveEdge = representationInfo.DVRWindow.end; 48978 if (representationInfo.useCalculatedLiveEdgeTime) { 48979 liveEdge = timelineConverter.getExpectedLiveEdge(); 48980 timelineConverter.setClientTimeOffset(liveEdge - representationInfo.DVRWindow.end); 48981 } 48982 return liveEdge; 48983 } 48984 48985 function reset() { 48986 timelineConverter = null; 48987 streamProcessor = null; 48988 } 48989 48990 instance = { 48991 getLiveEdge: getLiveEdge, 48992 reset: reset 48993 }; 48994 48995 return instance; 48996} 48997 48998LiveEdgeFinder.__dashjs_factory_name = 'LiveEdgeFinder'; 48999exports['default'] = _coreFactoryMaker2['default'].getClassFactory(LiveEdgeFinder); 49000module.exports = exports['default']; 49001 49002},{"51":51}],199:[function(_dereq_,module,exports){ 49003/** 49004 * The copyright in this software is being made available under the BSD License, 49005 * included below. This software may be subject to other third party and contributor 49006 * rights, including patent rights, and no such rights are granted under this license. 49007 * 49008 * Copyright (c) 2013, Dash Industry Forum. 49009 * All rights reserved. 49010 * 49011 * Redistribution and use in source and binary forms, with or without modification, 49012 * are permitted provided that the following conditions are met: 49013 * * Redistributions of source code must retain the above copyright notice, this 49014 * list of conditions and the following disclaimer. 49015 * * Redistributions in binary form must reproduce the above copyright notice, 49016 * this list of conditions and the following disclaimer in the documentation and/or 49017 * other materials provided with the distribution. 49018 * * Neither the name of Dash Industry Forum nor the names of its 49019 * contributors may be used to endorse or promote products derived from this software 49020 * without specific prior written permission. 49021 * 49022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 49023 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 49024 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49025 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49026 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 49027 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 49028 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 49029 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49030 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49031 * POSSIBILITY OF SUCH DAMAGE. 49032 */ 49033 49034'use strict'; 49035 49036Object.defineProperty(exports, '__esModule', { 49037 value: true 49038}); 49039 49040function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 49041 49042var _coreFactoryMaker = _dereq_(51); 49043 49044var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 49045 49046var _deepEqual = _dereq_(13); 49047 49048var _deepEqual2 = _interopRequireDefault(_deepEqual); 49049 49050/**
49051 * @module ObjectUtils 49052 * @description Provides utility functions for objects 49053 */ 49054function ObjectUtils() { 49055 49056 var instance = undefined; 49057 49058 /** 49059 * Returns true if objects are equal 49060 * @return {boolean} 49061 * @param {object} obj1 49062 * @param {object} obj2 49063 * @memberof module:ObjectUtils 49064 * @instance 49065 */ 49066 function areEqual(obj1, obj2) { 49067 return (0, _deepEqual2['default'])(obj1, obj2); 49068 } 49069 49070 instance = { 49071 areEqual: areEqual 49072 }; 49073 49074 return instance; 49075} 49076 49077ObjectUtils.__dashjs_factory_name = 'ObjectUtils'; 49078exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(ObjectUtils); 49079module.exports = exports['default']; 49080 49081},{"13":13,"51":51}],200:[function(_dereq_,module,exports){ 49082/** 49083 * The copyright in this software is being made available under the BSD License, 49084 * included below. This software may be subject to other third party and contributor 49085 * rights, including patent rights, and no such rights are granted under this license. 49086 * 49087 * Copyright (c) 2013, Dash Industry Forum. 49088 * All rights reserved. 49089 * 49090 * Redistribution and use in source and binary forms, with or without modification, 49091 * are permitted provided that the following conditions are met: 49092 * * Redistributions of source code must retain the above copyright notice, this 49093 * list of conditions and the following disclaimer. 49094 * * Redistributions in binary form must reproduce the above copyright notice, 49095 * this list of conditions and the following disclaimer in the documentation and/or 49096 * other materials provided with the distribution. 49097 * * Neither the name of Dash Industry Forum nor the names of its 49098 * contributors may be used to endorse or promote products derived from this software 49099 * without specific prior written permission. 49100 * 49101 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 49102 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 49103 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49104 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49105 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 49106 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 49107 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 49108 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49109 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49110 * POSSIBILITY OF SUCH DAMAGE. 49111 */ 49112 49113'use strict'; 49114 49115Object.defineProperty(exports, '__esModule', { 49116 value: true 49117}); 49118 49119function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 49120 49121var _coreFactoryMaker = _dereq_(51); 49122 49123var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 49124 49125function RequestModifier() { 49126 49127 var instance = undefined; 49128 49129 function modifyRequestURL(url) { 49130 return url; 49131 } 49132 49133 function modifyRequestHeader(request) { 49134 return request; 49135 } 49136 49137 instance = { 49138 modifyRequestURL: modifyRequestURL, 49139 modifyRequestHeader: modifyRequestHeader 49140 }; 49141 49142 return instance; 49143} 49144 49145RequestModifier.__dashjs_factory_name = 'RequestModifier'; 49146exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(RequestModifier); 49147module.exports = exports['default']; 49148 49149},{"51":51}],201:[function(_dereq_,module,exports){ 49150/** 49151 * The copyright in this software is being made available under the BSD License, 49152 * included below. This software may be subject to other third party and contributor 49153 * rights, including patent rights, and no such rights are granted under this license. 49154 * 49155 * Copyright (c) 2013, Dash Industry Forum. 49156 * All rights reserved. 49157 * 49158 * Redistribution and use in source and binary forms, with or without modification, 49159 * are permitted provided that the following conditions are met: 49160 * * Redistributions of source code must retain the above copyright notice, this 49161 * list of conditions and the following disclaimer. 49162 * * Redistributions in binary form must reproduce the above copyright notice, 49163 * this list of conditions and the following disclaimer in the documentation and/or 49164 * other materials provided with the distribution. 49165 * * Neither the name of Dash Industry Forum nor the names of its 49166 * contributors may be used to endorse or promote products derived from this software 49167 * without specific prior written permission. 49168 * 49169 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 49170 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 49171 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49172 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49173 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
49173INCLUDING, BUT 49174 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 49175 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 49176 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49177 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49178 * POSSIBILITY OF SUCH DAMAGE. 49179 */ 49180'use strict'; 49181 49182Object.defineProperty(exports, '__esModule', { 49183 value: true 49184}); 49185 49186function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 49187 49188var _coreFactoryMaker = _dereq_(51); 49189 49190var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 49191 49192var _coreDebug = _dereq_(49); 49193 49194var _coreDebug2 = _interopRequireDefault(_coreDebug); 49195 49196var _imsc = _dereq_(21); 49197 49198function TTMLParser() { 49199 49200 var context = this.context; 49201 var log = (0, _coreDebug2['default'])(context).getInstance().log; 49202 49203 /* 49204 * This TTML parser follows "EBU-TT-D SUBTITLING DISTRIBUTION FORMAT - tech3380" spec - https://tech.ebu.ch/docs/tech/tech3380.pdf. 49205 * */ 49206 var instance = undefined; 49207 49208 var cueCounter = 0; // Used to give every cue a unique ID. 49209 49210 function getCueID() { 49211 var id = 'cue_TTML_' + cueCounter; 49212 cueCounter++; 49213 return id; 49214 } 49215 49216 /** 49217 * Parse the raw data and process it to return the HTML element representing the cue. 49218 * Return the region to be processed and controlled (hide/show) by the caption controller. 49219 * @param {string} data - raw data received from the TextSourceBuffer 49220 * @param {number} offsetTime - offset time to apply to cue time 49221 * @param {integer} startTimeSegment - startTime for the current segment 49222 * @param {integer} endTimeSegment - endTime for the current segment 49223 * @param {Array} images - images array referenced by subs MP4 box 49224 */ 49225 function parse(data, offsetTime, startTimeSegment, endTimeSegment, images) { 49226 var i = undefined, 49227 j = undefined; 49228 49229 var errorMsg = ''; 49230 var captionArray = []; 49231 var startTime = undefined, 49232 endTime = undefined; 49233 49234 var embeddedImages = {}; 49235 var currentImageId = ''; 49236 var accumulated_image_data = ''; 49237 var metadataHandler = { 49238 49239 onOpenTag: function onOpenTag(ns, name, attrs) { 49240 if (name === 'image' && ns === 'http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt') { 49241 if (!attrs[' imagetype'] || attrs[' imagetype'].value !== 'PNG') { 49242 log('Warning: smpte-tt imagetype != PNG. Discarded'); 49243 return; 49244 } 49245 currentImageId = attrs['http://www.w3.org/XML/1998/namespace id'].value; 49246 } 49247 }, 49248 49249 onCloseTag: function onCloseTag() { 49250 if (currentImageId) { 49251 embeddedImages[currentImageId] = accumulated_image_data.trim(); 49252 } 49253 accumulated_image_data = ''; 49254 currentImageId = ''; 49255 }, 49256 49257 onText: function onText(contents) { 49258 if (currentImageId) { 49259 accumulated_image_data = accumulated_image_data + contents; 49260 } 49261 } 49262 }; 49263 49264 if (!data) { 49265 errorMsg = 'no ttml data to parse'; 49266 throw new Error(errorMsg); 49267 } 49268 49269 var imsc1doc = (0, _imsc.fromXML)(data, function (msg) { 49270 errorMsg = msg; 49271 }, metadataHandler); 49272 var mediaTimeEvents = imsc1doc.getMediaTimeEvents(); 49273 49274 for (i = 0; i < mediaTimeEvents.length; i++) { 49275 var isd = (0, _imsc.generateISD)(imsc1doc, mediaTimeEvents[i], function (error) { 49276 errorMsg = error; 49277 }); 49278 for (j = 0; j < isd.contents.length; j++) { 49279 if (isd.contents[j].contents.length >= 1) { 49280 //be sure that mediaTimeEvents values are in the mp4 segment time ranges. 49281 startTime = mediaTimeEvents[i] + offsetTime < startTimeSegment ? startTimeSegment : mediaTimeEvents[i] + offsetTime; 49282 endTime = mediaTimeEvents[i + 1] + offsetTime > endTimeSegment ? endTimeSegment : mediaTimeEvents[i + 1] + offsetTime; 49283 49284 captionArray.push({ 49285 start: startTime, 49286 end: endTime, 49287 type: 'html', 49288 cueID: getCueID(), 49289 isd: isd, 49290 images: images, 49291 embeddedImages: embeddedImages 49292 }); 49293 } 49294 } 49295 } 49296 49297 if (errorMsg !== '') { 49298 log(errorMsg); 49299 } 49300 49301 if (captionArray.length > 0) { 49302 return captionArray; 49303 } else { 49304 // This seems too strong given that there are segments with no TTML subtitles 49305 throw new Error(errorMsg); 49306 } 49307 } 49308 49309 function setup() {} 49310 49311 instance = { 49312 parse: parse 49313 }; 49314 49315 setup(); 49316 return instance; 49317} 49318TTMLParser.__dashjs_factory_name = 'TTMLParser'; 49319exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(TTMLParser); 49320module.exports = exports['default']; 49321 49322},{"21":21,"49":49,"51":51}],202:[function(_dereq_,module,exports){ 49323/** 49324 * The copyright in this software is being made available under the BSD License, 49325 * included below. This software may be subject to other third party and contributor 49326 * rights, including patent rights, and no such rights are granted under this license. 49327 * 49328 * Copyright (c) 2013, Dash Industry Forum. 49329 * All rights reserved. 49330 * 49331 * Redistribution and use in source and binary forms, with or without modification, 49332 * are permitted provided that the following conditions are met: 49333 * * Redistributions of source code must retain the above copyright notice, this 49334 * list of conditions and the following disclaimer. 49335 * * Redistributions in binary form must reproduce the above copyright notice, 49336 * this list of conditions and the following disclaimer in the documentation and/or 49337 * other materials provided with the distribution. 49338 * * Neither the name of Dash Industry Forum nor the names of its 49339 * contributors may be used to endorse or promote products derived from this software 49340 * without specific prior written permission. 49341 * 49342 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 49343 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 49344 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49345 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49346 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
49346INCLUDING, BUT 49347 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 49348 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 49349 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49350 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49351 * POSSIBILITY OF SUCH DAMAGE. 49352 */ 49353 49354'use strict'; 49355 49356Object.defineProperty(exports, '__esModule', { 49357 value: true 49358}); 49359 49360function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 49361 49362var _coreFactoryMaker = _dereq_(51); 49363 49364var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 49365 49366/** 49367 * @module URLUtils 49368 * @description Provides utility functions for operating on URLs. 49369 * Initially this is simply a method to determine the Base URL of a URL, but 49370 * should probably include other things provided all over the place such as 49371 * determining whether a URL is relative/absolute, resolving two paths etc. 49372 */ 49373function URLUtils() { 49374 49375 var resolveFunction = undefined; 49376 49377 var schemeRegex = /^[a-z][a-z0-9+\-.]*:/i; 49378 var httpUrlRegex = /^https?:\/\//i; 49379 var originRegex = /^([a-z][a-z0-9+\-.]*:\/\/[^\/]+)\/?/i; 49380 49381 /** 49382 * Resolves a url given an optional base url 49383 * Uses window.URL to do the resolution. 49384 * 49385 * @param {string} url 49386 * @param {string} [baseUrl] 49387 * @return {string} 49388 * @memberof module:URLUtils 49389 * @instance 49390 * @private 49391 */ 49392 var nativeURLResolver = function nativeURLResolver(url, baseUrl) { 49393 try { 49394 // this will throw if baseurl is undefined, invalid etc 49395 return new window.URL(url, baseUrl).toString(); 49396 } catch (e) { 49397 return url; 49398 } 49399 }; 49400 49401 /** 49402 * Resolves a url given an optional base url 49403 * Does not resolve ./, ../ etc but will do enough to construct something 49404 * which will satisfy XHR etc when window.URL is not available ie 49405 * IE11/node etc. 49406 * 49407 * @param {string} url 49408 * @param {string} [baseUrl] 49409 * @return {string} 49410 * @memberof module:URLUtils 49411 * @instance 49412 * @private 49413 */ 49414 var dumbURLResolver = function dumbURLResolver(url, baseUrl) { 49415 var baseUrlParseFunc = parseBaseUrl; 49416 49417 if (!baseUrl) { 49418 return url; 49419 } 49420 49421 if (!isRelative(url)) { 49422 return url; 49423 } 49424 49425 if (isPathAbsolute(url)) { 49426 baseUrlParseFunc = parseOrigin; 49427 } 49428 49429 if (isSchemeRelative(url)) { 49430 baseUrlParseFunc = parseScheme; 49431 } 49432 49433 var base = baseUrlParseFunc(baseUrl); 49434 var joinChar = base.charAt(base.length - 1) !== '/' && url.charAt(0) !== '/' ? '/' : ''; 49435 49436 return [base, url].join(joinChar); 49437 }; 49438 49439 function setup() { 49440 try { 49441 var u = new window.URL('x', 'http://y'); //jshint ignore:line 49442 resolveFunction = nativeURLResolver; 49443 } catch (e) { 49444 // must be IE11/Node etc 49445 } finally { 49446 resolveFunction = resolveFunction || dumbURLResolver; 49447 } 49448 } 49449 49450 /** 49451 * Returns a string that contains the Base URL of a URL, if determinable. 49452 * @param {string} url - full url 49453 * @return {string} 49454 * @memberof module:URLUtils 49455 * @instance 49456 */ 49457 function parseBaseUrl(url) { 49458 var slashIndex = url.indexOf('/'); 49459 var lastSlashIndex = url.lastIndexOf('/'); 49460 49461 if (slashIndex !== -1) { 49462 // if there is only '//' 49463 if (lastSlashIndex === slashIndex + 1) { 49464 return url; 49465 } 49466 49467 if (url.indexOf('?') !== -1) { 49468 url = url.substring(0, url.indexOf('?')); 49469 } 49470 49471 return url.substring(0, lastSlashIndex + 1); 49472 } 49473 49474 return ''; 49475 } 49476 49477 /** 49478 * Returns a string that contains the scheme and origin of a URL, 49479 * if determinable. 49480 * @param {string} url - full url 49481 * @return {string} 49482 * @memberof module:URLUtils 49483 * @instance 49484 */ 49485 function parseOrigin(url) { 49486 var matches = url.match(originRegex); 49487 49488 if (matches) { 49489 return matches[1]; 49490 } 49491 49492 return ''; 49493 } 49494 49495 /** 49496 * Returns a string that contains the scheme of a URL, if determinable. 49497 * @param {string} url - full url 49498 * @return {string} 49499 * @memberof module:URLUtils 49500 * @instance 49501 */ 49502 function parseScheme(url) { 49503 var matches = url.match(schemeRegex); 49504 49505 if (matches) { 49506 return matches[0]; 49507 } 49508 49509 return ''; 49510 } 49511 49512 /** 49513 * Determines whether the url is relative. 49514 * @return {bool} 49515 * @param {string} url 49516 * @memberof module:URLUtils 49517 * @instance 49518 */ 49519 function isRelative(url) { 49520 return !schemeRegex.test(url); 49521 } 49522 49523 /** 49524 * Determines whether the url is path-absolute. 49525 * @return {bool} 49526 * @param {string} url 49527 * @memberof module:URLUtils 49528 * @instance 49529 */ 49530 function isPathAbsolute(url) { 49531 return isRelative(url) && url.charAt(0) === '/'; 49532 } 49533 49534 /** 49535 * Determines whether the url is scheme-relative. 49536 * @return {bool} 49537 * @param {string} url 49538 * @memberof module:URLUtils 49539 * @instance 49540 */ 49541 function isSchemeRelative(url) { 49542 return url.indexOf('//') === 0; 49543 } 49544 49545 /** 49546 * Determines whether the url is an HTTP-URL as defined in ISO/IEC 49547 * 23009-1:2014 3.1.15. ie URL with a fixed scheme of http or https 49548 * @return {bool} 49549 * @param {string} url 49550 * @memberof module:URLUtils 49551 * @instance 49552 */ 49553 function isHTTPURL(url) { 49554 return httpUrlRegex.test(url); 49555 } 49556 49557 /** 49558 * Resolves a url given an optional base url 49559 * @return {string} 49560 * @param {string} url 49561 * @param {string} [baseUrl] 49562 * @memberof module:URLUtils 49563 * @instance 49564 */ 49565 function resolve(url, baseUrl) { 49566 return resolveFunction(url, baseUrl); 49567 } 49568 49569 setup(); 49570 49571 var instance = { 49572 parseBaseUrl: parseBaseUrl, 49573 parseOrigin: parseOrigin, 49574 parseScheme: parseScheme, 49575 isRelative: isRelative, 49576 isPathAbsolute: isPathAbsolute, 49577 isSchemeRelative: isSchemeRelative, 49578 isHTTPURL: isHTTPURL, 49579 resolve: resolve 49580 }; 49581 49582 return instance; 49583} 49584 49585URLUtils.__dashjs_factory_name = 'URLUtils'; 49586exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(URLUtils); 49587module.exports = exports['default']; 49588 49589},{"51":51}],203:[function(_dereq_,module,exports){ 49590/** 49591 * The copyright in this software is being made available under the BSD License, 49592 * included below. This software may be subject to other third party and contributor 49593 * rights, including patent rights, and no such rights are granted under this license. 49594 * 49595 * Copyright (c) 2013, Dash Industry Forum. 49596 * All rights reserved. 49597 * 49598 * Redistribution and use in source and binary forms, with or without modification, 49599 * are permitted provided that the following conditions are met: 49600 * * Redistributions of source code must retain the above copyright notice, this 49601 * list of conditions and the following disclaimer. 49602 * * Redistributions in binary form must reproduce the above copyright notice, 49603 * this list of conditions and the following disclaimer in the documentation and/or 49604 * other materials provided with the distribution. 49605 * * Neither the name of Dash Industry Forum nor the names of its 49606 * contributors may be used to endorse or promote products derived from this software 49607 * without specific prior written permission. 49608 * 49609 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 49610 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 49611 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49612 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49613 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
49613INCLUDING, BUT 49614 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 49615 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 49616 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49617 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49618 * POSSIBILITY OF SUCH DAMAGE. 49619 */ 49620'use strict'; 49621 49622Object.defineProperty(exports, '__esModule', { 49623 value: true 49624}); 49625 49626function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 49627 49628var _coreFactoryMaker = _dereq_(51); 49629 49630var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 49631 49632var _coreDebug = _dereq_(49); 49633 49634var _coreDebug2 = _interopRequireDefault(_coreDebug); 49635 49636var WEBVTT = 'WEBVTT'; 49637 49638function VTTParser() { 49639 var context = this.context; 49640 var log = (0, _coreDebug2['default'])(context).getInstance().log; 49641 49642 var instance = undefined, 49643 regExNewLine = undefined, 49644 regExToken = undefined, 49645 regExWhiteSpace = undefined, 49646 regExWhiteSpaceWordBoundary = undefined; 49647 49648 function setup() { 49649 regExNewLine = /(?:\r\n|\r|\n)/gm; 49650 regExToken = /-->/; 49651 regExWhiteSpace = /(^[\s]+|[\s]+$)/g; 49652 regExWhiteSpaceWordBoundary = /\s\b/g; 49653 } 49654 49655 function parse(data) { 49656 var captionArray = []; 49657 var len = undefined, 49658 lastStartTime = undefined; 49659 49660 if (!data) { 49661 return captionArray; 49662 } 49663 49664 data = data.split(regExNewLine); 49665 len = data.length; 49666 lastStartTime = -1; 49667 49668 for (var i = 0; i < len; i++) { 49669 var item = data[i]; 49670 49671 if (item.length > 0 && item !== WEBVTT) { 49672 if (item.match(regExToken)) { 49673 var attributes = parseItemAttributes(item); 49674 var cuePoints = attributes.cuePoints; 49675 var styles = attributes.styles; 49676 var text = getSublines(data, i + 1); 49677 var startTime = convertCuePointTimes(cuePoints[0].replace(regExWhiteSpace, '')); 49678 var endTime = convertCuePointTimes(cuePoints[1].replace(regExWhiteSpace, '')); 49679 49680 if (!isNaN(startTime) && !isNaN(endTime) && startTime >= lastStartTime && endTime > startTime) { 49681 if (text !== '') { 49682 lastStartTime = startTime; 49683 //TODO Make VO external so other parsers can use. 49684 captionArray.push({ 49685 start: startTime, 49686 end: endTime, 49687 data: text, 49688 styles: styles 49689 }); 49690 } else { 49691 log('Skipping cue due to empty/malformed cue text'); 49692 } 49693 } else { 49694 log('Skipping cue due to incorrect cue timing'); 49695 } 49696 } 49697 } 49698 } 49699 49700 return captionArray; 49701 } 49702 49703 function convertCuePointTimes(time) { 49704 var timeArray = time.split(':'); 49705 var len = timeArray.length - 1; 49706 49707 time = parseInt(timeArray[len - 1], 10) * 60 + parseFloat(timeArray[len]); 49708 49709 if (len === 2) { 49710 time += parseInt(timeArray[0], 10) * 3600; 49711 } 49712 49713 return time; 49714 } 49715 49716 function parseItemAttributes(data) { 49717 var vttCuePoints = data.split(regExToken); 49718 var arr = vttCuePoints[1].split(regExWhiteSpaceWordBoundary); 49719 arr.shift(); //remove first array index it is empty... 49720 vttCuePoints[1] = arr[0]; 49721 arr.shift(); 49722 return { cuePoints: vttCuePoints, styles: getCaptionStyles(arr) }; 49723 } 49724 49725 function getCaptionStyles(arr) { 49726 var styleObject = {}; 49727 arr.forEach(function (element) { 49728 if (element.split(/:/).length > 1) { 49729 var val = element.split(/:/)[1]; 49730 if (val && val.search(/%/) != -1) { 49731 val = parseInt(val.replace(/%/, ''), 10); 49732 } 49733 if (element.match(/align/) || element.match(/A/)) { 49734 styleObject.align = val; 49735 } 49736 if (element.match(/line/) || element.match(/L/)) { 49737 styleObject.line = val; 49738 } 49739 if (element.match(/position/) || element.match(/P/)) { 49740 styleObject.position = val; 49741 } 49742 if (element.match(/size/) || element.match(/S/)) { 49743 styleObject.size = val; 49744 } 49745 } 49746 }); 49747 49748 return styleObject; 49749 } 49750 49751 /* 49752 * VTT can have multiple lines to display per cuepoint. 49753 */ 49754 function getSublines(data, idx) { 49755 var i = idx; 49756 49757 var subline = ''; 49758 var lineData = ''; 49759 var lineCount = undefined; 49760 49761 while (data[i] !== '' && i < data.length) { 49762 i++; 49763 } 49764 49765 lineCount = i - idx; 49766 if (lineCount > 1) { 49767 for (var j = 0; j < lineCount; j++) { 49768 lineData = data[idx + j]; 49769 if (!lineData.match(regExToken)) { 49770 subline += lineData; 49771 if (j !== lineCount - 1) { 49772 subline += '\n'; 49773 } 49774 } else { 49775 // caption text should not have '-->' in it 49776 subline = ''; 49777 break; 49778 } 49779 } 49780 } else { 49781 lineData = data[idx]; 49782 if (!lineData.match(regExToken)) subline = lineData; 49783 } 49784 return subline; 49785 } 49786 49787 instance = { 49788 parse: parse 49789 }; 49790 49791 setup(); 49792 return instance; 49793} 49794VTTParser.__dashjs_factory_name = 'VTTParser'; 49795exports['default'] = _coreFactoryMaker2['default'].getSingletonFactory(VTTParser); 49796module.exports = exports['default']; 49797 49798},{"49":49,"51":51}],204:[function(_dereq_,module,exports){ 49799/** 49800 * The copyright in this software is being made available under the BSD License, 49801 * included below. This software may be subject to other third party and contributor 49802 * rights, including patent rights, and no such rights are granted under this license. 49803 * 49804 * Copyright (c) 2013, Dash Industry Forum. 49805 * All rights reserved. 49806 * 49807 * Redistribution and use in source and binary forms, with or without modification, 49808 * are permitted provided that the following conditions are met: 49809 * * Redistributions of source code must retain the above copyright notice, this 49810 * list of conditions and the following disclaimer. 49811 * * Redistributions in binary form must reproduce the above copyright notice, 49812 * this list of conditions and the following disclaimer in the documentation and/or 49813 * other materials provided with the distribution. 49814 * * Neither the name of Dash Industry Forum nor the names of its 49815 * contributors may be used to endorse or promote products derived from this software 49816 * without specific prior written permission. 49817 * 49818 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 49819 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 49820 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49821 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49822 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
49822INCLUDING, BUT 49823 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 49824 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 49825 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49826 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49827 * POSSIBILITY OF SUCH DAMAGE. 49828 */ 49829 49830'use strict'; 49831 49832Object.defineProperty(exports, '__esModule', { 49833 value: true 49834}); 49835 49836function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 49837 49838var _coreFactoryMaker = _dereq_(51); 49839 49840var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 49841 49842function BasicSelector(config) { 49843 49844 var instance = undefined; 49845 49846 var blacklistController = config.blacklistController; 49847 49848 function select(baseUrls) { 49849 var index = 0; 49850 var selectedBaseUrl = undefined; 49851 49852 if (baseUrls && baseUrls.some(function (baseUrl, idx) { 49853 index = idx; 49854 49855 return !blacklistController.contains(baseUrl.serviceLocation); 49856 })) { 49857 selectedBaseUrl = baseUrls[index]; 49858 } 49859 49860 return selectedBaseUrl; 49861 } 49862 49863 instance = { 49864 select: select 49865 }; 49866 49867 return instance; 49868} 49869 49870BasicSelector.__dashjs_factory_name = 'BasicSelector'; 49871exports['default'] = _coreFactoryMaker2['default'].getClassFactory(BasicSelector); 49872module.exports = exports['default']; 49873 49874},{"51":51}],205:[function(_dereq_,module,exports){ 49875/** 49876 * The copyright in this software is being made available under the BSD License, 49877 * included below. This software may be subject to other third party and contributor 49878 * rights, including patent rights, and no such rights are granted under this license. 49879 * 49880 * Copyright (c) 2013, Dash Industry Forum. 49881 * All rights reserved. 49882 * 49883 * Redistribution and use in source and binary forms, with or without modification, 49884 * are permitted provided that the following conditions are met: 49885 * * Redistributions of source code must retain the above copyright notice, this 49886 * list of conditions and the following disclaimer. 49887 * * Redistributions in binary form must reproduce the above copyright notice, 49888 * this list of conditions and the following disclaimer in the documentation and/or 49889 * other materials provided with the distribution. 49890 * * Neither the name of Dash Industry Forum nor the names of its 49891 * contributors may be used to endorse or promote products derived from this software 49892 * without specific prior written permission. 49893 * 49894 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 49895 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 49896 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49897 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49898 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 49899 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 49900 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 49901 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49902 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49903 * POSSIBILITY OF SUCH DAMAGE. 49904 */ 49905'use strict'; 49906 49907Object.defineProperty(exports, '__esModule', { 49908 value: true 49909}); 49910 49911function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 49912 49913var _coreFactoryMaker = _dereq_(51); 49914 49915var _coreFactoryMaker2 = _interopRequireDefault(_coreFactoryMaker); 49916 49917function DVBSelector(config) { 49918 49919 var instance = undefined; 49920 49921 var blacklistController = config.blacklistController; 49922 49923 function getNonBlacklistedBaseUrls(urls) { 49924 var removedPriorities = []; 49925 49926 var samePrioritiesFilter = function samePrioritiesFilter(el) { 49927 if (removedPriorities.length) { 49928 if (el.dvb_priority && removedPriorities.indexOf(el.dvb_priority) !== -1) { 49929 return false; 49930 } 49931 } 49932 49933 return true; 49934 }; 49935 49936 var serviceLocationFilter = function serviceLocationFilter(baseUrl) { 49937 if (blacklistController.contains(baseUrl.serviceLocation)) { 49938 // whenever a BaseURL is removed from the available list of 49939 // BaseURLs, any other BaseURL with the same @priority 49940 // value as the BaseURL being removed shall also be removed 49941 if (baseUrl.dvb_priority) { 49942 removedPriorities.push(baseUrl.dvb_priority); 49943 } 49944 49945 // all URLs in the list which have a @serviceLocation
vendor: 4,500 bytes, lines 49946-50050
49946 // attribute matching an entry in the blacklist shall be 49947 // removed from the available list of BaseURLs 49948 return false; 49949 } 49950 49951 return true; 49952 }; 49953 49954 return urls.filter(serviceLocationFilter).filter(samePrioritiesFilter); 49955 } 49956 49957 function selectByWeight(availableUrls) { 49958 var prioritySorter = function prioritySorter(a, b) { 49959 var diff = a.dvb_priority - b.dvb_priority; 49960 return isNaN(diff) ? 0 : diff; 49961 }; 49962 49963 var topPriorityFilter = function topPriorityFilter(baseUrl, idx, arr) { 49964 return !idx || arr[0].dvb_priority && baseUrl.dvb_priority && arr[0].dvb_priority === baseUrl.dvb_priority; 49965 }; 49966 49967 var totalWeight = 0; 49968 var cumulWeights = []; 49969 var idx = 0; 49970 var rn = undefined, 49971 urls = undefined; 49972 49973 // It shall begin by taking the set of resolved BaseURLs present or inherited at the current 49974 // position in the MPD, resolved and filtered as described in 10.8.2.1, that have the lowest 49975 // @priority attribute value. 49976 urls = availableUrls.sort(prioritySorter).filter(topPriorityFilter); 49977 49978 if (urls.length) { 49979 if (urls.length > 1) { 49980 // If there is more than one BaseURL with this lowest @priority attribute value then the Player 49981 // shall select one of them at random such that the probability of each BaseURL being chosen 49982 // is proportional to the value of its @weight attribute. The method described in RFC 2782 49983 // [26] or picking from a number of weighted entries is suitable for this, but there may be other 49984 // algorithms which achieve the same effect. 49985 49986 // add all the weights together, storing the accumulated weight per entry 49987 urls.forEach(function (baseUrl) { 49988 totalWeight += baseUrl.dvb_weight; 49989 cumulWeights.push(totalWeight); 49990 }); 49991 49992 // pick a random number between zero and totalWeight 49993 rn = Math.floor(Math.random() * (totalWeight - 1)); 49994 49995 // select the index for the range rn falls within 49996 cumulWeights.every(function (limit, index) { 49997 idx = index; 49998 49999 if (rn < limit) { 50000 return false; 50001 } 50002 50003 return true; 50004 }); 50005 } 50006 50007 return urls[idx]; 50008 } 50009 } 50010 50011 function select(baseUrls) { 50012 return baseUrls && selectByWeight(getNonBlacklistedBaseUrls(baseUrls)); 50013 } 50014 50015 instance = { 50016 select: select 50017 }; 50018 50019 return instance; 50020} 50021 50022DVBSelector.__dashjs_factory_name = 'DVBSelector'; 50023exports['default'] = _coreFactoryMaker2['default'].getClassFactory(DVBSelector); 50024module.exports = exports['default']; 50025 50026},{"51":51}],206:[function(_dereq_,module,exports){ 50027/** 50028 * The copyright in this software is being made available under the BSD License, 50029 * included below. This software may be subject to other third party and contributor 50030 * rights, including patent rights, and no such rights are granted under this license. 50031 * 50032 * Copyright (c) 2013, Dash Industry Forum. 50033 * All rights reserved. 50034 * 50035 * Redistribution and use in source and binary forms, with or without modification, 50036 * are permitted provided that the following conditions are met: 50037 * * Redistributions of source code must retain the above copyright notice, this 50038 * list of conditions and the following disclaimer. 50039 * * Redistributions in binary form must reproduce the above copyright notice, 50040 * this list of conditions and the following disclaimer in the documentation and/or 50041 * other materials provided with the distribution. 50042 * * Neither the name of Dash Industry Forum nor the names of its 50043 * contributors may be used to endorse or promote products derived from this software 50044 * without specific prior written permission. 50045 * 50046 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50047 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50048 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50049 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50050 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
50050INCLUDING, BUT 50051 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50052 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50053 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50054 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50055 * POSSIBILITY OF SUCH DAMAGE. 50056 */ 50057/** 50058 * @class 50059 * @ignore 50060 */ 50061"use strict"; 50062 50063Object.defineProperty(exports, "__esModule", { 50064 value: true 50065}); 50066 50067function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50068 50069var BitrateInfo = function BitrateInfo() { 50070 _classCallCheck(this, BitrateInfo); 50071 50072 this.mediaType = null; 50073 this.bitrate = null; 50074 this.width = null; 50075 this.height = null; 50076 this.scanType = null; 50077 this.qualityIndex = NaN; 50078}; 50079 50080exports["default"] = BitrateInfo; 50081module.exports = exports["default"]; 50082 50083},{}],207:[function(_dereq_,module,exports){ 50084/** 50085 * The copyright in this software is being made available under the BSD License, 50086 * included below. This software may be subject to other third party and contributor 50087 * rights, including patent rights, and no such rights are granted under this license. 50088 * 50089 * Copyright (c) 2013, Dash Industry Forum. 50090 * All rights reserved. 50091 * 50092 * Redistribution and use in source and binary forms, with or without modification, 50093 * are permitted provided that the following conditions are met: 50094 * * Redistributions of source code must retain the above copyright notice, this 50095 * list of conditions and the following disclaimer. 50096 * * Redistributions in binary form must reproduce the above copyright notice, 50097 * this list of conditions and the following disclaimer in the documentation and/or 50098 * other materials provided with the distribution. 50099 * * Neither the name of Dash Industry Forum nor the names of its 50100 * contributors may be used to endorse or promote products derived from this software 50101 * without specific prior written permission. 50102 * 50103 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50104 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50105 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50106 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50107 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50108 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50109 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50110 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50111 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50112 * POSSIBILITY OF SUCH DAMAGE. 50113 */ 50114/** 50115 * @class 50116 * @ignore 50117 */ 50118"use strict"; 50119 50120Object.defineProperty(exports, "__esModule", { 50121 value: true 50122}); 50123 50124function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50125 50126var DashJSError = function DashJSError(code, message, data) { 50127 _classCallCheck(this, DashJSError); 50128 50129 this.code = code || null; 50130 this.message = message || null; 50131 this.data = data || null; 50132}; 50133 50134exports["default"] = DashJSError; 50135module.exports = exports["default"]; 50136 50137},{}],208:[function(_dereq_,module,exports){ 50138/** 50139 * The copyright in this software is being made available under the BSD License, 50140 * included below. This software may be subject to other third party and contributor 50141 * rights, including patent rights, and no such rights are granted under this license. 50142 * 50143 * Copyright (c) 2013, Dash Industry Forum. 50144 * All rights reserved. 50145 * 50146 * Redistribution and use in source and binary forms, with or without modification, 50147 * are permitted provided that the following conditions are met: 50148 * * Redistributions of source code must retain the above copyright notice, this 50149 * list of conditions and the following disclaimer. 50150 * * Redistributions in binary form must reproduce the above copyright notice, 50151 * this list of conditions and the following disclaimer in the documentation and/or 50152 * other materials provided with the distribution. 50153 * * Neither the name of Dash Industry Forum nor the names of its 50154 * contributors may be used to endorse or promote products derived from this software 50155 * without specific prior written permission. 50156 * 50157 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50158 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50159 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50160 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50161 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
50161INCLUDING, BUT 50162 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50163 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50164 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50165 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50166 * POSSIBILITY OF SUCH DAMAGE. 50167 */ 50168 50169/** 50170 * @class 50171 * @ignore 50172 */ 50173"use strict"; 50174 50175Object.defineProperty(exports, "__esModule", { 50176 value: true 50177}); 50178 50179function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50180 50181var DataChunk = 50182//Represents a data structure that keep all the necessary info about a single init/media segment 50183function DataChunk() { 50184 _classCallCheck(this, DataChunk); 50185 50186 this.streamId = null; 50187 this.mediaInfo = null; 50188 this.segmentType = null; 50189 this.quality = NaN; 50190 this.index = NaN; 50191 this.bytes = null; 50192 this.start = NaN; 50193 this.end = NaN; 50194 this.duration = NaN; 50195 this.representationId = null; 50196}; 50197 50198exports["default"] = DataChunk; 50199module.exports = exports["default"]; 50200 50201},{}],209:[function(_dereq_,module,exports){ 50202/** 50203 * The copyright in this software is being made available under the BSD License, 50204 * included below. This software may be subject to other third party and contributor 50205 * rights, including patent rights, and no such rights are granted under this license. 50206 * 50207 * Copyright (c) 2013, Dash Industry Forum. 50208 * All rights reserved. 50209 * 50210 * Redistribution and use in source and binary forms, with or without modification, 50211 * are permitted provided that the following conditions are met: 50212 * * Redistributions of source code must retain the above copyright notice, this 50213 * list of conditions and the following disclaimer. 50214 * * Redistributions in binary form must reproduce the above copyright notice, 50215 * this list of conditions and the following disclaimer in the documentation and/or 50216 * other materials provided with the distribution. 50217 * * Neither the name of Dash Industry Forum nor the names of its 50218 * contributors may be used to endorse or promote products derived from this software 50219 * without specific prior written permission. 50220 * 50221 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50222 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50223 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50224 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50225 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50226 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50227 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50228 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50229 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50230 * POSSIBILITY OF SUCH DAMAGE. 50231 */ 50232/** 50233 * @class 50234 * @ignore 50235 */ 50236'use strict'; 50237 50238Object.defineProperty(exports, '__esModule', { 50239 value: true 50240}); 50241 50242function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 50243 50244var FragmentRequest = function FragmentRequest() { 50245 _classCallCheck(this, FragmentRequest); 50246 50247 this.action = FragmentRequest.ACTION_DOWNLOAD; 50248 this.startTime = NaN; 50249 this.mediaType = null; 50250 this.mediaInfo = null; 50251 this.type = null; 50252 this.duration = NaN; 50253 this.timescale = NaN; 50254 this.range = null; 50255 this.url = null; 50256 this.serviceLocation = null; 50257 this.requestStartDate = null; 50258 this.firstByteDate = null; 50259 this.requestEndDate = null; 50260 this.quality = NaN; 50261 this.index = NaN; 50262 this.availabilityStartTime = null; 50263 this.availabilityEndTime = null; 50264 this.wallStartTime = null; 50265 this.bytesLoaded = NaN; 50266 this.bytesTotal = NaN; 50267 this.delayLoadingTime = NaN; 50268 this.responseType = 'arraybuffer'; 50269 this.representationId = null; 50270}; 50271 50272FragmentRequest.ACTION_DOWNLOAD = 'download'; 50273FragmentRequest.ACTION_COMPLETE = 'complete'; 50274 50275exports['default'] = FragmentRequest; 50276module.exports = exports['default']; 50277 50278},{}],210:[function(_dereq_,module,exports){ 50279/** 50280 * The copyright in this software is being made available under the BSD License, 50281 * included below. This software may be subject to other third party and contributor 50282 * rights, including patent rights, and no such rights are granted under this license. 50283 * 50284 * Copyright (c) 2013, Dash Industry Forum. 50285 * All rights reserved. 50286 * 50287 * Redistribution and use in source and binary forms, with or without modification, 50288 * are permitted provided that the following conditions are met: 50289 * * Redistributions of source code must retain the above copyright notice, this 50290 * list of conditions and the following disclaimer. 50291 * * Redistributions in binary form must reproduce the above copyright notice, 50292 * this list of conditions and the following disclaimer in the documentation and/or 50293 * other materials provided with the distribution. 50294 * * Neither the name of Dash Industry Forum nor the names of its 50295 * contributors may be used to endorse or promote products derived from this software 50296 * without specific prior written permission. 50297 * 50298 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50299 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50300 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50301 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50302 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
50302INCLUDING, BUT 50303 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50304 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50305 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50306 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50307 * POSSIBILITY OF SUCH DAMAGE. 50308 */ 50309/** 50310 * @class 50311 * @ignore 50312 */ 50313'use strict'; 50314 50315Object.defineProperty(exports, '__esModule', { 50316 value: true 50317}); 50318 50319var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 50320 50321function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 50322 50323function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 50324 50325function _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; } 50326 50327var _FragmentRequest2 = _dereq_(209); 50328 50329var _FragmentRequest3 = _interopRequireDefault(_FragmentRequest2); 50330 50331var HeadRequest = (function (_FragmentRequest) { 50332 _inherits(HeadRequest, _FragmentRequest); 50333 50334 function HeadRequest(url) { 50335 _classCallCheck(this, HeadRequest); 50336 50337 _get(Object.getPrototypeOf(HeadRequest.prototype), 'constructor', this).call(this); 50338 this.url = url || null; 50339 this.checkForExistenceOnly = true; 50340 } 50341 50342 return HeadRequest; 50343})(_FragmentRequest3['default']); 50344 50345exports['default'] = HeadRequest; 50346module.exports = exports['default']; 50347 50348},{"209":209}],211:[function(_dereq_,module,exports){ 50349/** 50350 * The copyright in this software is being made available under the BSD License, 50351 * included below. This software may be subject to other third party and contributor 50352 * rights, including patent rights, and no such rights are granted under this license. 50353 * 50354 * Copyright (c) 2013, Dash Industry Forum. 50355 * All rights reserved. 50356 * 50357 * Redistribution and use in source and binary forms, with or without modification, 50358 * are permitted provided that the following conditions are met: 50359 * * Redistributions of source code must retain the above copyright notice, this 50360 * list of conditions and the following disclaimer. 50361 * * Redistributions in binary form must reproduce the above copyright notice, 50362 * this list of conditions and the following disclaimer in the documentation and/or 50363 * other materials provided with the distribution. 50364 * * Neither the name of Dash Industry Forum nor the names of its 50365 * contributors may be used to endorse or promote products derived from this software 50366 * without specific prior written permission. 50367 * 50368 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50369 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50370 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50371 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50372 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50373 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50374 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50375 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50376 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50377 * POSSIBILITY OF SUCH DAMAGE. 50378 */ 50379/** 50380 * @class 50381 * @ignore 50382 */ 50383'use strict'; 50384 50385Object.defineProperty(exports, '__esModule', { 50386 value: true 50387}); 50388 50389var _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; }; })();
vendor: 4,258 bytes, lines 50390-50484
50390 50391function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 50392 50393var IsoBox = (function () { 50394 function IsoBox(boxData) { 50395 _classCallCheck(this, IsoBox); 50396 50397 this.offset = boxData._offset; 50398 this.type = boxData.type; 50399 this.size = boxData.size; 50400 this.boxes = []; 50401 if (boxData.boxes) { 50402 for (var i = 0; i < boxData.boxes.length; i++) { 50403 this.boxes.push(new IsoBox(boxData.boxes[i])); 50404 } 50405 } 50406 this.isComplete = true; 50407 50408 switch (boxData.type) { 50409 case 'sidx': 50410 this.timescale = boxData.timescale; 50411 this.earliest_presentation_time = boxData.earliest_presentation_time; 50412 this.first_offset = boxData.first_offset; 50413 this.references = boxData.references; 50414 if (boxData.references) { 50415 this.references = []; 50416 for (var i = 0; i < boxData.references.length; i++) { 50417 var reference = { 50418 reference_type: boxData.references[i].reference_type, 50419 referenced_size: boxData.references[i].referenced_size, 50420 subsegment_duration: boxData.references[i].subsegment_duration 50421 }; 50422 this.references.push(reference); 50423 } 50424 } 50425 break; 50426 case 'emsg': 50427 this.id = boxData.id; 50428 this.value = boxData.value; 50429 this.timescale = boxData.timescale; 50430 this.scheme_id_uri = boxData.scheme_id_uri; 50431 this.presentation_time_delta = boxData.presentation_time_delta; 50432 this.event_duration = boxData.event_duration; 50433 this.message_data = boxData.message_data; 50434 break; 50435 case 'mdhd': 50436 this.timescale = boxData.timescale; 50437 break; 50438 case 'mfhd': 50439 this.sequence_number = boxData.sequence_number; 50440 break; 50441 case 'subs': 50442 this.entry_count = boxData.entry_count; 50443 this.entries = boxData.entries; 50444 break; 50445 case 'tfhd': 50446 this.base_data_offset = boxData.base_data_offset; 50447 this.sample_description_index = boxData.sample_description_index; 50448 this.default_sample_duration = boxData.default_sample_duration; 50449 this.default_sample_size = boxData.default_sample_size; 50450 this.default_sample_flags = boxData.default_sample_flags; 50451 this.flags = boxData.flags; 50452 break; 50453 case 'tfdt': 50454 this.version = boxData.version; 50455 this.baseMediaDecodeTime = boxData.baseMediaDecodeTime; 50456 this.flags = boxData.flags; 50457 break; 50458 case 'trun': 50459 this.sample_count = boxData.sample_count; 50460 this.first_sample_flags = boxData.first_sample_flags; 50461 this.data_offset = boxData.data_offset; 50462 this.flags = boxData.flags; 50463 this.samples = boxData.samples; 50464 if (boxData.samples) { 50465 this.samples = []; 50466 for (var i = 0, ln = boxData.samples.length; i < ln; i++) { 50467 var sample = { 50468 sample_size: boxData.samples[i].sample_size, 50469 sample_duration: boxData.samples[i].sample_duration, 50470 sample_composition_time_offset: boxData.samples[i].sample_composition_time_offset 50471 }; 50472 this.samples.push(sample); 50473 } 50474 } 50475 break; 50476 } 50477 } 50478 50479 _createClass(IsoBox, [{ 50480 key: 'getChildBox', 50481 value: function getChildBox(type) { 50482 for (var i = 0; i < this.boxes.length; i++) { 50483 if (this.boxes[i].type === type) { 50484 return this.boxes[i];
50485 } 50486 } 50487 } 50488 }, { 50489 key: 'getChildBoxes', 50490 value: function getChildBoxes(type) { 50491 var boxes = []; 50492 for (var i = 0; i < this.boxes.length; i++) { 50493 if (this.boxes[i].type === type) { 50494 boxes.push(this.boxes[i]); 50495 } 50496 } 50497 return boxes; 50498 } 50499 }]); 50500 50501 return IsoBox; 50502})(); 50503 50504exports['default'] = IsoBox; 50505module.exports = exports['default']; 50506 50507},{}],212:[function(_dereq_,module,exports){ 50508/** 50509 * The copyright in this software is being made available under the BSD License, 50510 * included below. This software may be subject to other third party and contributor 50511 * rights, including patent rights, and no such rights are granted under this license. 50512 * 50513 * Copyright (c) 2013, Dash Industry Forum. 50514 * All rights reserved. 50515 * 50516 * Redistribution and use in source and binary forms, with or without modification, 50517 * are permitted provided that the following conditions are met: 50518 * * Redistributions of source code must retain the above copyright notice, this 50519 * list of conditions and the following disclaimer. 50520 * * Redistributions in binary form must reproduce the above copyright notice, 50521 * this list of conditions and the following disclaimer in the documentation and/or 50522 * other materials provided with the distribution. 50523 * * Neither the name of Dash Industry Forum nor the names of its 50524 * contributors may be used to endorse or promote products derived from this software 50525 * without specific prior written permission. 50526 * 50527 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50528 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50529 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50530 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50531 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50532 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50533 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50534 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50535 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50536 * POSSIBILITY OF SUCH DAMAGE. 50537 */ 50538/** 50539 * @class 50540 * @ignore 50541 */ 50542"use strict"; 50543 50544Object.defineProperty(exports, "__esModule", { 50545 value: true 50546}); 50547 50548function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50549 50550var ManifestInfo = function ManifestInfo() { 50551 _classCallCheck(this, ManifestInfo); 50552 50553 this.DVRWindowSize = NaN; 50554 this.loadedTime = null; 50555 this.availableFrom = null; 50556 this.minBufferTime = NaN; 50557 this.duration = NaN; 50558 this.isDynamic = false; 50559 this.maxFragmentDuration = null; 50560}; 50561 50562exports["default"] = ManifestInfo; 50563module.exports = exports["default"]; 50564 50565},{}],213:[function(_dereq_,module,exports){ 50566/** 50567 * The copyright in this software is being made available under the BSD License, 50568 * included below. This software may be subject to other third party and contributor 50569 * rights, including patent rights, and no such rights are granted under this license. 50570 * 50571 * Copyright (c) 2013, Dash Industry Forum. 50572 * All rights reserved. 50573 * 50574 * Redistribution and use in source and binary forms, with or without modification, 50575 * are permitted provided that the following conditions are met: 50576 * * Redistributions of source code must retain the above copyright notice, this 50577 * list of conditions and the following disclaimer. 50578 * * Redistributions in binary form must reproduce the above copyright notice, 50579 * this list of conditions and the following disclaimer in the documentation and/or 50580 * other materials provided with the distribution. 50581 * * Neither the name of Dash Industry Forum nor the names of its 50582 * contributors may be used to endorse or promote products derived from this software 50583 * without specific prior written permission. 50584 * 50585 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50586 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50587 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50588 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50589 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
50589INCLUDING, BUT 50590 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50591 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50592 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50593 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50594 * POSSIBILITY OF SUCH DAMAGE. 50595 */ 50596/** 50597 * @class 50598 * @ignore 50599 */ 50600"use strict"; 50601 50602Object.defineProperty(exports, "__esModule", { 50603 value: true 50604}); 50605 50606function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50607 50608var MediaInfo = function MediaInfo() { 50609 _classCallCheck(this, MediaInfo); 50610 50611 this.id = null; 50612 this.index = null; 50613 this.type = null; 50614 this.streamInfo = null; 50615 this.representationCount = 0; 50616 this.lang = null; 50617 this.viewpoint = null; 50618 this.accessibility = null; 50619 this.audioChannelConfiguration = null; 50620 this.roles = null; 50621 this.codec = null; 50622 this.mimeType = null; 50623 this.contentProtection = null; 50624 this.isText = false; 50625 this.KID = null; 50626 this.bitrateList = null; 50627}; 50628 50629exports["default"] = MediaInfo; 50630module.exports = exports["default"]; 50631 50632},{}],214:[function(_dereq_,module,exports){ 50633/** 50634 * The copyright in this software is being made available under the BSD License, 50635 * included below. This software may be subject to other third party and contributor 50636 * rights, including patent rights, and no such rights are granted under this license. 50637 * 50638 * Copyright (c) 2013, Dash Industry Forum. 50639 * All rights reserved. 50640 * 50641 * Redistribution and use in source and binary forms, with or without modification, 50642 * are permitted provided that the following conditions are met: 50643 * * Redistributions of source code must retain the above copyright notice, this 50644 * list of conditions and the following disclaimer. 50645 * * Redistributions in binary form must reproduce the above copyright notice, 50646 * this list of conditions and the following disclaimer in the documentation and/or 50647 * other materials provided with the distribution. 50648 * * Neither the name of Dash Industry Forum nor the names of its 50649 * contributors may be used to endorse or promote products derived from this software 50650 * without specific prior written permission. 50651 * 50652 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50653 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50654 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50655 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50656 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50657 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50658 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50659 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50660 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50661 * POSSIBILITY OF SUCH DAMAGE. 50662 */ 50663/** 50664 * @class 50665 * @ignore 50666 */ 50667"use strict"; 50668 50669Object.defineProperty(exports, "__esModule", { 50670 value: true 50671}); 50672 50673function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50674 50675var MetricsList = function MetricsList() { 50676 _classCallCheck(this, MetricsList); 50677 50678 this.TcpList = []; 50679 this.HttpList = []; 50680 this.RepSwitchList = []; 50681 this.BufferLevel = []; 50682 this.BufferState = []; 50683 this.PlayList = []; 50684 this.DroppedFrames = []; 50685 this.SchedulingInfo = []; 50686 this.DVRInfo = []; 50687 this.ManifestUpdate = []; 50688 this.RequestsQueue = null; 50689 this.DVBErrors = []; 50690}; 50691 50692exports["default"] = MetricsList; 50693module.exports = exports["default"]; 50694 50695},{}],215:[function(_dereq_,module,exports){ 50696/** 50697 * The copyright in this software is being made available under the BSD License, 50698 * included below. This software may be subject to other third party and contributor 50699 * rights, including patent rights, and no such rights are granted under this license. 50700 * 50701 * Copyright (c) 2013, Dash Industry Forum. 50702 * All rights reserved. 50703 * 50704 * Redistribution and use in source and binary forms, with or without modification, 50705 * are permitted provided that the following conditions are met: 50706 * * Redistributions of source code must retain the above copyright notice, this 50707 * list of conditions and the following disclaimer. 50708 * * Redistributions in binary form must reproduce the above copyright notice, 50709 * this list of conditions and the following disclaimer in the documentation and/or 50710 * other materials provided with the distribution. 50711 * * Neither the name of Dash Industry Forum nor the names of its 50712 * contributors may be used to endorse or promote products derived from this software 50713 * without specific prior written permission. 50714 * 50715 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50716 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50717 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50718 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50719 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
50719INCLUDING, BUT 50720 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50721 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50722 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50723 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50724 * POSSIBILITY OF SUCH DAMAGE. 50725 */ 50726/** 50727 * @class 50728 * @ignore 50729 */ 50730"use strict"; 50731 50732Object.defineProperty(exports, "__esModule", { 50733 value: true 50734}); 50735 50736function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50737 50738var RepresentationInfo = function RepresentationInfo() { 50739 _classCallCheck(this, RepresentationInfo); 50740 50741 this.id = null; 50742 this.quality = null; 50743 this.DVRWindow = null; 50744 this.fragmentDuration = null; 50745 this.mediaInfo = null; 50746 this.MSETimeOffset = null; 50747}; 50748 50749exports["default"] = RepresentationInfo; 50750module.exports = exports["default"]; 50751 50752},{}],216:[function(_dereq_,module,exports){ 50753/** 50754 * The copyright in this software is being made available under the BSD License, 50755 * included below. This software may be subject to other third party and contributor 50756 * rights, including patent rights, and no such rights are granted under this license. 50757 * 50758 * Copyright (c) 2013, Dash Industry Forum. 50759 * All rights reserved. 50760 * 50761 * Redistribution and use in source and binary forms, with or without modification, 50762 * are permitted provided that the following conditions are met: 50763 * * Redistributions of source code must retain the above copyright notice, this 50764 * list of conditions and the following disclaimer. 50765 * * Redistributions in binary form must reproduce the above copyright notice, 50766 * this list of conditions and the following disclaimer in the documentation and/or 50767 * other materials provided with the distribution. 50768 * * Neither the name of Dash Industry Forum nor the names of its 50769 * contributors may be used to endorse or promote products derived from this software 50770 * without specific prior written permission. 50771 * 50772 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50773 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50774 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50775 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50776 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50777 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50778 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50779 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50780 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50781 * POSSIBILITY OF SUCH DAMAGE. 50782 */ 50783/** 50784 * @class 50785 * @ignore 50786 */ 50787"use strict"; 50788 50789Object.defineProperty(exports, "__esModule", { 50790 value: true 50791}); 50792 50793function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50794 50795var StreamInfo = function StreamInfo() { 50796 _classCallCheck(this, StreamInfo); 50797 50798 this.id = null; 50799 this.index = null; 50800 this.start = NaN; 50801 this.duration = NaN; 50802 this.manifestInfo = null; 50803 this.isLast = true; 50804}; 50805 50806exports["default"] = StreamInfo; 50807module.exports = exports["default"]; 50808 50809},{}],217:[function(_dereq_,module,exports){ 50810/** 50811 * The copyright in this software is being made available under the BSD License, 50812 * included below. This software may be subject to other third party and contributor 50813 * rights, including patent rights, and no such rights are granted under this license. 50814 * 50815 * Copyright (c) 2013, Dash Industry Forum. 50816 * All rights reserved. 50817 * 50818 * Redistribution and use in source and binary forms, with or without modification, 50819 * are permitted provided that the following conditions are met: 50820 * * Redistributions of source code must retain the above copyright notice, this 50821 * list of conditions and the following disclaimer. 50822 * * Redistributions in binary form must reproduce the above copyright notice, 50823 * this list of conditions and the following disclaimer in the documentation and/or 50824 * other materials provided with the distribution. 50825 * * Neither the name of Dash Industry Forum nor the names of its 50826 * contributors may be used to endorse or promote products derived from this software 50827 * without specific prior written permission. 50828 * 50829 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50830 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50831 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50832 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50833 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
50833INCLUDING, BUT 50834 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50835 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50836 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50837 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50838 * POSSIBILITY OF SUCH DAMAGE. 50839 */ 50840/** 50841 * @class 50842 * @ignore 50843 */ 50844'use strict'; 50845 50846Object.defineProperty(exports, '__esModule', { 50847 value: true 50848}); 50849 50850var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 50851 50852function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 50853 50854function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 50855 50856function _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; } 50857 50858var _constantsConstants = _dereq_(100); 50859 50860var _constantsConstants2 = _interopRequireDefault(_constantsConstants); 50861 50862var _FragmentRequest2 = _dereq_(209); 50863 50864var _FragmentRequest3 = _interopRequireDefault(_FragmentRequest2); 50865 50866var TextRequest = (function (_FragmentRequest) { 50867 _inherits(TextRequest, _FragmentRequest); 50868 50869 function TextRequest(url, type) { 50870 _classCallCheck(this, TextRequest); 50871 50872 _get(Object.getPrototypeOf(TextRequest.prototype), 'constructor', this).call(this); 50873 this.url = url || null; 50874 this.type = type || null; 50875 this.mediaType = _constantsConstants2['default'].STREAM; 50876 this.responseType = _constantsConstants2['default'].TEXT; 50877 } 50878 50879 return TextRequest; 50880})(_FragmentRequest3['default']); 50881 50882exports['default'] = TextRequest; 50883module.exports = exports['default']; 50884 50885},{"100":100,"209":209}],218:[function(_dereq_,module,exports){ 50886/** 50887 * The copyright in this software is being made available under the BSD License, 50888 * included below. This software may be subject to other third party and contributor 50889 * rights, including patent rights, and no such rights are granted under this license. 50890 * 50891 * Copyright (c) 2013, Dash Industry Forum. 50892 * All rights reserved. 50893 * 50894 * Redistribution and use in source and binary forms, with or without modification, 50895 * are permitted provided that the following conditions are met: 50896 * * Redistributions of source code must retain the above copyright notice, this 50897 * list of conditions and the following disclaimer. 50898 * * Redistributions in binary form must reproduce the above copyright notice, 50899 * this list of conditions and the following disclaimer in the documentation and/or 50900 * other materials provided with the distribution. 50901 * * Neither the name of Dash Industry Forum nor the names of its 50902 * contributors may be used to endorse or promote products derived from this software 50903 * without specific prior written permission. 50904 * 50905 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50906 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50907 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50908 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50909 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
50909INCLUDING, BUT 50910 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50911 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50912 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50913 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50914 * POSSIBILITY OF SUCH DAMAGE. 50915 */ 50916/** 50917 * @class 50918 * @ignore 50919 */ 50920"use strict"; 50921 50922Object.defineProperty(exports, "__esModule", { 50923 value: true 50924}); 50925 50926function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50927 50928var TextTrackInfo = function TextTrackInfo() { 50929 _classCallCheck(this, TextTrackInfo); 50930 50931 this.captionData = null; 50932 this.label = null; 50933 this.lang = null; 50934 this.defaultTrack = false; 50935 this.kind = null; 50936 this.isFragmented = false; 50937 this.isEmbedded = false; 50938}; 50939 50940exports["default"] = TextTrackInfo; 50941module.exports = exports["default"]; 50942 50943},{}],219:[function(_dereq_,module,exports){ 50944/** 50945 * The copyright in this software is being made available under the BSD License, 50946 * included below. This software may be subject to other third party and contributor 50947 * rights, including patent rights, and no such rights are granted under this license. 50948 * 50949 * Copyright (c) 2013, Dash Industry Forum. 50950 * All rights reserved. 50951 * 50952 * Redistribution and use in source and binary forms, with or without modification, 50953 * are permitted provided that the following conditions are met: 50954 * * Redistributions of source code must retain the above copyright notice, this 50955 * list of conditions and the following disclaimer. 50956 * * Redistributions in binary form must reproduce the above copyright notice, 50957 * this list of conditions and the following disclaimer in the documentation and/or 50958 * other materials provided with the distribution. 50959 * * Neither the name of Dash Industry Forum nor the names of its 50960 * contributors may be used to endorse or promote products derived from this software 50961 * without specific prior written permission. 50962 * 50963 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 50964 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50965 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50966 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 50967 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50968 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50969 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 50970 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50971 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50972 * POSSIBILITY OF SUCH DAMAGE. 50973 */ 50974/** 50975 * @class 50976 * @ignore 50977 */ 50978"use strict"; 50979 50980Object.defineProperty(exports, "__esModule", { 50981 value: true 50982}); 50983 50984function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 50985 50986var URIFragmentData = function URIFragmentData() { 50987 _classCallCheck(this, URIFragmentData); 50988 50989 this.t = null; 50990 this.xywh = null; 50991 this.track = null; 50992 this.id = null; 50993 this.s = null; 50994}; 50995 50996exports["default"] = URIFragmentData; 50997 50998/* 50999 From Spec http://www.w3.org/TR/media-frags/ 51000 51001 temporal (t) - This dimension denotes a specific time range in the original media, such as "starting at second 10, continuing until second 20"; 51002 spatial (xywh) - this dimension denotes a specific range of pixels in the original media, such as "a rectangle with size (100,100) with its top-left at coordinate (10,10)"; 51003 Media fragments support also addressing the media along two additional dimensions (in the advanced version defined in Media Fragments 1.0 URI (advanced)): 51004 track (track) - this dimension denotes one or more tracks in the original media, such as "the english audio and the video track"; 51005 id (id) - this dimension denotes a named temporal fragment within the original media, such as "chapter 2", and can be seen as a convenient way of specifying a temporal fragment. 51006 51007 51008 ## Note 51009 Akamai is purposing to add #s=X to the ISO standard. 51010 - (X) Value would be a start time to seek to at startup instead of starting at 0 or live edge 51011 - Allows for seeking back before the start time unlike a temporal clipping. 51012*/ 51013module.exports = exports["default"]; 51014 51015},{}],220:[function(_dereq_,module,exports){ 51016/** 51017 * The copyright in this software is being made available under the BSD License, 51018 * included below. This software may be subject to other third party and contributor 51019 * rights, including patent rights, and no such rights are granted under this license. 51020 * 51021 * Copyright (c) 2013, Dash Industry Forum. 51022 * All rights reserved. 51023 * 51024 * Redistribution and use in source and binary forms, with or without modification, 51025 * are permitted provided that the following conditions are met: 51026 * * Redistributions of source code must retain the above copyright notice, this 51027 * list of conditions and the following disclaimer. 51028 * * Redistributions in binary form must reproduce the above copyright notice, 51029 * this list of conditions and the following disclaimer in the documentation and/or 51030 * other materials provided with the distribution. 51031 * * Neither the name of Dash Industry Forum nor the names of its 51032 * contributors may be used to endorse or promote products derived from this software 51033 * without specific prior written permission. 51034 * 51035 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51036 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51037 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51038 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51039 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
51039INCLUDING, BUT 51040 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51041 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51042 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51043 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51044 * POSSIBILITY OF SUCH DAMAGE. 51045 */ 51046 51047/** 51048 * @class 51049 */ 51050"use strict"; 51051 51052Object.defineProperty(exports, "__esModule", { 51053 value: true 51054}); 51055 51056function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 51057 51058var BufferLevel = 51059/** 51060 * @description This Object holds reference to the current buffer level and the time it was recorded. 51061 */ 51062function BufferLevel() { 51063 _classCallCheck(this, BufferLevel); 51064 51065 /** 51066 * Real-Time | Time of the measurement of the buffer level. 51067 * @public 51068 */ 51069 this.t = null; 51070 /** 51071 * Level of the buffer in milliseconds. Indicates the playout duration for which 51072 * media data of all active media components is available starting from the 51073 * current playout time. 51074 * @public 51075 */ 51076 this.level = null; 51077}; 51078 51079exports["default"] = BufferLevel; 51080module.exports = exports["default"]; 51081 51082},{}],221:[function(_dereq_,module,exports){ 51083/** 51084 * The copyright in this software is being made available under the BSD License, 51085 * included below. This software may be subject to other third party and contributor 51086 * rights, including patent rights, and no such rights are granted under this license. 51087 * 51088 * Copyright (c) 2013, Dash Industry Forum. 51089 * All rights reserved. 51090 * 51091 * Redistribution and use in source and binary forms, with or without modification, 51092 * are permitted provided that the following conditions are met: 51093 * * Redistributions of source code must retain the above copyright notice, this 51094 * list of conditions and the following disclaimer. 51095 * * Redistributions in binary form must reproduce the above copyright notice, 51096 * this list of conditions and the following disclaimer in the documentation and/or 51097 * other materials provided with the distribution. 51098 * * Neither the name of Dash Industry Forum nor the names of its 51099 * contributors may be used to endorse or promote products derived from this software 51100 * without specific prior written permission. 51101 * 51102 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51103 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51104 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51105 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51106 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 51107 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51108 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51109 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51110 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51111 * POSSIBILITY OF SUCH DAMAGE. 51112 */ 51113'use strict'; 51114 51115Object.defineProperty(exports, '__esModule', { 51116 value: true 51117}); 51118 51119function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 51120 51121function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 51122 51123var _controllersBufferController = _dereq_(105); 51124 51125var _controllersBufferController2 = _interopRequireDefault(_controllersBufferController); 51126 51127/** 51128 * @class 51129 */ 51130 51131var BufferState = 51132/** 51133 * @description This Object holds reference to the current buffer state of the video element. 51134 */ 51135function BufferState() { 51136 _classCallCheck(this, BufferState); 51137 51138 /** 51139 * The Buffer Level Target determined by the BufferLevelRule. 51140 * @public 51141 */ 51142 this.target = null; 51143 /** 51144 * Current buffer state. Will be BufferController.BUFFER_EMPTY or BufferController.BUFFER_LOADED. 51145 * @public 51146 */ 51147 this.state = _controllersBufferController2['default'].BUFFER_EMPTY; 51148}; 51149 51150exports['default'] = BufferState; 51151module.exports = exports['default']; 51152 51153},{"105":105}],222:[function(_dereq_,module,exports){ 51154/** 51155 * The copyright in this software is being made available under the BSD License, 51156 * included below. This software may be subject to other third party and contributor 51157 * rights, including patent rights, and no such rights are granted under this license. 51158 * 51159 * Copyright (c) 2013, Dash Industry Forum. 51160 * All rights reserved. 51161 * 51162 * Redistribution and use in source and binary forms, with or without modification, 51163 * are permitted provided that the following conditions are met: 51164 * * Redistributions of source code must retain the above copyright notice, this 51165 * list of conditions and the following disclaimer. 51166 * * Redistributions in binary form must reproduce the above copyright notice, 51167 * this list of conditions and the following disclaimer in the documentation and/or 51168 * other materials provided with the distribution. 51169 * * Neither the name of Dash Industry Forum nor the names of its 51170 * contributors may be used to endorse or promote products derived from this software 51171 * without specific prior written permission. 51172 * 51173 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51174 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51175 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51176 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51177 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
51177INCLUDING, BUT 51178 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51179 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51180 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51181 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51182 * POSSIBILITY OF SUCH DAMAGE. 51183 */ 51184/** 51185 * @class 51186 */ 51187"use strict"; 51188 51189Object.defineProperty(exports, "__esModule", { 51190 value: true 51191}); 51192 51193function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 51194 51195var DVRInfo = 51196/** 51197 * @description This Object holds reference to DVR availability window information. 51198 */ 51199function DVRInfo() { 51200 _classCallCheck(this, DVRInfo); 51201 51202 /** 51203 * The current time of the video element when this was created. 51204 * @public 51205 */ 51206 this.time = null; 51207 /** 51208 * The current Segment Availability Range as an object with start and end properties. 51209 * It's delta defined by the timeShiftBufferDepth MPD attribute. 51210 * @public 51211 */ 51212 this.range = null; 51213 /** 51214 * Reference to the internal ManifestInfo.js VO. 51215 * @public 51216 */ 51217 this.manifestInfo = null; 51218}; 51219 51220exports["default"] = DVRInfo; 51221module.exports = exports["default"]; 51222 51223},{}],223:[function(_dereq_,module,exports){ 51224/** 51225 * The copyright in this software is being made available under the BSD License, 51226 * included below. This software may be subject to other third party and contributor 51227 * rights, including patent rights, and no such rights are granted under this license. 51228 * 51229 * Copyright (c) 2013, Dash Industry Forum. 51230 * All rights reserved. 51231 * 51232 * Redistribution and use in source and binary forms, with or without modification, 51233 * are permitted provided that the following conditions are met: 51234 * * Redistributions of source code must retain the above copyright notice, this 51235 * list of conditions and the following disclaimer. 51236 * * Redistributions in binary form must reproduce the above copyright notice, 51237 * this list of conditions and the following disclaimer in the documentation and/or 51238 * other materials provided with the distribution. 51239 * * Neither the name of Dash Industry Forum nor the names of its 51240 * contributors may be used to endorse or promote products derived from this software 51241 * without specific prior written permission. 51242 * 51243 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51244 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51245 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51246 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51247 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 51248 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51249 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51250 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51251 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51252 * POSSIBILITY OF SUCH DAMAGE. 51253 */ 51254/** 51255 * @class 51256 */ 51257"use strict"; 51258 51259Object.defineProperty(exports, "__esModule", { 51260 value: true 51261}); 51262 51263function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 51264 51265var DroppedFrames = 51266/** 51267 * @description This Object holds reference to DroppedFrames count and the time it was recorded. 51268 */ 51269function DroppedFrames() { 51270 _classCallCheck(this, DroppedFrames); 51271 51272 /** 51273 * Real-Time | Time of the measurement of the dropped frames. 51274 * @public 51275 */ 51276 this.time = null; 51277 /** 51278 * Number of dropped frames 51279 * @public 51280 */ 51281 this.droppedFrames = null; 51282}; 51283 51284exports["default"] = DroppedFrames; 51285module.exports = exports["default"]; 51286 51287},{}],224:[function(_dereq_,module,exports){ 51288/** 51289 * The copyright in this software is being made available under the BSD License, 51290 * included below. This software may be subject to other third party and contributor 51291 * rights, including patent rights, and no such rights are granted under this license. 51292 * 51293 * Copyright (c) 2013, Dash Industry Forum. 51294 * All rights reserved. 51295 * 51296 * Redistribution and use in source and binary forms, with or without modification, 51297 * are permitted provided that the following conditions are met: 51298 * * Redistributions of source code must retain the above copyright notice, this 51299 * list of conditions and the following disclaimer. 51300 * * Redistributions in binary form must reproduce the above copyright notice, 51301 * this list of conditions and the following disclaimer in the documentation and/or 51302 * other materials provided with the distribution. 51303 * * Neither the name of Dash Industry Forum nor the names of its 51304 * contributors may be used to endorse or promote products derived from this software 51305 * without specific prior written permission. 51306 * 51307 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51308 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51309 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51310 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51311 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
51311INCLUDING, BUT 51312 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51313 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51314 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51315 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51316 * POSSIBILITY OF SUCH DAMAGE. 51317 */ 51318/** 51319 * @classdesc This Object holds reference to the HTTPRequest for manifest, fragment and xlink loading. 51320 * Members which are not defined in ISO23009-1 Annex D should be prefixed by a _ so that they are ignored 51321 * by Metrics Reporting code. 51322 */ 51323'use strict'; 51324 51325Object.defineProperty(exports, '__esModule', { 51326 value: true 51327}); 51328 51329function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 51330 51331var HTTPRequest = 51332/** 51333 * @class 51334 */ 51335function HTTPRequest() { 51336 _classCallCheck(this, HTTPRequest); 51337 51338 /** 51339 * Identifier of the TCP connection on which the HTTP request was sent. 51340 * @public 51341 */ 51342 this.tcpid = null; 51343 /** 51344 * This is an optional parameter and should not be included in HTTP request/response transactions for progressive download. 51345 * The type of the request: 51346 * - MPD 51347 * - XLink expansion 51348 * - Initialization Fragment 51349 * - Index Fragment 51350 * - Media Fragment 51351 * - Bitstream Switching Fragment 51352 * - other 51353 * @public 51354 */ 51355 this.type = null; 51356 /** 51357 * The original URL (before any redirects or failures) 51358 * @public 51359 */ 51360 this.url = null; 51361 /** 51362 * The actual URL requested, if different from above 51363 * @public 51364 */ 51365 this.actualurl = null; 51366 /** 51367 * The contents of the byte-range-spec part of the HTTP Range header. 51368 * @public 51369 */ 51370 this.range = null; 51371 /** 51372 * Real-Time | The real time at which the request was sent. 51373 * @public 51374 */ 51375 this.trequest = null; 51376 /** 51377 * Real-Time | The real time at which the first byte of the response was received. 51378 * @public 51379 */ 51380 this.tresponse = null; 51381 /** 51382 * The HTTP response code. 51383 * @public 51384 */ 51385 this.responsecode = null; 51386 /** 51387 * The duration of the throughput trace intervals (ms), for successful requests only. 51388 * @public 51389 */ 51390 this.interval = null; 51391 /** 51392 * Throughput traces, for successful requests only. 51393 * @public 51394 */ 51395 this.trace = []; 51396 51397 /** 51398 * Type of stream ("audio" | "video" etc..) 51399 * @public 51400 */ 51401 this._stream = null; 51402 /** 51403 * Real-Time | The real time at which the request finished. 51404 * @public 51405 */ 51406 this._tfinish = null; 51407 /** 51408 * The duration of the media requests, if available, in milliseconds. 51409 * @public 51410 */ 51411 this._mediaduration = null; 51412 /** 51413 * all the response headers from request. 51414 * @public 51415 */ 51416 this._responseHeaders = null; 51417 /** 51418 * The selected service location for the request. string. 51419 * @public 51420 */ 51421 this._serviceLocation = null; 51422} 51423 51424/** 51425 * @classdesc This Object holds reference to the progress of the HTTPRequest. 51426 */ 51427; 51428 51429var HTTPRequestTrace = 51430/** 51431* @class 51432*/ 51433function HTTPRequestTrace() { 51434 _classCallCheck(this, HTTPRequestTrace); 51435 51436 /** 51437 * Real-Time | Measurement stream start. 51438 * @public 51439 */ 51440 this.s = null; 51441 /** 51442 * Measurement stream duration (ms). 51443 * @public 51444 */ 51445 this.d = null; 51446 /** 51447 * List of integers counting the bytes received in each trace interval within the measurement stream. 51448 * @public 51449 */ 51450 this.b = []; 51451}; 51452 51453HTTPRequest.GET = 'GET'; 51454HTTPRequest.HEAD = 'HEAD'; 51455HTTPRequest.MPD_TYPE = 'MPD'; 51456HTTPRequest.XLINK_EXPANSION_TYPE = 'XLinkExpansion'; 51457HTTPRequest.INIT_SEGMENT_TYPE = 'InitializationSegment'; 51458HTTPRequest.INDEX_SEGMENT_TYPE = 'IndexSegment'; 51459HTTPRequest.MEDIA_SEGMENT_TYPE = 'MediaSegment'; 51460HTTPRequest.BITSTREAM_SWITCHING_SEGMENT_TYPE = 'BitstreamSwitchingSegment'; 51461HTTPRequest.OTHER_TYPE = 'other'; 51462 51463exports.HTTPRequest = HTTPRequest; 51464exports.HTTPRequestTrace = HTTPRequestTrace; 51465 51466},{}],225:[function(_dereq_,module,exports){ 51467/** 51468 * The copyright in this software is being made available under the BSD License, 51469 * included below. This software may be subject to other third party and contributor 51470 * rights, including patent rights, and no such rights are granted under this license. 51471 * 51472 * Copyright (c) 2013, Dash Industry Forum. 51473 * All rights reserved. 51474 * 51475 * Redistribution and use in source and binary forms, with or without modification, 51476 * are permitted provided that the following conditions are met: 51477 * * Redistributions of source code must retain the above copyright notice, this 51478 * list of conditions and the following disclaimer. 51479 * * Redistributions in binary form must reproduce the above copyright notice, 51480 * this list of conditions and the following disclaimer in the documentation and/or 51481 * other materials provided with the distribution. 51482 * * Neither the name of Dash Industry Forum nor the names of its 51483 * contributors may be used to endorse or promote products derived from this software 51484 * without specific prior written permission. 51485 * 51486 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51487 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51488 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51489 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51490 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
51490INCLUDING, BUT 51491 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51492 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51493 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51494 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51495 * POSSIBILITY OF SUCH DAMAGE. 51496 */ 51497/** 51498 * @classdesc This Object holds reference to the manifest update information. 51499 */ 51500"use strict"; 51501 51502Object.defineProperty(exports, "__esModule", { 51503 value: true 51504}); 51505 51506function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 51507 51508var ManifestUpdate = 51509/** 51510 * @class 51511 */ 51512function ManifestUpdate() { 51513 _classCallCheck(this, ManifestUpdate); 51514 51515 /** 51516 * Media Type Video | Audio | FragmentedText 51517 * @public 51518 */ 51519 this.mediaType = null; 51520 /** 51521 * MPD Type static | dynamic 51522 * @public 51523 */ 51524 this.type = null; 51525 /** 51526 * When this manifest update was requested 51527 * @public 51528 */ 51529 this.requestTime = null; 51530 /** 51531 * When this manifest update was received 51532 * @public 51533 */ 51534 this.fetchTime = null; 51535 /** 51536 * Calculated Availability Start time of the stream. 51537 * @public 51538 */ 51539 this.availabilityStartTime = null; 51540 /** 51541 * the seek point (liveEdge for dynamic, Stream[0].startTime for static) 51542 * @public 51543 */ 51544 this.presentationStartTime = 0; 51545 /** 51546 * The calculated difference between the server and client wall clock time 51547 * @public 51548 */ 51549 this.clientTimeOffset = 0; 51550 /** 51551 * Actual element.currentTime 51552 * @public 51553 */ 51554 this.currentTime = null; 51555 /** 51556 * Actual element.ranges 51557 * @public 51558 */ 51559 this.buffered = null; 51560 /** 51561 * Static is fixed value of zero. dynamic should be ((Now-@availabilityStartTime) - elementCurrentTime) 51562 * @public 51563 */ 51564 this.latency = 0; 51565 /** 51566 * Array holding list of StreamInfo VO Objects 51567 * @public 51568 */ 51569 this.streamInfo = []; 51570 /** 51571 * Array holding list of RepresentationInfo VO Objects 51572 * @public 51573 */ 51574 this.representationInfo = []; 51575} 51576 51577/** 51578 * @classdesc This Object holds reference to the current period's stream information when the manifest was updated. 51579 */ 51580; 51581 51582var ManifestUpdateStreamInfo = 51583/** 51584 * @class 51585 */ 51586function ManifestUpdateStreamInfo() { 51587 _classCallCheck(this, ManifestUpdateStreamInfo); 51588 51589 /** 51590 * Stream@id 51591 * @public 51592 */ 51593 this.id = null; 51594 /** 51595 * Period Index 51596 * @public 51597 */ 51598 this.index = null; 51599 /** 51600 * Stream@start 51601 * @public 51602 */ 51603 this.start = null; 51604 /** 51605 * Stream@duration 51606 * @public 51607 */ 51608 this.duration = null; 51609} 51610 51611/** 51612 * @classdesc This Object holds reference to the current representation's info when the manifest was updated. 51613 */ 51614; 51615 51616var ManifestUpdateRepresentationInfo = 51617/** 51618 * @class 51619 */ 51620function ManifestUpdateRepresentationInfo() { 51621 _classCallCheck(this, ManifestUpdateRepresentationInfo); 51622 51623 /** 51624 * Track@id 51625 * @public 51626 */ 51627 this.id = null; 51628 /** 51629 * Representation Index 51630 * @public 51631 */ 51632 this.index = null; 51633 /** 51634 * Media Type Video | Audio | FragmentedText 51635 * @public 51636 */ 51637 this.mediaType = null; 51638 /** 51639 * Which representation 51640 * @public 51641 */ 51642 this.streamIndex = null; 51643 /** 51644 * Holds reference to @presentationTimeOffset 51645 * @public 51646 */ 51647 this.presentationTimeOffset = null; 51648 /** 51649 * Holds reference to @startNumber 51650 * @public 51651 */ 51652 this.startNumber = null; 51653 /** 51654 * list|template|timeline 51655 * @public 51656 */ 51657 this.fragmentInfoType = null; 51658}; 51659 51660exports.ManifestUpdate = ManifestUpdate; 51661exports.ManifestUpdateStreamInfo = ManifestUpdateStreamInfo; 51662exports.ManifestUpdateRepresentationInfo = ManifestUpdateRepresentationInfo; 51663 51664},{}],226:[function(_dereq_,module,exports){ 51665/** 51666 * The copyright in this software is being made available under the BSD License, 51667 * included below. This software may be subject to other third party and contributor 51668 * rights, including patent rights, and no such rights are granted under this license. 51669 * 51670 * Copyright (c) 2013, Dash Industry Forum. 51671 * All rights reserved. 51672 * 51673 * Redistribution and use in source and binary forms, with or without modification, 51674 * are permitted provided that the following conditions are met: 51675 * * Redistributions of source code must retain the above copyright notice, this 51676 * list of conditions and the following disclaimer. 51677 * * Redistributions in binary form must reproduce the above copyright notice, 51678 * this list of conditions and the following disclaimer in the documentation and/or 51679 * other materials provided with the distribution. 51680 * * Neither the name of Dash Industry Forum nor the names of its 51681 * contributors may be used to endorse or promote products derived from this software 51682 * without specific prior written permission. 51683 * 51684 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51685 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51686 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51687 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51688 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
51688INCLUDING, BUT 51689 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51690 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51691 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51692 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51693 * POSSIBILITY OF SUCH DAMAGE. 51694 */ 51695/** 51696 * @classdesc a PlayList from ISO23009-1 Annex D, this Object holds reference to the playback session information 51697 */ 51698'use strict'; 51699 51700Object.defineProperty(exports, '__esModule', { 51701 value: true 51702}); 51703 51704function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 51705 51706var PlayList = 51707/** 51708 * @class 51709 */ 51710function PlayList() { 51711 _classCallCheck(this, PlayList); 51712 51713 /** 51714 * Timestamp of the user action that starts the playback stream... 51715 * @public 51716 */ 51717 this.start = null; 51718 /** 51719 * Presentation time at which playout was requested by the user... 51720 * @public 51721 */ 51722 this.mstart = null; 51723 /** 51724 * Type of user action which triggered playout 51725 * - New playout request (e.g. initial playout or seeking) 51726 * - Resume from pause 51727 * - Other user request (e.g. user-requested quality change) 51728 * - Start of a metrics collection stream (hence earlier entries in the play list not collected) 51729 * @public 51730 */ 51731 this.starttype = null; 51732 51733 /** 51734 * List of streams of continuous rendering of decoded samples. 51735 * @public 51736 */ 51737 this.trace = []; 51738} 51739 51740/* Public Static Constants */ 51741; 51742 51743PlayList.INITIAL_PLAYOUT_START_REASON = 'initial_playout'; 51744PlayList.SEEK_START_REASON = 'seek'; 51745PlayList.RESUME_FROM_PAUSE_START_REASON = 'resume'; 51746PlayList.METRICS_COLLECTION_START_REASON = 'metrics_collection_start'; 51747 51748/** 51749 * @classdesc a PlayList.Trace from ISO23009-1 Annex D 51750 */ 51751 51752var PlayListTrace = 51753/** 51754 * @class 51755 */ 51756function PlayListTrace() { 51757 _classCallCheck(this, PlayListTrace); 51758 51759 /** 51760 * The value of the Representation@id of the Representation from which the samples were taken. 51761 * @type {string} 51762 * @public 51763 */ 51764 this.representationid = null; 51765 /** 51766 * If not present, this metrics concerns the Representation as a whole. 51767 * If present, subreplevel indicates the greatest value of any 51768 * Subrepresentation@level being rendered. 51769 * @type {number} 51770 * @public 51771 */ 51772 this.subreplevel = null; 51773 /** 51774 * The time at which the first sample was rendered 51775 * @type {number} 51776 * @public 51777 */ 51778 this.start = null; 51779 /** 51780 * The presentation time of the first sample rendered. 51781 * @type {number} 51782 * @public 51783 */ 51784 this.mstart = null; 51785 /** 51786 * The duration of the continuously presented samples (which is the same in real time and media time). "Continuously presented" means that the media clock continued to advance at the playout speed throughout the interval. NOTE: the spec does not call out the units, but all other durations etc are in ms, and we use ms too. 51787 * @type {number} 51788 * @public 51789 */ 51790 this.duration = null; 51791 /** 51792 * The playback speed relative to normal playback speed (i.e.normal forward playback speed is 1.0). 51793 * @type {number} 51794 * @public 51795 */ 51796 this.playbackspeed = null; 51797 /** 51798 * The reason why continuous presentation of this Representation was stopped. 51799 * representation switch 51800 * rebuffering 51801 * user request 51802 * end of Period 51803 * end of Stream 51804 * end of content 51805 * end of a metrics collection period 51806 * 51807 * @type {string} 51808 * @public 51809 */ 51810 this.stopreason = null; 51811}; 51812 51813PlayListTrace.REPRESENTATION_SWITCH_STOP_REASON = 'representation_switch'; 51814PlayListTrace.REBUFFERING_REASON = 'rebuffering'; 51815PlayListTrace.USER_REQUEST_STOP_REASON = 'user_request'; 51816PlayListTrace.END_OF_PERIOD_STOP_REASON = 'end_of_period'; 51817PlayListTrace.END_OF_CONTENT_STOP_REASON = 'end_of_content'; 51818PlayListTrace.METRICS_COLLECTION_STOP_REASON = 'metrics_collection_end'; 51819PlayListTrace.FAILURE_STOP_REASON = 'failure'; 51820 51821exports.PlayList = PlayList; 51822exports.PlayListTrace = PlayListTrace; 51823 51824},{}],227:[function(_dereq_,module,exports){ 51825/** 51826 * The copyright in this software is being made available under the BSD License, 51827 * included below. This software may be subject to other third party and contributor 51828 * rights, including patent rights, and no such rights are granted under this license. 51829 * 51830 * Copyright (c) 2013, Dash Industry Forum. 51831 * All rights reserved. 51832 * 51833 * Redistribution and use in source and binary forms, with or without modification, 51834 * are permitted provided that the following conditions are met: 51835 * * Redistributions of source code must retain the above copyright notice, this 51836 * list of conditions and the following disclaimer. 51837 * * Redistributions in binary form must reproduce the above copyright notice, 51838 * this list of conditions and the following disclaimer in the documentation and/or 51839 * other materials provided with the distribution. 51840 * * Neither the name of Dash Industry Forum nor the names of its 51841 * contributors may be used to endorse or promote products derived from this software 51842 * without specific prior written permission. 51843 * 51844 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51845 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51846 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51847 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51848 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
51848INCLUDING, BUT 51849 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51850 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51851 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51852 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51853 * POSSIBILITY OF SUCH DAMAGE. 51854 */ 51855/** 51856 * @class 51857 */ 51858"use strict"; 51859 51860Object.defineProperty(exports, "__esModule", { 51861 value: true 51862}); 51863 51864function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 51865 51866var RepresentationSwitch = 51867/** 51868 * @description This Object holds reference to the info at quality switch between two representations. 51869 */ 51870function RepresentationSwitch() { 51871 _classCallCheck(this, RepresentationSwitch); 51872 51873 /** 51874 * Time of the switch event. 51875 * @public 51876 */ 51877 this.t = null; 51878 /** 51879 * The media presentation time of the earliest access unit 51880 * (out of all media content components) played out from 51881 * the Representation. 51882 * 51883 * @public 51884 */ 51885 this.mt = null; 51886 /** 51887 * Value of Representation@id identifying the switch-to Representation. 51888 * @public 51889 */ 51890 this.to = null; 51891 /** 51892 * If not present, this metrics concerns the Representation as a whole. 51893 * If present, lto indicates the value of SubRepresentation@level within 51894 * Representation identifying the switch-to level of the Representation. 51895 * 51896 * @public 51897 */ 51898 this.lto = null; 51899}; 51900 51901exports["default"] = RepresentationSwitch; 51902module.exports = exports["default"]; 51903 51904},{}],228:[function(_dereq_,module,exports){ 51905/** 51906 * The copyright in this software is being made available under the BSD License, 51907 * included below. This software may be subject to other third party and contributor 51908 * rights, including patent rights, and no such rights are granted under this license. 51909 * 51910 * Copyright (c) 2013, Dash Industry Forum. 51911 * All rights reserved. 51912 * 51913 * Redistribution and use in source and binary forms, with or without modification, 51914 * are permitted provided that the following conditions are met: 51915 * * Redistributions of source code must retain the above copyright notice, this 51916 * list of conditions and the following disclaimer. 51917 * * Redistributions in binary form must reproduce the above copyright notice, 51918 * this list of conditions and the following disclaimer in the documentation and/or 51919 * other materials provided with the distribution. 51920 * * Neither the name of Dash Industry Forum nor the names of its 51921 * contributors may be used to endorse or promote products derived from this software 51922 * without specific prior written permission. 51923 * 51924 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51925 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51926 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51927 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51928 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 51929 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51930 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51931 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51932 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51933 * POSSIBILITY OF SUCH DAMAGE. 51934 */ 51935/** 51936 * @class 51937 */ 51938"use strict"; 51939 51940Object.defineProperty(exports, "__esModule", { 51941 value: true 51942}); 51943 51944function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 51945 51946var RequestsQueue = 51947/** 51948 * @description This Object holds reference to Fragment Model's request queues 51949 */ 51950function RequestsQueue() { 51951 _classCallCheck(this, RequestsQueue); 51952 51953 /** 51954 * Array of all of the requests that have begun to load 51955 * This request may not make it into the executed queue if it is abandon due to ABR rules for example. 51956 * @public 51957 */ 51958 this.loadingRequests = []; 51959 /** 51960 * Array of the The requests that have completed 51961 * @public 51962 */ 51963 this.executedRequests = []; 51964}; 51965 51966exports["default"] = RequestsQueue; 51967module.exports = exports["default"]; 51968 51969},{}],229:[function(_dereq_,module,exports){ 51970/** 51971 * The copyright in this software is being made available under the BSD License, 51972 * included below. This software may be subject to other third party and contributor 51973 * rights, including patent rights, and no such rights are granted under this license. 51974 * 51975 * Copyright (c) 2013, Dash Industry Forum. 51976 * All rights reserved. 51977 * 51978 * Redistribution and use in source and binary forms, with or without modification, 51979 * are permitted provided that the following conditions are met: 51980 * * Redistributions of source code must retain the above copyright notice, this 51981 * list of conditions and the following disclaimer. 51982 * * Redistributions in binary form must reproduce the above copyright notice, 51983 * this list of conditions and the following disclaimer in the documentation and/or 51984 * other materials provided with the distribution. 51985 * * Neither the name of Dash Industry Forum nor the names of its 51986 * contributors may be used to endorse or promote products derived from this software 51987 * without specific prior written permission. 51988 * 51989 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 51990 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 51991 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51992 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 51993 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (
51993INCLUDING, BUT 51994 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51995 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51996 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51997 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51998 * POSSIBILITY OF SUCH DAMAGE. 51999 */ 52000/** 52001 * @class 52002 */ 52003"use strict"; 52004 52005Object.defineProperty(exports, "__esModule", { 52006 value: true 52007}); 52008 52009function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 52010 52011var SchedulingInfo = 52012/** 52013 * @description This Object holds reference to the index handling of the current fragment being loaded or executed. 52014 */ 52015function SchedulingInfo() { 52016 _classCallCheck(this, SchedulingInfo); 52017 52018 /** 52019 * Type of stream Audio | Video | FragmentedText 52020 * @public 52021 */ 52022 this.mediaType = null; 52023 /** 52024 * Time of the scheduling event. 52025 * @public 52026 */ 52027 this.t = null; 52028 52029 /** 52030 * Type of fragment (initialization | media) 52031 * @public 52032 */ 52033 this.type = null; 52034 /** 52035 * Presentation start time of fragment 52036 * @public 52037 */ 52038 this.startTime = null; 52039 /** 52040 * Availability start time of fragment 52041 * @public 52042 */ 52043 this.availabilityStartTime = null; 52044 /** 52045 * Duration of fragment 52046 * @public 52047 */ 52048 this.duration = null; 52049 /** 52050 * Bit Rate Quality of fragment 52051 * @public 52052 */ 52053 this.quality = null; 52054 /** 52055 * Range of fragment 52056 * @public 52057 */ 52058 this.range = null; 52059 52060 /** 52061 * Current state of fragment 52062 * @public 52063 */ 52064 this.state = null; 52065}; 52066 52067exports["default"] = SchedulingInfo; 52068module.exports = exports["default"]; 52069 52070},{}],230:[function(_dereq_,module,exports){ 52071/** 52072 * The copyright in this software is being made available under the BSD License, 52073 * included below. This software may be subject to other third party and contributor 52074 * rights, including patent rights, and no such rights are granted under this license. 52075 * 52076 * Copyright (c) 2013, Dash Industry Forum. 52077 * All rights reserved. 52078 * 52079 * Redistribution and use in source and binary forms, with or without modification, 52080 * are permitted provided that the following conditions are met: 52081 * * Redistributions of source code must retain the above copyright notice, this 52082 * list of conditions and the following disclaimer. 52083 * * Redistributions in binary form must reproduce the above copyright notice, 52084 * this list of conditions and the following disclaimer in the documentation and/or 52085 * other materials provided with the distribution. 52086 * * Neither the name of Dash Industry Forum nor the names of its 52087 * contributors may be used to endorse or promote products derived from this software 52088 * without specific prior written permission. 52089 * 52090 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY 52091 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 52092 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 52093 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 52094 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 52095 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 52096 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 52097 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 52098 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 52099 * POSSIBILITY OF SUCH DAMAGE. 52100 */ 52101/** 52102 * @class 52103 */ 52104"use strict"; 52105 52106Object.defineProperty(exports, "__esModule", { 52107 value: true 52108}); 52109 52110function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 52111 52112var TCPConnection = 52113/** 52114 * @description This Object holds reference to the current tcp connection 52115 */ 52116function TCPConnection() { 52117 _classCallCheck(this, TCPConnection); 52118 52119 /** 52120 * Identifier of the TCP connection on which the HTTP request was sent. 52121 * @public 52122 */ 52123 this.tcpid = null; 52124 /** 52125 * IP Address of the interface over which the client is receiving the TCP data. 52126 * @public 52127 */ 52128 this.dest = null; 52129 /** 52130 * Real-Time | The time at which the connection was opened (sending time of the initial SYN or connect socket operation). 52131 * @public 52132 */ 52133 this.topen = null; 52134 /** 52135 * Real-Time | The time at which the connection was closed (sending or reception time of FIN or RST or close socket operation). 52136 * @public 52137 */ 52138 this.tclose = null; 52139 /** 52140 * Connect time in ms (time from sending the initial SYN to receiving the ACK or completion of the connect socket operation). 52141 * @public 52142 */ 52143 this.tconnect = null; 52144}; 52145 52146exports["default"] = TCPConnection; 52147module.exports = exports["default"]; 52148 52149},{}]},{},[5]) 52150//# sourceMappingURL=dash.all.debug.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.