Skip to main content

<audio> 要素と <video> 要素のプロパティをバインドすることができるので、(例えば) AudioPlayer.svelte のようなカスタムのプレーヤー UI をとても簡単に作ることができます。

最初に、<audio> 要素とそのバインディングを追加します (srcdurationpaused は短縮形を使います):

AudioPlayer
<div class="player" class:paused>
	<audio
		{src}
		bind:currentTime={time}
		bind:duration
		bind:paused
	></audio>

	<button
		class="play"
		aria-label={paused ? 'play' : 'pause'}
	></button>

次に、paused を切り替える <button> にイベントハンドラを追加します:

AudioPlayer
<button
	class="play"
	aria-label={paused ? 'play' : 'pause'}
	onclick={() => paused = !paused}
></button>

これでオーディオプレーヤーに基本的な機能が付きました。では、スライダーをドラッグして曲の指定した部分にシークできる機能を追加しましょう。スライダー(slider)の pointerdown ハンドラの内側にある seek 関数で、time を更新することができます:

AudioPlayer
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
<audio
	{src}
	bind:currentTime={time}
	bind:duration
	bind:paused
	onended={() => {
		time = 0;
	}}
></audio>

<audio><video> のバインディングの完全なセットは以下の通りです — 7つの 読み取り専用(readonly) のバインディング…

  • duration — 総再生時間 (秒単位)
  • buffered{start, end} オブジェクトの配列
  • seekable — 同上
  • played — 同上
  • seeking — boolean
  • ended — boolean
  • readyState — 0 から 4 までの数値 (0 と 4 も含む)

…と5つの 双方向 バインディングです:

  • currentTime — 再生マーカー (playhead) の現在の位置 (秒単位)
  • playbackRate — 再生速度を上げるか遅くするか (1 が ‘normal’)
  • paused — これは自明ですね
  • volume — 0 から 1 の値
  • muted — boolean で、true はミュートを意味します

video には読み取り専用の videoWidthvideoHeight バインディングがあります。

Edit this page on GitHub

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>