【发布时间】:2019-05-23 14:55:30
【问题描述】:
所以我发现了许多类似的问题,而且似乎归结为对您使用的编码格式的看法不同。我已经尝试过 Base64 和 UTF-8。当我使用 Base64 时,当我解码它们时,Java 端的字节似乎完全改变了,声音基本上只是静态噪声。然而,当我使用 UTF-8 时,我仍然可以听到其中的原始声音,但它非常失真和嘈杂,几乎听不见,但肯定仍然存在。我认为这是因为 UTF-8 没有许多音频字节的字符,所以在编码和解码过程中丢失了很多字符,这就是我尝试 base64 的原因,但这会导致音频更差。我正在流式传输实时麦克风音频,所以我没有一个音频文件,我可以在它到达 Java 后将其与编码类型的字节进行比较。
整个想法是我想将音频字节打包在 JSON 字符串中,以便从 C# 发送到 Java,而不是单独流式传输原始音频字节(效果很好)。我想这样做的原因是因为我也希望能够传达其他非音频内容,并且也计划为此使用 JSON。
有没有更好的方法将音频编码为可以在 JSON 中使用的字符串?或者,如果您尝试将它们编码为字符串,音频字节基本上会导致数据丢失?
对于我的 base64 尝试,我在 C# 中使用:
Convert.ToBase64String(byteBuffer);
在 Java 方面,我尝试使用
进行解码DatatypeConverter.parseBase64Binary(audioBufferData);
和
BASE64Decoder decoder = new BASE64Decoder();
byte[] bufferBytes = decoder.decodeBuffer(audioBufferData);
对于 UTF-8,我在 C# 中使用了
Encoding.UTF8.GetString(byteBuffer);
在 Java 中
audioBufferData.getBytes("UTF-8");
我在 Unity 中使用名为“NatMic”的资产来获取实时麦克风输入。它给了我一个 float[] sampleBuffer ,它按如下方式转换为字节:
var shortBuffer = new short[sampleBuffer.Length];
var byteBuffer = new byte[Buffer.ByteLength(shortBuffer)];
for (int i = 0; i < sampleBuffer.Length; i++)
shortBuffer[i] = (short)(sampleBuffer[i] * short.MaxValue);
Buffer.BlockCopy(shortBuffer, 0, byteBuffer, 0, byteBuffer.Length);
然后 byteBuffer 像上面一样被编码并发送到服务器。如果我在不编码的情况下发送字节并在 Java 中使用 Little Endian 格式 SourceDataLine 直接播放它们,这听起来很完美,但是在编码为 base64 之后,我必须更改 SourceDataLine 的格式以期望 Big Endian 能够正确播放。由于其他原因,我必须保持 Little Endian 顺序。
【问题讨论】:
-
发送base64已知数据,解码,看看有什么问题。您确定播放设置为正确的签名和字节序吗? Base64 不会以任何方式改变数据。
-
你能发布你的尝试吗?或者至少,发布原始字节版本。
-
大家好,我添加了更多代码。是的,音频数据的格式正确。如果我不编码为字符串而只是将音频作为字节发送,我可以用 Java 播放它,听起来绝对完美。编码和解码发生了一些事情,导致它变成静态的。 @SamiKuhmonen
-
然后你需要检查字节顺序,例如。这是最合乎逻辑的问题
-
@SamiKuhmonen,是的,你是对的。如果您发表评论作为答案,我会选择它作为答案。解码后它是 BigEndian,但在我将它设置为期望 LittleEndian 之前。