AudioRecord、AudioTractor实现音频的录制和播放

本文详细介绍使用AudioRecord和AudioTrack进行音频录制与播放的方法,包括常见参数配置、实例代码及封装技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

我们在刚学习多媒体编程的时候,接触音视频的录制时更多的是通过MediaRecorder实现音频的录制;请看我的这篇文章MediaRecorder录制音频及代码的抽取封装
实现音频的播放通过MediaPlayer;可以查看我的这篇博客MediaPlayer播放不同来源的音频文件
SoundPool更多的是播放短而急促的声音,比如:嘟一声!!!比较简单这里就不再累述;
我们可以通过AudioRecorder、AudioTractor实现录制及播放固定的采样率、声道数、音频格式;

知识结构

AudioRecorder:The AudioRecord class manages the audio resources for Java applications to record audio from the audio input hardware of the platform.(大致意思就是AudioRecord以平台的硬件录制音频)

常用方法:
1、构造方法:
AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

  • audioSource:声音来源;如:MediaRecorder.AudioSource.MIC
  • sampleRateInHz:声音采样率
  • audioFormat:声音的格式
  • bufferSizeInBytes:缓存大小;常通过bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
  • channelConfig, audioFormat);求得缓存大小

2、公共方法:
startRecording():开始录制

read(short[] audioData, int offsetInShorts, int sizeInShorts) Reads audio data from the audio hardware for recording into a buffer.

  • audioData :short类型的缓存
  • offsetInShorts :偏移量
  • int sizeInShorts : 需要读取的大小

stop()停止录制


AudioTractor:The AudioTrack class manages and plays a single audio resource for Java applications(大致意思:管理和播放应用中的音频资源)

常用方法:
1、构造函数:
AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode)

  • streamType:播放音频类型;可以设置为AudioManager.STREAM_MUSIC
  • sampleRateInHz、channelConfig、audioFormat这三个参数与上面的AudioRecord设置相同
  • bufferSizeInBytes:通过bufferSizePlay = AudioTrack.getMinBufferSize(sampleRateInHz,channelConfig, audioFormat)获得;

2、公共方法

play():开始播放

pause():暂停

write(short[] audioData, int offsetInShorts, int sizeInShorts):Writes the audio data to the audio hardware for playback.(大致意思:把音频数据写入到audioData中让 audio hardware 回放)

stop():停止

示例代码

package com.example.audiorecorderdemo.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.example.audiorecorderdemo.R;
import com.example.audiorecorderdemo.R.id;
import com.example.audiorecorderdemo.R.layout;

public class Main02Activity extends Activity implements OnClickListener{
    private Button bt_startAuduio;
    private Button bt_stopAudio;
    private Button bt_startPlay;
    private Button bt_stopPlay;
    private AudioRecord mAudioRecord;
    private AudioRecordAsyncTask mAudioRecordAsyncTask;
    private AudioStartAsyncTask mAudioStartAsyncTask;

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

