Skip to content

Commit 25585f0

Browse files
committed
refactor: simplify MP4 format handling
Replace Mp4Type enum with MIME type string for MP4 format detection: - Remove Mp4Type enum and its FromStr/Display implementations - Update new_mp4() to use "audio/mp4" MIME type instead - Simplify documentation to reflect the change This change removes unnecessary complexity around MP4 format variants while maintaining the same functionality through MIME types. Fixes #612
1 parent 699483f commit 25585f0

File tree

3 files changed

+29
-56
lines changed

3 files changed

+29
-56
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4848
### Deprecated
4949
- Deprecated `Sample::zero_value()` function in favor of `Sample::ZERO_VALUE` constant
5050

51+
### Removed
52+
- Breaking: Removed `Mp4Type` enum in favor of using MIME type string "audio/mp4" for MP4 format detection with `Decoder::new_mp4`.
53+
5154
# Version 0.20.1 (2024-11-08)
5255

5356
### Fixed

src/decoder/mod.rs

Lines changed: 23 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
use std::fmt;
3232
#[allow(unused_imports)]
3333
use std::io::{Read, Seek, SeekFrom};
34-
use std::str::FromStr;
3534
use std::time::Duration;
3635
use std::{error::Error, marker::PhantomData};
3736

@@ -129,9 +128,12 @@ pub struct Settings {
129128
pub(crate) coarse_seek: bool,
130129
/// Whether to trim frames for gapless playback.
131130
pub(crate) gapless: bool,
132-
/// A hint or extension for the decoder about the format of the stream.
133-
/// When known, this can help the decoder to select the correct demuxer.
131+
/// An extension hint for the decoder about the format of the stream.
132+
/// When known, this can help the decoder to select the correct codec.
134133
pub(crate) hint: Option<String>,
134+
/// An MIME type hint for the decoder about the format of the stream.
135+
/// When known, this can help the decoder to select the correct demuxer.
136+
pub(crate) mime_type: Option<String>,
135137
/// Whether the decoder should report as seekable.
136138
pub(crate) is_seekable: bool,
137139
}
@@ -143,6 +145,7 @@ impl Default for Settings {
143145
coarse_seek: false,
144146
gapless: true,
145147
hint: None,
148+
mime_type: None,
146149
is_seekable: true,
147150
}
148151
}
@@ -252,13 +255,22 @@ impl<R: Read + Seek + Send + Sync + 'static> DecoderBuilder<R> {
252255

253256
/// Sets a format hint for the decoder.
254257
///
255-
/// When known, this can help the decoder to select the correct demuxer.
258+
/// When known, this can help the decoder to select the correct codec.
256259
/// Common values are "mp3", "wav", "flac", "ogg", etc.
257260
pub fn with_hint(mut self, hint: &str) -> Self {
258261
self.settings.hint = Some(hint.to_string());
259262
self
260263
}
261264

265+
/// Sets a mime type hint for the decoder.
266+
///
267+
/// When known, this can help the decoder to select the correct demuxer.
268+
/// Common values are "audio/mpeg", "audio/vnd.wav", "audio/flac", "audio/ogg", etc.
269+
pub fn with_mime_type(mut self, mime_type: &str) -> Self {
270+
self.settings.mime_type = Some(mime_type.to_string());
271+
self
272+
}
273+
262274
/// Configure whether the decoder should report as seekable.
263275
pub fn with_seekable(mut self, is_seekable: bool) -> Self {
264276
self.settings.is_seekable = is_seekable;
@@ -665,27 +677,27 @@ impl<R: Read + Seek + Send + Sync + 'static> Decoder<R> {
665677

666678
/// Builds a new decoder with MP4 container format hint.
667679
///
668-
/// This method provides a hint about the MP4 container type, which may help the decoder
669-
/// identify the format more quickly. However, if MP4 decoding fails, other formats
670-
/// will still be attempted.
680+
/// This method provides a hint that the data is in MP4 container format by setting
681+
/// the MIME type to "audio/mp4". This may help the decoder identify the format
682+
/// more quickly. However, if MP4 decoding fails, other formats will still be attempted.
671683
///
672684
/// # Errors
673685
///
674686
/// Returns `DecoderError::UnrecognizedFormat` if no suitable decoder was found.
675687
///
676688
/// # Examples
677689
/// ```no_run
678-
/// use rodio::{Decoder, Mp4Type};
690+
/// use rodio::Decoder;
679691
/// use std::fs::File;
680692
///
681693
/// let file = File::open("audio.m4a").unwrap();
682-
/// let decoder = Decoder::new_mp4(file, Mp4Type::M4a).unwrap();
694+
/// let decoder = Decoder::new_mp4(file).unwrap();
683695
/// ```
684696
#[cfg(feature = "symphonia-isomp4")]
685-
pub fn new_mp4(data: R, hint: Mp4Type) -> Result<Self, DecoderError> {
697+
pub fn new_mp4(data: R) -> Result<Self, DecoderError> {
686698
match Self::builder()
687699
.with_data(data)
688-
.with_hint(&hint.to_string())
700+
.with_mime_type("audio/mp4")
689701
.build()?
690702
{
691703
DecoderOutput::Normal(decoder) => Ok(decoder),
@@ -694,51 +706,6 @@ impl<R: Read + Seek + Send + Sync + 'static> Decoder<R> {
694706
}
695707
}
696708

697-
/// Type for specifying MP4 container format variants.
698-
#[allow(missing_docs)] // Reason: will be removed, see: #612
699-
#[derive(Debug)]
700-
pub enum Mp4Type {
701-
Mp4,
702-
M4a,
703-
M4p,
704-
M4b,
705-
M4r,
706-
M4v,
707-
Mov,
708-
}
709-
710-
impl FromStr for Mp4Type {
711-
type Err = String;
712-
713-
fn from_str(input: &str) -> Result<Mp4Type, Self::Err> {
714-
match &input.to_lowercase()[..] {
715-
"mp4" => Ok(Mp4Type::Mp4),
716-
"m4a" => Ok(Mp4Type::M4a),
717-
"m4p" => Ok(Mp4Type::M4p),
718-
"m4b" => Ok(Mp4Type::M4b),
719-
"m4r" => Ok(Mp4Type::M4r),
720-
"m4v" => Ok(Mp4Type::M4v),
721-
"mov" => Ok(Mp4Type::Mov),
722-
_ => Err(format!("{input} is not a valid mp4 extension")),
723-
}
724-
}
725-
}
726-
727-
impl fmt::Display for Mp4Type {
728-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
729-
let text = match self {
730-
Mp4Type::Mp4 => "mp4",
731-
Mp4Type::M4a => "m4a",
732-
Mp4Type::M4p => "m4p",
733-
Mp4Type::M4b => "m4b",
734-
Mp4Type::M4r => "m4r",
735-
Mp4Type::M4v => "m4v",
736-
Mp4Type::Mov => "mov",
737-
};
738-
write!(f, "{text}")
739-
}
740-
}
741-
742709
impl<R> Iterator for Decoder<R>
743710
where
744711
R: Read + Seek,

src/decoder/symphonia.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ impl SymphoniaDecoder {
6464
if let Some(ext) = settings.hint.as_ref() {
6565
hint.with_extension(ext);
6666
}
67+
if let Some(typ) = settings.mime_type.as_ref() {
68+
hint.mime_type(typ);
69+
}
6770
let format_opts: FormatOptions = FormatOptions {
6871
enable_gapless: settings.gapless,
6972
..Default::default()

0 commit comments

Comments
 (0)