Skip to content

Commit

Permalink
convert to markdown for web/guide
Browse files Browse the repository at this point in the history
  • Loading branch information
yin1999 committed Aug 14, 2022
1 parent 18322ba commit 06c1baa
Show file tree
Hide file tree
Showing 13 changed files with 1,364 additions and 1,338 deletions.
247 changes: 130 additions & 117 deletions files/zh-cn/web/guide/ajax/getting_started/index.md

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,69 +1,76 @@
---
title: 'Media buffering, seeking, and time ranges'
title: Media buffering, seeking, and time ranges
slug: Web/Guide/Audio_and_video_delivery/buffering_seeking_time_ranges
translation_of: Web/Guide/Audio_and_video_delivery/buffering_seeking_time_ranges
---
<div>
<p>有时候知道 {{htmlelement("audio") }} 或 {{htmlelement("video") }} 已经下载了多少或有多少可以不延迟的播放是有用的 — 音频和视频的缓冲条就是这个的一个好例子。 这篇文章讨论 用 <a href="/zh-CN/docs/Web/API/TimeRanges">TimeRanges</a>如何创建一个 buffer/seek bar,和 media API 的其他特性。</p>
</div>
有时候知道 {{htmlelement("audio") }} 或 {{htmlelement("video") }} 已经下载了多少或有多少可以不延迟的播放是有用的 — 音频和视频的缓冲条就是这个的一个好例子。 这篇文章讨论 用 [TimeRanges](/zh-CN/docs/Web/API/TimeRanges)如何创建一个 buffer/seek bar,和 media API 的其他特性。

<h2 id="Buffered">Buffered</h2>
## Buffered

<p><code>Buffered</code> 属性会告诉我们媒体的哪一部分已经下载好了。它返回一个 {{ domxref("TimeRanges") }} 对象,表名哪些块已经下载。 这通常是连续的但是如果用户在缓冲时跳过,就可能会有缺口。</p>
`Buffered` 属性会告诉我们媒体的哪一部分已经下载好了。它返回一个 {{ domxref("TimeRanges") }} 对象,表名哪些块已经下载。 这通常是连续的但是如果用户在缓冲时跳过,就可能会有缺口。

<p>它与 {{htmlelement("audio") }} 或 {{htmlelement("video") }}一起工作; 现在我们来考虑一个简单的 aodio 例子:</p>
它与 {{htmlelement("audio") }} 或 {{htmlelement("video") }}一起工作; 现在我们来考虑一个简单的 aodio 例子:

<pre class="brush: html">&lt;audio id="my-audio" controls src="music.mp3"&gt;
&lt;/audio&gt;</pre>
```html
<audio id="my-audio" controls src="music.mp3">
</audio>
```

<p>我们可以这样访问这些属性:</p>
我们可以这样访问这些属性:

<pre class="brush: js">var myAudio = document.getElementById('my-audio');
```js
var myAudio = document.getElementById('my-audio');

var bufferedTimeRanges = myAudio.buffered;</pre>
var bufferedTimeRanges = myAudio.buffered;
```

<h2 id="TimeRanges_对象">TimeRanges 对象</h2>
## TimeRanges 对象

<p>TimeRanges 是一系列有开始和结束时间的非重叠的时间范围。 (<a href="/zh-CN/docs/Web/API/TimeRanges">learn more about TimeRanges</a>).</p>
TimeRanges 是一系列有开始和结束时间的非重叠的时间范围。 ([learn more about TimeRanges](/zh-CN/docs/Web/API/TimeRanges)).

<p>一个 {{ domxref("TimeRanges") }} 对象包括以下内容。</p>
一个 {{ domxref("TimeRanges") }} 对象包括以下内容。

<ul>
<li><code>length</code>: The number of time ranges in the object.</li>
<li><code>start(index)</code>: The start time, in seconds, of a time range.</li>
<li><code>end(index)</code>: The end time, in seconds, of a time range.</li>
</ul>
- `length`: The number of time ranges in the object.
- `start(index)`: The start time, in seconds, of a time range.
- `end(index)`: The end time, in seconds, of a time range.

<p>没有用户操作的话通常只有一个时间范围,但是如果你在媒体中跳来跳去那么就会出现多个时间范围,下面形象化的表名了这一点。 This represents two buffered time ranges — one spanning 0 to 5 seconds and the second spanning 15 to 19 seconds.</p>
没有用户操作的话通常只有一个时间范围,但是如果你在媒体中跳来跳去那么就会出现多个时间范围,下面形象化的表名了这一点。 This represents two buffered time ranges — one spanning 0 to 5 seconds and the second spanning 15 to 19 seconds.

<pre>------------------------------------------------------
```plain
------------------------------------------------------
|=============| |===========| |
------------------------------------------------------
0 5 15 19 21</pre>
0 5 15 19 21
```

<p>对于这个 audio 实例,相关联的 {{ domxref("TimeRange") }} 对象会有以下的可用属性:</p>
对于这个 audio 实例,相关联的 {{ domxref("TimeRange") }} 对象会有以下的可用属性:

