From 3e23840306c6d5174d418280e4300997cde4d5d4 Mon Sep 17 00:00:00 2001 From: Adam Jones Date: Mon, 6 Jan 2025 00:56:15 +0000 Subject: [PATCH 1/6] fix: ensure models run using correct binary paths --- src/WhisperHelper.ts | 6 +++--- src/autoDownloadModel.ts | 6 +++--- src/constants.ts | 5 +++++ src/downloadModel.ts | 6 +++--- src/whisper.ts | 6 +----- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/WhisperHelper.ts b/src/WhisperHelper.ts index 066b5db..39cdee3 100644 --- a/src/WhisperHelper.ts +++ b/src/WhisperHelper.ts @@ -1,7 +1,7 @@ import path from 'path' import fs from 'fs' -import { MODELS, MODELS_LIST, MODEL_OBJECT } from './constants' +import { MODELS_LIST, MODEL_OBJECT, WHISPER_CPP_PATH, WHISPER_CPP_MAIN_PATH } from './constants' import { IOptions } from '.' export const constructCommand = (filePath: string, args: IOptions): string => { @@ -15,7 +15,7 @@ export const constructCommand = (filePath: string, args: IOptions): string => { errors.push(`[Nodejs-whisper] Error: Enter a valid model name. Available models are: ${MODELS_LIST.join(', ')}`) } - const modelPath = path.join(__dirname, '..', 'cpp', 'whisper.cpp', 'models', MODEL_OBJECT[args.modelName]) + const modelPath = path.join(WHISPER_CPP_PATH, 'models', MODEL_OBJECT[args.modelName]) if (!fs.existsSync(modelPath)) { errors.push( '[Nodejs-whisper] Error: Model file does not exist. Please ensure the model is downloaded and correctly placed.' @@ -27,7 +27,7 @@ export const constructCommand = (filePath: string, args: IOptions): string => { } const modelName = MODEL_OBJECT[args.modelName as keyof typeof MODEL_OBJECT] - let command = `./main ${constructOptionsFlags(args)} -l ${args.whisperOptions?.language ? args.whisperOptions?.language : 'auto'} -m "./models/${modelName}" -f "${filePath}"` + let command = `${WHISPER_CPP_MAIN_PATH} ${constructOptionsFlags(args)} -l ${args.whisperOptions?.language ? args.whisperOptions?.language : 'auto'} -m "./models/${modelName}" -f "${filePath}"` return command } diff --git a/src/autoDownloadModel.ts b/src/autoDownloadModel.ts index feadaaf..ba05c9e 100644 --- a/src/autoDownloadModel.ts +++ b/src/autoDownloadModel.ts @@ -1,7 +1,7 @@ import path from 'path' import shell from 'shelljs' import fs from 'fs' -import { MODELS_LIST, MODELS } from './constants' +import { MODEL_OBJECT, MODELS_LIST, WHISPER_CPP_PATH } from './constants' export default async function autoDownloadModel( logger = console, @@ -19,9 +19,9 @@ export default async function autoDownloadModel( } try { - const modelDirectory = path.join(__dirname, '..', 'cpp', 'whisper.cpp', 'models') + const modelDirectory = path.join(WHISPER_CPP_PATH, 'models') shell.cd(modelDirectory) - const modelAlreadyExist = fs.existsSync(path.join(modelDirectory, autoDownloadModelName)) + const modelAlreadyExist = fs.existsSync(path.join(modelDirectory, MODEL_OBJECT[autoDownloadModelName])) if (modelAlreadyExist) { logger.debug(`[Nodejs-whisper] ${autoDownloadModel} already exist. Skipping download.`) diff --git a/src/constants.ts b/src/constants.ts index 716a8fc..5bff674 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,5 @@ +import path from 'path' + export const MODELS_LIST = [ 'tiny', 'tiny.en', @@ -41,3 +43,6 @@ export const MODEL_OBJECT = { } export const DEFAULT_MODEL = 'tiny.en' + +export const WHISPER_CPP_PATH = path.join(__dirname, '..', 'cpp', 'whisper.cpp') +export const WHISPER_CPP_MAIN_PATH = './build/bin/whisper-cli' diff --git a/src/downloadModel.ts b/src/downloadModel.ts index afdd3d9..03f51db 100644 --- a/src/downloadModel.ts +++ b/src/downloadModel.ts @@ -5,7 +5,7 @@ import path from 'path' import shell from 'shelljs' import readlineSync from 'readline-sync' -import { MODELS_LIST, DEFAULT_MODEL, MODELS } from './constants' +import { MODELS_LIST, DEFAULT_MODEL, MODELS, WHISPER_CPP_PATH, MODEL_OBJECT } from './constants' import fs from 'fs' const askForModel = async (logger = console): Promise => { @@ -48,12 +48,12 @@ const askIfUserWantToUseCuda = async (logger = console) => { async function downloadModel(logger = console) { try { - shell.cd(path.join(__dirname, '..', './cpp/whisper.cpp/models')) + shell.cd(path.join(WHISPER_CPP_PATH, 'models')) let anyModelExist = [] MODELS.forEach(model => { - if (!fs.existsSync(path.join(__dirname, '..', `./cpp/whisper.cpp/models/${model}`))) { + if (!fs.existsSync(path.join(WHISPER_CPP_PATH, 'models', MODEL_OBJECT[model]))) { } else { anyModelExist.push(model) } diff --git a/src/whisper.ts b/src/whisper.ts index b4486c7..3f003be 100644 --- a/src/whisper.ts +++ b/src/whisper.ts @@ -1,10 +1,6 @@ -import fs from 'fs' -import path from 'path' import shell from 'shelljs' -import { MODELS } from './constants' +import { WHISPER_CPP_PATH, WHISPER_CPP_MAIN_PATH } from './constants' -const WHISPER_CPP_PATH = path.join(__dirname, '..', 'cpp', 'whisper.cpp') -const WHISPER_CPP_MAIN_PATH = './main' const projectDir = process.cwd() export interface IShellOptions { From 8c5c50cac6d05e15f08456ebeec2d626e246bf86 Mon Sep 17 00:00:00 2001 From: Adam Jones Date: Mon, 6 Jan 2025 01:04:02 +0000 Subject: [PATCH 2/6] ci: Add integration tests And update integration test to actually fail (exit with non-zero status code) when there is a problem --- .github/workflows/integration.yml | 31 +++++++++++++++++++++++++++++++ example/index.ts | 1 + 2 files changed, 32 insertions(+) create mode 100644 .github/workflows/integration.yml diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000..439495c --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,31 @@ +name: Integration test + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + name: Test on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: lts/* + + - name: Install dependencies + run: npm ci + + - name: Run tests + run: npm test diff --git a/example/index.ts b/example/index.ts index d06280e..534a4fb 100644 --- a/example/index.ts +++ b/example/index.ts @@ -20,6 +20,7 @@ async function convert() { }) } catch (exc) { console.error(exc) + process.exit(1) } } From dbb8f09c52a57c0fb919ecdaa88419e2904042d9 Mon Sep 17 00:00:00 2001 From: Adam Jones Date: Mon, 6 Jan 2025 01:23:03 +0000 Subject: [PATCH 3/6] ci: Fix formatting checks for external contributors --- .github/workflows/ci.yml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index adeee01..3f89770 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,8 @@ jobs: steps: - uses: actions/checkout@v4 with: - ref: ${{ github.head_ref }} token: ${{ secrets.GITHUB_TOKEN }} - + - name: Setup Node.js uses: actions/setup-node@v4 with: @@ -32,9 +31,21 @@ jobs: - name: Format code run: npm run format - + + # For pushes to main or PRs from same repo, commit formatting changes - name: Commit changes + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: "style: format code with prettier" - branch: ${{ github.head_ref }} \ No newline at end of file + branch: ${{ github.event_name == 'push' && 'main' || github.head_ref }} + + # For PRs from forks, fail the check if there are formatting changes required + - name: Check for uncommitted changes + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository + run: | + if [[ -n "$(git status --porcelain)" ]]; then + echo "::error::Code formatting issues found. Please run 'npm run format' locally and commit the changes." + git diff + exit 1 + fi From 2b747959a9fcdf581eebc705fe6bc7c5ad7ee209 Mon Sep 17 00:00:00 2001 From: Adam Jones Date: Mon, 6 Jan 2025 02:05:29 +0000 Subject: [PATCH 4/6] fix: Windows special build path --- src/constants.ts | 4 +++- src/whisper.ts | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 5bff674..9542e73 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -45,4 +45,6 @@ export const MODEL_OBJECT = { export const DEFAULT_MODEL = 'tiny.en' export const WHISPER_CPP_PATH = path.join(__dirname, '..', 'cpp', 'whisper.cpp') -export const WHISPER_CPP_MAIN_PATH = './build/bin/whisper-cli' + +export const WHISPER_CPP_MAIN_PATH = + process.platform === 'win32' ? 'build\\bin\\Release\\whisper-cli.exe' : './build/bin/whisper-cli' \ No newline at end of file diff --git a/src/whisper.ts b/src/whisper.ts index 3f003be..1a37f61 100644 --- a/src/whisper.ts +++ b/src/whisper.ts @@ -53,13 +53,13 @@ export async function whisperShell( export async function executeCppCommand(command: string, logger = console, withCuda: boolean): Promise { try { shell.cd(WHISPER_CPP_PATH) - if (!shell.which(WHISPER_CPP_MAIN_PATH)) { + if (!shell.which(WHISPER_CPP_MAIN_PATH.replace(/\\/g, '/'))) { logger.debug('[Nodejs-whisper] whisper.cpp not initialized.') const makeCommand = withCuda ? 'WHISPER_CUDA=1 make -j' : 'make -j' shell.exec(makeCommand) - if (!shell.which(WHISPER_CPP_MAIN_PATH)) { + if (!shell.which(WHISPER_CPP_MAIN_PATH.replace(/\\/g, '/'))) { throw new Error( "[Nodejs-whisper] 'make' command failed. Please run 'make' command in /whisper.cpp directory." ) From 961be12f776f3c73f77f12ef4064b96f3454feab Mon Sep 17 00:00:00 2001 From: Adam Jones Date: Mon, 6 Jan 2025 02:06:07 +0000 Subject: [PATCH 5/6] test: use tiny.en model to speed up download --- example/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/index.ts b/example/index.ts index 534a4fb..532ba04 100644 --- a/example/index.ts +++ b/example/index.ts @@ -10,8 +10,8 @@ const filePath = path.resolve(__dirname, AUDIO_FILE) async function convert() { try { await nodewhisper(filePath, { - modelName: 'base.en', - autoDownloadModelName: 'base.en', + modelName: 'tiny.en', + autoDownloadModelName: 'tiny.en', whisperOptions: { outputInVtt: true, // Default is 20 which is too long From ba8e4aea714f760824727d9efaf824de2a3fe82d Mon Sep 17 00:00:00 2001 From: Adam Jones Date: Mon, 6 Jan 2025 02:10:51 +0000 Subject: [PATCH 6/6] chore: npm run format --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index 9542e73..b4dee17 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -47,4 +47,4 @@ export const DEFAULT_MODEL = 'tiny.en' export const WHISPER_CPP_PATH = path.join(__dirname, '..', 'cpp', 'whisper.cpp') export const WHISPER_CPP_MAIN_PATH = - process.platform === 'win32' ? 'build\\bin\\Release\\whisper-cli.exe' : './build/bin/whisper-cli' \ No newline at end of file + process.platform === 'win32' ? 'build\\bin\\Release\\whisper-cli.exe' : './build/bin/whisper-cli'