媒体(Media)就是人与人之间实现信息交流的中介,简单地说,就是信息的载体,也称为媒介。多媒体是计算机和视频技术的结合,实际上它是两个媒体;声音和图像,或者用现在的术语:音响和电视。
多媒体本身有两个方面,和所有现代技术一样它是由硬件和软件,或机器和思想混合组成。可以将多媒体技术和功能在概念上区分为控制系统和信息。多媒体之所以能够实现是依靠数字技术。多媒体代表数字控制和数字媒体的汇合,电脑是数字控制系统,而数字媒体是当今音频和视频最先进的存储和传播形式。事实上有人就简单地认为多媒体是电脑和电视的结合。电脑的能力达到实时处理电视和声音数据流的水平,这时多媒体就诞生了。
一、框架介绍
Android 多媒体框架为开发者提供了一系列强大的工具和 API,用于处理音频、视频以及图像等多种媒体类型。这个框架允许应用程序轻松地播放、录制和操作媒体内容,并支持多种格式和编码解码器(codec)。
1、演变历史
Android 多媒体框架自 Android 系统诞生以来经历了显著的变化和发展。以下是其演变历史的一个简要概述:
- 早期版本(Android 1.0 - Android 1.6):多媒体框架基于 PacketVideo 公司的 OpenCORE 平台,它支持多种音频、视频和静态图像格式的编解码。
- OpenCORE 2.0(Android 1.6 Donut):OpenCORE 得到了更新,以改进性能和支持更多的媒体格式。
- Stagefright 引入(Android 2.0 Eclair 和 Android 2.1 Eclair):Stagefright是一个新的多媒体引擎,旨在替代 OpenCORE。它提供了更高效的媒体处理能力,并且更加模块化。
- Stagefright 增强版(Android 3.0 Honeycomb):在这个版本中,Stagefright 得到了进一步的优化和功能增强,但总体架构没有发生根本性的变化。
- NuPlayer 加入(Android 2.3 Gingerbread):NuPlayer 被引入作为流媒体播放器,能够更好地支持在线流媒体内容,如 MPEG-2 传输流等。
- Jelly Bean 时期的重大变化(Android 4.1):对 C/C++ 部分的多媒体框架进行了重构,将相关代码从 framework/base 移到了一个新的 framework/av 目录下,并单独设立了 git 库。这标志着多媒体框架有了独立的发展空间。同时,NuPlayer 逐步取代了 Stagefright 的部分功能,预示着未来的多媒体处理可能会更多地依赖于 NuPlayer。
在之后的版本中,多媒体框架继续进化,增加了对新编解码器的支持以及对 MediaSession 和 MediaController 等功能的支持,使得开发者能够更容易地创建复杂的媒体应用。同时,ExoPlayer 作为一个高级媒体播放库也被引入,它为开发人员提供了比标准 MediaPlayer 更多的灵活性和控制力,特别适合流媒体应用。
随着 Android 系统的不断更新,多媒体框架也在持续演进,以适应新技术和用户需求的变化。例如,对于更高分辨率的视频支持、更好的音频质量、更低延迟的音频处理等方面都有所提升。同时,为了提高效率和性能,Google 也一直在优化底层的实现细节。
2、核心功能
音频和视频播放:Android 通过 MediaPlayer 类提供了一种简单的方法来播放音频和视频文件。无论是本地资源还是网络流媒体,都可以使用这个类进行播放。
音频和视频录制:使用 MediaRecorder 类可以实现音频和视频的录制功能。这使得开发人员能够创建诸如语音备忘录或视频录制的应用程序。
高级媒体播放:对于需要更复杂功能的应用程序(例如动态自适应流媒体),Google 推荐使用 ExoPlayer 库。ExoPlayer 是开源的,支持更多特性,并且可以更容易地进行定制。
低延迟音频:对于音乐应用或其他需要实时音频处理的应用,可以使用 AudioTrack 和 AudioRecord 类直接处理原始音频数据,以减少延迟。
编解码器访问:MediaCodec 类允许开发者访问底层的音视频编解码器,从而实现对编码和解码过程的细粒度控制。
多媒体提取和混流:MediaExtractor 用于从文件或流中提取音视频轨道,而 MediaMuxer 则可用于将多个轨道混合到一个文件中。
图形渲染:通过 OpenGL ES 和 Vulkan 等 API,Android 支持高质量的 2D 和 3D 图形渲染,适用于游戏和其他需要复杂视觉效果的应用。
在多媒体框架不断发展中。新的 API 和功能被引入的同时,一些旧的 API 可能会被弃用。因此,在开发过程中保持对最新文档的关注是非常重要的。
二、核心组件
在 Android 中,处理音视频播放的核心组件包括了 MediaPlayer 和 VideoView。MediaPlayer是一个较为底层的类,能够提供媒体播放的大部分功能,而 VideoView 则是基于 MediaPlayer 的高层封装,主要针对视频播放提供了一套简便的接口。除此之外,还有功能更加强大的第三方库 ExoPlayer,它提供了更好的自定义能力,适用于更复杂的播放场景。
1、VideoView
VideoView 是 Android 平台上用于视频播放的控件。它的主要功能是提供一个视图,让开发者能够将视频内容直接集成到应用的界面中。VideoView 支持常见的媒体格式,如 MP4 和 3GP,它能够处理视频的加载、播放、暂停、停止和释放等操作。在简单的视频播放需求中,VideoView 是一个非常实用的组件,适合那些只需要基础视频播放功能的场景。
尽管 VideoView 提供了许多便利的功能,但它在实际项目中的使用也存在一些限制。首先,VideoView 仅支持有限的视频格式,对于一些特殊的媒体文件格式,可能需要额外的解码器支持。其次,VideoView 不提供高级的播放控制和自定义播放视图的选项。最后,由于 VideoView 是一个 View,它的性能可能不如专门的视频播放库,如 ExoPlayer,在处理高分辨率视频或需要大量自定义功能的项目中,可能力不从心。
2、MediaPlayer
音频播放是移动应用中不可或缺的功能之一。Android 平台上的 MediaPlayer 组件提供了丰富的音频处理能力,支持本地和网络的音频文件播放。
MediaPlayer 是 Android 中用于播放音频和视频的主要组件。它可以用于控制媒体文件的播放、暂停、停止、快进和快退等操作。尽管 VideoView 组件在视频播放中有其独特的优势,但对于音频文件播放来说,MediaPlayer 提供了更精细的控制,同时 MediaPlayer 组件不仅提供了基本的音频播放功能,还支持一些高级特性,如网络流式播放和音频效果处理等。
3、ExoPlayer
ExoPlayer 是 Google 官方推出的一款开源播放器,它相比于 Android 系统中传统的 MediaPlayer 组件,提供了更多的优点和特性。
- 扩展性和模块化:ExoPlayer 通过一系列可插拔的组件,实现了高度的可定制化。用户可以根据需要选择不同的组件,例如 DASH 支持、HLS 支持、字幕显示等。
- 解码器分离:ExoPlayer 将解码器从播放器框架中分离出来,允许应用程序对解码器进行更好的管理和控制。
- 播放控制:提供了更为丰富的播放控制选项,如自适应比特率(ABR)播放,无缝循环播放,视频缓冲区大小调整等。
- 内置缓存支持:ExoPlayer 内置了对 HTTP Live Streaming (HLS) 和 Dynamic Adaptive Streaming over HTTP (DASH) 的缓存支持,提高了播放的稳定性和流畅性。
- 多格式支持:支持广泛的视频格式,包括 MP4、M4V、MKV、WebM、WMV、AVI、FLV 等,以及多种音频格式。
ExoPlayer 支持的媒体格式和特性远比传统 MediaPlayer 丰富,这使得它更加适合处理现代网络视频的需求。
- 自适应比特率:通过 DASH 和 HLS 支持自适应比特率视频流,能够根据网络状况调整视频质量。
- 字幕支持:支持多种字幕格式,包括 SRT、TTML、WebVTT 等,并且可以自定义字幕样式。
- 视频轨道选择:允许用户在多音频和多视频轨道之间进行切换,支持自定义标题轨道。
- 实时视频渲染:通过 MediaCodec API 的使用,提供了实时视频渲染能力,允许自定义视频输出的像素格式。
- 播放速度控制:支持从 0.5x 到 2.0x 倍速的播放,以及动态调整播放速度。
开发者在选择使用 MediaPlayer、VideoView 或是 ExoPlayer 时,需要根据项目需求和场景来决定。对于基础的播放需求,VideoView 和 MediaPlayer 足以应对。但当需要实现更复杂的播放功能,如自适应比特率流播放、字幕同步等,ExoPlayer 则显得更为合适。
4、核心类
MediaPlayer
源码位置:/frameworks/base/media/java/android/media/MediaPlayer.java
MediaPlayer 是 Android 框架中多媒体框架的核心组件之一,它是 Android 提供的用于播放音频和视频的高级 API,主要用于处理本地或远程媒体文件的播放任务。MediaPlayer 是一个状态机,它提供了以下主要功能:
- 音频和视频播放:支持从本地文件、资源文件或网络流中播放音频和视频。
- 多种媒体源支持:包括本地文件路径、URI、文件描述符(File Descriptor)、InputStream 等。
- 事件监听:提供回调机制,允许开发者监听播放状态的变化(如播放完成、缓冲更新等)。
- 控制操作:支持播放、暂停、停止、快进、快退等基本操作。
- 音量调节:可以设置左右声道音量。
- 循环播放:支持单曲循环或多曲循环。
- 元数据获取:可以从媒体文件中提取元数据(如标题、艺术家、专辑等)。
MediaRecorder
源码位置:/frameworks/base/media/java/android/media/MediaRecorder.java
MediaRecorder 是 Android 多媒体框架中用于录制音频和视频的核心类,它提供了一组简单易用的 API,允许开发者轻松实现音视频录制功能。
- 音视频录制:支持从设备的麦克风和摄像头捕获音频和视频。
- 多种输出格式支持:可以将录制的内容保存为不同的文件格式(如 MP4、3GP 等)。
- 编码器配置:支持设置音频和视频的编码器、比特率、采样率等参数。
- 灵活的录制控制:包括开始录制、暂停录制、停止录制以及释放资源等功能。
- 事件监听:提供回调机制,允许开发者监听录制过程中的状态变化或错误。
AudioTrack/AudioRecord
/frameworks/base/media/java/android/media/AudioTrack.java
/frameworks/base/media/java/android/media/AudioRecord.java
AudioTrack 和 AudioRecord 是 Android 多媒体框架中用于处理音频的核心类,分别用于音频的播放和录制。它们提供了对底层音频硬件的直接访问,可以直接处理原始音频数据。适用于需要低延迟、高精度音频处理的应用场景。
ExoPlayer
源码位置:/external/exoplayer/tree/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
ExoPlayer 是 Google 开源的 ExoPlayer 库中的核心类,它是一个功能强大且高度可定制的媒体播放器库,用于替代 Android 系统自带的 MediaPlayer。它支持多种媒体格式、流媒体协议和高级功能,适用于复杂的多媒体应用场景。
MediaCodec
源码位置:/frameworks/base/media/java/android/media/MediaCodec.java
MediaCodec 是 Android 多媒体框架中用于处理音视频编解码的核心类,它是 Android 提供的低级 API,允许开发者直接与硬件加速的编解码器交互,适用于需要对音视频数据进行精确控制的场景。提供了以下主要功能:
- 音视频编解码:支持音频和视频的编码(压缩)和解码(解压缩)。
- 硬件加速:通过底层硬件加速实现高效的音视频处理。
- 流式处理:支持从输入缓冲区读取原始数据,并将处理后的数据写入输出缓冲区。
- 灵活的参数配置:可以设置编解码器的格式、分辨率、帧率、比特率等参数。
- 多格式支持:支持多种音视频格式(如 H.264、H.265、AAC 等)。
虽然 MediaCodec 提供了对底层硬件加速的支持,适用于需要精确控制音视频数据的应用场景。但如果应用的需求较为简单(如播放 MP4 文件或录制视频),可以优先考虑使用 MediaPlayer 或 MediaRecorder,因为它们更易于使用且功能全面。
MediaExtractor/MediaMuxer
/frameworks/base/media/java/android/media/MediaExtractor.java
/frameworks/base/media/java/android/media/MediaMuxer.java
MediaExtractor 和 MediaMuxer 是 Android 多媒体框架中用于音视频处理的核心类,分别用于从多媒体文件中提取音视频轨道数据和将音视频多个轨道数据混合复用到多媒体文件中。它们提供了对多媒体容器格式(如 MP4、3GP 等)的底层支持,适用于需要自定义音视频处理的应用场景。
OpenGL ES/Vulkan
OpenGL ES 和 Vulkan 是两个用于渲染 2D 和 3D 图形的跨平台 API,主要用于移动设备、游戏控制台和其他嵌入式系统。
- OpenGL ES:是一个专为移动设备、手持设备和其他嵌入式系统设计的 3D 图形 API。它是桌面版 OpenGL 的一个简化版本,专注于提供高性能图形渲染能力的同时保持较低的资源消耗。
- Vulkan:是由 Khronos Group 开发的一个低开销、跨平台的 2D 和 3D 图形及计算 API。它旨在提供比 OpenGL ES 更高的性能和更直接的硬件控制,同时减少 CPU 负载。
对于初学者或需要快速开发的应用来说,OpenGL ES 更加容易上手,因为它抽象掉了许多底层细节。而 Vulkan 虽然强大但学习曲线陡峭,需要深入了解计算机图形学的基础知识。而在高要求的应用场景下,比如高端游戏或者虚拟现实应用中,Vulkan 通常能提供更好的性能表现,特别是在多核处理器环境下。
如果你正在开发一款对性能要求极高且希望最大化利用硬件资源的应用,那么 Vulkan 将是更好的选择。相反,如果项目时间紧迫或者你更关注于快速原型设计而非极致优化,则可能更适合使用 OpenGL ES。
总的来说,两者各有优势,在选择时应根据项目的具体需求以及团队的技术背景来做决定。随着 Vulkan 的不断成熟和发展,越来越多的新项目开始倾向于采用 Vulkan 来获得更好的性能表现。然而,OpenGL ES 仍然因其简单性和广泛的兼容性而在很多领域内被广泛使用。
Camera2 API
Camera2 API 是 Android 平台上用于控制设备摄像头的高级接口,旨在替代旧版 Camera API,并提供更强大的功能和更高的灵活性。它允许开发者对摄像头硬件进行细粒度的控制,如手动调整曝光、焦距、白平衡等参数,支持高分辨率图像捕捉及高效视频录制等功能。主要特性包括:
- 细粒度控制:提供了对摄像头硬件更加详细的控制,包括曝光时间、ISO 感光度、对焦距离等。
- 多摄像头支持:能够同时访问多个后置或前置摄像头(如果设备支持)。
- 动态范围扩展:支持 HDR 图像捕捉。
- 高效的图片与视频捕获:可以实现低延迟的照片拍摄和高质量的视频录制。
- 可配置的输出格式:支持多种输出格式,包括 JPEG、YUV、RAW_SENSOR 等。
- 异步操作:通过回调机制处理拍照和录像的结果,避免阻塞主线程。
通过 Camera2 API,开发者可以获得比传统 Camera API 更加丰富和灵活的摄像头控制体验,适用于从简单的拍照应用到复杂的实时图像处理系统等各种场景。