aboutsummaryrefslogtreecommitdiffstats
path: root/src/voice
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/voice/mod.rs80
1 files changed, 40 insertions, 40 deletions
diff --git a/src/voice/mod.rs b/src/voice/mod.rs
index 4087eba..9c92202 100644
--- a/src/voice/mod.rs
+++ b/src/voice/mod.rs
@@ -188,46 +188,6 @@ pub async fn download_url(client: &reqwest::Client, url: &str) -> Result<Vec<u8>
188 Ok(bytes.to_vec()) 188 Ok(bytes.to_vec())
189} 189}
190 190
191/// DEBUG: bypass encode/decode — just pipe through ffmpeg as PCM.
192/// If this plays, the streaming pipeline works; bug is in Opus roundtrip.
193pub async fn degrade_audio(input: &[u8]) -> Result<songbird::input::Input> {
194 use std::process::Stdio;
195
196 let mut child = tokio::process::Command::new("ffmpeg")
197 .args([
198 "-y", "-i", "pipe:0", "-vn", "-f", "f32le", "-ac", "2", "-ar", "8000", "-b:a", "500",
199 "pipe:1",
200 ])
201 .stdin(Stdio::piped())
202 .stdout(Stdio::piped())
203 .stderr(Stdio::null())
204 .kill_on_drop(true)
205 .spawn()
206 .map_err(|e| Error::Custom(format!("ffmpeg passthrough spawn: {e}")))?;
207
208 let mut stdin = child.stdin.take().unwrap();
209 let stdout = child
210 .stdout
211 .take()
212 .ok_or_else(|| Error::Custom("stdout not captured".into()))?;
213
214 let owned_input = input.to_vec();
215 tokio::spawn(async move {
216 use tokio::io::AsyncWriteExt;
217 let _ = stdin.write_all(&owned_input).await;
218 });
219
220 let ffmpeg_child = FfmpegChild {
221 _child: child,
222 stdout,
223 };
224
225 let async_source = AsyncReadOnlySource::new(ffmpeg_child);
226 let adapter = AsyncAdapterStream::new(Box::new(async_source), 64 * 1024);
227 let raw = RawAdapter::new(adapter, 48000, 2);
228 Ok(raw.into())
229}
230
231// ── HTTP streaming via songbird's built-in HttpRequest (legacy) ───── 191// ── HTTP streaming via songbird's built-in HttpRequest (legacy) ─────
232 192
233/// Create a songbird `Input` that streams audio directly from an HTTP(S) URL. 193/// Create a songbird `Input` that streams audio directly from an HTTP(S) URL.
@@ -268,6 +228,46 @@ impl tokio::io::AsyncRead for FfmpegChild {
268 } 228 }
269} 229}
270 230
231/// Decode a local audio file via ffmpeg to raw f32 PCM at 48 kHz stereo.
232/// No reconnect flags (those are for HTTP streams only).
233pub async fn ffmpeg_decode_file(path: &str) -> Result<songbird::input::Input> {
234 use std::process::Stdio;
235
236 let mut child = tokio::process::Command::new("ffmpeg")
237 .args([
238 "-i",
239 path,
240 "-vn",
241 "-f",
242 "f32le",
243 "-ar",
244 "48000",
245 "-ac",
246 "2",
247 "pipe:1",
248 ])
249 .stdout(Stdio::piped())
250 .stderr(Stdio::piped())
251 .kill_on_drop(true)
252 .spawn()
253 .map_err(|e| Error::Custom(format!("ffmpeg decode spawn: {e}")))?;
254
255 let stdout = child
256 .stdout
257 .take()
258 .ok_or_else(|| Error::Custom("ffmpeg stdout not captured".into()))?;
259
260 let ffmpeg_child = FfmpegChild {
261 _child: child,
262 stdout,
263 };
264
265 let async_source = AsyncReadOnlySource::new(ffmpeg_child);
266 let adapter = AsyncAdapterStream::new(Box::new(async_source), 64 * 1024);
267 let raw = RawAdapter::new(adapter, 48000, 2);
268 Ok(raw.into())
269}
270
271/// Stream an HTTP(S) URL live via an ffmpeg subprocess, producing a songbird 271/// Stream an HTTP(S) URL live via an ffmpeg subprocess, producing a songbird
272/// `Input` of raw f32 PCM at 48 kHz stereo — NO full download. 272/// `Input` of raw f32 PCM at 48 kHz stereo — NO full download.
273/// 273///