Property "muted" for <audio> and <video> (#4690)

* Audio two-way `muted` bind property

Loosely based on a37ee81676?w=1

* Documentation

* fix test

* dont bother coercing muted, it happens automatically

Co-authored-by: Richard Harris <richard.a.harris@gmail.com>
pull/4874/head
Robert Hall 5 years ago committed by GitHub
parent c19542b634
commit 7fe1384f43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -603,12 +603,13 @@ Media elements (`<audio>` and `<video>`) have their own set of bindings — six
* `seeking` (readonly) — boolean * `seeking` (readonly) — boolean
* `ended` (readonly) — boolean * `ended` (readonly) — boolean
...and four *two-way* bindings: ...and five *two-way* bindings:
* `currentTime` — the current point in the video, in seconds * `currentTime` — the current point in the video, in seconds
* `playbackRate` — how fast to play the video, where 1 is 'normal' * `playbackRate` — how fast to play the video, where 1 is 'normal'
* `paused` — this one should be self-explanatory * `paused` — this one should be self-explanatory
* `volume` — a value between 0 and 1 * `volume` — a value between 0 and 1
* `muted` — a boolean value where true is muted
Videos additionally have readonly `videoWidth` and `videoHeight` bindings. Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
@ -624,6 +625,7 @@ Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
bind:currentTime bind:currentTime
bind:paused bind:paused
bind:volume bind:volume
bind:muted
bind:videoWidth bind:videoWidth
bind:videoHeight bind:videoHeight
></video> ></video>

@ -33,11 +33,12 @@ The complete set of bindings for `<audio>` and `<video>` is as follows — six *
* `seeking` (readonly) — boolean * `seeking` (readonly) — boolean
* `ended` (readonly) — boolean * `ended` (readonly) — boolean
...and four *two-way* bindings: ...and five *two-way* bindings:
* `currentTime` — the current point in the video, in seconds * `currentTime` — the current point in the video, in seconds
* `playbackRate` — how fast to play the video, where `1` is 'normal' * `playbackRate` — how fast to play the video, where `1` is 'normal'
* `paused` — this one should be self-explanatory * `paused` — this one should be self-explanatory
* `volume` — a value between 0 and 1 * `volume` — a value between 0 and 1
* `muted` — a boolean value where true is muted
Videos additionally have readonly `videoWidth` and `videoHeight` bindings. Videos additionally have readonly `videoWidth` and `videoHeight` bindings.

@ -638,6 +638,7 @@ export default class Element extends Node {
name === 'seekable' || name === 'seekable' ||
name === 'played' || name === 'played' ||
name === 'volume' || name === 'volume' ||
name === 'muted' ||
name === 'playbackRate' || name === 'playbackRate' ||
name === 'seeking' || name === 'seeking' ||
name === 'ended' name === 'ended'

@ -93,7 +93,7 @@ const events = [
event_names: ['volumechange'], event_names: ['volumechange'],
filter: (node: Element, name: string) => filter: (node: Element, name: string) =>
node.is_media_node() && node.is_media_node() &&
name === 'volume' (name === 'volume' || name === 'muted')
}, },
{ {
event_names: ['ratechange'], event_names: ['ratechange'],

@ -29,18 +29,18 @@ function create_fragment(ctx) {
audio_updating = true; audio_updating = true;
} }
/*audio_timeupdate_handler*/ ctx[12].call(audio); /*audio_timeupdate_handler*/ ctx[13].call(audio);
} }
return { return {
c() { c() {
audio = element("audio"); audio = element("audio");
if (/*buffered*/ ctx[0] === void 0) add_render_callback(() => /*audio_progress_handler*/ ctx[10].call(audio)); if (/*buffered*/ ctx[0] === void 0) add_render_callback(() => /*audio_progress_handler*/ ctx[11].call(audio));
if (/*buffered*/ ctx[0] === void 0 || /*seekable*/ ctx[1] === void 0) add_render_callback(() => /*audio_loadedmetadata_handler*/ ctx[11].call(audio)); if (/*buffered*/ ctx[0] === void 0 || /*seekable*/ ctx[1] === void 0) add_render_callback(() => /*audio_loadedmetadata_handler*/ ctx[12].call(audio));
if (/*played*/ ctx[2] === void 0 || /*currentTime*/ ctx[3] === void 0 || /*ended*/ ctx[9] === void 0) add_render_callback(audio_timeupdate_handler); if (/*played*/ ctx[2] === void 0 || /*currentTime*/ ctx[3] === void 0 || /*ended*/ ctx[10] === void 0) add_render_callback(audio_timeupdate_handler);
if (/*duration*/ ctx[4] === void 0) add_render_callback(() => /*audio_durationchange_handler*/ ctx[13].call(audio)); if (/*duration*/ ctx[4] === void 0) add_render_callback(() => /*audio_durationchange_handler*/ ctx[14].call(audio));
if (/*seeking*/ ctx[8] === void 0) add_render_callback(() => /*audio_seeking_seeked_handler*/ ctx[17].call(audio)); if (/*seeking*/ ctx[9] === void 0) add_render_callback(() => /*audio_seeking_seeked_handler*/ ctx[18].call(audio));
if (/*ended*/ ctx[9] === void 0) add_render_callback(() => /*audio_ended_handler*/ ctx[18].call(audio)); if (/*ended*/ ctx[10] === void 0) add_render_callback(() => /*audio_ended_handler*/ ctx[19].call(audio));
}, },
m(target, anchor, remount) { m(target, anchor, remount) {
insert(target, audio, anchor); insert(target, audio, anchor);
@ -49,24 +49,26 @@ function create_fragment(ctx) {
audio.volume = /*volume*/ ctx[6]; audio.volume = /*volume*/ ctx[6];
} }
if (!isNaN(/*playbackRate*/ ctx[7])) { audio.muted = /*muted*/ ctx[7];
audio.playbackRate = /*playbackRate*/ ctx[7];
if (!isNaN(/*playbackRate*/ ctx[8])) {
audio.playbackRate = /*playbackRate*/ ctx[8];
} }
if (remount) run_all(dispose); if (remount) run_all(dispose);
dispose = [ dispose = [
listen(audio, "progress", /*audio_progress_handler*/ ctx[10]), listen(audio, "progress", /*audio_progress_handler*/ ctx[11]),
listen(audio, "loadedmetadata", /*audio_loadedmetadata_handler*/ ctx[11]), listen(audio, "loadedmetadata", /*audio_loadedmetadata_handler*/ ctx[12]),
listen(audio, "timeupdate", audio_timeupdate_handler), listen(audio, "timeupdate", audio_timeupdate_handler),
listen(audio, "durationchange", /*audio_durationchange_handler*/ ctx[13]), listen(audio, "durationchange", /*audio_durationchange_handler*/ ctx[14]),
listen(audio, "play", /*audio_play_pause_handler*/ ctx[14]), listen(audio, "play", /*audio_play_pause_handler*/ ctx[15]),
listen(audio, "pause", /*audio_play_pause_handler*/ ctx[14]), listen(audio, "pause", /*audio_play_pause_handler*/ ctx[15]),
listen(audio, "volumechange", /*audio_volumechange_handler*/ ctx[15]), listen(audio, "volumechange", /*audio_volumechange_handler*/ ctx[16]),
listen(audio, "ratechange", /*audio_ratechange_handler*/ ctx[16]), listen(audio, "ratechange", /*audio_ratechange_handler*/ ctx[17]),
listen(audio, "seeking", /*audio_seeking_seeked_handler*/ ctx[17]), listen(audio, "seeking", /*audio_seeking_seeked_handler*/ ctx[18]),
listen(audio, "seeked", /*audio_seeking_seeked_handler*/ ctx[17]), listen(audio, "seeked", /*audio_seeking_seeked_handler*/ ctx[18]),
listen(audio, "ended", /*audio_ended_handler*/ ctx[18]) listen(audio, "ended", /*audio_ended_handler*/ ctx[19])
]; ];
}, },
p(ctx, [dirty]) { p(ctx, [dirty]) {
@ -84,8 +86,12 @@ function create_fragment(ctx) {
audio.volume = /*volume*/ ctx[6]; audio.volume = /*volume*/ ctx[6];
} }
if (dirty & /*playbackRate*/ 128 && !isNaN(/*playbackRate*/ ctx[7])) { if (dirty & /*muted*/ 128) {
audio.playbackRate = /*playbackRate*/ ctx[7]; audio.muted = /*muted*/ ctx[7];
}
if (dirty & /*playbackRate*/ 256 && !isNaN(/*playbackRate*/ ctx[8])) {
audio.playbackRate = /*playbackRate*/ ctx[8];
} }
}, },
i: noop, i: noop,
@ -105,6 +111,7 @@ function instance($$self, $$props, $$invalidate) {
let { duration } = $$props; let { duration } = $$props;
let { paused } = $$props; let { paused } = $$props;
let { volume } = $$props; let { volume } = $$props;
let { muted } = $$props;
let { playbackRate } = $$props; let { playbackRate } = $$props;
let { seeking } = $$props; let { seeking } = $$props;
let { ended } = $$props; let { ended } = $$props;
@ -127,7 +134,7 @@ function instance($$self, $$props, $$invalidate) {
ended = this.ended; ended = this.ended;
$$invalidate(2, played); $$invalidate(2, played);
$$invalidate(3, currentTime); $$invalidate(3, currentTime);
$$invalidate(9, ended); $$invalidate(10, ended);
} }
function audio_durationchange_handler() { function audio_durationchange_handler() {
@ -142,22 +149,24 @@ function instance($$self, $$props, $$invalidate) {
function audio_volumechange_handler() { function audio_volumechange_handler() {
volume = this.volume; volume = this.volume;
muted = this.muted;
$$invalidate(6, volume); $$invalidate(6, volume);
$$invalidate(7, muted);
} }
function audio_ratechange_handler() { function audio_ratechange_handler() {
playbackRate = this.playbackRate; playbackRate = this.playbackRate;
$$invalidate(7, playbackRate); $$invalidate(8, playbackRate);
} }
function audio_seeking_seeked_handler() { function audio_seeking_seeked_handler() {
seeking = this.seeking; seeking = this.seeking;
$$invalidate(8, seeking); $$invalidate(9, seeking);
} }
function audio_ended_handler() { function audio_ended_handler() {
ended = this.ended; ended = this.ended;
$$invalidate(9, ended); $$invalidate(10, ended);
} }
$$self.$set = $$props => { $$self.$set = $$props => {
@ -168,9 +177,10 @@ function instance($$self, $$props, $$invalidate) {
if ("duration" in $$props) $$invalidate(4, duration = $$props.duration); if ("duration" in $$props) $$invalidate(4, duration = $$props.duration);
if ("paused" in $$props) $$invalidate(5, paused = $$props.paused); if ("paused" in $$props) $$invalidate(5, paused = $$props.paused);
if ("volume" in $$props) $$invalidate(6, volume = $$props.volume); if ("volume" in $$props) $$invalidate(6, volume = $$props.volume);
if ("playbackRate" in $$props) $$invalidate(7, playbackRate = $$props.playbackRate); if ("muted" in $$props) $$invalidate(7, muted = $$props.muted);
if ("seeking" in $$props) $$invalidate(8, seeking = $$props.seeking); if ("playbackRate" in $$props) $$invalidate(8, playbackRate = $$props.playbackRate);
if ("ended" in $$props) $$invalidate(9, ended = $$props.ended); if ("seeking" in $$props) $$invalidate(9, seeking = $$props.seeking);
if ("ended" in $$props) $$invalidate(10, ended = $$props.ended);
}; };
return [ return [
@ -181,6 +191,7 @@ function instance($$self, $$props, $$invalidate) {
duration, duration,
paused, paused,
volume, volume,
muted,
playbackRate, playbackRate,
seeking, seeking,
ended, ended,
@ -208,9 +219,10 @@ class Component extends SvelteComponent {
duration: 4, duration: 4,
paused: 5, paused: 5,
volume: 6, volume: 6,
playbackRate: 7, muted: 7,
seeking: 8, playbackRate: 8,
ended: 9 seeking: 9,
ended: 10
}); });
} }
} }

