dsh-pf-stream 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.en.md +145 -33
  2. package/README.md +142 -30
  3. package/client.js +1156 -0
  4. package/icon.svg +18 -0
  5. package/lib/asr/catalog.d.ts +74 -0
  6. package/lib/asr/catalog.js +168 -0
  7. package/lib/asr/catalog.js.map +1 -0
  8. package/lib/asr/detect.d.ts +33 -0
  9. package/lib/asr/detect.js +117 -0
  10. package/lib/asr/detect.js.map +1 -0
  11. package/lib/asr/engine.d.ts +43 -0
  12. package/lib/asr/engine.js +143 -0
  13. package/lib/asr/engine.js.map +1 -0
  14. package/lib/asr/install.d.ts +56 -0
  15. package/lib/asr/install.js +317 -0
  16. package/lib/asr/install.js.map +1 -0
  17. package/lib/asr/verify.d.ts +22 -0
  18. package/lib/asr/verify.js +174 -0
  19. package/lib/asr/verify.js.map +1 -0
  20. package/lib/audio/acousticVad.d.ts +45 -0
  21. package/lib/audio/acousticVad.js +179 -0
  22. package/lib/audio/acousticVad.js.map +1 -0
  23. package/lib/audio/asrProviders.d.ts +51 -0
  24. package/lib/audio/asrProviders.js +251 -0
  25. package/lib/audio/asrProviders.js.map +1 -0
  26. package/lib/audio/asrRouter.d.ts +30 -0
  27. package/lib/audio/asrRouter.js +187 -0
  28. package/lib/audio/asrRouter.js.map +1 -0
  29. package/lib/audio/hallucinationGuard.d.ts +18 -0
  30. package/lib/audio/hallucinationGuard.js +97 -0
  31. package/lib/audio/hallucinationGuard.js.map +1 -0
  32. package/lib/audio/sidecar.d.ts +76 -0
  33. package/lib/audio/sidecar.js +362 -0
  34. package/lib/audio/sidecar.js.map +1 -0
  35. package/lib/audio/subtitleExtractor.d.ts +36 -0
  36. package/lib/audio/subtitleExtractor.js +218 -0
  37. package/lib/audio/subtitleExtractor.js.map +1 -0
  38. package/lib/audio/transcriptCache.d.ts +33 -0
  39. package/lib/audio/transcriptCache.js +126 -0
  40. package/lib/audio/transcriptCache.js.map +1 -0
  41. package/lib/audio/types.d.ts +136 -0
  42. package/lib/audio/types.js +10 -0
  43. package/lib/audio/types.js.map +1 -0
  44. package/lib/host/api.d.ts +23 -0
  45. package/lib/host/api.js +286 -0
  46. package/lib/host/api.js.map +1 -0
  47. package/lib/host/runtime.d.ts +167 -0
  48. package/lib/host/runtime.js +335 -0
  49. package/lib/host/runtime.js.map +1 -0
  50. package/lib/index.d.ts +229 -1
  51. package/lib/index.js +103 -2
  52. package/lib/index.js.map +1 -1
  53. package/lib/session/state.js +4 -0
  54. package/lib/session/state.js.map +1 -1
  55. package/lib/stage0/decoder.d.ts +1 -9
  56. package/lib/stage0/decoder.js +15 -45
  57. package/lib/stage0/decoder.js.map +1 -1
  58. package/lib/stage2/stateMachine.d.ts +4 -1
  59. package/lib/stage2/stateMachine.js +7 -1
  60. package/lib/stage2/stateMachine.js.map +1 -1
  61. package/lib/stage3/deterministicRouter.js +3 -3
  62. package/lib/stage3/deterministicRouter.js.map +1 -1
  63. package/lib/stage3/streamSampler.d.ts +9 -2
  64. package/lib/stage3/streamSampler.js +37 -16
  65. package/lib/stage3/streamSampler.js.map +1 -1
  66. package/lib/stage6/history.d.ts +2 -1
  67. package/lib/stage6/history.js +4 -1
  68. package/lib/stage6/history.js.map +1 -1
  69. package/lib/tool/handler.d.ts +9 -0
  70. package/lib/tool/handler.js +33 -3
  71. package/lib/tool/handler.js.map +1 -1
  72. package/lib/tool/schema.js +15 -2
  73. package/lib/tool/schema.js.map +1 -1
  74. package/lib/tool/streamCall.d.ts +11 -0
  75. package/lib/tool/streamCall.js +122 -9
  76. package/lib/tool/streamCall.js.map +1 -1
  77. package/lib/types.d.ts +9 -0
  78. package/locale/en.json +6 -0
  79. package/locale/zh.json +6 -0
  80. package/package.json +17 -2
