Fix audio recorder (#16280)

FIx audio recorder
This commit is contained in:
Bram Kragten 2023-04-23 19:48:46 +02:00 committed by GitHub
parent 8d1ae71741
commit 35baf4c779
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 35 deletions

View File

@ -189,9 +189,7 @@ export class AssistPipelineRunDebug extends LitElement {
});
this._audioBuffer = [];
audioRecorder.start();
this.hass.connection.socket!.binaryType = "arraybuffer";
await audioRecorder.start();
let run: PipelineRun | undefined;
@ -288,6 +286,7 @@ export class AssistPipelineRunDebug extends LitElement {
}
private _sendAudioChunk(chunk: Int16Array) {
this.hass.connection.socket!.binaryType = "arraybuffer";
// Turn into 8 bit so we can prefix our handler ID.
const data = new Uint8Array(1 + chunk.length * 2);
data[0] = this._pipelineRuns[0].run.runner_data.stt_binary_handler_id!;

View File

@ -7,6 +7,10 @@ export class AudioRecorder {
private _stream: MediaStream | undefined;
private _source: MediaStreamAudioSourceNode | undefined;
private _recorder: AudioWorkletNode | undefined;
constructor(callback: (data: Int16Array) => void) {
this._callback = callback;
}
@ -28,30 +32,19 @@ export class AudioRecorder {
}
public async start() {
this._active = true;
if (!this._context || !this._stream) {
await this._createContext();
} else {
this._context.resume();
this._stream.getTracks()[0].enabled = true;
}
if (!this._context || !this._stream) {
this._active = false;
return;
}
const source = this._context.createMediaStreamSource(this._stream);
const recorder = new AudioWorkletNode(this._context, "recorder.worklet");
source.connect(recorder).connect(this._context.destination);
recorder.port.onmessage = (e) => {
if (!this._active) {
return;
if (!this._context || !this._stream || !this._source || !this._recorder) {
try {
await this._createContext();
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);
this._active = false;
}
this._callback(e.data);
};
} else {
this._stream.getTracks()[0].enabled = true;
await this._context.resume();
this._active = true;
}
}
public async stop() {
@ -68,21 +61,29 @@ export class AudioRecorder {
this._context?.close();
this._stream = undefined;
this._context = undefined;
this._source = undefined;
this._recorder = undefined;
}
private async _createContext() {
try {
// @ts-ignore-next-line
this._context = new (window.AudioContext || window.webkitAudioContext)();
this._stream = await navigator.mediaDevices.getUserMedia({ audio: true });
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);
return;
}
// @ts-ignore-next-line
this._context = new (window.AudioContext || window.webkitAudioContext)();
this._stream = await navigator.mediaDevices.getUserMedia({ audio: true });
await this._context.audioWorklet.addModule(
new URL("./recorder.worklet.js", import.meta.url)
);
this._source = this._context.createMediaStreamSource(this._stream);
this._recorder = new AudioWorkletNode(this._context, "recorder.worklet");
this._recorder.port.onmessage = (e) => {
if (!this._active) {
return;
}
this._callback(e.data);
};
this._active = true;
this._source.connect(this._recorder);
}
}