Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/web-codestyle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ on:
push:
branches: [ main ]
paths:
- '**/web/*.js'
- '**/web/*.ts'
- 'binding/web/*.js'
- 'binding/web/*.ts'
- '.github/workflows/web-codestyle.yml'
pull_request:
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- '**/web/*.js'
- '**/web/*.ts'
- 'binding/web/*.js'
- 'binding/web/*.ts'
- '.github/workflows/web-codestyle.yml'

jobs:
Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/web-demos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18.x, 20.x, 22.x]
node-version: [18.x, 20.x, 22.x, 24.x]

steps:
- uses: actions/checkout@v3
Expand All @@ -36,12 +36,11 @@ jobs:
with:
node-version: ${{ matrix.node-version }}

# ************** REMOVE AFTER RELEASE ********************
- name: Build Web SDK
run: yarn && yarn copywasm && yarn build
run: yarn install && yarn copywasm && yarn build
working-directory: binding/web

- name: Pre-build dependencies
run: npm install yarn
# ************** REMOVE AFTER RELEASE ********************

- name: Install dependencies
run: yarn install
5 changes: 1 addition & 4 deletions .github/workflows/web-perf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ jobs:
with:
node-version: ${{ matrix.node-version }}

- name: Pre-build dependencies
run: npm install yarn

- name: Install dependencies
run: yarn install

Expand All @@ -55,4 +52,4 @@ jobs:
run: yarn setup-test

- name: Test
run: yarn test-perf --env ACCESS_KEY=${{secrets.PV_VALID_ACCESS_KEY}},NUM_TEST_ITERATIONS=20,ENROLL_PERFORMANCE_THRESHOLD_SEC=${{matrix.enrollPerformanceThresholdSec}},PROCESS_PERFORMANCE_THRESHOLD_SEC=${{matrix.processPerformanceThresholdSec}}
run: yarn test-perf --env ACCESS_KEY=${{secrets.PV_VALID_ACCESS_KEY}},DEVICE=cpu:1,NUM_TEST_ITERATIONS=20,ENROLL_PERFORMANCE_THRESHOLD_SEC=${{matrix.enrollPerformanceThresholdSec}},PROCESS_PERFORMANCE_THRESHOLD_SEC=${{matrix.processPerformanceThresholdSec}}
8 changes: 3 additions & 5 deletions .github/workflows/web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ jobs:

strategy:
matrix:
node-version: [16.x, 18.x, 20.x]
device: [ cpu:1, cpu ]
node-version: [18.x, 20.x, 22.x, 24.x]

steps:
- uses: actions/checkout@v3
Expand All @@ -41,9 +42,6 @@ jobs:
with:
node-version: ${{ matrix.node-version }}

- name: Pre-build dependencies
run: npm install yarn

- name: Install dependencies
run: yarn install

Expand All @@ -57,4 +55,4 @@ jobs:
run: yarn setup-test

- name: Test
run: yarn test --env ACCESS_KEY=${{secrets.PV_VALID_ACCESS_KEY}}
run: yarn test --env ACCESS_KEY=${{secrets.PV_VALID_ACCESS_KEY}},DEVICE=${{ matrix.device }}
2 changes: 1 addition & 1 deletion binding/web/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
node_modules
dist
lib/pv_eagle*.wasm
src/lib/*
test/eagle_params.js
test/eagle_params.pv
cypress/fixtures/audio_samples/*.wav
21 changes: 19 additions & 2 deletions binding/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Eagle is an on-device speaker recognition engine. Eagle is:

- Private; All voice processing runs locally.
- Cross-Platform:
- Linux (x86_64), macOS (x86_64, arm64), Windows (x86_64)
- Linux (x86_64), macOS (x86_64, arm64), Windows (x86_64, arm64)
- Android and iOS
- Chrome, Safari, Firefox, and Edge
- Raspberry Pi (3, 4, 5)
Expand All @@ -19,11 +19,28 @@ Eagle is an on-device speaker recognition engine. Eagle is:
- Firefox
- Safari

## Requirements

The Eagle Web Binding uses [SharedArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer).

Include the following headers in the response to enable the use of `SharedArrayBuffers`:

```
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
```

Refer to our [Web demo](../../demo/web) for an example on creating a server with the corresponding response headers.

Browsers that don't support `SharedArrayBuffers` or applications that don't include the required headers will fall back to using standard `ArrayBuffers`. This will disable multithreaded processing.

### Restrictions

IndexedDB is required to use `Eagle` in a worker thread. Browsers without IndexedDB support
(i.e. Firefox Incognito Mode) should use `Eagle` in the main thread.

Multi-threading is only enabled for Eagle when using on a web worker.

## Installation

Using `yarn`:
Expand Down Expand Up @@ -88,7 +105,7 @@ function getAudioData(numSamples): Int16Array {
let percentage = 0;
while (percentage < 100) {
const audioData = getAudioData(eagleProfiler.minEnrollSamples);

const result: EagleProfilerEnrollResult = await eagleProfiler.enroll(audioData);
if (result.feedback === EagleProfilerEnrollFeedback.AUDIO_OK) {
// audio is good!
Expand Down
9 changes: 9 additions & 0 deletions binding/web/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,14 @@ export default defineConfig({
video: false,
screenshotOnRunFailure: false,
defaultCommandTimeout: 10000,
setupNodeEvents(on) {
on('before:browser:launch', (browser, launchOptions) => {
if (browser.name === 'chrome') {
launchOptions.args.push('--enable-features=SharedArrayBuffer');
}

return launchOptions;
});
},
},
});
2 changes: 1 addition & 1 deletion binding/web/cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": ["cypress"]
"types": ["cypress", "node"]
},
"include": [
"../test/**/*.ts",
Expand Down
Empty file removed binding/web/lib/.gitkeep
Empty file.
5 changes: 5 additions & 0 deletions binding/web/module.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ declare module "*.wasm" {
export default content;
}

