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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 2exports.FLACDemuxer = require('./src/demuxer'); 3exports.FLACDecoder = require('./src/decoder'); 4require('./src/ogg'); 5 6},{"./src/decoder":2,"./src/demuxer":3,"./src/ogg":4}],2:[function(require,module,exports){ 7/* 8 * FLAC.js - Free Lossless Audio Codec decoder in JavaScript 9 * Original C version from FFmpeg (c) 2003 Alex Beregszaszi 10 * JavaScript port by Devon Govett and Jens Nockert of Official.fm Labs 11 * 12 * Licensed under the same terms as the original. The original 13 * license follows. 14 * 15 * FLAC.js is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU Lesser General Public 17 * License as published by the Free Software Foundation; either 18 * version 2.1 of the License, or (at your option) any later version. 19 * 20 * FLAC.js is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 * Lesser General Public License for more details. 24 * 25 */ 26 27var AV = (window.AV); 28 29var FLACDecoder = AV.Decoder.extend(function() { 30 AV.Decoder.register('flac', this); 31 32 this.prototype.setCookie = function(cookie) { 33 this.cookie = cookie; 34 35 // initialize arrays 36 this.decoded = []; 37 for (var i = 0; i < this.format.channelsPerFrame; i++) { 38 this.decoded[i] = new Int32Array(cookie.maxBlockSize); 39 } 40 41 // for 24 bit lpc frames, this is used to simulate a 64 bit int 42 this.lpc_total = new Int32Array(2); 43 }; 44 45 const BLOCK_SIZES = new Int16Array([ 46 0, 192, 576 << 0, 576 << 1, 576 << 2, 576 << 3, 0, 0, 47 256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6, 256 << 7 48 ]); 49 50 const SAMPLE_RATES = new Int32Array([ 51 0, 88200, 176400, 192000, 52 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, 53 0, 0, 0, 0 54 ]); 55 56 const SAMPLE_SIZES = new Int8Array([ 57 0, 8, 12, 0, 16, 20, 24, 0 58 ]); 59 60 const MAX_CHANNELS = 8, 61 CHMODE_INDEPENDENT = 0, 62 CHMODE_LEFT_SIDE = 8, 63 CHMODE_RIGHT_SIDE = 9, 64 CHMODE_MID_SIDE = 10; 65 66 this.prototype.readChunk = function() { 67 var stream = this.bitstream; 68 if (!stream.available(32)) 69 return; 70 71 // frame sync code 72 if ((stream.read(15) & 0x7FFF) !== 0x7FFC) 73 throw new Error('Invalid sync code'); 74 75 var isVarSize = stream.read(1), // variable block size stream code 76 bsCode = stream.read(4), // block size 77 srCode = stream.read(4), // sample rate code 78 chMode = stream.read(4), // channel mode 79 bpsCode = stream.read(3); // bits per sample 80 81 stream.advance(1); // reserved bit 82 83 // channels 84 this.chMode = chMode; 85 var channels; 86 87 if (chMode < MAX_CHANNELS) { 88 channels = chMode + 1; 89 this.chMode = CHMODE_INDEPENDENT; 90 } else if (chMode <= CHMODE_MID_SIDE) { 91 channels = 2; 92 } else { 93 throw new Error('Invalid channel mode'); 94 } 95 96 if (channels !== this.format.channelsPerFrame) 97 throw new Error('Switching channel layout mid-stream not supported.'); 98 99 // bits per sample 100 if (bpsCode === 3 || bpsCode === 7) 101 throw new Error('Invalid sample size code'); 102 103 this.bps = SAMPLE_SIZES[bpsCode]; 104 if (this.bps !== this.format.bitsPerChannel) 105 throw new Error('Switching bits per sample mid-stream not supported.'); 106 107 // sample number or frame number 108 // see http://www.hydrogenaudio.org/forums/index.php?s=ea7085ffe6d57132c36e6105c0d434c9&showtopic=88390&pid=754269&st=0&#entry754269 109 var ones = 0; 110 while (stream.read(1) === 1) 111 ones++; 112 113 var frame_or_sample_num = stream.read(7 - ones); 114 for (; ones > 1; ones--) { 115 stream.advance(2); // == 2 116 frame_or_sample_num = (frame_or_sample_num << 6) | stream.read(6); 117 } 118 119 // block size 120 if (bsCode === 0) 121 throw new Error('Reserved blocksize code'); 122 else if (bsCode === 6) 123 this.blockSize = stream.read(8) + 1; 124 else if (bsCode === 7) 125 this.blockSize = stream.read(16) + 1; 126 else 127 this.blockSize = BLOCK_SIZES[bsCode]; 128 129 // sample rate 130 var sampleRate; 131 if (srCode < 12) 132 sampleRate = SAMPLE_RATES[srCode]; 133 else if (srCode === 12) 134 sampleRate = stream.read(8) * 1000; 135 else if (srCode === 13) 136 sampleRate = stream.read(16); 137 else if (srCode === 14) 138 sampleRate = stream.read(16) * 10; 139 else 140 throw new Error('Invalid sample rate code'); 141 142 stream.advance(8); // skip CRC check 143 144 // subframes 145 for (var i = 0; i < channels; i++) 146 this.decodeSubframe(i); 147 148 stream.align(); 149 stream.advance(16); // skip CRC frame footer 150 151 var is32 = this.bps > 16, 152 output = new ArrayBuffer(this.blockSize * channels * (is32 ? 4 : 2)), 153 buf = is32 ? new Int32Array(output) : new Int16Array(output), 154 blockSize = this.blockSize, 155 decoded = this.decoded, 156 j = 0; 157 158 switch (this.chMode) { 159 case CHMODE_INDEPENDENT: 160 for (var k = 0; k < blockSize; k++) { 161 for (var i = 0; i < channels; i++) { 162 buf[j++] = decoded[i][k]; 163 } 164 } 165 break; 166 167 case CHMODE_LEFT_SIDE: 168 for (var i = 0; i < blockSize; i++) { 169 var left = decoded[0][i], 170 right = decoded[1][i]; 171 172 buf[j++] = left; 173 buf[j++] = (left - right); 174 } 175 break; 176 177 case CHMODE_RIGHT_SIDE: 178 for (var i = 0; i < blockSize; i++) { 179 var left = decoded[0][i], 180 right = decoded[1][i]; 181 182 buf[j++] = (left + right); 183 buf[j++] = right; 184 } 185 break; 186 187 case CHMODE_MID_SIDE: 188 for (var i = 0; i < blockSize; i++) { 189 var left = decoded[0][i], 190 right = decoded[1][i]; 191 192 left -= right >> 1; 193 buf[j++] = (left + right); 194 buf[j++] = left; 195 } 196 break; 197 } 198 199 return buf; 200 }; 201 202 this.prototype.decodeSubframe = function(channel) { 203 var wasted = 0, 204 stream = this.bitstream, 205 blockSize = this.blockSize, 206 decoded = this.decoded; 207 208 this.curr_bps = this.bps; 209 if (channel === 0) { 210 if (this.chMode === CHMODE_RIGHT_SIDE) 211 this.curr_bps++; 212 } else { 213 if (this.chMode === CHMODE_LEFT_SIDE || this.chMode === CHMODE_MID_SIDE) 214 this.curr_bps++; 215 } 216 217 if (stream.read(1)) 218 throw new Error("Invalid subframe padding"); 219 220 var type = stream.read(6); 221 222 if (stream.read(1)) { 223 wasted = 1; 224 while (!stream.read(1)) 225 wasted++; 226 227 this.curr_bps -= wasted; 228 } 229 230 if (this.curr_bps > 32) 231 throw new Error("decorrelated bit depth > 32 (" + this.curr_bps + ")"); 232 233 if (type === 0) { 234 var tmp = stream.read(this.curr_bps, true); 235 for (var i = 0; i < blockSize; i++) 236 decoded[channel][i] = tmp; 237 238 } else if (type === 1) { 239 var bps = this.curr_bps; 240 for (var i = 0; i < blockSize; i++) 241 decoded[channel][i] = stream.read(bps, true); 242 243 } else if ((type >= 8) && (type <= 12)) { 244 this.decode_subframe_fixed(channel, type & ~0x8); 245 246 } else if (type >= 32) { 247 this.decode_subframe_lpc(channel, (type & ~0x20) + 1); 248 249 } else { 250 throw new Error("Invalid coding type"); 251 } 252 253 if (wasted) { 254 for (var i = 0; i < blockSize; i++) 255 decoded[channel][i] <<= wasted; 256 } 257 }; 258 259 this.prototype.decode_subframe_fixed = function(channel, predictor_order) { 260 var decoded = this.decoded[channel], 261 stream = this.bitstream, 262 bps = this.curr_bps; 263 264 // warm up samples 265 for (var i = 0; i < predictor_order; i++) 266 decoded[i] = stream.read(bps, true); 267 268 this.decode_residuals(channel, predictor_order); 269 270 var a = 0, b = 0, c = 0, d = 0; 271 272 if (predictor_order > 0) 273 a = decoded[predictor_order - 1]; 274 275 if (predictor_order > 1) 276 b = a - decoded[predictor_order - 2]; 277 278 if (predictor_order > 2) 279 c = b - decoded[predictor_order - 2] + decoded[predictor_order - 3]; 280 281 if (predictor_order > 3) 282 d = c - decoded[predictor_order - 2] + 2 * decoded[predictor_order - 3] - decoded[predictor_order - 4]; 283 284 switch (predictor_order) { 285 case 0: 286 break; 287 288 case 1: 289 case 2: 290 case 3: 291 case 4: 292 var abcd = new Int32Array([a, b, c, d]), 293 blockSize = this.blockSize; 294 295 for (var i = predictor_order; i < blockSize; i++) { 296 abcd[predictor_order - 1] += decoded[i]; 297 298 for (var j = predictor_order - 2; j >= 0; j--) { 299 abcd[j] += abcd[j + 1]; 300 } 301 302 decoded[i] = abcd[0]; 303 } 304 305 break; 306 307 default: 308 throw new Error("Invalid Predictor Order " + predictor_order); 309 } 310 }; 311 312 this.prototype.decode_subframe_lpc = function(channel, predictor_order) { 313 var stream = this.bitstream, 314 decoded = this.decoded[channel], 315 bps = this.curr_bps, 316 blockSize = this.blockSize; 317 318 // warm up samples 319 for (var i = 0; i < predictor_order; i++) { 320 decoded[i] = stream.read(bps, true); 321 } 322 323 var coeff_prec = stream.read(4) + 1; 324 if (coeff_prec === 16) 325 throw new Error("Invalid coefficient precision"); 326 327 var qlevel = stream.read(5, true); 328 if (qlevel < 0) 329 throw new Error("Negative qlevel, maybe buggy stream"); 330 331 var coeffs = new Int32Array(32); 332 for (var i = 0; i < predictor_order; i++) { 333 coeffs[i] = stream.read(coeff_prec, true); 334 } 335 336 this.decode_residuals(channel, predictor_order); 337 338 if (this.bps <= 16) { 339 for (var i = predictor_order; i < blockSize - 1; i += 2) { 340 var d = decoded[i - predictor_order], 341 s0 = 0, s1 = 0, c = 0; 342 343 for (var j = predictor_order - 1; j > 0; j--) { 344 c = coeffs[j]; 345 s0 += c * d; 346 d = decoded[i - j]; 347 s1 += c * d; 348 } 349 350 c = coeffs[0]; 351 s0 += c * d; 352 d = decoded[i] += (s0 >> qlevel); 353 s1 += c * d; 354 decoded[i + 1] += (s1 >> qlevel); 355 } 356 357 if (i < blockSize) { 358 var sum = 0; 359 for (var j = 0; j < predictor_order; j++) 360 sum += coeffs[j] * decoded[i - j - 1]; 361 362 decoded[i] += (sum >> qlevel); 363 } 364 } else { 365 // simulate 64 bit integer using an array of two 32 bit ints 366 var total = this.lpc_total; 367 for (var i = predictor_order; i < blockSize; i++) { 368 // reset total to 0 369 total[0] = 0; 370 total[1] = 0; 371 372 for (j = 0; j < predictor_order; j++) { 373 // simulate `total += coeffs[j] * decoded[i - j - 1]` 374 multiply_add(total, coeffs[j], decoded[i - j - 1]); 375 } 376 377 // simulate `decoded[i] += total >> qlevel` 378 // we know that qlevel < 32 since it is a 5 bit field (see above) 379 decoded[i] += (total[0] >>> qlevel) | (total[1] << (32 - qlevel)); 380 } 381 } 382 }; 383 384 const TWO_PWR_32_DBL = Math.pow(2, 32); 385 386 // performs `total += a * b` on a simulated 64 bit int 387 // total is an Int32Array(2) 388 // a and b are JS numbers (32 bit ints) 389 function multiply_add(total, a, b) { 390 // multiply a * b (we can use normal JS multiplication for this) 391 var r = a * b; 392 var n = r < 0; 393 if (n) 394 r = -r; 395 396 var r_low = (r % TWO_PWR_32_DBL) | 0; 397 var r_high = (r / TWO_PWR_32_DBL) | 0; 398 if (n) { 399 r_low = ~r_low + 1; 400 r_high = ~r_high; 401 } 402 403 // add result to total 404 var a48 = total[1] >>> 16; 405 var a32 = total[1] & 0xFFFF; 406 var a16 = total[0] >>> 16; 407 var a00 = total[0] & 0xFFFF; 408 409 var b48 = r_high >>> 16; 410 var b32 = r_high & 0xFFFF; 411 var b16 = r_low >>> 16; 412 var b00 = r_low & 0xFFFF; 413 414 var c48 = 0, c32 = 0, c16 = 0, c00 = 0; 415 c00 += a00 + b00; 416 c16 += c00 >>> 16; 417 c00 &= 0xFFFF; 418 c16 += a16 + b16; 419 c32 += c16 >>> 16; 420 c16 &= 0xFFFF; 421 c32 += a32 + b32; 422 c48 += c32 >>> 16; 423 c32 &= 0xFFFF; 424 c48 += a48 + b48; 425 c48 &= 0xFFFF; 426 427 // store result back in total 428 total[0] = (c16 << 16) | c00; 429 total[1] = (c48 << 16) | c32; 430 } 431 432 const INT_MAX = 32767; 433 434 this.prototype.decode_residuals = function(channel, predictor_order) { 435 var stream = this.bitstream, 436 method_type = stream.read(2); 437 438 if (method_type > 1) 439 throw new Error('Illegal residual coding method ' + method_type); 440 441 var rice_order = stream.read(4), 442 samples = (this.blockSize >>> rice_order); 443 444 if (predictor_order > samples) 445 throw new Error('Invalid predictor order ' + predictor_order + ' > ' + samples); 446 447 var decoded = this.decoded[channel], 448 sample = predictor_order, 449 i = predictor_order; 450 451 for (var partition = 0; partition < (1 << rice_order); partition++) { 452 var tmp = stream.read(method_type === 0 ? 4 : 5); 453 454 if (tmp === (method_type === 0 ? 15 : 31)) { 455 tmp = stream.read(5); 456 for (; i < samples; i++) 457 decoded[sample++] = stream.read(tmp, true); 458 459 } else { 460 for (; i < samples; i++) 461 decoded[sample++] = this.golomb(tmp, INT_MAX, 0); 462 } 463 464 i = 0; 465 } 466 }; 467 468 const MIN_CACHE_BITS = 25; 469 470 this.prototype.golomb = function(k, limit, esc_len) { 471 var data = this.bitstream, 472 offset = data.bitPosition, 473 buf = data.peek(32 - offset) << offset, 474 v = 0; 475 476 var log = 31 - clz(buf | 1); // log2(buf) 477 478 if (log - k >= 32 - MIN_CACHE_BITS && 32 - log < limit) { 479 buf >>>= log - k; 480 buf += (30 - log) << k; 481 482 data.advance(32 + k - log); 483 v = buf; 484 485 } else { 486 for (var i = 0; data.read(1) === 0; i++) 487 buf = data.peek(32 - offset) << offset; 488 489 if (i < limit - 1) { 490 if (k) 491 buf = data.read(k); 492 else 493 buf = 0; 494 495 v = buf + (i << k); 496 497 } else if (i === limit - 1) { 498 buf = data.read(esc_len); 499 v = buf + 1; 500 501 } else { 502 v = -1; 503 } 504 } 505 506 return (v >> 1) ^ -(v & 1); 507 }; 508 509 // Should be in the damned standard library... 510 function clz(input) { 511 var output = 0, 512 curbyte = 0; 513 514 while(true) { // emulate goto in JS using the break statement :D 515 curbyte = input >>> 24; 516 if (curbyte) break; 517 output += 8; 518 519 curbyte = input >>> 16; 520 if (curbyte & 0xff) break; 521 output += 8; 522 523 curbyte = input >>> 8; 524 if (curbyte & 0xff) break; 525 output += 8; 526 527 curbyte = input; 528 if (curbyte & 0xff) break; 529 output += 8; 530 531 return output; 532 } 533 534 if (!(curbyte & 0xf0)) 535 output += 4; 536 else 537 curbyte >>>= 4; 538 539 if (curbyte & 0x8) 540 return output; 541 542 if (curbyte & 0x4) 543 return output + 1; 544 545 if (curbyte & 0x2) 546 return output + 2; 547 548 if (curbyte & 0x1) 549 return output + 3; 550 551 // shouldn't get here 552 return output + 4; 553 } 554}); 555 556module.exports = FLACDecoder; 557 558},{}],3:[function(require,module,exports){ 559/* 560 * FLAC.js - Free Lossless Audio Codec decoder in JavaScript 561 * By Devon Govett and Jens Nockert of Official.fm Labs 562 * 563 * FLAC.js is free software; you can redistribute it and/or 564 * modify it under the terms of the GNU Lesser General Public 565 * License as published by the Free Software Foundation; either 566 * version 2.1 of the License, or (at your option) any later version. 567 * 568 * FLAC.js is distributed in the hope that it will be useful, 569 * but WITHOUT ANY WARRANTY; without even the implied warranty of 570 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 571 * Lesser General Public License for more details. 572 * 573 */ 574 575var AV = (window.AV); 576 577var FLACDemuxer = AV.Demuxer.extend(function() { 578 AV.Demuxer.register(this); 579 580 this.probe = function(buffer) { 581 return buffer.peekString(0, 4) === 'fLaC'; 582 } 583 584 const STREAMINFO = 0, 585 PADDING = 1, 586 APPLICATION = 2, 587 SEEKTABLE = 3, 588 VORBIS_COMMENT = 4, 589 CUESHEET = 5, 590 PICTURE = 6, 591 INVALID = 127, 592 STREAMINFO_SIZE = 34; 593 594 this.prototype.readChunk = function() { 595 var stream = this.stream; 596 597 if (!this.readHeader && stream.available(4)) { 598 if (stream.readString(4) !== 'fLaC') 599 return this.emit('error', 'Invalid FLAC file.'); 600 601 this.readHeader = true; 602 } 603 604 while (stream.available(1) && !this.last) { 605 if (!this.readBlockHeaders) { 606 var tmp = stream.readUInt8(); 607 this.last = (tmp & 0x80) === 0x80, 608 this.type = tmp & 0x7F, 609 this.size = stream.readUInt24(); 610 } 611 612 if (!this.foundStreamInfo && this.type !== STREAMINFO) 613 return this.emit('error', 'STREAMINFO must be the first block'); 614 615 if (!stream.available(this.size)) 616 return; 617 618 switch (this.type) { 619 case STREAMINFO: 620 if (this.foundStreamInfo) 621 return this.emit('error', 'STREAMINFO can only occur once.'); 622 623 if (this.size !== STREAMINFO_SIZE) 624 return this.emit('error', 'STREAMINFO size is wrong.'); 625 626 this.foundStreamInfo = true; 627 var bitstream = new AV.Bitstream(stream); 628 629 var cookie = { 630 minBlockSize: bitstream.read(16), 631 maxBlockSize: bitstream.read(16), 632 minFrameSize: bitstream.read(24), 633 maxFrameSize: bitstream.read(24) 634 }; 635 636 this.format = { 637 formatID: 'flac', 638 sampleRate: bitstream.read(20), 639 channelsPerFrame: bitstream.read(3) + 1, 640 bitsPerChannel: bitstream.read(5) + 1 641 }; 642 643 this.emit('format', this.format); 644 this.emit('cookie', cookie); 645 646 var sampleCount = bitstream.read(36); 647 this.emit('duration', sampleCount / this.format.sampleRate * 1000 | 0); 648 649 stream.advance(16); // skip MD5 hashes 650 this.readBlockHeaders = false; 651 break; 652 653 /* 654 I am only looking at the least significant 32 bits of sample number and offset data 655 This is more than sufficient for the longest flac file I have (~50 mins 2-channel 16-bit 44.1k which uses about 7.5% of the UInt32 space for the largest offset) 656 Can certainly be improved by storing sample numbers and offests as doubles, but would require additional overriding of the searchTimestamp and seek functions (possibly more?) 657 Also the flac faq suggests it would be possible to find frame lengths and thus create seek points on the fly via decoding but I assume this would be slow 658 I may look into these thigns though as my project progresses 659 */ 660 case SEEKTABLE: 661 for(var s=0; s<this.size/18; s++) 662 { 663 if(stream.peekUInt32(0) == 0xFFFFFFFF && stream.peekUInt32(1) == 0xFFFFFFFF) 664 { 665 //placeholder, ignore 666 stream.advance(18); 667 } else { 668 if(stream.readUInt32() > 0) 669 { 670 this.emit('error', 'Seek points with sample number >UInt32 not supported'); 671 } 672 var samplenum = stream.readUInt32(); 673 if(stream.readUInt32() > 0) 674 { 675 this.emit('error', 'Seek points with stream offset >UInt32 not supported'); 676 } 677 var offset = stream.readUInt32(); 678 679 stream.advance(2); 680 681 this.addSeekPoint(offset, samplenum); 682 } 683 } 684 break; 685 686 case VORBIS_COMMENT: 687 // see http://www.xiph.org/vorbis/doc/v-comment.html 688 this.metadata || (this.metadata = {}); 689 var len = stream.readUInt32(true); 690 691 this.metadata.vendor = stream.readString(len); 692 var length = stream.readUInt32(true); 693 694 for (var i = 0; i < length; i++) { 695 len = stream.readUInt32(true); 696 var str = stream.readString(len, 'utf8'), 697 idx = str.indexOf('='); 698 699 this.metadata[str.slice(0, idx).toLowerCase()] = str.slice(idx + 1); 700 } 701 702 // TODO: standardize field names across formats 703 break; 704 705 case PICTURE: 706 var type = stream.readUInt32(); 707 if (type !== 3) { // make sure this is album art (type 3) 708 stream.advance(this.size - 4); 709 } else { 710 var mimeLen = stream.readUInt32(), 711 mime = stream.readString(mimeLen), 712 descLen = stream.readUInt32(), 713 description = stream.readString(descLen), 714 width = stream.readUInt32(), 715 height = stream.readUInt32(), 716 depth = stream.readUInt32(), 717 colors = stream.readUInt32(), 718 length = stream.readUInt32(), 719 picture = stream.readBuffer(length); 720 721 this.metadata || (this.metadata = {}); 722 this.metadata.coverArt = picture; 723 } 724 725 // does anyone want the rest of the info? 726 break; 727 728 default: 729 stream.advance(this.size); 730 this.readBlockHeaders = false; 731 } 732 733 if (this.last && this.metadata) 734 this.emit('metadata', this.metadata); 735 } 736 737 while (stream.available(1) && this.last) { 738 var buffer = stream.readSingleBuffer(stream.remainingBytes()); 739 this.emit('data', buffer); 740 } 741 } 742 743}); 744 745module.exports = FLACDemuxer; 746 747},{}],4:[function(require,module,exports){ 748var AV = (window.AV); 749 750// if ogg.js exists, register a plugin 751try { 752 var OggDemuxer = (window.AV.OggDemuxer); 753} catch (e) {}; 754if (!OggDemuxer) return; 755 756OggDemuxer.plugins.push({ 757 magic: "\177FLAC", 758 759 init: function() { 760 this.list = new AV.BufferList(); 761 this.stream = new AV.Stream(this.list); 762 }, 763 764 readHeaders: function(packet) { 765 var stream = this.stream; 766 this.list.append(new AV.Buffer(packet)); 767 768 stream.advance(5); // magic 769 if (stream.readUInt8() != 1) 770 throw new Error('Unsupported FLAC version'); 771 772 stream.advance(3); 773 if (stream.peekString(0, 4) != 'fLaC') 774 throw new Error('Not flac'); 775 776 this.flac = AV.Demuxer.find(stream.peekSingleBuffer(0, stream.remainingBytes())); 777 if (!this.flac) 778 throw new Error('Flac demuxer not found'); 779 780 this.flac.prototype.readChunk.call(this); 781 return true; 782 }, 783 784 readPacket: function(packet) { 785 this.list.append(new AV.Buffer(packet)); 786 this.flac.prototype.readChunk.call(this); 787 } 788}); 789 790},{}]},{},[1]) 791 792 793//# sourceMappingURL=flac.js.map