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

Fix m4a and mp4a playback #582

Merged
merged 6 commits into from
Jun 6, 2024
Merged

Conversation

apolunar
Copy link

@apolunar apolunar commented Jun 1, 2024

Addresses issue #581 where all tests (including the new one) pass.

  1. It includes the necessary symphonia features
  2. Handles "end of stream" decoding errors
  3. Selects only tracks with supported codecs
  4. Adds test for m4pa file from YouTube (CC License)
    Let me know what revisions need to be made to get this merged.

@apolunar
Copy link
Author

apolunar commented Jun 1, 2024

Yikes, well it worked on my machine LOL
Edit: I did not in fact have the correct test command (should've been cargo test --features=symphonia-all --all-targets)
However, the new mp4a fix is successful, just not seeking on the RL.m4a, which is something I will fix later (for now maybe we can just disable the test again)

@dvdsk
Copy link
Collaborator

dvdsk commented Jun 1, 2024

just not seeking on the RL.m4a, which is something I will fix later (for now maybe we can just disable the test again)

I strongly suspect that's a bug in symphonia, see: #577. I haven't been able to work on bringing that to the attention of the symphonia folk yet unfortunatly.

Addresses issue #581 where all tests (including the new one) pass.

Thank you so much for adding a test 👍 that makes reviewing sooo much easier. I'm gonna take a detailed look tomorrow! At a quick glance it seems great though!

Cargo.toml Outdated
@@ -15,7 +15,7 @@ claxon = { version = "0.4.2", optional = true }
hound = { version = "3.3.1", optional = true }
lewton = { version = "0.10", optional = true }
minimp3_fixed = { version = "0.5.4", optional = true}
symphonia = { version = "0.5.2", optional = true, default-features = false }
symphonia = { version = "0.5.4", optional = true, default-features = false, features = ["all"] }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This increases compile time, is it needed to fix m4a? Might be better to adjust the features below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes we absolutely shouldn't enable all features by default

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this was a quick fix I forgot to actually investigate 😓

This increases compile time, is it needed to fix m4a? Might be better to adjust the features below.

I'm not really sure where to put them below, but it seems like you need features = ["aac", "isomp4"] for support

let current_frame = probed.format.next_packet()?;
let current_frame = match probed.format.next_packet() {
Ok(packet) => packet,
Err(_) => break decoder.last_decoded() // IoError end of stream is expected
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might make sense to match on the IoError explicitly and return all the other errors.

.iter()
.find(|t| t.codec_params.codec != CODEC_TYPE_NULL).unwrap().id;

let decode_opts = Default::default();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might make sense to inline this down below

let mut decoder = symphonia::default::get_codecs()
.make(&stream.codec_params, &DecoderOptions { verify: true })?;
.make(&track.codec_params, &decode_opts)?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this would be something like: .make(...., &DecoderOptions::default())?

@dvdsk
Copy link
Collaborator

dvdsk commented Jun 2, 2024

running cargo fmt should fix that last failing test

@dvdsk
Copy link
Collaborator

dvdsk commented Jun 2, 2024

Some nitpicks and a small mistake regarding the crate features otherwise looks great. With some tweaks we can get it merged!

@apolunar
Copy link
Author

apolunar commented Jun 2, 2024

Some nitpicks and a small mistake regarding the crate features otherwise looks great. With some tweaks we can get it merged!

Yippee! I think I covered everything, thanks for pointing that stuff out.

@apolunar apolunar closed this Jun 2, 2024
@apolunar apolunar reopened this Jun 2, 2024

let decode_opts = Default::default();
.find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
.unwrap()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This panics if there is not track with a valid codec or if there are no tracks at all. It would be better to return a DecodeError I think. Since a music player (one of the usecases of rodio) might very well run into bad files.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what error to return / where to put the error string, as I think it's bad practice to just put it in the file as I did in the most recent commit.

let mut decoder = symphonia::default::get_codecs()
.make(&track.codec_params, &decode_opts)?;
let mut decoder =
symphonia::default::get_codecs().make(&track.codec_params, &Default::default())?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another nitpick (feel free to ignore if you disagree). I personally find: Type::trait_fn clearer then Trait::trait_fn(). I think the former would be DecoderOpt::default() here.

@@ -97,7 +104,10 @@ impl SymphoniaDecoder {
let decoded = loop {
let current_frame = match probed.format.next_packet() {
Ok(packet) => packet,
Err(_) => break decoder.last_decoded() // IoError end of stream is expected
Err(e) => match e {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can inline this match so:
Err(Error::IoError(_)) => break etc etc,
Err(other) => return Err(other),

.format
.tracks()
.iter()
.find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
.unwrap()
.id;
{
Copy link
Collaborator

@dvdsk dvdsk Jun 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, thanks again for the investigation and fix!

One more tweak you could try (if you want to) is to replace the match with something using Option::ok_or, that would look something like this:

.find(...)
.ok_or(symphonia::core::errors::Error::Unsupported(...))?
.id;

But if you rather leave it thats fine too (let me know)! This code is better then most in rodio so we are good to merge it without any more changes :)

@apolunar
Copy link
Author

apolunar commented Jun 6, 2024

YIPPEE! Thanks for your help with this :D

@@ -15,7 +15,7 @@ claxon = { version = "0.4.2", optional = true }
hound = { version = "3.3.1", optional = true }
lewton = { version = "0.10", optional = true }
minimp3_fixed = { version = "0.5.4", optional = true}
symphonia = { version = "0.5.2", optional = true, default-features = false }
symphonia = { version = "0.5.4", optional = true, default-features = false, features = ["aac", "isomp4"] }
Copy link
Collaborator

@dvdsk dvdsk Jun 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, these should be gone too, my bad, no worries ill do it after the merge

Copy link
Collaborator

@dvdsk dvdsk Jun 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done see (a3ce660 and a3ce660)

@dvdsk dvdsk merged commit 23fe481 into RustAudio:master Jun 6, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants