UNPKG

@minto-ai/xunfei-tts

Version:

借助“讯飞在线语音合成API”实现浏览器端“文本转语音

75 lines (58 loc) 2.16 kB
import type { SerialTaskExecuteContext } from '../handler' import type { PrivateCustomEventName } from '../types' import { SerialHandler } from '../handler' import { createEventBus } from '../utils' const $bus = createEventBus<PrivateCustomEventName>() class AudioActuator extends SerialHandler<Array<number>, never> { private audioContext: AudioContext = new AudioContext() private bufferSource: AudioBufferSourceNode | null = null private gainNode: GainNode | null = null private volume = 1 public execute( context: SerialTaskExecuteContext<Array<number>, never>, ): void { if (context.isLastExecute) { this.taskCompletedCallback() return } const audioBuffer = this.audioContext.createBuffer(1, context.taskItem.original!.length, 22050) if (audioBuffer.copyToChannel) { audioBuffer.copyToChannel(new Float32Array(context.taskItem.original! as any), 0, 0) } this.bufferSource = this.audioContext.createBufferSource() this.bufferSource.buffer = audioBuffer this.gainNode = this.audioContext.createGain() this.bufferSource.connect(this.gainNode) this.gainNode.connect(this.audioContext.destination) this.gainNode.gain.setValueAtTime(this.volume, this.audioContext.currentTime) this.bufferSource.start() this.bufferSource.addEventListener('ended', () => { this.taskCompletedCallback() }) } protected onFinish(): void { if (this.bufferSource) { this.bufferSource.stop() this.bufferSource = null } if (this.gainNode) { this.gainNode.disconnect() this.gainNode = null } if (this.audioContext) { this.audioContext.suspend() this.audioContext = new AudioContext() } $bus.emit('_audioActuatorFinish') } protected onBeforeFirstExecute(): void { $bus.emit('_audioActuatorBeforeFirstExecute') } public setVolume(volume: number): void { if (this.gainNode) { this.gainNode.gain.setValueAtTime(volume, this.audioContext.currentTime) } this.volume = volume } } export default AudioActuator