java - Android的MediaPlayer是如何通过检查原生代码来工作的?

标签 java android android-ndk java-native-interface android-mediaplayer

检查 MediaPlayer ( link ) 的源代码,start() 方法如下所示:

public  void start() throws IllegalStateException {
        stayAwake(true);
        _start();
}

_start() 方法如下所示:

private native void _start() throws IllegalStateException;

检查 native _start() 方法 ( link )(称为 start() 但不应调用 _start()因为 native 调用被命名为_start()?):

status_t MediaPlayer::start()
{
    ALOGV("start");
    Mutex::Autolock _l(mLock);
    if (mCurrentState & MEDIA_PLAYER_STARTED)
        return NO_ERROR;
    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
                    MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
        mPlayer->setLooping(mLoop);
        mPlayer->setVolume(mLeftVolume, mRightVolume);
        mPlayer->setAuxEffectSendLevel(mSendLevel);
        mCurrentState = MEDIA_PLAYER_STARTED;
        status_t ret = mPlayer->start();
        if (ret != NO_ERROR) {
            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
        } else {
            if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
                ALOGV("playback completed immediately following start()");
            }
        }
        return ret;
    }
    ALOGE("start called in state %d", mCurrentState);
    return INVALID_OPERATION;
}

数据从哪里读取?我想检查 Android 如何与 RTSP 配合使用,但我找不到它加载数据的位置。我想知道它是否使用像 FFMpeg 这样的库或其他实现。

编辑:

为什么这段代码需要使用 JNI?

最佳答案

以下所有路径均引用 src/frameworks/base/。

在 media/jni/android_media_MediaPlayer.cpp 中,您将找到将 Java 方法调用转发到底层 native 框架的 JNI 代码。您可以在 gMethods[] 数组和文件底部附近的 AndroidRuntime::registerNativeMethods 调用中看到名称映射。您可以阅读有关使用 JNI 注册 native 方法的更多信息 here ,但这并不是真正有趣的部分。

在此阶段,我们处于 Java MediaPlayer 的 native 对应部分。在大多数情况下,它也没有做任何有趣的事情。它通过 IBinder 事务绑定(bind)到 MediaPlayerServiceMediaPlayerService 根据媒体类型创建实际 native 播放器,并维护一个客户端 (MediaPlayerService::Client) 以便于与媒体进行通信原生 MediaPlayer,它又将内容返回到 Java。您可以在以下文件中看到所有这些发生的情况(如果您感兴趣的话):

media/libmedia/mediaplayer.cpp, media/libmedia/IMediaPlayer.cpp, media/libmedia/IMediaPlayerClient.cpp, media/libmedia/IMediaPlayerService.cpp, media/libmediaplayerservice/MediaPlayerService.cpp

libmedia 的头文件位于 include/media/libmedia/中。

现在到了真正有趣的部分,即组件玩家。在 MediaServicePlayer.cpp 中有几个 getPlayerType 方法来决定要实例化的播放器。有 Stagefright 框架(AwesomePlayer 和 NuPlayer)和用于 MIDI 的 Sonivox 播放器。对于 RTSP,您将得到 NuPlayer。您可以在 media/libmediaplayerservice/nuplayer/中找到粘合层,并在 media/libstagefright/和 media/libstagefright/rtsp/中找到所有真正的源代码。

关于java - Android的MediaPlayer是如何通过检查原生代码来工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19491125/

相关文章:

java - 从整数数组中得到奇怪的结果

android - 在 Android 上使用网络

android - 想在 Android 中使用 Python 库

android - 高性能音频破解/防止 CPU 内核降频

java - 为什么我的类(class)没有加载

java - 如何使用java解析yaml注释?

java - 调用 Ant 时如何在 Jenkins GUI 中设置 Java 系统属性?

android - 创建自定义号码选择器

android - 什么会导致 Android 上的 SQLite 错误代码 778

android - ndk-gdb 无法找到 gdb.setup