美文网首页
MediaPlayer基础使用

MediaPlayer基础使用

作者: 重新起步 | 来源:发表于2023-02-08 19:23 被阅读0次

MediaPlayer是Android最基础的播放器,一般播放本地文件就会使用MediaPlayer;
关于MediaPlayer的基础用法的相关文章到处都是,本文就不在详细解说了;
Mediaplayer的使用,主要是记住他的状态机


image.png

下面来一起看一下他的内部实现


image.png

参考文档:
MediaPlayer框架概述
上面这个网站讲的还是比较清楚的
1.java framwork层的MediaPlayer.java通过JNI调用android_media_mediaplayer.cpp的方法,在native framwork层映射了一个MediaPlayer.cpp,
2.MediaPlayer.cpp 和MediaPlayerService之间一对aidl
3.MediaPlayerService内部实现会交给NuPlayer
4.NuPlayer才是实际去进行视频播放的播放器,NuPlayer会把视频资源分解成AudioTrack和VideoTrack
5.VideoTrack交给SurfaceFlinger去处理
6.AudioTrack交给AudioFlinger去处理;
7.最终形成视频播放;
关键类都在这个下面

image.png image.png

NuPlayer源码解析:
参考文档:
NuPlayer源码分析(一)
NuPlayer源码分析(二)

status_t NuPlayer::GenericSource::initFromDataSource() {
    ...
    /* 创建数据提取器 */
    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);
                    }
                }
            }
        }
        ...
    }
}

相关文章

网友评论

      本文标题:MediaPlayer基础使用

      本文链接:https://www.haomeiwen.com/subject/imrfkdtx.html