@@ -0,0 +1,362 @@
1
+ /**
2
+ * Audio Sidecar 门面:三级获取顺位(字幕 → VAD+ASR → 跳过)、
3
+ * 软截止并行编排、画布包挂载与提示行生成。
4
+ *
5
+ * 铁律:任何音频路径异常都折叠为 status='error'/'timeout_skipped',
6
+ * 不向视觉主链路抛错;无音轨时视觉输出与无本模块时逐字节一致。
7
+ */
8
+ import { isSilentWindow, scanVad } from './acousticVad.js';
9
+ import { loadSubtitleTimeline, sliceSegments } from './subtitleExtractor.js';
10
+ import { speechRateCps } from './hallucinationGuard.js';
11
+ import { transcribeWindow } from './asrRouter.js';
12
+ import { resolveAsr } from '../asr/engine.js';
13
+ const MOUNT_MARGIN_MS = 300;
14
+ /** 跨包 (cont.) 副本的最小重叠(毫秒)。 */
15
+ const CONT_MIN_OVERLAP_MS = 150;
16
+ const ASSIST_STATIC_MS = 10_000;
17
+ const ASSIST_SINCE_F_MS = 3_000;
18
+ const ASSIST_PAUSE_AFTER_ISLAND_MS = 400;
19
+ const ASSIST_ISLAND_RECENT_MS = 5_000;
20
+ const ASSIST_DENSE_ISLAND_MS = 2_000;
21
+ const ASSIST_DENSE_CPS = 5;
22
+ const ASSIST_MIN_SUM_D = 0.15;
23
+ const MAX_HINT_SEGMENTS = 3;
24
+ export const ASSIST_FOCUS_CONSTANTS = {
25
+ staticMs: ASSIST_STATIC_MS,
26
+ sinceFMs: ASSIST_SINCE_F_MS,
27
+ pauseAfterIslandMs: ASSIST_PAUSE_AFTER_ISLAND_MS,
28
+ islandRecentMs: ASSIST_ISLAND_RECENT_MS,
29
+ denseIslandMs: ASSIST_DENSE_ISLAND_MS,
30
+ denseCps: ASSIST_DENSE_CPS,
31
+ minSumD: ASSIST_MIN_SUM_D,
32
+ };
33
+ /**
34
+ * env(DSH_ASR_API_KEY)> 凭据存储 > Config;引擎按 engine 语义解析
35
+ * (auto:旧 provider → 云端密钥 → 本地引擎 → 未配置)。
36
+ */
37
+ export function resolveAudioSettings(config, intent, env, facts) {
38
+ const audioIntent = intent?.audio;
39
+ const mode = audioIntent?.mode ?? config.mode;
40
+ if (mode === 'off') {
41
+ return {
42
+ mode: 'off',
43
+ extractSubtitles: false,
44
+ assistFocus: false,
45
+ sliceCodec: config.sliceCodec,
46
+ cacheEnabled: false,
47
+ cacheDir: config.cacheDir,
48
+ graceMs: config.graceMs,
49
+ asr: null,
50
+ };
51
+ }
52
+ const resolution = resolveAsr(config.asr, audioIntent?.language, env, facts);
53
+ return {
54
+ mode: 'auto',
55
+ extractSubtitles: audioIntent?.extract_subtitles ?? config.extractSubtitles,
56
+ assistFocus: audioIntent?.assist_focus ?? config.assistFocus,
57
+ sliceCodec: config.sliceCodec,
58
+ cacheEnabled: true,
59
+ cacheDir: config.cacheDir,
60
+ graceMs: config.graceMs,
61
+ asr: resolution.settings,
62
+ };
63
+ }
64
+ function emptyContext(status) {
65
+ return {
66
+ status,
67
+ source: null,
68
+ language: null,
69
+ speechRatio: null,
70
+ rmsDb: null,
71
+ speechRateCps: null,
72
+ segmentsInWindow: 0,
73
+ mountedPackets: 0,
74
+ telemetry: { cacheHit: false, chunks: 0, requests: 0, droppedByGuard: 0, costMs: 0 },
75
+ };
76
+ }
77
+ /**
78
+ * 窗口音频上下文(三级顺位)。
79
+ *
80
+ * deadlineAt 为墙钟时刻(Date.now()):到达软截止仍有未完成块时返回
81
+ * timeout_skipped/partial,后台继续补缓存(fire-and-forget)。
82
+ */
83
+ export async function runAudioSidecar(deps, window, deadlineAt) {
84
+ const startedAt = Date.now();
85
+ const { probe, settings } = deps;
86
+ if (settings.mode === 'off')
87
+ return { context: emptyContext('disabled'), segments: [], islands: [], speechRate: null };
88
+ if (probe.audioStreams.length === 0) {
89
+ return { context: emptyContext('no_audio'), segments: [], islands: [], speechRate: null };
90
+ }
91
+ // A0 字幕
92
+ if (settings.extractSubtitles) {
93
+ try {
94
+ const timeline = await loadSubtitleTimeline(deps.videoPath, probe, {
95
+ ffmpegPath: deps.ffmpegPath,
96
+ signal: deps.signal,
97
+ });
98
+ if (timeline.status !== 'none') {
99
+ const segments = sliceSegments(timeline.segments, window);
100
+ let vad = deps.precomputedVad ?? null;
101
+ if (settings.assistFocus && vad === null) {
102
+ vad = await scanVad(deps.videoPath, window, { ffmpegPath: deps.ffmpegPath, signal: deps.signal });
103
+ }
104
+ const rate = speechRateCps(segments, vad);
105
+ return {
106
+ context: {
107
+ status: 'ok',
108
+ source: timeline.status,
109
+ language: timeline.language,
110
+ speechRatio: vad ? vad.activeRatio : null,
111
+ rmsDb: vad ? vad.rmsDb : null,
112
+ speechRateCps: rate,
113
+ segmentsInWindow: segments.length,
114
+ mountedPackets: 0,
115
+ telemetry: {
116
+ cacheHit: false,
117
+ chunks: 0,
118
+ requests: 0,
119
+ droppedByGuard: 0,
120
+ costMs: Date.now() - startedAt,
121
+ },
122
+ },
123
+ segments,
124
+ islands: vad ? vad.islands : [],
125
+ speechRate: rate,
126
+ };
127
+ }
128
+ }
129
+ catch {
130
+ // 字幕失败 → 继续声学路径
131
+ }
132
+ }
133
+ // A1 声学
134
+ let vad = deps.precomputedVad ?? null;
135
+ if (vad === null) {
136
+ try {
137
+ vad = await scanVad(deps.videoPath, window, { ffmpegPath: deps.ffmpegPath, signal: deps.signal });
138
+ }
139
+ catch {
140
+ vad = null;
141
+ }
142
+ }
143
+ if (isSilentWindow(vad)) {
144
+ return {
145
+ context: {
146
+ ...emptyContext('silent'),
147
+ speechRatio: vad.activeRatio,
148
+ rmsDb: vad.rmsDb,
149
+ telemetry: { cacheHit: false, chunks: 0, requests: 0, droppedByGuard: 0, costMs: Date.now() - startedAt },
150
+ },
151
+ segments: [],
152
+ islands: [],
153
+ speechRate: null,
154
+ };
155
+ }
156
+ if (!settings.asr) {
157
+ return {
158
+ context: {
159
+ ...emptyContext('no_subtitle_asr_unconfigured'),
160
+ speechRatio: vad ? vad.activeRatio : null,
161
+ rmsDb: vad ? vad.rmsDb : null,
162
+ telemetry: { cacheHit: false, chunks: 0, requests: 0, droppedByGuard: 0, costMs: Date.now() - startedAt },
163
+ },
164
+ segments: [],
165
+ islands: vad ? vad.islands : [],
166
+ speechRate: null,
167
+ };
168
+ }
169
+ // A2 ASR(软截止)
170
+ try {
171
+ const result = await withDeadline(transcribeWindow(deps.videoPath, window, vad, {
172
+ ffmpegPath: deps.ffmpegPath,
173
+ settings: settings.asr,
174
+ cacheDir: settings.cacheDir,
175
+ cacheEnabled: settings.cacheEnabled,
176
+ sliceCodec: settings.sliceCodec,
177
+ tempDir: deps.tempDir,
178
+ signal: deps.signal,
179
+ }), deadlineAt);
180
+ const rate = speechRateCps(result.segments, vad);
181
+ const status = result.failedChunks > 0 ? 'partial' : 'ok';
182
+ return {
183
+ context: {
184
+ status,
185
+ source: 'asr',
186
+ language: settings.asr.language,
187
+ speechRatio: vad ? vad.activeRatio : null,
188
+ rmsDb: vad ? vad.rmsDb : null,
189
+ speechRateCps: rate,
190
+ segmentsInWindow: result.segments.length,
191
+ mountedPackets: 0,
192
+ telemetry: {
193
+ cacheHit: result.cacheHit,
194
+ chunks: result.requests,
195
+ requests: result.requests,
196
+ droppedByGuard: result.droppedByGuard,
197
+ costMs: Date.now() - startedAt,
198
+ },
199
+ },
200
+ segments: result.segments,
201
+ islands: vad ? vad.islands : [],
202
+ speechRate: rate,
203
+ };
204
+ }
205
+ catch (error) {
206
+ if (error instanceof DeadlineExceededError) {
207
+ return {
208
+ context: {
209
+ ...emptyContext('timeout_skipped'),
210
+ speechRatio: vad ? vad.activeRatio : null,
211
+ rmsDb: vad ? vad.rmsDb : null,
212
+ telemetry: { cacheHit: false, chunks: 0, requests: 0, droppedByGuard: 0, costMs: Date.now() - startedAt },
213
+ },
214
+ segments: [],
215
+ islands: vad ? vad.islands : [],
216
+ speechRate: null,
217
+ };
218
+ }
219
+ return { context: emptyContext('error'), segments: [], islands: vad ? vad.islands : [], speechRate: null };
220
+ }
221
+ }
222
+ class DeadlineExceededError extends Error {
223
+ }
224
+ function withDeadline(task, deadlineAt) {
225
+ return new Promise((resolve, reject) => {
226
+ const remaining = deadlineAt - Date.now();
227
+ if (remaining <= 0) {
228
+ reject(new DeadlineExceededError('audio deadline exceeded'));
229
+ return;
230
+ }
231
+ const timer = setTimeout(() => reject(new DeadlineExceededError('audio deadline exceeded')), remaining);
232
+ task.then((v) => {
233
+ clearTimeout(timer);
234
+ resolve(v);
235
+ }, (e) => {
236
+ clearTimeout(timer);
237
+ reject(e);
238
+ });
239
+ });
240
+ }
241
+ /** ±300ms 交集 + 重叠最大归属;跨包段的第二副本加 (cont.) 前缀。 */
242
+ export function mountSegments(packets, segments, status, source, language) {
243
+ const mounts = new Map();
244
+ if (packets.length === 0 || segments.length === 0)
245
+ return mounts;
246
+ /** 每包命中的段与重叠毫秒数(±300ms 余量口径)。 */
247
+ const hitsByPacket = new Map();
248
+ for (const packet of packets) {
249
+ const lo = packet.startMs - MOUNT_MARGIN_MS;
250
+ const hi = packet.endMs + MOUNT_MARGIN_MS;
251
+ const hits = [];
252
+ for (const seg of segments) {
253
+ if (seg.endMs <= lo || seg.startMs >= hi)
254
+ continue;
255
+ const overlapMs = Math.min(seg.endMs, hi) - Math.max(seg.startMs, lo);
256
+ if (overlapMs <= 0)
257
+ continue;
258
+ hits.push({ seg, overlapMs });
259
+ }
260
+ if (hits.length > 0)
261
+ hitsByPacket.set(packet.packetId, hits);
262
+ }
263
+ // 主归属:重叠最大的包;并列时归较早的包
264
+ const owner = new Map();
265
+ for (const packet of packets) {
266
+ for (const hit of hitsByPacket.get(packet.packetId) ?? []) {
267
+ const prev = owner.get(hit.seg.segId);
268
+ if (prev === undefined) {
269
+ owner.set(hit.seg.segId, packet.packetId);
270
+ continue;
271
+ }
272
+ const prevHits = hitsByPacket.get(prev) ?? [];
273
+ const prevOverlap = prevHits.find((h) => h.seg.segId === hit.seg.segId)?.overlapMs ?? 0;
274
+ if (hit.overlapMs > prevOverlap)
275
+ owner.set(hit.seg.segId, packet.packetId);
276
+ }
277
+ }
278
+ for (const packet of packets) {
279
+ const hits = hitsByPacket.get(packet.packetId);
280
+ if (!hits)
281
+ continue;
282
+ const mounted = [];
283
+ for (const { seg } of hits) {
284
+ const isOwner = owner.get(seg.segId) === packet.packetId;
285
+ if (!isOwner) {
286
+ // 跨包补全:非归属包保留 (cont.) 副本(段在本包窗口开始前已起始)
287
+ const hit = hits.find((h) => h.seg.segId === seg.segId);
288
+ const lo = packet.startMs - MOUNT_MARGIN_MS;
289
+ if (hit.overlapMs < CONT_MIN_OVERLAP_MS || seg.startMs >= lo)
290
+ continue;
291
+ mounted.push({
292
+ segId: seg.segId,
293
+ startMs: Math.max(seg.startMs, packet.startMs - MOUNT_MARGIN_MS),
294
+ endMs: seg.endMs,
295
+ text: `(cont.) ${seg.text}`,
296
+ source: seg.source,
297
+ alignedUnitIds: packet.unitIds
298
+ .filter((u) => u.timestampMs >= seg.startMs - MOUNT_MARGIN_MS && u.timestampMs <= seg.endMs + MOUNT_MARGIN_MS)
299
+ .map((u) => u.globalId)
300
+ .slice(0, 8),
301
+ });
302
+ continue;
303
+ }
304
+ mounted.push({
305
+ segId: seg.segId,
306
+ startMs: seg.startMs,
307
+ endMs: seg.endMs,
308
+ text: seg.text,
309
+ source: seg.source,
310
+ alignedUnitIds: packet.unitIds
311
+ .filter((u) => u.timestampMs >= seg.startMs - MOUNT_MARGIN_MS && u.timestampMs <= seg.endMs + MOUNT_MARGIN_MS)
312
+ .map((u) => u.globalId)
313
+ .slice(0, 8),
314
+ });
315
+ }
316
+ if (mounted.length > 0)
317
+ mounts.set(packet.packetId, { status, source, language, segments: mounted });
318
+ }
319
+ return mounts;
320
+ }
321
+ /** 提示行:`Audio @Packet #N: [12.1s-12.9s] "台词" | …(+2 more)`。 */
322
+ export function audioHintLine(packetId, mount) {
323
+ const parts = mount.segments.slice(0, MAX_HINT_SEGMENTS).map((seg) => `[${(seg.startMs / 1000).toFixed(1)}s-${(seg.endMs / 1000).toFixed(1)}s] "${seg.text}"`);
324
+ const more = mount.segments.length > MAX_HINT_SEGMENTS ? ` …(+${mount.segments.length - MAX_HINT_SEGMENTS} more)` : '';
325
+ return `Audio @Packet #${packetId}: ${parts.join(' | ')}${more}`;
326
+ }
327
+ /** 冷区引用行:`[Audio@#N] K segment(s) retained`。 */
328
+ export function coldRefAudioHintLine(sourcePacketId, count) {
329
+ return `[Audio@#${sourcePacketId}] ${count} segment${count === 1 ? '' : 's'} retained`;
330
+ }
331
+ /**
332
+ * 触发条件(全部满足):
333
+ * STATIC >10s;距上一张 F >3s;Σd_t(自上 F) >0.15;
334
+ * 存在密集语音岛(≥2s 或语速 >5cps),岛结束后 0.4s~5s 处于停顿谷底。
335
+ */
336
+ export function assistFocusShouldFire(ctx, tMs, staticSinceMs, lastFMs, sumD, firedIslandEnd) {
337
+ if (tMs - staticSinceMs < ASSIST_STATIC_MS)
338
+ return null;
339
+ if (lastFMs !== null && tMs - lastFMs < ASSIST_SINCE_F_MS)
340
+ return null;
341
+ if (sumD < ASSIST_MIN_SUM_D)
342
+ return null;
343
+ for (const [a, b] of ctx.islands) {
344
+ const dense = b - a >= ASSIST_DENSE_ISLAND_MS || (ctx.speechRate !== null && ctx.speechRate > ASSIST_DENSE_CPS);
345
+ if (!dense)
346
+ continue;
347
+ const afterPause = tMs - b;
348
+ if (afterPause >= ASSIST_PAUSE_AFTER_ISLAND_MS && afterPause <= ASSIST_ISLAND_RECENT_MS) {
349
+ if (firedIslandEnd !== null && firedIslandEnd >= b)
350
+ continue; // 同一岛只触发一次
351
+ return b;
352
+ }
353
+ }
354
+ return null;
355
+ }
356
+ export function sourceLabel(source, language) {
357
+ if (source === null)
358
+ return 'none';
359
+ const kind = source === 'external_subtitle' || source === 'embedded_subtitle' ? 'subtitles' : 'asr';
360
+ return language ? `${kind}:${language}` : kind;
361
+ }
362
+ //# sourceMappingURL=sidecar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../src/audio/sidecar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Stage A0 —— 字幕提取(外挂同名文件优先,内嵌软字幕次之)。
3
+ *
4
+ * 外挂:与视频同目录、同主文件名,扩展名 srt / vtt / ass / ssa,
5
+ * 允许中间语言段(base.zh.srt);语言优先级 zh > en > 其他。
6
+ * 内嵌:probe.subtitleStreams 中的文本字幕轨(排除位图轨),
7
+ * ffmpeg -map 0:s:N -f webvtt - 转出后统一按 VTT 解析。
8
+ */
9
+ import type { ProbeResult } from '../types.js';
10
+ import type { AudioSourceKind, SubtitleTimeline, TranscriptSegment } from './types.js';
11
+ /** 同目录外挂字幕候选扫描。 */
12
+ export declare function findExternalSubtitle(videoPath: string): Promise<string | null>;
13
+ /** 内嵌文本字幕轨选择(zh > en > 首轨;返回轨序号,不是流 index)。 */
14
+ export declare function pickEmbeddedSubtitle(probe: ProbeResult): {
15
+ ordinal: number;
16
+ language: string | null;
17
+ } | null;
18
+ /** 提取内嵌软字幕:转 webvtt 文本(PTS 毫秒由解析器恢复)。 */
19
+ export declare function extractEmbeddedSubtitle(videoPath: string, ordinal: number, ffmpegPath: string, signal?: AbortSignal | undefined): Promise<string>;
20
+ /** SRT 解析。 */
21
+ export declare function parseSrt(content: string, source: AudioSourceKind): TranscriptSegment[];
22
+ /** WebVTT 解析(含 ffmpeg 转出的 mov_text 副本)。 */
23
+ export declare function parseVtt(content: string, source: AudioSourceKind): TranscriptSegment[];
24
+ /** ASS/SSA 解析(Dialogue 行,第 10 列起为文本)。 */
25
+ export declare function parseAss(content: string, source: AudioSourceKind): TranscriptSegment[];
26
+ /** 按扩展名分派解析。 */
27
+ export declare function parseSubtitleFile(content: string, ext: string, source: AudioSourceKind): TranscriptSegment[];
28
+ /**
29
+ * A0 主入口:外挂 → 内嵌 → none。抛错由调用方转软降级状态。
30
+ */
31
+ export declare function loadSubtitleTimeline(videoPath: string, probe: ProbeResult, deps: {
32
+ ffmpegPath: string;
33
+ signal?: AbortSignal | undefined;
34
+ }): Promise<SubtitleTimeline>;
35
+ /** 窗口内的字幕段(闭区间相交即取)。 */
36
+ export declare function sliceSegments(segments: TranscriptSegment[], window: [number, number]): TranscriptSegment[];
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Stage A0 —— 字幕提取(外挂同名文件优先,内嵌软字幕次之)。
3
+ *
4
+ * 外挂:与视频同目录、同主文件名,扩展名 srt / vtt / ass / ssa,
5
+ * 允许中间语言段(base.zh.srt);语言优先级 zh > en > 其他。
6
+ * 内嵌:probe.subtitleStreams 中的文本字幕轨(排除位图轨),
7
+ * ffmpeg -map 0:s:N -f webvtt - 转出后统一按 VTT 解析。
8
+ */
9
+ import { readFile, readdir } from 'node:fs/promises';
10
+ import path from 'node:path';
11
+ import { execFile } from '../stage0/ffmpeg.js';
12
+ const SUBTITLE_EXTS = new Set(['srt', 'vtt', 'ass', 'ssa']);
13
+ /** ffprobe codec_name 中的文本字幕轨(其余为位图,跳过)。 */
14
+ const TEXT_SUBTITLE_CODECS = new Set([
15
+ 'subrip',
16
+ 'srt',
17
+ 'ass',
18
+ 'ssa',
19
+ 'webvtt',
20
+ 'mov_text',
21
+ 'text',
22
+ ]);
23
+ function languageRank(lang) {
24
+ const l = (lang ?? '').toLowerCase();
25
+ if (/^(zh|chi|zho|chs|cht)/.test(l))
26
+ return 0;
27
+ if (/^(en|eng)/.test(l))
28
+ return 1;
29
+ return 2;
30
+ }
31
+ /** 同目录外挂字幕候选扫描。 */
32
+ export async function findExternalSubtitle(videoPath) {
33
+ const dir = path.dirname(videoPath);
34
+ const base = path.basename(videoPath, path.extname(videoPath));
35
+ let entries;
36
+ try {
37
+ entries = await readdir(dir);
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ const candidates = [];
43
+ for (const entry of entries) {
44
+ const m = new RegExp(`^${escapeRegExp(base)}(?:\\.([\\w-]+))?\\.(srt|vtt|ass|ssa)$`, 'i').exec(entry);
45
+ if (!m)
46
+ continue;
47
+ const ext = (m[2] ?? '').toLowerCase();
48
+ if (!SUBTITLE_EXTS.has(ext))
49
+ continue;
50
+ candidates.push({
51
+ file: path.join(dir, entry),
52
+ langRank: m[1] ? languageRank(m[1]) : 2,
53
+ index: candidates.length,
54
+ });
55
+ }
56
+ const first = candidates[0];
57
+ if (first === undefined)
58
+ return null;
59
+ candidates.sort((a, b) => a.langRank - b.langRank || a.index - b.index);
60
+ return candidates[0] === undefined ? null : candidates[0].file;
61
+ }
62
+ function escapeRegExp(s) {
63
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
64
+ }
65
+ /** 内嵌文本字幕轨选择(zh > en > 首轨;返回轨序号,不是流 index)。 */
66
+ export function pickEmbeddedSubtitle(probe) {
67
+ const textTracks = probe.subtitleStreams
68
+ .map((s, i) => ({ ...s, ordinal: i }))
69
+ .filter((s) => TEXT_SUBTITLE_CODECS.has(s.codec.toLowerCase()));
70
+ if (textTracks.length === 0)
71
+ return null;
72
+ textTracks.sort((a, b) => languageRank(a.language) - languageRank(b.language) || a.ordinal - b.ordinal);
73
+ const best = textTracks[0];
74
+ return best === undefined ? null : { ordinal: best.ordinal, language: best.language ?? null };
75
+ }
76
+ /** 提取内嵌软字幕:转 webvtt 文本(PTS 毫秒由解析器恢复)。 */
77
+ export async function extractEmbeddedSubtitle(videoPath, ordinal, ffmpegPath, signal) {
78
+ const { stdout } = await execFile(ffmpegPath, ['-nostdin', '-i', videoPath, '-map', `0:s:${ordinal}`, '-f', 'webvtt', '-'], { encoding: 'utf8', timeoutMs: 60_000, signal });
79
+ return stdout;
80
+ }
81
+ function parseTimeToMs(text) {
82
+ const m = /(?:(\d+):)?(\d{1,2}):(\d{1,2})[.,](\d{1,3})/.exec(text);
83
+ if (!m)
84
+ return null;
85
+ const h = m[1] ? Number(m[1]) : 0;
86
+ return (((h * 60 + Number(m[2] ?? '0')) * 60 + Number(m[3] ?? '0')) * 1000 +
87
+ Number((m[4] ?? '0').padEnd(3, '0')));
88
+ }
89
+ /** SRT 解析。 */
90
+ export function parseSrt(content, source) {
91
+ const out = [];
92
+ const blocks = content.replace(/\r\n/g, '\n').split(/\n{2,}/);
93
+ for (const block of blocks) {
94
+ const lines = block.split('\n').filter((l) => l.trim().length > 0);
95
+ if (lines.length === 0)
96
+ continue;
97
+ const timeLine = lines.find((l) => l.includes('-->'));
98
+ if (!timeLine)
99
+ continue;
100
+ const [a, b] = timeLine.split('-->');
101
+ const start = parseTimeToMs(a ?? '');
102
+ const end = parseTimeToMs(b ?? '');
103
+ if (start === null || end === null || end <= start)
104
+ continue;
105
+ const textLines = lines.filter((l) => l !== timeLine && !/^\d+$/.test(l.trim()));
106
+ const text = textLines.join(' ').trim();
107
+ if (!text)
108
+ continue;
109
+ out.push({ segId: out.length + 1, startMs: start, endMs: end, text, source });
110
+ }
111
+ return renumber(out);
112
+ }
113
+ /** WebVTT 解析(含 ffmpeg 转出的 mov_text 副本)。 */
114
+ export function parseVtt(content, source) {
115
+ const body = content.replace(/\r\n/g, '\n');
116
+ const out = [];
117
+ const cueRe = /((?:\d+:)?\d{1,2}:\d{1,2}\.\d{1,3})\s*-->\s*((?:\d+:)?\d{1,2}:\d{1,2}\.\d{1,3})[^\n]*\n([\s\S]*?)(?=\n{2,}|$)/g;
118
+ let m;
119
+ while ((m = cueRe.exec(body)) !== null) {
120
+ const start = parseTimeToMs(m[1] ?? '');
121
+ const end = parseTimeToMs(m[2] ?? '');
122
+ if (start === null || end === null || end <= start)
123
+ continue;
124
+ const text = (m[3] ?? '')
125
+ .split('\n')
126
+ .map(stripVttMarkup)
127
+ .join(' ')
128
+ .trim();
129
+ if (!text)
130
+ continue;
131
+ out.push({ segId: out.length + 1, startMs: start, endMs: end, text, source });
132
+ }
133
+ return renumber(out);
134
+ }
135
+ function stripVttMarkup(line) {
136
+ return line.replace(/<[^>]+>/g, '').trim();
137
+ }
138
+ /** ASS/SSA 解析(Dialogue 行,第 10 列起为文本)。 */
139
+ export function parseAss(content, source) {
140
+ const out = [];
141
+ const lines = content.split(/\r?\n/);
142
+ for (const line of lines) {
143
+ if (!line.startsWith('Dialogue:'))
144
+ continue;
145
+ const cells = line.slice('Dialogue:'.length).split(',');
146
+ if (cells.length < 10)
147
+ continue;
148
+ const start = parseAssClock(cells[1] ?? '');
149
+ const end = parseAssClock(cells[2] ?? '');
150
+ if (start === null || end === null || end <= start)
151
+ continue;
152
+ const text = cells
153
+ .slice(9)
154
+ .join(',')
155
+ .replace(/\{[^}]*\}/g, '')
156
+ .replace(/\\N|\\n/g, ' ')
157
+ .trim();
158
+ if (!text)
159
+ continue;
160
+ out.push({ segId: out.length + 1, startMs: start, endMs: end, text, source });
161
+ }
162
+ return renumber(out);
163
+ }
164
+ function parseAssClock(text) {
165
+ const m = /(\d+):(\d{1,2}):(\d{1,2})\.(\d{1,2})/.exec(text);
166
+ if (!m)
167
+ return null;
168
+ return ((Number(m[1] ?? '0') * 3600 + Number(m[2] ?? '0') * 60 + Number(m[3] ?? '0')) * 1000 +
169
+ Number((m[4] ?? '0').padEnd(3, '0')));
170
+ }
171
+ function renumber(segs) {
172
+ return segs.map((s, i) => ({ ...s, segId: i + 1 }));
173
+ }
174
+ /** 按扩展名分派解析。 */
175
+ export function parseSubtitleFile(content, ext, source) {
176
+ switch (ext.toLowerCase()) {
177
+ case 'srt':
178
+ return parseSrt(content, source);
179
+ case 'vtt':
180
+ return parseVtt(content, source);
181
+ case 'ass':
182
+ case 'ssa':
183
+ return parseAss(content, source);
184
+ default:
185
+ return [];
186
+ }
187
+ }
188
+ function languageOfExternal(file) {
189
+ const m = /\.([\w-]+)\.(srt|vtt|ass|ssa)$/i.exec(file);
190
+ return m !== null ? (m[1] ?? null) : null;
191
+ }
192
+ /**
193
+ * A0 主入口:外挂 → 内嵌 → none。抛错由调用方转软降级状态。
194
+ */
195
+ export async function loadSubtitleTimeline(videoPath, probe, deps) {
196
+ const external = await findExternalSubtitle(videoPath);
197
+ if (external) {
198
+ const content = await readFile(external, 'utf8');
199
+ const segments = parseSubtitleFile(content, path.extname(external).slice(1), 'external_subtitle');
200
+ if (segments.length > 0) {
201
+ return { status: 'external_subtitle', language: languageOfExternal(external), segments };
202
+ }
203
+ }
204
+ const embedded = pickEmbeddedSubtitle(probe);
205
+ if (embedded) {
206
+ const vtt = await extractEmbeddedSubtitle(videoPath, embedded.ordinal, deps.ffmpegPath, deps.signal);
207
+ const segments = parseVtt(vtt, 'embedded_subtitle');
208
+ if (segments.length > 0) {
209
+ return { status: 'embedded_subtitle', language: embedded.language, segments };
210
+ }
211
+ }
212
+ return { status: 'none', language: null, segments: [] };
213
+ }
214
+ /** 窗口内的字幕段(闭区间相交即取)。 */
215
+ export function sliceSegments(segments, window) {
216
+ return segments.filter((s) => s.endMs > window[0] && s.startMs < window[1]);
217
+ }
218
+ //# sourceMappingURL=subtitleExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subtitleExtractor.js","sourceRoot":"","sources":["../../src/audio/subtitleExtractor.ts"],"names":[],"mappings":"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"}