Skip to main content

mp4_atom/moov/trak/mdia/minf/stbl/stsd/
mp3.rs

1use crate::*;
2
3// See the QuickTime File Format Specification, "Sound Sample Description
4// Formats" (the `.mp3` / `kAudioFormatMPEGLayer3` format identifier).
5
6/// MPEG-1/2 Audio Layer III (MP3) sample entry, as used by QuickTime and
7/// other tools that store MP3 directly rather than wrapping it in `mp4a`/`esds`.
8#[derive(Debug, Clone, PartialEq, Eq)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct Mp3 {
11    pub audio: Audio,
12}
13
14impl Atom for Mp3 {
15    const KIND: FourCC = FourCC::new(b".mp3");
16
17    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
18        let audio = Audio::decode(buf)?;
19
20        while let Some(atom) = Any::decode_maybe(buf)? {
21            Self::decode_unknown(&atom)?;
22        }
23        skip_trailing_padding(buf);
24
25        Ok(Self { audio })
26    }
27
28    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
29        self.audio.encode(buf)?;
30        Ok(())
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    const ENCODED_MP3: &[u8] = &[
39        0x00, 0x00, 0x00, 0x24, 0x2e, 0x6d, 0x70, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00,
41        0x00, 0x00, 0xac, 0x44, 0x00, 0x00,
42    ];
43
44    #[test]
45    fn test_mp3_decode() {
46        let buf: &mut std::io::Cursor<&[u8]> = &mut std::io::Cursor::new(ENCODED_MP3);
47
48        let mp3 = Mp3::decode(buf).expect("failed to decode .mp3");
49
50        assert_eq!(
51            mp3,
52            Mp3 {
53                audio: Audio {
54                    data_reference_index: 1,
55                    channel_count: 2,
56                    sample_size: 16,
57                    sample_rate: 44100.into(),
58                }
59            }
60        );
61    }
62
63    #[test]
64    fn test_mp3_encode() {
65        let mp3 = Mp3 {
66            audio: Audio {
67                data_reference_index: 1,
68                channel_count: 2,
69                sample_size: 16,
70                sample_rate: 44100.into(),
71            },
72        };
73
74        let mut buf = Vec::new();
75        mp3.encode(&mut buf).unwrap();
76
77        assert_eq!(buf.as_slice(), ENCODED_MP3);
78    }
79}