Merge pull request #582 from apolunar/fix_m4a_mp4a_decode_seek

Fix m4a and mp4a playback
This commit is contained in:
David Kleingeld 2024-06-06 23:40:04 +02:00 committed by GitHub
commit 23fe481fcb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 46 additions and 5 deletions

View file

@ -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"] }
crossbeam-channel = { version = "0.5.8", optional = true }
thiserror = "1.0.49"

BIN
assets/monkeys.mp4a Normal file

Binary file not shown.

View file

@ -2,7 +2,7 @@ use std::time::Duration;
use symphonia::{
core::{
audio::{AudioBufferRef, SampleBuffer, SignalSpec},
codecs::{Decoder, DecoderOptions},
codecs::{Decoder, DecoderOptions, CODEC_TYPE_NULL},
errors::Error,
formats::{FormatOptions, FormatReader, SeekedTo},
io::MediaSourceStream,
@ -76,8 +76,26 @@ impl SymphoniaDecoder {
None => return Ok(None),
};
// Select the first supported track
let track_id = probed
.format
.tracks()
.iter()
.find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
.ok_or(symphonia::core::errors::Error::Unsupported(
"No track with supported codec",
))?
.id;
let track = probed
.format
.tracks()
.iter()
.find(|track| track.id == track_id)
.unwrap();
let mut decoder = symphonia::default::get_codecs()
.make(&stream.codec_params, &DecoderOptions { verify: true })?;
.make(&track.codec_params, &DecoderOptions::default())?;
let total_duration = stream
.codec_params
.time_base
@ -86,7 +104,17 @@ impl SymphoniaDecoder {
let mut decode_errors: usize = 0;
let decoded = loop {
let current_frame = probed.format.next_packet()?;
let current_frame = match probed.format.next_packet() {
Ok(packet) => packet,
Err(Error::IoError(_)) => break decoder.last_decoded(),
Err(e) => return Err(e),
};
// If the packet does not belong to the selected track, skip over it
if current_frame.track_id() != track_id {
continue;
}
match decoder.decode(&current_frame) {
Ok(decoded) => break decoded,
Err(e) => match e {

13
tests/mp4a_test.rs Normal file
View file

@ -0,0 +1,13 @@
use std::io::BufReader;
#[test]
fn test_mp4a_encodings() {
// mp4a codec downloaded from YouTube
// "Monkeys Spinning Monkeys"
// Kevin MacLeod (incompetech.com)
// Licensed under Creative Commons: By Attribution 3.0
// http://creativecommons.org/licenses/by/3.0/
let file = std::fs::File::open("assets/monkeys.mp4a").unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
assert!(decoder.any(|x| x != 0)); // Assert not all zeros
}

View file

@ -24,7 +24,7 @@ use rstest_reuse::{self, *};
)]
#[cfg_attr(feature = "symphonia-mp3", case("mp3", true, "symphonia"))]
// note: disabled, broken decoder see issue: #577
// #[cfg_attr(feature = "symphonia-isomp4", case("m4a", true, "symphonia"))]
#[cfg_attr(feature = "symphonia-isomp4", case("m4a", true, "symphonia"))]
#[cfg_attr(feature = "symphonia-wav", case("wav", true, "symphonia"))]
#[cfg_attr(feature = "symphonia-flac", case("flac", true, "symphonia"))]
fn all_decoders(