<pre class="brush: js">myAudio.buffered.length; // returns 2
```js
myAudio.buffered.length; // returns 2
myAudio.buffered.start(0); // returns 0
myAudio.buffered.end(0); // returns 5
myAudio.buffered.start(1); // returns 15
myAudio.buffered.end(1); // returns 19</pre>
myAudio.buffered.end(1); // returns 19
```

<p>为了试用并形象化 buffered time ranges 我们可以写一点 HTML:</p>
为了试用并形象化 buffered time ranges 我们可以写一点 HTML:

<pre class="brush: html">&lt;p&gt;
&lt;audio id="my-audio" controls&gt;
&lt;source src="music.mp3" type="audio/mpeg"&gt;
&lt;/audio&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;canvas id="my-canvas" width="300" height="20"&gt;
&lt;/canvas&gt;
&lt;/p&gt;</pre>
```html
<p>
<audio id="my-audio" controls>
<source src="music.mp3" type="audio/mpeg">
</audio>
</p>
<p>
<canvas id="my-canvas" width="300" height="20">
</canvas>
</p>
```

<p>and a little bit of JavaScript:</p>
and a little bit of JavaScript:

<pre class="brush: js"> window.onload = function(){
```js
window.onload = function(){

var myAudio = document.getElementById('my-audio');
var myCanvas = document.getElementById('my-canvas');
Expand All @@ -79,7 +86,7 @@ myAudio.buffered.end(1); // returns 19</pre>
// display TimeRanges

myAudio.addEventListener('seeked', function() {
for (i = 0; i &lt; myAudio.buffered.length; i++) {
for (i = 0; i < myAudio.buffered.length; i++) {

var startX = myAudio.buffered.start(i) * inc;
var endX = myAudio.buffered.end(i) * inc;
Expand All @@ -90,50 +97,53 @@ myAudio.buffered.end(1); // returns 19</pre>
context.stroke();
}
});
}</pre>
}
```

<p>这在长一些的 audio 或 video 上工作的更好, 但是按开始键并在进度条上点击,你会得到这个。 每个红色填充的长方形代表一个时间范围。</p>
这在长一些的 audio 或 video 上工作的更好, 但是按开始键并在进度条上点击,你会得到这个。 每个红色填充的长方形代表一个时间范围。

<p><img alt="A simple audio player with play button, seek bar and volume control, with a series of red rectangles beneath it representing time ranges." src="bufferedtimeranges.png"></p>
![A simple audio player with play button, seek bar and volume control, with a series of red rectangles beneath it representing time ranges.](bufferedtimeranges.png)

<div class="note">
<p><strong>Note</strong>: You can see the <a href="http://jsbin.com/memazaro/1/edit">timerange code running live on JS Bin</a>.</p>
</div>
> **备注:** You can see the [timerange code running live on JS Bin](http://jsbin.com/memazaro/1/edit).
<h2 id="Seekable">Seekable</h2>
## Seekable

<p><code>Seekable</code> 属性返回一个 {{ domxref("TimeRanges") }} 对象告诉我们哪一部分媒体可以不等待的播放; this is irrespective of whether that part has been downloaded or not. Some parts of the media may be seekable but not buffered if byte-range requests are enabled on the server. Byte range requests allow parts of the media file to be delivered from the server and so can be ready to play almost immediately — thus they are seekable.</p>
`Seekable` 属性返回一个 {{ domxref("TimeRanges") }} 对象告诉我们哪一部分媒体可以不等待的播放; this is irrespective of whether that part has been downloaded or not. Some parts of the media may be seekable but not buffered if byte-range requests are enabled on the server. Byte range requests allow parts of the media file to be delivered from the server and so can be ready to play almost immediately — thus they are seekable.

<pre class="brush: js">var seekableTimeRanges = myAudio.seekable;</pre>
```js
var seekableTimeRanges = myAudio.seekable;
```

<h2 id="Creating_our_own_Buffering_Feedback">Creating our own Buffering Feedback</h2>
## Creating our own Buffering Feedback

<p>If we wish to create our own custom player, we may want to provide feedback on how much of the media is ready to be played. In practice a good way to do this is use the <code>seekable</code> attribute, although as we have seen above seekable parts of the media are not neccessarily contiguous — they often are however and we can safely approximate this information to give the user an indication of which parts of the media can be played directly. We can find this point in the media using the following line of code:</p>
If we wish to create our own custom player, we may want to provide feedback on how much of the media is ready to be played. In practice a good way to do this is use the `seekable` attribute, although as we have seen above seekable parts of the media are not neccessarily contiguous — they often are however and we can safely approximate this information to give the user an indication of which parts of the media can be played directly. We can find this point in the media using the following line of code:

<pre class="brush: js">var seekableEnd = myAudio.seekable.end(myAudio.seekable.length - 1);</pre>
```js
var seekableEnd = myAudio.seekable.end(myAudio.seekable.length - 1);
```

<div class="note">
<p><strong>Note</strong>: <code>myAudio.seekable.end(myAudio.seekable.length - 1)</code> actually tells us the end point of the last time range that is seekable (not all seekable media). In practice this is good enough as the browser either enables range requests or it doesn't. If it doesn't then <code>audio.seekable</code> will be equivalent to <code>audio.buffered</code>, which will give a valid indication of the end of seekable media. If range requests are enabled this value usually becomes the duration of the media almost instantly.</p>
</div>
> **备注:** `myAudio.seekable.end(myAudio.seekable.length - 1)` actually tells us the end point of the last time range that is seekable (not all seekable media). In practice this is good enough as the browser either enables range requests or it doesn't. If it doesn't then `audio.seekable` will be equivalent to `audio.buffered`, which will give a valid indication of the end of seekable media. If range requests are enabled this value usually becomes the duration of the media almost instantly.
<p>It is better perhaps to give an indication of how much media has actually downloaded — this what the browser's native players seem to display.</p>
It is better perhaps to give an indication of how much media has actually downloaded — this what the browser's native players seem to display.

<p>So let's build this. The HTML for our player looks like this:</p>
So let's build this. The HTML for our player looks like this:

<pre class="brush: css">&lt;audio id="my-audio" preload controls&gt;
&lt;source src="music.mp3" type="audio/mpeg"&gt;
&lt;/audio&gt;
&lt;div class="buffered"&gt;
&lt;span id="buffered-amount"&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div class="progress"&gt;
&lt;span id="progress-amount"&gt;&lt;/span&gt;
&lt;/div&gt;
</pre>
```css
<audio id="my-audio" preload controls>
<source src="music.mp3" type="audio/mpeg">
</audio>
<div class="buffered">
<span id="buffered-amount"></span>
</div>
<div class="progress">
<span id="progress-amount"></span>
</div>
```

<p>We'll use the following CSS to style the buffering display:</p>
We'll use the following CSS to style the buffering display:

<pre class="brush: css">.buffered {
```css
.buffered {
height: 20px;
position: relative;
background: #555;
Expand All @@ -159,46 +169,49 @@ myAudio.buffered.end(1); // returns 19</pre>
height: 100%;
background-color: #595;
width: 0;
}</pre>
}
```

<p>And the following JavaScript provides our functionality:</p>
And the following JavaScript provides our functionality:

<pre class="brush: js">window.onload = function(){
```js
window.onload = function(){

var myAudio = document.getElementById('my-audio');

myAudio.addEventListener('progress', function() {
var bufferedEnd = myAudio.buffered.end(myAudio.buffered.length - 1);
var duration = myAudio.duration;
if (duration &gt; 0) {
if (duration > 0) {
document.getElementById('buffered-amount').style.width = ((bufferedEnd / duration)*100) + "%";
}
});

myAudio.addEventListener('timeupdate', function() {
var duration = myAudio.duration;
if (duration &gt; 0) {
if (duration > 0) {
document.getElementById('progress-amount').style.width = ((myAudio.currentTime / duration)*100) + "%";
}
});
}</pre>
}
```

<p>The progress event is fired as data is downloaded, this is a good event to react to if we want to display download or buffering progress.</p>
The progress event is fired as data is downloaded, this is a good event to react to if we want to display download or buffering progress.

<p>The timeupdate event is fired 4 times a second as the media plays and that's where we increment our playing progress bar.</p>
The timeupdate event is fired 4 times a second as the media plays and that's where we increment our playing progress bar.

<p>This should give you results similar to the following, where the light grey bar represents the buffered progress and green bar shows the played progress:</p>
This should give you results similar to the following, where the light grey bar represents the buffered progress and green bar shows the played progress:

<p><img alt="A simple audio player with play button, seek bar and volume control, with a bar below it. The bar has a red portion to show played video, and a dark gray bar to show how much has been buffered." src="bufferedprogress.png"></p>
![A simple audio player with play button, seek bar and volume control, with a bar below it. The bar has a red portion to show played video, and a dark gray bar to show how much has been buffered.](bufferedprogress.png)

<div class="note">
<p><strong>Note</strong>: You can see the <a href="http://jsbin.com/badimipi/1/edit">buffering code running live on JS Bin</a>.</p>
</div>
> **备注:** You can see the [buffering code running live on JS Bin](http://jsbin.com/badimipi/1/edit).
<h2 id="A_quick_word_about_Played">A quick word about Played</h2>
## A quick word about Played

<p>It’s worth mentioning the <code>played</code> property — this tells us which time ranges have been played within the media. For example:</p>
It’s worth mentioning the `played` property — this tells us which time ranges have been played within the media. For example:

<pre class="brush: js">var played = audio.played; // returns a TimeRanges object</pre>
```js
var played = audio.played; // returns a TimeRanges object
```

<p>This could be useful for establishing the parts of your media that are most listened to or watched.</p>
This could be useful for establishing the parts of your media that are most listened to or watched.
Loading

0 comments on commit 06c1baa

Please sign in to comment.