你可以绑定 <audio>
和 <video>
元素的属性,以轻松构建自定义的播放器 UI,就像 AudioPlayer.svelte
一样。
首先,添加 audio
元素及其绑定(我们使用 src
、duration
和 paused
的简写形式):
AudioPlayer.svelte
<div class="player" class:paused>
<audio
{src}
bind:currentTime={time}
bind:duration
bind:paused
></audio>
<button
class="play"
aria-label={paused ? 'play' : 'pause'}
></button>
然后,给 button
添加一个事件处理器,用来切换 paused
:
AudioPlayer.svelte
<button
class="play"
aria-label={paused ? 'play' : 'pause'}
on:click={() => paused = !paused}
></button>
现在我们的音乐播放器已经有基本的功能了。再让我们添加可以拖动滑块将音乐定位到指定时长的功能。在滑块的 pointerdown
处理器中有一个 seek
函数,我们可以在里面更新 time
:
AudioPlayer.svelte
function seek(e) {
const { left, width } = div.getBoundingClientRect();
let p = (e.clientX - left) / width;
if (p < 0) p = 0;
if (p > 1) p = 1;
time = p * duration;
}
当音乐播放完毕之后,让我们友好一点,给进度条复位:
AudioPlayer.svelte
<audio
{src}
bind:currentTime={time}
bind:duration
bind:paused
on:ended={() => {
time = 0;
}}
></audio>
<audio>
和 <video>
的所有绑定列举如下,一共七个 只读 绑定……
duration
(只读) — 总时长,以秒为单位buffered
(只读) — 一个包含{start, end}
对象的数组seekable
(只读) — 同上played
(只读) — 同上seeking
(只读) — 布尔ended
(只读) — 布尔readyState
(只读) — 0 到 4 (包含)之间的数字
……和五个 双向 绑定:
currentTime
— 当前播放位置,以秒为单位playbackRate
— 加速或者减速(1
是“正常速度”)paused
— 这个应该很好理解volume
— 0 到 1 之间的值muted
— 一个布尔值,true
表示静音
视频额外具有 videoWidth
和 videoHeight
两个只读绑定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
import AudioPlayer from './AudioPlayer.svelte';
import { tracks } from './tracks.js';
</script>
<div class="centered">
{#each tracks as track}
<AudioPlayer {...track} />
{/each}
</div>
<style>
.centered {
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
gap: 0.5em;
max-width: 40em;
margin: 0 auto;
}
</style>