MediaPlayer是Android最基礎(chǔ)的播放器姨蝴,一般播放本地文件就會使用MediaPlayer打颤;
關(guān)于MediaPlayer的基礎(chǔ)用法的相關(guān)文章到處都是,本文就不在詳細(xì)解說了枉层;
Mediaplayer的使用贰拿,主要是記住他的狀態(tài)機(jī)
下面來一起看一下他的內(nèi)部實(shí)現(xiàn)
參考文檔:
MediaPlayer框架概述
上面這個(gè)網(wǎng)站講的還是比較清楚的
1.java framwork層的MediaPlayer.java通過JNI調(diào)用android_media_mediaplayer.cpp的方法规哪,在native framwork層映射了一個(gè)MediaPlayer.cpp,
2.MediaPlayer.cpp 和MediaPlayerService之間一對aidl
3.MediaPlayerService內(nèi)部實(shí)現(xiàn)會交給NuPlayer
4.NuPlayer才是實(shí)際去進(jìn)行視頻播放的播放器求豫,NuPlayer會把視頻資源分解成AudioTrack和VideoTrack
5.VideoTrack交給SurfaceFlinger去處理
6.AudioTrack交給AudioFlinger去處理;
7.最終形成視頻播放;
關(guān)鍵類都在這個(gè)下面
NuPlayer源碼解析:
參考文檔:
NuPlayer源碼分析(一)
NuPlayer源碼分析(二)
status_t NuPlayer::GenericSource::initFromDataSource() {
...
/* 創(chuàng)建數(shù)據(jù)提取器 */
extractor = MediaExtractor::Create(mDataSource,
mSniffedMIME.empty() ? NULL: mSniffedMIME.c_str());
...
/* 分離音視頻track */
for (size_t i = 0; i < numtracks; ++i) {
sp<MediaSource> track = extractor->getTrack(i);
if (track == NULL) {
continue;
}
sp<MetaData> meta = extractor->getTrackMetaData(i);
const char *mime;
CHECK(meta->findCString(kKeyMIMEType, &mime));
// Do the string compare immediately with "mime",
// we can't assume "mime" would stay valid after another
// extractor operation, some extractors might modify meta
// during getTrack() and make it invalid.
if (!strncasecmp(mime, "audio/", 6)) {
if (mAudioTrack.mSource == NULL) {
mAudioTrack.mIndex = i;
mAudioTrack.mSource = track;
mAudioTrack.mPackets =
new AnotherPacketSource(mAudioTrack.mSource->getFormat());
if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
mAudioIsVorbis = true;
} else {
mAudioIsVorbis = false;
}
}
} else if (!strncasecmp(mime, "video/", 6)) {
if (mVideoTrack.mSource == NULL) {
mVideoTrack.mIndex = i;
mVideoTrack.mSource = track;
mVideoTrack.mPackets =
new AnotherPacketSource(mVideoTrack.mSource->getFormat());
// check if the source requires secure buffers
int32_t secure;
if (meta->findInt32(kKeyRequiresSecureBuffers, &secure)
&& secure) {
mIsSecure = true;
if (mUIDValid) {
extractor->setUID(mUID);
}
}
}
}
...
}
}