fix: 修复开始播放音频时爆音的问题

This commit is contained in:
Del Wang
2025-12-31 22:53:33 +08:00
committed by Del
parent 1caef01836
commit 871d01a158
3 changed files with 26 additions and 11 deletions
+5 -1
View File
@@ -1,7 +1,7 @@
#![cfg(target_os = "linux")]
use crate::config::AudioConfig;
use alsa::pcm::{Access, Format, HwParams, PCM};
use alsa::Direction;
use alsa::pcm::{Access, Format, HwParams, PCM};
use anyhow::{Context, Result};
pub struct AudioPlayer {
@@ -38,6 +38,10 @@ impl AudioPlayer {
}
}
}
pub fn prepare(&self) -> Result<()> {
self.pcm.prepare().context("Failed to prepare PCM")
}
}
fn setup_pcm(pcm: &PCM, sample_rate: u32, channels: u16) -> Result<()> {
+11 -10
View File
@@ -78,15 +78,6 @@ pub async fn run_master(master_role: ChannelRole) -> Result<()> {
..AudioConfig::default()
};
let mut left_encoder = OpusCodec::new(&AudioConfig {
channels: 1,
..config.clone()
})?;
let mut right_encoder = OpusCodec::new(&AudioConfig {
channels: 1,
..config.clone()
})?;
let mut current_player_channels = 0;
let mut player: Option<AudioPlayer> = None;
@@ -113,6 +104,16 @@ pub async fn run_master(master_role: ChannelRole) -> Result<()> {
}
};
// 每个新流开始时,重置编码器状态以避免残留音频导致爆音
let mut left_encoder = OpusCodec::new(&AudioConfig {
channels: 1,
..config.clone()
})?;
let mut right_encoder = OpusCodec::new(&AudioConfig {
channels: 1,
..config.clone()
})?;
loop {
// 从 FIFO 读取
if let Err(_) = fifo.read_exact(&mut raw_buf).await {
@@ -234,7 +235,7 @@ pub async fn run_master(master_role: ChannelRole) -> Result<()> {
seq += 1;
}
// 重置流计时
stream_start_ts = 0;
}
+10
View File
@@ -138,6 +138,7 @@ async fn handle_connection(role: ChannelRole) -> Result<()> {
println!("✅ 主节点已连接,音频串流中...");
let mut pcm_buf = vec![0i16; config.frame_size];
let mut last_seq: Option<u32> = None;
let mut last_packet_time = now_us();
loop {
// 检查 TCP 是否已断开
@@ -147,6 +148,15 @@ async fn handle_connection(role: ChannelRole) -> Result<()> {
// 填充 Jitter Buffer
while let Ok(pkt) = audio_rx.try_recv() {
let now = now_us();
// 如果超过 500ms 没有收到包,认为是新流开始,重置状态
if now - last_packet_time > 500_000 {
jitter.clear();
last_seq = None;
codec = OpusCodec::new(&config)?;
let _ = player.prepare();
}
last_packet_time = now;
jitter.push(pkt);
}