Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throw exception when HTMLMediaElement’s defaultPlaybackRate or playbackRate are set to negative values if unsupported by the user agent. #2754

Closed
japacible opened this issue Jun 13, 2017 · 35 comments
Labels
interop Implementations are not interoperable with each other topic: media

Comments

@japacible
Copy link
Contributor

japacible commented Jun 13, 2017

cc @jernoble @foolip @mounirlamouri @cpearce

Setting a video's defaultPlaybackRate or playbackRate to a negative value does not have uniform behavior across the major browsers:

Browser defaultPlaybackRate = -1 playbackRate = -1
Chrome defaultPlaybackRate set to -1, plays at 1 playbackRate set to -1, plays at 1
Edge defaultPlaybackRate set to 1 playbackRate set to 1
Firefox NS_ERROR_NOT_IMPLEMENTED NS_ERROR_NOT_IMPLEMENTED
Safari implements if set before load time implements

The spec does not currently specify the desired behavior in the case when the value set is negative.

While some non-negative values are unsupported by some implementations, they are usually approximated or capped, making the problem different (e.g. 10x as 5x, 0.001x as 0.1x). Negative values are uncommon, can’t be approximated, and unlikely to be used.

We propose to throw a RangeError when the value of playbackRate or defaultPlaybackRate is
negative.

edit: updated safari behavior per jernoble's comment.

@jernoble
Copy link

Your test seems to be incorrect in the case of Safari. Setting defaultPlaybackRate = -1 works correctly if you do it before load time. e.g.:

	video.defaultPlaybackRate = -1;
	video.src = "movie.mp4";
	video.addEventListener('canplay', event => {
		console.log(video.playbackRate); // "-1"
	});

@jernoble
Copy link

Additionally, this seems to be a quality-of-implementation issue. If a UA can't handle playing backwards at a given rate, they can approximate a negative playback rate by repeatedly seeking (perhaps to I-frame boundaries). This was always the intention, even with unsupported forward rates, as you mention.

@domenic
Copy link
Member

domenic commented Jun 13, 2017

In the end this is a matter of implementation interest; we can't include features in the spec that only one browser implements.

Do we have any interest from other browsers besides Safari in implementing negative playback rate?

Conversely, do we have interest from other browsers in converging on the proposal in the OP, of a RangeError? That seems safer as at least Firefox already throws an exception, so with Chrome we'll get two right off the bat.

@domenic domenic added interop Implementations are not interoperable with each other topic: media labels Jun 13, 2017
@jernoble
Copy link

This is an old, settled issue. See: https://lists.w3.org/Archives/Public/public-html/2011Feb/0113.html. Nothing has changed since this issue was originally brought up and dismissed.

@domenic
Copy link
Member

domenic commented Jun 13, 2017

What has changed is the introduction of an explicit requirement for multiple implementer interest in features in the standard; we've been removing many single-implementation features recently, and this likely is just one of them.

@jernoble
Copy link

@domenic

In the end this is a matter of implementation interest; we can't include features in the spec that only one browser implements.

It's not a feature of the spec, as @japacible pointed out. The page specifies a playbackRate, be it negative or not, and the UA tries to play at that rate as best as it is able, given software and hardware limitations. Negative playback on platforms which cannot do it is no different than >1x playback on platforms which cannot do that either. And the suggestion that this limitation is exposed was already suggested then discarded.

@jernoble
Copy link

@domenic

we've been removing many single-implementation features recently.

And this is not a feature. What you're suggesting is adding a feature, not removing one.

@domenic
Copy link
Member

domenic commented Jun 13, 2017

was already suggested then discarded.

To be clear, the fact that things were discussed once (or rather, a thread was sent and nobody replied) does not shut down further discussion on them. I'd appreciate if you stop trying to use such an argument.

What we have here is a clear interop problem, and interest from one browser in converging with another. We should document that convergence in the spec.

@jernoble
Copy link

@domenic

To be clear, the fact that things were discussed once (or rather, a thread was sent and nobody replied) does not shut down further discussion on them.

Actually, there's was a lot of discussion about that issue in the HTML working group. Perhaps you should look through the archives, and acquaint yourself with the arguments made at the time.

@jernoble
Copy link

