Simplify Windows TTS playback path
This commit is contained in:
@@ -511,6 +511,11 @@ export class LocalVoiceSession {
|
||||
}
|
||||
|
||||
private async playToWindowsDefaultSink(playback: PreparedSpeechAudio, signal: AbortSignal): Promise<void> {
|
||||
if (playback.sourceFilePath) {
|
||||
await this.playWindowsWaveFile(playback.sourceFilePath, signal);
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks: Buffer[] = [];
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
@@ -584,6 +589,47 @@ export class LocalVoiceSession {
|
||||
}
|
||||
}
|
||||
|
||||
private async playWindowsWaveFile(filePath: string, signal: AbortSignal): Promise<void> {
|
||||
const psScript = [
|
||||
"Add-Type -AssemblyName System;",
|
||||
`$player = New-Object System.Media.SoundPlayer('${filePath.replace(/'/g, "''")}');`,
|
||||
"$player.PlaySync();",
|
||||
].join(" ");
|
||||
|
||||
const player = spawn("powershell", ["-NoProfile", "-Command", psScript], {
|
||||
stdio: ["ignore", "ignore", "pipe"],
|
||||
});
|
||||
this.currentPlayer = player;
|
||||
|
||||
player.stderr.on("data", (chunk: Buffer) => {
|
||||
const text = chunk.toString().trim();
|
||||
if (text.length > 0) {
|
||||
this.options.logger.debug("[powershell-player]", text);
|
||||
}
|
||||
});
|
||||
|
||||
signal.addEventListener(
|
||||
"abort",
|
||||
() => {
|
||||
if (!player.killed) {
|
||||
player.kill("SIGKILL");
|
||||
}
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
|
||||
const [code, playSignal] = (await once(player, "exit")) as [number | null, NodeJS.Signals | null];
|
||||
this.currentPlayer = null;
|
||||
|
||||
if (signal.aborted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (code !== 0) {
|
||||
throw new Error(`powershell playback exited with code=${code ?? "null"} signal=${playSignal ?? "null"}`);
|
||||
}
|
||||
}
|
||||
|
||||
private getFfmpegPath(): string {
|
||||
return requireFfmpegPath();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user