feat: implement rendering

This commit is contained in:
2026-05-28 01:48:52 -04:00
parent 862a333131
commit 24ef5a67c4
11 changed files with 225 additions and 71 deletions

View File

@@ -1,4 +1,19 @@
use std::{convert::Infallible, fmt::Display};
use opendal::Operator;
use opus2::Application;
use songbird::driver::SampleRate;
use time::{
UtcDateTime,
format_description::{self, StaticFormatDescription},
macros::format_description,
};
use twilight_model::id::{
Id,
marker::{ChannelMarker, GuildMarker},
};
use crate::{AudioChannels, AudioSampleRate};
#[derive(Debug, Clone)]
pub struct RenderManager {
@@ -10,3 +25,65 @@ impl RenderManager {
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 bytes = Vec::new();
let mut encoder =
opus2::Encoder::new(sample_rate, channels, Application::Audio).expect("TODO");
encoder.encode(&samples, &mut bytes).expect("TODO");
let path = render.to_string();
self.operator.write(&path, bytes).await.expect("TODO");
Ok(())
}
}