tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mediasource-append-buffer.html (31926B)


      1 <!DOCTYPE html>
      2 <!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
      3 <html>
      4    <head>
      5        <title>SourceBuffer.appendBuffer() test cases</title>
      6        <meta name="timeout" content="long">
      7        <script src="/resources/testharness.js"></script>
      8        <script src="/resources/testharnessreport.js"></script>
      9        <script src="mediasource-util.js"></script>
     10    </head>
     11    <body>
     12        <div id="log"></div>
     13        <script>
     14          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
     15          {
     16              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
     17 
     18              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
     19              test.expectEvent(sourceBuffer, "update", "Append success.");
     20              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
     21              sourceBuffer.appendBuffer(mediaData);
     22 
     23              assert_true(sourceBuffer.updating, "updating attribute is true");
     24 
     25              test.waitForExpectedEvents(function()
     26              {
     27                 assert_false(sourceBuffer.updating, "updating attribute is false");
     28                 test.done();
     29              });
     30          }, "Test SourceBuffer.appendBuffer() event dispatching.");
     31 
     32          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
     33          {
     34              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
     35 
     36              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
     37              test.expectEvent(sourceBuffer, "update", "Append success.");
     38              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
     39              sourceBuffer.appendBuffer(mediaData);
     40 
     41              assert_true(sourceBuffer.updating, "updating attribute is true");
     42 
     43              assert_throws_dom("InvalidStateError",
     44                  function() { sourceBuffer.appendBuffer(mediaData); },
     45                  "appendBuffer() throws an exception there is a pending append.");
     46 
     47              assert_true(sourceBuffer.updating, "updating attribute is true");
     48 
     49              test.waitForExpectedEvents(function()
     50              {
     51                  assert_false(sourceBuffer.updating, "updating attribute is false");
     52                  test.done();
     53              });
     54          }, "Test SourceBuffer.appendBuffer() call during a pending appendBuffer().");
     55 
     56          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
     57          {
     58              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
     59 
     60              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
     61              test.expectEvent(sourceBuffer, "abort", "Append aborted.");
     62              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
     63              sourceBuffer.appendBuffer(mediaData);
     64 
     65              assert_true(sourceBuffer.updating, "updating attribute is true");
     66 
     67              sourceBuffer.abort();
     68 
     69              assert_false(sourceBuffer.updating, "updating attribute is false");
     70 
     71              test.waitForExpectedEvents(function()
     72              {
     73                  assert_false(sourceBuffer.updating, "updating attribute is false");
     74                  test.done();
     75              });
     76          }, "Test SourceBuffer.abort() call during a pending appendBuffer().");
     77 
     78          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
     79          {
     80              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
     81 
     82              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
     83              test.expectEvent(sourceBuffer, "update", "Append success.");
     84              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
     85              sourceBuffer.appendBuffer(mediaData);
     86              assert_true(sourceBuffer.updating, "updating attribute is true");
     87 
     88              test.waitForExpectedEvents(function()
     89              {
     90                  assert_false(sourceBuffer.updating, "updating attribute is false");
     91 
     92                  test.expectEvent(mediaSource, "sourceended", "MediaSource sourceended event");
     93                  mediaSource.endOfStream();
     94                  assert_equals(mediaSource.readyState, "ended", "MediaSource readyState is 'ended'");
     95              });
     96 
     97              test.waitForExpectedEvents(function()
     98              {
     99                  assert_equals(mediaSource.readyState, "ended", "MediaSource readyState is 'ended'");
    100 
    101                  test.expectEvent(mediaSource, "sourceopen", "MediaSource sourceopen event");
    102                  test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    103                  test.expectEvent(sourceBuffer, "update", "Append success.");
    104                  test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    105                  sourceBuffer.appendBuffer(mediaData);
    106 
    107                  assert_equals(mediaSource.readyState, "open", "MediaSource readyState is 'open'");
    108                  assert_true(sourceBuffer.updating, "updating attribute is true");
    109              });
    110 
    111              test.waitForExpectedEvents(function()
    112              {
    113                  assert_equals(mediaSource.readyState, "open", "MediaSource readyState is 'open'");
    114                  assert_false(sourceBuffer.updating, "updating attribute is false");
    115                  test.done();
    116              });
    117          }, "Test SourceBuffer.appendBuffer() triggering an 'ended' to 'open' transition.");
    118 
    119          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    120          {
    121              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    122              test.expectEvent(sourceBuffer, "update", "Append success.");
    123              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    124              sourceBuffer.appendBuffer(mediaData);
    125              assert_true(sourceBuffer.updating, "updating attribute is true");
    126 
    127              test.waitForExpectedEvents(function()
    128              {
    129                  assert_false(sourceBuffer.updating, "updating attribute is false");
    130 
    131                  test.expectEvent(mediaSource, "sourceended", "MediaSource sourceended event");
    132                  mediaSource.endOfStream();
    133                  assert_equals(mediaSource.readyState, "ended", "MediaSource readyState is 'ended'");
    134              });
    135 
    136              test.waitForExpectedEvents(function()
    137              {
    138                  assert_equals(mediaSource.readyState, "ended", "MediaSource readyState is 'ended'");
    139 
    140                  test.expectEvent(mediaSource, "sourceopen", "MediaSource sourceopen event");
    141                  test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    142                  test.expectEvent(sourceBuffer, "update", "Append success.");
    143                  test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    144                  sourceBuffer.appendBuffer(new Uint8Array(0));
    145 
    146                  assert_equals(mediaSource.readyState, "open", "MediaSource readyState is 'open'");
    147                  assert_true(sourceBuffer.updating, "updating attribute is true");
    148              });
    149 
    150              test.waitForExpectedEvents(function()
    151              {
    152                  assert_equals(mediaSource.readyState, "open", "MediaSource readyState is 'open'");
    153                  assert_false(sourceBuffer.updating, "updating attribute is false");
    154                  test.done();
    155              });
    156          }, "Test zero byte SourceBuffer.appendBuffer() call triggering an 'ended' to 'open' transition.");
    157 
    158          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    159          {
    160              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
    161 
    162              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    163              test.expectEvent(sourceBuffer, "abort", "Append aborted.");
    164              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    165              sourceBuffer.appendBuffer(mediaData);
    166 
    167              assert_true(sourceBuffer.updating, "updating attribute is true");
    168              assert_equals(mediaSource.activeSourceBuffers.length, 0, "activeSourceBuffers.length");
    169 
    170              test.expectEvent(mediaSource.sourceBuffers, "removesourcebuffer", "sourceBuffers");
    171              mediaSource.removeSourceBuffer(sourceBuffer);
    172 
    173              assert_false(sourceBuffer.updating, "updating attribute is false");
    174 
    175              assert_throws_dom("InvalidStateError",
    176                  function() { sourceBuffer.appendBuffer(mediaData); },
    177                  "appendBuffer() throws an exception because it isn't attached to the mediaSource anymore.");
    178 
    179              test.waitForExpectedEvents(function()
    180              {
    181                  assert_false(sourceBuffer.updating, "updating attribute is false");
    182                  test.done();
    183              });
    184          }, "Test MediaSource.removeSourceBuffer() call during a pending appendBuffer().");
    185 
    186          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    187          {
    188              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
    189 
    190              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    191              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    192              sourceBuffer.appendBuffer(mediaData);
    193 
    194              assert_true(sourceBuffer.updating, "updating attribute is true");
    195 
    196              assert_throws_dom("InvalidStateError",
    197                  function() { mediaSource.duration = 1.0; },
    198                  "set duration throws an exception when updating attribute is true.");
    199 
    200              test.waitForExpectedEvents(function()
    201              {
    202                  assert_false(sourceBuffer.updating, "updating attribute is false");
    203                  test.done();
    204              });
    205          }, "Test set MediaSource.duration during a pending appendBuffer() for one of its SourceBuffers.");
    206 
    207          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    208          {
    209              mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'"));
    210              mediaSource.addEventListener("sourceended", test.unreached_func("Unexpected event 'sourceended'"));
    211 
    212              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    213              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    214              sourceBuffer.appendBuffer(mediaData);
    215 
    216              assert_true(sourceBuffer.updating, "updating attribute is true");
    217 
    218              assert_throws_dom("InvalidStateError",
    219                  function() { mediaSource.endOfStream(); },
    220                  "endOfStream() throws an exception when updating attribute is true.");
    221 
    222              assert_equals(mediaSource.readyState, "open");
    223 
    224              test.waitForExpectedEvents(function()
    225              {
    226                  assert_false(sourceBuffer.updating, "updating attribute is false");
    227                  assert_equals(mediaSource.readyState, "open");
    228                  test.done();
    229              });
    230          }, "Test MediaSource.endOfStream() during a pending appendBuffer() for one of its SourceBuffers.");
    231 
    232          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    233          {
    234              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
    235 
    236              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    237              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    238              sourceBuffer.appendBuffer(mediaData);
    239 
    240              assert_true(sourceBuffer.updating, "updating attribute is true");
    241 
    242              assert_throws_dom("InvalidStateError",
    243                  function() { sourceBuffer.timestampOffset = 10.0; },
    244                  "set timestampOffset throws an exception when updating attribute is true.");
    245 
    246              test.waitForExpectedEvents(function()
    247              {
    248                  assert_false(sourceBuffer.updating, "updating attribute is false");
    249                  test.done();
    250              });
    251          }, "Test set SourceBuffer.timestampOffset during a pending appendBuffer().");
    252 
    253          mediasource_test(function(test, mediaElement, mediaSource)
    254          {
    255              var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VIDEO_ONLY_TYPE);
    256 
    257              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    258              test.expectEvent(sourceBuffer, "update", "Append success.");
    259              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    260              sourceBuffer.appendBuffer(new Uint8Array(0));
    261 
    262              assert_true(sourceBuffer.updating, "updating attribute is true");
    263 
    264              test.waitForExpectedEvents(function()
    265              {
    266                  assert_false(sourceBuffer.updating, "updating attribute is false");
    267                  test.done();
    268              });
    269          }, "Test appending an empty ArrayBufferView.");
    270 
    271          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    272          {
    273              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    274              test.expectEvent(sourceBuffer, "update", "Append success.");
    275              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    276 
    277              var arrayBufferView = new Uint8Array(mediaData);
    278 
    279              assert_equals(arrayBufferView.length, mediaData.length, "arrayBufferView.length before transfer.");
    280 
    281              // Send the buffer as in a message so it gets neutered.
    282              window.postMessage( "test", "*", [arrayBufferView.buffer]);
    283 
    284              assert_equals(arrayBufferView.length, 0, "arrayBufferView.length after transfer.");
    285 
    286              sourceBuffer.appendBuffer(arrayBufferView);
    287 
    288              assert_true(sourceBuffer.updating, "updating attribute is true");
    289 
    290              test.waitForExpectedEvents(function()
    291              {
    292                 assert_false(sourceBuffer.updating, "updating attribute is false");
    293                 test.done();
    294              });
    295          }, "Test appending a neutered ArrayBufferView.");
    296 
    297          mediasource_test(function(test, mediaElement, mediaSource)
    298          {
    299              var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VIDEO_ONLY_TYPE);
    300 
    301              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    302              test.expectEvent(sourceBuffer, "update", "Append success.");
    303              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    304              sourceBuffer.appendBuffer(new ArrayBuffer(0));
    305 
    306              assert_true(sourceBuffer.updating, "updating attribute is true");
    307 
    308              test.waitForExpectedEvents(function()
    309              {
    310                  assert_false(sourceBuffer.updating, "updating attribute is false");
    311                  test.done();
    312              });
    313          }, "Test appending an empty ArrayBuffer.");
    314 
    315          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    316          {
    317              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    318              test.expectEvent(sourceBuffer, "update", "Append success.");
    319              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    320 
    321              var arrayBuffer = mediaData.buffer.slice(0);
    322 
    323              assert_equals(arrayBuffer.byteLength, mediaData.buffer.byteLength, "arrayBuffer.byteLength before transfer.");
    324 
    325              // Send the buffer as in a message so it gets neutered.
    326              window.postMessage( "test", "*", [arrayBuffer]);
    327 
    328              assert_equals(arrayBuffer.byteLength, 0, "arrayBuffer.byteLength after transfer.");
    329 
    330              sourceBuffer.appendBuffer(arrayBuffer);
    331 
    332              assert_true(sourceBuffer.updating, "updating attribute is true");
    333 
    334              test.waitForExpectedEvents(function()
    335              {
    336                 assert_false(sourceBuffer.updating, "updating attribute is false");
    337                 test.done();
    338              });
    339          }, "Test appending a neutered ArrayBuffer.");
    340 
    341          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    342          {
    343              var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
    344              var halfIndex = (initSegment.length + 1) / 2;
    345              var partialInitSegment = initSegment.subarray(0, halfIndex);
    346              var remainingInitSegment = initSegment.subarray(halfIndex);
    347              var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
    348 
    349              test.expectEvent(sourceBuffer, "updateend", "partialInitSegment append ended.");
    350              sourceBuffer.appendBuffer(partialInitSegment);
    351 
    352              test.waitForExpectedEvents(function()
    353              {
    354                  assert_equals(mediaElement.readyState, mediaElement.HAVE_NOTHING);
    355                  assert_equals(mediaSource.duration, Number.NaN);
    356                  test.expectEvent(sourceBuffer, "updateend", "remainingInitSegment append ended.");
    357                  test.expectEvent(mediaElement, "loadedmetadata", "loadedmetadata event received.");
    358                  sourceBuffer.appendBuffer(remainingInitSegment);
    359              });
    360 
    361              test.waitForExpectedEvents(function()
    362              {
    363                  assert_equals(mediaElement.readyState, mediaElement.HAVE_METADATA);
    364                  assert_equals(mediaSource.duration, segmentInfo.duration);
    365                  test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
    366                  test.expectEvent(mediaElement, "loadeddata", "loadeddata fired.");
    367                  sourceBuffer.appendBuffer(mediaSegment);
    368              });
    369 
    370              test.waitForExpectedEvents(function()
    371              {
    372                  assert_greater_than_equal(mediaElement.readyState, mediaElement.HAVE_CURRENT_DATA);
    373                  assert_equals(sourceBuffer.updating, false);
    374                  assert_equals(mediaSource.readyState, "open");
    375                  test.done();
    376              });
    377          }, "Test appendBuffer with partial init segments.");
    378 
    379          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    380          {
    381              var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
    382              var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
    383              var halfIndex = (mediaSegment.length + 1) / 2;
    384              var partialMediaSegment = mediaSegment.subarray(0, halfIndex);
    385              var remainingMediaSegment = mediaSegment.subarray(halfIndex);
    386 
    387              test.expectEvent(sourceBuffer, "updateend", "InitSegment append ended.");
    388              test.expectEvent(mediaElement, "loadedmetadata", "loadedmetadata done.");
    389              sourceBuffer.appendBuffer(initSegment);
    390 
    391              test.waitForExpectedEvents(function()
    392              {
    393                  assert_equals(mediaElement.readyState, mediaElement.HAVE_METADATA);
    394                  assert_equals(mediaSource.duration, segmentInfo.duration);
    395                  test.expectEvent(sourceBuffer, "updateend", "partial media segment append ended.");
    396                  sourceBuffer.appendBuffer(partialMediaSegment);
    397              });
    398 
    399              test.waitForExpectedEvents(function()
    400              {
    401                  test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
    402                  test.expectEvent(mediaElement, "loadeddata", "loadeddata fired.");
    403                  sourceBuffer.appendBuffer(remainingMediaSegment);
    404              });
    405 
    406              test.waitForExpectedEvents(function()
    407              {
    408                  assert_greater_than_equal(mediaElement.readyState, mediaElement.HAVE_CURRENT_DATA);
    409                  assert_equals(mediaSource.readyState, "open");
    410                  assert_equals(sourceBuffer.updating, false);
    411                  test.done();
    412              });
    413          }, "Test appendBuffer with partial media segments.");
    414 
    415          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    416          {
    417              var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
    418              var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
    419 
    420              assert_equals(mediaElement.readyState, mediaElement.HAVE_NOTHING);
    421              assert_equals(mediaSource.duration, Number.NaN);
    422 
    423              // readyState is changing as per the Initialization Segment Received algorithm.
    424              var loadedmetadataCalled = false;
    425              mediaElement.addEventListener("loadedmetadata", function metadata(e) {
    426                 loadedmetadataCalled = true;
    427                 e.target.removeEventListener(e.type, metadata);
    428              });
    429              sourceBuffer.addEventListener("updateend", test.step_func(function updateend(e) {
    430                 assert_true(loadedmetadataCalled);
    431                 assert_equals(mediaElement.readyState, mediaElement.HAVE_METADATA);
    432                 e.target.removeEventListener(e.type, updateend);
    433              }));
    434              test.expectEvent(sourceBuffer, "updateend", "remainingInitSegment append ended.");
    435              test.expectEvent(mediaElement, "loadedmetadata", "loadedmetadata event received.");
    436              sourceBuffer.appendBuffer(initSegment);
    437 
    438              test.waitForExpectedEvents(function()
    439              {
    440                  assert_equals(mediaElement.readyState, mediaElement.HAVE_METADATA);
    441                  assert_equals(mediaSource.duration, segmentInfo.duration);
    442                  // readyState is changing as per the Coded Frame Processing algorithm.
    443                  var loadeddataCalled = false;
    444                  mediaElement.addEventListener("loadeddata", function loadeddata(e) {
    445                      loadeddataCalled = true;
    446                      e.target.removeEventListener(e.type, loadeddata);
    447                  });
    448                  sourceBuffer.addEventListener("updateend", test.step_func(function updateend(e) {
    449                      assert_true(loadeddataCalled);
    450                      assert_greater_than_equal(mediaElement.readyState, mediaElement.HAVE_CURRENT_DATA);
    451                      e.target.removeEventListener(e.type, updateend);
    452                  }));
    453                  test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
    454                  test.expectEvent(mediaElement, "loadeddata", "loadeddata fired.");
    455                  sourceBuffer.appendBuffer(mediaSegment);
    456              });
    457 
    458              test.waitForExpectedEvents(function()
    459              {
    460                  assert_greater_than_equal(mediaElement.readyState, mediaElement.HAVE_CURRENT_DATA);
    461                  assert_equals(sourceBuffer.updating, false);
    462                  assert_equals(mediaSource.readyState, "open");
    463                  test.done();
    464              });
    465          }, "Test appendBuffer events order.");
    466 
    467          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    468          {
    469              var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
    470              var partialInitSegment = initSegment.subarray(0, initSegment.length / 2);
    471              var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
    472 
    473              test.expectEvent(sourceBuffer, "updateend", "partialInitSegment append ended.");
    474              sourceBuffer.appendBuffer(partialInitSegment);
    475 
    476              test.waitForExpectedEvents(function()
    477              {
    478                  // Call abort to reset the parser.
    479                  sourceBuffer.abort();
    480 
    481                  // Append the full intiialization segment.
    482                  test.expectEvent(sourceBuffer, "updateend", "initSegment append ended.");
    483                  sourceBuffer.appendBuffer(initSegment);
    484              });
    485 
    486              test.waitForExpectedEvents(function()
    487              {
    488                  test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
    489                  test.expectEvent(mediaElement, "loadeddata", "loadeddata fired.");
    490                  sourceBuffer.appendBuffer(mediaSegment);
    491              });
    492 
    493              test.waitForExpectedEvents(function()
    494              {
    495                  test.done();
    496              });
    497          }, "Test abort in the middle of an initialization segment.");
    498 
    499          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    500          {
    501              test.expectEvent(mediaSource.sourceBuffers, "removesourcebuffer", "SourceBuffer removed.");
    502              mediaSource.removeSourceBuffer(sourceBuffer);
    503              test.waitForExpectedEvents(function()
    504              {
    505                  assert_throws_dom("InvalidStateError",
    506                      function() { sourceBuffer.abort(); },
    507                      "sourceBuffer.abort() throws an exception for InvalidStateError.");
    508 
    509                  test.done();
    510              });
    511          }, "Test abort after removing sourcebuffer.");
    512 
    513          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    514          {
    515              var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
    516              var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
    517 
    518              test.expectEvent(sourceBuffer, "updateend", "initSegment append ended.");
    519              sourceBuffer.appendBuffer(initSegment);
    520 
    521              test.waitForExpectedEvents(function()
    522              {
    523                  assert_equals(mediaSource.readyState, "open", "readyState is open after init segment appended.");
    524                  test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
    525                  sourceBuffer.appendBuffer(mediaSegment);
    526              });
    527 
    528              test.waitForExpectedEvents(function()
    529              {
    530                  assert_equals(sourceBuffer.buffered.length, 1, "sourceBuffer has a buffered range");
    531                  assert_equals(mediaSource.readyState, "open", "readyState is open after media segment appended.");
    532                  test.expectEvent(mediaSource, "sourceended", "source ended");
    533                  mediaSource.endOfStream();
    534              });
    535 
    536              test.waitForExpectedEvents(function()
    537              {
    538                  assert_equals(mediaSource.readyState, "ended", "readyState is ended.");
    539                  assert_throws_dom("InvalidStateError",
    540                      function() { sourceBuffer.abort(); },
    541                      "sourceBuffer.abort() throws an exception for InvalidStateError.");
    542                  test.done();
    543              });
    544 
    545          }, "Test abort after readyState is ended following init segment and media segment.");
    546 
    547          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    548          {
    549              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    550              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    551              sourceBuffer.appendWindowStart = 1;
    552              sourceBuffer.appendWindowEnd = 100;
    553              sourceBuffer.appendBuffer(mediaData);
    554 
    555              test.waitForExpectedEvents(function()
    556              {
    557                  assert_false(sourceBuffer.updating, "updating attribute is false");
    558                  sourceBuffer.abort();
    559                  assert_equals(sourceBuffer.appendWindowStart, 0, "appendWindowStart is reset to 0");
    560                  assert_equals(sourceBuffer.appendWindowEnd, Number.POSITIVE_INFINITY,
    561                      "appendWindowEnd is reset to +INFINITY");
    562                  test.done();
    563              });
    564          }, "Test abort after appendBuffer update ends.");
    565 
    566          mediasource_test(function(test, mediaElement, mediaSource)
    567          {
    568              var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VIDEO_ONLY_TYPE);
    569 
    570              test.expectEvent(sourceBuffer, "updatestart", "Append started.");
    571              test.expectEvent(sourceBuffer, "update", "Append success.");
    572              test.expectEvent(sourceBuffer, "updateend", "Append ended.");
    573 
    574              assert_throws_js( TypeError,
    575                  function() { sourceBuffer.appendBuffer(null); },
    576                  "appendBuffer(null) throws an exception.");
    577              test.done();
    578          }, "Test appending null.");
    579 
    580          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    581          {
    582              mediaSource.removeSourceBuffer(sourceBuffer);
    583 
    584              assert_throws_dom( "InvalidStateError",
    585                  function() { sourceBuffer.appendBuffer(mediaData); },
    586                  "appendBuffer() throws an exception when called after removeSourceBuffer().");
    587              test.done();
    588          }, "Test appending after removeSourceBuffer().");
    589 
    590          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
    591          {
    592              // Media elements using MSE should not fire the stalled event. See discussion at
    593              // https://github.com/w3c/media-source/issues/88#issuecomment-374406928
    594              mediaElement.addEventListener("stalled", test.unreached_func("Unexpected 'stalled' event."));
    595 
    596              // Prime the media element with initial appends.
    597              var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
    598              var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
    599              test.expectEvent(sourceBuffer, "updateend", "initSegment append ended.");
    600              sourceBuffer.appendBuffer(initSegment);
    601              test.waitForExpectedEvents(function()
    602              {
    603                  assert_equals(mediaSource.readyState, "open", "readyState is open after init segment appended.");
    604                  test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
    605                  sourceBuffer.appendBuffer(mediaSegment);
    606              });
    607 
    608              // Verify state and wait for the 'stalled' event.
    609              test.waitForExpectedEvents(function()
    610              {
    611                  assert_equals(sourceBuffer.buffered.length, 1, "sourceBuffer has a buffered range");
    612                  assert_equals(mediaSource.readyState, "open", "readyState is open after media segment appended.");
    613 
    614                  // Set timeout to 4 seconds. This creates an opportunity for UAs to _improperly_ fire the stalled event.
    615                  // For media elements doing progressive download (not MSE), stalled is thrown after ~3 seconds of the
    616                  // download failing to progress.
    617                  test.step_timeout(function() { test.done(); }, 4000);
    618              });
    619          }, "Test slow appending does not trigger stalled events.");
    620 
    621        </script>
    622    </body>
    623 </html>