现在项目中有使用到音视频相关技术,在参考了网上各种大牛的资料及根据自己项目实际情况(兼容安卓6.0以上版本动态权限管理等),把声音录制及播放相关代码做个记录。
public class MediaRecorderActivity extends BaseActivity { private button start_tv; private ListVIEw ListVIEw; //线程 *** 作 private ExecutorService mExecutorService; //录音API private MediaRecorder mMediaRecorder; //录音开始时间与结束时间 private long startTime,endTime; //录音所保存的文件 private file mAudiofile; //文件列表数据 private List<fileBean> dataList; //录音文件数据列表适配器 private AudioAdapter mAudioAdapter; //录音文件保存位置 private String mfilePath = Environment.getExternalStorageDirectory().getabsolutePath() + "/audio/"; //当前是否正在播放 private volatile boolean isPlaying; //播放音频文件API private MediaPlayer mediaPlayer; //使用Handler更新UI线程 private Handler mHandler = new Handler() { @OverrIDe public voID handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case Constant.RECORD_SUCCESS: //录音成功,展示数据 if (null == mAudioAdapter) { mAudioAdapter = new AudioAdapter(MediaRecorderActivity.this,dataList,R.layout.file_item_layout); } ListVIEw.setAdapter(mAudioAdapter); break; //录音失败 case Constant.RECORD_FAIL: showToastMsg(getString(R.string.record_fail)); break; //录音时间太短 case Constant.RECORD_TOO_SHORT: showToastMsg(getString(R.string.time_too_short)); break; case Constant.PLAY_COMPLETION: showToastMsg(getString(R.string.play_over)); break; case Constant.PLAY_ERROR: showToastMsg(getString(R.string.play_error)); break; } } }; @OverrIDe protected voID setwindowVIEw() { setContentVIEw(R.layout.activity_record); //录音及播放要使用单线程 *** 作 mExecutorService = Executors.newSingleThreadExecutor(); dataList = new ArrayList<>(); } @OverrIDe protected voID initVIEws() { this.start_tv = (button) findVIEwByID(R.ID.start_tv); this.ListVIEw = (ListVIEw) findVIEwByID(R.ID.ListvIEw); } @OverrIDe protected voID initEvents() { //类似微信等应用按住说话进行录音,所以用Ontouch事件 this.start_tv.setontouchListener(new VIEw.OntouchListener() { @OverrIDe public boolean ontouch(VIEw vIEw,MotionEvent motionEvent) { switch (motionEvent.getAction()) { //按下 *** 作 case MotionEvent.ACTION_DOWN: //安卓6.0以上录音相应权限处理 if (Build.VERSION.SDK_INT > 22) { permissionForM(); } else { startRecord(); } break; //松开 *** 作 case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: stopRecord(); break; } //对Ontouch事件做了处理,返回true return true; } }); //点击播放对应的录音文件 this.ListVIEw.setonItemClickListener(new AdapterVIEw.OnItemClickListener() { @OverrIDe public voID onItemClick(AdapterVIEw<?> adapterVIEw,VIEw vIEw,int i,long l) { //使用MediaPlayer播放声音文件 startPlay(dataList.get(i).getfile()); } }); } /** * @description 开始进行录音 * @author ldm * @time 2017/2/9 9:18 */ private voID startRecord() { start_tv.setText(R.string.stop_by_up); start_tv.setBackgroundResource(R.drawable.bg_gray_round); //异步任务执行录音 *** 作 mExecutorService.submit(new Runnable() { @OverrIDe public voID run() { //播放前释放资源 releaseRecorder(); //执行录音 *** 作 recordOperation(); } }); } /** * @description 录音失败处理 * @author ldm * @time 2017/2/9 9:35 */ private voID recordFail() { mAudiofile = null; mHandler.sendEmptyMessage(Constant.RECORD_FAIL); } /** * @description 录音 *** 作 * @author ldm * @time 2017/2/9 9:34 */ private voID recordOperation() { //创建MediaRecorder对象 mMediaRecorder = new MediaRecorder(); //创建录音文件,.m4a为MPEG-4音频标准的文件的扩展名 mAudiofile = new file(mfilePath + System.currentTimeMillis() + ".m4a"); //创建父文件夹 mAudiofile.getParentfile().mkdirs(); try { //创建文件 mAudiofile.createNewfile(); //配置mMediaRecorder相应参数 //从麦克风采集声音数据 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); //设置保存文件格式为MP4 mMediaRecorder.setoutputFormat(MediaRecorder.OutputFormat.MPEG_4); //设置采样频率,44100是所有安卓设备都支持的频率,频率越高,音质越好,当然文件越大 mMediaRecorder.setAudioSamplingRate(44100); //设置声音数据编码格式,音频通用格式是AAC mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //设置编码频率 mMediaRecorder.setAudioEnCodingBitRate(96000); //设置录音保存的文件 mMediaRecorder.setoutputfile(mAudiofile.getabsolutePath()); //开始录音 mMediaRecorder.prepare(); mMediaRecorder.start(); //记录开始录音时间 startTime = System.currentTimeMillis(); } catch (Exception e) { e.printstacktrace(); recordFail(); } } /** * @description 结束录音 *** 作 * @author ldm * @time 2017/2/9 9:18 */ private voID stopRecord() { start_tv.setText(R.string.speak_by_press); start_tv.setBackgroundResource(R.drawable.bg_white_round); //停止录音 mMediaRecorder.stop(); //记录停止时间 endTime = System.currentTimeMillis(); //录音时间处理,比如只有大于2秒的录音才算成功 int time = (int) ((endTime - startTime) / 1000); if (time >= 3) { //录音成功,添加数据 fileBean bean = new fileBean(); bean.setfile(mAudiofile); bean.setfileLength(time); dataList.add(bean); //录音成功,发Message mHandler.sendEmptyMessage(Constant.RECORD_SUCCESS); } else { mAudiofile = null; mHandler.sendEmptyMessage(Constant.RECORD_TOO_SHORT); } //录音完成释放资源 releaseRecorder(); } /** * @description 翻放录音相关资源 * @author ldm * @time 2017/2/9 9:33 */ private voID releaseRecorder() { if (null != mMediaRecorder) { mMediaRecorder.release(); mMediaRecorder = null; } } @OverrIDe public voID onClick(VIEw vIEw) { } @OverrIDe protected voID onDestroy() { super.onDestroy(); //页面销毁,线程要关闭 mExecutorService.shutdownNow(); } /*******6.0以上版本手机权限处理***************************/ /** * @description 兼容手机6.0权限管理 * @author ldm * @time 2016/5/24 14:59 */ private voID permissionForM() { if (ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUdio) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUdio,Manifest.permission.WRITE_EXTERNAL_STORAGE},Constant.PERMISSIONS_REQUEST_FOR_AUdio); } else { startRecord(); } } @OverrIDe public voID onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) { if (requestCode == Constant.PERMISSIONS_REQUEST_FOR_AUdio) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { startRecord(); } return; } super.onRequestPermissionsResult(requestCode,permissions,grantResults); } /** * @description 播放音频 * @author ldm * @time 2017/2/9 16:54 */ private voID playAudio(final file mfile) { if (null != mfile && !isPlaying) { isPlaying = true; mExecutorService.submit(new Runnable() { @OverrIDe public voID run() { startPlay(mfile); } }); } } /** * @description 开始播放音频文件 * @author ldm * @time 2017/2/9 16:56 */ private voID startPlay(file mfile) { try { //初始化播放器 mediaPlayer = new MediaPlayer(); //设置播放音频数据文件 mediaPlayer.setDataSource(mfile.getabsolutePath()); //设置播放监听事件 mediaPlayer.setonCompletionListener(new MediaPlayer.OnCompletionListener() { @OverrIDe public voID onCompletion(MediaPlayer mediaPlayer) { //播放完成 playEndOrFail(true); } }); //播放发生错误监听事件 mediaPlayer.setonErrorListener(new MediaPlayer.OnErrorListener() { @OverrIDe public boolean onError(MediaPlayer mediaPlayer,int i1) { playEndOrFail(false); return true; } }); //播放器音量配置 mediaPlayer.setVolume(1,1); //是否循环播放 mediaPlayer.setLooPing(false); //准备及播放 mediaPlayer.prepare(); mediaPlayer.start(); } catch (IOException e) { e.printstacktrace(); //播放失败正理 playEndOrFail(false); } } /** * @description 停止播放或播放失败处理 * @author ldm * @time 2017/2/9 16:58 */ private voID playEndOrFail(boolean isEnd) { isPlaying = false; if (isEnd) { mHandler.sendEmptyMessage(Constant.PLAY_COMPLETION); } else { mHandler.sendEmptyMessage(Constant.PLAY_ERROR); } if (null != mediaPlayer) { mediaPlayer.setonCompletionListener(null); mediaPlayer.setonErrorListener(null); mediaPlayer.stop(); mediaPlayer.reset(); mediaPlayer.release(); mediaPlayer = null; } }}
页面布局
<linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical" androID:paddingleft="@dimen/activity_horizontal_margin" androID:paddingRight="@dimen/activity_horizontal_margin" androID:paddingtop="@dimen/activity_vertical_margin" androID:paddingBottom="@dimen/activity_vertical_margin"> <button androID:ID="@+ID/start_tv" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="开始录音" androID:textSize="16sp" /> <ListVIEw androID:ID="@+ID/ListvIEw" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:divIDer="#d1d1d1" androID:divIDerHeight="1dp" androID:scrollbars="none" androID:layout_margintop="10dp" androID:layout_marginBottom="10dp"></ListVIEw></linearLayout>
对应资源文件strings.xml:
<resources> <string name="app_name">mediarecorder</string> <string name="record_fail">录音失败</string> <string name="time_too_short">时间太短,请重新录音</string> <string name="play_over">播放完成</string> <string name="play_error">抱歉,播放发生异常</string> <string name="stop_by_up">松开停止录音</string> <string name="speak_by_press">按住说话</string> <string name="start_record">开始录音</string> <string name="stop_record">停止录音</string></resources>
录音相关权限 :
<!--SD卡权限--><uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE"/><!--录音权限--><uses-permission androID:name="androID.permission.RECORD_AUdio"/>
安卓录制播放音频:https://github.com/ldm520/Android_Media
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android使用MediaRecorder实现录音及播放全部内容,希望文章能够帮你解决Android使用MediaRecorder实现录音及播放所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)