Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web demo refactor #151

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions demo/web/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ignore artifacts:
build
coverage
1 change: 1 addition & 0 deletions demo/web/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
119 changes: 3 additions & 116 deletions demo/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,126 +9,13 @@
specific language governing permissions and limitations under the License.
-->

<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8" />
<script src="node_modules/@picovoice/octopus-web/dist/iife/index.js"></script>
<script src="octopus_params.js"></script>
<script type="application/javascript">
let audioContext = new (window.AudioContext || window.webKitAudioContext)(
{ sampleRate: 16000 }
);

function writeStatus(status) {
console.log(status);
document.getElementById("status").innerHTML = status;
}

function readAudioFile(selectedFile, callback) {
let reader = new FileReader();
reader.onload = function (ev) {
let wavBytes = reader.result;
audioContext.decodeAudioData(wavBytes, callback);
};
reader.readAsArrayBuffer(selectedFile);
}

let octopusMetadata = undefined;

function octopusSearchHandler(matches) {
document.getElementById("result").style.display = "block";
document.getElementById("result-table").style.display = "block";

document.getElementById(
"result"
).innerHTML = `Search results (${matches.length}):<br>`;
const table = document.getElementById("result-table");
const rowCount = table.rows.length;
for (let i = 1; i < rowCount; i++) {
table.deleteRow(1);
}
matches.forEach((match) => {
const row = table.insertRow(-1);
const start = row.insertCell(0);
const end = row.insertCell(1);
const probability = row.insertCell(2);

start.innerHTML = `${match.startSec.toFixed(3)}`;
end.innerHTML = `${match.endSec.toFixed(3)}`;
probability.innerHTML = `${match.probability.toFixed(3)}`;
});
}

async function startOctopus(accessKey) {
document.getElementById("dashboard").style.display = "none";
document.getElementById("search").style.display = "none";
document.getElementById("result").style.display = "none";
document.getElementById("result-table").style.display = "none";
writeStatus("Octopus is loading. Please wait...");
let engineHandle = undefined;
try {
engineHandle =
await OctopusWeb.OctopusWorker.create(
accessKey,
{ base64: modelParams },
);
} catch (err) {
document.getElementById("accessKey").style.border = "1px solid red";
console.error(err);
return;
}
document.getElementById("accessKey").style.border = "";
writeStatus("Octopus worker ready! Select a .wav file to index.");
document.getElementById("dashboard").style.display = "block";

const fileSelector = document.getElementById("file-selector");
fileSelector.addEventListener("change", (event) => {
document.getElementById("search").style.display = "none";
document.getElementById("result").style.display = "none";
document.getElementById("result-table").style.display = "none";
writeStatus("Indexing audio; please wait...");
const fileList = event.target.files;
readAudioFile(fileList[0], async (audioBuffer) => {
const f32PCM = audioBuffer.getChannelData(0);
const i16PCM = new Int16Array(f32PCM.length);

const INT16_MAX = 32767;
const INT16_MIN = -32768;
i16PCM.set(
f32PCM.map((f) => {
let i = Math.trunc(f * INT16_MAX);
if (f > INT16_MAX) i = INT16_MAX;
if (f < INT16_MIN) i = INT16_MIN;
return i;
})
);

octopusMetadata = await engineHandle.index(i16PCM, { transfer: true });
document.getElementById("search").style.display = "block";
writeStatus("Audio indexed! Enter a phrase to search the index.");
});
});

const searchForm = document.getElementById("search-form");
searchForm.addEventListener("submit", async (event) => {
event.preventDefault();
const searchText = document.getElementById("search-phrase").value;
if (searchText.trim() === "") {
document.getElementById("search-phrase").style.border =
"1px solid red";
writeStatus("Search phrase is empty");
} else if (octopusMetadata) {
document.getElementById("search-phrase").style.border = "";
writeStatus(`Searching for ${searchText}...`);
let matches = await engineHandle.search(octopusMetadata, searchText);
octopusSearchHandler(matches);
} else {
writeStatus("Please index an audio file first");
}
});
}
</script>
<script type="application/javascript" src="scripts/octopus.js"></script>
<style>
table {
margin-top: 2rem;
Expand Down
3 changes: 2 additions & 1 deletion demo/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@picovoice/octopus-web": "=2.0.0"
},
"devDependencies": {
"http-server": "^14.0.0"
"http-server": "^14.0.0",
"prettier": "3.5.1"
}
}
108 changes: 108 additions & 0 deletions demo/web/scripts/octopus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
let audioContext = new (window.AudioContext || window.webKitAudioContext)({
sampleRate: 16000,
});

