skua_voice/input/sources/
file.rs1use crate::input::{AudioStream, AudioStreamError, Compose, Input};
2use std::{error::Error, ffi::OsStr, path::Path};
3use symphonia_core::{io::MediaSource, probe::Hint};
4
5#[derive(Clone, Debug)]
7pub struct File<P: AsRef<Path>> {
8 path: P,
9}
10
11impl<P: AsRef<Path>> File<P> {
12 pub fn new(path: P) -> Self {
16 Self { path }
17 }
18}
19
20impl<P: AsRef<Path> + Send + Sync + 'static> From<File<P>> for Input {
21 fn from(val: File<P>) -> Self {
22 Input::Lazy(Box::new(val))
23 }
24}
25
26#[async_trait::async_trait]
27impl<P: AsRef<Path> + Send + Sync> Compose for File<P> {
28 fn create(&mut self) -> Result<AudioStream<Box<dyn MediaSource>>, AudioStreamError> {
29 let err: Box<dyn Error + Send + Sync> =
30 "Files should be created asynchronously.".to_string().into();
31 Err(AudioStreamError::Fail(err))
32 }
33
34 async fn create_async(
35 &mut self,
36 ) -> Result<AudioStream<Box<dyn MediaSource>>, AudioStreamError> {
37 let file = tokio::fs::File::open(&self.path)
38 .await
39 .map_err(|io| AudioStreamError::Fail(Box::new(io)))?;
40
41 let input = Box::new(file.into_std().await);
42
43 let mut hint = Hint::default();
44 if let Some(ext) = self.path.as_ref().extension().and_then(OsStr::to_str) {
45 hint.with_extension(ext);
46 }
47
48 Ok(AudioStream {
49 input,
50 hint: Some(hint),
51 })
52 }
53
54 fn should_create_async(&self) -> bool {
55 true
56 }
57
58 }