index.html 8.43 KB
<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title></title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width">

  <link rel="stylesheet" href="css/normalize.min.css">
  <link rel="stylesheet" href="css/main.css">

  <script src="js/vendor/modernizr-2.6.2.min.js"></script>
</head>
<body>
  <!--[if lt IE 7]>
      <p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
      <![endif]-->

  <div class="header-container">
    <header class="wrapper clearfix">
      <h1 class="title">Transmux Analyzer</h1>
    </header>
  </div>

  <div class="main-container">
    <div class="main wrapper clearfix">

      <article>
        <header>
          <p>
            This page can help you compare the results of the
            transmuxing performed by videojs-contrib-hls with a known,
            working file produced by another tool. You could use
            ffmpeg to transform an MPEG-2 transport stream into an FLV
            with a command like this:
            <pre>ffmpeg -i input.ts -acodec copy -vcodec copy output.flv</pre>
          </p>
        </header>
        <section>
          <h2>Inputs</h2>
          <form id="inputs">
            <fieldset>
              <label>
                Your original MP2T segment:
                <input type="file" id="original">
              </label>
              <label>
                Key (optional):
                <input type="text" id="key">
              </label>
              <label>
                IV (optional):
                <input type="text" id="iv">
              </label>
            </fieldset>
            <label>
              A working, FLV version of the underlying stream
              produced by another tool:
              <input type="file" id="working">
            </label>
          </form>
        </section>
        <section>
          <h2>Tag Comparison</h2>
          <div class="result-wrapper">
            <h3>videojs-contrib-hls</h3>
            <ol class="vjs-tags">
            </ol>
          </div>
          <div class="result-wrapper">
            <h3>Working</h3>
            <ol class="working-tags">
            </ol>
          </div>
        </section>
        <section>
          <h2>Results</h2>
          <div class="result-wrapper">
            <h3>videojs-contrib-hls</h3>
            <div class="vjs-hls-output result">
              <p>
                The results of transmuxing your input file with
                videojs-contrib-hls will show up here.
              </p>
            </div>
          </div>
          <div class="result-wrapper">
            <h3>Working</h3>
            <div class="working-output result">
              <p>
                The "good" version of the file will show up here.
              </p>
            </div>
          </div>
        </section>
      </article>

    </div> <!-- #main -->
  </div> <!-- #main-container -->

  <div class="footer-container">
    <footer class="wrapper">
      <h3>footer</h3>
    </footer>
  </div>


  <script>
    window.videojs = {
      Hls: {}
    };
  </script>
  <!-- transmuxing -->
  <script src="../../src/stream.js"></script>
  <script src="../../src/flv-tag.js"></script>
  <script src="../../src/exp-golomb.js"></script>
  <script src="../../src/h264-stream.js"></script>
  <script src="../../src/aac-stream.js"></script>
  <script src="../../src/metadata-stream.js"></script>
  <script src="../../src/segment-parser.js"></script>
  <script src="../../node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
  <script src="../../src/decrypter.js"></script>
  
  <script src="../../src/bin-utils.js"></script>
  <script>
    var inputs = document.getElementById('inputs'),
        original = document.getElementById('original'),
        key = document.getElementById('key'),
        iv = document.getElementById('iv'),
        working = document.getElementById('working'),

        vjsTags = document.querySelector('.vjs-tags'),
        workingTags = document.querySelector('.working-tags'),

        vjsOutput = document.querySelector('.vjs-hls-output'),
        workingOutput = document.querySelector('.working-output'),

        tagTypes = {
          0x08: 'audio',
          0x09: 'video',
          0x12: 'metadata'
        };

    videojs.log = console.log.bind(console);

    original.addEventListener('change', function() {
      var reader = new FileReader();
      reader.addEventListener('loadend', function() {
        var parser = new videojs.Hls.SegmentParser(),
            tags = [parser.getFlvHeader()],
            tag,
            bytes,
            hex,
            li,
            byteLength = 0,
            data,
            i,
            pos;

        // clear old tag info
        vjsTags.innerHTML = '';

        // optionally, decrypt the segment
        if (key.value && iv.value) {
          bytes = videojs.Hls.decrypt(new Uint8Array(reader.result),
                                      key.value.match(/([0-9a-f]{8})/gi).map(function(e) {
                                        return parseInt(e, 16);
                                      }),
                                      iv.value.match(/([0-9a-f]{8})/gi).map(function(e) {
                                        return parseInt(e, 16);
                                      }));
        } else {
          bytes = new Uint8Array(reader.result);
        }

        parser.parseSegmentBinaryData(bytes);

        // collect all the tags
        while (parser.tagsAvailable()) {
          tag = parser.getNextTag();
          tags.push(tag.bytes);
          li = document.createElement('li');
          li.innerHTML = tagTypes[tag.bytes[0]] + ': ' + tag.bytes.byteLength + 'B';
          vjsTags.appendChild(li);
        }
        // create a uint8array for the entire segment and copy everything over
        i = tags.length;
        while (i--) {
          byteLength += tags[i].byteLength;
        }
        data = new Uint8Array(byteLength);
        i = tags.length;
        pos = byteLength;
        while (i--) {
          pos -= tags[i].byteLength;
          data.set(tags[i], pos);
        }

        hex = '<pre>'
        hex += videojs.Hls.utils.hexDump(data);
        hex += '</pre>'
    
        vjsOutput.innerHTML = hex;
      });
      reader.readAsArrayBuffer(this.files[0]);
    }, false);

    working.addEventListener('change', function() {
      var reader = new FileReader();
      reader.addEventListener('loadend', function() {
        var hex = '<pre>',
            bytes = new Uint8Array(reader.result),
            i = 9, // header
            dataSize,
            li;

        // clear old tag info
        workingTags.innerHTML = '';

        // traverse the tags
        i += 4; // previous tag size
        while (i < bytes.byteLength) {
          dataSize = bytes[i + 1] << 16;
          dataSize |= bytes[i + 2] << 8;
          dataSize |= bytes[i + 3];
          dataSize += 11;

          li = document.createElement('li');
          li.innerHTML = tagTypes[bytes[i]] + ': ' + dataSize + 'B';
          workingTags.appendChild(li);

          i += dataSize; // tag size
          i += 4; // previous tag size
        }

        // output the hex dump
        hex += videojs.Hls.utils.hexDump(bytes);
        hex += '</pre>';
        workingOutput.innerHTML = hex;
      });
      reader.readAsArrayBuffer(this.files[0]);
    }, false);
  </script>
  <script type="text/plain">
    // map nal_unit_types to friendly names
    console.log([
      'unspecified',
      'slice_layer_without_partitioning',
      'slice_data_partition_a_layer',
      'slice_data_partition_b_layer',
      'slice_data_partition_c_layer',
      'slice_layer_without_partitioning_idr',
      'sei',
      'seq_parameter_set',
      'pic_parameter_set',
      'access_unit_delimiter',
      'end_of_seq',
      'end_of_stream',
      'filler',
      'seq_parameter_set_ext',
      'prefix_nal_unit',
      'subset_seq_parameter_set',
      'reserved',
      'reserved',
      'reserved'
    ][nalUnitType]);
  </script>
</body>
</html>