zoukankan      html  css  js  c++  java
  • 安卓实现视频录制

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

    以下内容也是通过自己测试整理而来。转载请注明出处:http://www.pm-road.com/index.php/2014/12/05/267/

    这两种方法我全部测试了,每种方法都有自己的优缺点。接下来,把两种方法的代码写出来。

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

    代码很简单:

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

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

    Java代码  收藏代码
    1. //跳转至录制视频页面的按钮事件  
    2.   
    3. class VideoListener implements OnClickListener {  
    4.   
    5.         @Override  
    6.         public void onClick(View v) {  
    7.           
    8.             Intent intent = new Intent(context,MovieRecorder.class);  
    9.             startActivity(intent);  
    10.             
    11.         }  
    12.   
    13.     }  

    MovieRecorder.class 中的代码:

    Java代码  收藏代码
    1. package com.titan.ti_yuqiao.video;  
    2.   
    3. import java.io.File;  
    4.   
    5. import android.app.Activity;  
    6. import android.content.pm.ActivityInfo;  
    7. import android.graphics.PixelFormat;  
    8. import android.media.MediaRecorder;  
    9. import android.os.Bundle;  
    10. import android.os.Environment;  
    11. import android.view.SurfaceView;  
    12. import android.view.View;  
    13. import android.view.View.OnClickListener;  
    14. import android.view.Window;  
    15. import android.view.WindowManager;  
    16. import android.widget.ImageButton;  
    17. import android.widget.Toast;  
    18.   
    19. import com.titan.ti_yuqiao.R;  
    20.   
    21. public class MovieRecorder extends Activity implements OnClickListener {  
    22.     // 程序中的两个按钮,录制和停止  
    23.     ImageButton record, stop;  
    24.     // 系统的视频文件  
    25.     File videoFile;  
    26.     MediaRecorder mRecorder;  
    27.     // 显示视频预览的SurfaceView  
    28.     SurfaceView sView;  
    29.     // 记录是否正在进行录制  
    30.     private boolean isRecording = false;  
    31.   
    32.     @Override  
    33.     public void onCreate(Bundle savedInstanceState) {  
    34.         super.onCreate(savedInstanceState);  
    35.         // 去掉标题栏 ,必须放在setContentView之前  
    36.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
    37.         setContentView(R.layout.video);  
    38.         // 设置横屏显示  
    39.         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
    40.         // 设置全屏  
    41.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
    42.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
    43.         // 选择支持半透明模式,在有surfaceview的activity中使用。  
    44.         getWindow().setFormat(PixelFormat.TRANSLUCENT);  
    45.         // 获取程序界面中的两个按钮  
    46.         record = (ImageButton) findViewById(R.id.record);  
    47.         stop = (ImageButton) findViewById(R.id.stop);  
    48.         // 让stop按钮不可用。  
    49.         stop.setEnabled(false);  
    50.         // 为两个按钮的单击事件绑定监听器  
    51.         record.setOnClickListener(this);  
    52.         stop.setOnClickListener(this);  
    53.         // 获取程序界面中的SurfaceView  
    54.         sView = (SurfaceView) this.findViewById(R.id.sView);  
    55.         // 设置分辨率  
    56.         sView.getHolder().setFixedSize(1280, 720);  
    57.         // 设置该组件让屏幕不会自动关闭  
    58.         sView.getHolder().setKeepScreenOn(true);  
    59.     }  
    60.   
    61.     @Override  
    62.     public void onClick(View source) {  
    63.         switch (source.getId()) {  
    64.         // 单击录制按钮  
    65.         case R.id.record:  
    66.             if (!Environment.getExternalStorageState().equals(  
    67.                     android.os.Environment.MEDIA_MOUNTED)) {  
    68.                 Toast.makeText(MovieRecorder.this, "SD卡不存在,请插入SD卡!",  
    69.                         Toast.LENGTH_SHORT).show();  
    70.                 return;  
    71.             }  
    72.             try {  
    73.                 // 创建保存录制视频的视频文件,视频结果会保存在sd卡的根目录20141205123345.3gp  
    74.                 videoFile = new File(Environment.getExternalStorageDirectory()  
    75.                         .getCanonicalFile() + "/20141205123345.3gp");  
    76.                 // 创建MediaPlayer对象  
    77.                 mRecorder = new MediaRecorder();  
    78.                 mRecorder.reset();  
    79.                 // 设置从麦克风采集声音(或来自录像机的声音AudioSource.CAMCORDER)  
    80.                 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  
    81.                 // 设置从摄像头采集图像  
    82.                 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);  
    83.                 // 设置视频文件的输出格式  
    84.                 // 必须在设置声音编码格式、图像编码格式之前设置  
    85.                 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
    86.                 // 设置声音编码的格式  
    87.                 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
    88.                 // 设置图像编码的格式  
    89.                 mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);  
    90.   
    91. //我一开始将这里的分辨率调成了640,480调完之后,发现录出的视频会花屏,改成1280,720则没事  
    92.                 mRecorder.setVideoSize(1280, 720);  
    93.                 // 每秒 4帧  
    94.                 mRecorder.setVideoFrameRate(20);  
    95.                 //数值越大,越清晰,占用内存越大,一开始我使用的是5*1024*1024,画面的质量和第一种方法质量为0的时候差不多,  
    96.   
    97. //后来改成7*1024*1024,清晰度立马提升,后来写成了8*1024*1024  
    98.                 mRecorder.setVideoEncodingBitRate(8*1024*1024);  
    99.                 mRecorder.setOutputFile(videoFile.getAbsolutePath());  
    100.                 // 指定使用SurfaceView来预览视频  
    101.                 mRecorder.setPreviewDisplay(sView.getHolder().getSurface()); // ①  
    102.                 mRecorder.prepare();  
    103.                 // 开始录制  
    104.                 mRecorder.start();  
    105.                 
    106.                 // 让record按钮不可用。  
    107.                 record.setEnabled(false);  
    108.                 // 让stop按钮可用。  
    109.                 stop.setEnabled(true);  
    110.                 isRecording = true;  
    111.             } catch (Exception e) {  
    112.                 e.printStackTrace();  
    113.             }  
    114.             break;  
    115.         // 单击停止按钮  
    116.         case R.id.stop:  
    117.             // 如果正在进行录制  
    118.             if (isRecording) {  
    119.                 // 停止录制  
    120.                 mRecorder.stop();  
    121.                 // 释放资源  
    122.                 mRecorder.release();  
    123.                 mRecorder = null;  
    124.                 // 让record按钮可用。  
    125.                 record.setEnabled(true);  
    126.                 // 让stop按钮不可用。  
    127.                 stop.setEnabled(false);  
    128.             }  
    129.             break;  
    130.         }  
    131.     }  
    132. }  

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

    Xml代码  收藏代码
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <RelativeLayout  
    3. xmlns:android="http://schemas.android.com/apk/res/android"  
    4. android:orientation="vertical"  
    5. android:layout_width="match_parent"  
    6. android:layout_height="match_parent">  
    7. <!-- 显示视频预览的SurfaceView -->  
    8. <SurfaceView  
    9. android:id="@+id/sView"  
    10. android:layout_width="match_parent"  
    11. android:layout_height="match_parent" />  
    12. <LinearLayout  
    13. android:orientation="horizontal"  
    14. android:layout_width="wrap_content"  
    15. android:layout_height="wrap_content"  
    16. android:gravity="center_horizontal"  
    17. android:layout_alignParentBottom="true"  
    18. android:layout_centerHorizontal="true">  
    19. <ImageButton  
    20. android:id="@+id/record"  
    21. android:layout_width="66dp"  
    22. android:layout_height="66dp"  
    23. android:scaleType="fitCenter"  
    24. android:src="@drawable/red_no_problem" />  
    25. <ImageButton  
    26. android:id="@+id/stop"  
    27. android:layout_width="66dp"  
    28. android:layout_height="66dp"  
    29. android:scaleType="fitCenter"  
    30. android:src="@drawable/red_success" />  
    31. </LinearLayout>  
    32. </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;

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

    第二种只能自己去写暂停、录制或播放按钮;

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

    以上内容也是通过自己测试整理而来。

  • 相关阅读:
    SQL Server 文件规划 位置规划
    在VS2008中使用WSE 3.0过程全记录
    关于CDC功能的答疑
    SQL Server 2008 : 基于策略的管理(PolicyBased Management)
    使用 Google Gears 开发离线应用
    SQL Server 2008 :安装
    WCF 之UserName身份验证全记录
    SQL Server 文件规划 文件组
    不可思议的SQLite
    使用Trigger让UpdatePanel外部的控件也支持无刷新异步调用
  • 原文地址:https://www.cnblogs.com/xiaochao1234/p/4213166.html
Copyright © 2011-2022 走看看