将音频文件转换为线性 PCM 16 位
convert audio file to Linear PCM 16-bit
我正在尝试通过 websocket 发送音频文件,我意识到为此我需要将 mp3 文件转换为线性 PCM 16 位代码,但我找不到方法所以。
这是我想要做的:
let mp3File = // the 16-bit pcm file
ws.on('message', async(msg) => {
if (typeof msg === "string") {
} else if (recognizeStream) {
recognizeStream.write(msg);
}
ws.send(mp3File) <== stream back the audio file
});
});
一些背景,流是一个 phone 调用(通过 vonage api)所以 ny ws 连接到 phone 调用并听到用户输入,然后经过一些逻辑我的服务器 我想通过 ws.send().
向用户播放一个 mp3 文件,该文件是我服务器中的本地文件
------------更新--------
现在,如果我从流中发送 pcm 数据(来自 phone 调用的原始音频)
它的工作原理(服务器回应 phone 调用)
所以我想将 mp3 文件转换为相同的格式,以便我可以通过 ws.send().
将其发送到
------------更新2--------
以正确的格式制作我的音频文件后:
“线性 PCM 16 位,采样率为 8kHz 或 16kHz,帧大小为 20ms”
我正在尝试通过网络套接字发送文件,但我不知道该怎么做,
我在项目文件夹中有该文件,但我不知道如何通过 websocket 发送它,我寻找如何这样做但我没有找到任何东西。
我正在尝试执行此处指定的操作:
首先让我们了解一下这是什么意思:
Linear PCM 16-bit, with either a 8kHz or a 16kHz sample rate, and a
20ms frame size
他们在这里谈论两件事:
- 音频数据的格式,即“线性 PCM 16 位,具有 8kHz 或 16kHz 采样率”
- 您如何将此音频数据发送给他们以及他们如何将其发送给您:在价值 20 毫秒帧的音频数据块中
根据音频格式,如果选择“16bit Linear PCM with sample rate of 16K”意味着:
- 采样率 = 16000
- 采样宽度=16位=2字节
因此 1 秒的音频块将包含字节数 = (16000 * 2) = 32000 字节
这意味着 20 毫秒/0.02 秒的音频帧将相当于 (32000*0.2) = 640 字节
需要两件事:
将 mp3 转换为 wav。在你的系统上安装 ffmpeg 和 运行 这个命令
ffmpeg -i filename.mp3 -ar 16000 -sample_fmt s16 output.wav
这会将您的 filename.mp3
转换为 output.wav
,这将是 16K 采样率中的 16 位线性 PCM
在您的代码中,当您发送回音频时,您需要将其作为 640 字节的块进行流式传输,而不是一次性传输整个文件数据。有 3 个选项:
- 运行 一个写入循环将所有音频写入 websocket,但以 640 字节的块为单位。
但这有一个问题,Nexmo 只会缓冲前 20 秒的音频。超出此范围的任何内容都将被丢弃
- 启动一个异步任务,每 20 毫秒 运行s 并将 640 字节的数据写入 websocket。
- 当你从 nexmo 获得音频时写下(这是我将展示的)
由于 nexmo 将每 20 毫秒向您发送 640 个字节,您可以同时发送回 640 个字节。
我正在使用 npm websocket
包编写此示例。
var fs = require('fs');
var binaryData = fs.readFileSync('output.wav');
var start = 44 // discard the wav header
var chunkSize = 640
...
// ws is a websocket connection object
connection.on('message', function(message) {
if (message.type === 'utf8') {
// handle a text message here
}
else if (message.type === 'binary') {
// print length of audio sent by nexmo. will be 640 for 16K and 320 for 8K
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
if (start >= binaryData.length) {
// slice a chunk and send
toSend = binaryData.slice(start, start + chunkSize)
start = start + chunkSize
connection.sendBytes(toSend);
console.log('Sent Binary Message of ' + toSend.length + ' bytes');
}
} ...
});
请记住,从您将音频从您的服务器发送到 nexmo 到您在另一端听到时会有一些延迟。
它可能从半秒到更多不等,具体取决于 Nexmo 数据中心的位置、您 运行 您的代码所在的服务器的位置、网络速度等。
我观察到它接近 0.5 秒。
我正在尝试通过 websocket 发送音频文件,我意识到为此我需要将 mp3 文件转换为线性 PCM 16 位代码,但我找不到方法所以。
这是我想要做的:
let mp3File = // the 16-bit pcm file
ws.on('message', async(msg) => {
if (typeof msg === "string") {
} else if (recognizeStream) {
recognizeStream.write(msg);
}
ws.send(mp3File) <== stream back the audio file
});
});
一些背景,流是一个 phone 调用(通过 vonage api)所以 ny ws 连接到 phone 调用并听到用户输入,然后经过一些逻辑我的服务器 我想通过 ws.send().
向用户播放一个 mp3 文件,该文件是我服务器中的本地文件------------更新--------
现在,如果我从流中发送 pcm 数据(来自 phone 调用的原始音频) 它的工作原理(服务器回应 phone 调用) 所以我想将 mp3 文件转换为相同的格式,以便我可以通过 ws.send().
将其发送到------------更新2--------
以正确的格式制作我的音频文件后: “线性 PCM 16 位,采样率为 8kHz 或 16kHz,帧大小为 20ms”
我正在尝试通过网络套接字发送文件,但我不知道该怎么做, 我在项目文件夹中有该文件,但我不知道如何通过 websocket 发送它,我寻找如何这样做但我没有找到任何东西。
我正在尝试执行此处指定的操作:
首先让我们了解一下这是什么意思:
Linear PCM 16-bit, with either a 8kHz or a 16kHz sample rate, and a 20ms frame size
他们在这里谈论两件事:
- 音频数据的格式,即“线性 PCM 16 位,具有 8kHz 或 16kHz 采样率”
- 您如何将此音频数据发送给他们以及他们如何将其发送给您:在价值 20 毫秒帧的音频数据块中
根据音频格式,如果选择“16bit Linear PCM with sample rate of 16K”意味着:
- 采样率 = 16000
- 采样宽度=16位=2字节
因此 1 秒的音频块将包含字节数 = (16000 * 2) = 32000 字节 这意味着 20 毫秒/0.02 秒的音频帧将相当于 (32000*0.2) = 640 字节
需要两件事:
将 mp3 转换为 wav。在你的系统上安装 ffmpeg 和 运行 这个命令
ffmpeg -i filename.mp3 -ar 16000 -sample_fmt s16 output.wav
这会将您的filename.mp3
转换为output.wav
,这将是 16K 采样率中的 16 位线性 PCM在您的代码中,当您发送回音频时,您需要将其作为 640 字节的块进行流式传输,而不是一次性传输整个文件数据。有 3 个选项:
- 运行 一个写入循环将所有音频写入 websocket,但以 640 字节的块为单位。 但这有一个问题,Nexmo 只会缓冲前 20 秒的音频。超出此范围的任何内容都将被丢弃
- 启动一个异步任务,每 20 毫秒 运行s 并将 640 字节的数据写入 websocket。
- 当你从 nexmo 获得音频时写下(这是我将展示的) 由于 nexmo 将每 20 毫秒向您发送 640 个字节,您可以同时发送回 640 个字节。
我正在使用 npm websocket
包编写此示例。
var fs = require('fs');
var binaryData = fs.readFileSync('output.wav');
var start = 44 // discard the wav header
var chunkSize = 640
...
// ws is a websocket connection object
connection.on('message', function(message) {
if (message.type === 'utf8') {
// handle a text message here
}
else if (message.type === 'binary') {
// print length of audio sent by nexmo. will be 640 for 16K and 320 for 8K
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
if (start >= binaryData.length) {
// slice a chunk and send
toSend = binaryData.slice(start, start + chunkSize)
start = start + chunkSize
connection.sendBytes(toSend);
console.log('Sent Binary Message of ' + toSend.length + ' bytes');
}
} ...
});
请记住,从您将音频从您的服务器发送到 nexmo 到您在另一端听到时会有一些延迟。 它可能从半秒到更多不等,具体取决于 Nexmo 数据中心的位置、您 运行 您的代码所在的服务器的位置、网络速度等。 我观察到它接近 0.5 秒。