This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 12559 - <video> Make paused true at playback end
Summary: <video> Make paused true at playback end
Status: RESOLVED FIXED
Alias: None
Product: HTML WG
Classification: Unclassified
Component: LC1 HTML5 spec (show other bugs)
Version: unspecified
Hardware: Other other
: P3 normal
Target Milestone: ---
Assignee: Ian 'Hixie' Hickson
QA Contact: HTML WG Bugzilla archive list
URL: http://www.whatwg.org/specs/web-apps/...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-26 15:35 UTC by contributor
Modified: 2011-09-22 22:29 UTC (History)
7 users (show)

See Also:


Attachments

Description contributor 2011-04-26 15:35:39 UTC
Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
Section: http://www.whatwg.org/specs/web-apps/current-work/#ended-playback

Comment:
Make paused true at playback end

Posted from: 83.218.67.122
User agent: Opera/9.80 (X11; Linux x86_64; U; en) Presto/2.8.131 Version/11.10
Comment 1 Philip Jägenstedt 2011-04-26 15:40:26 UTC
This is a long-standing piece of ugliness in the spec that's just been left in. When playback ends, the paused state does not automatically change, so any UI must look at both the paused state and the ended state to decide whether to show a play button or pause button. If they don't, you'll end up with a UI that shows the wrong thing at playback end and a button you have to click twice for playback to start over.

