需要将音频字节 [] 编码为要通过 JSON 传输的字符串。将被编码并从 C# 发送,并在 Java 中作为音频字节读取
Need to encode audio byte[] as string to be transferred via JSON. Will be encoded and sent from C# and read as audio bytes in Java
所以我发现了很多类似的问题,似乎归结为对您使用的编码格式的看法不同。我已经尝试过 Base64 和 UTF-8。当我使用 Base64 时,当我解码它们时,字节似乎在 Java 一侧完全改变,声音基本上只是静态噪音。然而,当我使用 UTF-8 时,我仍然可以听到那里的原始声音,但它非常失真和嘈杂,几乎听不见,但绝对仍然在那里。我认为这是因为 UTF-8 没有许多音频字节的字符,所以很多音频字节在编码和解码过程中丢失了,这就是我尝试 base64 的原因,但这导致音频更糟糕。我正在流式传输实时麦克风音频,所以我没有音频文件可以在它到达 Java.
后比较编码类型的字节
整个想法是我想将音频字节打包到 JSON 字符串中,以便从 C# 发送到 Java,而不是单独流式传输原始音频字节(效果非常好)。 Thea 我想这样做的原因是因为我也希望能够交流其他非音频的东西,并且也计划为此使用 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 将直接对您提供的字节进行编码,不会造成问题。最有可能的问题是字节顺序,每一端都不同。从和到字节的转换需要在两端相同。您还没有展示如何从 16 位音频数据中获取字节缓冲区,因此无法建议对该部分进行任何更正。
默认情况下 Java 是大端,而 .NET 采用任何底层架构,通常是小端,因此在某些时候需要进行交换。 Java 的 ByteBuffer
支持设置字节序,这可能会有所帮助。
所以我发现了很多类似的问题,似乎归结为对您使用的编码格式的看法不同。我已经尝试过 Base64 和 UTF-8。当我使用 Base64 时,当我解码它们时,字节似乎在 Java 一侧完全改变,声音基本上只是静态噪音。然而,当我使用 UTF-8 时,我仍然可以听到那里的原始声音,但它非常失真和嘈杂,几乎听不见,但绝对仍然在那里。我认为这是因为 UTF-8 没有许多音频字节的字符,所以很多音频字节在编码和解码过程中丢失了,这就是我尝试 base64 的原因,但这导致音频更糟糕。我正在流式传输实时麦克风音频,所以我没有音频文件可以在它到达 Java.
后比较编码类型的字节整个想法是我想将音频字节打包到 JSON 字符串中,以便从 C# 发送到 Java,而不是单独流式传输原始音频字节(效果非常好)。 Thea 我想这样做的原因是因为我也希望能够交流其他非音频的东西,并且也计划为此使用 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 将直接对您提供的字节进行编码,不会造成问题。最有可能的问题是字节顺序,每一端都不同。从和到字节的转换需要在两端相同。您还没有展示如何从 16 位音频数据中获取字节缓冲区,因此无法建议对该部分进行任何更正。
默认情况下 Java 是大端,而 .NET 采用任何底层架构,通常是小端,因此在某些时候需要进行交换。 Java 的 ByteBuffer
支持设置字节序,这可能会有所帮助。