Skip to content

Commit 270e082

Browse files
committed
feat(classroom): 视频导入 OCR 进度携带累计识别块数
1 parent a96da78 commit 270e082

2 files changed

Lines changed: 17 additions & 8 deletions

File tree

‎app/src-tauri/src/import.rs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,17 +249,19 @@ fn ocr_keyframes<F: Fn(&ImportProgress)>(
249249
// 各区域帧间文本去重(静态画面不重复落库)
250250
let mut last_full: Vec<String> = Vec::new();
251251
let mut last_subtitle: Vec<String> = Vec::new();
252+
// v0.11.7:累计识别块数(进度消息「已识别 N 块文字」)
253+
let mut total_blocks = 0usize;
252254
for (i, path) in files.iter().enumerate() {
253255
let timestamp_ms = (i as u64) * FRAME_INTERVAL_MS;
254256
match image::open(path).map(|d| d.into_rgb8()) {
255-
Ok(img) => crate::import_frame::ocr_keyframe(
257+
Ok(img) => total_blocks += crate::import_frame::ocr_keyframe(
256258
db, engines, session_id, timestamp_ms, &img, &mut last_full, &mut last_subtitle, ui_junk,
257259
),
258260
Err(e) => eprintln!("[Import] 关键帧解码失败(跳过): {}", e),
259261
}
260262
progress(&ImportProgress {
261263
stage: "ocr".into(),
262-
message: format!("画面识别 {}/{}", i + 1, total),
264+
message: format!("画面识别 {}/{} · 已识别 {} 块文字", i + 1, total, total_blocks),
263265
done: (i + 1) as u32,
264266
total,
265267
});

‎app/src-tauri/src/import_frame.rs‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,24 @@ pub fn ocr_keyframe(
7979
last_full: &mut Vec<String>,
8080
last_subtitle: &mut Vec<String>,
8181
ui_junk: &crate::ui_junk::UiJunkList,
82-
) {
82+
) -> usize {
8383
let (orig_w, orig_h) = image.dimensions();
8484
// 中部区域 → 画面要点(region=full,避开字幕带干扰)
85+
let mut count = 0usize;
8586
if let Some(mid) = crop_and_scale(image, MIDDLE_TOP_RATIO, MIDDLE_BOTTOM_RATIO, OCR_MAX_WIDTH) {
86-
recognize_region(
87+
count += recognize_region(
8788
db, engines, session_id, timestamp_ms, mid, "full", MIDDLE_TOP_RATIO, orig_w, orig_h,
8889
last_full, ui_junk,
8990
);
9091
}
9192
// 底部区域 → 烧录字幕(region=subtitle,与实时链路语义一致)
9293
if let Some(bot) = crop_and_scale(image, BOTTOM_TOP_RATIO, 1.0, OCR_MAX_WIDTH) {
93-
recognize_region(
94+
count += recognize_region(
9495
db, engines, session_id, timestamp_ms, bot, "subtitle", BOTTOM_TOP_RATIO, orig_w, orig_h,
9596
last_subtitle, ui_junk,
9697
);
9798
}
99+
count
98100
}
99101

100102
/// 单区域识别 + 帧间去重 + 落库。
@@ -116,11 +118,11 @@ fn recognize_region(
116118
orig_h: u32,
117119
last_texts: &mut Vec<String>,
118120
ui_junk: &crate::ui_junk::UiJunkList,
119-
) {
121+
) -> usize {
120122
// H2 修复:有界等待变体——单区域推理卡死时超时返回 Err 走下帧重试,
121123
// 不得无限阻塞导入管线
122124
let Ok(blocks) = engines.recognize_image_timeout(region_img, crate::engine::OCR_REQUEST_TIMEOUT) else {
123-
return; // 识别失败/超时:下帧重试(不阻断管线)
125+
return 0; // 识别失败/超时:下帧重试(不阻断管线)
124126
};
125127
// v0.7.3(REQ-156):bbox 反算回帧坐标系所需的等比缩放因子
126128
// (crop_and_scale 裁剪+缩放后识别,bbox 处于裁剪图坐标系——TD-046 同思路;
@@ -143,8 +145,10 @@ fn recognize_region(
143145
.map(|b| b.text.clone())
144146
.collect();
145147
if same_texts(&texts, last_texts) {
146-
return; // 静态画面:与上帧完全一致,不重复落库
148+
return 0; // 静态画面:与上帧完全一致,不重复落库
147149
}
150+
// 本区域本次新落库块数(进度消息用;v0.11.7)
151+
let mut count = 0usize;
148152
for block in blocks {
149153
if block.score >= MIN_SCORE
150154
&& !block.text.trim().is_empty()
@@ -171,10 +175,13 @@ fn recognize_region(
171175
screen_id: None,
172176
}) {
173177
eprintln!("[Import] OCR 块落库失败: {}", e);
178+
} else {
179+
count += 1;
174180
}
175181
}
176182
}
177183
*last_texts = texts;
184+
count
178185
}
179186

180187
#[cfg(test)]

0 commit comments

Comments
 (0)