This is a bit of a special Simplequiz this week. Simon Pieters (@zcorpan), who works on multimedia QA for Opera and is one of those working on the HTML5 spec, asked us to run a quiz that would help the spec writers decide on a new aspect of the language. What power you wield, gentle reader! Over to Simon…
This SimpleQuiz is a bit different to previous SimpleQuizzes, since we’d like to use the result of this quiz to inform a design decision in the HTML5 spec. The question concerns how to mute a video in markup, and how this should be reflected in the DOM.
The use case is wanting to have multiple videos playing at once, but with all but one being muted at a time.
This can be done today by setting .muted = true
with script, but it would be more convenient to be able to mute with markup.
The .muted
IDL attribute reflects the user setting of muted for the video element — if the user clicks “mute” in the native video controls, then the value of .muted
changes, and vice versa. It would make sense for the browser to remember the mute setting for individual video elements on page reload (or later visit), so that the user doesn’t have to re-mute them.
This is where it starts to get hairy if we introduce a content attribute for muting. (Note that code fragments below aren’t real code, just suggestions.)
We could introduce muted=""
which is reflected by .muted
(i.e. if one changes, so does the other), but this would cause the DOM to mutate during parsing if the remembered setting doesn’t match the markup, i.e. you would get muted=""
to appear in the DOM if the video is muted by the user even though there was no such attribute in the markup, which could confuse your scripts or style sheets if it’s not what you expected to happen.
We could introduce defaultmuted=""
which is reflected by .defaultMuted
, and just let the user setting change .muted
, but defaultmuted=""
is a bit long and ugly in markup.
We could have muted=""
which is reflected by .defaultMuted
and let the user setting change .muted
, but it might be confusing for some people. On the other hand it is consistent with <input value>
and .defaultValue
.
What do you think? Which is the best option? Is there another option that is better than any of the above?
32 Responses on the article “HTML5 Simplequiz #3: how to mute a video”
That is difficult.
My gut reaction was to say that I wouldn’t expect the markup property and the script property to be synchronised (beyond page load).
But it would be useful if they were, given your use case.
Rich
To me, it seems like volume=”0″ would cover the muted attribute. Why would you need 2 different attributes for the same end result?
Mike: The API has both .volume and .muted since video controls often have separate buttons for mute and volume (and the volume is remembered if you unmute).
However, if we ignore that and imagine that we want volume=”0″ instead, we still face the same problem, since the browser would want to remember the volume setting but we don’t want to mutate the DOM during parsing.
Shouldn’t you also mention Hixie’s audio=”” option, even though you don’t like it?
I do like the defaultMuted=”” solution, but to get around the clumsy language, I’d suggest that “mute” could be a fitting label.
The markup uses mute=”true|false” simply as a request to the browser. A nice and easy attribute name.
The browser compares that with the .muted (past-tense) value in the DOM if it exists, any overriding user settings (like an “always mute videos” option), and decides whether or not to mute the video?
Oh, I don’t know.
Introduce muted as a Boolean attribute reflected by .defaultMuted. The markup is short and readable, and it ‘paves the cowpaths’ by reinforcing an established pattern (value=”” and .defaultValue).
Philip: yeah, I guess. My defence is that I wrote this before he suggested audio=””. :-)
Hixie’s suggestion is in the relevant spec bug here: http://www.w3.org/Bugs/Public/show_bug.cgi?id=10419#c8
Bruce, I do not understand exactly the use case. Are you saying that the page contains a list of videos, let say: three videos. One would have an attribute
muted="false"
and the two others
muted="true"
?
1. The person arrives on the page the first video is not muted.
2. Then the person mutes it and unmutes the second video.
3. The person closes the tab.
4. The person comes back later on the same page and the state is the second video is unmuted and 1 and 3 muted?
It seems windows media player had a
<param name="Mute" value="false">
. (*to check*)Youtube has in its API
http://code.google.com/apis/youtube/js_api_reference.html
*
player.mute():Void
-- Mutes the player.*
player.isMuted():Boolean
- Returns true if the player is muted, false if not.DailyMotion API
http://www.dailymotion.com/en/doc/api/player/javascript_api
*
player.mute():Void
-- Mutes the audio playback.*
player.isMuted():Boolean
- If audio playback is muted, returns true, false otherwise.Vimeo Moogaloop video player doesn't seem to have anything for mute in the API.
http://vimeo.com/forums/topic:25102
A parameter which is mute="" seems to be aligned with YouTube and DailyMotion
I agree with [video muted/] as a boolean attribute a la “selected”, and to have it reflected in the DOM as .defaultMuted.
It’s a useful piece of markup on an element that is expected to be heavily scripted, and I like the comparison to [input value/].
I understand now.
It seems to me the best way to do it would be through using muted to define defaultmuted. I don’t think that’s confusing.
Is there any point in reflecting muted=”” at all? It doesn’t seem particularly useful, since if you have scripts you can just set .muted, right?
I distinguish between what happens at the instant of loading the markup and what happens via scripting after the fact. So if there are three videos, with two set to defaultMuted=’true’ and one defaultMuted=’false’ (false is default?) then at load one is playing sound. After that fact, if scripts change the .muted property, that only needs to be represented in the javascript object. I wouldn’t expect the markup to change.
It might be slightly clearer if the attribute were loadsMuted or startsMuted to more clearly reflect the fact that it can (will) change.
Simply calling the attribute ‘muted’ is confusing because it will be out of sync with reality, where calling it defaultMuted or loadsMuted or startsMuted maintains sync with the reality that it *did* start muted, but it must have been changed.
Sticking to the input model sounds fine (muted=””, .defaultMuted, .muted)
What is mute?
Mute is an automatic Volume=”0″ and remembers where it came from. When I mute my TV the volume reflected to me is 0. When I un-mute my TV my volume returns to where it originally was. This is the same behavior my OS exhibits when I open up my sound controller and perform the same action.
But video players have both right now, don’t they?
True most video players have a volume control and a control that handles the mute process. But what does that mute button really do? It is setting the volume to 0. Some systems allow it to directly interface with the OS settings. But it also remembers where it was so that when unmuting it returns to that previous volume level.
So how should “Mute” be handled in HTML5
As I see it, HTML5 should handle muting just like my other video players.
HTML
<video volume="0" />
<video volume="5" mute="true" />
<video mute="false" />
Mute=true would provide the developer to set a default volume for the player to play at when the user plays it. The mute attribute will allow the volume to be muted initially and providing a volume value would set the default for when it is unmuted. Mute=false would be the default experience from this attribute.
When the DOM is built the previousVolume would be set to 5 if mute=true. if mute= false then the default volume value would be used.
If no mute value is assumed and no volume value is provided then the default expectation would be to have the default volume be set, the previousvolume set to the default volume value and the mute state to be false.
JS
var vPlayer = document.getElementById("video1");
vPlayer.mute(true); //this is a method specific to video player elements
vPlayer.previousVolume; //this is the property set by mute
/*
If we allow this to be set then we allow developers to misbehave
This should be a get ONLY method for this setting
*/
vPlayer.volume; //the current volume setting
vPlayer.mute(false); //this unmutes the volume and returns the volume back to the previous level
The way we use and experience “Mute”ing the volume of something on any device we have that provides this functionality, is designing the experience of the user. Why should we try to redefine a functionality that has been around for decades already? Let us experience Mute in HTML5 as we do in all aspects of our lives that provide us the ability to Mute.
I agree with Bryan above, but would prefer it to be a Boolean attribute.
I have a comment in the moderation queue ;)
I see commenters using muted and mute. To facilitate learning and ease usage of the new HTML5 vocabularies, as much as possible we should keep the model of Boolean attributes as adjectives.
My previous comment mysteriously hasn’t been published, so I’d like to repeat it one more.
The attribute muted could be given a value of auto, which is the user’s remembered value. As simple as that.
Personally, I find the idea of having “muted” and “defaultMuted” IDL attributes and an “muted” content attribute reflected by the defautMuted IDL attribute a gotcha in the making. I accept that it follows the input value/.defaultValue pattern but I would ask how many web authors actually understand how that works? I must confess that I only very recently came to grasp it. I’m guessing that the input value/.defaultValue pattern came about out of the necessity for backward compatibility, rather than because it was considered the “right” pattern from day one.
Whenever the content attribute and IDL attribute don’t have matching names, I’ve seen it cause confusion. I know that in many places it’s unavoidable, but that doesn’t seem to be the case here, so while “defaultmuted” is an ugly name for a content attribute, HTML mark-up is not in any case a thing of great beauty, and I would vote for it as the best option.
I really like Bryan Wood’s proposal, but I would suggest some changes:
HTML
<video volume="84" muted="muted"/>
JS
var video = $(...) / getElement(s)ByWhatever... / blah blah blah
video.volume // returns 84
video.muted // returns true
video.muted = false; // unmutes the video
video.volume; // returns 84
video.muted; // returns false
video.muted = true; // mutes the video
video.volume; // returns 84
video.muted; // returns true
How is different, you ask?
First: HTML tags make use of real boolean attributes — sorry buddy:
mute="true"
is not a valid boolean selector according to the spec!This means that we can access the
muted
property via JS in a consistent way.More: the browser will consider anything else being rubbish and will ignore it straight away (if I got the specs right.)
Second: volume is not involved at all: it’s a browser behavior thing.
Is the
muted
attribute present? Okay, let’s mute the video (andaudio
too?) volume, but DON’T touch thevolume
attribute!Maybe internally the browser could do just that, take the volume to zero, but from the DOM point of view, it shouldn’t touch the
volume
attribute.previousVolume
!? Why using a third property for reading the current volume? We already have that data!volume
&muted
are enough, as long as you keep ’em independent from each other.Whoops!
[…] is not a valid boolean attribute according […]
Sorry for the typo!
Having read the relevant bug discussion, and what the spec currently says (sorry, should have done that first), an “audio” content attribute reflected by an “audio” IDL attribute also works for me, although the current spec looks a bit weird with a list of space-separated tokens being used to set a boolean value.
In fact, won’t the fact that the audio IDL attribute is boolean preclude it reflecting the content attribute if it is extended to use the space-separated list more fully? For example it is suggested in the spec that the content attribute could have a volume setting so I can envisage a content attribute use like audio=”muted 0.5″ to set the default volume to half max volume when the video is unmuted. I’d want the audio IDL attribute to reflect all of that, not just the initial muted state.
Alohci, Hixie just changed the spec to add his audio=”” suggestion (for now just supports “muted” but is intended to be extensible to cover volume and other things as well going forward). However that doesn’t mean it’s a done deal; if we come to a conclusion from this discussion that something else is a better design then we can reopen the bug with that new information.
@zcorpan – Of course, I wasn’t trying in any way to help pre-empt the discussion here. My comment was really just an aside; I was looking to see if others here agreed that what the spec currently says doesn’t quite work at a technical level. That if it was implemented as is, it would be necessary to create a new IDL attribute in addition to “audio” to reflect a later extended “audio” content attribute. That would be bad.
I agree with Steve above , and also with Massimo –
1.
mute
should be for the mute action – should I mute? It should indicate what will be the default behavior. In JS – instead of doing.muted = true
it should be.mute() / .unmute()
. Methods instead of properties.2.
muted
should only exist in the API to tell the current state of the element, as represented by the Browser’s decision. So I can doif (myEl.muted)
. As such, it defenetly has to bemuted="muted"
(or – alsomuted
) – this is a very important standard.3. I don’t like the
.defaultMuted
concept – it make the API less intuitive – when do I lookup a “default” attribute, and when am I looking for the attribute name? I find that since we have so many APIs around, we should stick to simple naming conventions.Nice one Bruce. Some good comments and discussion going on here.
I like muted=”muted”
I’m a fan of the third option:
<video muted>
being represented by.deaultMuted
IDL attribute. The described behaviour is exactly what I would expect as a web author.Still can’t decide whether or not I agree with proposal for
audio=""
attribute, though. I like how it allows separation of audio options in video context, but don’t like the fact that it would have to have different semantics in<audio>
, which has is the point already raised by Philip Jägenstedt. Having separate attributes for volume and other potential audio settings makes them reusable across media elements.Of course, as a user I would expect that after I mute one video all videos loaded in the future should be muted as well, whether or not attribute being set. Although web author can unmute video using script, such a behaviour should not be supported using markup.
I like Bryan’s way of doing it, it makes sense.
One question I have is why multiple videos would play simultaneously? A user could only watch one at a time, and playing multiple videos uses up more resources, and if the user is interested in them, would force them to rewind the next video they want to see. wouldn’t it be better to simply have all other videos paused at load?
gabriel, one use case is having multiple videos playing at once to see what’s on other channels on TV right now.
OK to today is wrap-up day; thanks for all the comments! I’ve reopened the bug asking the editor to consider your comments.
Hmm, perhaps it would benefit to consider a child audio element managing the audio parameters, similar to [source] and [param]. This may be considered as overloading a tag, but consider that a video element (in most cases) handles media that houses both video and audio content that happen to be synced together in rendering time: The video tag is like an audio tag with added video accompaniment. The audio portion could easily have all or most of the same settings as an audio tag by itself, and it would be ideal to keep them the same between the two tags (or any others with audio): A child audio tag would ensure this, and the video tag attributes could be limited to those directly related to the video portion of playback. Then the muted solution used for [audio] would also be used for [video]. I’m fine with muted=”muted” -> .defaultMuted and .muted as current state.
It would look something like:
<video controls>
<audio muted>
<source src=”whatever”>
… other sources … fallback content …
</video>
This would also allow for handling the rare use case of a separate audio track for silent movies or a single audio track for multiple videos (changed via JS). And an audio element without src would be nothing to a browser that could for some reason understand [audio] but not [video].
If that seems to be rubbish, I still would prefer to see some sort of solution where the audio portion of a video has the same attributes as the audio tag itself, and thus dislike the audio attribute. I’d be fine with the muted attribute as above.
As memory of settings go though it would be more common to want mute state / volume to remain the same for a single site or all sites though rather than individual videos.
Video tags attribute muted=”true” could help a lot. A Better suggestion would be volume=”0″, so that when we connect laptop to tv or audio outputs we can control the relative volume.
Join the discussion.