Android MediaPlayer接口及状态迁移
[时间:2016-09] [状态:Open]
[关键词:android,mediaplayer,播放接口,播放状态图]
引言
本文内容相对简单,作为后续处理的起点,简要整理了Android MediaPlayer的接口层,并且这里只会涉及c层的实现,至于上层的JNI/跨进程调用逻辑,建议参考其他资料。
整理本文的目的仅供个人后续参考使用。
MediaPlayer Interface
我们可以在Android源码中找到MediaPlayerInterface的定义如下:(这里只列出接口信息,详细内容建议参考源码)
// from frameworks/av/include/media/MediaPlayerInterface.h
// abstract base class - use MediaPlayerInterface
class MediaPlayerBase : public RefBase
{
public:
    // AudioSink: abstraction layer for audio output
    class AudioSink : public RefBase {...};
    MediaPlayerBase() : mCookie(0), mNotify(0) {}
    virtual             ~MediaPlayerBase() {}
    virtual status_t    initCheck() = 0;
    virtual bool        hardwareOutput() = 0;
    virtual status_t    setUID(uid_t /* uid */);
    virtual status_t    setDataSource(
            const sp<IMediaHTTPService> &httpService,
            const char *url,
            const KeyedVector<String8, String8> *headers = NULL) = 0;
    virtual status_t    setDataSource(int fd, int64_t offset, int64_t length) = 0;
    virtual status_t    setDataSource(const sp<IStreamSource>& /* source */);
    virtual status_t    setDataSource(const sp<DataSource>& /* source */);
    // pass the buffered IGraphicBufferProducer to the media player service
    virtual status_t    setVideoSurfaceTexture(
                                const sp<IGraphicBufferProducer>& bufferProducer) = 0;
    virtual status_t    prepare() = 0;
    virtual status_t    prepareAsync() = 0;
    virtual status_t    start() = 0;
    virtual status_t    stop() = 0;
    virtual status_t    pause() = 0;
    virtual bool        isPlaying() = 0;
    virtual status_t    setPlaybackSettings(const AudioPlaybackRate& rate);
    virtual status_t    getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */);
    virtual status_t    setSyncSettings(const AVSyncSettings& sync, float /* videoFps */);
    virtual status_t    getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */);
    virtual status_t    seekTo(int msec) = 0;
    virtual status_t    getCurrentPosition(int *msec) = 0;
    virtual status_t    getDuration(int *msec) = 0;
    virtual status_t    reset() = 0;
    virtual status_t    setLooping(int loop) = 0;
    virtual player_type playerType() = 0;
    virtual status_t    setParameter(int key, const Parcel &request) = 0;
    virtual status_t    getParameter(int key, Parcel *reply) = 0;
    // default no-op implementation of optional extensions
    virtual status_t setRetransmitEndpoint(const struct sockaddr_in* /* endpoint */);
    virtual status_t getRetransmitEndpoint(struct sockaddr_in* /* endpoint */);
    virtual status_t setNextPlayer(const sp<MediaPlayerBase>& /* next */);
    virtual status_t    invoke(const Parcel& request, Parcel *reply) = 0;
    virtual status_t    getMetadata(const media::Metadata::Filter& /* ids */, Parcel* /* records */);
    void        setNotifyCallback(void* cookie, notify_callback_f notifyFunc);
    void        sendEvent(int msg, int ext1=0, int ext2=0, const Parcel *obj=NULL);
    virtual status_t dump(int /* fd */, const Vector<String16>& /* args */) const;
private:
    friend class MediaPlayerService;
    Mutex               mNotifyLock;
    void*               mCookie;
    notify_callback_f   mNotify;
};
// Implement this class for media players that use the AudioFlinger software mixer
class MediaPlayerInterface : public MediaPlayerBase
{
public:
    virtual             ~MediaPlayerInterface() { }
    virtual bool        hardwareOutput() { return false; }
    virtual void        setAudioSink(const sp<AudioSink>& audioSink) { mAudioSink = audioSink; }
protected:
    sp<AudioSink>       mAudioSink;
};
// Implement this class for media players that output audio directly to hardware
class MediaPlayerHWInterface : public MediaPlayerBase
{
public:
    virtual             ~MediaPlayerHWInterface() {}
    virtual bool        hardwareOutput() { return true; }
    virtual status_t    setVolume(float leftVolume, float rightVolume) = 0;
    virtual status_t    setAudioStreamType(audio_stream_type_t streamType) = 0;
};
通常我们的调用逻辑是,构造函数->setDataSource->SetVideoSurfaceTexture->prepare/prepareAsync->start->stop->reset->析构函数,按照实际需求还会调用pause、isPlaying、getDuration、getCurrentPosition、setLooping、seekTo等。
各个接口具体含义参考下表:
| 方法 | 说明 | 
|---|---|
| setDataSource | 设置多媒体数据来源(位置) | 
| setVideoSurfaceTexture | 设置用SurfaceHolder来显示多媒体 | 
| prepare | 准备(同步) | 
| prepareAsync | 准备(异步) | 
| start | 开始播放 | 
| stop | 停止播放 | 
| reset | 重置MediaPlayer对象为刚刚创建的状态 | 
| getCurrentPosition | 得到当前播放位置 | 
| getDuration | 得到文件的时间 | 
| isPlaying | 是否正在播放 | 
| pause | 暂停 | 
| seekTo | 指定播放的位置(以毫秒为单位的时间) | 
| setLooping | 设置是否循环播放 | 
MediaPlayer状态图
MediaPlayer的状态图如下:

