<html>
    <head>
      <base href="https://bugs.webkit.org/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [MSE] MediaSource.endOfStream() triggers updateend event"
   href="https://bugs.webkit.org/show_bug.cgi?id=165336">165336</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[MSE] MediaSource.endOfStream() triggers updateend event
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>WebKit
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>Safari 10
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Unspecified
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Unspecified
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>Normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P2
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Media Elements
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>webkit-unassigned&#64;lists.webkit.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>joeyparrish&#64;google.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Shaka Player (<a href="https://github.com/google/shaka-player">https://github.com/google/shaka-player</a>) discovered that calling endOfStream() on Safari's MediaSource can trigger an unexpected 'updateend' event.

In our test, we set a duration, append several segments, then call endOfStream().  endOfStream() should never result in an 'updateend' event according to the spec.



Quoting the MSE spec: <a href="https://www.w3.org/TR/media-source/#end-of-stream-algorithm">https://www.w3.org/TR/media-source/#end-of-stream-algorithm</a>

=====
2.4.7 End of stream algorithm

1. Change the readyState attribute value to &quot;ended&quot;.
2. Queue a task to fire a simple event named sourceended at the MediaSource.
3. If error is not set
  1. Run the duration change algorithm with new duration set to the largest track buffer ranges end time across all the track buffers across all SourceBuffer objects in sourceBuffers.

NOTE:
This allows the duration to properly reflect the end of the appended media segments. For example, if the duration was explicitly set to 10 seconds and only media segments for 0 to 5 seconds were appended before endOfStream() was called, then the duration will get updated to 5 seconds.
=====
2.4.6 Duration change

1. If the current value of duration is equal to new duration, then return.
2. If new duration is less than the highest presentation timestamp of any buffered coded frames for all SourceBuffer objects in sourceBuffers, then throw an InvalidStateError exception and abort these steps.

NOTE:
Duration reductions that would truncate currently buffered media are disallowed. When truncation is necessary, use remove() to reduce the buffered range before updating duration.
=====

In this repro, the duration reduction is triggered by endOfStream(), which sets the new duration to the largest end time.  Therefore, the new duration cannot truncate currently buffered media, which would be disallowed anyway.  There is no reason for 'updateend' to fire.

The event only fires when endOfStream() causes a reduction in duration.  Could this perhaps be caused by an inappropriate call to the &quot;range removal&quot; algorithm?



This is a problem because 'updateend' must be used to carefully track SourceBuffer state.  If I call endOfStream() (which should be synchronous), followed by some async operation, the 'updateend' event can cause the application to believe that the other operation is complete, even though it is not.  This can, in turn, trick the app into starting other operations at a time when they will fail.



To reproduce:

1. Visit <a href="http://storage.googleapis.com/shaka-demo-assets/_bugs/safari-mse-endofstream/index.html">http://storage.googleapis.com/shaka-demo-assets/_bugs/safari-mse-endofstream/index.html</a> in Safari 10
2. Open the JavaScript console
3. Observe the error message &quot;Unexpected updateend event!&quot;

Reproducible on macOS Sierra, Safari 10.0.1 (12602.2.14.0.7).
*Not* reproducible in WebKit nightly r209234.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>