欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android使用MediaRecorder类进行录制视频

程序员文章站 2023-11-26 16:57:46
萬仟网提醒大家使用mediarecorder录音录像的设置代码步骤一定要按照api指定的顺序来设置,否则报错 步骤为: 1、设置视频源,音频源,即输入源 2、设置输出...

提醒大家使用mediarecorder录音录像的设置代码步骤一定要按照api指定的顺序来设置,否则报错

步骤为:

1、设置视频源,音频源,即输入源

2、设置输出格式

3、设置音视频的编码格式

一、首先看布局文件,这里有一个surfaceview,这是一个绘制容器,可以直接从内存或者dma等硬件接口取得图像数据,

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.xqx.mediarecorder.app.workrecorder">
    <!-- 开始录制按钮 -->
    <button
        android:id="@+id/startrecord"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onclick="btnstartrecord"
        android:text="开始录制"
        />
    <button
        android:id="@+id/stoprecord"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onclick="btnstoprecord"
        android:text="停止录制"
        />
    <surfaceview
        android:id="@+id/surview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</linearlayout>

二、activity 代码

1、首先看下成员变量

 // 开始录制,停止录制按钮
  private button startrecord,stoprecord;
  // 显示预览的surfaceview
  private surfaceview surfaceview;
  // 标记,判断当前是否正在录制
  boolean isrunning = false;
  // 录制类
  private mediarecorder recorder;
  // 存储文件
  private file savefile;

2、oncreate()方法中进行一些初始化

     startrecord = (button) findviewbyid(r.id.startrecord);
        stoprecord = (button) findviewbyid(r.id.stoprecord);
        surfaceview = (surfaceview) findviewbyid(r.id.surview);
        // oncreate()初始化 ,一开始肯定没有开始录制,所以停止按钮不可点击
        stoprecord.setenabled(false);
     // 设置surface不需要维护自己的缓冲区
        surfaceview.getholder().settype(surfaceholder.surface_type_push_buffers);
        // 设置分辨率
        surfaceview.getholder().setfixedsize(320, 280);
        // 设置该组件不会让屏幕自动关闭
        surfaceview.getholder().setkeepscreenon(true);

3、现在看“开始录制”监听事件

----3.1

 创建mediarecorder对象
  recorder = new mediarecorder();
  recorder.reset();

----3.2 设置三步,顺序固定

//1.设置采集声音
recorder.setaudiosource(mediarecorder.audiosource.mic);
//设置采集图像
recorder.setvideosource(mediarecorder.videosource.camera);
//2.设置视频,音频的输出格式
recorder.setoutputformat(mediarecorder.outputformat.three_gpp);
//3.设置音频的编码格式
recorder.setaudioencoder(mediarecorder.audioencoder.default);
//设置图像的编码格式
recorder.setvideoencoder(mediarecorder.videoencoder.default);

----3.3 其他可选设置,更多请查看api

//设置立体声
recorder.setaudiochannels(2);
//设置最大录像时间 单位:毫秒
recorder.setmaxduration(600000);
//设置最大录制的大小 单位,字节
recorder.setmaxfilesize(1024*1024);
//音频一秒钟包含多少数据位
recorder.setaudioencodingbitrate(128);
//设置选择角度,顺时针方向,因为默认是逆向90度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度
recorder.setorientationhint(90);
//设置录像的分辨率
recorder.setvideosize(176, 144);

----3.4 设置文件存储路径,这里简陋了,实际开发中需要判断是否有外部存储,是否有目标目录 ,是否已经存在相同名字的文件 等问题

//设置输出文件路径

savefile = new file(environment.getexternalstoragedirectory()
            .getcanonicalfile() + "/myvideo.mp4");
recorder.setoutputfile(savefile.getabsolutepath());

----3.5 使用surfaceview进行预览

recorder.setpreviewdisplay(surfaceview.getholder().getsurface());

----3.6 开始录制

recorder.prepare();
//开始录制
recorder.start();
//让开始按钮不可点击,停止按钮可点击
startrecord.setenabled(false);
stoprecord.setenabled(true);
isrunning = true;

----3.7 停止录制

 //停止录制
recorder.stop();
//释放资源
recorder.release();
recorder = null;
//设置开始按钮可点击,停止按钮不可点击
startrecord.setenabled(true);
stoprecord.setenabled(false);

