前言

通过上篇通过MediaRecord实现录音后,对MediaRecord有了基本的了解,本篇是通过其实现视频的录制


地址

前人栽树:http://www.cnblogs.com/whoislcj/p/5583833.html

后人乘凉:http://blog.csdn.net/xiangyong_1521/article/details/78249343


补充:MediaRecorder主要配置参数:

  1. 视频编码格式MediaRecorder.VideoEncoderdefault,H263,H264,MPEG4SP,VP8
  2. 音频编码格式MediaRecorder.AudioEncoderdefault,AAC,HEAAC,AACELD,AMRNB,AMRWB,VORBIS
  3. 视频资源获取方式MediaRecorder.VideoSourcedefault,CAMERA,SURFACE
  4. 音频资源获取方式MediaRecorder.AudioSourcedefalut,camcorder,mic,voicecall,voicecommunication,voicedownlink,voicerecognition, voice_uplink
  5. 资源输出格式MediaRecorder.OutputFormatamrnb,amrwb,default,mpeg4,rawamr,threegpp,aacadif, aacadts, outputformatrtpavp, outputformatmpeg2ts ,webm

实现


主要代码

  • MediaRecord
package com.example.book_mediarecorder;import java.io.File;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.graphics.PixelFormat;
import android.hardware.Camera; public class MediaRecord extends Activity implements SurfaceHolder.Callback{private SurfaceView mSurfaceView;private SurfaceHolder mSurfaceHolder;private Button btnStartStop;private boolean isRecording = false;//标记是否已经在录制private  MediaRecorder mRecorder;//音视频录制类private Camera mCamera = null;//相机private Camera.Size mSize = null;//相机的尺寸private int mCameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;//默认后置摄像头private static final SparseIntArray orientations = new SparseIntArray();//手机旋转对应的调整角度static {orientations.append(Surface.ROTATION_0, 90);orientations.append(Surface.ROTATION_90, 0);orientations.append(Surface.ROTATION_180, 270);orientations.append(Surface.ROTATION_270, 180);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setWindow();setContentView(R.layout.mediarecord);initViews();}private void setWindow() {requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏// 设置竖屏显示setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);// 选择支持半透明模式,在有surfaceview的activity中使用。getWindow().setFormat(PixelFormat.TRANSLUCENT);}private void initViews() {mSurfaceView = (SurfaceView) findViewById(R.id.sf_view);btnStartStop = (Button) findViewById(R.id.rButton_media);btnStartStop.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!isRecording) {startRecord();} else {stopRecord();}}});SurfaceHolder holder = mSurfaceView.getHolder();// 取得holderholder.setFormat(PixelFormat.TRANSPARENT);holder.setKeepScreenOn(true);holder.addCallback(this); // holder加入回调接口}/*** 初始化相机*/private void initCamera() {if (Camera.getNumberOfCameras() == 2) {mCamera = Camera.open(mCameraFacing);} else {mCamera = Camera.open();}CameraSizeComparator sizeComparator = new CameraSizeComparator();Camera.Parameters parameters = mCamera.getParameters();if (mSize == null) {List<Camera.Size> vSizeList = parameters.getSupportedPreviewSizes();Collections.sort(vSizeList, sizeComparator);for (int num = 0; num < vSizeList.size(); num++) {Camera.Size size = vSizeList.get(num);if (size.width >= 800 && size.height >= 480) {this.mSize = size;break;}}mSize = vSizeList.get(0);List<String> focusModesList = parameters.getSupportedFocusModes();//增加对聚焦模式的判断if (focusModesList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);} else if (focusModesList.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);}mCamera.setParameters(parameters);}int rotation = getWindowManager().getDefaultDisplay().getRotation();int orientation = orientations.get(rotation);mCamera.setDisplayOrientation(orientation);}@Overrideprotected void onResume() {super.onResume();initCamera();}@Overridepublic void onPause() {releaseCamera();super.onPause();}/*** 开始录制*/private void startRecord() {if (mRecorder == null) {mRecorder = new MediaRecorder(); // 创建MediaRecorder}if (mCamera != null) {mCamera.stopPreview();mCamera.unlock();mRecorder.setCamera(mCamera);}try {// 设置音频采集方式mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);//设置视频的采集方式mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);//设置文件的输出格式mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//aac_adif, aac_adts, output_format_rtp_avp, output_format_mpeg2ts ,webm//设置audio的编码格式mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置video的编码格式mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设置录制的视频编码比特率mRecorder.setVideoEncodingBitRate(1024 * 1024);//设置录制的视频帧率,注意文档的说明:mRecorder.setVideoFrameRate(30);//设置要捕获的视频的宽度和高度mSurfaceHolder.setFixedSize(320, 240);//最高只能设置640x480mRecorder.setVideoSize(320, 240);//最高只能设置640x480//设置记录会话的最大持续时间(毫秒)mRecorder.setMaxDuration(60 * 1000);mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());String path = getExternalCacheDir().getPath();if (path != null) {File dir = new File(path + "/videos");if (!dir.exists()) {dir.mkdir();}path = dir + "/" + System.currentTimeMillis() + ".mp4";//设置输出文件的路径mRecorder.setOutputFile(path);//准备录制mRecorder.prepare();//开始录制mRecorder.start();isRecording = true;btnStartStop.setText("停止");}} catch (Exception e) {e.printStackTrace();}}/*** 停止录制*/private void stopRecord() {try {//停止录制mRecorder.stop();//重置mRecorder.reset();btnStartStop.setText("开始");} catch (Exception e) {e.printStackTrace();}isRecording = false;}/*** 释放MediaRecorder*/private void releaseMediaRecorder() {if (mRecorder != null) {mRecorder.release();mRecorder = null;}}/*** 释放相机资源*/private void releaseCamera() {try {if (mCamera != null) {mCamera.stopPreview();mCamera.setPreviewCallback(null);mCamera.unlock();mCamera.release();}} catch (RuntimeException e) {} finally {mCamera = null;}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHoldermSurfaceHolder = holder;if (mCamera == null) {return;}try {//设置显示mCamera.setPreviewDisplay(holder);mCamera.startPreview();} catch (Exception e) {e.printStackTrace();releaseCamera();finish();}}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHoldermSurfaceHolder = holder;}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// surfaceDestroyed的时候同时对象设置为nullif (isRecording && mCamera != null) {mCamera.lock();}mSurfaceView = null;mSurfaceHolder = null;releaseMediaRecorder();releaseCamera();}private class CameraSizeComparator implements Comparator<Camera.Size> {public int compare(Camera.Size lhs, Camera.Size rhs) {if (lhs.width == rhs.width) {return 0;} else if (lhs.width > rhs.width) {return 1;} else {return -1;}}}}
  • XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><SurfaceViewandroid:id="@+id/sf_view"android:layout_width="match_parent"android:layout_height="match_parent" /><Buttonandroid:id="@+id/rButton_media"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:text="开始录像" /></RelativeLayout>

  • 权限
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><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.READ_EXTERNAL_STORAGE" /><!-- 硬件支持 --><uses-feature android:name="android.hardware.camera" /><uses-feature android:name="android.hardware.camera.autofocus" />

0
0
  • 上一篇笔记14 | 图片倒影+渐变效果
  • 下一篇笔记20 | 学习整理开源APP(BaseAnimation)程序源码“中的通讯录效果
相关文章推荐
  • Android--MediaRecorder实现手机录像
  • MVVM在美团点评酒旅移动端的最佳实践--王禹华
  • 使用MediaRecorder实现简单的录像功能
  • C语言大型软件设计的面向对象--宋宝华
  • 用MediaRecorder实现简单的录像功能
  • Retrofit 从入门封装到源码解析
  • 整合Camera和MediaRecorder实现拍照和录像
  • 跳过Java开发的各种坑
  • 使用MediaRecorder+SurfaceView实现录像
  • Spring Boot 2小时入门基础教程
  • Android 多媒体 通过MediaRecorder+SurfaceView实现拍照,录像
  • Shell脚本编程
  • Android中通过MediaRecorder录音录像
  • Android中使用MediaRecorder进行录像详解
  • Android使用MediaRecorder录像
  • android Camera拍照 及 MediaRecorder录像 预览图像差90度

转载于:https://www.cnblogs.com/xiangevan/p/7818142.html

笔记19 | 利用MediaRecorder实现录像相关推荐

  1. 推荐系统实践读书笔记-04利用用户标签数据

    推荐系统实践读书笔记-04利用用户标签数据 推荐系统的目的是联系用户的兴趣和物品,这种联系需要依赖不同的媒介.GroupLens在一篇文章中表示目前流行的推荐系统基本上通过3种方式联系用户兴趣和物品. ...

  2. 推荐系统实践读书笔记-06利用社交网络数据

    推荐系统实践读书笔记-06利用社交网络数据 自从搜索引擎谷歌诞生后,大家都在讨论互联网的下一个金矿是什么.现在,几乎所有的人都认为那就是社交网络.根据尼尔森2010年的报告,用户在互联网上22%的时间 ...

  3. Linux 学习笔记19 信号

    Linux 学习笔记19 信号 信号 信号概述 为什么要是使用信号--为了实现进程的有序退出 信号是进程运行过程中,由自身产生或者由进程外部发来的消息.信号是硬件中断的软件模拟(软中断) signal ...

  4. vm虚拟机安装lede旁路由_折腾群晖笔记:利用VMM虚拟机 安装LEDE旁路由 实现软路由超强功能...

    折腾群晖笔记:利用VMM虚拟机 安装LEDE旁路由 实现软路由超强功能 2019-07-04 15:02:49 305点赞 2000收藏 292评论 你是AMD Yes党?还是intel和NVIDIA ...

  5. 工作笔记1——利用bat脚本实现批量上传文件到ftp服务器

    工作笔记1--利用bat脚本实现批量上传文件到ftp服务器 问题概述 利用ftp命令实现上传文件 注意 限时功能 将共享目录映射到电脑中的某个盘符 实现断点续传 问题概述 公司中有大概225k个文件需 ...

  6. 《编程之美》读书笔记19: 3.9 重建二叉树

    <编程之美>读书笔记19: 3.9 重建二叉树 对根节点a以及先序遍历次序P和中序遍历次序I,查找a在I中的位置,将I分为两部分,左边部分的元素都在a的左子树上,右边的元素都在a的右子树上 ...

  7. 第十九章 19 利用私有继承来实现代码重用

    //19 利用私有继承来实现代码重用 //我们还有一种方法来实现这种包含式的代码重用,那就是私有继承,派生类从基类私有继承后,其类的公有成员和保护成员在派生类中都是私有成员,私有成员成为不可访问的成员 ...

  8. Ext.Net学习笔记19:Ext.Net FormPanel 简单用法

    Ext.Net学习笔记19:Ext.Net FormPanel 简单用法 FormPanel是一个常用的控件,Ext.Net中的FormPanel控件同样具有非常丰富的功能,在接下来的笔记中我们将一起 ...

  9. springmvc学习笔记(19)-RESTful支持

    springmvc学习笔记(19)-RESTful支持 标签: springmvc springmvc学习笔记19-RESTful支持 概念 REST的样例 controller REST方法的前端控 ...

最新文章

  1. 【技术随笔】学习C语言之前你要知道的事
  2. 2020年人工智能领域突破性工作
  3. typescript设置只读属性和任意类型
  4. bzoj 1369: Gem 树形dp
  5. 嵌入式学习在linux下使用c语言对文件进行打开、读写操作。_2000字干货!单片机进阶嵌入式Linux要怎么学习……...
  6. 笑傲江湖客户端服务器地址修改,《笑傲江湖》改键调整操作手把手教你玩笑傲...
  7. 工作45:注意公用方法 别混入
  8. [WorldWind学习]5.相机对象
  9. mysql 字符转数组_mysql下将分隔字符串转换为数组
  10. 人工智能数学基础之概率论
  11. linux下cmake使用教程,超详细的cmake教程
  12. python网络爬虫笔记-re正则表达式
  13. 引子——漂在中关村 1
  14. Transformer相关的各种预训练模型优点缺点对比总结与资料收集(Transformer/Bert/Albert/RoBerta/ERNIE/XLnet/ELECTRA)
  15. docker安装和入门教程
  16. 七周七并发模型与七周七语言
  17. 《一往无前》10岁的小米,给世界讲了一个怎样的故事?
  18. 计算机绩点3.2算什么水平,绩点3.3代表什么水平
  19. Unity 大气特效插件分析 - Aura #01
  20. 洛谷P2790 ccj与zrz之积木问题 题解

热门文章

  1. Android基于nfc的读写(一)
  2. 武汉市首个城管装备部于8月1日上午在汉阳区城管局建立
  3. 各种友(e)善(xin)数论总集,从入门到绝望2---快速判断素数
  4. 贫乏却最美好的三段论和神奇而不太严格的欧几里得算法-逻辑与算法之六
  5. 嘉立创电路板制作过程全流程详解(四):阻焊、字符、喷锡或沉金
  6. 【方向盘】的新版Blog正式上线,2个周末,历时100+小时
  7. 基于rk3288平台的gt9xx 触摸驱动移植
  8. Cinema 4D 手指关节制作、关节绑定模型
  9. JavaAWT教程1F
  10. C语言中计算字符个数