前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android多媒体录制--MediaRecorder视频录制

Android多媒体录制--MediaRecorder视频录制

作者头像
听着music睡
发布于 2018-05-18 07:51:14
发布于 2018-05-18 07:51:14
2.9K00
代码可运行
举报
文章被收录于专栏:Android干货Android干货
运行总次数:0
代码可运行

Android使用MediaRecorder类进行视频的录制。

需要注意,使用MediaRecorder 录音录像 的设置代码步骤一定要按照API指定的顺序来设置,否则报错

步骤为:

1、设置视频源,音频源,即输入源

2、设置输出格式

3、设置音视频的编码格式

一、首先看布局文件,这里有一个SurfaceView,这是一个绘制容器,可以直接从内存或者DMA等硬件接口取得图像数据,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                tools:context="com.xqx.mediarecorder.app.WorkRecorder">

        <!-- 开始录制按钮 -->
        <Button
                android:id="@+id/startRecord"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="btnStartRecord"
                android:text="开始录制"
                />

        <Button
                android:id="@+id/stopRecord"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="btnStopRecord"
                android:text="停止录制"
                />
        <SurfaceView
                android:id="@+id/surView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
</LinearLayout>

二、Activity 代码

1、首先看下成员变量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // 开始录制,停止录制按钮
    private Button startRecord,stopRecord;
    // 显示预览的SurfaceView
    private SurfaceView surfaceView;
    // 标记,判断当前是否正在录制
    boolean isRunning = false;
    // 录制类
    private MediaRecorder recorder;
    // 存储文件
    private File saveFile;

2、onCreate()方法中进行一些初始化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
     startRecord = (Button) findViewById(R.id.startRecord);
        stopRecord = (Button) findViewById(R.id.stopRecord);
        surfaceView = (SurfaceView) findViewById(R.id.surView);

        // onCreate()初始化 ,一开始肯定没有开始录制,所以停止按钮不可点击
        stopRecord.setEnabled(false);
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
     // 设置Surface不需要维护自己的缓冲区
        surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        // 设置分辨率
        surfaceView.getHolder().setFixedSize(320, 280);
        // 设置该组件不会让屏幕自动关闭
        surfaceView.getHolder().setKeepScreenOn(true);

3、现在看“开始录制”监听事件

----3.1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 创建MediaRecorder对象
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   recorder = new MediaRecorder();
   recorder.reset();

----3.2 设置三步,顺序固定

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//1.设置采集声音
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//设置采集图像
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//2.设置视频,音频的输出格式
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//3.设置音频的编码格式
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
//设置图像的编码格式
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);

----3.3 其他可选设置,更多请查看API

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//设置立体声
recorder.setAudioChannels(2);
//设置最大录像时间 单位:毫秒
recorder.setMaxDuration(600000);
//设置最大录制的大小 单位,字节
recorder.setMaxFileSize(1024*1024);
//音频一秒钟包含多少数据位
recorder.setAudioEncodingBitRate(128);
//设置选择角度,顺时针方向,因为默认是逆向90度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度
recorder.setOrientationHint(90);

----3.4 设置文件存储路径,这里简陋了,实际开发中需要判断是否有外部存储,是否有目标目录 ,是否已经存在相同名字的文件 等问题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//设置输出文件路径

saveFile = new File(Environment.getExternalStorageDirectory()
                        .getCanonicalFile() + "/myvideo.mp4");

----3.5 使用SurfaceView进行预览

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
recorder.setPreviewDisplay(surfaceView.getHolder().getSurface());   

----3.6 开始录制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
recorder.prepare();
//开始录制
recorder.start();
//让开始按钮不可点击,停止按钮可点击
startRecord.setEnabled(false);
stopRecord.setEnabled(true);
isRunning = true;

----3.7 停止录制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 //停止录制
recorder.stop();
//释放资源
recorder.release();
recorder = null;
//设置开始按钮可点击,停止按钮不可点击
startRecord.setEnabled(true);
stopRecord.setEnabled(false);

