播放音视频的核心类 MediaPlayer

MediaPlayer是android播放音视频的库,我们常见播放视频的组件VideoView对MediaPlayer进行了封装,通过MediaPlayer.java类提供的接口,对视频进行相应的操作。例如,播放,暂停,获取视频的长宽,媒体文件时间等等。但这些功能的真正实现也不是在MediaPlayer.java中,而是在本地代码C++,MediaPlayer.cpp中实现的。这里就涉及到了jni的知识,可以参考《Java语言如何与本地代码(C/C++)交互》这篇文章http://www.jianshu.com/writer#/notebooks/12418576/notes/20268367

MediaPlayer.java是通过动态库media_jni.so对C++代码进行操作的,功能真正的实现是在MediaPlayer.cpp中

image.png

MediaPlayer.java中声明的本地方法如下所示,具体实现在MediaPlayer.cpp中。

image.png

image.png

MediaPlayer.java声明的相关接口如下所示,当java代码想要了解C++代码中当前操作的视频情况时,可以通过如下接口了解。


image.png

本地代码MediaPlayer.cpp传递消息给MediaPlayer.java,是通过MediaPlayer.java中的方法postEventFromNative(...),该代码是在子线程中执行的,因此想更新消息需要通过Handler把消息转移都主线程。该方法被回调时,通过Handler把消息转移到主线程,然后根据消息的类型回调上面的接口,现在已经弄明白以上接口是在哪里回调的啦,现在具体看看postEventFromNative的代码,如下所示:

//mediaplayer_ref表示播放器的弱引用对象
//what表示相应消息的代码值。
//arg1,arg2,obj表示传递的相应消息。

 private static void postEventFromNative(Object mediaplayer_ref,
                                        int what, int arg1, int arg2, Object obj)
{
      //静态方法对外部类不存在引用,所有这里需要获取一个对象。
    MediaPlayer mp = (MediaPlayer)((WeakReference)mediaplayer_ref).get();
    if (mp == null) {
        return;
    }

    if (what == MEDIA_INFO && arg1 == MEDIA_INFO_STARTED_AS_NEXT) {
        // this acquires the wakelock if needed, and sets the client side state
        mp.start();
    }
    //获取MediaPlayer.java中的Handler,mEventHandler。
    if (mp.mEventHandler != null) {
       //Handler发送消息
        Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj);
        mp.mEventHandler.sendMessage(m);
    }
}

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 166,823评论 24 703
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 5,415评论 0 17
  • 今天终于可以回家接孩子了,进门时孩子正在火炉旁玩,他尚处于咿呀学语阶段,扭头看到我的那一刻,欣喜已全在脸上,虽然只...
    Fantali阅读 90评论 0 1