录音与播放——(AudioRecord & AudioTrack)

作者:追风剑情 发布于:2016-6-13 17:55 分类:Android

添加权限


  1. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  3. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  4. <uses-permission android:name="android.permission.RECORD_AUDIO" />


1、新建活动

fragment_audio_main.xml


  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:paddingBottom="@dimen/activity_vertical_margin"
  6. android:paddingLeft="@dimen/activity_horizontal_margin"
  7. android:paddingRight="@dimen/activity_horizontal_margin"
  8. android:paddingTop="@dimen/activity_vertical_margin"
  9. tools:context="com.test.androidtest.AudioMainActivity$PlaceholderFragment" >
  10.  
  11. <Button
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:text="开始录音"
  15. android:onClick="startRecording" />
  16. <Button
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. android:text="停止录音"
  20. android:onClick="stopRecording" />
  21. <Button
  22. android:layout_width="wrap_content"
  23. android:layout_height="wrap_content"
  24. android:text="播放录音"
  25. android:onClick="playRecording" />
  26.  
  27. </LinearLayout>


代码


  1. package com.test.androidtest;
  2.  
  3. import java.io.BufferedInputStream;
  4. import java.io.BufferedOutputStream;
  5. import java.io.DataInputStream;
  6. import java.io.DataOutputStream;
  7. import java.io.File;
  8. import java.io.FileInputStream;
  9. import java.io.FileOutputStream;
  10. import java.io.IOException;
  11. import java.io.InputStream;
  12. import java.io.OutputStream;
  13.  
  14. import android.app.Activity;
  15. import android.media.AudioFormat;
  16. import android.media.AudioManager;
  17. import android.media.AudioRecord;
  18. import android.media.AudioTrack;
  19. import android.media.MediaRecorder;
  20. import android.os.Bundle;
  21. import android.os.Environment;
  22. import android.util.Log;
  23. import android.view.View;
  24.  
  25. public class AudioMainActivity extends Activity {
  26. //以下值会影响所录制音频的大小和质量
  27. //采样频率
  28. private int frequency = 11025;
  29. //声道配置
  30. private int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
  31. //音频编码
  32. private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
  33. private boolean isRecording = false;
  34. @Override
  35. protected void onCreate(Bundle savedInstanceState) {
  36. super.onCreate(savedInstanceState);
  37. setContentView(R.layout.fragment_audio_main);
  38. }
  39. public void startRecording(View view)
  40. {
  41. Log.d("test", "开始录音");
  42. Thread thread=new Thread(new Runnable()
  43. {
  44. @Override
  45. public void run()
  46. {
  47. File file = new File(Environment.getExternalStorageDirectory(), "raw.pcm");//保存在SD卡上
  48. try{
  49. file.createNewFile();
  50. }catch(IOException e){
  51. Log.e("test", "IO Exception", e);
  52. }
  53. try{
  54. OutputStream os = new FileOutputStream(file);
  55. BufferedOutputStream bos = new BufferedOutputStream(os);
  56. DataOutputStream dos = new DataOutputStream(bos);
  57. int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
  58. short[] buffer = new short[bufferSize];
  59. //创建一个新的AudioRecord对象来录制音频
  60. AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,//从麦克风录制原始音频
  61. frequency,
  62. channelConfiguration,
  63. audioEncoding, bufferSize);
  64. audioRecord.startRecording();//开始异步录制
  65. isRecording = true;
  66. while(isRecording){
  67. int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
  68. Log.d("test", "bufferReadResult="+bufferReadResult);
  69. for(int i=0; i<bufferReadResult; i++)
  70. dos.writeShort(buffer[i]);
  71. }
  72. audioRecord.stop();
  73. dos.flush();
  74. dos.close();
  75. }catch(Throwable t){
  76. Log.e("test", "An error occurred during recording", t);
  77. }
  78. }
  79. });
  80. thread.start();
  81. }
  82. public void stopRecording(View view)
  83. {
  84. Log.d("test", "停止录音");
  85. isRecording = false;
  86. }
  87. public void playRecording(View view)
  88. {
  89. Log.d("test", "播放录音");
  90. File file = new File(Environment.getExternalStorageDirectory(), "raw.pcm");
  91. //用于存储音轨的short数组(每个short占用16位,即2个字节)
  92. int audioLength = (int)(file.length()/2);
  93. short[] audio = new short[audioLength];
  94. try{
  95. InputStream is = new FileInputStream(file);
  96. BufferedInputStream bis = new BufferedInputStream(is);
  97. DataInputStream dis = new DataInputStream(bis);
  98. int i = 0;
  99. while(dis.available() > 0){
  100. audio[i] = dis.readShort();
  101. i++;
  102. }
  103. //关闭输入流
  104. dis.close();
  105. //创建和播放新的AudioTrack对象
  106. //由于录制的原始音频没有关联元数据,因此必须将音频的数据属性设为与录制时相同
  107. AudioTrack audioTrack = new AudioTrack(
  108. AudioManager.STREAM_MUSIC,//流模式
  109. frequency,//频率
  110. channelConfiguration,//声道配置
  111. audioEncoding,//音频编码类型
  112. audioLength,//要播放的音频的长度
  113. AudioTrack.MODE_STREAM);
  114. audioTrack.play();//异步播放
  115. audioTrack.write(audio, 0, audioLength);//将原始音频数据添加到播放缓冲区
  116. }catch(Throwable t){
  117. Log.d("test", "An error occurred during playback", t);
  118. }
  119. }
  120. }


运行效果

111111.png

标签: Android

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号