feat: add WAV format support for audio chunks in artplayer-plugin-asr

- Implemented pcmToWav function to convert PCM audio data to WAV format.
- Updated onAudioChunk callback to receive both PCM and WAV buffers.
- Modified TypeScript definitions to reflect changes in onAudioChunk parameter and append method.
This commit is contained in:
Harvey Zack committed 2025-05-23 10:23:27 +08:00
1 parent 62835bb042
commit 10337ddb1d
6 files changed
+81 -13

No files matched your search

+34 -3
View File
@@ -81,6 +81,36 @@ export default function artplayerPluginAsr(option = {}) {
return buffer;
}
function pcmToWav(pcmBuffer, sampleRate) {
const pcmLength = pcmBuffer.byteLength;
const wavBuffer = new ArrayBuffer(44 + pcmLength);
const view = new DataView(wavBuffer);
const writeString = (offset, str) => {
for (let i = 0; i < str.length; i++) {
view.setUint8(offset + i, str.charCodeAt(i));
}
};
writeString(0, 'RIFF');
view.setUint32(4, 36 + pcmLength, true);
writeString(8, 'WAVE');
writeString(12, 'fmt ');
view.setUint32(16, 16, true);
view.setUint16(20, 1, true);
view.setUint16(22, 1, true);
view.setUint32(24, sampleRate, true);
view.setUint32(28, sampleRate * 2, true);
view.setUint16(32, 2, true);
view.setUint16(34, 16, true);
writeString(36, 'data');
view.setUint32(40, pcmLength, true);
new Uint8Array(wavBuffer).set(new Uint8Array(pcmBuffer), 44);
return wavBuffer;
}
async function setupAudioContext() {
if (audioCtx) return audioCtx;
audioCtx = new (window.AudioContext || window.webkitAudioContext)({ sampleRate });
@@ -94,7 +124,7 @@ export default function artplayerPluginAsr(option = {}) {
sourceNode = audioCtx.createMediaElementSource(art.video);
return sourceNode;
} catch (err) {
console.warn('[artplayerPluginAsr] Direct connection failed, trying fallback...', err);
console.warn('[artplayerPluginAsr] Direct connection failed:', err);
}
}
@@ -166,8 +196,9 @@ export default function artplayerPluginAsr(option = {}) {
if (accumulated.length < CHUNK_SAMPLES) return;
const chunkToSend = accumulated.slice(0, CHUNK_SAMPLES);
const buffer = floatTo16BitPCM(chunkToSend);
const subtitle = await onAudioChunk(buffer);
const pcm = floatTo16BitPCM(chunkToSend);
const wav = pcmToWav(pcm, sampleRate);
const subtitle = await onAudioChunk({ pcm, wav });
append(subtitle);
}, interval);
@@ -3,19 +3,24 @@ import type Artplayer from 'artplayer';
export = artplayerPluginAsr;
export as namespace artplayerPluginAsr;
interface AudioChunk {
pcm: ArrayBuffer;
wav: ArrayBuffer;
}
interface AsrPluginOption {
length?: number;
interval?: number;
sampleRate?: number;
autoHideTimeout?: number;
onAudioChunk?: (buffer: ArrayBuffer) => void | Promise<void>;
onAudioChunk?: (chunk: AudioChunk) => void | Promise<void>;
}
interface AsrPluginInstance {
name: 'artplayerPluginAsr';
stop: () => void;
hide: () => void;
append: () => void;
append: (subtitle: string) => void;
}
declare function artplayerPluginAsr(option?: AsrPluginOption): (art: Artplayer) => AsrPluginInstance;