zoukankan      html  css  js  c++  java
  • 使用Android编写录制视频小程序演示样例

    主要实现录制功能的类:Camera类MediaRecorder类。功能描写叙述:首先进入视频录制界面,点击录像button进入录像功能界面,点击录制開始录制视频, 点击停止button,将录制的视频存放到指定文件夹下存放。以下通过Samples_10_3程序实现详细功能:

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

    (2)在res/layout文件改动activity_main.xml主布局文件(主要加入一个标题摄像button)

    <?xml version="1.0" ?

    > <LinearLayout xmlns: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视图控件摄像button和停止摄像button)

    <?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"/>
    	<LinearLayout
    		android: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() {
    			//为摄像按钮加入事件监听
    			@Override
    			public 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对象
    	@Override
    	public 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类翻转Preview
    		this.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);	//注冊实现好的Callback
    		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);	//设置缓存类型
    		startButton=(Button)this.findViewById(R.id.start);	//实例化開始录制button的Button组件对象
    		stopButton=(Button)this.findViewById(R.id.stop);	//实例化停止录制button的Button组件对象
    		startButton.setEnabled(true);
    		stopButton.setEnabled(false);
    		
    		//加入摄像button单击监听
    		startButton.setOnClickListener(new View.OnClickListener() {
    			
    			@Override
    			public void onClick(View v) {
    				// 调用開始摄像方法
    				startRecording();	
    			}
    		});
    		//加入停止button单击监听
    		stopButton.setOnClickListener(new View.OnClickListener() {
    			
    			@Override
    			public 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() {
    				
    				@Override
    				public void onError(MediaRecorder arg0, int arg1, int arg2) {
    					// 停止摄像方法
    					stopRecording();
    				}
    			});
    			startButton.setText("录制中");	
    			startButton.setEnabled(false);		//開始录制button失效
    			stopButton.setEnabled(true);		//停止录制button生效
    		}catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    	}
    	/**
    	 * 手机按键监听事件
    	 */
    	@Override
    	 public boolean onKeyDown(int keyCode, KeyEvent event)
    	{
    		//推断手机按键按下是否是返回键
    		if(keyCode==KeyEvent.KEYCODE_BACK)
    		{
    			stopRecording();	//调用停止摄像方法
    			Intent intent=new Intent();		//初始化Intent
    			intent.setClass(VideoRecord.this, MainActivity.class);		//指定Intent对象启动的类
    			intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);	//清楚该进程空间中的全部Activity
    			this.startActivity(intent);		//启动新的Activity
    			VideoRecord.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() {
    				@Override
    				public 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);		//摄像button生效
    			stopButton.setEnabled(false);	//停止button生效
    			
    			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();		//初始化Camera
    		try
    		{
    			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()+"视频文件?");	//设置信息内容
    		//设置确认button,并加入button监听事件
    		alertDialog.setButton("确认", new android.content.DialogInterface.OnClickListener() {
    			
    			@Override
    			public void onClick(DialogInterface arg0, int arg1) {
    				// TODO Auto-generated method stub
    				
    			}
    		});
    		alertDialog.setButton("取消", new android.content.DialogInterface.OnClickListener() {
    			
    			@Override
    			public 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
    		}
    	}
    	/**
    	 * 初次实例化,预览界面创建时,该方法被调用
    	 */
    	@Override
    	public void surfaceCreated(SurfaceHolder arg0)
    	{
    		prepareCamera();	//调用初始化Camera
    	}
    	/**
    	 * 当预览界面的格式和大小发生变化时,该方法调用
    	 */
    	@Override
    	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
    	{
    		startCamera();		//调用開始Camera
    	}
    	/**
    	 * 当预览界面关闭时,该方法被调用
    	 */
    	@Override
    	public void surfaceDestroyed(SurfaceHolder arg0)
    	{
    		stopCamera();
    	}
    
    }
    (6)程序执行的结果如图所看到的:

    A.进入视频录制界面:



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



    C.点击录制button后视频文件被保存在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();		//初始化Intent
    			intent.setClass(VideoRecord.this, MainActivity.class);		//指定Intent对象启动的类
    			intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);	//清楚该进程空间中的全部Activity
    			this.startActivity(intent);		//启动新的Activity
    			VideoRecord.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。

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




  • 相关阅读:
    mysql 查找数组格式的字符串中是否包含某个值
    假期总结
    shell循环结构解析:for/while/case
    ansible笔记(15):循环(二)with_items/with_list/with_together/with_flattened
    ansible笔记(14):循环(一)
    解决报错Failed to start LSB: Bring up/down networking:MAC地址导致
    实现ENSP模拟器与物理主机、虚拟机通信
    zabbix4.2配置监控华为路由器:基于ENSP模拟器
    Grafana展示zabbix监控数据
    zabbix4.2配置监控TCP连接状态
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6709446.html
Copyright © 2011-2022 走看看