Files
fomo-reducer/src/render_data.rs

90 lines
2.2 KiB
Rust

use std::{convert::Infallible, fmt::Display};
use opendal::Operator;
use opus2::Application;
use time::{UtcDateTime, format_description::StaticFormatDescription, macros::format_description};
use twilight_model::id::{
Id,
marker::{ChannelMarker, GuildMarker},
};
#[derive(Debug, Clone)]
pub struct RenderManager {
operator: Operator,
}
impl RenderManager {
pub fn new(operator: Operator) -> Self {
Self { operator }
}
}
#[derive(Debug, Clone)]
pub struct Render {
pub start: UtcDateTime,
pub end: UtcDateTime,
pub guild_id: Id<GuildMarker>,
pub voice_channel_id: Id<ChannelMarker>,
}
const DATE_FORMAT: StaticFormatDescription =
format_description!("[year]-[month]-[day]T[hour]-[minute]-[second].[subsecond]Z");
impl Display for Render {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self {
start,
end,
guild_id,
voice_channel_id,
} = self;
let start = start.format(&DATE_FORMAT).unwrap();
let end = end.format(&DATE_FORMAT).unwrap();
write!(f, "{guild_id}/{voice_channel_id}/{start}_{end}.opus")
}
}
#[derive(Debug)]
pub struct RenderData {
pub channels: opus2::Channels,
pub sample_rate: u32,
pub samples: Vec<i16>,
}
impl RenderManager {
pub async fn write(
&self,
render: &Render,
RenderData {
channels,
sample_rate,
samples,
}: RenderData,
) -> Result<
(),
Infallible, // TODO: a real error type
> {
let mut encoder =
opus2::Encoder::new(sample_rate, channels, Application::Audio).expect("TODO");
const MAX_SIZE: usize = usize::MAX / 4;
let encode_result = encoder.encode_vec(&samples, MAX_SIZE);
if let Err(error) = &encode_result {
tracing::error!(?error);
} else {
tracing::info!("encode ok");
}
encode_result.expect("TODO");
let path = render.to_string();
let write_result = self.operator.write(&path, bytes).await;
tracing::info!(?write_result);
write_result.expect("TODO");
Ok(())
}
}