-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Add FLAC support #4772
Add FLAC support #4772
Conversation
One thing I'm unsure of how to handle - I can't find a good source on what Everything seems to work correctly with a lowercase UPDATE After doing some research - figured I should provide a few notes on the CODECS parameter:
The codec name listed by the MPEG4 Registration Authority has to match the fourcc in the Sample Description box, so it seems like there's an unresolved issue. If the MPEG4-RA adopts "flac" as the fourcc, then the FLAC-in-MP4 spec will need to be updated, and tools that produce FLAC-in-MP4 files updated as well, and many existing files rendered obsolete. If instead the MPEG4-RA adopts "fLaC" as the fourcc, the existing specs and tools don't need an update, but browsers should add support for it in the This is spread out amongst a few issues: |
Update - the MP4 registration authority adopted I've opened bugs with Firefox and Chromium about the https://bugs.chromium.org/p/chromium/issues/detail?id=1350534 https://bugzilla.mozilla.org/show_bug.cgi?id=1783453 Safari works with |
FourCCs are always case sensitive
|
Correct. Sorry, I should clarify - Safari seems to handle the fourcc in a case-insensitive manner. This isn't correct behavior but it means it accepts "fLaC"
I opened bugs with Firefox and chromium for rejecting "fLaC".
…On August 5, 2022 6:40:14 PM EDT, Dimitri Podborski ***@***.***> wrote:
> Safari works with `fLaC`, it seems like it's case-insensitive.
FourCCs are always case sensitive `fLaC != flac`.
`fLaC = 0x664C6143` while lowercase would be `flac = 0x666C6163`. Applications should be updated and use registered fourCCs
--
Reply to this email directly or view it on GitHub:
#4772 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
@podborski sorry, didn't see the edit about filing a bug (and honestly didn't realize you probably meant with Safari until I checked your GitHub profile). Where do I file that? Even though it works it'd be good to get it registered and on Apple's radar. Also for non-safari products, I know the hls verification tools are looking for the string "FLAC" in multivariant playlists, which I think is incorrect. |
I already filed a radar yesterday. Thanks for checking :) |
Hi there! Just to be clear, what's the recommendation for the |
@toots I believe RFC 8216 and the latest draft for HTTP Live Streaming 2nd Edition have this to say for
RFC 6381, under "ISO Base Media File Format Name Space" states:
And the MP4 Registration Authority now lists |
Thanks! |
Hi @robwalch - I redid this change and pushed it up. Basically, this adds some logic for checking if the browser will use the MP4 Registration Authority's listed codecs ( This allows for manifest playlists to signal the FLAC codec using either I also did the same for Opus since it has basically the same issue - most browsers added Opus support and used the lowercase string The main difference in this attempt vs the previous is, I'm keeping the changes in the level controller more minimal. I'm not sure what should happen if say, Safari on an iPhone encounters a manifest with multiple codecs, since Safari isn't able to change the codec type on the fly. |
Hi @robwalch - new attempt pushed, rather than performing codec name changes in the worker, it's performed just before creating buffers / changing types / etc, using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more suggestions, and one issue with onBufferCodecs
. Thanks for this!
Hi @robwalch - I refactored a bit based on your feedback - So, since in buffer-controller it's possible for the And since it's possible for the codec string to be something like I believe using I wrote a small wrapper function around the original codec = codec.replace(AUDIO_CODEC_REGEXP, getCodecCompatibleName); as opposed to codec = codec.replace(AUDIO_CODEC_REGEXP, (m) => getCodecCompatibleName(m.toLowerCase() as "flac" | "opus")); One question, should the regular expression be more strict? It's doing a case-insensitive match, would it make sense to have it only match expected strings like Or alternatively, maybe getCodecCompatible name should be a wrapper around codec = getCodecCompatibleName(codec); and in the codecs utility: const AUDIO_CODEC_REGEXP = /flac|opus/gi;
export function getCodecCompatibleName(codec: string) : string {
return codec.replace(AUDIO_CODEC_REGEXP, (m) => getCodecCompatibleNameLower(m.toLowerCase() as LowerCaseCodecType));
} |
No. |
Hi @robwalch - I made |
This fixes test exceptions that did not fail their tests. One was an HlsParser instance that outlived the test run and failed after server disconnection. The other was an exception in AdManager that did not fail the test, but nonetheless caused an unexpected error to be logged. Both of these issues were spotted while running the tests in a local browser in debug mode. Neither caused test failures directly, but both were examples of poor hygiene in our tests.
This adds the MP4-registered codec entry "fLaC", as well as the non-registered codec entries "flac" and "FLAC". Browsers added FLAC support before the MP4 Registration Authority listed the codec entry "fLaC", and went with "flac". Bugs have been opened with browsers to address this, but in order to deal with legacy playlist manifests (they may list "flac" or even "FLAC"), this replaces any instance of "flac" and "opus" (any case) with the first compatible codec string.
Hey, I was testing out this branch and it was working great until Chrome (on Windows) pushed out an update this week. Now it just keeps failing with Hls.ErrorTypes.MEDIA_ERROR and reloading forever while trying to play a flac stream until it finally gives up. Might want to force Chrome to update and make sure it still works. It's possible the issue is Chrome getting more strict on CORS or something and it's on my end, but so far I've been unable to isolate the issue. Whatever happened is definitely associated with the Chrome update. Worked fine on a different system, then I updated Chrome (by going to Settings/About Chrome), and it failed. If you need a test case our stream is https://d3d4yli4hf5bmh.cloudfront.net/hls/live.m3u8 |
I got an email notification on this issue (but I don't see the comment here on GitHub for it?) that Chrome may have updated the logic for There's a bug report open on Chromium but they're probably going to have a hard time triaging it - it mentions HLS.js and doesn't provide a minimal viable example of the issue. I'll try to draft up an example that only uses the needed APIs to 1) verify that this is the case, and 2) demonstrate the discrepancy. |
Hello, yeah I have no idea where my comment went. 😕 This is definitely the case as I made a patch that forced the SourceBuffer to be created with the lowercase variants and it worked fine. Thank you for your help with the MVE, I'm not very well-versed with the MSE API. |
I created a small demo page that confirms the issue is around creating SourceBuffers with "fLaC" as the codecs string and updated the Chrome issue. My demo page is available at https://jprjr.github.io/chrome-issue-1422728/ - it demos trying to load FLAC and Opus using the different codec string names. I think the issue is Chrome is normalizing "fLaC" to "flac" internally, then is unable to find a matching SourceBuffer when trying to append? A quick work-around may be changing the order that codecs are probed, to use "flac" and "opus" first. This can be done by modifying Change to: const codecsToCheck = {
flac: ['flac', 'fLaC', 'FLAC'],
opus: ['opus', 'Opus'],
}[lowerCaseCodec]; I say "may" because I haven't actually tested it, this is just a suggestion as a temporary fix for anybody that needs this to work ASAP. I'm fairly confident that would work, though. The most correct thing is for Chrome to fix the issue, not to change the probe order. |
Thank you for digging into this! I can confirm that changing the probe order does work around the issue for now. |
Hi @jprjr , The FLAC support feature has not yet been merged into the hls.js master, and I am wondering how I can test this using some sample .flac URLs. Specifically, I need to play this format file in the Lightning video player plugin. I know how to play m3u8 URLs by attaching hls.js to the Lightning player. However, I am facing an issue where I am unable to import the source branch [jprjr:fmp4-flac] into the local repo package.json, which generally maintains all dependencies. I have tried running npm i, but it did not work. Moreover, I cannot find any demo player to insert the .flac URL and check this out. Can anyone help me with this issue? Thank you. |
@BlakeB415 Haven't seen any movement on the Chromium issue, it wouldn't surprise me if it's stuck in some kind of "waiting for more info from the bug reporter" state, it may be worth leaving a response confirming my comment is a correct summary of your issue. |
if ( | ||
audioCodec && | ||
audioCodec.indexOf('mp4a.40.5') !== -1 && | ||
ua.indexOf('android') !== -1 && | ||
audio.container !== 'audio/mpeg' | ||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need this MSE workaround don't we? Is there a better way to address this? (doesn't need to be in this PR, just curious, and would like to gather feedback and opinions here)
Co-authored-by: Rob Walch <robwalch@users.noreply.github.com>
Does anybody have a contact with the Chromium project? This bug hasn't had an update from the Chromium team since March 9 and it's still an issue in stable Chrome/Chromium. Try visiting this demo page - the media type is reported as supported but it doesn't actually work. One work-around is to change the probe order (see #4772 (comment)) to prefer the non-compliant |
This PR will...
Allow hls.js to demux and decode FLAC and Opus audio, regardless of whether the browser accepts the MP4-Registered codec entries (
fLaC
andOpus
, respectively), or if they use a fallback legacy codec entry (flac
,FLAC
, andopus
).Why is this Pull Request needed?
See https://developer.apple.com/documentation/http-live-streaming/hls-authoring-specification-for-apple-devices - which lists FLAC as a supported codec.
Opus is not listed for Apple devices, but adding Opus support is about the same as adding FLAC support.
Are there any points in the code the reviewer needs to double check?
In
stream-controller.ts
- this file contains fallback logic for browsers which aren't able to change the codec type (Safari on iPhone is the only browser with this issue, as far as I know). I'm unsure what should happen there, if anything.Resolves issues:
See #4387 - it works in the browsers I've tested that support FLAC and/or Opus (Firefox, Chrome, Safari).
Checklist