generated from tailored/router-template
feat: 添加流获取音频的事件
This commit is contained in:
parent
ad5bcd5be8
commit
3ecc9353c7
@ -1,7 +1,7 @@
|
|||||||
// https://www.volcengine.com/docs/6561/1329505#%E7%A4%BA%E4%BE%8Bsamples
|
// https://www.volcengine.com/docs/6561/1329505#%E7%A4%BA%E4%BE%8Bsamples
|
||||||
|
|
||||||
import { WebSocket } from 'ws';
|
import { WebSocket } from 'ws';
|
||||||
|
import { EventEmitter } from 'eventemitter3';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
const uuidv4 = nanoid;
|
const uuidv4 = nanoid;
|
||||||
@ -308,7 +308,7 @@ async function finishConnection(ws: WebSocket): Promise<void> {
|
|||||||
return await sendEvent(ws, header, optional, payload);
|
return await sendEvent(ws, header, optional, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runDemo(appId: string, token: string, speaker: string, text: string, outputPath: string): Promise<void> {
|
export async function runDemo(appId: string, token: string, speaker: string, text: string, outputPath: string, emitter?: EventEmitter): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const wsHeader = {
|
const wsHeader = {
|
||||||
'X-Api-App-Key': appId,
|
'X-Api-App-Key': appId,
|
||||||
@ -319,13 +319,36 @@ export async function runDemo(appId: string, token: string, speaker: string, tex
|
|||||||
|
|
||||||
const url = 'wss://openspeech.bytedance.com/api/v3/tts/bidirection';
|
const url = 'wss://openspeech.bytedance.com/api/v3/tts/bidirection';
|
||||||
const ws = new WebSocket(url, { headers: wsHeader });
|
const ws = new WebSocket(url, { headers: wsHeader });
|
||||||
|
const filename = outputPath.split('/').pop() || '';
|
||||||
|
let isBegin = true;
|
||||||
|
const writeFileEmitter = (data: Buffer) => {
|
||||||
|
const value: TTSWriteType = {
|
||||||
|
type: 'tts-mix',
|
||||||
|
filename,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
if (isBegin) {
|
||||||
|
value.isBegin = true;
|
||||||
|
isBegin = false;
|
||||||
|
}
|
||||||
|
emitter?.emit?.('writeFile', value);
|
||||||
|
};
|
||||||
|
const finishEmitter = () => {
|
||||||
|
emitter?.emit?.('writeFile', {
|
||||||
|
type: 'tts-mix',
|
||||||
|
isEnd: true,
|
||||||
|
data: Buffer.from(''),
|
||||||
|
filename,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
ws.on('open', async () => {
|
ws.on('open', async () => {
|
||||||
try {
|
try {
|
||||||
await startConnection(ws);
|
await startConnection(ws);
|
||||||
let isFirstResponse = true;
|
|
||||||
let fileHandle: fs.FileHandle | null = null;
|
let fileHandle: fs.FileHandle | null = null;
|
||||||
let sessionId: string = '';
|
let sessionId: string = '';
|
||||||
|
let isFirstResponse = true;
|
||||||
|
|
||||||
ws.on('message', async (data) => {
|
ws.on('message', async (data) => {
|
||||||
try {
|
try {
|
||||||
const res = parserResponse(data as Buffer);
|
const res = parserResponse(data as Buffer);
|
||||||
@ -347,14 +370,17 @@ export async function runDemo(appId: string, token: string, speaker: string, tex
|
|||||||
} else if (!isFirstResponse) {
|
} else if (!isFirstResponse) {
|
||||||
if (res.optional.event === EVENT_TTSResponse && res.header.messageType === AUDIO_ONLY_RESPONSE && res.payload && fileHandle) {
|
if (res.optional.event === EVENT_TTSResponse && res.header.messageType === AUDIO_ONLY_RESPONSE && res.payload && fileHandle) {
|
||||||
await fileHandle.write(res.payload);
|
await fileHandle.write(res.payload);
|
||||||
|
writeFileEmitter(res.payload);
|
||||||
} else if (res.optional.event === EVENT_TTSSentenceStart || res.optional.event === EVENT_TTSSentenceEnd) {
|
} else if (res.optional.event === EVENT_TTSSentenceStart || res.optional.event === EVENT_TTSSentenceEnd) {
|
||||||
// continue
|
// continue
|
||||||
} else {
|
} else {
|
||||||
|
// 152
|
||||||
if (fileHandle) {
|
if (fileHandle) {
|
||||||
await fileHandle.close();
|
await fileHandle.close();
|
||||||
fileHandle = null;
|
fileHandle = null;
|
||||||
}
|
}
|
||||||
await finishConnection(ws);
|
await finishConnection(ws);
|
||||||
|
finishEmitter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -374,12 +400,22 @@ export async function runDemo(appId: string, token: string, speaker: string, tex
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TTSWriteType = {
|
||||||
|
type: 'tts-mix';
|
||||||
|
filename: string;
|
||||||
|
data?: Buffer;
|
||||||
|
isBegin?: boolean;
|
||||||
|
isEnd?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export class TtsMix {
|
export class TtsMix {
|
||||||
appId: string;
|
appId: string;
|
||||||
token: string;
|
token: string;
|
||||||
|
emitter: EventEmitter;
|
||||||
constructor(appId: string, token: string) {
|
constructor(appId: string, token: string) {
|
||||||
this.appId = appId;
|
this.appId = appId;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
|
this.emitter = new EventEmitter();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取语音
|
* 获取语音
|
||||||
@ -389,6 +425,12 @@ export class TtsMix {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async getVoiceDemo(speaker: string, text: string, outputPath: string): Promise<void> {
|
async getVoiceDemo(speaker: string, text: string, outputPath: string): Promise<void> {
|
||||||
return runDemo(this.appId, this.token, speaker, text, outputPath);
|
return runDemo(this.appId, this.token, speaker, text, outputPath, this.emitter);
|
||||||
|
}
|
||||||
|
onWriteFile(callback: (data: TTSWriteType) => void) {
|
||||||
|
this.emitter.on('writeFile', callback);
|
||||||
|
return () => {
|
||||||
|
this.emitter.off?.('writeFile', callback);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user