jernoble commented Jun 13, 2017

Perhaps this issue is more appropriate to start out in the Interventions Spec https://github.com/WICG/interventions.

@domenic
Copy link
Member

domenic commented Jun 13, 2017

This doesn't appear to be an intervention (see the definition in that repo). This is a discussion of a normative change to the HTML specification to document the convergence of two browsers (possibly three, if Microsoft is interested in throwing, although their last message implies they would rather leave it as the old value) on what is currently a spec one browser is following.

@jernoble
Copy link

No, you're proposing on defining Safari's behavior as out-of-spec. The proposal isn't "throw an error when the UA is asked to play at a rate it doesn't support", but "throw an error when asked to play back at a negative rate".

@Zirro
Copy link
Contributor

Zirro commented Jun 13, 2017

With both Chrome and Edge currently playing -1 (and presumably other negative rates) as 1, there'd be more convergence between existing implementations if the spec were to define this as the behaviour instead of throwing when negative rates are not supported. In that case only Firefox would need to change. This leaves open the possibility for current and future implementations to support negative playback rates where it can be handled.

@mounirlamouri
Copy link
Member

The original intent was to reach compatibility here. Given that Firefox throws when playbackRate is set to a negative value, it sounds most likely that not that many websites use the feature without at least doing some checks. The Chrome videostack team expressed clear interest in not implementing this feature. Making this feature per-spec sounds like a lot of work for implementers. Allowing this feature to be not implemented is a tax on the web developers because they would have to do checks if they intend to rely on this feature.

In my opinion, we should decide what the behaviour should be based on whether we want the Web to support playing video backwards or not. Doing what Edge does would make sense if in the future we expect the Web to enable negative values. Rejecting would make sense otherwise. The reason why I think rejecting would make sense unless we intend to have broad support is that a lack of compatibility like this will lead to incompatibilities: websites tested only on Firefox or Chrome or Edge will assume playbackRate can't be negative, websites only tested on Safari will assume they can be negative and a minority will try to feature detect.

@Zirro
Copy link
Contributor

Zirro commented Jun 13, 2017

I suppose that if the ability to play videos backwards turns out to be desirable in the future, it could be implemented through a playbackDirection attribute, while playbackRate can remain as a positive-only indicator for playback speed regardless of the direction and throw on negative values as proposed.

@jernoble
Copy link

@mounirlamouri

Allowing this feature to be not implemented is a tax on the web developers because they would have to do checks if they intend to rely on this feature.

Indeed, which is why Chrome and Firefox should implement it. Here's an ugly javascript polyfill I whipped up: https://jsfiddle.net/ojxyqr9b/

Even without explicit video engine support, this example shows that it should be trivially easy to implement in any browser which does not currently support negative playback rates. Browsers which do support negative playback rates in their video engines will have better performance, but it doesn't require web developers to catch exceptions or (ick) UA sniff.

@cpearce
Copy link

cpearce commented Jun 14, 2017

Firefox has no interest in supporting negative playback rates at this time. We're not aware of any significant interest from web authors for negative playback rates. As a feature, it seems more of a gimmick, a usage pattern left over from the days of VCRs, rather than something which will have significant use in the modern web. We don't see a compelling use case for it.

This is an old, settled issue. See: https://lists.w3.org/Archives/Public/public-html/2011Feb/0113.html.

Having read this thread, it seems the group settled on not changing the spec at the time, and adding some mechanism to report the playback rate achieved in future in some sort of metrics API. I'm not aware of a way to report achieved playback rate being added to any metrics API or spec. Perhaps it got forgotten about?

So it seems the group resolved to take some action that was never taken?

@jernoble
Copy link

@cpearce

As a feature, it seems more of a gimmick, a usage pattern left over from the days of VCRs, rather than something which will have significant use in the modern web.

I disagree. We have seen very advanced uses of negative playback in video elements, e.g. where a video's (dynamic) playback rate was linked to page scroll speed. The <video> element has moved beyond it's "VCR playback" roots and is now a general purpose tool.

@cpearce
Copy link

cpearce commented Jun 14, 2017

@jernoble

I disagree. We have seen very advanced uses of negative playback in video elements, e.g. where a video's (dynamic) playback rate was linked to page scroll speed.

