falcon_library/audio/
ffmpeg.rs1use std::path::Path;
6
7use super::{AudioError, AudioSource, Block};
8
9pub struct FfmpegSource(falcon_ffmpeg::AudioFile);
11
12impl FfmpegSource {
13 pub fn open(path: &Path) -> Result<FfmpegSource, AudioError> {
15 if !falcon_ffmpeg::available() {
16 return Err(AudioError::UnsupportedCodec);
17 }
18 falcon_ffmpeg::AudioFile::open(path).map(FfmpegSource).map_err(|_| AudioError::UnsupportedCodec)
19 }
20}
21
22impl AudioSource for FfmpegSource {
23 fn channels(&self) -> u16 {
24 falcon_ffmpeg::AudioFile::CHANNELS
25 }
26
27 fn sample_rate(&self) -> u32 {
28 falcon_ffmpeg::AudioFile::RATE
29 }
30
31 fn duration(&self) -> Option<f64> {
32 Some(self.0.duration()).filter(|d| *d > 0.0)
33 }
34
35 fn next_block(&mut self) -> Option<Block<'_>> {
36 let samples = self.0.next_block()?;
37 Some(Block { samples, channels: falcon_ffmpeg::AudioFile::CHANNELS, rate: falcon_ffmpeg::AudioFile::RATE })
38 }
39
40 fn seek(&mut self, secs: f64) -> Result<f64, AudioError> {
41 let t = match self.duration() {
42 Some(d) => secs.clamp(0.0, d),
43 None => secs.max(0.0),
44 };
45 self.0.seek(t).map_err(|e| AudioError::Seek(e.0))?;
46 Ok(t)
47 }
48
49 fn position(&self) -> f64 {
50 self.0.position()
51 }
52
53 fn backend(&self) -> &'static str {
54 "ffmpeg"
55 }
56}