Skip to main content

selene_core/media_container/
format.rs

1use std::{fs::File, io::Read};
2
3use serde::{Deserialize, Serialize};
4
5mod format_byte_checks;
6pub use format_byte_checks::*;
7
8/// All recognized audio containers
9#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize)]
10pub enum ContainerFormat {
11    Flac,
12    Mpa,
13    Ogg,
14    Wav,
15    Aiff,
16    Ape,
17}
18
19impl ContainerFormat {
20    /// Gets container type by reading magic bytes
21    ///
22    /// Returns none if the container type is unsupported or unrecognized, or cannot be read
23    pub fn from_file(handle: &mut File) -> Option<Self> {
24        let mut buf = [0_u8; 16];
25
26        handle.read_exact(&mut buf).ok()?;
27
28        let container = if is_flac(&buf) {
29            ContainerFormat::Flac
30        } else if is_ogg(&buf) {
31            ContainerFormat::Ogg
32        } else if is_mpa(&buf) {
33            ContainerFormat::Mpa
34        } else if is_wav(&buf) {
35            ContainerFormat::Wav
36        } else if is_aiff(&buf) {
37            ContainerFormat::Aiff
38        } else if is_ape(&buf) {
39            ContainerFormat::Ape
40        } else {
41            return None;
42        };
43        Some(container)
44    }
45
46    /// Returns the name as of the container that ffmpeg uses for encoding (the "`format_name`")
47    #[must_use]
48    pub fn format_name(&self) -> &str {
49        match self {
50            ContainerFormat::Aiff => "aiff",
51            ContainerFormat::Ape => "ape",
52            ContainerFormat::Flac => "flac",
53            ContainerFormat::Mpa => "mp3",
54            ContainerFormat::Ogg => "ogg",
55            ContainerFormat::Wav => "wav",
56        }
57    }
58}