现在的位置: 首页 > 综合 > 正文

Android MultiMedia之MediaPlayer

2013年10月27日 ⁄ 综合 ⁄ 共 5453字 ⁄ 字号 评论关闭

本文主要是从宏观上把握Android MediaPlayer的架构,尽量做到简洁,希望对感兴趣的朋友有所帮助。


(1)BBinder/BpBinder类图


说明:

a. 需要使用Android智能指针管理对象生命周期的类必须继承自Refbase;

b. BBinder用于server端,BpBinder用于client端。

注:关于Binder的知识,参见Android Binder之经典好文

(2)BnInterface/BpInterface类图

(3)MediaPlayerService类图


说明:

a. BnMediaPlayerService 为MediaPlayerService在server端的具体实现;

b. BpMediaPlayerService为MediaPlayerService在client端的具体代理;

c. 通过BpMediaPlayerService(通过ServiceManager可以获取到BpMediaPlayerService)可以享用MediaPlayerService所提供的服务(具体由BnMediaPlayerService实际完成)

d. 通过BpMediaPlayerService可以获取到IMediaRecorder、IMediaMetadataRetriever、IMediaPlayer、IOMX在client端的代理类BpXXX(IMediaRecorder、IMediaMetadataRetriever、IMediaPlayer、IOMX,这些皆是Bp和Bn的共同接口,和MediaPlayerService一样,都有Bp和Bn构成)。

(4)MediaPlayer类图

说明:

a. BpMediaPlayer为通过BpMediaPlayerService获取到的MediaPlayer在client端的代理类;

b. MediaPlayerService::Client为MediaPlayer在server的具体实现类。

(5)MediaPlayerClient类图

说明:

a. IMediaPlayerClient由BpMediaPlayerClien和BnMediaPlayerClien组成;

b. BnMediaPlayerService 和 MediaPlayerService::Client(即BnMediaPlayer)通过BpMediaPlayerClien向BnMediaPlayerClien发送消息。

// IMediaPlayerService.h

class IMediaPlayerService: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayerService);

    virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0;
    virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0;
    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId = 0) = 0;
};

// ----------------------------------------------------------------------------

class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

// IMediaPlayerService.cpp

class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
{
};

IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");

// MediaPlayerService.h

class MediaPlayerService : public BnMediaPlayerService
{
};

// IMediaPlayer.h

class IMediaPlayer: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayer);

    virtual status_t        setDataSource(const char *url,
                                    const KeyedVector<String8, String8>* headers) = 0;
  
    virtual status_t        prepareAsync() = 0;
    virtual status_t        start() = 0;
    virtual status_t        stop() = 0; // 后面还有一系列关于player的接口函数
};

// ----------------------------------------------------------------------------

class BnMediaPlayer: public BnInterface<IMediaPlayer>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

// IMediaPlayer.cpp

class BpMediaPlayer: public BpInterface<IMediaPlayer>
{
public:
    BpMediaPlayer(const sp<IBinder>& impl)
        : BpInterface<IMediaPlayer>(impl)
    {
    }

    // disconnect from media player service
    void disconnect()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
        remote()->transact(DISCONNECT, data, &reply);
    }

    status_t setDataSource(const char* url,
            const KeyedVector<String8, String8>* headers)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
        data.writeCString(url);
        if (headers == NULL) {
            data.writeInt32(0);
        } else {
            // serialize the headers
            data.writeInt32(headers->size());
            for (size_t i = 0; i < headers->size(); ++i) {
                data.writeString8(headers->keyAt(i));
                data.writeString8(headers->valueAt(i));
            }
        }
        remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
        return reply.readInt32();
    }

    // 后面还有一系列关于player的接口函数

};

IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");

// MediaPlayerService.h

class MediaPlayerService::Client : public BnMediaPlayer 
{
};

// MediaPlayer.h

class MediaPlayer : public BnMediaPlayerClient,
                    public virtual IMediaDeathNotifier
{
public:
    MediaPlayer();
    ~MediaPlayer();

    status_t        setDataSource(
            const char *url,
            const KeyedVector<String8, String8> *headers);


    status_t        setListener(const sp<MediaPlayerListener>& listener);
    status_t        prepare();
    status_t        prepareAsync();
    status_t        start();
    status_t        stop(); // 后面还有一系列关于player的接口函数

private:
    sp<IMediaPlayer>            mPlayer;
};

// IMediaPlayerClient.h 

class IMediaPlayerClient: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayerClient);

    virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
};

// ----------------------------------------------------------------------------

class BnMediaPlayerClient: public BnInterface<IMediaPlayerClient>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

// IMediaPlayerClient.cpp

class BpMediaPlayerClient: public BpInterface<IMediaPlayerClient>
{
public:
    BpMediaPlayerClient(const sp<IBinder>& impl)
        : BpInterface<IMediaPlayerClient>(impl)
    {
    }

    virtual void notify(int msg, int ext1, int ext2, const Parcel *obj)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayerClient::getInterfaceDescriptor());
        data.writeInt32(msg);
        data.writeInt32(ext1);
        data.writeInt32(ext2);
        if (obj && obj->dataSize() > 0) {
            data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize());
        }
        remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY);
    }
};

IMPLEMENT_META_INTERFACE(MediaPlayerClient, "android.media.IMediaPlayerClient");

// ----------------------------------------------------------------------

status_t BnMediaPlayerClient::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case NOTIFY: {
            CHECK_INTERFACE(IMediaPlayerClient, data, reply);
            int msg = data.readInt32();
            int ext1 = data.readInt32();
            int ext2 = data.readInt32();
            Parcel obj;
            if (data.dataAvail() > 0) {
                obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
            }

            notify(msg, ext1, ext2, &obj);
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

// MediaPlayer.h

class MediaPlayer : public BnMediaPlayerClient,
                    public virtual IMediaDeathNotifier
{
private:
    sp<IMediaPlayer>            mPlayer; // 用于保存BpMediaPlayer实例
};

抱歉!评论已关闭.