Index transcripts into library search (FTS), both UIs
The 🔍 library search now matches spoken words, not just titles /
channels / descriptions.
- database.rs: add a `transcript` column to the `video_search` FTS5 index.
Fresh DBs get it directly; existing ones are migrated (FTS5 has no ADD
COLUMN, so the table is recreated and search_meta cleared to force a
one-time reindex). `sync_search_index` reads each video's first subtitle
(mtime-gated like the description), flattens it via the shared `vtt`
parser (`transcript_text`, capped at 256 KB), and indexes it. Search
snippets now use column -1 so the excerpt comes from whichever column
matched (description or transcript).
- library.rs: `build_search_entries` passes the first subtitle path.
- Both UIs: search copy updated to mention transcripts.
Tests: a unit test (a word only in the .vtt is found), a migration test
(seed an old 5-column index + stale meta, open, confirm the recreated
index indexes transcript text), and the search integration test now seeds
a subtitle and asserts a spoken-only word hits. Also bumped the test
server's startup budget so the ffmpeg-heavy dedup test can't starve a
sibling server into a flaky timeout. 120 tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4136a9468b
commit
e840d55332
5 changed files with 132 additions and 18 deletions
|
|
@ -994,7 +994,7 @@ impl App {
|
|||
.show(ctx, |ui| {
|
||||
let resp = ui.add(
|
||||
egui::TextEdit::singleline(&mut self.search_query)
|
||||
.hint_text("titles, channels, descriptions…")
|
||||
.hint_text("titles, channels, descriptions, transcripts…")
|
||||
.desired_width(f32::INFINITY),
|
||||
);
|
||||
if std::mem::take(&mut self.search_focus) {
|
||||
|
|
@ -1007,7 +1007,7 @@ impl App {
|
|||
}
|
||||
ui.separator();
|
||||
if self.search_query.trim().is_empty() {
|
||||
ui.weak("Type to search every title, channel, and description in the library.");
|
||||
ui.weak("Type to search every title, channel, description, and transcript in the library.");
|
||||
} else if self.search_results.is_empty() {
|
||||
ui.weak("No matches.");
|
||||
} else {
|
||||
|
|
@ -1377,7 +1377,7 @@ impl App {
|
|||
);
|
||||
ui.separator();
|
||||
if ui.button("🔎 Search")
|
||||
.on_hover_text("Full-text search titles + descriptions across the whole library")
|
||||
.on_hover_text("Full-text search titles, descriptions + transcripts across the whole library")
|
||||
.clicked()
|
||||
{
|
||||
self.show_search = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue