html icon indicating copy to clipboard operation
html copied to clipboard

MediaError not acccessible for a video element if using it with source elements

Open callumgare opened this issue 3 years ago • 10 comments

video elements are instances of HTMLMediaElement and thus have an error attribute which gives a MediaError if an error has occurred. This works fine if you're providing the source to a video element via the src attribute like so:

<video 
  autoplay
  controls
  src="http://example.com/does-not-exist"
></video>

But if you use a source element to provide the video url like so:

<video 
  autoplay
  controls
>
  <source src="http://example.com/does-not-exist">
</video>

Then the error attribute of the video element will return null event though an error has occurred. As far as I'm aware the source element does not provide any alternative way of accessing a MediaError object of the error. This means that if you use a source element instead of an src attribute it is not possible to differentiate between the different types of errors that a MediaError object provides details about.

I have created a CodePen to demonstrate this behavior.

This makes source elements feel like a bit of a second class citizen. I want to use source elements to offer multiple video formats but that should not come with the trade off of having worse error handling.

Thus I propose that the error attribute of a video element with child source elements should start returning a MediaError object when an error has occurred in the same way that a video element using the src attribute instead of child source elements does.

Thanks for considering :)

callumgare avatar Jan 20 '23 08:01 callumgare

I am pretty sure after skimming the relevant parts of the spec that the error property should be populated. So I think this is just a browser bug, that you should file on the browser bug trackers.

Or, did you find a part of the spec that distinguishes the source vs. src="" cases?

domenic avatar Jan 20 '23 08:01 domenic

did you find a part of the spec that distinguishes the source vs. src="" cases?

I didn't. Looking at the spec I couldn't specifically see anything that specifies that the error attribute should not be set when using source elements but to be honest I guess I just presumed that given that all major browser that I tested (Firefox, Chrome, Safari) behavior this way then the spec was being interpreted such that "technically" the error occurs with the source element or something so it's not the video element's responsibility to report an error.

But looking again that does seem a bit silly! The spec does state that video elements should populate the error attribute if an error occurred while running it's "resource selection algorithm":

All media elements have an associated error status, which records the last error the element encountered since its resource selection algorithm was last invoked. The error attribute, on getting, must return the MediaError object created for this last error, or null if there has not been an error.

- https://html.spec.whatwg.org/multipage/media.html#error-codes

And I guess it's still the video element that is considered to be running the "resource selection algorithm" even though the sources are defined in source elements since the spec on the resource selection algorithm definitely describes the algorithm used by the video element even when the source is defined with a source child element.

So I guess you're right! If you think this is a browser issue then feel free to close this and I'll open issues with the respective browsers :)

Screen Shot 2023-01-20 at 19 47 44

callumgare avatar Jan 20 '23 08:01 callumgare

Great! Let's close this, and feel free to point browser engineers here in the bugs you file. It's possible they'll spot something in the spec that we didn't, and then we can reopen...

domenic avatar Jan 20 '23 08:01 domenic

I have now opened up tickets with Firefox, Chrome and Safari (which doesn't using a public bug tracking system).

callumgare avatar Jan 23 '23 20:01 callumgare

@callumgare thanks for filing a bug, I'm currently having a look at fixing Firefox. Just a note that you can file issue for WebKit, that powers Safari, here: https://bugs.webkit.org/.

padenot avatar Jan 26 '23 09:01 padenot

Browsers are correctly following the spec AFAICS if they do not set the error attribute for MEDIA_ERR_SRC_NOT_SUPPORTED from source elements.

The dedicated media source failure steps set the error attribute if there is a failure when mode is object or attribute. Failure when mode is children does not run the dedicated media source failure steps, but fires an event named "error" at the source element.

All media elements have an associated error status, which records the last error the element encountered since its resource selection algorithm was last invoked. The error attribute, on getting, must return the MediaError object created for this last error, or null if there has not been an error. Arguably, however, an error on a source element child is not "encountered" by the media element.

If the error attribute were set for failure from one child, then that would cause play() to fail even if a subsequent source elements provided a resource: If the media element's error attribute is not null and its code is MEDIA_ERR_SRC_NOT_SUPPORTED, then return a promise rejected with a "NotSupportedError" DOMException.

I see the error attribute set to null only before the media element load algorithm invokes the resource selection algorithm.

karlt avatar Oct 09 '24 08:10 karlt

cc @whatwg/media

annevk avatar Oct 09 '24 08:10 annevk

If information about the source load failure were exposed on the media element then information would be limited to a single source. If the information is important, then it is presumably important for all sources that fail their load, and so would preferably be on the source element or on the "error" Events fired on those source elements.

karlt avatar Oct 09 '24 09:10 karlt

@karlt is correct.

An error attribute on HTMLSourceElement would be more consistent. Though source is also used for img where this kind of information is not exposed (and the error event is always fired on the img element), but it seems OK to leave error as null for images.

zcorpan avatar Oct 09 '24 09:10 zcorpan

To back up @karlt and @zcorpan, not firing an "error" event on HTMLMediaElement is intentional; you can always add another <source> child to the media element, and the resource selection algorithm will continue. .error is a sticky state; once the media element is in that state, it requires a call to .load() to get out of it, which would start the resource selection algorithm from scratch on the first <source> rather than the next <source>.

Currently, authors have to add a "error" listener to the last <source> to detect that none of the sources were playable: From html:

Example: If the author isn't sure if user agents will all be able to render the media resources provided, the author can listen to the error event on the last source element and trigger fallback behavior:

Perhaps we could make this easier by adding a new event and property to HTMLMediaElement to expose the Waiting: state of the resource selection algorithm to the author. But that event probably shouldn't be "error".

jernoble avatar Oct 09 '24 15:10 jernoble