[时间: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的官方文档。

参考资料

  1. Google Android MediaPlayer
  2. Android多媒体MediaPlayer使用详解

Android MediaPlayer接口及状态迁移的更多相关文章

  1. android MediaPlayer API大全已经方法详解(转载)

    通过这张图,我们可以知道一个MediaPlayer对象有以下的状态: 1)当一个MediaPlayer对象被刚刚用new操作符创建或是调用了reset()方法后,它就处于Idle状态.当调用了rele ...

  2. Android MediaPlayer状态机

    对播放音频/视频文件和流的控制是通过一个状态机来管理的.下图显示一个MediaPlayer对象被支持的播放控制操作驱动的生命周期和状态.椭圆代表MediaPlayer对象可能驻留的状态.弧线表示驱动M ...

  3. 学习Android MediaPlayer

    Android Media Playback 原文 The Android multimedia framework includes support for playing variety of c ...

  4. 翻译的很好的一篇android mediaplayer

    MediaPlayer类可用于控制音频/视频文件或流的播放.关于如何使用这个类的方法还可以阅读VideoView类的文档. 1.状态图对播放音频/视频文件和流的控制是通过一个状态机来管理的.下图显示一 ...

  5. Android MediaPlayer和VideoView的使用

          MediaPlayer MediaPlayer类是Androd多媒体框架中的一个重要组件,通过该类,我们可以以最小的步骤来获取,解码和播放音视频.它支持三种不同的媒体来源: 本地资源 内部 ...

  6. [转]Android MediaPlayer状态机

    翻译Android Reference Manual的MediaPlayer的状态机 对播放音频/视频文件和流的控制是通过一个状态机来管理的.下图显示一个MediaPlayer对象被支持的播放控制操作 ...

  7. Android MediaPlayer 在 6.0 以上版本使用倍速播放功能说明

    Android MediaPlayer 在API 23即6.0版本开始支持倍速播放,下面我们来介绍一下如何使用MediaPlayer进行倍速播放. 一.核心接口 MediaPlayer.setPlay ...

  8. Android MediaPlayer的生命周期

    MediaPlayer的状态转换图也表征了它的生命周期,如下: 这张状态转换图清晰的描述了MediaPlayer的各个状态,也列举了主要的方法的调用时序,每种方法只能在一些特定的状态下使用,如果使用时 ...

  9. Android MediaPlayer Error/Info Code

    1. 常见错误 error(-38, 0) 我觉得-38表示在当前的MediaPlayer状态下,不能运行你的操作. 详细怎样做请參考:Android MediaPlayer 另外我在其它资料中.发现 ...

随机推荐

  1. windows下如何生成gitlab ssh公钥

    1.查看是否已经有了ssh密钥:cd ~/.ssh如果没有密钥则不会有此文件夹,有则备份删除2.生存密钥: $ ssh-keygen -t rsa -C “你的邮箱”按3个回车,密码为空. Your ...

  2. Rust hello world !

    特点: 安全,速度,并发 文件:hello_world.rs 代码: fn main() { println!("hello world!"); } 执行:rustc hello_ ...

  3. VS与SQL资源

    经常在网上看到有同学费尽心思的找SQL server数据库各版本的下载地址,看到别人的求助贴就不自觉的想去帮助他们,但是一个一个去帮助又不太现实,毕竟个人精力有限,既然大家有需求,那么笔者就本着乐于分 ...

  4. MySQL -- 外键创建失败

    使用show engine innodb status\G 查看数据库状态的时候,发现以下报错信息: ------------------------ LATEST FOREIGN KEY ERROR ...

  5. Android之内存泄露、内存溢出、内存抖动分析

      内存   JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆.栈和方法区.栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放.优点:速度快.堆(heap) ...

  6. sql server中QUOTENAME()函数的用法

    操作sql server尤其是写存储过程时,要用到各种各样的函数,今天就总结一个quotename()的用法. 1.语法: quotename('character_string'[,'quote_c ...

  7. junit 用法实例

    package com.zy.junit.test; import org.junit.After;import org.junit.AfterClass;import org.junit.Befor ...

  8. python 多进程,实际上都没有运行,sleep

    进程以及状态 1. 进程程序:例如xxx.py这是程序,是一个静态的 进程:一个程序运行起来后,代码+用到的资源 称之为进程,它是操作系统分配资源的基本单元. 不仅可以通过线程完成多任务,进程也是可以 ...

  9. 温故而知新 前端日志上传新姿势 navigator.sendBeacon(信标)

    原文地址:https://mp.weixin.qq.com/s/-moAfEZicrFmun4qfWLdOQ 简单示例js: var data = JSON.stringify({ name: 'Be ...

  10. CentOS7.2安装pure-ftpd 及其配置项

    CentOS7.2安装FTP(pure-ftpd-1.0.43) 原文链接: https://www.linuxidc.com/Linux/2016-10/135971.htm [日期:2016-10 ...