博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android实现视频录制
阅读量:5773 次
发布时间:2019-06-18

本文共 6199 字,大约阅读时间需要 20 分钟。

实现视频录制,有两种方法,一种是调用自带的视频功能,一种是使用MediaRecorder。

每种方法都有自己的优缺点。接下来,把两种方法的代码写出来。

先说第一种方法,也是最简单的方法,那就是直接调用系统的视频功能。

代码很简单:

  • //这是跳转至录制视频界面的按钮监听  
  •     class VideoListener implements OnClickListener {  
  •         @Override  
  •         public void onClick(View v) {  
  •             Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);  
  • //在这里的QUALITY参数,值为两个,一个是0,一个是1,代表录制视频的清晰程度,0最不清楚,1最清楚  
  • //没有0-1的中间值,另外,使用1也是比较占内存的,测试了一下,录制1分钟,大概内存是43M多  
  • //使用0,录制1分钟大概内存是几兆  
  •             intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);  
  •             // 限制时长 ,参数61代表61秒,可以根据需求自己调,最高应该是2个小时。  
  • //当在这里设置时长之后,录制到达时间,系统会自动保存视频,停止录制  
  •             intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 61);  
  •             // 限制大小 限制视频的大小,这里是100兆。当大小到达的时候,系统会自动停止录制  
  •             intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024 * 1024 * 100);  
  • //在这里有录制完成之后的操作,系统会默认把视频放到照片的文件夹中  
  •             startActivityForResult(intent, 11);  
  •         }



接下来是第二方法 ,也是比第一次麻烦的方法 ,使用MediaRecorder:

 

  • //跳转至录制视频页面的按钮事件  
  • class VideoListener implements OnClickListener {  
  •         @Override  
  •         public void onClick(View v) {  
  •             Intent intent = new Intent(context,MovieRecorder.class);  
  •             startActivity(intent);
  •         }
  •     }



MovieRecorder.class 中的代码:

  • package com.titan.ti_yuqiao.video;  
  • import java.io.File;  
  • import android.app.Activity;  
  • import android.content.pm.ActivityInfo;  
  • import android.graphics.PixelFormat;  
  • import android.media.MediaRecorder;  
  • import android.os.Bundle;  
  • import android.os.Environment;  
  • import android.view.SurfaceView;  
  • import android.view.View;  
  • import android.view.View.OnClickListener;  
  • import android.view.Window;  
  • import android.view.WindowManager;  
  • import android.widget.ImageButton;  
  • import android.widget.Toast;  
  • import com.titan.ti_yuqiao.R;  
  • public class MovieRecorder extends Activity implements OnClickListener {  
  •     // 程序中的两个按钮,录制和停止  
  •     ImageButton record, stop;
  •     // 系统的视频文件  
  •     File videoFile;
  •     MediaRecorder mRecorder;
  •     // 显示视频预览的SurfaceView  
  •     SurfaceView sView;
  •     // 记录是否正在进行录制  
  •     private boolean isRecording = false;  
  •     @Override  
  •     public void onCreate(Bundle savedInstanceState) {  
  •         super.onCreate(savedInstanceState);  
  •         // 去掉标题栏 ,必须放在setContentView之前  
  •         requestWindowFeature(Window.FEATURE_NO_TITLE);
  •         setContentView(R.layout.video);
  •         // 设置横屏显示  
  •         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
  •         // 设置全屏  
  •         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  •                 WindowManager.LayoutParams.FLAG_FULLSCREEN);
  •         // 选择支持半透明模式,在有surfaceview的activity中使用。  
  •         getWindow().setFormat(PixelFormat.TRANSLUCENT);
  •         // 获取程序界面中的两个按钮  
  •         record = (ImageButton) findViewById(R.id.record);
  •         stop = (ImageButton) findViewById(R.id.stop);
  •         // 让stop按钮不可用。  
  •         stop.setEnabled(false);  
  •         // 为两个按钮的单击事件绑定监听器  
  •         record.setOnClickListener(this);  
  •         stop.setOnClickListener(this);  
  •         // 获取程序界面中的SurfaceView  
  •         sView = (SurfaceView) this.findViewById(R.id.sView);  
  •         // 设置分辨率  
  •         sView.getHolder().setFixedSize(1280, 720);  
  •         // 设置该组件让屏幕不会自动关闭  
  •         sView.getHolder().setKeepScreenOn(true);  
  •     }
  •     @Override  
  •     public void onClick(View source) {  
  •         switch (source.getId()) {  
  •         // 单击录制按钮  
  •         case R.id.record:  
  •             if (!Environment.getExternalStorageState().equals(  
  •                     android.os.Environment.MEDIA_MOUNTED)) {
  •                 Toast.makeText(MovieRecorder.this, "SD卡不存在,请插入SD卡!",  
  •                         Toast.LENGTH_SHORT).show();
  •                 return;  
  •             }
  •             try {  
  •                 // 创建保存录制视频的视频文件,视频结果会保存在sd卡的根目录20141205123345.3gp  
  •                 videoFile = new File(Environment.getExternalStorageDirectory()  
  •                         .getCanonicalFile() + "/20141205123345.3gp");  
  •                 // 创建MediaPlayer对象  
  •                 mRecorder = new MediaRecorder();  
  •                 mRecorder.reset();
  •                 // 设置从麦克风采集声音(或来自录像机的声音AudioSource.CAMCORDER)  
  •                 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  •                 // 设置从摄像头采集图像  
  •                 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
  •                 // 设置视频文件的输出格式  
  •                 // 必须在设置声音编码格式、图像编码格式之前设置  
  •                 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  •                 // 设置声音编码的格式  
  •                 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  •                 // 设置图像编码的格式  
  •                 mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
  • //我一开始将这里的分辨率调成了640,480调完之后,发现录出的视频会花屏,改成1280,720则没事  
  •                 mRecorder.setVideoSize(1280, 720);  
  •                 // 每秒 4帧  
  •                 mRecorder.setVideoFrameRate(20);  
  •                 //数值越大,越清晰,占用内存越大,一开始我使用的是5*1024*1024,画面的质量和第一种方法质量为0的时候差不多,  
  • //后来改成7*1024*1024,清晰度立马提升,后来写成了8*1024*1024  
  •                 mRecorder.setVideoEncodingBitRate(8*1024*1024);  
  •                 mRecorder.setOutputFile(videoFile.getAbsolutePath());
  •                 // 指定使用SurfaceView来预览视频  
  •                 mRecorder.setPreviewDisplay(sView.getHolder().getSurface()); // ①  
  •                 mRecorder.prepare();
  •                 // 开始录制  
  •                 mRecorder.start();
  •                 // 让record按钮不可用。  
  •                 record.setEnabled(false);  
  •                 // 让stop按钮可用。  
  •                 stop.setEnabled(true);  
  •                 isRecording = true;  
  •             } catch (Exception e) {  
  •                 e.printStackTrace();
  •             }
  •             break;  
  •         // 单击停止按钮  
  •         case R.id.stop:  
  •             // 如果正在进行录制  
  •             if (isRecording) {  
  •                 // 停止录制  
  •                 mRecorder.stop();
  •                 // 释放资源  
  •                 mRecorder.release();
  •                 mRecorder = null;  
  •                 // 让record按钮可用。  
  •                 record.setEnabled(true);  
  •                 // 让stop按钮不可用。  
  •                 stop.setEnabled(false);  
  •             }
  •             break;  
  •         }
  •     }
  • }



