Skip to content

Commit 23fe481

Browse files
authored
Merge pull request #582 from apolunar/fix_m4a_mp4a_decode_seek
Fix m4a and mp4a playback
2 parents ee73f6d + eac5a32 commit 23fe481

File tree

5 files changed

+46
-5
lines changed

5 files changed

+46
-5
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ claxon = { version = "0.4.2", optional = true }
1515
hound = { version = "3.3.1", optional = true }
1616
lewton = { version = "0.10", optional = true }
1717
minimp3_fixed = { version = "0.5.4", optional = true}
18-
symphonia = { version = "0.5.2", optional = true, default-features = false }
18+
symphonia = { version = "0.5.4", optional = true, default-features = false, features = ["aac", "isomp4"] }
1919
crossbeam-channel = { version = "0.5.8", optional = true }
2020
thiserror = "1.0.49"
2121

assets/monkeys.mp4a

2.44 MB
Binary file not shown.

src/decoder/symphonia.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::time::Duration;
22
use symphonia::{
33
core::{
44
audio::{AudioBufferRef, SampleBuffer, SignalSpec},
5-
codecs::{Decoder, DecoderOptions},
5+
codecs::{Decoder, DecoderOptions, CODEC_TYPE_NULL},
66
errors::Error,
77
formats::{FormatOptions, FormatReader, SeekedTo},
88
io::MediaSourceStream,
@@ -76,8 +76,26 @@ impl SymphoniaDecoder {
7676
None => return Ok(None),
7777
};
7878

79+
// Select the first supported track
80+
let track_id = probed
81+
.format
82+
.tracks()
83+
.iter()
84+
.find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
85+
.ok_or(symphonia::core::errors::Error::Unsupported(
86+
"No track with supported codec",
87+
))?
88+
.id;
89+
90+
let track = probed
91+
.format
92+
.tracks()
93+
.iter()
94+
.find(|track| track.id == track_id)
95+
.unwrap();
96+
7997
let mut decoder = symphonia::default::get_codecs()
80-
.make(&stream.codec_params, &DecoderOptions { verify: true })?;
98+
.make(&track.codec_params, &DecoderOptions::default())?;
8199
let total_duration = stream
82100
.codec_params
83101
.time_base
@@ -86,7 +104,17 @@ impl SymphoniaDecoder {
86104

87105
let mut decode_errors: usize = 0;
88106
let decoded = loop {
89-
let current_frame = probed.format.next_packet()?;
107+
let current_frame = match probed.format.next_packet() {
108+
Ok(packet) => packet,
109+
Err(Error::IoError(_)) => break decoder.last_decoded(),
110+
Err(e) => return Err(e),
111+
};
112+
113+
// If the packet does not belong to the selected track, skip over it
114+
if current_frame.track_id() != track_id {
115+
continue;
116+
}
117+
90118
match decoder.decode(&current_frame) {
91119
Ok(decoded) => break decoded,
92120
Err(e) => match e {

tests/mp4a_test.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use std::io::BufReader;
2+
3+
#[test]
4+
fn test_mp4a_encodings() {
5+
// mp4a codec downloaded from YouTube
6+
// "Monkeys Spinning Monkeys"
7+
// Kevin MacLeod (incompetech.com)
8+
// Licensed under Creative Commons: By Attribution 3.0
9+
// http://creativecommons.org/licenses/by/3.0/
10+
let file = std::fs::File::open("assets/monkeys.mp4a").unwrap();
11+
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
12+
assert!(decoder.any(|x| x != 0)); // Assert not all zeros
13+
}

tests/seek.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rstest_reuse::{self, *};
2424
)]
2525
#[cfg_attr(feature = "symphonia-mp3", case("mp3", true, "symphonia"))]
2626
// note: disabled, broken decoder see issue: #577
27-
// #[cfg_attr(feature = "symphonia-isomp4", case("m4a", true, "symphonia"))]
27+
#[cfg_attr(feature = "symphonia-isomp4", case("m4a", true, "symphonia"))]
2828
#[cfg_attr(feature = "symphonia-wav", case("wav", true, "symphonia"))]
2929
#[cfg_attr(feature = "symphonia-flac", case("flac", true, "symphonia"))]
3030
fn all_decoders(

0 commit comments

Comments
 (0)