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
用途:元数据(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
相关文章推荐
- Android JB MediaPlayer MediaPlayerService Binder 构建 分析
- Android MediaPlayer 分析 - service端文件结构
- Android Media Player 框架分析-Nuplayer(1)
- Android MediaPlayer 分析- MediaPlayerService.cpp
- Android MediaPlayer 分析 - client库
- android mediaPlayer error (-38,0)
- Android MediaCodec 状态(States)转换分析
- Android MediaPlayer之视频预加载
- android mediaplayer and mediaplayerservice的小说明
- Android播放器框架分析之AwesomePlayer
- Android多媒体开发【1】-- 利用SurfaceView + MediaPlayer开发最简单的视频播放器
- android开发SurfaceView+MediaPlayer实现视频播放
- android MediaPlayer 出…
- android Mediaplayer各种属性和方法简单介绍
- 【Android】- MediaPlayer错误之MediaPlayer start called in state 0
- Android MediaPlayer如何设置宽高
- Android MediaPlayer使用方法简单介绍
- android MediaPlayer
- Android Mediaplayer+sufaceView
- Android MediaPlayer基本使用方式