使用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目录以下:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
D.MyVideo目录下录制好的文件:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
(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。
使用Android编写录制视频小程序演示样例的更多相关文章
- MapGuide应用程序演示样例——你好,MapGuide!
图 3‑4显示了基于MapGuide的Web应用程序的开发流程,整个开发流程能够分为五个阶段.图中,矩形代表任务,椭圆形被任务使用的或被任务创建的实体,箭头代表数据流. 1) 载入文件类型的数据,配置 ...
- 【UNIX网络编程(三)】TCP客户/server程序演示样例
上一节给出了TCP网络编程的函数.这一节使用那些基本函数编写一个完毕的TCP客户/server程序演示样例. 该样例运行的过程例如以下: 1.客户从标准输入读入一行文本,并写给server. 2.se ...
- Android通过startService播放背景音乐简单演示样例
关于startService的基本使用概述及其生命周期可參见博客<Android中startService的使用及Service生命周期>. 本文通过播放背景音乐的简单演示样例,演示sta ...
- android动画-动画分类及代码演示样例
原来一直对动画一知半解,仅仅知道依照网上的方法会用即可了,可是自己写起来感觉确实有点费劲,今天最终研究了代码实现,一下子感觉清晰多了.先把总结例如以下,代码中有具体的凝视. 动画分类 1.Peoper ...
- 使用JavaScript定义一个微信小程序插件样例
var wxTimer = new wxTimer({ beginTime: "00:00:20", complete: function () { wx.redirectTo({ ...
- Android之——流量管理程序演示样例
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47680811 眼下.市面上有非常多管理手机流量的软件,能够让用户实时获取到自己手机 ...
- 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇)
系列文章 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇) 手牵手,使用uni-app从零开发一款视频小程序 (系列下 开发实战篇) 前言 好久不见,很久没更新博客了,前段时间 ...
- 手牵手,使用uni-app从零开发一款视频小程序 (系列下 开发实战篇)
系列文章 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇) 手牵手,使用uni-app从零开发一款视频小程序 (系列下 开发实战篇) 扫码体验,先睹为快 可以扫描下微信小程序的 ...
- uni-app微信小程序开发之引入腾讯视频小程序播放插件
登录微信小程序管理后台添加腾讯视频播放插件: 正式开始使用腾讯视频小程序插件之前需先在微信公众平台 -> 第三方设置 -> 插件管理处添加插件,如下图所示: 在uni-app中引入插件代码 ...
随机推荐
- 基于Landmark的人脸对齐以及裁剪方法
利用Landmarks进行人脸对齐裁剪是人脸检测中重要的一个步骤.效果如下图所示: 基本思路为: a.人脸检测 人脸的检测不必多说了,基本Cascade的方式已经很不错了,或者用基于HOG/FHOG的 ...
- CentOS6安装redmine
Author: JinDate: 20140827System: CentOS release 6.5 (Final) 参考:http://www.redmine.org/projects/redmi ...
- 使用Chrome快速实现数据的抓取(一)——概述
对于一些简单的网页,我们可以非常容易的通过Develop Tool来获取其请求报文规律,并仿照其构建报文来获取页面信息.但是,随着网页越来越复杂,许多页面是由js动态渲染生成的.要获取这类信息,则需要 ...
- RAD Studio 2010~XE8 官方 ISO 下载地址 (2015-03-28更新)
http://bbs.csdn.net/topics/390816856 RAD Studio XE8 目前最新版 v22.0.19027.8951 官方 ISO 文件下载(6.72GB):http: ...
- linux 内核大牛-谢宝友
http://blog.chinaunix.net/uid/25845340.html 谢宝友:毕业于四川省税务学校税收专业,现供职于中兴通讯操作系统团队,对操作系统内核有较强的兴趣.专职于操作系统内 ...
- 关于ANDROID模拟器的一些事
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 继上一篇Android Studio VS Eclipse的文章后接着来分享AnDevCo ...
- NGUI 3.5教程(一)安装NGUI 3.5.8
写在前面: 网上找的NGUI教程,都是基于2.x版本号的.为了能配合教程学着做,我也是下载了各种NGUI 2.x版本号.可是在导入的时候,或多或少都报错(我用的Unity 的版本号是4.3.2).无奈 ...
- Informatica 常用组件Lookup缓存之三 重建查找高速缓存
如果您认为查找源在 PowerCenter 上次构建高速缓存时已更改,则可指示 PowerCenter 重建查找高速缓存. 重建高速缓存时,PowerCenter 会覆盖现有永久高速缓存文件而创建新的 ...
- 求两个数中的较大值max(a,b)。(不用if,>)
题目:求两个数的较大值,不能使用if.>. 1.不使用if.>,还要比较大小,貌似就只能使用条件表达式: x=<表达式1>?<表达式2>:<表达式3>; ...
- ScaleIO与XtremSW Cache如何集成呢?
在ScaleIO上, XtremSW Cache主要有两种部署方式: 把XtremSW Cache在每台server的内部用作cache - 在ScaleIO Data Server(SDS)下做ca ...