mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-14 15:56:38 +03:00
0b003d3819
Closes #53. Change-Id: I5c28336e839d109ca09013011ec4a31823257027
140 lines
5.1 KiB
HTML
140 lines
5.1 KiB
HTML
<!--
|
|
Copyright 2015 Google Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
-->
|
|
|
|
<h3 class="tutorial-heading">
|
|
Live Streaming Issues
|
|
</h3>
|
|
|
|
<p>
|
|
Shaka Player supports live streaming since v1.3.0. Live streams are handled by
|
|
{@link shaka.player.DashVideoSource}, and there is no difference in the API for
|
|
live vs static content.
|
|
</p>
|
|
|
|
<p>
|
|
Live content can, however, contain large timestamps. This can make the built-in
|
|
controls on the video tag (or any other naive UI) confusing. The currentTime on
|
|
the video may report as something like 397002:54:56. This is not a very helpful
|
|
or meaningful number to the user. Plus, if the video "started" over 300k+ hours
|
|
ago, seeking to 0 is not realistic. The server is surely not keeping that much
|
|
content sitting around.
|
|
</p>
|
|
|
|
<p>
|
|
In reality, live content limits the range in which the user may seek. One live
|
|
stream may allow the user to seek backward 5 minutes, while another may allow 4
|
|
hours. If a user tries to seek to a point outside of this range, the player can
|
|
clamp this value to one within the seek range. Better still is to show the user
|
|
a meaningful range of content in the seek UI.
|
|
</p>
|
|
|
|
|
|
<h3 class="tutorial-heading">
|
|
Seek Range Events
|
|
</h3>
|
|
|
|
<p>
|
|
{@link shaka.player.DashVideoSource.event:SeekRangeChanged} events give the app
|
|
the information it needs to present a better live stream UI. An app which does
|
|
not support live streams may safely ignore them. An app which does not support
|
|
seeking in a live stream may also ignore them.
|
|
</p>
|
|
|
|
<p>
|
|
A SeekRangeChanged event contains "start" and "end" timestamps which define the
|
|
range of time which is currently seekable. Over time, this window of available
|
|
content will move to the right in the video timeline.
|
|
</p>
|
|
|
|
<p>
|
|
The "end" time corresponds to the most recent available live content. Therefore
|
|
to jump forward to the "live edge", the application would set video.currentTime
|
|
to the range's "end" time.
|
|
</p>
|
|
|
|
<p>
|
|
Rather than display actual timestamps from the video stream, which may be quite
|
|
large, we recommend displaying an offset from the live edge. For example, when
|
|
the user is watching content 1 minute and 30 seconds behind the live edge, show
|
|
"-1:30".
|
|
</p>
|
|
|
|
<p>
|
|
During live playback, the user's offset from the live edge is roughly constant,
|
|
so any time code displayed would only be changed by buffering or seeking.
|
|
</p>
|
|
|
|
<p>
|
|
For an example of a UI which uses the SeekRangeChanged event, see controls.js.
|
|
</p>
|
|
|
|
|
|
<h3 class="tutorial-heading">
|
|
Clock Synchronization
|
|
</h3>
|
|
|
|
<p>
|
|
Segment availability for live streams is based on the current time. You cannot
|
|
access segments from the future, but the manifest may give you enough detail to
|
|
know their locations in advance. Therefore, if the client's clock is not synced
|
|
with the server's clock, the client might request unavailable segments.
|
|
</p>
|
|
|
|
<p>
|
|
Clock synchronization between client and server is important. In the DASH spec,
|
|
it states (under heading A.3.1) that "clients are expected to synchronize their
|
|
clocks to a globally accurate time standard." It does not specify how, though.
|
|
</p>
|
|
|
|
<p>
|
|
Shaka Player uses a very simple mechanism for clock sync. When the library asks
|
|
the server for a manifest, the HTTP Date response header is used to synchronize
|
|
the client's {@link shaka.util.Clock virtual clock} with the server. All timing
|
|
for the live stream is based on this virtual clock, rather than the system time
|
|
of the client. This has a few advantages.
|
|
</p>
|
|
|
|
<p>
|
|
Rather than requiring synchronization to a globally accurate time standard, our
|
|
mechanism requires only that the server time is consistent between the manifest
|
|
and the web server. This self-consistency is a lighter-weight requirement than
|
|
the one in the DASH specification, and one which we think is easier to satisfy.
|
|
</p>
|
|
|
|
<p>
|
|
The HTTP specification requires the Date header for all responses, so it should
|
|
always be present. By using the Date header, we avoid the need for out-of-band
|
|
clock synchronization mechanisms.
|
|
</p>
|
|
|
|
|
|
<h3 class="tutorial-heading">
|
|
Clock Synchronization vs CORS
|
|
</h3>
|
|
|
|
<p>
|
|
If your application operates <a href="http://goo.gl/meEW9Q">same-origin</a>, no
|
|
special configuration is required for clock synchronization. If manifests come
|
|
from another origin, your server must allow Cross-Origin Resource Sharing, also
|
|
known as <a href="http://goo.gl/vqldIX">CORS</a>. The response for the manifest
|
|
must include the "Access-Control-Expose-Headers" header with "Date" in the list
|
|
of values. If this is not given, the browser will not permit the application to
|
|
read the Date header. Chrome will log an error message to the JS console saying
|
|
"Refused to get unsafe header". (Note that this is coming directly from Chrome
|
|
and cannot be silenced by the library.)
|
|
</p>
|
|
|