完整代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  1 package com.xqx.mediarecorder.app;
  2 
  3 import android.app.Activity;
  4 import android.media.MediaRecorder;
  5 import android.os.Bundle;
  6 import android.os.Environment;
  7 import android.view.SurfaceHolder;
  8 import android.view.SurfaceView;
  9 import android.view.View;
 10 import android.widget.Button;
 11 import android.hardware.Camera;
 12 
 13 import java.io.File;
 14 import java.io.IOException;
 15 
 16 public class WorkRecorder extends Activity implements Camera.PreviewCallback {
 17 
 18     // 开始录制,停止录制按钮
 19     private Button startRecord,stopRecord;
 20     // 显示预览的SurfaceView
 21     private SurfaceView surfaceView;
 22     // 标记,判断当前是否正在录制
 23     boolean isRunning = false;
 24     // 录制类
 25     private MediaRecorder recorder;
 26     // 存储文件
 27     private File saveFile;
 28     @Override
 29     protected void onCreate(Bundle savedInstanceState) {
 30         super.onCreate(savedInstanceState);
 31         setContentView(R.layout.activity_work_recorder);
 32 
 33         startRecord = (Button) findViewById(R.id.startRecord);
 34         stopRecord = (Button) findViewById(R.id.stopRecord);
 35         surfaceView = (SurfaceView) findViewById(R.id.surView);
 36 
 37         // onCreate()初始化 ,一开始肯定没有开始录制,所以停止按钮不可点击
 38         stopRecord.setEnabled(false);
 39 
 40         // 设置Surface不需要维护自己的缓冲区
 41         surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 42         // 设置分辨率
 43         surfaceView.getHolder().setFixedSize(320, 280);
 44         // 设置该组件不会让屏幕自动关闭
 45         surfaceView.getHolder().setKeepScreenOn(true);
 46 
 47     }
 48 
 49     /**
 50      * 开始录制
 51      * @param view
 52      */
 53     public void btnStartRecord(View view) {
 54 
 55         // 首先判断当前是否处理视频录制状态,只有不是录制状态的时候,才可以开始录制
 56         if (!isRunning){
 57             try {
 58                 //创建MediaRecorder对象
 59                 recorder = new MediaRecorder();
 60                 recorder.reset();
 61 
 62 
 63                 //1.设置采集声音
 64                 recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
 65                 //设置采集图像
 66                 recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
 67                 //2.设置视频,音频的输出格式
 68                 recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
 69                 //3.设置音频的编码格式
 70                 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
 71                 //设置图像的编码格式
 72                 recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
 73 
 74                 //设置立体声
 75                 recorder.setAudioChannels(2);
 76                 //设置最大录像时间 单位:毫秒
 77                 recorder.setMaxDuration(600000);
 78                 //设置最大录制的大小 单位,字节
 79                 recorder.setMaxFileSize(1024*1024);
 80                 //音频一秒钟包含多少数据位
 81                 recorder.setAudioEncodingBitRate(128);
 82                 //设置选择角度,顺时针方向,因为默认是逆向90度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度
 83                 recorder.setOrientationHint(90);
 84 
 85                 //设置输出文件路径
 86 //                saveFile = FileUtils.getMediaRecoderFolder(this);
 87                 saveFile = new File(Environment.getExternalStorageDirectory()
 88                         .getCanonicalFile() + "/myvideo.mp4");
 89 //        recorder.setVideoSize(320, 240);
 90 //        recorder.setVideoFrameRate(20);
 91                 recorder.setOutputFile(saveFile.getAbsolutePath());
 92                 //使用SurfaceView预览
 93                 recorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
 94                 recorder.prepare();
 95                 //开始录制
 96                 recorder.start();
 97                 //让开始按钮不可点击,停止按钮可点击
 98                 startRecord.setEnabled(false);
 99                 stopRecord.setEnabled(true);
100                 isRunning = true;
101             } catch (IOException e) {
102                 e.printStackTrace();
103             }
104 
105 
106         }
107     }
108 
109     /**
110      * 结束录制
111      * @param view
112      */
113     public void btnStopRecord(View view) {
114         if (isRunning){
115             //停止录制
116             recorder.stop();
117             //释放资源
118             recorder.release();
119             recorder = null;
120             //设置开始按钮可点击,停止按钮不可点击
121             startRecord.setEnabled(true);
122             stopRecord.setEnabled(false);
123         }
124     }
125 
126     @Override
127     public void onPreviewFrame(byte[] data, Camera camera) {
128 
129     }
130 }