While that sounds like a very shiny demo, it doesn't actually sound very useful or compelling to me.

@jernoble
Copy link

@cpearce

While that sounds like a very shiny demo, it doesn't actually sound very useful or compelling to me.

Actually, this technique is used extensively on Apple.com product pages. And I've received direct feedback from our web developers complaining about lack of negative playback rate support in other browsers, and the lengths they have to go to work around that lack of support.

So, frankly, I put much more weight into what they think is compelling and useful than I put in your opinion.

@cpearce
Copy link

cpearce commented Jun 14, 2017

@jernoble Do you have a link to a page demonstrating this being used? I'd be keen to see what's possible with this.

It sounds like Apple are keen on this feature internally. Have you received feedback from external parties regarding this feature?

@jernoble
Copy link

@cpearce Sure, both the HomePod page and especially the iMac Pro page have <video> elements whose current time is linked to the scroll position. They simulate a negative playback rate by repeatedly seeking, due to a general lack of negative rate support. The iMac Pro page, specifically, has multiple video elements with synchronized timelines, composited together with CSS transforms to display the "cloud" video on the display of the iMac video. (This feature seems to be implemented for WebKit/Safari UAs only.)

@cpearce
Copy link

cpearce commented Jun 19, 2017

The use case demonstrated on the HomePod and iMac Pro web sites could be implemented by using two videos, one of which was (re)encoded backwards. You can then swap out which one is visible when going forwards/backwards. To do that glitch free, you might need to render the video to a canvas, and you'd need seeking to be accurate down to at least the level of video frames. Firefox's seek is accurate to the audio-frame level.

We'll probably not agree to either have Chrome and Firefox implement reverse playback, or have Safari remove it.

So we should agree on what to do when reverse playback is not implemented. I agree that throwing an exception or error of some kind is good, as it makes the failure obvious and explicit. I'd be fine to change our implementation to throw something mutually agreed upon.

@japacible
Copy link
Contributor Author

Thanks for everyone's thoughts.

+1 defining behavior if reverse playback is not implemented. We propose:

The user agent may support negative playback rate. If it does not, it should fire an exception with RangeError.

@domenic
Copy link
Member

domenic commented Jun 20, 2017

I'm not very comfortable with "may"s of that sort; per https://whatwg.org/working-mode#conflicts ,

Implementation disagreement should not result in implementation-defined behavior or optional features.

With my spec editor hat on, I'd rather that we have it always throw a RangeError in the standard.

Vendors are, of course, able to implement additional features beyond the multi-implementer-interest standard. Google certainly does all the time, often with counterpart specs in incubation or at least issues opened on the issue tracker.

But the HTML Standard itself should reflect the interoperable baseline with multi-implementer interest. The fact that historically it has had features without multi-implementer interest (sortable tables, context menus, MediaController, etc.) is a bug we are working to correct, and we should not perpetuate.

As such I'd propose that negative values throw a RangeError, but we can add a note such as:

