录制的音频文件无法播放

时间:2018-05-13 19:15:49

标签: java android audio-recording

我尝试在Android上使用带有Java的AudioRecord类创建音轨。该文件保存到我使用我想要的名称和扩展名指定的目录。问题是,我无法播放录制的文件。

这是代码;

public class RecordActivity extends AppCompatActivity {

FloatingActionButton recordButton = null;
Chronometer chronometer = null;

boolean isRecording = false;
private int bufferSize = 0;

private AudioRecord recorder = null;

private static final int RECORDER_BPP = 16;
private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

private Thread recordingThread = null;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_record);

    recordButton = findViewById(R.id.fabbtn_record);
    chronometer = findViewById(R.id.ch_recorder);

    recordButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(!isRecording)
            {
                recordButton.setImageResource(R.drawable.ic_record_stop);
                chronometer.start();
                isRecording = true;
                startRecording();
            }
            else {
                recordButton.setImageResource(R.drawable.ic_record_mic);
                chronometer.stop();
                chronometer.setBase(SystemClock.elapsedRealtime());
                isRecording = false;
                stopRecording();
            }
        }
    });
}

private void startRecording(){

    bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);

    recorder = new AudioRecord(
            MediaRecorder.AudioSource.MIC,
            RECORDER_SAMPLERATE,
            RECORDER_CHANNELS,
            RECORDER_AUDIO_ENCODING,
            bufferSize);

    int i = recorder.getState();

    if(i == 1)
    {
        recorder.startRecording();
    }

    recordingThread = new Thread(new Runnable() {
        @Override
        public void run() {
            writeAudioDataToFile();
        }
    }, "Record Thread");
    recordingThread.start();
}

private void stopRecording(){

    if (null != recorder)
    {
        int i = recorder.getState();

        if (i == 1) {
            recorder.stop();
        }
        recorder.release();
        recorder = null;
        recordingThread = null;
    }

    copyWaveFile(getTempFileName(), getFileName());
    deleteTempFile();
}

private void writeAudioDataToFile(){
    byte[] data = new byte[bufferSize];
    String fileName = getTempFileName();
    FileOutputStream os = null;

    try
    {
        os = new FileOutputStream(fileName);
    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }

    int read = 0;
    if (null != os)
    {
        while (isRecording)
        {
            read = recorder.read(data, 0, bufferSize);

            if (AudioRecord.ERROR_INVALID_OPERATION != read)
            {
                try
                {
                    os.write(data);
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        try
        {
            os.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

private void copyWaveFile(String inFilename, String outFilename){
    FileInputStream in = null;
    FileOutputStream out = null;
    long totalAudioLen = 0;
    long totalDataLen = totalAudioLen + 36;
    long longSampleRate = RECORDER_SAMPLERATE;
    int channels = 2;
    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;

        while (in.read(data) != -1) {
            out.write(data);
        }

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

private String getTempFileName(){
    String filePath = Environment.getExternalStorageDirectory().getPath();
    File file = new File(filePath, AUDIO_RECORDER_FOLDER);

    if(!file.exists()){
        file.mkdirs();
    }

    File tempFile = new File(filePath, AUDIO_RECORDER_TEMP_FILE);

    if (tempFile.exists()){
        tempFile.delete();
    }
    return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
}

private String getFileName(){
    String filepath = Environment.getExternalStorageDirectory().getPath();
    File file = new File(filepath, AUDIO_RECORDER_FOLDER);
    if (!file.exists()) {
        file.mkdirs();
    }

    return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + AUDIO_RECORDER_FILE_EXT_WAV);
}

private void deleteTempFile() {
    File file = new File(getTempFileName());
    file.delete();
}

很抱歉代码的长度因为我对Android编程很新,所以我不确定它对你来说重要。

1 个答案:

答案 0 :(得分:0)

问题是无法使用普通数据保存扩展名为.wav的文件。我设置了这样的标题;

private void WriteWaveFileHeader(
        FileOutputStream out, long totalAudioLen,
        long totalDataLen, long longSampleRate, int channels,
        long byteRate) throws IOException {

    byte[] header = new byte[44];

    header[0] = 'R'; // RIFF/WAVE header
    header[1] = 'I';
    header[2] = 'F';
    header[3] = 'F';
    header[4] = (byte) (totalDataLen & 0xff);
    header[5] = (byte) ((totalDataLen >> 8) & 0xff);
    header[6] = (byte) ((totalDataLen >> 16) & 0xff);
    header[7] = (byte) ((totalDataLen >> 24) & 0xff);
    header[8] = 'W';
    header[9] = 'A';
    header[10] = 'V';
    header[11] = 'E';
    header[12] = 'f'; // 'fmt ' chunk
    header[13] = 'm';
    header[14] = 't';
    header[15] = ' ';
    header[16] = 16; // 4 bytes: size of 'fmt ' chunk
    header[17] = 0;
    header[18] = 0;
    header[19] = 0;
    header[20] = 1; // format = 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);
    header[32] = (byte) (2 * 16 / 8); // block align
    header[33] = 0;
    header[34] = RECORDER_BPP; // bits per sample
    header[35] = 0;
    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);
}

问题解决了。