function writeStatus(status) {
console.log(status);
document.getElementById("status").innerHTML = status;
}

function readAudioFile(selectedFile, callback) {
let reader = new FileReader();
reader.onload = function (ev) {
let wavBytes = reader.result;
audioContext.decodeAudioData(wavBytes, callback);
};
reader.readAsArrayBuffer(selectedFile);
}

let octopusMetadata = undefined;

function octopusSearchHandler(matches) {
document.getElementById("result").style.display = "block";
document.getElementById("result-table").style.display = "block";

document.getElementById("result").innerHTML =
`Search results (${matches.length}):<br>`;
const table = document.getElementById("result-table");
const rowCount = table.rows.length;
for (let i = 1; i < rowCount; i++) {
table.deleteRow(1);
}
matches.forEach((match) => {
const row = table.insertRow(-1);
const start = row.insertCell(0);
const end = row.insertCell(1);
const probability = row.insertCell(2);

start.innerHTML = `${match.startSec.toFixed(3)}`;
end.innerHTML = `${match.endSec.toFixed(3)}`;
probability.innerHTML = `${match.probability.toFixed(3)}`;
});
}

async function startOctopus(accessKey) {
document.getElementById("dashboard").style.display = "none";
document.getElementById("search").style.display = "none";
document.getElementById("result").style.display = "none";
document.getElementById("result-table").style.display = "none";
writeStatus("Octopus is loading. Please wait...");
let engineHandle = undefined;
try {
engineHandle = await OctopusWeb.OctopusWorker.create(accessKey, {
base64: modelParams,
});
} catch (err) {
document.getElementById("accessKey").style.border = "1px solid red";
console.error(err);
return;
}
document.getElementById("accessKey").style.border = "";
writeStatus("Octopus worker ready! Select a .wav file to index.");
document.getElementById("dashboard").style.display = "block";

const fileSelector = document.getElementById("file-selector");
fileSelector.addEventListener("change", (event) => {
document.getElementById("search").style.display = "none";
document.getElementById("result").style.display = "none";
document.getElementById("result-table").style.display = "none";
writeStatus("Indexing audio; please wait...");
const fileList = event.target.files;
readAudioFile(fileList[0], async (audioBuffer) => {
const f32PCM = audioBuffer.getChannelData(0);
const i16PCM = new Int16Array(f32PCM.length);

const INT16_MAX = 32767;
const INT16_MIN = -32768;
i16PCM.set(
f32PCM.map((f) => {
let i = Math.trunc(f * INT16_MAX);
if (f > INT16_MAX) i = INT16_MAX;
if (f < INT16_MIN) i = INT16_MIN;
return i;
}),
);

octopusMetadata = await engineHandle.index(i16PCM, { transfer: true });
document.getElementById("search").style.display = "block";
writeStatus("Audio indexed! Enter a phrase to search the index.");
});
});

const searchForm = document.getElementById("search-form");
searchForm.addEventListener("submit", async (event) => {
event.preventDefault();
const searchText = document.getElementById("search-phrase").value;
if (searchText.trim() === "") {
document.getElementById("search-phrase").style.border = "1px solid red";
writeStatus("Search phrase is empty");
} else if (octopusMetadata) {
document.getElementById("search-phrase").style.border = "";
writeStatus(`Searching for ${searchText}...`);
let matches = await engineHandle.search(octopusMetadata, searchText);
octopusSearchHandler(matches);
} else {
writeStatus("Please index an audio file first");
}
});
}
5 changes: 5 additions & 0 deletions demo/web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ portfinder@^1.0.28:
debug "^3.2.7"
mkdirp "^0.5.6"

[email protected]:
version "3.5.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.1.tgz#22fac9d0b18c0b92055ac8fb619ac1c7bef02fb7"
integrity sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==

qs@^6.4.0:
version "6.11.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
Expand Down