在开发上,习惯性的将音频、短视频功能模块的应用称作多媒体,事实上假如讲的广泛一些得话,照相机的应用,例如照相,录视频等,还可以区划到多媒体的范围里边。
从这节课逐渐,大家就一起来看看Android中多媒体的API应用和实际的作用。
这篇内容大家先从音频开发聊到。
零、音频开发情景、內容和基本要素
在说音频开发以前,我们可以先想一想自身揣摩一下,什么应用场景会使用音频开发。关键的应用场景大概包含:
- 音频视频播放器
- 收录机
- 语音
- 音视频监管运用
- 音视频直播应用
- 音频编写/图像处理软件
- 无线蓝牙耳机/音响
- … …
假如我们要成体系的学习培训多媒体和音视频的开发,大概会出现牵涉到哪几个方面的专业知识呢,梳理看来关键有一下这几个领域的內容:
- 音频收集/播放视频:已经有音频怎样播放视频;怎样收集一段音频;
- 音频优化算法解决:主要包含去噪、静音模式检验、消噪、声效解决、功放机/提高、混响/分离出来,这些
- 音频的pcm编码和格式转化:不一样文件格式中间的转换格式实际操作
- 音频传输协议的开发:主要包含SIP,A2DP、AVRCP,这些
此外,假如要开展音频开发,必须认识一些音频的定义做为外置专业知识,一些常用的定义如下所示所显示:
- SampleRate:采样频率,每秒钟收集响声的总数,它用HZ(Hz)来表明。采样率越高,音频品质越好。常见的音频采样率有:8kHz、16kHz、44.1kHz、48kHz 等。
- Channel:声道数,表示声音拍摄时的音频总数或回看时相对的音箱总数。常见的是单声道(Mono)和双声道(Stereo)。要记牢这两个词:Stereo和Mono。
- BitDepth:取样精密度,每一个取样加用是多少信息量表明,它以位(Bit)为企业。十位数越多,表明得就越细致,响声品质肯定就就越好,自然信息量也越大。普遍的位宽是:8bit 或是 16bit。
- BitRate:视频码率,每秒钟音频占有的比特犬总数,企业是 bps(Bit Per Second),视频码率越高,发动机压缩比越小,响声品质越好,音频容积也越大。
一、音频播放视频
说到音视频多媒体,最先就有一个定义叫:媒体格式。也就是人们常说的不一样形式的音视频文档。在Android这一开放系统服务平台中,适用的媒体格式或是很充足的,详尽信息如下所示:
音频文件格式和转码软件
汇总而言,Android中多见的音频压缩格式有:MP3,AAC,OGG,WMA,Opus,FLAC,APE,m4a,AMR,这些。
1.1 音频的播放视频
1.1.1 MediaPlayer
最先了解2个基本的定义和API:
- MediaPlayer:用以播放视频响声视频的关键 API。Android 多媒体架构适用播放视频各种各样普遍新闻媒体种类,可以简单地将音频、短视频和照片集成化到运用中。可以应用 MediaPlayer API,播放视频储存在运用資源(初始資源)内的文件类型、系统文件中的单独文档或是根据数据连接得到的数据流分析中的音频或短视频。
- AudioManager:此类API用以管理方法机器设备上的音频源和音频輸出。
此外必须说一下,MediaPlayerl除开可以获得、编解码及其播放视频音频视频,并且只需非常简单的设定就可以之外。它还适用各种不同的新闻媒体源,例如:
- 当地資源:即res文件目录下的音频資源。
- URI:例如可能是根据Content Provider分析到的某一資源URI
- 互联网:根据互联网,获得流式传输数据信息开展播放视频。
应用流程
- 1、复位MediaPlayer目标
- 2、提前准备播放视频工作中:准备工作主要是音频数据库的获得或是是音频数据信息的编解码实际操作等,该全过程归属于用时实际操作,因而必须在工作中进程中开展。
- 3、音频情况管理方法:在准备工作之后,可以对音频开展播放视频、中止等实际操作。与此同时必须留意的是MediaPlayer是有情况的,包含:Idle、Initialized、Prepared、Started、Paused、PlaybackCompleted等情况。当在开始情况的转换时,必须特别注意这几个点:
- ① Started(逐渐)/Paused(中止)到Stopped(终止)是单边变换,没法再从Stopped立即变换到Started,必须历经Prepared再次运载才可以再次播放视频。
- ② Initialized(复位)情况必须运载数据信息才可以开展start()播放视频,可是假如应用prepareAsync()方式多线程提前准备,必须等候提前准备进行再开播,这儿必须运用一个调整方式:setOnPreparedListener(),它会在多线程运载进行后启用。
- ③ End(完毕)情况是分散在别的情况以外的,在一切情况皆可转换,一般在不用再次应用MediaPlayer的情况下,才会应用release()回收利用資源。
- ④ Error(不正确)情况是分散在别的情况以外的,仅有在MediaPlayer产生失误的过程中才会变换。为了更好地维持运用的客户体验,通常会监视setOnErrorListener()调整方式,它会在MediaPlayer产生失误的情况下被调整。
常见问题
- 1、应用Service播放视频音频。在应用MediaPlayer播放视频音频流时,强烈推荐应用一个Service来承重MediaPlayer,而不是立即在Activity里应用。
- 2、使用唤起锁。Android系統的功率设计方案里,为了更好地节约电池耗费,假如机器设备处在休眠状态,系统软件将尝试减少或是关掉一些没机器设备务必的特点,包含CPU和Wifi硬件配置。如果是一个后台播放歌曲的运用,减少CPU很有可能造成在程序运行的情况下影响音频的正常的播放视频,关掉Wifi将有可能造成互联网音频流的获得发生不正确。因而为了确保作用的常规应用,大家需要阻拦系统软件关掉服务项目。可以应用wake locks(唤起锁),它会告知系统软件你已经应用一些作用,那样就可以一直维持该作用处在唤起情况,即使屏保无实际操作也可以再次应用。这一锁会在paused和stoped情况下释放出来。
1.1.2 SoundPool
假如应用软件常常播放视频聚集、紧促而又短暂性的声效(如手机游戏声效)那麼应用MediaPlayer看起来有一些不太合适了。由于MediaPlayer存有如下所示缺陷:
- 1、延迟時间较长,且資源占用量高。
- 2、不兼容好几个音频与此同时播放视频。
Android中除开MediaPlayer播放视频音频以外还带来了SoundPool来播放视频声效,SoundPool应用声效池的基本概念来管理方法好几个短暂的声效,例如它可以逐渐就载入20个声效,之后在系统中按声效的ID开展播放视频。SoundPool的优点和应用湘江如下所示:
- 1、主要运用于播放视频一些较短的响声精彩片段。
- 2、SoundPool对CPU資源占使用量低和反映延迟时间小。
- 3、SoundPool还适用自主设定响声的质量、声音、 播放视频比例等主要参数。
SoundPool的API表明如下所示:
- 1、SoundPool(int maxStreams, int streamType, int srcQuality):特定它一共适用多少个响声(也就是池的尺寸)、响声的质量。该方式归属于5.0下列版本号应用。
- 2、SoundPool.Builder:从5.0版本号逐渐采用的是SoundPool.Builder方式。
- 3、load(Context context, int resld, int priority):从 resld 所相应的网络资源载入响声。
- 4、load(FileDescriptor fd, long offset, long length, int priority):载入 fd 所相应的资料的offset逐渐、长短为length的响声。
- 5、load(AssetFileDescriptor afd, int priority):从afd 所相应的文档中载入响声。
- 6、load(String path, int priority):从path 相匹配的文档去载入响声。
- 表明:4个load方式里都有一个priority主要参数,该参数现阶段还没一切功效,Android提议将该 主要参数设成1,维持和明天的兼容模式。
- play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate):特定播放视频哪个响声,2和3主要参数的意思是声音,priority特定播放视频的优先,标值越大优先越高;loop用以特定是不是循环系统,0不循环,-1位循环系统;rate特定播放视频的比例,可选择数值0.5 – 2 ,1为正常的比例。
1.1.3 AudioTrack
AudioTrack归属于更偏最底层的音频播放视频,在Android的framework层有MediaPlayerService,其内部结构便是应用了AudioTrack。AudioTrack用以单独音频播放视频和管理方法,对比于MediaPlayer具备:精练、高效率的优势。因而,针对AutioTrack可以汇总如下所示:
- 应用情景:更合适即时造成播放视频数据信息的状况,如数据加密的音频,MediaPlayer是无计可施的,AudioTrack可以解决。
- 规定:AudioTrack用以播放视频PCM(PCM无缩小的音频文件格式)歌曲流的回看,假如开播应放其他文件格式音频,必须对应的视频解码器,这也是AudioTrack用的相对比较少的缘故,原因取决于必须程序流程开发者自身编解码音频。
- 播放视频方式:
- ① AudioTrack播放音频有二种播放视频方式,一种是静态数据方式,即载入的数据和資源可以同时所有载入结束,载入方法简易,高效率也非常高。可是假如数据量非常大,通常不适宜;
- ② 流方式和互联网上播放短视频是相似的,即数据是依照一定规律性不断传送给传输方的。音频文件过大 音频特性规定高,例如采样频率高、深层大的数据;此外假如音频数据是即时造成的,这样的事情就只有用流方式。
应用AudioTrack公有制三个流程:
一共有三个流程:
- 搭建AudioTrack目标,而且把PCM的主要参数传入目标里边
- 启用start
- 调用write。
此外,实际上AudioTrack之外,还有一个Audio系统软件,在该体系中具体包括三个关键的API,分别是:
- AudioManager:主要是用于管理方法Audio系统软件的。
- AudioTrack:主要是用于播放响声。
- AudioRecord:主要是用于音频。
1.1.4 RingtoneManager
Ringtone为手机铃声、通告和其它相近响声给予迅速播放的方法,这种方法播放音频时,还会继续牵涉到一个主要的管理类专业”RingtoneManager”,此类做为管理类专业给予系统软件手机铃声目录查找方法,而且RingtoneManager可以转化成Ringtone案例。实际的Ringtone的应用流程和相应的方法如下所示所显示:
- 1、获得Ringtone目标案例:
//1.根据手机铃声uri获得
static Ringtone getRingtone(Context context, Uri ringtoneUri)
//2.根据手机铃声查找部位获得
Ringtone getRingtone(int position)
- 2、RingtoneManager中至关重要的方法:
1. // 2个结构方法
(Activity activity)
RingtoneManager(Context context)
2. // 获得特定响声种类(手机铃声、通告、闹钟铃声等)的默认设置响声的Uri
static Uri getDefaultUri(int type)
3. // 获得系统软件全部Ringtone的cursor
Cursor getCursor()
4. // 获得cursor特定部位的Ringtone uri
Uri getRingtoneUri(int position)
5. // 分辨特定Uri是不是为默认设置手机铃声
static boolean isDefault(Uri ringtoneUri)
6. //获得特定uri的隶属种类
static int getDefaultType(Uri defaultRingtoneUri)
7. //将特定Uri设定为特定响声种类的默认设置响声
static void setActualDefaultRingtoneUri(Context context, int type, Uri ringtoneUri)
8、//播放
void play()
9、//终止播放
void stop()
1.1.5 音频及声效的播放汇总
通过如上几类声效的播放方法的解读,我们可以对声效的播放做简易的归纳如下所示所显示:
- 1.针对延迟时间度规定不高,而且期待可以更全方位的操纵歌曲的播放,MediaPlayer比较合适。
- 2.响声简短,延迟时间度小,而且必须几类响声与此同时播放的情景,合适应用SoundPool。
- 3.播放大文件歌曲,如WAV高质量音频和PCM无缩小音频,可采用更低层的播放方法AudioTrack。它适用流式的播放,可以载入(可来源于当地和互联网)音频流,却播放延迟时间较小。
- 4、AudioTrack立即适用WAV和PCM,别的音频必须编解码成PCM文件格式才可以播放。 .jet的音频较为罕见(有的游戏里面在应用),可使用专业的播放器JetPlayer播放。
- 5.针对系统软件类响声的播放和实际操作,Ringtone更合适。
二、音频的收集
手机上一般都是有话筒和监控摄像头,而Android系统软件就可以运用这种硬件配置来拍摄音视频了。为了更好地提升对拍摄音视频的适用,Android系统软件保证了一个MediaRecorder的类。
与MediaPlayer类十分类似MediaRecorder也是有它自身的状态图,MediaRecorder的每个状态详细介绍如下所示:
- Initial:复位状态。应用new()方法建立MediaRecorder目标或是启用了reset()方法时,该MediaRecorder目标处在Initial状态。
- Initialized:已复位状态,在Initial状态启用setAudioSource()或setVideoSource()方法进到该状态。在这个状态可以根据setOutputFormat()方法设定輸出文件格式,这时MediaRecorder变换为DataSourceConfigured状态。此外,根据reset()再次进到Initial状态。
- DataSourceConfigured:数据源配备状态,这期内可以设置编码方法、輸出文档、屏幕旋转、浏览表明这些。可以在Initialized状态根据setOutputFormat()方法进到该状态。可以根据prepare()方法抵达Prepared状态。
- Prepared:准备就绪状态,在DataSourceConfigured状态根据prepare()方法进到该状态。可以根据start()进到拍摄状态。此外,可以根据reset()方法返回Initialized状态。
- Recording:拍摄状态,根据启用start()方法进到该状态。此外,它可以根据stop()方法或reset()方法返回Initial状态。
- Released:释放出来状态,可以利用在Initial状态启用release()方法来进到这一状态,这时可能释放出来全部和MediaRecorder目标关联的資源。
- Error:不正确状态,当问题产生的情况下进到这一状态,它可以根据reset()方法进到Initial状态。
必须表明的是,与MediaPlayer类似,应用MediaRecorder同步录音录像时必须严格执行状态调用函数的顺序,在不一样的状态启用不一样的函数公式,不然会发现异常。以上的文字说明可以转变为如下所示状态图:
三、Android中多音视频编解码
音视频的初始数据十分巨大,无法储存和传送。要处理音视频数据的存放和传送问题,必须做以下解决:
- 音视频编号:即对数据开展缩小,音视频数据压缩技术性便是音视频编号。编码的目标便是在最少图象或音频信息内容遗失状况下获得最高的缩小。
- 音视频编解码:解码是相对性编号的,其目标是最大限度的复原初始图象或响声信息内容。
- 编解码的功效:编解码的含义便是有利于数据传送和储存。
而我们知道音视频编解码文件格式十分多(h264、h265、vp8、vp9、aac、opus……),完成每一种编解码都必须引进外界库,造成新项目松垮、包容积过大且运作特性差。
因而Google明确提出了一套规范,这就是MediaCodec。从总体上,掌握MediaCodec可以从下列一些层面而言:
- 界定:MediaCodec是Google公司专业为Android开发人员和处理芯片生产商构建的一套用以启用硬件配置转码软件部件的统一插口,所有遵循该接口规范就可以简易的应用,关键的目标取决于统一标准。
- 特性:与基本编解码库对比,MediaCodec具备十分明显的优点,它速度更快、高效率、CPU占用量低、运行内存小、节约包容积。应用MediaCodec可以处理新项目松垮、减少包容积和提高编解码特性。
有关MediaCodec的原理,可以参照下面的图所显示:
工作中流程如下所示所显示:
- MediaCodec解决键入数据后产生輸出数据。根据多线程方法解决数据,并应用一组键入和输入输出缓冲区域。
- 键入端:要求一个空的键入缓冲区域,用数据添充它并将其发送至转码软件开展解决。
- 輸出端:转码软件解决完数据并将其转化到一个空的輸出缓冲区域。最终,要求一个已铺满的輸出缓冲区域,应用它的主要内容并将其释放出来回转码软件。
可以操控的数据种类
MediaCodec可以对三种数据开展实际操作,分别是:
- 编号数据
- 初始音频数据
- 原始短视频数据
MediaCodec的状态管理方法
MediaCodec存有三种状态:终止(stoped)、实行(executing)、释放出来(released)。
- 终止状态:包括三个子状态:配备(configured)、未复位(uninitialized)、不正确(error)
- 实行状态:包括三个子状态:更新(flushed)、运作(running)、完毕流(end-of-stream)
MediaCodec 发展趋势
Android系统软件中有关MediaCodec的详细介绍,可以参照Android的官网给予的信息内容:https://developer.android.google.cn/reference/kotlin/android/media/MediaCodec
MediaCodec 是在 Android 4.1版本号(API16 )中产生并可以用的,它保证了一种极为初始的插口。MediaCodec类与此同时存有 Java和C 层中,可是仅有前面一种是公共性浏览方式。
在Android 4.3 (API18)中,MediaCodec被拓展为根据 Surface 给予键入的方式(根据 createInputSurface方式),容许来自于照相机的浏览或是是通过OpenGL ES展现。在该版本中,MediaCodec是第一个过去了CTS检测的版本。所说的CTS,全名是Compatibility Test Suite,主要是google推出的一种机器设备可用性测试标准,用于确保不一样机器设备一致的用户体验设计的标准。
此外,4.3版本还引入了 MediaMuxer。MediaMuxer容许将AVC转码软件(初始H.264基本上流)的輸出转变为.MP4文件格式,可以和音频流一起转换格式还可以独立变换。
音视频编写
MediaCodec通常与MediaExtractor、MediaSync、MediaMuxer、MediaCrypto、MediaDrm、Image、Surface和AudioTrack一起应用,几乎可以完成绝大多数音视频有关作用。关键的操作流程如下所示所示:
- 1、复位。
- 2、MediaExtractor:获取音视频编码数据信息,MediaExtractor用以对音视频文档解封装形式,获取出已编码的网络媒体数据信息。
- 3、MediaCodec:应用视频解码器开展编解码。
- 4、解决:对音视频开展解决。
- 5、编码:应用MediaCodec编码器对音视频数据信息编码。
- 6、生成:MediaMuxer合成音视频文档。MediaMuxer用以封装形式编码后的音视频数据信息,现阶段适用MP4、Webm和3GP文档做为輸出。
- 7、 释放出来資源。
编码中的反映如下所示:
- createEncoderByType/createDecoderByType
- configure
- start
- while(true) {
- dequeueInputBuffer
- queueInputBuffer
- dequeueOutputBuffer
- releaseOutputBuffer
}
- stop
- release
应用MediaCodec编码音频
- 复位MediaCodec目标,如下所示所示:
private static MediaCodec createAudioEncoder() throws IOException {
MediaCodec codec = MediaCodec.createEncoderByType(AUDIO_MIME);
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, AUDIO_MIME);
format.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
return codec;
}
- 载入PCM数据信息,实行编码实际操作。
...
while (!sawOutputEOS) {
if (!sawInputEOS) {
inputBufIndex = audioEncoder.dequeueInputBuffer(10_000);
if (inputBufIndex >= 0) {
ByteBuffer inputBuffer = audioInputBuffers[inputBufIndex];
//先清除缓冲区域
inputBuffer.clear();
int bufferSize = inputBuffer.remaining();
if (bufferSize != rawInputBytes.length) {
rawInputBytes = new byte[bufferSize];
}
//载入
readRawAudioCount = fisRawAudio.read(rawInputBytes);
//分辨是不是到文档的结尾
if (readRawAudioCount == -1) {
readRawAudioEOS = true;
}
if (readRawAudioEOS) {
audioEncoder.queueInputBuffer(inputBufIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
sawInputEOS = true;
} else {
//放进缓冲区域
inputBuffer.put(rawInputBytes, 0, readRawAudioCount);
rawAudioSize = readRawAudioCount;
//放进编码序列
audioEncoder.queueInputBuffer(inputBufIndex, 0, readRawAudioCount, audioTimeUs, 0);
audioTimeUs = (long) (1_000_000 * ((float) rawAudioSize / AUDIO_BYTES_PER_SAMPLE));
}
}
}
//輸出端
outputBufIndex = audioEncoder.dequeueOutputBuffer(outBufferInfo, 10_000);
if (outputBufIndex >= 0) {
// Simply ignore codec config buffers.
if ((outBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
Log.i(TAG, \"audio encoder: codec config buffer\");
audioEncoder.releaseOutputBuffer(outputBufIndex, false);
continue;
}
if (outBufferInfo.size != 0) {
ByteBuffer outBuffer = audioOutputBuffers[outputBufIndex];
outBuffer.position(outBufferInfo.offset);
outBuffer.limit(outBufferInfo.offset outBufferInfo.size);
//Log.v(TAG, String.format(\" writing audio sample : size=%s , presentationTimeUs=%s\", outBufferInfo.size, outBufferInfo.presentationTimeUs));
if (lastAudioPresentationTimeUs <= outBufferInfo.presentationTimeUs) {
lastAudioPresentationTimeUs = outBufferInfo.presentationTimeUs;
int outBufSize = outBufferInfo.size;
int outPacketSize = outBufSize 7;
outBuffer.position(outBufferInfo.offset);
outBuffer.limit(outBufferInfo.offset outBufSize);
byte[] outData = new byte[outPacketSize];
addADTStoPacket(outData, outPacketSize);
outBuffer.get(outData, 7, outBufSize);
fosAccAudio.write(outData, 0, outData.length);
//Log.v(TAG, outData.length \" bytes written.\");
} else {
Log.e(TAG, \"error sample! its presentationTimeUs should not lower than before.\");
}
}
audioEncoder.releaseOutputBuffer(outputBufIndex, false);
if ((outBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
sawOutputEOS = true;
}
} else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
audioOutputBuffers = audioEncoder.getOutputBuffers();
} else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat audioFormat = audioEncoder.getOutputFormat();
Log.i(TAG, \"format change : \" audioFormat);
}
}
...
以上是MediaCodec的编号实行实际操作。如果是编解码,与编号全过程反过来就可以进行。
汇总
- 优势:MediaCodec是Android关键的最底层多媒体系统部件,合理使用MediaCodec可以完成视频播放器、直播间、视频剪辑、录制视频、微信视频聊天、视频会议系统等几乎全部音频视频有关的编解码作用,且与基本编解码库对比有着一定的特性优点。
- 不够:MediaCodec也具有一些缺陷,兼容模式、可靠性都非常差,开发设计流程中会常常碰到型号、版本号等兼容问题,这种可以根据兼容有效处理。
四、声频NDK API开发设计
假如碰到一些规定更多的项目开发设计,对声频有性能的要求,例如:需要的不单单是简洁的响声播放视频或拍摄作用。他们必须响应式网站实时系统个人行为。一些典型性用例如:音频合成器、电子鼓、声乐学习运用、DJ 混响、声效、短视频/声频大会等这种规定非常高的需要时。就需要从更多方面的底部来给予作用适用,这儿便会使用NDK开发设计。
最先来了解一下NDK,全名是Native Development Kit,翻泽为原生态开发设计工具箱,关键的功能是可以让开发人员在Android运用中利用C和c 编码的专用工具,可以用以从自身的源码搭建,或是运用原有的预搭建库。
本部位的內容可以在如下所示的Android官网中开展查询和学习培训:https://developer.android.google.cn/ndk/guides/audio
Android官方网给带来了如下所示挑选:
- OpenSL ES:全称之为Open Sound Library for Embedded Systems,内嵌式声频加快规范。OpenSL ES是无受权费、混合开发、对于嵌入式操作系统用心提升的硬件配置声频加快 API,为内嵌式挪动计算机设备上的当地 应用开发者给予了规范化、性能卓越、低响应速度的声频作用完成方式,与此同时还建立了软/硬件配置声频特性的立即混合开发布署,不但减少了实行难度系数,并且推动了高級声频销售市场的发展趋势。
- 与Android的关联:Android 2.3即API9时逐渐适用 OpenSL ES 规范,根据 NDK 给予对应的 API 开发设计插口。Android 完成的OpenSL ES仅仅OpenSL的子集合,随后完成了拓展。
- Android 中OpenSL ES的相关资料:https://developer.android.google.cn/ndk/guides/audio/opensl
- AAudio:在 Android 8.0 版本号后引进的声频库 , 该音频库必须应用C语言在Native层开展启用 , 归属于NDK开发设计范围 。AAudio是OpenSL ES 库的轻量完成,一样具备低延迟时间 , 性能卓越的特性。必须注意的是,AAudio做为一款精准定位为微服务架构的声频库,只给予载入声频流开展音标发音的作用 , 不承担麦克风设备管理方法 , 文档 I / O , 声频编解码 等实际操作 ;
- 音频输入:从麦克风 , 手机耳机等音频输入机器设备中 , 应用AAudio声频流收集声频数据信息 , 载入特性高 , 低延迟时间 。
- 音频输出:将声频流载入到 AAudio,以极性能卓越方法将声频流輸出到音标发音机器设备中 。
- Oboe:该库是根据AAudio封装形式的一个开源系统库,在github上面有开源系统的详细地址,连接如下所示:https://github.com/google/oboe 该库与AAudio是应用C 撰写的适用Android研发的效率高的声频开发设计,仍然归属于NDK开发设计的范围。Google官方网强烈推荐应用该库。
五、声频优化算法的开源代码库
FFmpeg:昭然若揭
FFmpeg是一套可以用于纪录、变换视频信号、短视频,并且能够将其转换为流的开源代码。它保证了拍摄、变换及其气流输送音频视频的详细解决方法。它包括了十分专业的声频/视频编解码库libavcodec,为了确保高可扩展性和编解码品质,libavcodec里许多code全是从头开始开发设计的。
只需是做音频视频开发设计的开发人员,几乎沒有不清楚FFmpeg库的。在github上可以寻找FFmpeg的首页详细地址如下所示:https://github.com/FFmpeg/FFmpeg 官网的地点是:https://ffmpeg.org/
在其中含有的库主要包含:
- libavcodec:音/视频编码库。
- libavformat:音频视频文件格式的产生和分析等实际操作。
- libavutil:公共性的专用工具函数公式。
该程序流程最开始在Linux平台上开发设计和应用,现阶段在windows、mac上父可以应用。
在Android中使用FFmpeg
假如必须在Android中应用FFmpeg,必须开展集成化。必须通过好多个流程:
- 编译程序:最先要免费下载FFmpeg,并开展编译程序,编译出Android中需用的文档。
- 将编译程序后的內容集成化到Android新项目中。
- 检测并启用集成化的FFmpeg中的方式。
Speex
Speex主要是对于视频语音的开源代码完全免费,无专利的一种音频压缩文件格式,是特意为视频码率在2-44kbps的语音压缩而设计方案。Speex的特性主要包含:
- 捷变(8kHz),宽带网络(16kHz)和微波通信(32kHz)缩小于同一位流
- 可变视频码率(VBR)
- 非持续传送(DTX)
- 感观消噪(AEC)
- 噪声屏蔽掉
Slik
Slik优化算法关键的功能是完成视频语音和音频文件的编解码,其具体的特性是:
- 适用4种采样频率:8KHz、12KHz、16KHz、24KHz;三种复杂性:低、中、高。
- 编号视频码率在 6~40kbps。
- 给予了指定C编码,十分有益于向ARM、DSP移殖和提升。
六、汇总
这篇文本文档,大家用较长的篇数详细介绍了多媒体系统开发设计中的声频作用的开发设计和应用,在实际的开发设计和运用中,关键应当放到对总体专业知识的掌握和构架的整理上,不必局限于某一API的应用,主要参数的效果等。归根结底,不一样的建立计划方案,不一样的解决方法最后的着力点和编码操作流程几乎是一致的。再度回顾与展望大家这篇內容:
- 声频的播放视频:MediaPlayer、SoundPool、AudioTrack、RingtoneManager
- 声频的收集:MediaRecorder
- 音频文件格式的变换:MediaCodec
- 最底层库的大力支持和应用:OpenSL ES、AAudio、Oboe
- 开源系统库的熟悉和详细介绍:FFmpeg
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。