feat: 支持多播放源并发混音
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
#![cfg(target_os = "linux")]
|
||||
use anyhow::{Context, Result};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
|
||||
const FIFO_PATH: &str = "/tmp/stereo_out.fifo";
|
||||
const REAL_ASOUND_CONF: &str = "/etc/asound.conf";
|
||||
const TEMP_ASOUND_CONF: &str = "/tmp/asound.stereo.conf";
|
||||
|
||||
/// ALSA 音频重定向器,用于拦截系统音频输出到 FIFO 管道
|
||||
/// ALSA 音频重定向器,通过 Pipe 模式将音频流注入到主进程的混音器中
|
||||
pub struct AlsaRedirector;
|
||||
|
||||
impl AlsaRedirector {
|
||||
@@ -17,12 +17,32 @@ impl AlsaRedirector {
|
||||
let original_conf = fs::read_to_string(REAL_ASOUND_CONF).unwrap_or_default();
|
||||
|
||||
if !original_conf.contains("pcm.original_default") {
|
||||
let current_exe = env::current_exe()
|
||||
.context("无法获取当前可执行文件路径")?
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
// 重命名原有的 default 逻辑,插入拦截器
|
||||
let mut new_conf = original_conf.replace("pcm.!default", "pcm.original_default");
|
||||
new_conf.push_str(&format!(
|
||||
"\npcm.!default {{ type plug slave {{ pcm \"stereo_interceptor\" format S16_LE rate 48000 channels 2 }} }}\n\
|
||||
pcm.stereo_interceptor {{ type file slave.pcm \"null\" file \"{}\" format \"raw\" }}\n",
|
||||
FIFO_PATH
|
||||
r#"
|
||||
pcm.!default {{
|
||||
type plug
|
||||
slave {{
|
||||
pcm "stereo_interceptor"
|
||||
format S16_LE
|
||||
rate 48000
|
||||
channels 2
|
||||
}}
|
||||
}}
|
||||
pcm.stereo_interceptor {{
|
||||
type file
|
||||
slave.pcm "null"
|
||||
file "| {} --inject"
|
||||
format "raw"
|
||||
}}
|
||||
"#,
|
||||
current_exe
|
||||
));
|
||||
|
||||
fs::write(TEMP_ASOUND_CONF, new_conf)?;
|
||||
@@ -40,11 +60,6 @@ impl AlsaRedirector {
|
||||
}
|
||||
}
|
||||
|
||||
// 创建 FIFO 管道
|
||||
let _ = Command::new("mkfifo").arg(FIFO_PATH).status();
|
||||
let _ = Command::new("chmod").arg("666").arg(FIFO_PATH).status();
|
||||
|
||||
// println!("ALSA 输出已重定向至 {}", FIFO_PATH);
|
||||
Ok(Self)
|
||||
}
|
||||
|
||||
@@ -54,12 +69,6 @@ impl AlsaRedirector {
|
||||
.arg(format!("umount -l {} >/dev/null 2>&1", REAL_ASOUND_CONF))
|
||||
.status();
|
||||
let _ = fs::remove_file(TEMP_ASOUND_CONF);
|
||||
let _ = fs::remove_file(FIFO_PATH);
|
||||
// println!("ALSA 配置已恢复。");
|
||||
}
|
||||
|
||||
pub fn fifo_path() -> &'static str {
|
||||
FIFO_PATH
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user