以下是该MovieRecorder.class对应的xml配置

  • <?xml version="1.0" encoding="utf-8"?>  
  • <RelativeLayout  
  • xmlns:android="http://schemas.android.com/apk/res/android"  
  • android:orientation="vertical"  
  • android:layout_width="match_parent"  
  • android:layout_height="match_parent">  
  • <!-- 显示视频预览的SurfaceView -->  
  • <SurfaceView  
  • android:id="@+id/sView"  
  • android:layout_width="match_parent"  
  • android:layout_height="match_parent" />  
  • <LinearLayout  
  • android:orientation="horizontal"  
  • android:layout_width="wrap_content"  
  • android:layout_height="wrap_content"  
  • android:gravity="center_horizontal"  
  • android:layout_alignParentBottom="true"  
  • android:layout_centerHorizontal="true">  
  • <ImageButton  
  • android:id="@+id/record"  
  • android:layout_width="66dp"  
  • android:layout_height="66dp"  
  • android:scaleType="fitCenter"  
  • android:src="@drawable/red_no_problem" />  
  • <ImageButton  
  • android:id="@+id/stop"  
  • android:layout_width="66dp"  
  • android:layout_height="66dp"  
  • android:scaleType="fitCenter"  
  • android:src="@drawable/red_success" />  
  • </LinearLayout>  
  • </RelativeLayout>  

 

对该程序添加权限:

  • <!-- 授予该程序录制声音的权限 -->
  •     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  •     <!-- 授予该程序使用摄像头的权限 -->
  •     <uses-permission android:name="android.permission.CAMERA"/>
  •     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
  •     <!-- 授予使用外部存储器的权限 -->
  •     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

通过对这两种方法的测试,:也发现两种方法的优缺点,以下为对比

 

一:使用第一种方法,方便快捷,不需要太多的代码量;使用第二种方法,代码量稍大;

二:第一种方法视频清晰度只有两种,一个是最不清楚,一个是最清楚;第二种方法视频清晰度可根据数值自动往上调 ;

三:第一种方法,清晰度为1的时候,会占用大内存;第二种方法 :清晰度越高的时候,内存也会增大;

经测试:第一种方法清晰度为1,录制一分钟,大小在43M左右;第二种方法当为8*1024*1024时,录制一分钟,大小在57M;

四:第一种方法在录制过程中,操作方便,有自己的暂停、录制、播放按钮 ;第二种只能自己去写暂停、录制或播放按钮;

综上,如果内存足够大的时候,推荐使用第一种方法,方便快捷。

以上内容分享给大家学习。

转载地址:http://egxux.baihongyu.com/

你可能感兴趣的文章
mybitis 使用记录
查看>>
关于构造函数 和 析构函数 能否抛出异常的讨论
查看>>
haproxy负载均衡和配合keepalived的快速部署
查看>>
Git上传本地项目到git@OSC
查看>>
Linux 安装 Elasticsearch
查看>>
web.xml 详细介绍
查看>>
WIN10+RTX2070 tensorflow-gpu环境搭建
查看>>
Linux 下编译 redis 和 phpredis
查看>>
config.status: error: cannot find input file: s...
查看>>
SHA512编程实现与优化之一:maj函数
查看>>
Yii2的ActiveRecord与ActiveQuery简单介绍
查看>>
select下js的基本操作(备忘)
查看>>
html5的原装api
查看>>
SparkSQL使用之Thrift JDBC server
查看>>
小黑小波比.功能测试登录用户
查看>>
Java enum用法详解
查看>>
去云端的多条途径
查看>>
Docker容器从一知半解到入门
查看>>
关于“方法参数”
查看>>
Redis命令总结
查看>>