Add TTS volume, a browser preview, and the split-audio plan
This commit is contained in:
@@ -156,7 +156,7 @@ export class AudioService {
|
||||
* grows. The wrapper touches `<file>.ready` after the first word, which is the reliable
|
||||
* signal; a size threshold and a timeout cover providers that do not mark readiness.
|
||||
*/
|
||||
private async playWhenReady(file: string): Promise<void> {
|
||||
private async playWhenReady(file: string, volume?: number): Promise<void> {
|
||||
for (let attempt = 0; attempt < 400; attempt++) {
|
||||
try {
|
||||
if (statSync(`${file}.ready`).size >= 0) break;
|
||||
@@ -172,7 +172,7 @@ export class AudioService {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.manager.play(file);
|
||||
await this.manager.play(file, volume);
|
||||
} finally {
|
||||
try {
|
||||
unlinkSync(`${file}.ready`);
|
||||
@@ -182,6 +182,23 @@ export class AudioService {
|
||||
}
|
||||
}
|
||||
|
||||
/** The TTS output directory, for serving preview files. */
|
||||
get ttsDirectory(): string {
|
||||
return this.tts.directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize a line for browser playback. This never touches the call:
|
||||
* no queue, no ducking, no virtual microphone, no voice-processing bypass.
|
||||
*/
|
||||
async preview(text: string, options: TtsOptions = {}): Promise<string> {
|
||||
const trimmed = text.trim();
|
||||
if (!trimmed) throw new Error("text is required");
|
||||
if (trimmed.length > 1000) throw new Error("text is too long (max 1000 characters)");
|
||||
|
||||
return this.tts.synthesize(trimmed, { ...options, stream: false, onOutputPath: undefined });
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
this.queue.length = 0;
|
||||
this.manager.stopPlayback();
|
||||
@@ -402,7 +419,7 @@ export class AudioService {
|
||||
options.onOutputPath = path => {
|
||||
streaming = (async () => {
|
||||
await this.applyDuck(this.shouldDuck());
|
||||
await this.playWhenReady(path);
|
||||
await this.playWhenReady(path, item.options.volume);
|
||||
})();
|
||||
};
|
||||
}
|
||||
@@ -413,7 +430,7 @@ export class AudioService {
|
||||
await pending;
|
||||
} else {
|
||||
await this.applyDuck(this.shouldDuck());
|
||||
await this.manager.play(file);
|
||||
await this.manager.play(file, item.options.volume);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[audio] speak failed:", (error as Error).message);
|
||||
|
||||
Reference in New Issue
Block a user