mirror of
https://github.com/RustAudio/rodio
synced 2024-11-10 06:04:16 +00:00
possibly fixed m4a and mp4a playback
This commit is contained in:
parent
ee73f6d97d
commit
b712559418
5 changed files with 38 additions and 6 deletions
|
@ -15,7 +15,7 @@ claxon = { version = "0.4.2", optional = true }
|
||||||
hound = { version = "3.3.1", optional = true }
|
hound = { version = "3.3.1", optional = true }
|
||||||
lewton = { version = "0.10", optional = true }
|
lewton = { version = "0.10", optional = true }
|
||||||
minimp3_fixed = { version = "0.5.4", 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"] }
|
||||||
crossbeam-channel = { version = "0.5.8", optional = true }
|
crossbeam-channel = { version = "0.5.8", optional = true }
|
||||||
thiserror = "1.0.49"
|
thiserror = "1.0.49"
|
||||||
|
|
||||||
|
|
BIN
assets/monkeys.mp4a
Normal file
BIN
assets/monkeys.mp4a
Normal file
Binary file not shown.
|
@ -2,7 +2,7 @@ use std::time::Duration;
|
||||||
use symphonia::{
|
use symphonia::{
|
||||||
core::{
|
core::{
|
||||||
audio::{AudioBufferRef, SampleBuffer, SignalSpec},
|
audio::{AudioBufferRef, SampleBuffer, SignalSpec},
|
||||||
codecs::{Decoder, DecoderOptions},
|
codecs::{Decoder, DecoderOptions, CODEC_TYPE_NULL},
|
||||||
errors::Error,
|
errors::Error,
|
||||||
formats::{FormatOptions, FormatReader, SeekedTo},
|
formats::{FormatOptions, FormatReader, SeekedTo},
|
||||||
io::MediaSourceStream,
|
io::MediaSourceStream,
|
||||||
|
@ -76,8 +76,18 @@ impl SymphoniaDecoder {
|
||||||
None => return Ok(None),
|
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).unwrap().id;
|
||||||
|
|
||||||
|
let decode_opts =
|
||||||
|
DecoderOptions { verify: false, ..Default::default() };
|
||||||
|
|
||||||
|
let track = probed.format.tracks().iter().find(|track| track.id == track_id).unwrap();
|
||||||
|
|
||||||
let mut decoder = symphonia::default::get_codecs()
|
let mut decoder = symphonia::default::get_codecs()
|
||||||
.make(&stream.codec_params, &DecoderOptions { verify: true })?;
|
.make(&track.codec_params, &decode_opts)?;
|
||||||
let total_duration = stream
|
let total_duration = stream
|
||||||
.codec_params
|
.codec_params
|
||||||
.time_base
|
.time_base
|
||||||
|
@ -86,7 +96,16 @@ impl SymphoniaDecoder {
|
||||||
|
|
||||||
let mut decode_errors: usize = 0;
|
let mut decode_errors: usize = 0;
|
||||||
let decoded = loop {
|
let decoded = loop {
|
||||||
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
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the packet does not belong to the selected track, skip over it
|
||||||
|
if current_frame.track_id() != track_id {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
match decoder.decode(¤t_frame) {
|
match decoder.decode(¤t_frame) {
|
||||||
Ok(decoded) => break decoded,
|
Ok(decoded) => break decoded,
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
|
|
13
tests/mp4a_test.rs
Normal file
13
tests/mp4a_test.rs
Normal 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
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ use rstest_reuse::{self, *};
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "symphonia-mp3", case("mp3", true, "symphonia"))]
|
#[cfg_attr(feature = "symphonia-mp3", case("mp3", true, "symphonia"))]
|
||||||
// note: disabled, broken decoder see issue: #577
|
// 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-wav", case("wav", true, "symphonia"))]
|
||||||
#[cfg_attr(feature = "symphonia-flac", case("flac", true, "symphonia"))]
|
#[cfg_attr(feature = "symphonia-flac", case("flac", true, "symphonia"))]
|
||||||
fn all_decoders(
|
fn all_decoders(
|
||||||
|
@ -44,7 +44,7 @@ fn all_decoders(
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "symphonia-mp3", case("mp3", "symphonia"))]
|
#[cfg_attr(feature = "symphonia-mp3", case("mp3", "symphonia"))]
|
||||||
// note: disabled, broken decoder see issue: #577
|
// note: disabled, broken decoder see issue: #577
|
||||||
// #[cfg_attr(feature = "symphonia-isomp4", case("m4a", "symphonia"))]
|
#[cfg_attr(feature = "symphonia-isomp4", case("m4a", "symphonia"))]
|
||||||
#[cfg_attr(feature = "symphonia-wav", case("wav", "symphonia"))]
|
#[cfg_attr(feature = "symphonia-wav", case("wav", "symphonia"))]
|
||||||
#[cfg_attr(feature = "symphonia-flac", case("flac", "symphonia"))]
|
#[cfg_attr(feature = "symphonia-flac", case("flac", "symphonia"))]
|
||||||
fn supported_decoders(#[case] format: &'static str, #[case] decoder_name: &'static str) {}
|
fn supported_decoders(#[case] format: &'static str, #[case] decoder_name: &'static str) {}
|
||||||
|
|
Loading…
Reference in a new issue