@remotion/install-whisper-cpp 4.0.129 → 4.0.131

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.
@@ -7,11 +7,22 @@ type Offsets = {
7
7
  from: number;
8
8
  to: number;
9
9
  };
10
+ type WordLevelToken = {
11
+ t_dtw: number;
12
+ text: string;
13
+ timestamps: Timestamps;
14
+ offsets: Offsets;
15
+ id: number;
16
+ p: number;
17
+ };
10
18
  type TranscriptionItem = {
11
19
  timestamps: Timestamps;
12
20
  offsets: Offsets;
13
21
  text: string;
14
22
  };
23
+ type TranscriptionItemWithTimestamp = TranscriptionItem & {
24
+ tokens: WordLevelToken[];
25
+ };
15
26
  type Model = {
16
27
  type: string;
17
28
  multilingual: boolean;
@@ -39,18 +50,19 @@ type Params = {
39
50
  type Result = {
40
51
  language: string;
41
52
  };
42
- export type TranscriptionJson = {
53
+ export type TranscriptionJson<WithTokenLevelTimestamp extends boolean> = {
43
54
  systeminfo: string;
44
55
  model: Model;
45
56
  params: Params;
46
57
  result: Result;
47
- transcription: TranscriptionItem[];
58
+ transcription: true extends WithTokenLevelTimestamp ? TranscriptionItemWithTimestamp[] : TranscriptionItem[];
48
59
  };
49
- export declare const transcribe: ({ inputPath, whisperPath, model, modelFolder, translateToEnglish, }: {
60
+ export declare const transcribe: <HasTokenLevelTimestamps extends boolean>({ inputPath, whisperPath, model, modelFolder, translateToEnglish, tokenLevelTimestamps, }: {
50
61
  inputPath: string;
51
62
  whisperPath: string;
52
63
  model: WhisperModel;
64
+ tokenLevelTimestamps: HasTokenLevelTimestamps;
53
65
  modelFolder?: string | undefined;
54
66
  translateToEnglish?: boolean | undefined;
55
- }) => Promise<TranscriptionJson>;
67
+ }) => Promise<TranscriptionJson<HasTokenLevelTimestamps>>;
56
68
  export {};
@@ -31,7 +31,6 @@ const node_child_process_1 = require("node:child_process");
31
31
  const node_fs_1 = __importStar(require("node:fs"));
32
32
  const node_os_1 = __importDefault(require("node:os"));
33
33
  const node_path_1 = __importDefault(require("node:path"));
34
- const node_util_1 = __importDefault(require("node:util"));
35
34
  const download_whisper_model_1 = require("./download-whisper-model");
36
35
  const isWavFile = (inputPath) => {
37
36
  const splitted = inputPath.split('.');
@@ -42,27 +41,58 @@ const isWavFile = (inputPath) => {
42
41
  };
43
42
  const readJson = async (jsonPath) => {
44
43
  const data = await node_fs_1.default.promises.readFile(jsonPath, 'utf8');
45
- const jsonData = await JSON.parse(data);
46
- return jsonData;
44
+ return JSON.parse(data);
47
45
  };
48
- const transcribeToTempJSON = async ({ fileToTranscribe, whisperPath, model, tmpJSONPath, modelFolder, translate, }) => {
49
- const promisifiedExec = node_util_1.default.promisify(node_child_process_1.exec);
46
+ const transcribeToTempJSON = async ({ fileToTranscribe, whisperPath, model, tmpJSONPath, modelFolder, translate, tokenLevelTimestamps, }) => {
50
47
  const modelPath = (0, download_whisper_model_1.getModelPath)(modelFolder !== null && modelFolder !== void 0 ? modelFolder : whisperPath, model);
51
48
  if (!node_fs_1.default.existsSync(modelPath)) {
52
- throw new Error(`Error: Model ${model} does not exist at ${modelFolder ? modelFolder : modelPath}. Check out the downloadWhisperMode() API at https://www.remotion.dev/docs/install-whisper-cpp/download-whisper-model to see how to install whisper models`);
49
+ throw new Error(`Error: Model ${model} does not exist at ${modelFolder ? modelFolder : modelPath}. Check out the downloadWhisperModel() API at https://www.remotion.dev/docs/install-whisper-cpp/download-whisper-model to see how to install whisper models`);
53
50
  }
54
51
  const executable = node_os_1.default.platform() === 'win32'
55
52
  ? node_path_1.default.join(whisperPath, 'main.exe')
56
53
  : node_path_1.default.join(whisperPath, './main');
57
- const modelOption = model ? `-m ${modelPath}` : '';
58
- const translateOption = translate ? `-tr ` : '';
59
- await promisifiedExec(`${executable} -f ${fileToTranscribe} --output-file ${tmpJSONPath} --output-json --max-len 1 ${modelOption} ${translateOption}`, { cwd: whisperPath }).then(({ stderr }) => {
60
- if (stderr.includes('error')) {
61
- throw new Error('An error occured while transcribing: ' + stderr);
62
- }
54
+ const args = [
55
+ '-f',
56
+ fileToTranscribe,
57
+ '--output-file',
58
+ tmpJSONPath,
59
+ '--output-json',
60
+ '--max-len',
61
+ '1',
62
+ '-ofj',
63
+ tokenLevelTimestamps ? ['--dtw', model] : null,
64
+ model ? [`-m`, `${modelPath}`] : null,
65
+ translate ? '-tr' : null,
66
+ ]
67
+ .flat(1)
68
+ .filter(Boolean);
69
+ const outputPath = await new Promise((resolve, reject) => {
70
+ const task = (0, node_child_process_1.spawn)(executable, args, { cwd: whisperPath });
71
+ const predictedPath = `${tmpJSONPath}.json`;
72
+ let output = '';
73
+ const onData = (data) => {
74
+ const str = data.toString('utf-8');
75
+ output += str;
76
+ // Sometimes it hangs here
77
+ if (str.includes('ggml_metal_free: deallocating')) {
78
+ task.kill();
79
+ }
80
+ };
81
+ task.stdout.on('data', onData);
82
+ task.stderr.on('data', onData);
83
+ task.on('exit', (code) => {
84
+ // Whisper sometimes files also with error code 0
85
+ // https://github.com/ggerganov/whisper.cpp/pull/1952/files
86
+ if ((0, node_fs_1.existsSync)(predictedPath)) {
87
+ resolve(predictedPath);
88
+ return;
89
+ }
90
+ reject(new Error(`No transcription was created (process exited with code ${code}): ${output}`));
91
+ });
63
92
  });
93
+ return { outputPath };
64
94
  };
65
- const transcribe = async ({ inputPath, whisperPath, model, modelFolder, translateToEnglish = false, }) => {
95
+ const transcribe = async ({ inputPath, whisperPath, model, modelFolder, translateToEnglish = false, tokenLevelTimestamps, }) => {
66
96
  if (!(0, node_fs_1.existsSync)(whisperPath)) {
67
97
  throw new Error(`Whisper does not exist at ${whisperPath}. Double-check the passed whisperPath. If you havent installed whisper, check out the installWhisperCpp() API at https://www.remotion.dev/docs/install-whisper-cpp/install-whisper-cpp to see how to install whisper programatically.`);
68
98
  }
@@ -73,15 +103,15 @@ const transcribe = async ({ inputPath, whisperPath, model, modelFolder, translat
73
103
  throw new Error('Invalid inputFile type. The provided file is not a wav file!');
74
104
  }
75
105
  const tmpJSONDir = node_path_1.default.join(process.cwd(), 'tmp');
76
- await transcribeToTempJSON({
106
+ const { outputPath: tmpJSONPath } = await transcribeToTempJSON({
77
107
  fileToTranscribe: inputPath,
78
108
  whisperPath,
79
109
  model,
80
110
  tmpJSONPath: tmpJSONDir,
81
111
  modelFolder: modelFolder !== null && modelFolder !== void 0 ? modelFolder : null,
82
112
  translate: translateToEnglish,
113
+ tokenLevelTimestamps,
83
114
  });
84
- const tmpJSONPath = `${tmpJSONDir}.json`;
85
115
  const json = (await readJson(tmpJSONPath));
86
116
  node_fs_1.default.unlinkSync(tmpJSONPath);
87
117
  return json;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/install-whisper-cpp",
3
- "version": "4.0.129",
3
+ "version": "4.0.131",
4
4
  "description": "Install helper for Whisper.cpp",
5
5
  "main": "dist/index.js",
6
6
  "sideEffects": false,
@@ -43,6 +43,7 @@
43
43
  "formatting": "prettier src --check",
44
44
  "lint": "eslint src --ext ts,tsx",
45
45
  "build": "tsc -d",
46
- "watch": "tsc -w"
46
+ "watch": "tsc -w",
47
+ "test": "vitest --run"
47
48
  }
48
49
  }