• 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的状态图如下:
    MediaPlayer state diagram

    这个状态图对应的java层的MediaPlayer。不过可以参考,在实际的源码实现时,不会完全参考这个状态图,可能有更多的内部状态和简化状态。
    比如,你可以不调用prepare,直接调用start。
    图中各个状态的迁移,建议参考MediaPlayer的官方文档。

    参考资料

    1. Google Android MediaPlayer
    2. Android多媒体MediaPlayer使用详解
  • 相关阅读:
    js中异步方案比较完整版(callback,promise,generator,async)
    10分钟搞懂toString和valueOf函数(详细版)
    Angular ViewChild
    Angular动画
    Angular组件之间的通讯
    用12个例子全面示范Angular的模板语法
    使用c++为node.js扩展模块
    requestAnimationFrame 实现JS动画
    使用CSS修改HTML5 input placeholder颜色
    js数组的方法
  • 原文地址:https://www.cnblogs.com/tocy/p/android-mediaplayer-interface-state-intro.html
Copyright © 2020-2023  润新知