PCM 音频到文件

Posted

技术标签:

【中文标题】PCM 音频到文件【英文标题】:PCM Audio to File 【发布时间】:2019-09-24 00:14:59 【问题描述】:

我想在 Discord 语音频道中录制音频并使用 Discord Bot 将其保存到文件中。

我每 20 毫秒接收一次音频,作为 pcm 编码的字节 [],我想将其保存到文件中。 MP3 是首选,但我对 ogg 等其他文件格式也没有问题(它可能更容易)。

我正在使用 JDA 版本 4.ALPHA.0_82 并且我还包括 lavaplayer 版本 1.3.17 用于其他功能。如果这些库足够的话会很有帮助,但如果我必须包含更多库也没问题。

【问题讨论】:

我将 PCM 转储到一个文件中,然后通过 discord 将其发回以听到它。当然,这些文件很大,但它可以工作:^) 另请注意,JDA 为您提供 PCM 数据,而不是作品(除非他们在 v4 中更改了某些内容) 我想到了同样的方法,难道没有一种简单的方法可以将其保存为压缩音频格式吗? 我曾经被告知要通过 ffmpeg 进行管道传输。我假设你想要一个跨平台/独立的解决方案 【参考方案1】:

This question 解释了如何将 pcm 转换为 wav。 我通过覆盖方法 AudioReceiveHandler#handleCombinedAudio 将 Discord 音频复制到 List<byte[]>

private List<byte[]> rescievedBytes=new ArrayList<>();
@Override
public void handleCombinedAudio(CombinedAudio combinedAudio) 
    try 
        rescievedBytes.add(combinedAudio.getAudioData(VOLUME));
    catch (OutOfMemoryError e) 
        //close connection
    

之后,我将List 复制到byte[] 并创建了wav 文件。

try 
        int size=0;
        for (byte[] bs : rescievedBytes) 
            size+=bs.length;
        
        byte[] decodedData=new byte[size];
        int i=0;
        for (byte[] bs : rescievedBytes) 
            for (int j = 0; j < bs.length; j++) 
                decodedData[i++]=bs[j];
            
        
        getWavFile(getNextFile(), decodedData);
     catch (IOException|OutOfMemoryError e) 
        e.printStackTrace();
    

private void getWavFile(File outFile, byte[] decodedData) throws IOException 
    AudioFormat format = new AudioFormat(8000, 16, 1, true, false);
    Audiosystem.write(new AudioInputStream(new ByteArrayInputStream(
            decodedData), format, decodedData.length), AudioFileFormat.Type.WAVE, outFile);

如果恢复的音频太大 (OutOfMemoryError),转换将中止。

【讨论】:

你忘了增加 i。 为什么不使用AudioReceiveHandler提供的格式?

以上是关于PCM 音频到文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 上录制 PCM 音频文件?

使用 (Python) Gstreamer 解码音频(到 PCM 数据)

如何将Pcm格式的音频文件转换成Wave格式的文件

如何混合两个 PCM 音频文件

使用 AudioConverter 将 PCM 转换为 AAC 并使用 AVAssetWriter 写入 .mp4 文件时音频失真

在 Python 中检测并录制音频为 PCM 格式