Closed Bug 1704115 Opened 1 year ago Closed 11 months ago

Firefox fails to play specific m4a (NS_ERROR_DOM_MEDIA_METADATA_ERR)

Categories

(Core :: Audio/Video: Playback, defect, P3)

Firefox 89
defect

Tracking

()

RESOLVED FIXED
93 Branch
Tracking Status
firefox93 --- fixed

People

(Reporter: thewalter, Assigned: padenot)

References

(Regressed 4 open bugs)

Details

Attachments

(4 files, 1 obsolete file)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0

Steps to reproduce:

Actual user agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0 (I'm using RFP)

Visit
https://sf16-ies-music-sg.tiktokcdn.com/obj/iesmusic-sg-local/v1/ies-msc/cb45995d1fa8a085b07c515268811bc0.m4a or https://sf16-ies-music-sg.tiktokcdn.com/obj/iesmusic-sg-local/v1/ies-msc/e5fa661a0044ca22f213d9d1be882104.m4a in a new tab

Actual results:

Audio decoding fails with NS_ERROR_DOM_MEDIA_METADATA_ERR (0x806e0006)

Expected results:

Audio plays as expected

I think it's reproducible on all tiktok audios served with the m4a extension. More: https://sf16-ies-music-sg.tiktokcdn.com/obj/tiktok-obj/9f6787885cdfc40318913f93018bf1f6.m4a or https://sf16-sg.tiktokcdn.com/obj/tiktok-obj/72b6fdaa83a957ffff50ff889a7bd2f0.m4a

These files are MPEG-4 audio, which should have the MIME type audio/mp4 per rfc4337. However, they're being served as audio/mpeg:

$ curl -IL "https://sf16-ies-music-sg.tiktokcdn.com/obj/iesmusic-sg-local/v1/ies-msc/cb45995d1fa8a085b07c515268811bc0.m4a"
HTTP/1.1 200 OK
Server: nginx
Content-Type: audio/mpeg

which is the MIME type for MPEG-1 and MPEG-2 layer I, II or III (in other words, .mp3 files) per rfc3003.

Are there any examples of files being served like this in the context of a tiktok page? It's possible that the MIME type would be different in context and this problem only occurs when using these URLs directly.

Unfortunately, the simple solution of adding audio/mpeg to the MIME types accepted in MP4Decoder.cpp breaks regular mp3 files, so if we end up supporting this, it will be more involved.

Flags: needinfo?(liamrengland)

The audios are served with the same (wrong) MIME type when listening on tiktok's site, but tiktok's player (I think it's a version of this library) handles the mismatch correctly. You can test on any of the below URLs on tiktok's website (you can play the audio by pressing play on the album cover).

https://www.tiktok.com/music/2-On-222500453429972992
https://www.tiktok.com/music/ReYup-feat-Spodee-6756092955003488257
https://www.tiktok.com/music/Programs-6704932932563240962

So, this is pretty low-priority, but a webcompat difference between Chrome and Firefox.

Flags: needinfo?(liamrengland)

*as in chrome can do it and firefox can't. The site works fine in both browsers.

Over the last 10 years, the expected behaviour changed drastically.

I was not really specified before 2014, but the behaviour we've been using for Firefox went from "only using the mimetype, refusing to play if (e.g.) application/octet-stream or no Content-Type header, or empty Content-Type header", (2011 and before) to "sniff, but only when served with no Content-Type header or application/octet-stream (2012 and after).

After long discussions it was specified to ignore the Content-Type header: https://github.com/whatwg/html/commit/2635145a67bda860a382abad1a7477510d1cc042#diff-41cf6794ba4200b839c53531555f0f3998df4cbb01a4d5cb0b94e3ca5e23947dL28557, and this still is the behaviour to adopt today.

Firefox is not implementing the standard here, and we should sniff in all cases, ignoring the type (except if X-Content-Type-Options: nosniff is specified I assume).

Severity: -- → S3
Priority: -- → P3

(In reply to Paul Adenot (:padenot) from comment #5)

Firefox is not implementing the standard here, and we should sniff in all cases, ignoring the type (except if X-Content-Type-Options: nosniff is specified I assume).

Anne, fyi. The patch is up, but I'm pretty sure I need to adjust quite a few tests I wrote for this 10 years ago, and probably add some.

Flags: needinfo?(annevk)

video and audio elements should always sniff, even when nosniff is present, I think. It would surprise me if Chrome implemented something different.

Navigating directly to a video or audio resource is different and there nosniff might have to be respected, though we've also run into some issues there with Chrome not respecting it as much as we did.

So I would recommend testing both of those contexts separately and comparing with Chrome/Safari. Happy to help diagnose weird results and things that need clarification in the standard (I know the nosniff stuff for navigations still isn't where it needs to be).

Flags: needinfo?(annevk)
Attached file sniff-testing.zip

Here is a testcase, with a server in node (node server-mimetype.js + open localhost:8888), a sample HTML page showing a bunch of test cases, and a sample mp4 file.

Here is a breakdown of the results. It's not that bad, but there are some inconsistencies. Direct refers to directly opening the URL in a tab, whereas element is loading it in a regular document in a <video> tag.

testcase \ browser Chrome Safari Firefox Nightly Firefox + 1704115
direct Plays Plays Plays Plays
direct + nosniff + no content-type Plays Download Download Plays
direct + nosniff + empty content-type Render as text Download Download Plays
direct + nosniff + correct content-type Plays Plays Plays Plays
direct + incorrect content-type Stall Plays Displays sad player icon Plays
direct + nosniff + incorrect content-type Plays Plays Displays sad player icon Displays sad player icon
element + wrong content-type Plays Plays Plays Plays
element + nosniff + no content-type Plays Plays Plays Plays
element + nosniff + empty content-type Plays Plays Plays Plays
element + nosniff + correct content-type Plays Plays Plays Plays
element + nosniff + incorrect content-type Plays Plays Plays Plays
element + nosniff + correct content-type Plays Plays Plays Plays
element + nosniff + incorrect content-type Plays Plays Plays Plays
direct + nosniff + bogus content-type Renders as text Downloads Downloads Plays
direct + bogus content-type Downloads Plays Plays Plays

We can fix the remaining "Sad player icon" if we want, but otherwise it's not bad I think?

Flags: needinfo?(annevk)
Assignee: nobody → padenot

You also want to try a bogus MIME type, e.g., Content-Type: bogus. That cannot be parsed and is usually treated differently (often similar to omitted).

I'm somewhat surprised "direct + nosniff + incorrect content-type" would still be different. Is that because something earlier in the stack is making a call about nosniff or some such?

With regards to the web-platform-tests changes: I'm a little unsure about them as Chrome and Firefox currently pass these tests. Which if anything indicates there's a problem with the specification.

(1704115 does seem like great progress, to be clear!)

Flags: needinfo?(annevk)

(In reply to Anne (:annevk) from comment #13)

You also want to try a bogus MIME type, e.g., Content-Type: bogus. That cannot be parsed and is usually treated differently (often similar to omitted).

Added at the end of the table above under the separation.

I'm somewhat surprised "direct + nosniff + incorrect content-type" would still be different. Is that because something earlier in the stack is making a call about nosniff or some such?

That would be my guess: the channel is created earlier in the lifetime of the element: at this time, it's not passing in the options Gecko uses to fetch a media file.

With regards to the web-platform-tests changes: I'm a little unsure about them as Chrome and Firefox currently pass these tests. Which if anything indicates there's a problem with the specification.

I'm not sure either, but I've posted my reasoning in the review. It seems to me that Chrome and certainly Firefox are wrong according to the current text.

Flags: needinfo?(annevk)

I suggest we file a follow-up bug on the nosniff case since I think we should just make that work as well. It's not like we honor nosniff for <video>, it doesn't help with security, and honoring it for <img> has caused us problems in the past.

I think you're correct that the specification says to essentially always sniff in order to determine the final MIME type, although I do wonder a bit about how well everyone is following those algorithms. They might need some more research.

Flags: needinfo?(annevk)
Attachment #9228331 - Attachment is obsolete: true
Attachment #9217133 - Attachment description: WIP: Bug 1704115 - Always sniff to determine the MIME type when attempting to play a media file. → Bug 1704115 - Always sniff to determine the MIME type when attempting to play a media file. r?edenchuang,#necko-reviewers
Pushed by padenot@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/bb4d0d4d1b1c
Always sniff to determine the MIME type when attempting to play a media file. r=necko-reviewers,valentin
https://hg.mozilla.org/integration/autoland/rev/9d94d1e411c9
Sniffed type for an ogg file is application/ogg, per spec. r=annevk
https://hg.mozilla.org/integration/autoland/rev/ffba9897b9eb
Update xpcshelltest because sniffing happens in more cases now. r=annevk
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/29943 for changes under testing/web-platform/tests
Status: UNCONFIRMED → RESOLVED
Closed: 11 months ago
Resolution: --- → FIXED
Target Milestone: --- → 93 Branch
Regressions: 1726534
Regressions: 1734606
Regressions: 1735014
See Also: → 1740736
Upstream PR merged by jgraham
Regressions: 1749294
Regressions: 1772738
You need to log in before you can comment on or make changes to this bug.