| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- import { LipSyncAnalyzeResult } from "./lipSyncAnalyzeResult";
- const TIME_DOMAIN_DATA_LENGTH = 2048;
- export class LipSync {
- public readonly audio: AudioContext;
- public readonly analyser: AnalyserNode;
- public readonly timeDomainData: Float32Array<ArrayBuffer>;
- public constructor(audio: AudioContext) {
- this.audio = audio;
- this.analyser = audio.createAnalyser();
- this.timeDomainData = new Float32Array(TIME_DOMAIN_DATA_LENGTH) as Float32Array<ArrayBuffer>;
- }
- public update(): LipSyncAnalyzeResult {
- this.analyser.getFloatTimeDomainData(this.timeDomainData);
- let volume = 0.0;
- for (let i = 0; i < TIME_DOMAIN_DATA_LENGTH; i++) {
- volume = Math.max(volume, Math.abs(this.timeDomainData[i]));
- }
- // cook
- volume = 1 / (1 + Math.exp(-45 * volume + 5));
- if (volume < 0.1) volume = 0;
- return {
- volume,
- };
- }
- public async playFromArrayBuffer(buffer: ArrayBuffer, onEnded?: () => void) {
- const audioBuffer = await this.audio.decodeAudioData(buffer);
- const bufferSource = this.audio.createBufferSource();
- bufferSource.buffer = audioBuffer;
- bufferSource.connect(this.audio.destination);
- bufferSource.connect(this.analyser);
- bufferSource.start();
- if (onEnded) {
- bufferSource.addEventListener("ended", onEnded);
- }
- }
- public async playFromURL(url: string, onEnded?: () => void) {
- const res = await fetch(url);
- const buffer = await res.arrayBuffer();
- this.playFromArrayBuffer(buffer, onEnded);
- }
- }
|