You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中使用AudioRecord录制的音频文件无法播放求助

问题分析与解决方案

嘿,刚接触Android开发就能写出这样的录制逻辑已经很不错了!你的问题核心很明确:你生成的.wav文件其实只是原始PCM数据,缺少WAV格式必须的文件头信息,播放器根本不知道该怎么解析这些原始字节,所以没法播放。

核心修复:补全WAV文件头

你的copyWaveFile方法现在只是把临时.raw文件里的PCM数据直接复制到了.wav文件里,但WAV格式要求开头必须包含描述音频属性的文件头。下面是修改后的完整方法:

private void copyWaveFile(String inFilename, String outFilename){
    FileInputStream in = null;
    FileOutputStream out = null;
    long totalAudioLen = 0;
    long totalDataLen;
    long longSampleRate = RECORDER_SAMPLERATE;
    int channels = (RECORDER_CHANNELS == AudioFormat.CHANNEL_IN_STEREO) ? 2 : 1;
    long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels / 8;

    byte[] data = new byte[bufferSize];

    try {
        in = new FileInputStream(inFilename);
        out = new FileOutputStream(outFilename);
        totalAudioLen = in.getChannel().size();
        totalDataLen = totalAudioLen + 36; // WAV头的长度是44字节,这里36是因为后面会写8字节的RIFF和WAVE标识

        // 写入WAV文件头
        writeWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate);

        // 写入PCM数据
        while (in.read(data) != -1) {
            out.write(data);
        }

        in.close();
        out.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 新增:写入WAV文件头的方法
private void writeWaveFileHeader(FileOutputStream out, long totalAudioLen,
                                 long totalDataLen, long longSampleRate, int channels, long byteRate)
        throws IOException {
    byte[] header = new byte[44];

    // RIFF标识
    header[0] = 'R';
    header[1] = 'I';
    header[2] = 'F';
    header[3] = 'F';
    // 文件总长度(RIFF标识 + 后续数据长度)
    header[4] = (byte) (totalDataLen & 0xff);
    header[5] = (byte) ((totalDataLen >> 8) & 0xff);
    header[6] = (byte) ((totalDataLen >> 16) & 0xff);
    header[7] = (byte) ((totalDataLen >> 24) & 0xff);
    // WAVE标识
    header[8] = 'W';
    header[9] = 'A';
    header[10] = 'V';
    header[11] = 'E';
    // fmt子块标识
    header[12] = 'f';
    header[13] = 'm';
    header[14] = 't';
    header[15] = ' ';
    // fmt子块长度(PCM格式为16)
    header[16] = 16;
    header[17] = 0;
    header[18] = 0;
    header[19] = 0;
    // 音频格式(PCM为1)
    header[20] = 1;
    header[21] = 0;
    // 声道数
    header[22] = (byte) channels;
    header[23] = 0;
    // 采样率
    header[24] = (byte) (longSampleRate & 0xff);
    header[25] = (byte) ((longSampleRate >> 8) & 0xff);
    header[26] = (byte) ((longSampleRate >> 16) & 0xff);
    header[27] = (byte) ((longSampleRate >> 24) & 0xff);
    // 字节率
    header[28] = (byte) (byteRate & 0xff);
    header[29] = (byte) ((byteRate >> 8) & 0xff);
    header[30] = (byte) ((byteRate >> 16) & 0xff);
    header[31] = (byte) ((byteRate >> 24) & 0xff);
    // 块对齐(声道数*位深/8)
    header[32] = (byte) (channels * 16 / 8);
    header[33] = 0;
    // 位深
    header[34] = RECORDER_BPP;
    header[35] = 0;
    // data子块标识
    header[36] = 'd';
    header[37] = 'a';
    header[38] = 't';
    header[39] = 'a';
    // 音频数据长度
    header[40] = (byte) (totalAudioLen & 0xff);
    header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
    header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
    header[43] = (byte) ((totalAudioLen >> 24) & 0xff);

    out.write(header, 0, 44);
}

为什么这样修改?

WAV文件由文件头和PCM音频数据两部分组成:

  • 文件头包含了音频的关键参数:采样率、声道数、位深、数据长度等,播放器靠这些信息来解码音频。
  • 之前你直接复制PCM数据,播放器没有这些元数据,自然无法识别播放。

其他需要检查的潜在问题

  • 权限问题:确保你在AndroidManifest.xml中添加了录音权限和存储权限,并且在运行时请求了这些权限(Android 6.0及以上需要动态申请):
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  • BufferSize的正确性:AudioRecord.getMinBufferSize()返回的是最小缓冲区大小,实际使用时可以适当放大(比如乘以2),避免出现缓冲区溢出的问题。
  • 线程安全:isRecording变量建议用volatile修饰,确保线程之间的可见性:
    private volatile boolean isRecording = false;
    

测试验证

修改完代码后,重新录制音频,你会发现生成的.wav文件已经可以正常播放了。如果还是有问题,可以用Audacity等音频工具打开文件,查看是否能识别到音频参数,进一步排查问题。

内容的提问来源于stack exchange,提问作者Umut Gür

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:32:37