您的位置:首页 > 移动开发 > Android开发

Android N MediaPlayer(一) : MediaMetadataRetriever分析

2017-08-16 17:21 537 查看
    MediaMetadataRetriever类方法

    用途:元数据(MetaData)获取

        获取多媒体文件中的元信息(metadata),eg. Album、Artist、Title、Year等信息,显示在UI界面。

        API说明:MediaMetadataRetriever class providesa unified interface for retrieving frame and meta data from an input
mediafile.

        MediaMetadataRetriever类提供了一个统一的接口用于从一个输入媒体文件中取得帧和元数据。

        API官方链接:

              http://developer.android.com/reference/android/media/MediaMetadataRetriever.html

 

一、MediaMetadataRetriever 的创建流程解析

   java-->JNI-->native层的flow

    java:frameworks\base\media\java\android\meida 

    --- Java API类android.media.MediaMetadataRetriever

       MediaMetadataRetriever.java

    jni:framwworks\base\media\jni

      android_media_MediaMetadataRetriever.cpp

    native:frameworks\av\media\

      (libmedia)--->Mediametadataretriever.cpp

      (libmediaplayerservice)-->MetadataRetrieverClient.cpp

    注释:

    应用程序开发者调用Java API类android.media.MediaMetadataRetriever,进而调用到JNI层。JNI层调用用C++类MediaMetadataRetriever,后者又使用IMediaMetadataRetriever接口强指针(实际指向)进行跨进程调用到MediaPlayerService中的MetadataRetrieverClient。MetadataRetrieverClient是一个wrapper(包裹)类,它通过创建不同的多媒体框架的Retriever来获取元数据信息。

 

在xxPlayer中,添加MediaMetadataRetriever的实现

1、java层的实现(部分内容)

        mMediaRetriver = new MediaMetadataRetriever();

        if(mMediaRetriver != null){

            try{

                mMediaRetriver.setDataSource(videoPath);

                String title = mMediaRetriver.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);

                Log.d(TAG, "title is "+ title);

                String album = mMediaRetriver.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM);  

            Log.d(TAG, "album:" + album);  

            String mime = mMediaRetriver.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);  

            Log.d(TAG, "mime:" + mime);  

            String artist = mMediaRetriver.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);  

            Log.d(TAG, "artist:" + artist);  

            String duration = mMediaRetriver.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);

            Log.d(TAG, "duration:" + duration);  

            String bitrate = mMediaRetriver.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE);

            Log.d(TAG, "bitrate:" +bitrate);  

            String date = mMediaRetriver.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE);  

            Log.d(TAG, "date:" + date);  

            }catch (IllegalArgumentException e) {

                e.printStackTrace();

            } catch (SecurityException e) {

                e.printStackTrace();

            } catch (IllegalStateException e) {

                e.printStackTrace();

            }

        }

2、native层的实现

staticsp<MediaMetadataRetrieverBase> createRetriever(player_type playerType)

{

   sp<MediaMetadataRetrieverBase> p;

   switch (playerType) {

        case STAGEFRIGHT_PLAYER:

        case NU_PLAYER:

        case xx_PLAYER:

        {

            p = newStagefrightMetadataRetriever;

            break;

        }

        default:

            // TODO:

           // support for TEST_PLAYER

            ALOGE("player type %d is notsupported",  playerType);

            break;

   }

   if (p == NULL) {

        ALOGE("failed to create aretriever object");

   }

   return p;

}

xxplayer中的创建flow

1、libmedia---setDataSource

./frameworks/av/media/libmedia/MediaMetadataRetriever.cpp-->setDataSource

status_tMediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)

{

    ALOGV("setDataSource(%d, %"PRId64 ", %" PRId64 ")", fd, offset, length);

    Mutex::Autolock _l(mLock);

    if (mRetriever == 0) {

        ALOGE("retriever is notinitialized");

        return INVALID_OPERATION;

    }

    if (fd < 0 || offset < 0 || length< 0) {

        ALOGE("Invalid negativeargument");

        return UNKNOWN_ERROR;

    }

   
return mRetriever->setDataSource(fd, offset, length);


}

2、libmediaplayerservice---setDataSource中创建createRetriever

./frameworks/av/media/libmediaplayerservice/MetadataRetrieverClient.cpp-->setDataSource

status_tMetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t length)

{

   ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld",

            fd, nameForFd(fd).c_str(), (longlong) offset, (long long) length);

   Mutex::Autolock lock(mLock);

   struct stat sb;

   int ret = fstat(fd, &sb);

   if (ret != 0) {

        ALOGE("fstat(%d) failed: %d,%s", fd, ret, strerror(errno));

        return BAD_VALUE;

   }

    ……

   player_type playerType =

        MediaPlayerFactory::getPlayerType(NULL/* client */,

                                          fd,

                                         offset,

                                         length);

   ALOGV("player type = %d", playerType);

   //根据playerType创建Retriever。

    sp<MediaMetadataRetrieverBase> p =createRetriever(playerType);

   if (p == NULL) {

        return NO_INIT;

   }

    //进入StagefrightMetadataRetriever的setDataSource

   status_t status = p->setDataSource(fd,offset, length);

   if (status == NO_ERROR) mRetriever = p;

   return status;

}

./frameworks/av/media/libmediaplayerservice/MetadataRetrieverClient.cpp --->createRetriever

函数功能:根据playertype, 创建相应的Retriever,这里只有StagefrightMetadataRetriever

staticsp<MediaMetadataRetrieverBase> createRetriever(player_type playerType)

{

   sp<MediaMetadataRetrieverBase> p;

   switch (playerType) {

        case STAGEFRIGHT_PLAYER:

        case NU_PLAYER:

        case xx_PLAYER:

        {

        
   p = newStagefrightMetadataRetriever;


            break;

        }

        default:

            // TODO:

           // support for TEST_PLAYER

            ALOGE("player type %d is notsupported",  playerType);

            break;

   }

   if (p == NULL) {

        ALOGE("failed to create aretriever object");

   }

   return p;

}

./frameworks/av/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp --->setDataSource()

函数功能:Retriever中,创建extractor

status_tStagefrightMetadataRetriever::setDataSource(

        int fd, int64_t offset, int64_t length){

   fd = dup(fd);

   clearMetadata();

   mSource = new FileSource(fd, offset, length);

   status_t err;

   if ((err = mSource->initCheck()) != OK) {

        mSource.clear(); 

        return err;

   }

   mExtractor= MediaExtractor::Create(mSource);

……

}

 

后续MediaExtractor的创建见文:Android N MediaPlayer (二):MediaExtractor创建flow
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: