@remotion/install-whisper-cpp 4.0.124 → 4.0.126

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.
@@ -0,0 +1,11 @@
1
+ declare const models: readonly ["tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium", "medium.en", "large-v1", "large-v2", "large-v3"];
2
+ export type WhisperModel = (typeof models)[number];
3
+ export declare const downloadWhisperModel: ({ model, folder, printOutput, onProgress, }: {
4
+ model: WhisperModel;
5
+ folder: string;
6
+ printOutput?: boolean | undefined;
7
+ onProgress?: ((downloadedBytes: number, totalBytes: number) => void) | undefined;
8
+ }) => Promise<{
9
+ alreadyExisted: boolean;
10
+ }>;
11
+ export {};
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.downloadWhisperModel = void 0;
30
+ const path_1 = __importDefault(require("path"));
31
+ const fs_1 = __importStar(require("fs"));
32
+ const promises_1 = require("node:stream/promises");
33
+ const node_stream_1 = require("node:stream");
34
+ const models = [
35
+ "tiny",
36
+ "tiny.en",
37
+ "base",
38
+ "base.en",
39
+ "small",
40
+ "small.en",
41
+ "medium",
42
+ "medium.en",
43
+ "large-v1",
44
+ "large-v2",
45
+ "large-v3",
46
+ ];
47
+ const downloadWhisperModel = async ({ model, folder, printOutput = true, onProgress, }) => {
48
+ if (!models.includes(model)) {
49
+ throw new Error(`Invalid whisper model ${model}. Available: ${models.join(", ")}`);
50
+ }
51
+ const filePath = path_1.default.join(folder, `ggml-${model}.bin`);
52
+ if ((0, fs_1.existsSync)(filePath)) {
53
+ if (printOutput) {
54
+ console.log(`Model already exists at ${filePath}`);
55
+ }
56
+ return Promise.resolve({ alreadyExisted: true });
57
+ }
58
+ const baseModelUrl = `https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-${model}.bin`;
59
+ if (printOutput) {
60
+ console.log(`Downloading whisper model ${model} from ${baseModelUrl}`);
61
+ }
62
+ const fileStream = fs_1.default.createWriteStream(filePath);
63
+ const { body, headers } = await fetch(baseModelUrl);
64
+ const contentLength = headers.get("content-length");
65
+ if (body === null) {
66
+ throw new Error("Failed to download whisper model");
67
+ }
68
+ if (contentLength === null) {
69
+ throw new Error("Content-Length header not found");
70
+ }
71
+ let downloaded = 0;
72
+ let lastPrinted = 0;
73
+ const readable = node_stream_1.Readable.fromWeb(body);
74
+ readable.on("data", (chunk) => {
75
+ downloaded += chunk.length;
76
+ if (printOutput) {
77
+ if (downloaded - lastPrinted > 1024 * 1024 * 10) {
78
+ console.log(`Downloaded ${downloaded} of ${contentLength} bytes (${((downloaded / Number(contentLength)) *
79
+ 100).toFixed(2)}%)`);
80
+ lastPrinted = downloaded;
81
+ }
82
+ }
83
+ fileStream.write(chunk);
84
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress(downloaded, parseInt(contentLength, 10));
85
+ });
86
+ await (0, promises_1.finished)(readable);
87
+ return { alreadyExisted: false };
88
+ };
89
+ exports.downloadWhisperModel = downloadWhisperModel;
@@ -1,6 +1,7 @@
1
1
  declare const models: readonly ["tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium", "medium.en", "large-v1", "large-v2", "large-v3"];
2
2
  export type WhisperModel = (typeof models)[number];
3
3
  export type OnProgress = (downloadedBytes: number, totalBytes: number) => void;
4
+ export declare const getModelPath: (folder: string, model: WhisperModel) => string;
4
5
  export declare const downloadWhisperModel: ({ model, folder, printOutput, onProgress, }: {
5
6
  model: WhisperModel;
6
7
  folder: string;
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.downloadWhisperModel = void 0;
29
+ exports.downloadWhisperModel = exports.getModelPath = void 0;
30
30
  const fs_1 = __importStar(require("fs"));
31
31
  const node_stream_1 = require("node:stream");
32
32
  const path_1 = __importDefault(require("path"));
@@ -43,11 +43,15 @@ const models = [
43
43
  'large-v2',
44
44
  'large-v3',
45
45
  ];
46
+ const getModelPath = (folder, model) => {
47
+ return path_1.default.join(folder, `ggml-${model}.bin`);
48
+ };
49
+ exports.getModelPath = getModelPath;
46
50
  const downloadWhisperModel = async ({ model, folder, printOutput = true, onProgress, }) => {
47
51
  if (!models.includes(model)) {
48
52
  throw new Error(`Invalid whisper model ${model}. Available: ${models.join(', ')}`);
49
53
  }
50
- const filePath = path_1.default.join(folder, `ggml-${model}.bin`);
54
+ const filePath = (0, exports.getModelPath)(folder, model);
51
55
  if ((0, fs_1.existsSync)(filePath)) {
52
56
  if (printOutput) {
53
57
  console.log(`Model already exists at ${filePath}`);
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { downloadWhisperModel, OnProgress, WhisperModel, } from './download-whisper-model';
2
2
  export { installWhisperCpp } from './install-whisper-cpp';
3
+ export { transcribe } from './transcribe';
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.installWhisperCpp = exports.downloadWhisperModel = void 0;
3
+ exports.transcribe = exports.installWhisperCpp = exports.downloadWhisperModel = void 0;
4
4
  var download_whisper_model_1 = require("./download-whisper-model");
5
5
  Object.defineProperty(exports, "downloadWhisperModel", { enumerable: true, get: function () { return download_whisper_model_1.downloadWhisperModel; } });
6
6
  var install_whisper_cpp_1 = require("./install-whisper-cpp");
7
7
  Object.defineProperty(exports, "installWhisperCpp", { enumerable: true, get: function () { return install_whisper_cpp_1.installWhisperCpp; } });
8
+ var transcribe_1 = require("./transcribe");
9
+ Object.defineProperty(exports, "transcribe", { enumerable: true, get: function () { return transcribe_1.transcribe; } });
@@ -0,0 +1,7 @@
1
+ export declare const installWhisper: ({ version, to, printOutput, }: {
2
+ version: string;
3
+ to: string;
4
+ printOutput?: boolean | undefined;
5
+ }) => Promise<{
6
+ alreadyExisted: boolean;
7
+ }>;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.installWhisper = void 0;
30
+ const fs_1 = __importStar(require("fs"));
31
+ const node_child_process_1 = require("node:child_process");
32
+ const node_stream_1 = require("node:stream");
33
+ const promises_1 = require("node:stream/promises");
34
+ const path_1 = __importDefault(require("path"));
35
+ const installForWindows = async ({ version, to, printOutput, }) => {
36
+ const url = `https://github.com/ggerganov/whisper.cpp/releases/download/v${version}/whisper-bin-x64.zip`;
37
+ const filePath = path_1.default.join(process.cwd(), "whisper-bin-x64.zip");
38
+ const fileStream = fs_1.default.createWriteStream(filePath);
39
+ const { body } = await fetch(url);
40
+ if (body === null) {
41
+ throw new Error("Failed to download whisper binary");
42
+ }
43
+ await (0, promises_1.finished)(node_stream_1.Readable.fromWeb(body).pipe(fileStream));
44
+ (0, node_child_process_1.execSync)(`Expand-Archive -Force ${filePath} ${to}`, {
45
+ shell: "powershell",
46
+ stdio: printOutput ? "inherit" : "ignore",
47
+ });
48
+ (0, fs_1.rmSync)(filePath);
49
+ };
50
+ const installWhisperForUnix = ({ version, to, printOutput, }) => {
51
+ const stdio = printOutput ? "inherit" : "ignore";
52
+ (0, node_child_process_1.execSync)(`git clone https://github.com/ggerganov/whisper.cpp.git ${to}`, {
53
+ stdio,
54
+ });
55
+ (0, node_child_process_1.execSync)(`git checkout v${version}`, {
56
+ stdio,
57
+ cwd: to,
58
+ });
59
+ (0, node_child_process_1.execSync)(`make`, {
60
+ cwd: to,
61
+ stdio,
62
+ });
63
+ };
64
+ const installWhisper = async ({ version, to, printOutput = true, }) => {
65
+ if ((0, fs_1.existsSync)(to)) {
66
+ if (printOutput) {
67
+ console.log(`Whisper already exists at ${to}`);
68
+ }
69
+ return Promise.resolve({ alreadyExisted: true });
70
+ }
71
+ if (process.platform === "darwin" || process.platform === "linux") {
72
+ installWhisperForUnix({ version, to, printOutput });
73
+ return Promise.resolve({ alreadyExisted: false });
74
+ }
75
+ if (process.platform === "win32") {
76
+ await installForWindows({ version, to, printOutput });
77
+ return Promise.resolve({ alreadyExisted: false });
78
+ }
79
+ throw new Error(`Unsupported platform: ${process.platform}`);
80
+ };
81
+ exports.installWhisper = installWhisper;
@@ -0,0 +1,56 @@
1
+ import type { WhisperModel } from './download-whisper-model';
2
+ type Timestamps = {
3
+ from: string;
4
+ to: string;
5
+ };
6
+ type Offsets = {
7
+ from: number;
8
+ to: number;
9
+ };
10
+ type TranscriptionItem = {
11
+ timestamps: Timestamps;
12
+ offsets: Offsets;
13
+ text: string;
14
+ };
15
+ type Model = {
16
+ type: string;
17
+ multilingual: boolean;
18
+ vocab: number;
19
+ audio: {
20
+ ctx: number;
21
+ state: number;
22
+ head: number;
23
+ layer: number;
24
+ };
25
+ text: {
26
+ ctx: number;
27
+ state: number;
28
+ head: number;
29
+ layer: number;
30
+ };
31
+ mels: number;
32
+ ftype: number;
33
+ };
34
+ type Params = {
35
+ model: string;
36
+ language: string;
37
+ translate: boolean;
38
+ };
39
+ type Result = {
40
+ language: string;
41
+ };
42
+ export type TranscriptionJson = {
43
+ systeminfo: string;
44
+ model: Model;
45
+ params: Params;
46
+ result: Result;
47
+ transcription: TranscriptionItem[];
48
+ };
49
+ export declare const transcribe: ({ inputPath, whisperPath, model, modelFolder, translateToEnglish, }: {
50
+ inputPath: string;
51
+ whisperPath: string;
52
+ model: WhisperModel;
53
+ modelFolder?: string | undefined;
54
+ translateToEnglish?: boolean | undefined;
55
+ }) => Promise<TranscriptionJson>;
56
+ export {};
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.transcribe = void 0;
30
+ const node_child_process_1 = require("node:child_process");
31
+ const node_fs_1 = __importStar(require("node:fs"));
32
+ const node_os_1 = __importDefault(require("node:os"));
33
+ const node_path_1 = __importDefault(require("node:path"));
34
+ const node_util_1 = __importDefault(require("node:util"));
35
+ const download_whisper_model_1 = require("./download-whisper-model");
36
+ const isWavFile = (inputPath) => {
37
+ const splitted = inputPath.split('.');
38
+ if (!splitted) {
39
+ return false;
40
+ }
41
+ return splitted[splitted.length - 1] === 'wav';
42
+ };
43
+ const readJson = async (jsonPath) => {
44
+ const data = await node_fs_1.default.promises.readFile(jsonPath, 'utf8');
45
+ const jsonData = await JSON.parse(data);
46
+ return jsonData;
47
+ };
48
+ const transcribeToTempJSON = async ({ fileToTranscribe, whisperPath, model, tmpJSONPath, modelFolder, translate, }) => {
49
+ const promisifiedExec = node_util_1.default.promisify(node_child_process_1.exec);
50
+ const modelPath = (0, download_whisper_model_1.getModelPath)(modelFolder !== null && modelFolder !== void 0 ? modelFolder : whisperPath, model);
51
+ 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`);
53
+ }
54
+ const executable = node_os_1.default.platform() === 'win32'
55
+ ? node_path_1.default.join(whisperPath, 'main.exe')
56
+ : 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
+ }
63
+ });
64
+ };
65
+ const transcribe = async ({ inputPath, whisperPath, model, modelFolder, translateToEnglish = false, }) => {
66
+ if (!(0, node_fs_1.existsSync)(whisperPath)) {
67
+ 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
+ }
69
+ if (!(0, node_fs_1.existsSync)(inputPath)) {
70
+ throw new Error(`Input file does not exist at ${inputPath}`);
71
+ }
72
+ if (!isWavFile(inputPath)) {
73
+ throw new Error('Invalid inputFile type. The provided file is not a wav file!');
74
+ }
75
+ const tmpJSONDir = node_path_1.default.join(process.cwd(), 'tmp');
76
+ await transcribeToTempJSON({
77
+ fileToTranscribe: inputPath,
78
+ whisperPath,
79
+ model,
80
+ tmpJSONPath: tmpJSONDir,
81
+ modelFolder: modelFolder !== null && modelFolder !== void 0 ? modelFolder : null,
82
+ translate: translateToEnglish,
83
+ });
84
+ const tmpJSONPath = `${tmpJSONDir}.json`;
85
+ const json = (await readJson(tmpJSONPath));
86
+ node_fs_1.default.unlinkSync(tmpJSONPath);
87
+ return json;
88
+ };
89
+ exports.transcribe = transcribe;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/install-whisper-cpp",
3
- "version": "4.0.124",
3
+ "version": "4.0.126",
4
4
  "description": "Install helper for Whisper.cpp",
5
5
  "main": "dist/index.js",
6
6
  "sideEffects": false,