小白學習android mediaPlayer過程的記錄

     爲了督促自己對於android MediaPlayer部分的學習與理解,簡單的貼出自己逐步學習的過程歡迎大家一起探討,以及大牛的指導

     第一天20170410:

     看源碼的方法是通過點擊studio的MediaPlayer進入。

      

  public class MediaPlayer implements SubtitleController.Listener
  簡單的點進入SubtitleController 看了下,感覺是實現了對於MediaPlayer中的視圖部分的控制(個人猜想)
  在看具體的代碼前,看一下MediaPlayer的功能流程

這個是mediaPlayer的功能過程,從直觀上理解我們可以從一個播放器的使用流程來考慮問題
最初一個播放器是處於空閒狀態的(將這個播放器理解爲一個容器),這時候我們需要加載一部影片我們需要
像這個容器中加入視頻的數據(視頻數據的格式不同,且有各種加入方式,因爲是播放和加載的同步進行如何
控制視頻數據的正確加入是一個坑,此處後續要看看)。
當一個容器獲取到足夠的資源時,我們要對這個狀態進行確認。
這個準備的過程可以是一個異步的操作(據瞭解這塊有的android版本會有坑點)。
資源就緒了,這時候就要研究一下播放的功能,正常播放對於視頻流操作的方法主要是,開始,暫停,快進,停止。這些功能實現了
視頻播放流程,但是具體的實現每個方法有很多細節(此處需看一下mediaPlayer中具體的實現的原理)。

簡單的順了一下media的使用流程,第一步我們先看下對於加入數據這一步,mediaPlayer是如何的實現的。

常規思路,一個視頻第一步加載時的數據有很多,包括視頻數據和音頻數據,視頻數據要想展示在畫面上也需要
畫在屏幕上。
    開始我的小白琢磨代碼的旅程。
    因爲還不確定,setDateSource這一過程中所做的工作,計劃從create開始看起control+f12看一下包含
oncreate的方法。
有三種方法,所傳入的參數不同,逐個查看實現的過程,
 //第一個create中傳入的參數只有context,和一個整數型數據,(因爲開始需要有表面的視圖變換,以及
內在的數據傳入 ,姑且在此時認爲是某個控件的Id)
 public static MediaPlayer create(Context context, int resid) {
        try {
            //認爲這裏是讓context獲取資源信息的過程
            AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
            if (afd == null) return null;
            //創建了mediaPlayer對象
            MediaPlayer mp = new MediaPlayer();
            mediaPlayer設置了數據
            mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            //afd這個東西爲什麼在這一步close?這時候說明之前的判斷不太正確。
            afd.close();
            //走到這一步mediaplayer已經到了prepare的狀態
            mp.prepare();
            return mp;
        } catch (IOException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "create failed:", ex);
           // fall through
        } catch (SecurityException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        }
        return null;
    }
簡單看了第一個再看下第二個
    public static MediaPlayer create(Context context, Uri uri) {
    //這個的區別是第二個參數不同,第二種以url定位控件的情景還沒有想出來,返回值多了一個參數
        return create (context, uri, null);
    }
    public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder) {
    //這個地方多了一個SurfaceHolder,介紹說這個是用來顯示視頻的
        try {
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(context, uri);
            這個地方進行了判空操作,猜想這個地方是沒有釋放播放器時候開始播放
            if (holder != null) {
                mp.setDisplay(holder);
            }
            mp.prepare();
            return mp;
        } catch (IOException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        } catch (SecurityException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        }

        return null;
    }
今天暫時就先看這些
20170415今天終於偷得浮生半日閒繼續咱的計劃 沒偷成,忙了一下午。
總體上不看細節大致就是創建播放器然後set資源,看一下創建播放器的過程。
    public MediaPlayer() {

        Looper looper;
        //在線程中執行,會優先判斷子線程
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }
        //推測:時間控制,標題控制
        mTimeProvider = new TimeProvider(this);
        mOutOfBandSubtitleTracks = new Vector<SubtitleTrack>();
        mOpenSubtitleSources = new Vector<InputStream>();
        mInbandSubtitleTracks = new SubtitleTrack[0];

        /* Native setup requires a weak reference to our object.
         * It's easier to create it here than in C++.
         */
        //從註釋中看這裏要實現更底層c++的實現
        native_setup(new WeakReference<MediaPlayer>(this));
    }

看一下在線程做的事情,可以判斷爲對操作事件的判斷響應(這個後續研究對視頻的操作的時候研究)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章