aboutsummaryrefslogtreecommitdiff
path: root/src/audio
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio')
-rw-r--r--src/audio/play_queue.rs90
-rw-r--r--src/audio/ytdl.rs47
2 files changed, 56 insertions, 81 deletions
diff --git a/src/audio/play_queue.rs b/src/audio/play_queue.rs
index 4bb6ade..fcbb4f9 100644
--- a/src/audio/play_queue.rs
+++ b/src/audio/play_queue.rs
@@ -1,20 +1,13 @@
use std::{
collections::VecDeque,
- io::{self, Cursor},
- iter,
- process::{
- Command,
- Stdio,
- },
+ io::{self, BufRead, BufReader, Cursor},
+ process,
sync::{Arc, RwLock},
thread,
time::Duration,
};
-use byteorder::{ByteOrder, NativeEndian};
use either::{Left, Right};
-use itertools::Itertools;
-use lame_sys;
use serenity::{
prelude::*,
voice,
@@ -114,52 +107,51 @@ impl PlayQueue {
}
}
},
- Right(ref mut v) => {
-
-// let out = unsafe {
-// let hip_t = lame_sys::hip_decode_init();
-//
-// let mut pcm_l = vec![0; 5 * 1024 * 1024 / 2];
-// let mut pcm_r = vec![0; 5 * 1024 * 1024 / 2];
-//
-// let count = lame_sys::hip_decode(hip_t,
-// v.as_mut_ptr(),
-// v.len(),
-// pcm_l.as_mut_ptr(),
-// pcm_r.as_mut_ptr());
-//
-// lame_sys::hip_decode_exit(hip_t);
-//
-// pcm_l.into_iter()
-// .interleave(pcm_r.into_iter())
-// .flat_map(|x| {
-// let mut b = vec![0u8; 2];
-// NativeEndian::write_i16(&mut b, x);
-//
-// b.into_iter()
-// })
-// .collect::<Vec<u8>>()
-// };
-
- let mut out = Command::new("lame")
+ Right(ref vec) => {
+ let mut transcoder = process::Command::new("ffmpeg")
.args(&[
- "--decode", "-t",
- "-", "-",
+ "-format", "opus",
+ "-i", "pipe:0",
+ "-acodec", "pcm_s16le",
+ "-f", "s16le",
+ "-"
])
- .stdin(Stdio::piped())
- .stdout(Stdio::piped())
- .stderr(Stdio::piped())
+ .stdin(process::Stdio::piped())
+ .stdout(process::Stdio::piped())
+ .stderr(process::Stdio::piped())
.spawn()
- .unwrap();
+ .expect("unable to call ffmpeg");
+
+ let process::Child {
+ stdin,
+ stderr,
+ stdout,
+ ..
+ } = transcoder;
+
+ thread::spawn(move || {
+ let stderr = BufReader::new(stderr.unwrap());
- io::copy(&mut Cursor::new(v), &mut out.stdin.as_mut().unwrap());
- let result = voice::pcm(true, Cursor::new("abc"));
+ for line in stderr.lines() {
+ let line = line.unwrap();
-// out.stdout.as_mut().unwrap()
+ trace!("{}", line);
+ }
+ });
+
+ let v = vec.clone();
+ thread::spawn(move || {
+ if let Err(e) = io::copy(&mut Cursor::new(v), &mut stdin.unwrap()) {
+ use std::io::ErrorKind;
+ if e.kind() == ErrorKind::BrokenPipe {
+ debug!("ffmpeg closed unexpectedly");
+ } else {
+ error!("copying audio to ffmpeg {}", e);
+ }
+ }
+ });
- let status = out.wait_with_output().unwrap();
- println!("{}", status.status);
- println!("{}", String::from_utf8(status.stderr).unwrap());
+ let result = voice::pcm(true, stdout.unwrap());
result
}
diff --git a/src/audio/ytdl.rs b/src/audio/ytdl.rs
index 7333c18..8239683 100644
--- a/src/audio/ytdl.rs
+++ b/src/audio/ytdl.rs
@@ -45,8 +45,9 @@ pub(crate) trait CodecInfo {
}
pub(crate) struct Pcm {}
+
+#[allow(dead_code)]
pub(crate) struct Opus {}
-pub(crate) struct Mp3 {}
impl CodecInfo for Pcm {
#[inline]
@@ -67,28 +68,9 @@ impl CodecInfo for Opus {
fn ffmpeg_opts() -> &'static[&'static str] {
lazy_static! {
static ref OPTS: Vec<&'static str> = vec! [
-// "-f", "s16le",
+ "-f", "opus",
"-acodec", "libopus",
- "-sample_fmt", "s16",
- "-vbr", "off",
-// "-b:a 96k",
-// "-vn",
- ];
- }
-
- &*OPTS
- }
-}
-
-impl CodecInfo for Mp3 {
- #[inline]
- fn ffmpeg_opts() -> &'static[&'static str] {
- lazy_static! {
- static ref OPTS: Vec<&'static str> = vec! [
- "-f", "aac",
- "-acodec", "libfdk_aac",
- "-b:a", "96k",
- "-sample_fmt", "s16",
+ "-b:a 96k",
];
}
@@ -130,7 +112,7 @@ pub fn ytdl_url(uri: &str) -> Result<String> {
}
}
-pub(crate) fn ffmpeg_dl<T: CodecInfo>(uri: &str, start: Option<Duration>, end: Option<Duration>, size_limit: Option<usize>) -> Result<Child> {
+pub(crate) fn ffmpeg_dl<T: CodecInfo>(uri: &str, start: Option<Duration>, end: Option<Duration>, size_limit: Option<usize>) -> Result<Box<dyn Read + Send>> {
let start = start.unwrap_or(Duration::zero());
let start_str = format!("{:02}:{:02}:{:02}", start.num_hours(), start.num_minutes() % 60, start.num_seconds() % 60);
@@ -146,6 +128,11 @@ pub(crate) fn ffmpeg_dl<T: CodecInfo>(uri: &str, start: Option<Duration>, end: O
.map(|s| s.to_owned())
.collect::<Vec<_>>();
+ if let Some(e) = end {
+ opts.push("-to".to_owned());
+ opts.push(format!("{:02}:{:02}:{:02}", e.num_hours(), e.num_minutes() % 60, e.num_seconds() % 60));
+ }
+
let codec_opts = T::ffmpeg_opts().into_iter().map(|&s| s.to_owned()).collect::<Vec<_>>();
opts.extend(codec_opts);
@@ -154,28 +141,24 @@ pub(crate) fn ffmpeg_dl<T: CodecInfo>(uri: &str, start: Option<Duration>, end: O
opts.push(format!("{}", limit));
}
- if let Some(e) = end {
- opts.push("-to".to_owned());
- opts.push(format!("{:02}:{:02}:{:02}", e.num_hours(), e.num_minutes() % 60, e.num_seconds() % 60));
- }
-
opts.push("-".to_owned());
debug!("ffmpeg -i \"{}\" {}", uri, opts.join(" "));
- Command::new("ffmpeg")
+ let command = Command::new("ffmpeg")
.arg("-i")
.arg(uri)
.args(opts)
.stderr(Stdio::piped())
.stdin(Stdio::null())
.stdout(Stdio::piped())
- .spawn()
- .map_err(|e| e.into())
+ .spawn()?;
+
+ Ok(Box::new(ChildContainer(command)))
}
pub fn ytdl(uri: &str, start: Option<Duration>, end: Option<Duration>) -> Result<Box<AudioSource>> {
let youtube_uri = ytdl_url(uri)?;
let command = ffmpeg_dl::<Pcm>(&youtube_uri, start, end, None)?;
- Ok(pcm(true, command.stdout.unwrap()))
+ Ok(pcm(true, command))
}