这个状态图对应的java层的MediaPlayer。不过可以参考,在实际的源码实现时,不会完全参考这个状态图,可能有更多的内部状态和简化状态。
比如,你可以不调用prepare,直接调用start。
图中各个状态的迁移,建议参考MediaPlayer的官方文档。
参考资料
Android MediaPlayer接口及状态迁移的更多相关文章
- android MediaPlayer API大全已经方法详解(转载)
		
通过这张图,我们可以知道一个MediaPlayer对象有以下的状态: 1)当一个MediaPlayer对象被刚刚用new操作符创建或是调用了reset()方法后,它就处于Idle状态.当调用了rele ...
 - Android MediaPlayer状态机
		
对播放音频/视频文件和流的控制是通过一个状态机来管理的.下图显示一个MediaPlayer对象被支持的播放控制操作驱动的生命周期和状态.椭圆代表MediaPlayer对象可能驻留的状态.弧线表示驱动M ...
 - 学习Android MediaPlayer
		
Android Media Playback 原文 The Android multimedia framework includes support for playing variety of c ...
 - 翻译的很好的一篇android mediaplayer
		
MediaPlayer类可用于控制音频/视频文件或流的播放.关于如何使用这个类的方法还可以阅读VideoView类的文档. 1.状态图对播放音频/视频文件和流的控制是通过一个状态机来管理的.下图显示一 ...
 - Android MediaPlayer和VideoView的使用
		
MediaPlayer MediaPlayer类是Androd多媒体框架中的一个重要组件,通过该类,我们可以以最小的步骤来获取,解码和播放音视频.它支持三种不同的媒体来源: 本地资源 内部 ...
 - [转]Android MediaPlayer状态机
		
翻译Android Reference Manual的MediaPlayer的状态机 对播放音频/视频文件和流的控制是通过一个状态机来管理的.下图显示一个MediaPlayer对象被支持的播放控制操作 ...
 - Android MediaPlayer 在 6.0 以上版本使用倍速播放功能说明
		
Android MediaPlayer 在API 23即6.0版本开始支持倍速播放,下面我们来介绍一下如何使用MediaPlayer进行倍速播放. 一.核心接口 MediaPlayer.setPlay ...
 - Android MediaPlayer的生命周期
		
MediaPlayer的状态转换图也表征了它的生命周期,如下: 这张状态转换图清晰的描述了MediaPlayer的各个状态,也列举了主要的方法的调用时序,每种方法只能在一些特定的状态下使用,如果使用时 ...
 - Android MediaPlayer Error/Info Code
		
1. 常见错误 error(-38, 0) 我觉得-38表示在当前的MediaPlayer状态下,不能运行你的操作. 详细怎样做请參考:Android MediaPlayer 另外我在其它资料中.发现 ...
 
随机推荐
- NYOJ----蛇形填数
			
蛇形填数 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 在n*n方陈里填入1,2,...,n*n,要求填成蛇形.例如n=4时方陈为: 10 11 12 1 9 16 ...
 - python配置文件转dict
			
配置文件有很多种,如JSON,properties,conf,xml等. 除非需要跟别的语言进行交互,python本身是完全可以取代所有配置文件的.使用python进行配置可以使用非常灵活地执行一些逻 ...
 - C# Log4Net level优先级别
			
原文地址:https://blog.csdn.net/pukuimin1226/article/details/51819388?locationNum=2&fps=1 Level定义记录的日 ...
 - Html中 <tr> 标签的隐藏与显示
			
TR标签的隐藏与显示:block(显示)和none(隐藏) <tr style="display:none"> <tr id="sample" ...
 - Delphi GDI对象之剪切区域
			
原文链接: http://www.cnblogs.com/pchmonster/archive/2012/07/05/2577627.html 剪切区域(Clipping Regions) Regio ...
 - 记一次常规的Mysql数据库访问的时间分析
			
背景:记一次常规的数据访问的时间分析(插入操作) 1. TCP三次握手 SYN ---> <--- SYN,ACK ACK ---> 花费时间: 386.718-385.784=0. ...
 - SQL中特殊符号的使用
			
1. & 在Oracle中,& 是从需要外部输入输入的变量,PS:MySqL中可以直接用"P&G"这样的字符串,故不存在本文所说的问题 如下SQL语句就不能 ...
 - Java 8 – Convert Instant to LocalDateTime
			
Java 8 examples to show you how to convert from Instant to LocalDateTime 1. Instant -> LocalDateT ...
 - 修改eclipse.ini文件指定jdk
			
在eclipse.ini文件顶部插入 -vmE:/kfgj/Java/jdk1.7.0_21/bin/javaw.exe
 - maven依赖包冲突解决办法
			
今天在写一个demo时报了以下错误 SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding /slf4j-lo ...