【Android-R1】MediaRecorder和MediaPlayer的基本使用

2023-11-28 09:50

本文主要是介绍【Android-R1】MediaRecorder和MediaPlayer的基本使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        最近看到网上曾经火热的倒放挑战感觉挺有意思,于是打算研发一款线下游戏APP,让广大群众可以体验一把感受一下。现在处于起步研究阶段,目前总算找对了方向,先把之前做的一些研究和笔记整理一下,今天先把MediaRecorder和MediaPlayer的基本使用写了。如果没有意外的话,我会把这个项目做成一个系列,代号R1(random one缩写,意思是这个项目是第一个随机的安卓项目),我会把这个项目中研究过的我认为有价值的东西整理成笔记发表在这里,欢迎各位小伙伴来一起探讨和学习,下面废话不多说,直接进入正题。

 MediaRecorder

        用一个东西必然要先了解它,所以我们先进android developer的MediaRecorder指南浏览一番,这个指南就是介绍一下基本的使用,如果要更详细的可以看MediaRecorder参考文档,我把我使用过程中需要注意的点再啰嗦一下。

        MediaRecorder这个玩意是有状态变化的,如果你的MediaRecorder还没进入准备状态就直接调用record方法,那么程序会直接报错;所以参考文档给了以下的状态变化图

         由此可知,对于录音这个过程的正确调用顺序是:

        new -->setAudioSource-->setOutputFormat-->setAudioEncoder-->setOutputFile-->

prepare-->start-->stop-->setAudioSource或release

        在new的时候,我发现我使用的sdk版本(API 31)会提示旧的构造函数已经deprecated,但是用新的构造函数反而会报错,所以那个提示可以先无视掉。

        大家看完这个图有没有什么想法,我有个想法是,如果我第一次录完音stop后,recorder回到初始状态,如果我想再次录音,又要再写一遍设置参数的代码,所以这里可以做个小扩展,从setAudioSource到prepare之前都封装掉,所以我们可以动手写个Recorder的子类。

import android.media.MediaRecorder;public class MyRecorder extends MediaRecorder{private final int DEFAULT_AUDIO_SOURCE = MediaRecorder.AudioSource.MIC;private final int DEFAULT_OUTPUT_FORMAT = MediaRecorder.OutputFormat.DEFAULT;private final int DEFAULT_AUDIO_ENCODER = MediaRecorder.AudioEncoder.DEFAULT;public MyRecorder(){}public void setDefaultParam(){setAudioSource(DEFAULT_AUDIO_SOURCE);setOutputFormat(DEFAULT_OUTPUT_FORMAT);setAudioEncoder(DEFAULT_AUDIO_ENCODER);}public void setParam(int audioSource,int outputFormat,int audioEncoder){setAudioSource(audioSource);setOutputFormat(outputFormat);setAudioEncoder(audioEncoder);}
}

        由于MediaRecorder的start和stop方法系统会自动将其放在后台运行,所以不用特意写个线程来避开UI线程的阻塞。这里做的扩展仅仅是为了调用时少写点代码。

        调用步骤如下所示:

mRecorder = new MyRecorder();
mRecorder.setParam(MediaRecorder.AudioSource.MIC,
MediaRecorder.OutputFormat.AMR_WB,
MediaRecorder.AudioEncoder.AMR_WB);
mRecorder.setOutputFile(getExternalFilesDir("").getAbsolutePath()
+ File.separator + getFileName());
try {mRecorder.prepare();
}catch (Exception e){e.printStackTrace();
}
mRecorder.start();

        其实我比较困惑的是编码器和格式各个值的意义,AudioEncoder的枚举值如下(方便排版,我将逗号换成tab):

AAC        AAC_ELD        AMR_NB        AMR_WB        DEFAULT        HE_AAC        OPUS       VORBIS

       OutputFormat的枚举值如下:


AAC_ADTS        AMR_NB        AMR_WB        DEFAULT        MPEG_2_TS        MPEG_4

OGG                RAW_AMR        THREE_GPP        WEBM

        先讲下DEFAULT值,这个值是由你的机器决定选取其他格式中的任意一种。我查了百度,似乎没有对这些值的详细讲解,也没有哪篇文章把每个算法对应输出的文件格式对号入座,那么这个艰巨的任务就交给我了!接下来我将列出每个OutputFormat对应的文件格式(后缀名)。

AAC_ADTS

        AAC音频格式Advanced Audio Coding(高级音频解码),是一种由MPEG-4标准定义的有损音频压缩格式。

        ADTS:ADTS的全称是Audio Data Transport Stream。是AAC音频的传输流格式。AAC音频格式在MPEG-2(ISO-13318-7 2003)中有定义。AAC后来又被采用到MPEG-4标准中。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。

        还有一种传输格式是ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。

        其实不用具体了解那么多格式,我们需要知道的是,以AAC开头的就是AAC压缩格式,其对应的输出文件格式为.aac;

AMR

        AMR(全称是Adaptibve Multi-Rate)是一种音频格式。主要用于移动设备的音频,压缩比比较大,但相对其他的压缩格式质量比较差,语音带宽范围:300-3400Hz,由于多用于人声,通话,效果还是很不错的。AMR-NB就是指AMR。

        “AMR-WB”全称为“Adaptive Multi-rate - Wideband”,即“自适应多速率宽带编码”,采样频率为16kHz,是一种同时被国际标准化组织ITU-T和3GPP采用的宽带语音编码标准,也称 为G722.2标准。AMR-WB提供语音带宽范围达到50~7000Hz,用户可主观感受到话音比以前更加自然、舒适和易于分辨。

        其对应格式:.amr

MPEG

        MPEG是一种专门针对运动图像和语音压缩的编码标准。上面列举的MPEG_2_TS和MPEG_4是不同的版本,支持MPEG的文件格式有很多,比如mp4,avi等。

OGG

        Ogg全称是OGGVobis(oggVorbis)是一种音频压缩格式,类似于MP3等的音乐格式。Ogg是完全免费、开放和没有专利限制的。OggVorbis文件的扩展名是".ogg"。这种文件的设计格式是非常先进的。现在创建的OGG文件可以在未来的任何播放器上播放,因此,这种文件格式可以不断地进行大小和音质的改良,而不影响旧有的编码器或播放器。

THREE_GPP

        3GPP是由一组电信合作伙伴建立的、成立于1998年12月的标准化组织或机构,其成员包括欧洲ETSI、日本ARIB和TTC、中国CCSA、韩国TTA和北美ATIS。其目标是在ITU的IMT-2000计划范围内制订和实现全球性的第三代移动通信电话系统技术规范和宽带标准,致力于GSM到UMTS(WCDMA)的演进。

        3GP是一种常见视频格式,是MPEG-4 Part 14(MP4)格式的一种简化版本,常用于手机。其对应文件格式:.3gp

WEBM

        WebM 格式,其实是以 Matroska(就是我们熟知的 MKV)容器格式为基础开发的新容器格式,里面包括了 VP8 视频和 Ogg Vorbis 音轨。Ogg Vorbis 本来就是开放格式, VP8 则是 Google 当年买下 On2 公司时取得的 视频编码器,这次 Google 也把这个编码器以类似 BSD 授权开放,因此 WebM 应该是不会有 H.264 的那些潜在的专利问题。

        对应文件格式:.webm

Opus

        Opus是一个有损声音编码的格式,由Xiph.Org基金会开发,之后由IETF(互联网工程任务组)进行标准化,目标是希望用单一格式包含声音和语音,取代Speex和Vorbis,且适用于网络上低延迟的即时声音传输,标准格式定义于RFC 6716文件。Opus格式是一个开放格式,使用上没有任何专利或限制。

        以上各种格式介绍借鉴自百度百科和一些大神的博客,如果有错误请多包涵~基本上,你设置的编码器编码算法和你的输出格式大类是一样的就OK了,比如AudioEncoder我设置AAC,OutputFormat设置AAC_ADTS,然后输出文件名的后缀设为.aac。

        

MediaPlayer

        参考文档里是这么介绍的:

        MediaPlayer class can be used to control playback of audio/video files and streams.

        MediaPlayer is not thread-safe. Creation of and all access to player instances should be on the same thread. If registering callbacks, the thread must have a Looper.

        翻译成人话就是,MediaPlayer是用来控制播放音频/视频的,其输入可以是文件或流的形式。但MediaPlayer不是线程安全的,MediaPlayer对象的创建以及对其域或方法的访问应当都在同一线程中,如果注册了回调函数,那么线程应该有个looper(这looper是啥我暂时不清楚,高手可以评论解答下)。

        与MediaRecorder相同,MediaPlayer也有一个状态图:

         我看到这个图片下还有好大一段文字,这些文字内容先放着哪天我有空了再完整整理出来,这次我就抓重点讲。从这张图可以分析出最基本的使用流程:

new-->setDataSource-->prepare-->start-->stop/pause-->release

        MediaPlayer相对MediaRecorder没有那么多需要设置的参数了,所以我们应当将关注的重点放在什么状态下才能调什么API上,以及怎么写代码更加规范,基本上对照着这张图调API不会有什么大问题,很多东西参考文档也已经给出详细解释了,所以MediaPlayer没啥好讲的。

        那么本期就简单讲了下MediaRecorder和MediaPlayer,这两个玩意其实已经封装得很好用了,底层的AudioRecord和AudioTrack才是真的调用起来麻烦的一批,好那么我们下期再见!

这篇关于【Android-R1】MediaRecorder和MediaPlayer的基本使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/429490

相关文章

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

prometheus如何使用pushgateway监控网路丢包

《prometheus如何使用pushgateway监控网路丢包》:本文主要介绍prometheus如何使用pushgateway监控网路丢包问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录监控网路丢包脚本数据图表总结监控网路丢包脚本[root@gtcq-gt-monitor-prome

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期