【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

相关文章

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

使用Python的requests库调用API接口的详细步骤

《使用Python的requests库调用API接口的详细步骤》使用Python的requests库调用API接口是开发中最常用的方式之一,它简化了HTTP请求的处理流程,以下是详细步骤和实战示例,涵... 目录一、准备工作:安装 requests 库二、基本调用流程(以 RESTful API 为例)1.

使用Python开发一个Ditto剪贴板数据导出工具

《使用Python开发一个Ditto剪贴板数据导出工具》在日常工作中,我们经常需要处理大量的剪贴板数据,下面将介绍如何使用Python的wxPython库开发一个图形化工具,实现从Ditto数据库中读... 目录前言运行结果项目需求分析技术选型核心功能实现1. Ditto数据库结构分析2. 数据库自动定位3

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3