【eoe Android 特刊】第十八期
本文档由 eoeAndroid 社区组织策划,整理及发布,版权所有,转载请保留!
www.eoeandroid.com 做最棒的 Android 开发社区!
【eoe Android 特刊】第十八期
本文档由 eoeAndroid 社区组织策划,整理及发布,版权所有,转载请保留!
www.eoeandroid.com 做最棒的 Android 开发社区!
目录
【Android 音频视频简介】
1.1 音频播放………………………………………………………………………………………..…..03
1.2 所支持的音频格式…………………………………………………………………………..…..04
1.3 通过 Intent 使用内建的音频播放器…………………………………………………..…..05
1.4 Android 音频实例分析……………………………………………………………………..…..06
1.5 Android 支持的视频格式……………………………………………………………………...07
1.6 Android 支持的编码方式………………………………………………………………..…....08
【Android 音频视频开发】
2.1 在 APP 中播放 media 音频…………………………………………………………….….….11
2.2 如何录制 media 音频资源…………………………………………………………….……...11
2.3 实例分析…………………………………………………………………………………………...12
【Android 多媒体】
3.1 多媒体系统的结构和层次介绍……………………………………………………………...14
3.2 多媒体实现的核心部分 OpenCore………………………………………………………...18
3.3 OpenCore 的代码结构………………………………………………………………………….20
3.4 OpenCore OSCL 简介 ………………………………………………………..………….......29
3.5 文件格式处理和编解码部分简介…………………………………………………………...32
【Android 音频视频 实例教程】
4.1 音频视频编解码格式 ……………………………………………………………..………..…36
4.2 Android 视录视频示例………………………………………………………………..……....40
4.3 利用 ffmpeg 框架扩展 android 平台解码器...............................................45
【其它】
5.1 关于 BUG………………………………………………………………………………………………..………...49
5.2 关于 eoeAndroid………………………………………………………………………………….………...49
【eoe Android 特刊】第十八期
本文档由 eoeAndroid 社区组织策划,整理及发布,版权所有,转载请保留!
www.eoeandroid.com 做最棒的 Android 开发社区!
【Android 音频入门介绍】
1.1 android 音频介绍
这个世界音频设备千变万化,Android 也不可能为每种设备都提供支持。Android 定
义了一个框架,这个框架来适配底层的音频设备。该适配层的定义位于:
hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.h
要 想 视 频 底 层 的 音 频 设 备 必 须 要 继 承 该 文 件 中 定 义 的 AudioStreamOut ,
AudioStreamIn,AudioHardwareInterface 等类,并实现 createAudioHardware 函数。
下面我们看一下 Android 创建音频设备的代码,代码位于:
frameworks/base/libs/audioflinger/AudioHardwareInterface.cpp
该文件有如下代码:
AudioHardwareInterface* AudioHardwareInterface::create()
{
/*
* FIXME: This code needs to instantiate the correct audio device
* interface. For now - we use compile-time switches.
*/
AudioHardwareInterface* hw = 0;
char value[PROPERTY_VALUE_MAX];
#ifdef GENERIC_AUDIO
hw = new AudioHardwareGeneric();
#else
// if running in emulation - use the emulator driver
if (property_get("ro.kernel.qemu", value, 0)) {
LOGD("Running in emulation - using generic audio driver");
hw = new AudioHardwareGeneric();
}
else {
LOGV("Creating Vendor Specific AudioHardware");
hw = createAudioHardware();
}
#endif
if (hw->initCheck() != NO_ERROR) {
LOGW("Using stubbed audio hardware. No sound will be produced.");
delete hw;
hw = new AudioHardwareStub();
}
#ifdef WITH_A2DP
hw = new A2dpAudioInterface(hw);
#endif
#ifdef ENABLE_AUDIO_DUMP
// This code adds a record of buffers in a file to write calls made by AudioFlinger.
// It replaces the current AudioHardwareInterface object by an intermediate
【eoe Android 特刊】第十八期
本文档由 eoeAndroid 社区组织策划,整理及发布,版权所有,转载请保留!
www.eoeandroid.com 做最棒的 Android 开发社区!
one which
// will record buffers in a file (after sending them to hardware) for testing purpose.
// This feature is enabled by defining symbol ENABLE_AUDIO_DUMP.
// The output file is set with setParameters("test_cmd_file_opening PCM dump
interface");
hw = new AudioDumpInterface(hw); // replace interface
#endif
return hw;
}
从代码中我们可以看出如果定义了 GENERIC_AUDIO 的宏,则会创建
AudioHardwareGeneric,如果是模拟器的话,AudioHardwareGeneric 会不能初始化,进
而创建 AudioHardwareStub。这两个类都是 Audio 设备的适配层,是 Android 默认提供
的 。 模 拟 器 都 是 用 AudioHardwareStub , 不 会 有 声 音 输 出 。 设 备 都 是 用
AudioHardwareGeneric,因为默认 GENERIC_AUDIO 是设置的。
一般我们只关心 AudioHardwareGeneric 实现,谁会去给模拟器去调试声音呢,反正
我没这个闲心。首先说明一下这个音频适配层是 Android 自带的,可以保证你的音频设
备 正 常 运 行 , 但 是 不 能 发 挥 设 备 的 最 佳 性 能 。 通 过 后 面 的 描 述 你 将 会 了 解 。
AudioHardwareGeneric 的定义位于:
frameworks/base/libs/audioflinger/AudioHardwareGeneric.cpp
查看源码你会发现这个适配层需要实现设备/dev/eac,并且该设备只输出 44.1khz
采 样 率 的 音 频 数 据 给 /dev/eac 设 备 , 如 果 不 是 44.1khz 的 采 样 率 的 数 据 ,
AudioHardwareGeneric 会经过 Resample 过程把它转换成 44.1kHZ 的音频数据,然后再
输出给音频设备。44.1kHZ 音频数据是最普遍的音频采样率,大部分 Mp3 都是以这个采
样 率 压 缩 的 , 所 以 选 择 这 个 采 样 率 做 为 默 认 采 样 率 还 是 有 一 定 的 合 理 性 的 。
AudioHardwareGeneric 是软件实现 Resample 过程是,效率会比较低。很多音频设备支
持不同采样率的数据,可以理解成硬件实现 Resample 过程。
通过上面的描述我们可以知道这个通用音频适配层只是让你的设备可以用而已,不
能发挥设备的性能优势,如果你的设备对音频质量有更高的要求,必须要自己实现音频
适配层。谷歌只能保证你的音频可以播放,但是不能保证效率(他也没有办法保证效率)。
1.2 所支持的音频格式
对于播放,Android 支持各种各样的音频文件格式和编解码。对于录音的支持少一些,
以后我们学到录音部分将会讨论这点。
AAC:
高级音频编码(以及其扩展:HE AAC)编解码,.m4a,.3gp 文件.AAC 是一个流行的标
准,IPOD 和其他便携式媒体播放器都使用它。Android 在 MPEG4 音频文件和 3GP 文件
内(都是基于 MPEG4 格式)支持这种音频格式。最近 AAC 的附加规范 HE AAC 也被支持
了。
【eoe Android 特刊】第十八期
本文档由 eoeAndroid 社区组织策划,整理及发布,版权所有,转载请保留!
www.eoeandroid.com 做最棒的 Android 开发社区!
MP3:
MPGE-1 音频层 3,.mp3 文件。Android 支持 MP3,MP3 可能是使用最广泛的音频编
解码,这允许 Android 通过各种网站和音乐商店来使用大部分在线音频。
AMR:
自适应多速率编解码(AMR-NB,AMR-WB),.3gp,.amr 文件。AMR 音频编解码已经被标
准化了,主要被 3GPP(第三代合作伙伴项 目)用于语音音频编解码。3GPP 是一个为其
合作伙伴创建规范的电信行业机构。换句话说,AMR 编解码主要用于现代移动电话的语
音呼叫程序,并且手机厂商 和手机携带者普遍都支持这个格式。AMR 这格式一般对语音
编码很有用,但对更复杂的类型表现的不够好,比如音乐。
Ogg:
Ogg Vorbis,.ogg 文件。Ogg Vorbis 是个开源的,无专利费的音频编解码。其品质可
媲美商业性的,需缴纳专利费的编解码比如 MP3,AAC。它由一群自愿者开发,当前由
Xiph.Org 基金会负责维护。
PCM:
脉冲编码调制通常被用在 WAVE,WAV 文件,.wav 文件。PCM 这技术主要用于音频
在电脑和其他电子音频设备上的存储。它通常是个未压缩的音频 文件,其数据代表随着
时间流逝一段音频的振幅。“采样率”是多长时间一次一个振幅读取被存储起来。“位深度”
是指多少位被用来代表一个单独的样本。一段 16KHZ 采样率,32 位位深度的音频数据
是指它包含每秒钟 16000 个的 32 位的数据用来表示音频振幅。采样率和位深度越高,数
字化音频越精准。采样率 和位深度也决定了音频文件的大小。Android 在 WAV 文件内支
持 PCM 音频数据。WAV 是 PC 上的一个长期存在的标准音频格式。
1.3 通过 Intent 使用内建的音频播放器
正如使用摄像头,在一个应用程序里提供播放音频文件的能力,最容易的方法就是
使用内建的“音乐”程序的功能。这个程序有个用户熟悉的界面,能播放所有 Android 支持
的格式,并且能通过一个 intent,被触发去播放一个指定的文件。
普通的 android.content.Intent.ACTION_VIEW intent,其数据设置为一个音频文件的
Uri,并指定其 MIME 类型,这样 Android 会自动选择一个合适的应用程序来播放。这个
程序应该是内建的 音乐播放程序,但用户可能被提供其他的选项,如果他/她安装了其他
的音频播放软件。
1. Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
2. intent.setDataAndType(audioFileUri, "audio/mp3");
3. startActivity(intent);
注解:MIME 全称是 Multipurpose Internet Mail Extensions(多用途互联网邮件扩展)。
它起初专门用来帮助电子邮件客户端发送和接收附件。但它的使用范围从电子邮件极大
地扩展到其他的通讯协 议,包括 HTTP,标准万维网服务。Android 使用 MIME 类型来解
析 intent,并且用它来决定应该选择哪个应用程序来处理 intent.