mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-09-10 17:16:20 -07:00
- Generate Japanese SRTs through the overlay modal or launcher - Support managed whisper.cpp models and optional dialogue detection
87 lines
2.5 KiB
TypeScript
87 lines
2.5 KiB
TypeScript
import {
|
|
isSubtitleGenerationModelId,
|
|
RECOMMENDED_SUBTITLE_GENERATION_MODEL,
|
|
type SubtitleGenerationModelId,
|
|
} from './subtitle-generation-model-catalog';
|
|
|
|
export interface SubtitleGenerationConfig {
|
|
whisperPath: string;
|
|
modelPath: string;
|
|
managedModel: SubtitleGenerationModelId;
|
|
threads: number;
|
|
ffmpegPath: string;
|
|
ffprobePath: string;
|
|
vadModelPath: string;
|
|
vadPath: string;
|
|
}
|
|
|
|
export const DEFAULT_SUBTITLE_GENERATION_CONFIG: SubtitleGenerationConfig = {
|
|
whisperPath: '',
|
|
modelPath: '',
|
|
managedModel: RECOMMENDED_SUBTITLE_GENERATION_MODEL,
|
|
threads: 4,
|
|
ffmpegPath: '',
|
|
ffprobePath: '',
|
|
vadModelPath: '',
|
|
vadPath: '',
|
|
};
|
|
|
|
export interface SubtitleGenerationProgress {
|
|
stage: 'download' | 'extract' | 'transcribe' | 'write';
|
|
percent?: number;
|
|
message: string;
|
|
}
|
|
|
|
export type SubtitleGenerationModelStatus =
|
|
| { kind: 'external' | 'managed'; path: string }
|
|
| { kind: 'missing'; path: string }
|
|
| { kind: 'invalid'; path: string; message: string };
|
|
|
|
export function resolveSubtitleGenerationConfig(
|
|
value: unknown,
|
|
onWarning?: (key: string, value: unknown, message: string) => void,
|
|
): SubtitleGenerationConfig {
|
|
const result = { ...DEFAULT_SUBTITLE_GENERATION_CONFIG };
|
|
if (value === undefined) return result;
|
|
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
onWarning?.('subtitleGeneration', value, 'Expected an object.');
|
|
return result;
|
|
}
|
|
for (const [key, rawValue] of Object.entries(value)) {
|
|
if (
|
|
key !== 'whisperPath' &&
|
|
key !== 'modelPath' &&
|
|
key !== 'ffmpegPath' &&
|
|
key !== 'ffprobePath' &&
|
|
key !== 'vadModelPath' &&
|
|
key !== 'vadPath'
|
|
)
|
|
continue;
|
|
const candidate: unknown = rawValue;
|
|
if (typeof candidate === 'string') {
|
|
result[key] = candidate.trim();
|
|
} else onWarning?.(key, candidate, 'Expected a string.');
|
|
}
|
|
if ('managedModel' in value) {
|
|
if (isSubtitleGenerationModelId(value.managedModel)) {
|
|
result.managedModel = value.managedModel;
|
|
} else
|
|
onWarning?.(
|
|
'managedModel',
|
|
value.managedModel,
|
|
'Expected a supported multilingual Whisper model.',
|
|
);
|
|
}
|
|
if ('threads' in value) {
|
|
if (
|
|
typeof value.threads === 'number' &&
|
|
Number.isInteger(value.threads) &&
|
|
value.threads >= 1 &&
|
|
value.threads <= 256
|
|
) {
|
|
result.threads = value.threads;
|
|
} else onWarning?.('threads', value.threads, 'Expected an integer between 1 and 256.');
|
|
}
|
|
return result;
|
|
}
|