Remove unused stuff from ts demo
Signed-off-by: Aron Heinecke <aron.heinecke@t-online.de>
This commit is contained in:
parent
4cbcd275e8
commit
92ec89e7f5
6 changed files with 8 additions and 226 deletions
30
Cargo.lock
generated
30
Cargo.lock
generated
|
@ -1955,29 +1955,6 @@ dependencies = [
|
||||||
"untrusted",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sdl2"
|
|
||||||
version = "0.34.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "deecbc3fa9460acff5a1e563e05cb5f31bba0aa0c214bb49a43db8159176d54b"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 1.2.1",
|
|
||||||
"lazy_static",
|
|
||||||
"libc",
|
|
||||||
"sdl2-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sdl2-sys"
|
|
||||||
version = "0.34.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41a29aa21f175b5a41a6e26da572d5e5d1ee5660d35f9f9d0913e8a802098f74"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
"libc",
|
|
||||||
"version-compare",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
@ -3163,12 +3140,6 @@ version = "0.2.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cbdbff6266a24120518560b5dc983096efb98462e51d0d68169895b237be3e5d"
|
checksum = "cbdbff6266a24120518560b5dc983096efb98462e51d0d68169895b237be3e5d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version-compare"
|
|
||||||
version = "0.0.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
|
@ -3183,7 +3154,6 @@ dependencies = [
|
||||||
"audiopus",
|
"audiopus",
|
||||||
"byte-slice-cast",
|
"byte-slice-cast",
|
||||||
"futures",
|
"futures",
|
||||||
"sdl2",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serenity",
|
"serenity",
|
||||||
"slog",
|
"slog",
|
||||||
|
|
|
@ -20,7 +20,6 @@ tracing-futures = "0.2"
|
||||||
|
|
||||||
### TS stuff
|
### TS stuff
|
||||||
audiopus = "0.2"
|
audiopus = "0.2"
|
||||||
sdl2 = "0.34"
|
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
# we use the ts slog stuff for the code copied
|
# we use the ts slog stuff for the code copied
|
||||||
slog = "2"
|
slog = "2"
|
||||||
|
|
|
@ -1,27 +1,18 @@
|
||||||
use std::{env, sync::Arc, time::Duration};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use tsclientlib::{ClientId, Connection, DisconnectOptions, Identity, StreamItem};
|
|
||||||
use tsproto_packets::packets::{AudioData, CodecType, Direction, OutAudio, OutPacket};
|
|
||||||
use audiopus::coder::Encoder;
|
|
||||||
use futures::prelude::*;
|
|
||||||
use sdl2::audio::{AudioCallback, AudioDevice, AudioSpec, AudioSpecDesired, AudioStatus};
|
|
||||||
use sdl2::AudioSubsystem;
|
|
||||||
use serenity::prelude::Mentionable;
|
use serenity::prelude::Mentionable;
|
||||||
|
|
||||||
// This trait adds the `register_songbird` and `register_songbird_with` methods
|
// This trait adds the `register_songbird` and `register_songbird_with` methods
|
||||||
// to the client builder below, making it easy to install this voice client.
|
// to the client builder below, making it easy to install this voice client.
|
||||||
// The voice client can be retrieved in any command using `songbird::get(ctx).await`.
|
// The voice client can be retrieved in any command using `songbird::get(ctx).await`.
|
||||||
use songbird::{SerenityInit, input::Input};
|
use songbird::input::Input;
|
||||||
|
|
||||||
// Import the `Context` to handle commands.
|
// Import the `Context` to handle commands.
|
||||||
use serenity::client::Context;
|
use serenity::client::Context;
|
||||||
|
|
||||||
use serenity::{
|
use serenity::{
|
||||||
async_trait,
|
async_trait,
|
||||||
client::{Client, EventHandler},
|
client::{EventHandler},
|
||||||
framework::{
|
framework::{
|
||||||
StandardFramework,
|
|
||||||
standard::{
|
standard::{
|
||||||
Args, CommandResult,
|
Args, CommandResult,
|
||||||
macros::{command, group},
|
macros::{command, group},
|
||||||
|
@ -31,13 +22,11 @@ use serenity::{
|
||||||
Result as SerenityResult,
|
Result as SerenityResult,
|
||||||
};
|
};
|
||||||
use songbird::{
|
use songbird::{
|
||||||
driver::{Config as DriverConfig, DecodeMode},
|
|
||||||
model::payload::{ClientConnect, ClientDisconnect, Speaking},
|
model::payload::{ClientConnect, ClientDisconnect, Speaking},
|
||||||
CoreEvent,
|
CoreEvent,
|
||||||
Event,
|
Event,
|
||||||
EventContext,
|
EventContext,
|
||||||
EventHandler as VoiceEventHandler,
|
EventHandler as VoiceEventHandler,
|
||||||
Songbird,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::ListenerHolder;
|
use crate::ListenerHolder;
|
||||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -1,18 +1,15 @@
|
||||||
use std::{collections::HashMap, io::{Read, copy}, mem::size_of, sync::Arc, time::Duration};
|
use std::{collections::HashMap, io::Read, mem::size_of, sync::Arc, time::Duration};
|
||||||
use byte_slice_cast::{AsByteSlice, AsMutByteSlice};
|
use byte_slice_cast::AsByteSlice;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tsclientlib::{ClientId, Connection, DisconnectOptions, Identity, StreamItem, audio::AudioHandler};
|
use tsclientlib::{ClientId, Connection, DisconnectOptions, Identity, StreamItem};
|
||||||
use tsproto_packets::packets::{AudioData, CodecType, OutAudio, OutPacket};
|
use tsproto_packets::packets::{AudioData, CodecType, OutAudio, OutPacket};
|
||||||
use audiopus::coder::Encoder;
|
use audiopus::coder::Encoder;
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use slog::{debug, o, Drain, Logger};
|
use slog::{debug, o, Drain, Logger};
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
use tokio::task::LocalSet;
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
|
|
||||||
|
|
||||||
mod ts_voice;
|
|
||||||
mod discord;
|
mod discord;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||||
|
@ -21,24 +18,17 @@ struct ConnectionId(u64);
|
||||||
// This trait adds the `register_songbird` and `register_songbird_with` methods
|
// This trait adds the `register_songbird` and `register_songbird_with` methods
|
||||||
// to the client builder below, making it easy to install this voice client.
|
// to the client builder below, making it easy to install this voice client.
|
||||||
// The voice client can be retrieved in any command using `songbird::get(ctx).await`.
|
// The voice client can be retrieved in any command using `songbird::get(ctx).await`.
|
||||||
use songbird::{SerenityInit, Songbird, input::Input};
|
use songbird::{SerenityInit, Songbird};
|
||||||
use songbird::driver::{Config as DriverConfig, DecodeMode};
|
use songbird::driver::{Config as DriverConfig, DecodeMode};
|
||||||
|
|
||||||
// Import the `Context` to handle commands.
|
// Import the `Context` to handle commands.
|
||||||
use serenity::{client::Context, prelude::{RwLock, TypeMapKey}};
|
use serenity::{prelude::{TypeMapKey}};
|
||||||
|
|
||||||
use serenity::{
|
use serenity::{
|
||||||
async_trait,
|
client::{Client},
|
||||||
client::{Client, EventHandler},
|
|
||||||
framework::{
|
framework::{
|
||||||
StandardFramework,
|
StandardFramework,
|
||||||
standard::{
|
|
||||||
Args, CommandResult,
|
|
||||||
macros::{command, group},
|
|
||||||
},
|
},
|
||||||
},
|
|
||||||
model::{channel::Message, gateway::Ready},
|
|
||||||
Result as SerenityResult,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use slog::Logger;
|
|
||||||
use tokio::task::LocalSet;
|
|
||||||
|
|
||||||
|
|
||||||
use ts_to_audio::TsToAudio;
|
|
||||||
|
|
||||||
// Example from tsclientlib, to be removed later on
|
|
||||||
|
|
||||||
pub mod ts_to_audio;
|
|
||||||
|
|
||||||
/// The usual frame size.
|
|
||||||
///
|
|
||||||
/// Use 48 kHz, 20 ms frames (50 per second) and mono data (1 channel).
|
|
||||||
/// This means 1920 samples and 7.5 kiB.
|
|
||||||
const USUAL_FRAME_SIZE: usize = 48000 / 50;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct AudioData {
|
|
||||||
pub ts2a: Arc<Mutex<TsToAudio>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn start(logger: Logger, local_set: &LocalSet) -> Result<AudioData> {
|
|
||||||
let sdl_context = sdl2::init().unwrap();
|
|
||||||
|
|
||||||
let audio_subsystem = sdl_context.audio().unwrap();
|
|
||||||
// SDL automatically disables the screensaver, enable it again
|
|
||||||
if let Ok(video_subsystem) = sdl_context.video() {
|
|
||||||
video_subsystem.enable_screen_saver();
|
|
||||||
}
|
|
||||||
|
|
||||||
let ts2a = TsToAudio::new(logger.clone(), audio_subsystem.clone(), local_set)?;
|
|
||||||
|
|
||||||
|
|
||||||
Ok(AudioData { ts2a })
|
|
||||||
}
|
|
|
@ -1,126 +0,0 @@
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
use anyhow::{format_err, Result};
|
|
||||||
use futures::prelude::*;
|
|
||||||
use sdl2::audio::{AudioCallback, AudioDevice, AudioSpecDesired, AudioStatus};
|
|
||||||
use sdl2::AudioSubsystem;
|
|
||||||
use slog::{debug, error, o, Logger};
|
|
||||||
use tokio::task::LocalSet;
|
|
||||||
use tokio::time::{self, Duration};
|
|
||||||
use tokio_stream::wrappers::IntervalStream;
|
|
||||||
use tsclientlib::ClientId;
|
|
||||||
use tsproto_packets::packets::InAudioBuf;
|
|
||||||
|
|
||||||
// Example from tsclientlib, to be removed later on
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
use crate::ConnectionId;
|
|
||||||
|
|
||||||
type Id = (ConnectionId, ClientId);
|
|
||||||
type AudioHandler = tsclientlib::audio::AudioHandler<Id>;
|
|
||||||
|
|
||||||
pub struct TsToAudio {
|
|
||||||
logger: Logger,
|
|
||||||
audio_subsystem: AudioSubsystem,
|
|
||||||
device: AudioDevice<SdlCallback>,
|
|
||||||
data: Arc<Mutex<AudioHandler>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SdlCallback {
|
|
||||||
data: Arc<Mutex<AudioHandler>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TsToAudio {
|
|
||||||
pub fn new(
|
|
||||||
logger: Logger, audio_subsystem: AudioSubsystem, local_set: &LocalSet,
|
|
||||||
) -> Result<Arc<Mutex<Self>>> {
|
|
||||||
let logger = logger.new(o!("pipeline" => "ts-to-audio"));
|
|
||||||
let data = Arc::new(Mutex::new(AudioHandler::new(logger.clone())));
|
|
||||||
|
|
||||||
let device = Self::open_playback(logger.clone(), &audio_subsystem, data.clone())?;
|
|
||||||
|
|
||||||
let res = Arc::new(Mutex::new(Self { logger, audio_subsystem, device, data }));
|
|
||||||
|
|
||||||
Self::start(res.clone(), local_set);
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_playback(
|
|
||||||
logger: Logger, audio_subsystem: &AudioSubsystem, data: Arc<Mutex<AudioHandler>>,
|
|
||||||
) -> Result<AudioDevice<SdlCallback>> {
|
|
||||||
let desired_spec = AudioSpecDesired {
|
|
||||||
freq: Some(48000),
|
|
||||||
channels: Some(2),
|
|
||||||
samples: Some(USUAL_FRAME_SIZE as u16),
|
|
||||||
};
|
|
||||||
|
|
||||||
audio_subsystem.open_playback(None, &desired_spec, move |spec| {
|
|
||||||
// This spec will always be the desired spec, the sdl wrapper passes
|
|
||||||
// zero as `allowed_changes`.
|
|
||||||
debug!(logger, "Got playback spec"; "spec" => ?spec, "driver" => audio_subsystem.current_audio_driver());
|
|
||||||
SdlCallback {
|
|
||||||
data,
|
|
||||||
}
|
|
||||||
}).map_err(|e| format_err!("SDL error: {}", e))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start(t2a: Arc<Mutex<Self>>, local_set: &LocalSet) {
|
|
||||||
local_set.spawn_local(
|
|
||||||
IntervalStream::new(time::interval(Duration::from_secs(1))).for_each(move |_| {
|
|
||||||
let mut t2a = t2a.lock().unwrap();
|
|
||||||
|
|
||||||
if t2a.device.status() == AudioStatus::Stopped {
|
|
||||||
// Try to reconnect to audio
|
|
||||||
match Self::open_playback(
|
|
||||||
t2a.logger.clone(),
|
|
||||||
&t2a.audio_subsystem,
|
|
||||||
t2a.data.clone(),
|
|
||||||
) {
|
|
||||||
Ok(d) => {
|
|
||||||
t2a.device = d;
|
|
||||||
debug!(t2a.logger, "Reconnected to playback device");
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!(t2a.logger, "Failed to open playback device"; "error" => %e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let data_empty = t2a.data.lock().unwrap().get_queues().is_empty();
|
|
||||||
if t2a.device.status() == AudioStatus::Paused && !data_empty {
|
|
||||||
debug!(t2a.logger, "Resuming playback");
|
|
||||||
t2a.device.resume();
|
|
||||||
} else if t2a.device.status() == AudioStatus::Playing && data_empty {
|
|
||||||
debug!(t2a.logger, "Pausing playback");
|
|
||||||
t2a.device.pause();
|
|
||||||
}
|
|
||||||
future::ready(())
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn play_packet(&mut self, id: Id, packet: InAudioBuf) -> Result<()> {
|
|
||||||
let mut data = self.data.lock().unwrap();
|
|
||||||
data.handle_packet(id, packet)?;
|
|
||||||
|
|
||||||
if self.device.status() == AudioStatus::Paused {
|
|
||||||
debug!(self.logger, "Resuming playback");
|
|
||||||
self.device.resume();
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AudioCallback for SdlCallback {
|
|
||||||
type Channel = f32;
|
|
||||||
fn callback(&mut self, buffer: &mut [Self::Channel]) {
|
|
||||||
// Clear buffer
|
|
||||||
for d in &mut *buffer {
|
|
||||||
*d = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut data = self.data.lock().unwrap();
|
|
||||||
data.fill_buffer(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue