【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

相关文章

使用Java实现通用树形结构构建工具类

《使用Java实现通用树形结构构建工具类》这篇文章主要为大家详细介绍了如何使用Java实现通用树形结构构建工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录完整代码一、设计思想与核心功能二、核心实现原理1. 数据结构准备阶段2. 循环依赖检测算法3. 树形结构构建4. 搜索子

GORM中Model和Table的区别及使用

《GORM中Model和Table的区别及使用》Model和Table是两种与数据库表交互的核心方法,但它们的用途和行为存在著差异,本文主要介绍了GORM中Model和Table的区别及使用,具有一... 目录1. Model 的作用与特点1.1 核心用途1.2 行为特点1.3 示例China编程代码2. Tab

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

使用Python实现获取网页指定内容

《使用Python实现获取网页指定内容》在当今互联网时代,网页数据抓取是一项非常重要的技能,本文将带你从零开始学习如何使用Python获取网页中的指定内容,希望对大家有所帮助... 目录引言1. 网页抓取的基本概念2. python中的网页抓取库3. 安装必要的库4. 发送HTTP请求并获取网页内容5. 解

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

使用Python实现网络设备配置备份与恢复

《使用Python实现网络设备配置备份与恢复》网络设备配置备份与恢复在网络安全管理中起着至关重要的作用,本文为大家介绍了如何通过Python实现网络设备配置备份与恢复,需要的可以参考下... 目录一、网络设备配置备份与恢复的概念与重要性二、网络设备配置备份与恢复的分类三、python网络设备配置备份与恢复实

C#中的 StreamReader/StreamWriter 使用示例详解

《C#中的StreamReader/StreamWriter使用示例详解》在C#开发中,StreamReader和StreamWriter是处理文本文件的核心类,属于System.IO命名空间,本... 目录前言一、什么是 StreamReader 和 StreamWriter?1. 定义2. 特点3. 用

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详

Python使用DrissionPage中ChromiumPage进行自动化网页操作

《Python使用DrissionPage中ChromiumPage进行自动化网页操作》DrissionPage作为一款轻量级且功能强大的浏览器自动化库,为开发者提供了丰富的功能支持,本文将使用Dri... 目录前言一、ChromiumPage基础操作1.初始化Drission 和 ChromiumPage

Django序列化中SerializerMethodField的使用详解

《Django序列化中SerializerMethodField的使用详解》:本文主要介绍Django序列化中SerializerMethodField的使用,具有很好的参考价值,希望对大家有所帮... 目录SerializerMethodField的基本概念使用SerializerMethodField的