fix(bailian): 修复 DashScope ASR 部分语句重复输出的问题
两个根因: 1. end_time 判断用 is_some() 而非 > 0:API 对 interim 结果设 end_time:0, 导致所有中间结果被当成 final 推入 segments 2. 累积文本拼接:同一句 API 多次发送("你"→"你好"→"你好吗"), 每次作为新 segment push,join 后变成重复拼接 修复: - end_time 改用 > 0 判断真正的句子结束 - 引入 sentence_id → BTreeMap 按序存储,同一 sentence_id 后到覆盖前到 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
7635df5df5
commit
54f07d85e9
1 file changed
+19
-5
@@ -5,6 +5,7 @@
|
||||
//! matches OpenLess' recorder output directly. The Qwen OpenAI Realtime line is
|
||||
//! a different protocol and is intentionally left for a follow-up provider.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
@@ -94,7 +95,9 @@ struct SyncState {
|
||||
start: Option<Instant>,
|
||||
final_tx: Option<oneshot::Sender<Result<RawTranscript, BailianASRError>>>,
|
||||
send_tx: Option<mpsc::UnboundedSender<SendItem>>,
|
||||
final_segments: Vec<String>,
|
||||
/// sentence_id → text,按 sentence_id 排序拼接得到最终文本。
|
||||
/// 同一 sentence_id 的后到结果覆盖前一个,消除累积文本导致的重复。
|
||||
final_segments: BTreeMap<i64, String>,
|
||||
last_result_text: String,
|
||||
}
|
||||
|
||||
@@ -367,11 +370,22 @@ impl BailianRealtimeASR {
|
||||
if trimmed.is_empty() {
|
||||
return;
|
||||
}
|
||||
let is_sentence_final = sentence.get("end_time").is_some();
|
||||
// end_time 为 0 或缺失时是 interim 结果;仅正数才是真正完成的句子。
|
||||
let end_time = sentence
|
||||
.get("end_time")
|
||||
.and_then(Value::as_i64)
|
||||
.unwrap_or(0);
|
||||
let is_sentence_final = end_time > 0;
|
||||
let sentence_id = sentence
|
||||
.get("sentence_id")
|
||||
.and_then(Value::as_i64)
|
||||
.unwrap_or(0);
|
||||
let mut st = self.state.lock();
|
||||
st.last_result_text = trimmed.to_string();
|
||||
if is_sentence_final && st.final_segments.last().map(|s| s.as_str()) != Some(trimmed) {
|
||||
st.final_segments.push(trimmed.to_string());
|
||||
if is_sentence_final && sentence_id > 0 {
|
||||
// 同一 sentence_id 后到覆盖前到:API 对同一句话的累积更新
|
||||
// ("你"→"你好"→"你好吗")只保留最终版本。
|
||||
st.final_segments.insert(sentence_id, trimmed.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +400,7 @@ impl BailianRealtimeASR {
|
||||
let text = if st.final_segments.is_empty() {
|
||||
st.last_result_text.clone()
|
||||
} else {
|
||||
st.final_segments.join("")
|
||||
st.final_segments.values().cloned().collect::<Vec<_>>().join("")
|
||||
};
|
||||
let duration_ms = if st.bytes_received > 0 {
|
||||
st.bytes_received / BYTES_PER_MS
|
||||
|
||||
Reference in new issue
Block a user