我在 Twilio 中创建了一个使用 双向流 的电话代理,现在我想记录所有来电。
问题是没有关于如何使用双向媒体流执行此操作的文档。我正在使用 twilio-media-stream-save-audio-file npm 包,它可以让我将音频从媒体流保存到 wav 文件,但正如 documentation 指出的那样:
使用双向媒体流,您只能接收入站曲目。
因此,当我设置录音机来保存 Twilio websocket 收到的所有
media
类型消息时,它仅记录呼叫者的音频,而不记录我的服务器发送回 Twilio 的音频(我正在使用 Eleven Labs 生成音频)。
代码:
录制来电者音频:
sendAudio(audio: string): void {
const audioInput = {
encodedAudioData: audio,
};
this.sendMessage("audio_input", audioInput);
// Record caller audio
if (this.callerSpeaking) {
this.mediaStreamSaver.twilioStreamMedia(audio);
}
}
录制人工智能音频:
async sendAudioToTwilio(audioBase64: string, twilioConnection: TwilioSocket) {
const twilioMediaMessage = {
event: "media",
streamSid: twilioConnection.streamSid,
media: {
payload: audioBase64,
},
};
if (twilioConnection.ws.readyState === 1) {
// Record AI audio
if (this.aiSpeaking && !this.callerSpeaking) {
this.mediaStreamSaver.twilioStreamMedia(audioBase64);
}
twilioConnection.ws.send(JSON.stringify(twilioMediaMessage));
} else {
console.error(
"Twilio WebSocket is not open. Current state:",
twilioConnection.ws.readyState
);
}
}
我当前的方法是手动记录每个流,如上所示,但这会导致在使用
clear
消息时处理重叠音频和修剪出站音频的困难问题。最后,录音代表了电话通话的 80%,但我更喜欢一种方法来记录听到的确切音频。
record
属性的拨号动词:用于录制正常通话,不涉及媒体流
事实证明这非常简单。这篇文章有答案。
当您的 Websocket 收到
start
消息时,记录 callSid
:
const callSid = jsonMessage.start.callSid;
connection.callSid = callSid;
console.log(`CallSid: ${callSid}`);
startRecording(callSid, connection);
然后使用您的账户 ID 和 callSid 调用
Recordings
端点:
// https://help.twilio.com/articles/360010317333-Recording-Incoming-Twilio-Voice-Calls
const startRecording = async (
callSid: string,
twilioConnection: TwilioSocket
) => {
try {
const twilioAccountSid = process.env.TWILIO_ACCOUNT_SID;
const twilioAuthToken = process.env.TWILIO_AUTH_TOKEN;
const response = await fetch(
`https://api.twilio.com/2010-04-01/Accounts/${twilioAccountSid}/Calls/${callSid}/Recordings.json`,
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization:
"Basic " + btoa(`${twilioAccountSid}:${twilioAuthToken}`),
},
body: new URLSearchParams({
RecordingStatusCallback: `https://${twilioConnection.host}/recording-callback`,
RecordingStatusCallbackEvent: "in-progress completed absent",
}),
}
);
const data = await response.json();
console.log("Recording started:", data);
} catch (error) {
console.error("Error starting recording:", error);
}
};