Skip to content
This repository has been archived by the owner on Jul 21, 2024. It is now read-only.

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
thedtvn committed Mar 6, 2024
1 parent 8c3cf64 commit a8d9fed
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 68 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ openssl = { version = "0.10", features = ["vendored"]}
rustube = {git = "https://github.com/fantasybot-red/rustube" , rev = "372c5aeddb4403032f69ac9dbe621a4f61a798af"}
dashmap = "5.5.3"
chrono = "0.4.31"
base64 = "0.21.5"
base64 = "0"
hound = "3.5.1"
ffmpeg-sidecar = "1.0.1"


[dependencies.symphonia]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ A audio sender on top of serenity-rs/songbird
this to connect use https://github.com/fantasybot-red/songbird-client.py

dependencies
- ffmpeg (for play audio i think that symphonia not better than ffmpeg)
- ffmpeg ( it auto install )
11 changes: 3 additions & 8 deletions src/ffmpeg_support.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use songbird::input::Input;
use std::process::{Command, Stdio};

pub async fn get_input(path: String) -> Input {
ffmpeg_player(path.clone()).await
Expand Down Expand Up @@ -27,15 +26,11 @@ pub async fn ffmpeg_player(path: String) -> Input {
"48000",
"-"];
args.extend(options);
let command = Command::new("ffmpeg")
let command = ffmpeg_sidecar::command::FfmpegCommand::new()
.args(pre_input_args)
.arg("-i")
.arg(path)
.input(path)
.args(args)
.stderr(Stdio::null())
.stdin(Stdio::null())
.stdout(Stdio::piped())
.spawn().unwrap();
let data = crate::task_support::ChildContainer::from(command);
let data = crate::task_support::FFmpegContainer::from(command);
return Input::from(data);
}
11 changes: 11 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ async fn auth(req: Request, next: Next) -> Result<Response, StatusCode> {

#[tokio::main]
async fn main() {
println!("starting");
if !ffmpeg_sidecar::command::ffmpeg_is_installed() {
println!("ffmpeg is not installed");
println!("installing ffmpeg");
ffmpeg_sidecar::download::auto_download().unwrap();
println!("ffmpeg install successfully");
} else {
println!("ffmpeg is already installed");
}
println!("ffmpeg path: {}", ffmpeg_sidecar::paths::ffmpeg_path().to_string_lossy());
println!("getting region");
*REGION.lock().await = reqwest::get("https://api.techniknews.net/ipgeo/").await.unwrap().text().await.unwrap();
println!("get region successfully");
let app = Router::new()
Expand Down
81 changes: 23 additions & 58 deletions src/task_support.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,41 @@
use songbird::input::{Input, RawAdapter};
use std::{
io::{Read, Result as IoResult},
mem,
process::Child,
io::Read, process::ChildStdout, sync::Mutex, io::Result as IoResult
};
use symphonia::core::io::ReadOnlySource;
use tokio::runtime::Handle;
use ffmpeg_sidecar::child::FfmpegChild;

/// Handle for a child process which ensures that any subprocesses are properly closed
/// on drop.
///
/// # Warning
/// To allow proper cleanup of child processes, if you create a process chain you must
/// make sure to use `From<Vec<Child>>`. Here, the *last* process in the `Vec` will be
/// used as the audio byte source.
#[derive(Debug)]
pub struct ChildContainer(pub Vec<Child>);

impl Read for ChildContainer {
fn read(&mut self, buffer: &mut [u8]) -> IoResult<usize> {
match self.0.last_mut() {
Some(ref mut child) => child.stdout.as_mut().unwrap().read(buffer),
None => Ok(0),
}
}
pub struct FFmpegContainer {
pub(crate) inter: FfmpegChild,
pub(crate) stdout: Mutex<ChildStdout>,
}

impl ChildContainer {
/// Create a new [`ChildContainer`] from a child process
#[must_use]
pub fn new(children: Vec<Child>) -> Self {
Self(children)
impl FFmpegContainer {
fn new(mut inter: FfmpegChild) -> Self {
let stdout = Mutex::new(inter.take_stdout().unwrap());
Self { inter, stdout }
}
}

impl From<Child> for ChildContainer {
fn from(container: Child) -> Self {
Self(vec![container])
impl Read for FFmpegContainer {
fn read(&mut self, buffer: &mut [u8]) -> IoResult<usize> {
let stdout = self.stdout.lock();
if stdout.is_err() {
return Ok(0);
}
stdout.unwrap().read(buffer)
}
}

impl From<Vec<Child>> for ChildContainer {
fn from(container: Vec<Child>) -> Self {
Self(container)
impl From<FfmpegChild> for FFmpegContainer {
fn from(container: FfmpegChild) -> Self {
Self::new(container)
}
}

impl From<ChildContainer> for Input {
fn from(val: ChildContainer) -> Self {
impl From<FFmpegContainer> for Input {
fn from(val: FFmpegContainer) -> Self {
let source = ReadOnlySource::new(val);
let audio_stream = RawAdapter::new(
source, 48000, 2
Expand All @@ -56,31 +44,8 @@ impl From<ChildContainer> for Input {
}
}

impl Drop for ChildContainer {
impl Drop for FFmpegContainer {
fn drop(&mut self) {
let children = mem::take(&mut self.0);

if let Ok(handle) = Handle::try_current() {
handle.spawn_blocking(move || {
cleanup_child_processes(children);
});
} else {
cleanup_child_processes(children);
}
let _ = self.inter.kill();
}
}

fn cleanup_child_processes(mut children: Vec<Child>) {
let attempt = if let Some(child) = children.last_mut() {
child.kill()
} else {
return;
};

let _ = attempt.and_then(|()| {
children
.iter_mut()
.rev()
.try_for_each(|child| child.wait().map(|_| ()))
});
}

0 comments on commit a8d9fed

Please sign in to comment.