如何在Android中将记录的原始PCM数据保存/编码为AAC / MP4格式文件

时间:2015-01-27 06:06:06

标签: android ffmpeg audiorecord android-audiorecord libfaac

我想将刻录机pcm数据保存为aac / mp4格式文件。 我正在使用AudioRecord类在android中录制音频。通过向原始数据添加波形头,我已成功将其保存为波形文件。但不知道如何将其保存为aac / mp4文件,因为aac / mp4格式被压缩然后波动。 我用来保存pcm数据的方法粘贴在下面。

recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
            SavedSampleRate, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING,
            bufferSize);
recorder.startRecording();
isRecording = true;

isRecording = true;

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

recordingThread.start();

第二

private void writeAudioDataToFile() {

    byte data[] = new byte[bufferSize];
    // short sData[] = new short[bufferSize];
    String filename = getTempFilename();
    FileOutputStream os = null;

    try {
        os = new FileOutputStream(filename);
    } catch (Exception e) {
        e.printStackTrace();
    }

    int read = 0;

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

            if (AudioRecord.ERROR_INVALID_OPERATION != read) {
                try {

                    synchronized (this) {


                        // Necessary in order to convert negative shorts!
                        final int USHORT_MASK = (1 << 16) - 1;

                        final ByteBuffer buf = ByteBuffer.wrap(data).order(
                                ByteOrder.LITTLE_ENDIAN);

                        final ByteBuffer newBuf = ByteBuffer.allocate(
                                data.length).order(ByteOrder.LITTLE_ENDIAN);

                        int sample;

                        while (buf.hasRemaining()) {



                            short shortSample = buf.getShort();
                            sample = (int) shortSample & USHORT_MASK;



                            sample = sample * db_value_global;
                            sample = mRmsFilterSetting.filter
                                    .apply((((int) 0) | shortSample)
                                            * db_value_global);



                            newBuf.putShort((short) sample);
                        }

                        data = newBuf.array();

                        os.write(data);





                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

最后将其保存为

private void copyWaveFile(ArrayList<String> inFilename, String outFilename) {
    FileInputStream[] in = null;
    FileOutputStream out = null;
    long totalAudioLen = 0;
    long totalDataLen = totalAudioLen + 36;
    long longSampleRate = SavedSampleRate;
    int channels = 2;
    long byteRate = RECORDER_BPP * SavedSampleRate * channels / 8;

    byte[] data = new byte[bufferSize];

    try {
        out = new FileOutputStream(outFilename);

        in = new FileInputStream[inFilename.size()];

        for (int i = 0; i < in.length; i++) {
            in[i] = new FileInputStream(inFilename.get(i));
            totalAudioLen += in[i].getChannel().size();
        }

        totalDataLen = totalAudioLen + 36;

        WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
                longSampleRate, channels, byteRate);

        for (int i = 0; i < in.length; i++) {
            while (in[i].read(data) != -1) {
                out.write(data);
            }

            in[i].close();
        }

        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}



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);
}

在这段代码中,我用AudioRecord录制小型PCM文件,并通过添加波形头将它们保存为波形文件。

是否有任何分步教程,如何将pcm数据保存为mp4 / aac文件。

提前感谢。

0 个答案:

没有答案