    private void initView() {
        bt_startAuduio = (Button) this.findViewById(R.id.startAudio);
        bt_stopAudio = (Button) this.findViewById(R.id.stopAudio);
        bt_startPlay = (Button) this.findViewById(R.id.startPlay);
        bt_stopPlay = (Button) this.findViewById(R.id.stopPlay);
        bt_startPlay.setOnClickListener(this);
        bt_stopPlay.setOnClickListener(this);
        bt_startAuduio.setOnClickListener(this);
        bt_stopAudio.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.startAudio:
            mAudioRecordAsyncTask = new AudioRecordAsyncTask();
            mAudioRecordAsyncTask.execute();
            bt_startAuduio.setEnabled(false);
            break;
        case R.id.stopAudio:
            isAudioRecording = false;
            bt_startAuduio.setEnabled(true);
            break;
        case R.id.startPlay:
            mAudioStartAsyncTask = new AudioStartAsyncTask();
            mAudioStartAsyncTask.execute();
            break;
        case R.id.stopPlay:
            isPlay = false;
            break;
        default:
            break;
        }
    }

    private boolean isAudioRecording = false;
    private int sampleRateInHz = 8000;
    private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    private int bufferSizeInBytes;

    private void prepareStartRecordAudio() {
        bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
                channelConfig, audioFormat);
        mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes);
        // createAudioRecord();
        mAudioRecord.startRecording();
        isAudioRecording = true;
    }

    private File audioFile;

    private class AudioRecordAsyncTask extends AsyncTask<Void, Void, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            prepareStartRecordAudio();
        }

        @Override
        protected String doInBackground(Void... params) {
            String result = null;
            try {
                // 获取录制视频保存的文件
                audioFile = new File(Environment.getExternalStorageDirectory(),
                        "/audiodatas/files/audioRecord.pcm");
                if (!audioFile.exists()) {
                    audioFile.getParentFile().mkdirs();
                }
                DataOutputStream audioOutputStream = new DataOutputStream(
                        new BufferedOutputStream(
                                new FileOutputStream(audioFile)));
                // 建立一个AudioRecorder读入数据的缓冲区
                short[] buffer = new short[bufferSizeInBytes / 4];

                while (isAudioRecording) {
                    int readResult = mAudioRecord
                            .read(buffer, 0, buffer.length);
                    for (int i = 0; i < readResult; i++) {
                        audioOutputStream.writeShort(buffer[i]);
                    }
                }

                audioOutputStream.close();
                mAudioRecord.stop();
                result = "audio record end !!!";

            } catch (Exception e) {
                result = "sudio record exception !";
            }
            return result;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            Toast.makeText(Main02Activity.this, result, Toast.LENGTH_LONG).show();
        }
    }

    private void createAudioRecord() {
        for (int sampleRate : new int[] { 44100, 8000, 11025, 16000, 22050,
                32000, 47250, 48000 }) {
            for (short audioFormat : new short[] {
                    AudioFormat.ENCODING_PCM_16BIT,
                    AudioFormat.ENCODING_PCM_8BIT }) {
                for (short channelConfig : new short[] {
                        AudioFormat.CHANNEL_IN_MONO,
                        AudioFormat.CHANNEL_IN_STEREO }) {

                    // Try to initialize
                    try {
                        bufferSizeInBytes = AudioRecord.getMinBufferSize(
                                sampleRate, channelConfig, audioFormat);

                        if (bufferSizeInBytes < 0) {
                            continue;
                        }

                        mAudioRecord = new AudioRecord(
                                MediaRecorder.AudioSource.MIC, sampleRate,
                                channelConfig, audioFormat, bufferSizeInBytes);

                        if (mAudioRecord.getState() == AudioRecord.STATE_INITIALIZED) {

                            return;
                        }

                        mAudioRecord.release();
                        mAudioRecord = null;
                    } catch (Exception e) {
                        // Do nothing
                    }
                }
            }
        }

        throw new IllegalStateException(
                "getInstance() failed : no suitable audio configurations on this device.");
    }

    private AudioTrack mAudioTrack;
    private int bufferSizePlay;
    private boolean isPlay = false;

    public void prepareStartingAudio() {
        bufferSizePlay = AudioTrack.getMinBufferSize(sampleRateInHz,channelConfig, audioFormat);
        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRateInHz,
                channelConfig, audioFormat, bufferSizePlay,
                AudioTrack.MODE_STREAM);
        mAudioTrack.play();
        isPlay = true;
    }

    public class AudioStartAsyncTask extends AsyncTask<Void, Void, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            prepareStartingAudio();
        }

        @Override
        protected String doInBackground(Void... params) {
            String result = null;
            try {
                DataInputStream fileInput = new DataInputStream(
                        new BufferedInputStream(new FileInputStream(audioFile)));
                short[] buffer = new short[bufferSizePlay / 4];
                while (isPlay && fileInput.available() > 0) {
                    for (int i = 0; fileInput.available() > 0
                            && i < buffer.length; i++) {
                        buffer[i] = fileInput.readShort();
                    }
                    mAudioTrack.write(buffer, 0, buffer.length);
                }

                mAudioTrack.stop();
                fileInput.close();
                result = "success";
            } catch (Exception e) {
                e.printStackTrace();
                result = "fail ";
            }
            return result;
        }

        @Override
        protected void onPostExecute(String result) {
            Toast.makeText(Main02Activity.this, result, Toast.LENGTH_LONG).show();
            super.onPostExecute(result);
        }

    }
}

我把上面的代码给整理抽取了一个封装类,想看可以在这里下载:AudioRecord/AudioTractorDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值