美文网首页
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