音视频开发文档
音视频开发文档
媒体应用概览
对于音视频开发来说,总共就包括两部分:播放器与界面。播放器比较容易理解,但界面可能对音频来说不需要。此处界面不仅仅包括显示视频的那个界面,而且包括显示播放器状态的传输控件,并且它有用于运行播放器。
播放器
- 在Android中,你可以从零开始构建自己的播放器(大佬专属),也可以从以下选项中进行选择。
- MediaPlayer 类提供准系统播放器的基本功能,支持最常见的音频/视频格式和数据源。
- ExoPlayer是提供了低层级Android音频API的开源库。ExoPlayer支持DASH和HLS流等高性能功能,这些功能在MediaPlayer中未提供。你可以自定义ExoPlayer代码,从而轻松添加新组件。ExoPlayer只能用于Android 4.1 及更高版本。
媒体会话和媒体控制器
界面和播放器我们可以任意选择,但对于所有媒体播放器来说,这两部分之间的交互的性质都基本相同。Android框架定义了两个类(Media Session和Media Controller)
MediaSession
- 媒体会话负责与播放器的所有通讯。系统只能从控制播放器的媒体会话中调用播放器。
- 会话可以维护播放器状态以及播放内容相关信息。会话可以接收来自一个或多个媒体播放器的回调。但响应回调的逻辑必须保持一致。
MediaController
- 媒体控制器会隔离你的界面。界面代码只与媒体控制器通信。每当会话状态发生变化时,它也会接收来自MediaSession的回调。这提供了一种自动更新关联界面的机制。MediaController一次只能连接到一个MediaSession。
media-compat库
media-compat 库包含可帮助构建音视频应用的类。这些类与运行Android2.3 及更高版本的设备兼容。
MediaSession 和MediaController 建议实现方式是MediaSessionCompat 和MediaControllerCompat 类。他们取代了Android 5.0 中引入的早期版本MediaSession 和 MediaController类。compat更加便捷轻松。
衡量性能
在Android 8.0 及更高版本中,getMetrics() 方法可用于某些媒体类。它会返回一个包含配置和性能信息的 PersistableBundle 对象。
MediaPlayer使用
需要使用权限声明
// 网络权限声明
<uses-permission android:name="android.permission.INTERNET" />
// 唤醒锁定权限
<uses-permission android:name="android.permission.WAKE_LOCK" />
使用方法
MediaPlayer 类是媒体框架的重要组成部分之一。此类的对象能够获取、解码以及播放音视频,而且只需要少量的设置。它支持多种不同的媒体源,例如:
- 本地资源
- 内部URI,例如你可能从内容解析器那获取的URI
- 外部网址(流式传输)
代码展示
本地原始资源
播放本地可用的URL
通过HTTP流式传输
异步准备
原则上,使用MediaPlayer很简单。但还需要执行一些额外操作。例如,对prepare()的调用可能需要很长时间执行,因为它可能涉及获取和解码媒体数据。因此一般不能在主线程调用它。否则会卡顿甚至ANR错误。
为了避免这种情况,我们可以自行编写县城逻辑,也可以使用prepareAsync()方法。当媒体准备就绪后,系统会调用 setOnPreparedListener() 配置的 MediaPlayer.OnPreparedListener 的 onPrepared() 方法。
管理状态
MediaPlayer 以状态为基础。也就是说,MediaPlayer 具有内部状态,编写代码时必须注意,某些操作仅在播放器处于特定状态时才有效。如果你在错误的状态下执行某项操作,则会抛出异常。
- 当MediaPlayer新创建或者调用 reset()的时候,它处于idle状态 。并且在release() 被调用之后,它处于End 状态。在这两种状态之间是MediaPlayer对象的生命周期。
- 新构造的MediaPlayer跟reset()之后的MediaPlayer还是有些细微区别。在一些编程错误调用方法后,新构造的对象不会为用户回调方法OnErrorListener.onError(),并且对象状态保持不变;但是如果这些方法在之后被调用reset(),用户提供的回调方法OnErrorListener.onError()将由内部播放器引擎调用,并且该对象将转移到Error状态。
- 建议一旦不再使用MediaPlayer对象,请 release()立即调用
- 只有在idel状态下可以使用 setDataSource()。其他状态下会抛出IllegalStateException。
- MediaPlayer对象必须首先进入“准备”状态,然后才能开始播放。
- 有同步和异步两种方式。
- prepare()同步方法,一旦调用,状态就会变为prepared
- prepareAsync()(异步方法)当调用返回后,对象状态也会变为prepared
- 重要的是要注意,Preparing状态是一个过渡状态,并且在MediaPlayer对象处于Preparing状态时调用具有副作用
- 有同步和异步两种方式。