使用Android编写录制视频小程序示例

来源:互联网 发布:网络公关公司排名 编辑:程序博客网 时间:2024/06/06 15:36

主要实现录制功能的类:Camera类MediaRecorder类。功能描述:首先进入视频录制界面,点击录像按钮进入录像功能界面,点击录制开始录制视频, 点击停止按钮,将录制的视频存放到指定目录下存放。下面通过Samples_10_3程序实现具体功能:

(1)新建一个Android Application Project项目取名为Samples_10_3

(2)在res/layout文件修改activity_main.xml主布局文件(主要添加一个标题摄像按钮)

<?xml version="1.0" ?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"><TextView android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/hello"/><Button android:id="@+id/camera_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="摄像"/></LinearLayout>

(3)因为要实现摄像的功能,在res/layout目录下添加video.xml布局文件(主要包括SurfaceView视图控件摄像按钮和停止摄像按钮)

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:id="@+id/linearLayout1" >    <SurfaceView     android:id="@+id/surface_view"    android:layout_width="wrap_content"    android:layout_height="fill_parent"    android:layout_weight="0.58"/><LinearLayoutandroid:id="@+id/linearLayout2"android:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="vertical"><Button android:id="@+id/start"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="录制"/><Button android:id="@+id/stop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="停止"/></LinearLayout></LinearLayout>
(4)首先需要给程序必要的权限才能读/写、访问Camera、录制音频文件、创建删除文件等权限。在程序的AndroidManifest.xml程序清单文件下添加如下权限:

读取Camera权限

<uses-permission android:name="android.permission.CAMERA" ></uses-permission>
视频录制权限
<span style="color:#ff0000;"><uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission></span>
读写内存卡权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
创建和删除文件目录权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
因为因为VideoRecord.java类是另一个Activity所以还需要在AndroidMainifest.xml文件中添加这样一段代码(一般这里的类名需要写完整的类结构):
<activity android:name=".VideoRecord"></activity>
(5)下面就是两个Activity实现布局文件调用和具体功能的实现:MainActivity.java类(摄像主界面)和VideoRecord类(摄像功能):
A.MainActivity.java类的具体实现:

package com.example.samples_10_3;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.View;import android.widget.Button;import android.content.Intent;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                Button button=(Button)this.findViewById(R.id.camera_button);//实例化摄像按钮对象        button.setOnClickListener(new View.OnClickListener() {//为摄像按钮添加事件监听@Overridepublic void onClick(View arg0) {Intent intent=new Intent();intent.setClass(MainActivity.this, VideoRecord.class);//intent对象指定的类MainActivity.this.startActivity(intent);//启动新的Activity}});    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        return true;    }    }
B.VideoRecord的具体实现:

