Android调用手机摄像头使用MediaRecorder录像并播放
最近在项目开发中需要调用系统的摄像头录像并播放。
在开发中遇到了两个问题,记录下:
(1)开发过程中出现摄像头占用,启动失败,报错。但是我已经在onDestory()中关闭了资源。
报错原因:打开程序,调用摄像头,按Home键再打开程序调用,报错摄像头被占用。
解决:在onStop()中关闭资源,在onResume()中判断是否为null,否则实例化资源。
(2)其中我录像播放的代码写在Fragment+ViewPager中,在来回切换Fragment的时候,摄像头只能调用一次,并且所在的Fragment可能会被销毁。(这里可去看下Fragment生命周期的调用过程)
报错原因:ViewPager有缓存加载机制,只会预缓存下一页。所以在来回切换的过程中录像播放Fragment存在不断销毁、创建的可能。
解决:如果你的ViewPager页数不多,并大概知道它的页数,可以修改ViewPager的缓存页面数量。
viewPagwer.setoffscreenPageLimit(int numbers); //当页面切换时,当前页面相邻两侧的numbers页面不会被销毁。
ViewPager的缓存机制: http://www.cnblogs.com/Joanna-Yan/p/4824434.html
下面看具体的代码分析:
录制过程:
mediarecorder = new MediaRecorder();// 创建mediarecorder对象
// 设置录制视频源为Camera(相机)
mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4
mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// 设置录制的视频编码h263 h264
mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
// 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错
mediarecorder.setVideoSize(176, 144);
// 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错
mediarecorder.setVideoFrameRate(20);
mediarecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
// 设置视频文件输出的路径
lastFileName = newFileName();
mediarecorder.setOutputFile(lastFileName);
try {
// 准备录制
mediarecorder.prepare();
// 开始录制
mediarecorder.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
结束拍摄:
if (mediarecorder != null) {
// 停止
mediarecorder.stop();
mediarecorder.release();
mediarecorder = null;
}
自己的封装类:
package zyf.demo.moviedemo;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import android.media.MediaRecorder;
import android.view.SurfaceView;
public class MovieRecorder {
private MediaRecorder mediarecorder;
boolean isRecording;
public void startRecording(SurfaceView surfaceView) {
mediarecorder = new MediaRecorder();// 创建mediarecorder对象
// 设置录制视频源为Camera(相机)
mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4
mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// 设置录制的视频编码h263 h264
mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
// 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错
mediarecorder.setVideoSize(176, 144);
// 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错
mediarecorder.setVideoFrameRate(20);
mediarecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
// 设置视频文件输出的路径
lastFileName = newFileName();
mediarecorder.setOutputFile(lastFileName);
try {
// 准备录制
mediarecorder.prepare();
// 开始录制
mediarecorder.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
isRecording = true;
timeSize = 0;
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
timeSize++;
}
}, 0,1000);
}
Timer timer;
int timeSize = 0;
private String lastFileName;
public void stopRecording() {
if (mediarecorder != null) {
// 停止
mediarecorder.stop();
mediarecorder.release();
mediarecorder = null;
timer.cancel();
if (null != lastFileName && !"".equals(lastFileName)) {
File f = new File(lastFileName);
String name = f.getName().substring(0,
f.getName().lastIndexOf(".3gp"));
name += "_" + timeSize + "s.3gp";
String newPath = f.getParentFile().getAbsolutePath() + "/"
+ name;
if (f.renameTo(new File(newPath))) {
int i = 0;
i++;
}
}
}
}
public String newFileName() {
try {
return File.createTempFile("/mov_", ".3gp").getAbsolutePath();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
public void release() {
if (mediarecorder != null) {
// 停止
mediarecorder.stop();
mediarecorder.release();
mediarecorder = null;
}
} }
如何播放:
public void play(String fileName, SurfaceView view) {
mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDisplay(view.getHolder()); // 定义一个SurfaceView播放它
mPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer arg0) {
stop();
// canvas.drawColor(Color.TRANSPARENT,
// PorterDuff.Mode.CLEAR);
}
});
try {
mPlayer.setDataSource(fileName);
mPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mPlayer.start();
}
结束播放时:
public void stop() {
if (mPlayer != null) {
mPlayer.release();
mPlayer = null;
}
}
附上源码:http://pan.baidu.com/s/1dDuI2HF 提取码:cmm6
Android调用手机摄像头使用MediaRecorder录像并播放的更多相关文章
- html5调用手机摄像头,实现拍照上传功能
今天做手机网站,想实现手机扫描二维码功能.首先实现在浏览器中调用手机摄像头,实现拍照功能并且把拍下的照片显示在页面并上传到服务器上,然后再在服务器端进行分析. 首先实现在浏览器中调用摄像头,当然用现在 ...
- 怎样让HTML5调用手机摄像头拍照——实践就是一切
原文:怎样让HTML5调用手机摄像头拍照--实践就是一切 NanShan 小编将思路提供给了大家.学编程最重要的是实践,我这尽管有完好的代码,可是希望大家都能够自己写出属于自己的代码 HTML5 Th ...
- 亲测可用)html5 file调用手机摄像头
在切图网一个客户的webapp项目中需要用到 html5调用手机摄像头,找了很多资料,大都是 js调用api 然后怎样怎样,做了几个demo测试发现根本不行, 后来恍然大悟,用html5自带的 in ...
- 使用HTML5+调用手机摄像头和相册
前言:前端时间使用HTML5做了一个WEB端APP,其中用到了H5页面调用手机摄像头的功能,当时也是花了不少时间去研究.最终是采用了HTML5plus(HTML5+)的方式完成了该功能,现将具体方法简 ...
- HTML5调用手机摄像头,仅仅支持OPPOHD浏览器
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Android调用手机中的应用市场,去评分的功能实现
在我们常常使用的软件当中,我们经常可以看到在软件的设置界面,有一个功能那就是去评分的功能,只要我们一点击“去评分”就会调用手机中的应用市场软件.一开始我以为这个功能的实现是要遍历整个手机中的软件包名, ...
- Android 调用系统照相机拍照和录像
本文实现android系统照相机的调用来拍照 项目的布局相当简单,只有一个Button: <RelativeLayout xmlns:android="http://schemas.a ...
- Android实现手机摄像头的自动对焦
如何实现Android相机的自动对焦,而且是连续自动对焦的.当然直接调用系统相机就不用说了,那个很简单的.下面我们主要来看看如如何自己实现一个相机,并且实现自动连续对焦. 代码如下: public c ...
- js 调用手机摄像头或相册并展示图片
效果图 手机浏览器.微信打开该网页,都支持调用摄像头拍照和打开相册. 先看最终结果: 每次点击“点击上传”,可以选择相册或者拍照,选完以后可以多展示一张图片,同时上传服务器. 点击“重新上传”,清空所 ...
随机推荐
- 重拾java之路之webservice
Web service平台是一套标准,它定义了应用程序如何在Web上实现互操作性.你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web servi ...
- DLL和LIB的一些知识点(网上搜集)
关于lib和dll的区别如下:(1)lib是编译时用到的,dll是运行时用到的.如果要完成源代码的编译,只需要lib:如果要使动态链接的程序运行起来,只需要dll.(2)如果有dll文件,那么lib一 ...
- 【leetcode】Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- spark on centos6.5 安装
第一步在centos 6.5上安装java 运行环境 http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-18 ...
- iOS Wi-Fi
查漏补缺集是自己曾经做过相关的功能,但是重做相关功能或者重新看到相关功能的实现,感觉理解上更深刻.这一类的文章集中记录在查漏补缺集. iOS 开发中难免会遇到很多与网络方面的判断,这里做个汇总,大多可 ...
- Swift语言的基础详解
1.1.关于swift · Swift 是一种适用于 iOS 和 OS X 应用的全新编程语言,它建立在最好的 C 和 Objective-C 语言之上,并且没有 C 语言的兼容性限制.Swift 采 ...
- 将EnyimMemcached从.NET Core RC1升级至RC2
.NET Core RC1时project.json中的配置如下: { "version": "3.2.4", "summary": &qu ...
- JavaScript –类型之我晕
每次写博我觉得取上恬当的题目比整篇行文都难,词量有限的情况下突然想到JavaScript拾遗应该会是一个非常文艺而夺目的博文题目,但我并没有急着使用,经验告诉我应该先去搜一下看有没有被用过.果不其然, ...
- ReactMix框架,让你实现一套js代码,基于ReactNative在H5,App都能完美跑起来,Write Once,Run Anywhere
ReactNative框架推出已经有一段时间了,相信很多小伙伴都在尝试实现Write Once, Run Anywhere的梦想,比如淘宝的ReactWeb等等,但是这些框架都局限于因为ReactNa ...
- flex swf和movieclip之前的微妙关系
开始不清楚, 一直尝试想load图片一样加载一个swftools转换的swf,然后在尝试转换成movieclip的时候,总是报错, avmiMovieClip 不能转换成movieclip之类的. 但 ...