- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Twilio 语音通话和 Discord 语音 channel 之间接收和传输音频。我正在努力弄清楚如何转换我从 DSharpPlus 接收的音频数据(.NET 的 Discord 库)转换为 Twilio Voice 所需的格式。
如果我正在阅读 DSharpPlus' docs correctly ,来自 DSharpPlus 的 PCM 数据是 PCM S16LE 格式。Twilio 希望数据采用 MU-LAW/8000 格式(我认为不包括标题)。
我正在尝试使用 NAudio转换数据,但我从电话里听到的只是刺耳的痛苦噪音。我不能使用完整的 NAudio 库,因为这个项目应该在 Windows/Mac/Linux 上工作,并且一些 NAudio API 仅适用于 Windows。
这是我目前拥有的相关代码:
private async Task VoiceReceiveHandler(VoiceNextConnection connection, VoiceReceiveEventArgs args)
{
if (twilioSocketConnectionManager.TryGetSocketById(socketId, out var twilioSocket) && twilioSocket.Socket.State == WebSocketState.Open)
{
var media = ConvertPcmToMulawBase64Encoded(args.AudioFormat, args.PcmData.ToArray());
var json = JsonSerializer.Serialize<MediaMessage>
(
new MediaMessage("media", twilioSocket.StreamSid, new MediaPayload(media)),
jsonSerializerOptions
);
logger.LogInformation(json);
var bytes = Encoding.Default.GetBytes(json);
var arraySegment = new ArraySegment<byte>(bytes, 0, bytes.Length);
await twilioSocket.Socket.SendAsync(arraySegment, WebSocketMessageType.Text, WebSocketMessageFlags.EndOfMessage, CancellationToken.None);
}
}
private static string ConvertPcmToMulawBase64Encoded(AudioFormat audioFormat, byte[] pcmData)
{
var sourceFormat = new WaveFormat(audioFormat.SampleRate, 16, audioFormat.ChannelCount);
return Convert.ToBase64String(EncodeMuLaw(pcmData, 0, pcmData.Length));
}
public static byte[] EncodeMuLaw(byte[] data, int offset, int length)
{
var encoded = new byte[length / 2];
int outIndex = 0;
for(int n = 0; n < length; n+=2)
{
encoded[outIndex++] = MuLawEncoder.LinearToMuLawSample(BitConverter.ToInt16(data, offset + n));
}
return encoded;
}
我还需要再次从 MU-LAW 转换为 PCM S16LE,但首先要做的是。
我对音频处理一窍不通,所以请放轻松。
这是源代码的其余部分:https://github.com/Swimburger/DiscordTwilioVoiceBot
基本上我的问题是,如何在支持 Windows/Linux/Mac 的情况下使用 .NET 将 PCM S16LE 音频转换为 MU-LAW/8000?
更新 1:
人们建议使用 ffmpeg 而不是 NAudio,我认为我在这里做的是正确的,但我仍然听到尖锐的噪音而不是实际的音频。
private async Task VoiceReceiveHandler(VoiceNextConnection connection, VoiceReceiveEventArgs args)
{
var ffmpeg = Process.Start(new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $@"-hide_banner -ac 2 -f s16le -ar 48000 -i pipe:0 -c:a pcm_mulaw -f mulaw -ar 8000 -ac 1 pipe:1",
RedirectStandardInput = true,
RedirectStandardOutput = true
});
//byte[] trimmedData = new byte[args.PcmData.Length - 44];
//Buffer.BlockCopy(args.PcmData.ToArray(), 44, trimmedData, 0, trimmedData.Length);
await ffmpeg.StandardInput.BaseStream.WriteAsync(args.PcmData);
ffmpeg.StandardInput.Close();
byte[] data;
using(var memoryStream = new MemoryStream())
{
ffmpeg.StandardOutput.BaseStream.CopyTo(memoryStream);
data = memoryStream.ToArray();
}
ffmpeg.Dispose();
//byte[] trimmedData = new byte[data.Length - 44];
//Buffer.BlockCopy(data, 44, trimmedData, 0, trimmedData.Length);
//return;
if (twilioSocketConnectionManager.TryGetSocketById(socketId, out var twilioSocket) && twilioSocket.Socket.State == WebSocketState.Open)
{
var json = JsonSerializer.Serialize<MediaMessage>
(
new MediaMessage("media", twilioSocket.StreamSid, new MediaPayload(Convert.ToBase64String(data))),
jsonSerializerOptions
);
logger.LogInformation(json);
var bytes = Encoding.Default.GetBytes(json);
var arraySegment = new ArraySegment<byte>(bytes, 0, bytes.Length);
await twilioSocket.Socket.SendAsync(arraySegment, WebSocketMessageType.Text, WebSocketMessageFlags.EndOfMessage, CancellationToken.None);
}
}
这是在 separate branch 上.
最佳答案
我有一个类似的问题,将 Twilio 的 MU-LAW 转换为 PCM 16LE 以流式传输到 Azure 认知服务转录服务。我是用 Java 而不是 dotnet 编写的,我没有找到好的库解决方案。
但是,可以使用查找表一次一个字节地完成转换(请注意,一个字节的 mulaw 由 2 个字节的 pcm 表示)。有一个 rather abstract description of the algorithm on wikipedia ,然后我找到了 this dotnet repo的代码很容易翻译成 Java,并且运行良好。对于您的情况,您需要查看 MulawDecoder.cs。
我为 mulaw->pcm 生成的 Java 代码是 here .
关于c# - 如何使用 .NET (Windows/Mac/Linux) 将 PCM S16LE 音频转换为 MU-LAW/8000,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70599169/
当我向我的安装程序添加依赖项时,我总是留下文件的硬编码路径。 根据 this blog ,解决此问题的唯一方法是使用 ISProjectFolder 变量手动更改 ISL 文件中的硬编码路径。这没有任
我想开发像蓝牙 LE 外围设备这样的应用程序,它停止在与蓝牙 LE 中央设备连接时做广告,并限制与多个蓝牙 LE 中央设备连接的蓝牙 LE 外围设备。 一个蓝牙 LE 外围设备一次只能与一个蓝牙 LE
示例代码: # Step 1 $start = get-date for($i=1; $i -le 1000000; $i++){} $end = get-date ($end-$start).Tot
在Basic customisation ,python 文档说明了比较方法: [no swapped-argument versions of these methods]; rather, __l
蓝牙双模设备是否可以在与 BT LE 设备配对的同时被经典蓝牙发现?如果设备不能同时运行这两种模式也没关系,但我真的应该在这些模式之间切换芯片吗?我只是在 BT 4 Core 规范中找不到答案 最佳答
我正在尝试使用 fscanf 从输入文件中读取 3 个 double 值,但在尝试这样做时遇到了段错误。我的代码如下: FILE * infile = fopen(argv[1], "r");
我的域指向另一个网站,我想为其安装 LE 证书,这可能吗,或者我的域应该链接到服务器? 最佳答案 letsencrypt 不允许安装非 NS 指向,因为它检查反向验证,所以它会失败 关于wordpre
在我的 Android(API 版本 21 及更高版本)Bluetooth LE 应用程序中,该应用程序首先使用 BluetoothLeScanner 和 ScanCallback 对象扫描外围设备。
我正在使用 Xamarin 和这个 BLE 插件构建一个 iOS 应用程序: https://github.com/aritchie/bluetoothle 我只是通过 BLE 广播一个 UUID,它
我可以在点击时同时扫描蓝牙和蓝牙 LE 设备吗? 最佳答案 答案是否定的。 原文来自: http://developer.android.com/guide/topics/connectivity/b
关于 Dennis Mathews answer,您如何在 iOS 上指定经典蓝牙而不是 LE?有没有和Core Bluetooth Framework?不同的api 最佳答案 Joels 有一种在
我有一个使用 BLE 的应用程序。在某些情况下,例如当安装在 iPhone 6 上时,应用程序正在运行并且不请求使用 BLE 的许可。 在其他情况下,比如我的 iPad Air,应用程序开始运行,并且
我尝试使用 Bluetooth LE 检测设备,按照 Xamarin 库中的说明执行此操作,但设备发现 0 包括 android 中的必要声明。将扫描时间增加到 30 秒,但没有任何效果。支持蓝牙,版
配对“普通”蓝牙设备和配对蓝牙 LE 设备之间是否存在任何(大)技术差异? 我找到了很多关于蓝牙 LE 配对的信息,但没有正常的?例如 Info 1 . 那么普通蓝牙的这个信息也正确吗? 最佳答案 如
我尝试使用下面的代码将发现的设备的UUID存储到Array,然后在该阵列中选择UUID进行连接,但无法运行。 - (void)centralManager:(CBCentralManager *)ce
我正在研究一个通过蓝牙 LE 发送数据的 Android 应用程序。这里有两种方法让我感到困惑。有人可以解释一下这两种方法及其相互关系吗: private String localmessage =
我在使用 BluetoothLeScanner 的 startScan 方法时遇到了问题,找到了一个 BLE 设备,但是当我关闭 BLE 设备时,我的手机仍然显示此设备已打开!! 我尝试过使用: pr
我使用 StartLeScan 已经有一段时间了,扫描后返回的设备的名称从未被填充。我永远无法弄清楚为什么,我只是找回了 mac 地址。今天我从 OS BT 设置页面运行扫描,它只显示 MAC 地址,
在实现大量使用 Service 的 Android 应用程序方面,我不是很有经验,而且我在 SO 或 github 上找不到任何好的建议或示例来帮助我(或者只是谷歌搜索)所以我决定问我自己的问题。 当
开发用于蓝牙技术的移动应用程序能否用于蓝牙 LE 技术? 或者开发人员是否需要修改代码来处理蓝牙 LE(智能)信号、输入、输出等? 编辑 问这个问题的时候我想知道 如果我写一段代码,我可以在 BLE
我是一名优秀的程序员,十分优秀!