declare module "*.txt" {
const content: string;
export default content;
}

declare module 'web-worker:*.ts' {
const WorkerFactory: new () => Worker;
export default WorkerFactory;
Expand Down
11 changes: 6 additions & 5 deletions binding/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Eagle Speaker Recognition engine for web browsers (via WebAssembly)",
"author": "Picovoice Inc",
"license": "Apache-2.0",
"version": "1.0.0",
"version": "2.0.0",
"keywords": [
"eagle",
"web",
Expand Down Expand Up @@ -33,11 +33,11 @@
"format": "prettier --write \"**/*.{js,ts,json}\"",
"copywasm": "node scripts/copy_wasm.js",
"setup-test": "node scripts/setup_test.js && npx pvbase64 -i ./test/eagle_params.pv -o ./test/eagle_params.js",
"test": "cypress run --spec test/eagle.test.ts",
"test-perf": "cypress run --spec test/eagle_perf.test.ts"
"test": "cypress run --spec test/eagle.test.ts --browser chrome",
"test-perf": "cypress run --spec test/eagle_perf.test.ts --browser chrome"
},
"dependencies": {
"@picovoice/web-utils": "=1.3.2"
"@picovoice/web-utils": "=1.4.3"
},
"devDependencies": {
"@babel/core": "^7.20.12",
Expand All @@ -49,6 +49,7 @@
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-terser": "^0.4.0",
"@rollup/pluginutils": "^5.0.2",
"@types/emscripten": "1.40.0",
"@types/node": "^18.13.0",
"@typescript-eslint/eslint-plugin": "^5.51.0",
"@typescript-eslint/parser": "^5.51.0",
Expand All @@ -67,6 +68,6 @@
"wasm-feature-detect": "^1.5.0"
},
"engines": {
"node": ">=16"
"node": ">=18"
}
}
2 changes: 1 addition & 1 deletion binding/web/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default {
exclude: '**/node_modules/**',
}),
base64({
include: ['./lib/**/*.wasm']
include: ['./src/lib/*.wasm', './src/lib/*.txt'],
})
],
};
34 changes: 25 additions & 9 deletions binding/web/scripts/copy_wasm.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
const fs = require('fs');
const { join } = require('path');
const fs = require("fs");
const { join, extname } = require("path");

const wasmFiles = ['pv_eagle.wasm', 'pv_eagle_simd.wasm'];
const wasmFiles = [
"pv_eagle_simd.wasm",
"pv_eagle_simd.js",
"pv_eagle_pthread.wasm",
"pv_eagle_pthread.js",
]

console.log('Copying the WASM model...');
console.log("Copying the WASM model...");

const sourceDirectory = join(__dirname, '..', '..', '..', 'lib', 'wasm');
const sourceDirectory = join(
__dirname,
"..",
"..",
"..",
"lib",
"wasm"
);

const outputDirectory = join(__dirname, '..', 'lib');
const outputDirectory = join(__dirname, "..", "src", "lib");

try {
fs.mkdirSync(outputDirectory, { recursive: true });
wasmFiles.forEach(file => {
fs.copyFileSync(join(sourceDirectory, file), join(outputDirectory, file));
});
fs.copyFileSync(join(sourceDirectory, file), join(outputDirectory, file))
const ext = extname(file);
if (ext === ".js") {
fs.copyFileSync(join(sourceDirectory, file), join(outputDirectory, file.replace(ext, ".txt")));
}
})
} catch (error) {
console.error(error);
}

console.log('... Done!');
console.log("... Done!");
Loading