package com.example.samples_10_3;import android.app.Activity;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;import android.widget.Button;import android.media.MediaRecorder;import android.hardware.Camera;import java.io.File;import android.os.Bundle;import android.graphics.PixelFormat;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.content.pm.ActivityInfo;import android.os.Environment;import android.app.AlertDialog;import android.content.DialogInterface;import android.media.MediaRecorder.OnErrorListener;import java.io.IOException;import android.view.KeyEvent;import android.content.Intent;public class VideoRecord extends Activity implements Callback  {private SurfaceView surfaceView=null;//创建一个空的SurfaceView对象private SurfaceHolder surfaceHolder=null;//创建一个空的SurfaceHolder对象private Button startButton=null;//创建一个开始录制Button组件对象private Button stopButton=null;//创建一个停止录制Button组件对象private MediaRecorder mediaRecorder=null;//创建一个空的MediaRecorder对象private Camera camera=null;//创建一个空的Camera对象private boolean previewRunning=false;//预览状态private File videoFile=null;//录制视频文件的File对象@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);this.getWindow().setFormat(PixelFormat.TRANSLUCENT);//窗口设为半透明this.requestWindowFeature(Window.FEATURE_NO_TITLE);//窗口去掉标题this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//窗口设置为全屏//setRequestedOrientation类翻转Previewthis.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//设置预览水平翻转this.setContentView(R.layout.video);surfaceView=(SurfaceView)this.findViewById(R.id.surface_view);//实例化SurfaceView对象surfaceHolder=surfaceView.getHolder();//获取SurfaceHolder对象surfaceHolder.addCallback(this);//注册实现好的CallbacksurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置缓存类型startButton=(Button)this.findViewById(R.id.start);//实例化开始录制按钮的Button组件对象stopButton=(Button)this.findViewById(R.id.stop);//实例化停止录制按钮的Button组件对象startButton.setEnabled(true);stopButton.setEnabled(false);//添加摄像按钮单击监听startButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 调用开始摄像方法startRecording();}});//添加停止按钮单击监听stopButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//调用停止摄像方法stopRecording();}});}/** * 开始摄像方法 */public void startRecording(){try{stopCamera();//调用停止Camera方法if(!getStorageState())//判断是否有存储卡,如果没有就关闭页面{VideoRecord.this.finish();}//获取存储(sdCard)的根目录String sdCard=Environment.getExternalStorageDirectory().getPath();//设置相片存放的目录String dirFilePath=sdCard+File.separator+"MyVideo";//获取录制文件夹路径的File对象File dirFile=new File(dirFilePath);if(!dirFile.exists())//判断文件夹是否存在{dirFile.mkdir();//创建文件}//创建录制视频临时文件videoFile=File.createTempFile("video", ".3gp",dirFile);//初始化MediaRecorder对象mediaRecorder=new MediaRecorder();mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());//设置预览mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);//Camera视频源mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//录音源为麦克风//输出格式为3gp格式mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);mediaRecorder.setVideoSize(480, 320);//视频尺寸mediaRecorder.setVideoFrameRate(15);//视频帧的频率mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//视频编码mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//音频编码mediaRecorder.setMaxDuration(10000);//最大期限mediaRecorder.setOutputFile(videoFile.getAbsolutePath());//保存路径mediaRecorder.prepare();//准备录制mediaRecorder.start();//开始录制//文件录制错误监听mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {@Overridepublic void onError(MediaRecorder arg0, int arg1, int arg2) {// 停止摄像方法stopRecording();}});startButton.setText("录制中");startButton.setEnabled(false);//开始录制按钮失效stopButton.setEnabled(true);//停止录制按钮生效}catch(Exception e){e.printStackTrace();}}/** * 手机按键监听事件 */@Override public boolean onKeyDown(int keyCode, KeyEvent event){//判断手机按键按下是否是返回键if(keyCode==KeyEvent.KEYCODE_BACK){stopRecording();//调用停止摄像方法Intent intent=new Intent();//初始化Intentintent.setClass(VideoRecord.this, MainActivity.class);//指定Intent对象启动的类intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//清楚该进程空间中的所有Activitythis.startActivity(intent);//启动新的ActivityVideoRecord.this.finish();//销毁这个Activity}return super.onKeyDown(keyCode, event);}/** * 获取sdCard存储状态 * @return 手机sd卡的存储状态 */public boolean getStorageState(){if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))//判断sdCard的存储状态{return true;}else{new AlertDialog.Builder(this)//创建AlertDialog对象.setTitle("提示信息")//设置信息标题.setMessage("未安装SD卡,请检查你的设备")//设置信息内容.setPositiveButton("确定", new android.content.DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface arg0, int arg1) {// 结束应用程序VideoRecord.this.finish();}}).show();//设置弹出提示框return false;}}/** * 停止摄像 */public void stopRecording(){if(mediaRecorder!=null)//判定MediaRecorder对象是否为空{mediaRecorder.stop();//停止摄像mediaRecorder.release();//释放资源mediaRecorder=null;//置空MediaRecorder对象startButton.setEnabled(true);//摄像按钮生效stopButton.setEnabled(false);//停止按钮生效startButton.setText("录制");isSave();//调用是否保存方法}stopCamera();//调用停止Camera方法prepareCamera();//调用初始化Camera对象startCamera();//调用开始Camera方法}/** * 开始Camera */public void startCamera()//判断预览开启{if(previewRunning){camera.stopPreview();//停止预览}try{//设置用SurfaceView作为承载镜头取景画面显示camera.setPreviewDisplay(surfaceHolder);camera.startPreview();//开始预览previewRunning=true;//设置预览状态为true}catch(IOException e){e.printStackTrace();}}/** * 初始化Camera方法 */public void prepareCamera(){camera=Camera.open();//初始化Cameratry{camera.setPreviewDisplay(surfaceHolder);//设置预览}catch(IOException e){camera.release();//释放相机资源camera=null;//置空Camera对象}}/** * 是否保存视频录制的文件 */public void isSave(){AlertDialog alertDialog=new AlertDialog.Builder(this).create();//创建AlertDialog对象alertDialog.setTitle("提示信息");alertDialog.setMessage("是否保存"+videoFile.getName()+"视频文件?");//设置信息内容//设置确认按钮,并添加按钮监听事件alertDialog.setButton("确认", new android.content.DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface arg0, int arg1) {// TODO Auto-generated method stub}});alertDialog.setButton("取消", new android.content.DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface arg0, int arg1) {//判断文件是否存在,存在删除文件if(videoFile.exists()){videoFile.delete();}}});alertDialog.show();//设置弹出提示框}/** * 停止Camera */public void stopCamera(){if(camera!=null)//判断Camera对象不为空{camera.stopPreview();//停止预览camera.release();//释放Camera资源camera=null;previewRunning=false;//设置预览状态为false}}/** * 初次实例化,预览界面创建时,该方法被调用 */@Overridepublic void surfaceCreated(SurfaceHolder arg0){prepareCamera();//调用初始化Camera}/** * 当预览界面的格式和大小发生变化时,该方法调用 */@Overridepublic void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3){startCamera();//调用开始Camera}/** * 当预览界面关闭时,该方法被调用 */@Overridepublic void surfaceDestroyed(SurfaceHolder arg0){stopCamera();}}
(6)程序运行的结果如图所示:

A.进入视频录制界面:



B.点击摄像按钮进入视频预览功能:



C.点击录制按钮后视频文件被保存在MyVideo文件夹下面:



D.MyVideo文件夹下录制好的文件:



(7)代码程序具体详解:

                       //获取存储(sdCard)的根目录String sdCard=Environment.getExternalStorageDirectory().getPath();//设置相片存放的目录String dirFilePath=sdCard+File.separator+"MyVideo";//获取录制文件夹路径的File对象File dirFile=new File(dirFilePath);if(!dirFile.exists())//判断文件夹是否存在{dirFile.mkdir();//创建文件}//创建录制视频临时文件videoFile=File.createTempFile("video", ".3gp",dirFile);

获取手机sdCard根目录,指定根目录下自定义文件夹用于存放录制视频文件,以3gp格式存储,video为前缀

<span style="white-space:pre"></span>//判断手机按键按下是否是返回键if(keyCode==KeyEvent.KEYCODE_BACK){stopRecording();//调用停止摄像方法Intent intent=new Intent();//初始化Intentintent.setClass(VideoRecord.this, MainActivity.class);//指定Intent对象启动的类intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//清楚该进程空间中的所有Activitythis.startActivity(intent);//启动新的ActivityVideoRecord.this.finish();//销毁这个Activity}
这是Activity类的onKeyDown事件用于监听,点击手机返回键时,回到MainActivity窗体并销毁VideoRecord这个Activity.指定Intent.FLAG_ACTIVITY_CLEAR_TOP例如现在的栈情况为:A B C D 。D此时通过intent跳转到B,如果这个intent添加FLAG_ACTIVITY_CLEAR_TOP标记,则栈情况变为:A B。

至此所有的摄像功能的介绍都已经结束了,录制视频需要考虑调用摄像头功能和音频录制功能。




1 0