Compare commits
2 Commits
d8d2526782
...
58212ce240
| Author | SHA1 | Date | |
|---|---|---|---|
| 58212ce240 | |||
| 1b88e6a11d |
154
Cargo.lock
generated
154
Cargo.lock
generated
@@ -433,6 +433,27 @@ version = "1.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.65.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"peeking_take_while",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash 1.1.0",
|
||||
"shlex",
|
||||
"syn 2.0.111",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
@@ -565,6 +586,16 @@ version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
||||
|
||||
[[package]]
|
||||
name = "bzip2-sys"
|
||||
version = "0.1.13+1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cacache"
|
||||
version = "13.1.0"
|
||||
@@ -662,6 +693,15 @@ dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
@@ -722,6 +762,17 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading 0.8.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.53"
|
||||
@@ -1698,6 +1749,7 @@ dependencies = [
|
||||
"clap",
|
||||
"dashmap 6.1.0",
|
||||
"futures",
|
||||
"hound",
|
||||
"opendal",
|
||||
"patricia_tree 0.10.1",
|
||||
"rhai",
|
||||
@@ -2152,7 +2204,7 @@ dependencies = [
|
||||
"hex",
|
||||
"hmac",
|
||||
"libc",
|
||||
"libloading",
|
||||
"libloading 0.9.0",
|
||||
"log",
|
||||
"md-5",
|
||||
"num-traits",
|
||||
@@ -2291,6 +2343,12 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hound"
|
||||
version = "3.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f"
|
||||
|
||||
[[package]]
|
||||
name = "hpke-rs"
|
||||
version = "0.6.1"
|
||||
@@ -2843,6 +2901,12 @@ dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "leb128fmt"
|
||||
version = "0.1.0"
|
||||
@@ -3071,6 +3135,16 @@ dependencies = [
|
||||
"rand 0.9.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.9.0"
|
||||
@@ -3109,6 +3183,20 @@ dependencies = [
|
||||
"redox_syscall 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "librocksdb-sys"
|
||||
version = "0.11.0+8.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"bzip2-sys",
|
||||
"cc",
|
||||
"glob",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.30.1"
|
||||
@@ -3119,6 +3207,17 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
@@ -3327,6 +3426,12 @@ dependencies = [
|
||||
"triomphe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
@@ -3477,6 +3582,16 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nonmax"
|
||||
version = "0.5.5"
|
||||
@@ -3647,6 +3762,7 @@ dependencies = [
|
||||
"opendal-service-postgresql",
|
||||
"opendal-service-redb",
|
||||
"opendal-service-redis",
|
||||
"opendal-service-rocksdb",
|
||||
"opendal-service-s3",
|
||||
"opendal-service-sled",
|
||||
"opendal-service-webdav",
|
||||
@@ -4127,6 +4243,16 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opendal-service-rocksdb"
|
||||
version = "0.55.0"
|
||||
source = "git+https://github.com/apache/opendal#3c2fedd4535a59652fb4d1ac5cce2f7911194585"
|
||||
dependencies = [
|
||||
"opendal-core",
|
||||
"rocksdb",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opendal-service-s3"
|
||||
version = "0.55.0"
|
||||
@@ -4394,6 +4520,12 @@ dependencies = [
|
||||
"hmac",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "pem"
|
||||
version = "3.0.6"
|
||||
@@ -4826,7 +4958,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls 0.23.35",
|
||||
"socket2 0.6.1",
|
||||
"thiserror 2.0.17",
|
||||
@@ -4846,7 +4978,7 @@ dependencies = [
|
||||
"lru-slab",
|
||||
"rand 0.9.2",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls 0.23.35",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
@@ -5333,6 +5465,16 @@ dependencies = [
|
||||
"portable-atomic-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocksdb"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"librocksdb-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roxmltree"
|
||||
version = "0.21.1"
|
||||
@@ -5385,6 +5527,12 @@ dependencies = [
|
||||
"ordered-multimap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
|
||||
@@ -10,6 +10,7 @@ capnp = "0.25.3"
|
||||
clap = { version = "4.5.40", features = ["derive", "env"] }
|
||||
dashmap = "6.1.0"
|
||||
futures = "0.3.32"
|
||||
hound = "3.5.1"
|
||||
opendal = { git = "https://github.com/apache/opendal", features = [
|
||||
"services-azfile",
|
||||
"services-aliyun-drive",
|
||||
@@ -43,6 +44,7 @@ opendal = { git = "https://github.com/apache/opendal", features = [
|
||||
"services-postgresql",
|
||||
"services-redb",
|
||||
"services-redis",
|
||||
"services-rocksdb",
|
||||
"services-s3",
|
||||
"services-sled",
|
||||
"services-webdav",
|
||||
|
||||
@@ -13,6 +13,7 @@ ARG PROTOC_VERSION=31.1-r1
|
||||
RUN --mount=type=cache,sharing=locked,target=/var/cache/apk \
|
||||
apk add --update protoc=${PROTOC_VERSION}
|
||||
|
||||
ENV CXXFLAGS="-include cstdint"
|
||||
RUN \
|
||||
# This one would be nice if it worked:
|
||||
# --mount=type=bind,source=.,target=/root/app \
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
use crate::{VCs, command::State};
|
||||
use crate::{OneToManyUniqueBTreeMap, VCs, command::State};
|
||||
use async_trait::async_trait;
|
||||
use hound::{SampleFormat, WavSpec};
|
||||
use opendal::Operator;
|
||||
use snafu::{OptionExt, Snafu};
|
||||
use songbird::{CoreEvent, Event, EventContext, EventHandler};
|
||||
use std::{sync::LazyLock, time::Instant};
|
||||
use std::{
|
||||
io::Cursor,
|
||||
sync::{Arc, LazyLock, Mutex},
|
||||
time::Instant,
|
||||
};
|
||||
use time::UtcDateTime;
|
||||
use twilight_model::{
|
||||
application::{
|
||||
@@ -13,7 +19,7 @@ use twilight_model::{
|
||||
http::interaction::{InteractionResponse, InteractionResponseType},
|
||||
id::{
|
||||
Id,
|
||||
marker::{ChannelMarker, GuildMarker},
|
||||
marker::{ChannelMarker, GuildMarker, UserMarker},
|
||||
},
|
||||
};
|
||||
use twilight_util::builder::{
|
||||
@@ -88,34 +94,105 @@ fn get_guild_and_vc_error_to_embed(error: GetGuildAndVoiceChannelIdError) -> Emb
|
||||
struct Handler {
|
||||
start_instant: Instant,
|
||||
start_utc: UtcDateTime,
|
||||
|
||||
recordings: Operator,
|
||||
|
||||
guild_id: Id<GuildMarker>,
|
||||
channel_id: Id<ChannelMarker>,
|
||||
vcs: Arc<VCs>,
|
||||
|
||||
known_ssrcs: Arc<Mutex<OneToManyUniqueBTreeMap<Id<UserMarker>, u32>>>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn act(&self, ctx: &EventContext<'_>) -> Option<Event> {
|
||||
tracing::error!(?ctx, "TODO");
|
||||
|
||||
let Some(core_event) = ctx.to_core_event() else {
|
||||
return None;
|
||||
};
|
||||
tracing::error!(?core_event, "TODO");
|
||||
|
||||
let elapsed = self.start_instant.elapsed();
|
||||
let elapsed = elapsed.try_into().expect("TODO");
|
||||
|
||||
let now_utc = self.start_utc.checked_add(elapsed).expect("TODO");
|
||||
tracing::error!(?now_utc, "TODO");
|
||||
|
||||
match core_event {
|
||||
CoreEvent::SpeakingStateUpdate => todo!(),
|
||||
CoreEvent::VoiceTick => todo!(),
|
||||
CoreEvent::RtpPacket => todo!(),
|
||||
CoreEvent::RtcpPacket => todo!(),
|
||||
CoreEvent::ClientDisconnect => todo!(),
|
||||
CoreEvent::DriverConnect => todo!(),
|
||||
CoreEvent::DriverReconnect => todo!(),
|
||||
CoreEvent::DriverDisconnect => todo!(),
|
||||
_ => todo!(),
|
||||
match ctx {
|
||||
EventContext::Track(_items) => {
|
||||
// Not expected to fire
|
||||
}
|
||||
EventContext::SpeakingStateUpdate(speaking) => {
|
||||
if let Some(user_id) = speaking.user_id {
|
||||
let user_id = Id::new(user_id.0);
|
||||
|
||||
self.known_ssrcs
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(user_id, speaking.ssrc);
|
||||
}
|
||||
}
|
||||
EventContext::VoiceTick(voice_tick) => {
|
||||
for (ssrc, voice_data) in &voice_tick.speaking {
|
||||
let user_id = self.known_ssrcs.lock().unwrap().get_left_for(ssrc).cloned();
|
||||
|
||||
if let Some(pcm) = &voice_data.decoded_voice {
|
||||
let year = now_utc.year();
|
||||
let month = now_utc.month();
|
||||
let day = now_utc.day();
|
||||
|
||||
let hour = now_utc.hour();
|
||||
let minute = now_utc.minute();
|
||||
let second = now_utc.second();
|
||||
|
||||
let microseconds = now_utc.microsecond();
|
||||
|
||||
let guild_id = self.guild_id;
|
||||
let channel_id = self.channel_id;
|
||||
|
||||
let user = user_id.map_or_else(|| "Unknown".into(), ToString::to_string);
|
||||
|
||||
let path = format!(
|
||||
"{year}/{month}/{day}/{hour}/{minute}/audio-{second}.{microseconds}-{guild_id}-{channel_id}-{user}.wav"
|
||||
);
|
||||
|
||||
let wav_spec = WavSpec {
|
||||
channels: 2,
|
||||
sample_rate: 48000,
|
||||
bits_per_sample: 16,
|
||||
sample_format: SampleFormat::Int,
|
||||
};
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
let writer = Cursor::new(&mut buffer);
|
||||
|
||||
let mut wav_writer = hound::WavWriter::new(writer, wav_spec).expect("TODO");
|
||||
|
||||
let mut sample_writer = wav_writer.get_i16_writer(pcm.len() as u32);
|
||||
|
||||
for sample in pcm {
|
||||
sample_writer.write_sample(*sample);
|
||||
}
|
||||
sample_writer.flush().expect("TODO");
|
||||
|
||||
wav_writer.finalize().expect("TODO");
|
||||
|
||||
tracing::info!("going to write the audio shortly");
|
||||
|
||||
let recordings = self.recordings.clone();
|
||||
tokio::spawn(async move {
|
||||
recordings.write(&path, buffer).await.expect("TODO");
|
||||
tracing::info!("successfully wrote the audio!");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
EventContext::RtpPacket(_rtp_data) => {}
|
||||
EventContext::RtcpPacket(_rtcp_data) => {}
|
||||
EventContext::ClientDisconnect(_client_disconnect) => {
|
||||
// This is already taken care of elsewhere
|
||||
}
|
||||
EventContext::DriverConnect(_connect_data) => {}
|
||||
EventContext::DriverReconnect(_connect_data) => {}
|
||||
EventContext::DriverDisconnect(_disconnect_data) => {}
|
||||
other => {
|
||||
tracing::warn!(?other, "cannot be handled yet");
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
@@ -180,10 +257,19 @@ pub async fn handle(state: State, interaction: Interaction) {
|
||||
let handler = Handler {
|
||||
start_instant,
|
||||
start_utc,
|
||||
recordings: state.recording_data,
|
||||
guild_id,
|
||||
channel_id: voice_channel_id,
|
||||
vcs,
|
||||
known_ssrcs: Default::default(),
|
||||
};
|
||||
call.lock()
|
||||
.await
|
||||
.add_global_event(CoreEvent::RtpPacket.into(), handler);
|
||||
|
||||
{
|
||||
let call = call.lock().await;
|
||||
|
||||
call.add_global_event(CoreEvent::SpeakingStateUpdate.into(), handler);
|
||||
call.add_global_event(CoreEvent::VoiceTick.into(), handler);
|
||||
}
|
||||
|
||||
let channel_mention = format!("<#{voice_channel_id}>");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user