feat(subs): translate from an image-only release
A release whose only subtitle is a PGS or VobSub track was stuck both ways: the track satisfied English so no English SRT was ever fetched, and bitmaps can never feed a translator. §15 is amended to separate satisfying viewing from providing a translation source, and to carve a fetch made to obtain a source out of the no-upgrade rule. Timings come from the disc rather than from alass guessing at the audio. At import, each non-forced image track's packet timestamps are paired show-to-clear into a cue skeleton and stored; the fetched source is then aligned against that skeleton, and the translation made from it skips the post-translation pass, which could only move disc-exact timings off. Pairing is validated before it is trusted — even packet count, plausible durations, sane density for the runtime — because PGS allows several composition segments per subtitle and a slipped pairing is quietly half a second out. A track that fails validation gets no skeleton and falls back to aligning against the video, as does any file imported before this: there is no backfill. Closes #268 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
015b90a458
commit
6cd2902341
+3
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO subtitle_files\n (media_file_id, language, origin, provider, candidate_id, engine,\n forced, sdh, synced, sync_rejected, path)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (path) DO NOTHING\n ON CONFLICT (media_file_id, language, forced, sdh)\n WHERE origin = 'embedded' DO NOTHING\n RETURNING id AS \"id!: i64\"",
|
||||
"query": "INSERT INTO subtitle_files\n (media_file_id, language, origin, provider, candidate_id, engine,\n forced, sdh, synced, sync_rejected, skeleton_aligned, path)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (path) DO NOTHING\n ON CONFLICT (media_file_id, language, forced, sdh)\n WHERE origin = 'embedded' DO NOTHING\n RETURNING id AS \"id!: i64\"",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -16,11 +16,11 @@
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 11
|
||||
"Right": 12
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "3d48b78768bf8dc2e337d0935889a5654089f38bb7ee2a15b7e19f4ed5540262"
|
||||
"hash": "266c8e63e7f81cb07921de180f32b47ac8c4e9d47a31af786742404f8e54f517"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id AS \"id!: i64\" FROM media_files WHERE path = ?",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: i64",
|
||||
"ordinal": 0,
|
||||
"type_info": "Integer",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "media_files",
|
||||
"name": "id"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "8651688f9f999629b4996c0451f87f5a84fabe748849b4b80063af1c18f73917"
|
||||
}
|
||||
+15
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id AS \"id!: i64\",\n media_file_id AS \"media_file_id!: i64\",\n language AS \"language!: String\",\n origin AS \"origin!: SubtitleOrigin\",\n provider,\n candidate_id,\n engine,\n forced AS \"forced!: bool\",\n sdh AS \"sdh!: bool\",\n synced AS \"synced!: bool\",\n sync_rejected AS \"sync_rejected!: bool\",\n path\n FROM subtitle_files\n WHERE media_file_id = ?\n ORDER BY language, id",
|
||||
"query": "SELECT id AS \"id!: i64\",\n media_file_id AS \"media_file_id!: i64\",\n language AS \"language!: String\",\n origin AS \"origin!: SubtitleOrigin\",\n provider,\n candidate_id,\n engine,\n forced AS \"forced!: bool\",\n sdh AS \"sdh!: bool\",\n synced AS \"synced!: bool\",\n sync_rejected AS \"sync_rejected!: bool\",\n skeleton_aligned AS \"skeleton_aligned!: bool\",\n path\n FROM subtitle_files\n WHERE media_file_id = ?\n ORDER BY language, id",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -125,8 +125,19 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "path",
|
||||
"name": "skeleton_aligned!: bool",
|
||||
"ordinal": 11,
|
||||
"type_info": "Integer",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "subtitle_files",
|
||||
"name": "skeleton_aligned"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "path",
|
||||
"ordinal": 12,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
@@ -151,8 +162,9 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "62d625c322c8c64b48317cdbf466d74043708d8e12997e0efec23a18eaaaaace"
|
||||
"hash": "8abb1e992e0972a19e76c7788c8c350951a1d14766088b1cf3fb886fb658d575"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO subtitle_skeletons (media_file_id, stream_index, language, cues)\n VALUES (?, ?, ?, ?)\n ON CONFLICT (media_file_id, stream_index) DO UPDATE SET\n language = excluded.language,\n cues = excluded.cues",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "8e3c23ed488bc82ff3dd4f6da02d00435525d321b6002b9f31979a39281369ce"
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT stream_index AS \"stream_index!: i64\",\n language AS \"language!: String\",\n cues AS \"cues!: String\"\n FROM subtitle_skeletons\n WHERE media_file_id = ?\n ORDER BY stream_index",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "stream_index!: i64",
|
||||
"ordinal": 0,
|
||||
"type_info": "Integer",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "subtitle_skeletons",
|
||||
"name": "stream_index"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "language!: String",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "subtitle_skeletons",
|
||||
"name": "language"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "cues!: String",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "subtitle_skeletons",
|
||||
"name": "cues"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "eb7df52055a60a00b721e3eef152e1b04a8512a85e8ad3618545c634c23abf31"
|
||||
}
|
||||
Reference in New Issue
Block a user