NOTE: One implementation has implemented an additional feature of backward playback by allowing negative playback rates instead of throwing. This does not have multi-implementer interest, and thus not part of this standard; please track the corresponding proposal at [link to Apple's proposal].

@jernoble
Copy link

I don't support @domenic's proposal (obviously). I think we could standardize around language like "if a playback rate which is not supported by the UA, a RangeError is thrown." which would allow Firefox's current "throw if > 5x" behavior, allow Safari's current negative playback rate behavior, and allow future UAs to change their behavior without having to go through around of spec editing to do so.

@cpearce
Copy link

cpearce commented Jun 20, 2017

Firefox's behaviour is to throw if the playbackRate is negative, and clamp playbackRate into the range [0.25,5] if it's outside of that range.

It looks like Chromium clamps to playbackRate of their underlying player into the range [1/16, 16]:

https://cs.chromium.org/chromium/src/media/blink/webmediaplayer_impl.cc?l=662&rcl=a50819a86ab1ebb6c0c22b2f60c47119534c58a9
https://cs.chromium.org/chromium/src/media/blink/webmediaplayer_impl.cc?l=106&rcl=a50819a86ab1ebb6c0c22b2f60c47119534c58a9

(Though as noted above, Chromium does not report that player's playbackRate to JavaScript)

It would be good to have language in the spec to allow clamping if the direction of playback is supported, and throwing if the direction of playback is not supported. And the achieved playback rate should be specified to be set to the playbackRate attribute.

@jernoble
Copy link

@cpearce Oh, I assumed Firefox would want to throw an exception if it were asked to play at a rate it doesn't support. Isn't that the entire point? Right now you have the bizarre behavior of:

video.playbackRate = -1
[Exception... "Method not implemented"  nsresult: "0x80004001 (NS_ERROR_NOT_IMPLEMENTED)"  location: "JS frame :: debugger eval code :: <TOP_LEVEL> :: line 1"  data: no]
video.playbackRate = 5
5
video.playbackRate = 10
10
video.playbackRate
5

@japacible
Copy link
Contributor Author

japacible commented Jun 23, 2017

Thanks all-

It sounds like nobody wants to explicitly specify the valid playbackRange range. While it would be convenient to have this well scoped across browsers, this is a range that can easily vary across implementations. It doesn't seem practical to mandate everyone have the same capabilities. For example, it seems reasonable for a browser to only support 1x playback, or only support variable playback rates for certain media types, or similar.

That being said, we need to decide if negative playback is a feature or part of the range of values.

The Chrome folks discussed this a bit offline. After some consideration, we think it's OK to treat negatives as part of a range of values.

With this in mind, we'd change the error type to "NotSupportedError" DOMException. RangeError made sense when we were thinking of this as "negative numbers are outside the valid range", but now we're talking about a more general case of a playback rate not being supported.

So the concrete proposal is:

If playbackRate is set to a value not supported by the UA, a "NotSupportedError" DOMException is thrown.

This is essentially the same as what I mentioned upthread and @jernoble mentioned a few messages back. @domenic is OK with this from a spec editor perspective.

This would also require a change from Firefox for setting a playbackRate of 10, as @jernoble points out, from echoing back 5 to throwing. @cpearce, what do you think about this?

@cpearce
Copy link

cpearce commented Jun 27, 2017

@japacible Changing to throwing NotSupportedError when the playbackRate is outside of the range of rates we support is fine with us.

@domenic
Copy link
Member

domenic commented Jul 19, 2017

@japacible Congrats on your first contribution! To finish things out, can you file issues on all of the browsers for them to conform to this spec change, and link to them here? For example see #2753 (comment)

@jamesplease
Copy link

jamesplease commented Jun 8, 2018

I recognize that the primary purpose of this thread was about consistency when an invalid playback speed was given, but there were a few comments (from @cpearce mainly) about there being no real use cases for playing videos in reverse.

I wanted to pop in here to give an example of where it is useful: video editing. In Premiere there are 3 hotkeys that are crucial to shuttling: J, K, and L.

J - play the video in reverse. continually press it to increase the (negative) playback speed
K - pause
L - play the video in the forward direction. continued presses increase the (positive) playback speed

Users of Premiere are constantly using this system to navigate videos, and anyone who is making a video editor in the browser will likely want to reproduce this same workflow. For this reason, I think that negative playback rates are an important feature that browsers should consider adding.

It goes without saying that, as with other "pro" features, negative playback rates won't be used as broadly as "normal" usage of video (watching it at +x1 playback rates), but I think they serve a real use case.

(You can watch a tutorial showing shuttling in Premiere here)


Thanks for reading! And if you know of a better place for me to share this, do let me know. I understand it is a bit off topic, and I apologize for that.

@annevk
Copy link
Member

annevk commented Jun 9, 2018

@jamesplease it seems worth tracking in a new issue that investigates if we can require support somehow. The other thing that would help is filing issues against the browsers lacking support, probably cross-linking those with the issue against the HTML Standard, so we get input one way or another. And then if there's sufficient interest, tests and such would help and clarified language in the HTML Standard.

@knoajp
Copy link

knoajp commented Mar 16, 2019

I want negative values.

When you seek some scene in videos, if you can longpress arrow keys to set playbackRate +8 or -8, it's much more comfortable than multiple pressing arrow keys for rewinding/fowarding 5sec by 5sec.

(sorry for poor English)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interop Implementations are not interoperable with each other topic: media
Development

No branches or pull requests

9 participants