本例子只是一个简单的Demo,用于给刚接触MediaRecorder音频录制的coder学习,存在一些Bug和不足,各位coder可以继续拓展

不足:

1、只有当点击“开始录制”的时候SurfaceView组件才可以看到摄像头拍摄的预览,否则是一篇黑,这里可以看下Canera类,进行相应的调整

2、保存路径,需要判断是否有外部存储,存储空间是否足够,路径是否不存在,是否有已有的文件名相同的文件存在等问题,设置文件的名字,我这里是固定路径固定文件名

3、摄像预览效果是有90度旋转的,这里需要大家个人去看下MedioRecoder的API 去进行设置

4、没有设置对焦,像素不清楚,摄像宽高变形

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-10-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Spring Boot+cucumber+契约测试
1.使用start.spring.io创建一个“web”项目。在“依赖项”对话框中搜索并添加“web”依赖项,为了后面的契约文件,再加入“Config Client ”和“Contract Stub Runner依赖项。点击“生成”按钮,下载zip,并将其解压缩到计算机上的文件夹中。
顾翔
2024/09/10
1180
Spring Boot+cucumber+契约测试
微服务架构与springcloud03——项目热部署与消费者订单模块
自动热部署会消耗一定的性能,如果您的电脑配置不佳,可能会有点卡顿。除了自动热部署,也可以通过手动按下面的锤子按钮,只编译修改的文件,会比重启更加快点。
半旧518
2022/10/26
3350
微服务架构与springcloud03——项目热部署与消费者订单模块
Spring Boot+cucumber
1 使用start.spring.io创建一个“web”项目。在“依赖项”对话框中搜索并添加“web”依赖项,如屏幕截图所示。点击“生成”按钮,下载zip,并将其解压缩到计算机上的文件夹中。
顾翔
2024/09/10
1250
Spring Boot+cucumber
第十六节 SCC消费驱动测试-生产端
[https://docs.spring.io/spring-cloud-contract]
用户1418372
2021/06/01
6210
第十七节 SCC消费驱动测试-消费端
[https://docs.spring.io/spring-cloud-contract]
用户1418372
2021/06/01
4810
Docker 部署 SpringCloud 微服务(docker-compose 编排微服务高可用案例)
前面的一篇文章,通过对每个项目建立单独的 Dockerfile,可以实现对单个项目生成 Docker 镜像,然后单独启动容器,可以实现简单连接,达到部署的目的。
子乾建建-Jeff
2020/06/29
9.4K2
Docker 部署 SpringCloud 微服务(docker-compose 编排微服务高可用案例)
SpringCloud 微服务实现方式 原
消费启动服务,注意EnableFeginClients 一定要加basePackages,要不然扫不到单独作为api的jar包里面接口
用户2603479
2018/08/15
4730
一文带你了解服务降级的前世今生
  在分布式的环境下,多个服务之间的调用难免会出现异常、超时等问题,这些问题出现的时候,为了提高用户的体验,我们不能够直接将错误的信息展示给用户,而是在出现这种情况的时候,给用户返回一个友好的提示。服务降级的作用就在这里体现了。
IT学习日记
2022/09/13
5670
一文带你了解服务降级的前世今生
微服务(五)——服务注册与发现:Zookeeper&Consul
6.启动8004注册进zookeeper(要先启动zookeeper的server)
不愿意做鱼的小鲸鱼
2022/09/26
3670
微服务(五)——服务注册与发现:Zookeeper&Consul
微服务(十二)——Steam消息驱动&Sleuth链路监控
有没有一种新的技术诞生,让我们不再关注具体MQ的细节,我们只需要用一种适配绑定的方式,自动的给我们在各种MQ内切换。(类似于Hibernate)
不愿意做鱼的小鲸鱼
2022/09/26
4320
微服务(十二)——Steam消息驱动&Sleuth链路监控
Spring Cloud构建微服务架构:服务消费者
通过上一篇《Spring Cloud构建微服务架构:服务注册与发现》,我们已经成功地将服务提供者:compute-service服务注册到Eureka服务注册中心或Consul服务端上了,那么我们要如何去消费服务提供者的接口呢? Spring Cloud Ribbon Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。它是一个基于HTTP和TCP的客户端负载均衡器。它可以通过在客户端中配置ribbonServerList来设置服务端列表去轮询访问以达到均
程序猿DD
2018/02/01
8330
Zipkin和微服务链路跟踪
本期分享的内容是有关zipkin和分布式跟踪的内容。 首先,我们还是通过spring initializr来新建三个项目。一个zipkin service。另外两个是普通的业务应用,分别叫servic
ImportSource
2018/04/03
7.9K1
Zipkin和微服务链路跟踪
微服务架构与springcloud04——Eureka服务注册与发现
如果你有自己的私人医生,那么你需要时直接与医生进行联系就可以。但大多数人都需要去医院,医院有很多病人,也有很多医生,那么就需要一个窗口来挂号、取号、管理余号等等。同样的道理,当我们的服务数量变得多起来,就需要进行服务注册与发现的管理了。
半旧518
2022/10/26
2250
微服务架构与springcloud04——Eureka服务注册与发现
Docker 部署 SpringCloud 微服务的服务提供者和消费者(初级版)
Spring Cloud 微服务和 Docker 容器化技术,随便拿出来一个,都够你玩半天喝二两的。那么当它俩交叉在一起时,确实让新手烧脑。
子乾建建-Jeff
2020/06/29
1.4K0
Docker 部署 SpringCloud 微服务的服务提供者和消费者(初级版)
微服务注册中心:Consul——服务注册
微服务注册中心:Consul——概念与基础操作介绍了consul的安装和基本操作,本篇开始在consul上进行服务注册与发现,语言使用Java,框架使用Spring Boot整合Consul。
程序员架构进阶
2021/05/27
2.5K0
微服务注册中心:Consul——服务注册
微服务注册中心:Consul——服务发现
说完了Consul的服务注册,那么就该到服务发现了。大家有过rpc框架使用经验的,例如nacos、eureka、dubbo等,就会了解服务中的角色,也就是生产者和消费者,也可以理解为服务的提供方和服务使用方。服务注册,是服务提供方把自己的信息(ip、端口、方法、参数&返回值信息)注册到一个中心;服务发现就是服务使用方,从中心获取到可用的服务提供方信息,并像本地方法调用一样调用其方法(远程方法),这也就是RPC(远程方法调用)的过程。
程序员架构进阶
2021/05/29
2K0
SpringCloud微服务框架搭建
一、微服务架构 1.1什么是分布式 不同模块部署在不同服务器上 作用:分布式解决网站高并发带来问题 1.2什么是集群 多台服务器部署相同应用构成一个集群 作用:通过负载均衡设备共同对外提供服务 1.3什么是RPC RPC 的全称是 Remote Procedure Call 是一种进程间通信方式。 它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即无论是调用本地接口/服务的还是远程的接口/服务,本质上编写的调用代码基本相同。 比如两台服务器
编程软文
2018/06/20
1.6K0
微服务综合案例-03-其他服务的创建
  上篇文章我们详细的介绍了product服务的创建,因为其他几个服务的创建过程是相似的,所以其他几个服务我们就快速创建了。
用户4919348
2019/06/17
4930
一文带你搞懂微服务的协调者SpringCloud
从零开始构建一套完整的分布式系统是困难的。在1.2节中,我们讨论了众多的分布式系统的架构,可以说每种架构都有其优势及局限,采用何种架构风格要看应用程序当前的使用场景。就微服务架构的风格而言,一套完整的微服务架构系统往往需要考虑以下挑战。
愿天堂没有BUG
2022/10/28
5100
一文带你搞懂微服务的协调者SpringCloud
微服务(八)——Hystrix服务降级、熔断、限流(上)
复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。
不愿意做鱼的小鲸鱼
2022/09/26
5820
微服务(八)——Hystrix服务降级、熔断、限流(上)
推荐阅读
相关推荐
Spring Boot+cucumber+契约测试
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档