@ -6,9 +6,10 @@
export let duration; export let duration;
export let paused; export let paused;
export let volume; export let volume;
export let muted;
export let playbackRate; export let playbackRate;
export let seeking; export let seeking;
export let ended; export let ended;
</script> </script>
<audio bind:buffered bind:seekable bind:played bind:currentTime bind:duration bind:paused bind:volume bind:playbackRate bind:seeking bind:ended/> <audio bind:buffered bind:seekable bind:played bind:currentTime bind:duration bind:paused bind:volume bind:muted bind:playbackRate bind:seeking bind:ended/>

@ -8,6 +8,7 @@ export default {
assert.equal(component.t, 0); assert.equal(component.t, 0);
assert.equal(component.d, 0); assert.equal(component.d, 0);
assert.equal(component.v, 0.5); assert.equal(component.v, 0.5);
assert.equal(component.m, true);
assert.equal(component.r, 1); assert.equal(component.r, 1);
assert.equal(component.paused, true); assert.equal(component.paused, true);
@ -20,6 +21,7 @@ export default {
audio.currentTime = 10; audio.currentTime = 10;
audio.duration = 20; audio.duration = 20;
audio.volume = 0.75; audio.volume = 0.75;
audio.muted = false;
audio.playbackRate = 2; audio.playbackRate = 2;
audio.dispatchEvent(timeupdate); audio.dispatchEvent(timeupdate);
audio.dispatchEvent(durationchange); audio.dispatchEvent(durationchange);
@ -30,6 +32,7 @@ export default {
assert.equal(component.t, 10); assert.equal(component.t, 10);
assert.equal(component.d, 0); // not 20, because read-only. Not sure how to test this! assert.equal(component.d, 0); // not 20, because read-only. Not sure how to test this!
assert.equal(component.v, 0.75); assert.equal(component.v, 0.75);
assert.equal(component.m, false);
assert.equal(component.r, 2); assert.equal(component.r, 2);
assert.equal(component.paused, true); // ditto... assert.equal(component.paused, true); // ditto...
} }

@ -4,7 +4,8 @@
export let paused; export let paused;
export let v; export let v;
export let r; export let r;
export let m;
</script> </script>
<audio bind:currentTime={t} bind:duration={d} bind:paused bind:volume={v} bind:playbackRate={r} <audio bind:currentTime={t} bind:duration={d} bind:paused bind:volume={v} bind:muted={m} bind:playbackRate={r}
src='music.mp3'></audio> src='music.mp3'></audio>
Loading…
Cancel
Save