完整代码:

 package com.xqx.mediarecorder.app;
  import android.app.activity;
  import android.media.mediarecorder;
  import android.os.bundle;
  import android.os.environment;
  import android.view.surfaceholder;
  import android.view.surfaceview;
  import android.view.view;
 import android.widget.button;
 import android.hardware.camera;
 import java.io.file;
 import java.io.ioexception;
 public class workrecorder extends activity implements camera.previewcallback {
   // 开始录制,停止录制按钮
   private button startrecord,stoprecord;
   // 显示预览的surfaceview
   private surfaceview surfaceview;
   // 标记,判断当前是否正在录制
   boolean isrunning = false;
   // 录制类
   private mediarecorder recorder;
   // 存储文件
   private file savefile;
   @override
   protected void oncreate(bundle savedinstancestate) {
     super.oncreate(savedinstancestate);
     setcontentview(r.layout.activity_work_recorder);
     startrecord = (button) findviewbyid(r.id.startrecord);
     stoprecord = (button) findviewbyid(r.id.stoprecord);
     surfaceview = (surfaceview) findviewbyid(r.id.surview);
     // oncreate()初始化 ,一开始肯定没有开始录制,所以停止按钮不可点击
     stoprecord.setenabled(false);
     // 设置surface不需要维护自己的缓冲区
     surfaceview.getholder().settype(surfaceholder.surface_type_push_buffers);
     // 设置分辨率
     surfaceview.getholder().setfixedsize(, );
     // 设置该组件不会让屏幕自动关闭
     surfaceview.getholder().setkeepscreenon(true);
   }
   /**
    * 开始录制
    * @param view
    */
   public void btnstartrecord(view view) {
     // 首先判断当前是否处理视频录制状态,只有不是录制状态的时候,才可以开始录制
     if (!isrunning){
       try {
         //创建mediarecorder对象
         recorder = new mediarecorder();
         recorder.reset();
         //.设置采集声音
         recorder.setaudiosource(mediarecorder.audiosource.mic);
         //设置采集图像
         recorder.setvideosource(mediarecorder.videosource.camera);
         //.设置视频,音频的输出格式
         recorder.setoutputformat(mediarecorder.outputformat.mpeg_);
         //.设置音频的编码格式
         recorder.setaudioencoder(mediarecorder.audioencoder.aac);
         //设置图像的编码格式
         recorder.setvideoencoder(mediarecorder.videoencoder.h);
         //设置立体声
         recorder.setaudiochannels();
         //设置最大录像时间 单位:毫秒
         recorder.setmaxduration();
         //设置最大录制的大小 单位,字节
         recorder.setmaxfilesize(*);
         //音频一秒钟包含多少数据位
         recorder.setaudioencodingbitrate();
         //设置选择角度,顺时针方向,因为默认是逆向度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度
         recorder.setorientationhint();
         //设置输出文件路径
 //        savefile = fileutils.getmediarecoderfolder(this);
         savefile = new file(environment.getexternalstoragedirectory()
             .getcanonicalfile() + "/myvideo.mp");
 //    recorder.setvideosize(, );
 //    recorder.setvideoframerate();
         recorder.setoutputfile(savefile.getabsolutepath());
         //使用surfaceview预览
         recorder.setpreviewdisplay(surfaceview.getholder().getsurface());
         recorder.prepare();
         //开始录制
         recorder.start();
         //让开始按钮不可点击,停止按钮可点击
         startrecord.setenabled(false);
         stoprecord.setenabled(true);
         isrunning = true;
       } catch (ioexception e) {
         e.printstacktrace();
       }
     }
   }
   /**
   * 结束录制
   * @param view
   */
   public void btnstoprecord(view view) {
     if (isrunning){
       //停止录制
       recorder.stop();
       //释放资源
       recorder.release();
       recorder = null;
       //设置开始按钮可点击,停止按钮不可点击
       startrecord.setenabled(true);
       stoprecord.setenabled(false);
     }
   }
   @override
   public void onpreviewframe(byte[] data, camera camera) {
   }
 }

本例子只是一个简单的demo,用于给刚接触mediarecorder音频录制的coder学习,存在一些bug和不足,各位coder可以继续拓展

不足:

1、只有当点击“开始录制”的时候surfaceview组件才可以看到摄像头拍摄的预览,否则是一篇黑,这里可以看下canera类,进行相应的调整

2、保存路径,需要判断是否有外部存储,存储空间是否足够,路径是否不存在,是否有已有的文件名相同的文件存在等问题,设置文件的名字,我这里是固定路径固定文件名

3、摄像预览效果是有90度旋转的,这里需要大家个人去看下mediorecoder的api 去进行设置

4、没有设置对焦,像素不清楚,摄像宽高变形