Files
everyone-can-use-english/enjoy/src/utils.ts
an-lee cec9d73bc8 Feat: transcribe from web (#204)
* add transcribe from web

* transcribe from web

* add azure speech ai

* fix azure speech output

* may select stt service

* fix UI

* remove debug code

* lint

* fix default stt service

* tweak

* fix secondsToTimestamp
2024-01-27 00:45:06 +08:00

80 lines
2.4 KiB
TypeScript

import { createHash } from "crypto";
import { createReadStream } from "fs";
import Pitchfinder from "pitchfinder";
export function hashFile(
path: string,
options: { algo: string }
): Promise<string> {
const algo = options.algo || "md5";
return new Promise((resolve, reject) => {
const hash = createHash(algo);
const stream = createReadStream(path);
stream.on("error", reject);
stream.on("data", (chunk) => hash.update(chunk));
stream.on("end", () => resolve(hash.digest("hex")));
});
}
export function hashBlob(
blob: Blob,
options: { algo: string }
): Promise<string> {
const algo = options.algo || "md5";
return new Promise((resolve, reject) => {
const hash = createHash(algo);
const reader = new FileReader();
reader.onload = () => {
if (reader.result instanceof ArrayBuffer) {
const buffer = Buffer.from(reader.result);
hash.update(buffer);
resolve(hash.digest("hex"));
} else {
reject(new Error("Unexpected result from FileReader"));
}
};
reader.onerror = reject;
reader.readAsArrayBuffer(blob);
});
}
export function generatePitch(peaks: Float32Array, sampleRate: number) {
const detectPitch = Pitchfinder.YIN({ sampleRate });
const duration = peaks.length / sampleRate;
const bpm = peaks.length / duration / 60;
const frequencies = Pitchfinder.frequencies(detectPitch, peaks, {
tempo: bpm,
quantization: bpm,
});
// Find the baseline frequency (the value that appears most often)
const frequencyMap: any = {};
let maxAmount = 0;
let baseFrequency = 0;
frequencies.forEach((frequency) => {
if (!frequency) return;
const tolerance = 10;
frequency = Math.round(frequency * tolerance) / tolerance;
if (!frequencyMap[frequency]) frequencyMap[frequency] = 0;
frequencyMap[frequency] += 1;
if (frequencyMap[frequency] > maxAmount) {
maxAmount = frequencyMap[frequency];
baseFrequency = frequency;
}
});
return { frequencies, baseFrequency };
}
export function milisecondsToTimestamp(ms: number) {
const hours = Math.floor(ms / 3600000).toString();
const minutes = Math.floor((ms % 3600000) / 60000).toString();
const seconds = Math.floor(((ms % 360000) % 60000) / 1000).toString();
const milliseconds = Math.floor(((ms % 360000) % 60000) % 1000).toString();
return `${hours.padStart(2, "0")}:${minutes.padStart(
2,
"0"
)}:${seconds.padStart(2, "0")},${milliseconds}`;
}