赞
踩
github源码:https://github.com/heinsven/Test5.git
AudioRecord 是Android提供的用于录音的工具类。
AudioRecord管理应用的各类音频资源,记录平台的各类输入设备的音频输入。
AudioRecord实现Android录音的流程:
AudioRecord由于输出的数据是原始数据PCM,MediaPlayer播放器是不能识别播放的,需要通过AudioTrack处理播放,或者把PCM转化为可以播放的格式类似wav,MP3等。
- public class Test5 extends AppCompatActivity {
- private ProgressBar mProgressBar;
- private Button mBtn1;
- private Button mBtn2;
- private Button mBtn3;
-
- private AudioRecord mAudioRecord;
- private boolean isRecording = false;
-
- private byte[] audioData;
- int laiyuan = MediaRecorder.AudioSource.MIC;//来源
- int samHz = 16000;//采样频率
- int shengdao = AudioFormat.CHANNEL_IN_MONO;//声道
- int audioFormat = AudioFormat.ENCODING_PCM_16BIT;//格式
- int bufferSize = 2 * AudioRecord.getMinBufferSize(samHz, shengdao, audioFormat);//缓冲区大小
-
- private String voicePath = Environment.getExternalStorageDirectory().getPath() + "/audio";
- private String voiceName = "/test.pcm";
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_test5);
- init();
- }
-
- private void init() {
- verifyStoragePermissions(this);
- mProgressBar = findViewById(R.id.progressbar);
- mProgressBar.setVisibility(View.GONE);
- mBtn1 = findViewById(R.id.btn1);
- mBtn2 = findViewById(R.id.btn2);
- mBtn3 = findViewById(R.id.btn3);
-
- mBtn1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mAudioRecord == null) {
- startRecord();
- }
- }
- });
-
- mBtn2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mAudioRecord != null) {
- stopRecord();
- }
- }
- });
-
- mBtn3.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- try {
- InputStream in = new FileInputStream(voicePath + voiceName);
- try {
- ByteArrayOutputStream out = new ByteArrayOutputStream(264848);
- for (int b; (b = in.read()) != -1; ) {
- out.write(b);
- }
- audioData = out.toByteArray();
- } finally {
- in.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, samHz,
- AudioFormat.CHANNEL_OUT_MONO, audioFormat,
- audioData.length, AudioTrack.MODE_STATIC);
- audioTrack.write(audioData, 0, audioData.length);
- audioTrack.play();
- }
- });
- }
-
- private static final int REQUEST_EXTERNAL_STORAGE = 1;
- private static String[] PERMISSIONS_STORAGE = {"android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.RECORD_AUDIO"};
-
- public static void verifyStoragePermissions(Activity activity) {
- try {
- //检测是否有写的权限
- int permission1 = ActivityCompat.checkSelfPermission(activity,
- "android.permission.WRITE_EXTERNAL_STORAGE");
- int permission2 = ActivityCompat.checkSelfPermission(activity,
- "android.permission.RECORD_AUDIO");
- if (permission1 != PackageManager.PERMISSION_GRANTED || permission2 != PackageManager.PERMISSION_GRANTED) {
- // 没有写的权限,去申请写的权限,会弹出对话框
- ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void startRecord() {
- mAudioRecord = new AudioRecord(laiyuan, samHz, shengdao, audioFormat, bufferSize);
-
- final byte data[] = new byte[bufferSize];
- final File file = new File(voicePath);
- final File fileaudio = new File(voicePath + voiceName);
-
- if (fileaudio.exists()) {
- fileaudio.delete();
- }
- if (!file.exists()) {
- file.mkdirs();
- }
- mAudioRecord.startRecording();
- isRecording = true;
- mProgressBar.setVisibility(View.VISIBLE);
-
- new Thread(new Runnable() {
- @Override
- public void run() {
- FileOutputStream fos = null;
- try {
- fos = new FileOutputStream(fileaudio);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- if (null != fos) {
- while (isRecording) {
- int read = mAudioRecord.read(data, 0, bufferSize);
- //返回正确时才读取数据
- if (AudioRecord.ERROR_INVALID_OPERATION != read) {
- try {
- fos.write(data);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- try {
- fos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }).start();
- }
-
-
- public void stopRecord() {
- isRecording = false;
- if (mAudioRecord != null) {
- mProgressBar.setVisibility(View.GONE);
- mAudioRecord.stop();
- mAudioRecord.release();
- //调用release之后必须置为null
- mAudioRecord = null;
- }
- }
- }
AudioTrack只能播放已经解码的PCM流,对于文件,也支持wav格式的音频文件,因为wav格式的音频文件大部分都是PCM流。AudioTrack不创建解码器,所以只能播放不需要解码的wav文件。
AudioTrack可以在两种模式下工作,一种是静态(static),一种是流(streaming)
MODE_STREAM:在这种模式下,通过write一次次把音频数据写到AudioTrack中。但这种工作方式每次都需要把数据从用户提供的Buffer中拷贝到AudioTrack内部的Buffer中,这在一定程度上会使引入延时。
MODE_STATIC:在play之前,只需要把所有数据通过一次write调用传递到AudioTrack中的内部缓冲区,后续就不必再传递数据了。这种模式适用于像铃声这种内存占用量较小,延时要求较高的文件。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。