据我所知,Java 声音 api 不会转换为 RAW 音频。它确实转换为 WAV,即RAW audio with a 44-byte header。一旦你理解了这一点,你就可以把问题分解成两部分:
1.将音频从任何格式转换为 WAV 格式。
下面的代码示例仅在 WAV 到 WAV(不同的音频格式)之间进行了测试,但理论上对 AudioSystem.getAudioInputStream(audioFormat, originalAudioStream); 的调用应该会找到合适的编解码器(如果有的话)。
此方法会将音频字节转换为给定的格式,并生成一个 byte[] 结果作为 WAV。
private static final AudioFormat EXAMPLE_FORMAT = new AudioFormat(
16_000,
16,
1,
true,
false
);
public byte[] formatAudioToWav(@NotNull final byte[] audioFileContent,
@NotNull final AudioFormat audioFormat) throws
IOException,
UnsupportedAudioFileException {
try (
final AudioInputStream originalAudioStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(audioFileContent));
final AudioInputStream formattedAudioStream = AudioSystem.getAudioInputStream(audioFormat, originalAudioStream);
final AudioInputStream lengthAddedAudioStream = new AudioInputStream(formattedAudioStream, audioFormat, audioFileContent.length);
final ByteArrayOutputStream convertedOutputStream = new ByteArrayOutputStream()
) {
AudioSystem.write(lengthAddedAudioStream, AudioFileFormat.Type.WAVE, convertedOutputStream);
return convertedOutputStream.toByteArray();
}
}
2。从步骤 1 中创建的 WAV 文件中去除标题。
public byte[] formatWavToRaw(@NotNull final byte[] audioFileContent) {
return Arrays.copyOfRange(audioFileContent, 44, audioFileContent.length);
}
备注
- 该代码的优点是可以正确关闭所有流,但缺点是直接使用 byte[],因此不适用于大文件。它可以转换为纯流,但请注意,在对
new AudioInputStream(formattedAudioStream, audioFormat, audioFileContent.length); 的调用中,您需要其中一个流的长度。
- 另一个缺点是,即使代码清晰易读,也需要创建/包装 3 个 AudioInputStream 才能使其工作,这有点令人费解。我找不到更好的解决方案。
进一步阅读