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 4 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
* `ended` (readonly) — boolean
...and four *two-way* bindings:
...and five *two-way* bindings:
* `currentTime` — the current point in the video, in seconds
* `playbackRate` — how fast to play the video, where 1 is 'normal'
* `paused` — this one should be self-explanatory
* `volume` — a value between 0 and 1
* `muted` — a boolean value where true is muted
Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
@ -624,6 +625,7 @@ Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
bind:currentTime
bind:paused
bind:volume
bind:muted
bind:videoWidth
bind:videoHeight
></video>

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

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

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

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

@ -6,9 +6,10 @@
export let duration;
export let paused;
export let volume;
export let muted;
export let playbackRate;
export let seeking;
export let ended;
</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.d, 0);
assert.equal(component.v, 0.5);
assert.equal(component.m, true);
assert.equal(component.r, 1);
assert.equal(component.paused, true);
@ -20,6 +21,7 @@ export default {
audio.currentTime = 10;
audio.duration = 20;
audio.volume = 0.75;
audio.muted = false;
audio.playbackRate = 2;
audio.dispatchEvent(timeupdate);
audio.dispatchEvent(durationchange);
@ -30,6 +32,7 @@ export default {
assert.equal(component.t, 10);
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.m, false);
assert.equal(component.r, 2);
assert.equal(component.paused, true); // ditto...
}

@ -4,7 +4,8 @@
export let paused;
export let v;
export let r;
export let m;
</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>
Loading…
Cancel
Save