I've seen confusion about this pop up now and again. While it's easy enough to work around, it'd be nice if it would just work to begin with. So, unless there are good reasons for the current design, I suggest we change it to pause automatically at playback end.
Comment 2 Silvia Pfeiffer 2011-04-27 05:37:33 UTC
(In reply to comment #1)
> This is a long-standing piece of ugliness in the spec that's just been left in.
> When playback ends, the paused state does not automatically change, so any UI
> must look at both the paused state and the ended state to decide whether to
> show a play button or pause button. If they don't, you'll end up with a UI that
> shows the wrong thing at playback end and a button you have to click twice for
> playback to start over.
> 
> I've seen confusion about this pop up now and again. While it's easy enough to
> work around, it'd be nice if it would just work to begin with. So, unless there
> are good reasons for the current design, I suggest we change it to pause
> automatically at playback end.

That is: unless it's looping.

I agree with this change. It is really annoying as a user when the video reaches the end and the controls go into "pause" state, but the video state doesn't. So, everything that is based on the "onplay" event doesn't get restarted when the user hits the "play" button again. You can see an example at http://www.html5videoguide.net/code_c7_1.html . Let it play through to the end, then hit the play button again, and notice that the "onplay" event is not reactivated.
Comment 3 Ian 'Hixie' Hickson 2011-07-15 21:51:06 UTC
This would have all kinds of weird side-effects I don't think you want. For example, say you had two <video> elements with the same mediagroup="", both marked as autoplay="", and one is longer than the other. If we set paused to true when a media element's playback ends, then as soon as one of the two tracks ends, seeking back to before that point would only have the long track playing.
Comment 4 Silvia Pfeiffer 2011-07-15 23:04:57 UTC
(In reply to comment #3)
> This would have all kinds of weird side-effects I don't think you want. For
> example, say you had two <video> elements with the same mediagroup="", both
> marked as autoplay="", and one is longer than the other. If we set paused to
> true when a media element's playback ends, then as soon as one of the two
> tracks ends, seeking back to before that point would only have the long track
> playing.

I think there is something weird going on with the MediaController.

I only just noticed that the MediaController's paused state is true when *any* slave is paused. The way I read this, it means that when pause() is called on one slave, that this slave goes into paused state, the controller goes into paused state, but all other slaves continue playing. I think that's a mistake.

The MediaController is representing the combined state of all slaves. Therefore, a MediaController's paused state should be true only when *all* slaves are paused (not when one of them is). Further, a pause() and play() call on the controller need to be propagated to all slaves - I couldn't find this in the spec.

Then, the combined resource will continue playing until all slaves reach ended, at which point the controller reaches ended. Now, when all slaves have reached ended, we could put them all into paused state, which is what a combined play button would also show at this instance, thus removing the weird side-effect that you pointed out.
Comment 5 Ian 'Hixie' Hickson 2011-07-19 19:46:11 UTC
(In reply to comment #4)
> 
> I only just noticed that the MediaController's paused state is true when *any*
> slave is paused.

I don't think that's accurate — what part of the spec says that?

 
> The MediaController is representing the combined state of all slaves.
> Therefore, a MediaController's paused state should be true only when *all*
> slaves are paused (not when one of them is). Further, a pause() and play() call
> on the controller need to be propagated to all slaves - I couldn't find this in
> the spec.

The paused state of MediaControllers is mostly independent of the state of the slaves.


> Then, the combined resource will continue playing until all slaves reach ended,
> at which point the controller reaches ended. Now, when all slaves have reached
> ended, we could put them all into paused state, which is what a combined play
> button would also show at this instance, thus removing the weird side-effect
> that you pointed out.

Hm, interesting approach. Let me think about how to do that.
Comment 6 Ian 'Hixie' Hickson 2011-07-19 19:52:07 UTC
Looks like this would mean putting hooks in the following places:

 - mediagroup="" setter, probably between steps 2 and 3.
 - controller IDL attribute setter.
 - the algorithm that currently sets 'ended'.

Need to decide what should happen when a video that is shorter than the mediagroup's other media resources is ended and the video is switched to another media controller rather than to no controller (and whether it depends on the length of the media in that other controller).

Also need to decide what happens when going backwards and hitting the front.
Comment 7 Silvia Pfeiffer 2011-07-20 04:40:52 UTC
(In reply to comment #5)
> (In reply to comment #4)
> > 
> > I only just noticed that the MediaController's paused state is true when *any*
> > slave is paused.
> 
> I don't think that's accurate — what part of the spec says that?


I might have mis-read this part of the spec:

controller.paused
    Returns true if playback is paused; false otherwise. When this attribute is true, any media element slaved to this controller will be stopped.

Does "any" in this sentence mean "all"?


> > The MediaController is representing the combined state of all slaves.
> > Therefore, a MediaController's paused state should be true only when *all*
> > slaves are paused (not when one of them is). Further, a pause() and play() call
> > on the controller need to be propagated to all slaves - I couldn't find this in
> > the spec.
> 
> The paused state of MediaControllers is mostly independent of the state of the
> slaves.
> 
> > Then, the combined resource will continue playing until all slaves reach ended,
> > at which point the controller reaches ended. Now, when all slaves have reached
> > ended, we could put them all into paused state, which is what a combined play
> > button would also show at this instance, thus removing the weird side-effect
> > that you pointed out.
> 
> Hm, interesting approach. Let me think about how to do that.
Comment 8 Silvia Pfeiffer 2011-07-20 04:45:55 UTC
(In reply to comment #6)
> Looks like this would mean putting hooks in the following places:
> 
>  - mediagroup="" setter, probably between steps 2 and 3.
>  - controller IDL attribute setter.
>  - the algorithm that currently sets 'ended'.
> 
> Need to decide what should happen when a video that is shorter than the
> mediagroup's other media resources is ended and the video is switched to
> another media controller rather than to no controller (and whether it depends
> on the length of the media in that other controller).

Would it make sense to take the slave to "ended", but non-paused state until all of them have reached "ended", then an "ended" on the controller will move itself to paused and all slaves, too?


> Also need to decide what happens when going backwards and hitting the front.

Is that through an explicit seek by the user or implicit? I would think that once all have reached "ended" and everything is in "paused" sitting at the end, then hitting "play" again does a seek to the beginning of them all and raises the "playing" event. Explicit seeks use whatever state the controller is still in (paused if ended, playing if not all slaves have ended).
Comment 9 Michael[tm] Smith 2011-08-04 05:00:14 UTC
mass-moved component to LC1
Comment 10 Ian 'Hixie' Hickson 2011-08-09 05:07:43 UTC
> I might have mis-read this part of the spec:
> 
> controller.paused
>     Returns true if playback is paused; false otherwise. When this attribute is
> true, any media element slaved to this controller will be stopped.

Please ignore the non-normative text. It's only useful for people who just want a quick introduction and don't need to know the details. You don't qualify for that. :-)


> Does "any" in this sentence mean "all"?

They would both mean the same thing in that context, no?


For the last comment in comment 6 I meant when playing backwards.
Comment 11 Silvia Pfeiffer 2011-08-09 10:04:54 UTC
(In reply to comment #10)
> > I might have mis-read this part of the spec:
> > 
> > controller.paused
> >     Returns true if playback is paused; false otherwise. When this attribute is
> > true, any media element slaved to this controller will be stopped.
> 
> Please ignore the non-normative text. It's only useful for people who just want
> a quick introduction and don't need to know the details. You don't qualify for
> that. :-)


Still needs to be accurate since we don't want to confuse those after a quick answer either.

 
> > Does "any" in this sentence mean "all"?
> 
> They would both mean the same thing in that context, no?

I am not a native English speaker, but my reading of "any out of a group" is that it means a single one out of the group - which one doesn't matter. I'd prefer we use the word "every" in this sentence instead if that's what is meant.


 
> For the last comment in comment 6 I meant when playing backwards.

I see. I'd say it should also go into paused state. Since grouped elements started at the same time, that shouldn't cause the same kinds of problems as the different length.
Comment 12 Ian 'Hixie' Hickson 2011-09-22 22:28:51 UTC
EDITOR'S RESPONSE: This is an Editor's Response to your comment. If you are satisfied with this response, please change the state of this bug to CLOSED. If you have additional information and would like the editor to reconsider, please reopen this bug. If you would like to escalate the issue to the full HTML Working Group, please add the TrackerRequest keyword to this bug, and suggest title and text for the tracker issue; or you may create a tracker issue yourself, if you are able to do so. For more details, see this document:
   http://dev.w3.org/html5/decision-policy/decision-policy.html

Status: Partially Accepted
Change Description: see diff given below
Rationale: 

Ok I did this but it ended up being a bit different than what I'd described earlier.

* I made the changing of the 'ended' attribute synchronous with the firing of the asynchronous 'ended' event, so it can no longer happen in the middle of a script running.

* A standalone media element, when it reaches its end going forwards, if it isn't looping, now pauses automatically. The sequence of events is .ended becomes true, timeupdate fires, .paused becomes true and pause fires, and finally ended fires.

* A slaved media element never pauses when it reaches its end, because otherwise it would desync with its controller. The controller, however, does the same 'pause' dance as a standalone media element; when the last slave ends, that media element's .ended becomes true, timeupdate fires on it, ended fires on it, then the media controller pauses and pause fires, then ended fires.

* I haven't done anything to make slaved media elements automatically pause when they are unslaved, so it's still possible to have a media element that is ended and not paused. This is necessary because otherwise when you move an element from one slave to another while it's ended, you'd always have to unpause it again, which would be crazy.

* Because all this is async rather than happening when the playback actually ends, we have to deal with hostile scripts changing the state out from under us. See the spec for the precise details, but basically the pausing only happens if nothing has screwed around with the media element in the meantime (hopefully I didn't miss any important cases... testing this is going to be hell).


(In reply to comment #11)
> > > 
> > > controller.paused
> > >     Returns true if playback is paused; false otherwise. When this attribute is
> > > true, any media element slaved to this controller will be stopped.
> > 
> > Please ignore the non-normative text. It's only useful for people who just want
> > a quick introduction and don't need to know the details. You don't qualify for
> > that. :-)
> 
> Still needs to be accurate since we don't want to confuse those after a quick
> answer either.

It's accurate, as far as I can tell. It just tells you what happens, not what to implement.


> > > Does "any" in this sentence mean "all"?
> > 
> > They would both mean the same thing in that context, no?
> 
> I am not a native English speaker, but my reading of "any out of a group" is
> that it means a single one out of the group - which one doesn't matter. I'd
> prefer we use the word "every" in this sentence instead if that's what is
> meant.

If we used "all" or "every" we'd have to also say "if any" to handle the case where there are none.

"Any" is the right word here. It doesn't mean "one", it means "whichever of these that exist".


> > For the last comment in comment 6 I meant when playing backwards.
> 
> I see. I'd say it should also go into paused state. Since grouped elements
> started at the same time, that shouldn't cause the same kinds of problems as
> the different length.

I haven't made anything pause when going backwards. It also doesn't fire the ended event or indeed set .ended to true, either on the media element or the controller.
Comment 13 contributor 2011-09-22 22:29:32 UTC
Checked in as WHATWG revision r6562.
Check-in comment: When a media element ends, pause it. Same for MediaControllers. Also a bunch of minor editorial tweaks.
http://html5.org/tools/web-apps-tracker?from=6561&to=6562