1use serde::{Deserialize, Serialize};
2use symphonia::core::codecs::{
3 CODEC_TYPE_AAC, CODEC_TYPE_AC4, CODEC_TYPE_ADPCM_G722, CODEC_TYPE_ADPCM_G726,
4 CODEC_TYPE_ADPCM_G726LE, CODEC_TYPE_ADPCM_IMA_QT, CODEC_TYPE_ADPCM_IMA_WAV,
5 CODEC_TYPE_ADPCM_MS, CODEC_TYPE_ALAC, CODEC_TYPE_ATRAC1, CODEC_TYPE_ATRAC3,
6 CODEC_TYPE_ATRAC3PLUS, CODEC_TYPE_ATRAC9, CODEC_TYPE_DCA, CODEC_TYPE_EAC3, CODEC_TYPE_FLAC,
7 CODEC_TYPE_MONKEYS_AUDIO, CODEC_TYPE_MP1, CODEC_TYPE_MP2, CODEC_TYPE_MP3, CODEC_TYPE_MUSEPACK,
8 CODEC_TYPE_NULL, CODEC_TYPE_OPUS, CODEC_TYPE_PCM_ALAW, CODEC_TYPE_PCM_F32BE,
9 CODEC_TYPE_PCM_F32BE_PLANAR, CODEC_TYPE_PCM_F32LE, CODEC_TYPE_PCM_F32LE_PLANAR,
10 CODEC_TYPE_PCM_F64BE, CODEC_TYPE_PCM_F64BE_PLANAR, CODEC_TYPE_PCM_F64LE,
11 CODEC_TYPE_PCM_F64LE_PLANAR, CODEC_TYPE_PCM_MULAW, CODEC_TYPE_PCM_S8, CODEC_TYPE_PCM_S8_PLANAR,
12 CODEC_TYPE_PCM_S16BE, CODEC_TYPE_PCM_S16BE_PLANAR, CODEC_TYPE_PCM_S16LE,
13 CODEC_TYPE_PCM_S16LE_PLANAR, CODEC_TYPE_PCM_S24BE, CODEC_TYPE_PCM_S24BE_PLANAR,
14 CODEC_TYPE_PCM_S24LE, CODEC_TYPE_PCM_S24LE_PLANAR, CODEC_TYPE_PCM_S32BE,
15 CODEC_TYPE_PCM_S32BE_PLANAR, CODEC_TYPE_PCM_S32LE, CODEC_TYPE_PCM_S32LE_PLANAR,
16 CODEC_TYPE_PCM_U8, CODEC_TYPE_PCM_U8_PLANAR, CODEC_TYPE_PCM_U16BE, CODEC_TYPE_PCM_U16BE_PLANAR,
17 CODEC_TYPE_PCM_U16LE, CODEC_TYPE_PCM_U16LE_PLANAR, CODEC_TYPE_PCM_U24BE,
18 CODEC_TYPE_PCM_U24BE_PLANAR, CODEC_TYPE_PCM_U24LE, CODEC_TYPE_PCM_U24LE_PLANAR,
19 CODEC_TYPE_PCM_U32BE, CODEC_TYPE_PCM_U32BE_PLANAR, CODEC_TYPE_PCM_U32LE,
20 CODEC_TYPE_PCM_U32LE_PLANAR, CODEC_TYPE_SPEEX, CODEC_TYPE_TTA, CODEC_TYPE_VORBIS,
21 CODEC_TYPE_WAVPACK, CODEC_TYPE_WMA, CodecType,
22};
23
24use crate::errors::CodecError;
25
26#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
28pub enum Codec {
29 Aac,
30 Ac4,
31 AdpcmG722,
32 AdpcmG726,
33 AdpcmG726Le,
34 AdpcmImaQt,
35 AdpcmImaWav,
36 AdpcmMs,
37 Alac,
38 Atrac1,
39 Atrac3,
40 Atrac9,
41 Atrac3Plus,
42 Dca,
43 Eac3,
44 Flac,
45 MonkeysAudio,
46 Mp1,
47 Mp2,
48 Mp3,
49 Musepack,
50 Opus,
51 PcmAlaw,
52 PcmF32Be,
53 PcmF32BePlanar,
54 PcmF32Le,
55 PcmF32LePlanar,
56 PcmF64Be,
57 PcmF64BePlanar,
58 PcmF64Le,
59 PcmF64LePlanar,
60 PcmMulaw,
61 PcmS8,
62 PcmS8Planar,
63 PcmS16Be,
64 PcmS16BePlanar,
65 PcmS16Le,
66 PcmS16LePlanar,
67 PcmS24Be,
68 PcmS24BePlanar,
69 PcmS24Le,
70 PcmS24LePlanar,
71 PcmS32Be,
72 PcmS32BePlanar,
73 PcmS32Le,
74 PcmS32LePlanar,
75 PcmU8,
76 PcmU8Planar,
77 PcmU16Be,
78 PcmU16BePlanar,
79 PcmU16Le,
80 PcmU16LePlanar,
81 PcmU24Be,
82 PcmU24BePlanar,
83 PcmU24Le,
84 PcmU24LePlanar,
85 PcmU32Be,
86 PcmU32BePlanar,
87 PcmU32Le,
88 PcmU32LePlanar,
89 Speex,
90 Tta,
91 Vorbis,
92 WavPack,
93 Wma,
94}
95
96impl Codec {
97 #[must_use]
98 pub fn is_pcm(&self) -> bool {
99 matches!(
100 self,
101 Codec::PcmAlaw
102 | Codec::PcmF32Be
103 | Codec::PcmF32BePlanar
104 | Codec::PcmF32Le
105 | Codec::PcmF32LePlanar
106 | Codec::PcmF64Be
107 | Codec::PcmF64BePlanar
108 | Codec::PcmF64Le
109 | Codec::PcmF64LePlanar
110 | Codec::PcmMulaw
111 | Codec::PcmS8
112 | Codec::PcmS8Planar
113 | Codec::PcmS16Be
114 | Codec::PcmS16BePlanar
115 | Codec::PcmS16Le
116 | Codec::PcmS16LePlanar
117 | Codec::PcmS24Be
118 | Codec::PcmS24BePlanar
119 | Codec::PcmS24Le
120 | Codec::PcmS24LePlanar
121 | Codec::PcmS32Be
122 | Codec::PcmS32BePlanar
123 | Codec::PcmS32Le
124 | Codec::PcmS32LePlanar
125 | Codec::PcmU8
126 | Codec::PcmU8Planar
127 | Codec::PcmU16Be
128 | Codec::PcmU16BePlanar
129 | Codec::PcmU16Le
130 | Codec::PcmU16LePlanar
131 | Codec::PcmU24Be
132 | Codec::PcmU24BePlanar
133 | Codec::PcmU24Le
134 | Codec::PcmU24LePlanar
135 | Codec::PcmU32Be
136 | Codec::PcmU32BePlanar
137 | Codec::PcmU32Le
138 | Codec::PcmU32LePlanar
139 | Codec::Tta
140 | Codec::WavPack
141 )
142 }
143
144 #[must_use]
145 pub fn is_lossless(&self) -> bool {
146 matches!(
147 self,
148 Codec::Alac
149 | Codec::Flac
150 | Codec::MonkeysAudio
151 | Codec::PcmF32Be
152 | Codec::PcmF32BePlanar
153 | Codec::PcmF32Le
154 | Codec::PcmF32LePlanar
155 | Codec::PcmF64Be
156 | Codec::PcmF64BePlanar
157 | Codec::PcmF64Le
158 | Codec::PcmF64LePlanar
159 | Codec::PcmS8
160 | Codec::PcmS8Planar
161 | Codec::PcmS16Be
162 | Codec::PcmS16BePlanar
163 | Codec::PcmS16Le
164 | Codec::PcmS16LePlanar
165 | Codec::PcmS24Be
166 | Codec::PcmS24BePlanar
167 | Codec::PcmS24Le
168 | Codec::PcmS24LePlanar
169 | Codec::PcmS32Be
170 | Codec::PcmS32BePlanar
171 | Codec::PcmS32Le
172 | Codec::PcmS32LePlanar
173 | Codec::PcmU8
174 | Codec::PcmU8Planar
175 | Codec::PcmU16Be
176 | Codec::PcmU16BePlanar
177 | Codec::PcmU16Le
178 | Codec::PcmU16LePlanar
179 | Codec::PcmU24Be
180 | Codec::PcmU24BePlanar
181 | Codec::PcmU24Le
182 | Codec::PcmU24LePlanar
183 | Codec::PcmU32Be
184 | Codec::PcmU32BePlanar
185 | Codec::PcmU32Le
186 | Codec::PcmU32LePlanar
187 )
188 }
189
190 #[must_use]
191 pub fn is_flac(&self) -> bool {
192 matches!(self, Self::Flac)
193 }
194
195 #[must_use]
196 pub fn is_mp3(&self) -> bool {
197 matches!(self, Self::Mp3)
198 }
199
200 #[must_use]
201 pub fn is_opus(&self) -> bool {
202 matches!(self, Self::Opus)
203 }
204
205 #[must_use]
206 pub fn is_vorbis(&self) -> bool {
207 matches!(self, Self::Vorbis)
208 }
209
210 pub fn ffmpeg_encoder(&self) -> Result<&'static str, CodecError> {
211 let encoder = match self {
212 Codec::Aac => "aac",
213 Codec::Alac => "alac",
214 Codec::Eac3 => "eac3",
215 Codec::Flac => "flac",
216 Codec::Mp2 => "mp2",
217 Codec::Mp3 => "libmp3lame",
218 Codec::Opus => "libopus",
219 Codec::PcmAlaw => "pcm_alaw",
220 Codec::PcmMulaw => "pcm_mulaw",
221 Codec::PcmF32Be => "pcm_f32be",
222 Codec::PcmF32Le => "pcm_f32le",
223 Codec::PcmF64Be => "pcm_f64be",
224 Codec::PcmF64Le => "pcm_f64le",
225 Codec::PcmS8 => "pcm_s8",
226 Codec::PcmS16Be => "pcm_s16be",
227 Codec::PcmS16Le => "pcm_s16le",
228 Codec::PcmS24Be => "pcm_s24be",
229 Codec::PcmS24Le => "pcm_s24le",
230 Codec::PcmS32Be => "pcm_s32be",
231 Codec::PcmS32Le => "pcm_s32le",
232 Codec::PcmU8 => "pcm_u8",
233 Codec::PcmU16Be => "pcm_u16be",
234 Codec::PcmU16Le => "pcm_u16le",
235 Codec::PcmU24Be => "pcm_u24be",
236 Codec::PcmU24Le => "pcm_u24le",
237 Codec::PcmU32Be => "pcm_u32be",
238 Codec::PcmU32Le => "pcm_u32le",
239 Codec::Speex => "libspeex",
240 Codec::Tta => "tta",
241 Codec::Vorbis => "libvorbis",
242 Codec::WavPack => "wavpack",
243 Codec::Wma => "wmav2",
244 _ => return Err(CodecError::NoEncoder(*self)),
245 };
246 Ok(encoder)
247 }
248}
249
250impl TryFrom<CodecType> for Codec {
251 type Error = CodecError;
252
253 fn try_from(value: CodecType) -> Result<Codec, CodecError> {
254 let codec = match value {
255 CODEC_TYPE_AAC => Codec::Aac,
256 CODEC_TYPE_AC4 => Codec::Ac4,
257 CODEC_TYPE_ADPCM_G722 => Codec::AdpcmG722,
258 CODEC_TYPE_ADPCM_G726 => Codec::AdpcmG726,
259 CODEC_TYPE_ADPCM_G726LE => Codec::AdpcmG726Le,
260 CODEC_TYPE_ADPCM_IMA_QT => Codec::AdpcmImaQt,
261 CODEC_TYPE_ADPCM_IMA_WAV => Codec::AdpcmImaWav,
262 CODEC_TYPE_ADPCM_MS => Codec::AdpcmMs,
263 CODEC_TYPE_ALAC => Codec::Alac,
264 CODEC_TYPE_ATRAC1 => Codec::Atrac1,
265 CODEC_TYPE_ATRAC3 => Codec::Atrac3,
266 CODEC_TYPE_ATRAC9 => Codec::Atrac9,
267 CODEC_TYPE_ATRAC3PLUS => Codec::Atrac3Plus,
268 CODEC_TYPE_DCA => Codec::Dca,
269 CODEC_TYPE_EAC3 => Codec::Eac3,
270 CODEC_TYPE_FLAC => Codec::Flac,
271 CODEC_TYPE_MONKEYS_AUDIO => Codec::MonkeysAudio,
272 CODEC_TYPE_MP1 => Codec::Mp1,
273 CODEC_TYPE_MP2 => Codec::Mp2,
274 CODEC_TYPE_MP3 => Codec::Mp3,
275 CODEC_TYPE_MUSEPACK => Codec::Musepack,
276 CODEC_TYPE_OPUS => Codec::Opus,
277 CODEC_TYPE_PCM_ALAW => Codec::PcmAlaw,
278 CODEC_TYPE_PCM_F32BE => Codec::PcmF32Be,
279 CODEC_TYPE_PCM_F32BE_PLANAR => Codec::PcmF32BePlanar,
280 CODEC_TYPE_PCM_F32LE => Codec::PcmF32Le,
281 CODEC_TYPE_PCM_F32LE_PLANAR => Codec::PcmF32LePlanar,
282 CODEC_TYPE_PCM_F64BE => Codec::PcmF64Be,
283 CODEC_TYPE_PCM_F64BE_PLANAR => Codec::PcmF64BePlanar,
284 CODEC_TYPE_PCM_F64LE => Codec::PcmF64Le,
285 CODEC_TYPE_PCM_F64LE_PLANAR => Codec::PcmF64LePlanar,
286 CODEC_TYPE_PCM_MULAW => Codec::PcmMulaw,
287 CODEC_TYPE_PCM_S8 => Codec::PcmS8,
288 CODEC_TYPE_PCM_S8_PLANAR => Codec::PcmS8Planar,
289 CODEC_TYPE_PCM_S16BE => Codec::PcmS16Be,
290 CODEC_TYPE_PCM_S16BE_PLANAR => Codec::PcmS16BePlanar,
291 CODEC_TYPE_PCM_S16LE => Codec::PcmS16Le,
292 CODEC_TYPE_PCM_S16LE_PLANAR => Codec::PcmS16LePlanar,
293 CODEC_TYPE_PCM_S24BE => Codec::PcmS24Be,
294 CODEC_TYPE_PCM_S24BE_PLANAR => Codec::PcmS24BePlanar,
295 CODEC_TYPE_PCM_S24LE => Codec::PcmS24Le,
296 CODEC_TYPE_PCM_S24LE_PLANAR => Codec::PcmS24LePlanar,
297 CODEC_TYPE_PCM_S32BE => Codec::PcmS32Be,
298 CODEC_TYPE_PCM_S32BE_PLANAR => Codec::PcmS32BePlanar,
299 CODEC_TYPE_PCM_S32LE => Codec::PcmS32Le,
300 CODEC_TYPE_PCM_S32LE_PLANAR => Codec::PcmS32LePlanar,
301 CODEC_TYPE_PCM_U8 => Codec::PcmU8,
302 CODEC_TYPE_PCM_U8_PLANAR => Codec::PcmU8Planar,
303 CODEC_TYPE_PCM_U16BE => Codec::PcmU16Be,
304 CODEC_TYPE_PCM_U16BE_PLANAR => Codec::PcmU16BePlanar,
305 CODEC_TYPE_PCM_U16LE => Codec::PcmU16Le,
306 CODEC_TYPE_PCM_U16LE_PLANAR => Codec::PcmU16LePlanar,
307 CODEC_TYPE_PCM_U24BE => Codec::PcmU24Be,
308 CODEC_TYPE_PCM_U24BE_PLANAR => Codec::PcmU24BePlanar,
309 CODEC_TYPE_PCM_U24LE => Codec::PcmU24Le,
310 CODEC_TYPE_PCM_U24LE_PLANAR => Codec::PcmU24LePlanar,
311 CODEC_TYPE_PCM_U32BE => Codec::PcmU32Be,
312 CODEC_TYPE_PCM_U32BE_PLANAR => Codec::PcmU32BePlanar,
313 CODEC_TYPE_PCM_U32LE => Codec::PcmU32Le,
314 CODEC_TYPE_PCM_U32LE_PLANAR => Codec::PcmU32LePlanar,
315 CODEC_TYPE_SPEEX => Codec::Speex,
316 CODEC_TYPE_TTA => Codec::Tta,
317 CODEC_TYPE_VORBIS => Codec::Vorbis,
318 CODEC_TYPE_WAVPACK => Codec::WavPack,
319 CODEC_TYPE_WMA => Codec::Wma,
320 CODEC_TYPE_NULL => return Err(CodecError::NoDecoder),
321 other => return Err(CodecError::Unknown(other.to_string())),
322 };
323 Ok(codec)
324 }
325}