1. 程式人生 > >如何寫一個播放器-解析MNVideoPlayer(一)

如何寫一個播放器-解析MNVideoPlayer(一)

注:本文適合初學Android或未接觸過系統自帶的MediaPlayer人群,閱讀之前請下載相關程式碼

在瞭解MediaPlayer編寫之前,讓我們參考一下已翻譯資料,瞭解一下它有哪些方法:

主要涉及類:MediaPlayer
(1) 當一個MediaPlayer物件被建立或者呼叫reset()方法之後,它處於空閒狀態,呼叫release()方法後處於結束狀態
1,一個MediaPlayer物件呼叫了reset()方法後,再呼叫其它方法可能會觸發OnErrorListener.onError()事件,未呼叫reset()方法則不會觸發
2,當Mediaplayer物件不再被使用時,最好呼叫release()方法對其進行釋放,使其處於結束狀態,此時它不能被使用
3,Mediaplayer物件被建立時(呼叫構造方法)處於空閒狀態,若使用create()方法建立後則處於準備狀態。
(2) 一般情況下,一些常用的播放控制操作可能因為音訊、視訊的格式不被支援或者質量較差以及流超時,也有可能由於開發者的疏忽使得Mediaplayer物件處於無效狀態等而導致錯誤。此時可通過註冊setOnErrorListener方法實現監控。如果發生了錯誤,Mediaplayer物件將處於多霧狀態,可以使用reset()方法來回復錯誤。
(3) 任何Mediaplayer物件都必須先處於準備狀態,然後才開始播放
(4) 要開始播放Mediaplayer物件都必須成功呼叫start()方法,可通過isPlaying()方法來檢測是否正在播放
(5) 當Mediaplayer物件在播放時,可以進行暫停和停止操作,pause()方法暫停播放,stop()方法停止播放。處於暫停暫停時可通過start()方法恢復播放,但是處於停止狀態時則必須先呼叫prepare()方法使其處於準備狀態,再呼叫start()方法。
主要方法:
Mediaplayer:構造方法
create:        建立一個要播放的多媒體
getCurrentPosition:得到當前播放位置
getDuration:    得到檔案的時間
prepare:    準備(同步)
prepareAsync:準備(非同步)
seekTo:        指定播放的位置(以毫秒為單位)
setAudioStreamType:    設定流媒體的型別
setDataSource:    設定資料來源
setDisplay:        設定用SurfaceHolder來顯示多媒體
setOnBufferingUpdateListener:    網路流媒體的緩衝監聽
setOnErrorListener:            設定錯誤資訊監聽
setOnVideoSizeChangedListener:視訊尺寸監聽
setScreenOnWhilePlaying:        設定是否使用SurfaceHolder來顯示
setVolume:                    設定音量
//獲取sd卡上的音訊檔案
setDataSource(“/sdcard/test.mp3”);
//裝載資源中的音樂
MediaPlayer.create(Activity01.this,R.raw.test);
//目前存在問題,不能迴圈解析出音訊檔案
原因:.android_secure資料夾受保護,無法獲取裡面的檔案資訊
播放視訊
相關類:VideoView
方法說明:
getBufferPercentage:得到緩衝的百分比
getCurrentPosition:得到當前播放位置
getDuration:得到視訊檔案的時間
resolveAdjustedSize:調整視訊顯示大小
setMediaController:設定播放控制器模式(播放進度條)
setOnCompletionListener:當視訊檔案播放完時觸發事件
setVideoPath:設定視訊源路徑
setVideoURI:設定視訊源地址 
上述方法及其描述轉自部落格水漫金山的部落格:https://www.cnblogs.com/dyllove98/p/3192090.html

MNVideoPlayer比較方便的地方在於,你可以直接例項化new出來,也可以在layout檔案中直接引用,我們以後寫控制元件也儘量做到這一點

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#e2e2e2"
    android:orientation="vertical">

    <com.maning.mnvideoplayerlibrary.player.MNViderPlayer
        android:id="@+id/mn_videoplayer"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#363636"
        app:mnFirstNeedPlay="false" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:onClick="btn01"
        android:text="地址1" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:onClick="btn02"
        android:text="地址2 --- 直接播放指定的位置" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:onClick="btn03"
        android:text="地址3---錯誤地址" />

</LinearLayout>

在MainActivity中進行Player的例項化
mnViderPlayer = (MNViderPlayer) findViewById(R.id.mn_videoplayer);
之後進行Player的相關設定

電量監聽(個人感覺沒什麼必要,但是也有可能產品就需要呢):

mnViderPlayer.setIsNeedBatteryListen(true);
網路監聽(這個很重要,後面我們瞭解了之後,這裡可以做各種DIY):
mnViderPlayer.setIsNeedNetChangeListen(true);
設定資料來源,通過前面的瞭解,我們知道MediaPlayer不但支援本地檔案,還支援網路檔案:
mnViderPlayer.setDataSource(url2, "標題2");
播放完監聽(注意:此demo所用的播放結束監聽為系統提供的onCompletion方法,但是在一些情況如Error時,也會觸發系統的onCompletion方法,所以一定要注意,我自己就沒有用系統的方法,但是跟專案中所用的方式方法衝突,所以在後面遇到了相關講解時我再細緻的告訴大家如何優雅的結束視訊****很簡單,做個定時器,當播放時間等於總時間時,延時一秒結束即可):
 //播放完成監聽
        mnViderPlayer.setOnCompletionListener(new MNViderPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {
                Log.i(TAG, "播放完成----");
            }
        });

此demo視訊暫停放在了系統的onPause方法中:
@Override
    protected void onPause() {
        super.onPause();
        mnViderPlayer.pauseVideo();
    }
視訊銷燬:
@Override
    protected void onDestroy() {
        //一定要記得銷燬View
        if(mnViderPlayer != null){
            mnViderPlayer.destroyVideo();
            mnViderPlayer = null;
        }
        super.onDestroy();
    }

OK,MainActivity中的相關引用就這樣,非常簡單,我們前期瞭解到這裡就可以,但是在實際專案中並沒有這麼簡單,下一章我將為大家詳細的解析MNVideoPlayer的原始碼以及其中哪些地方容易遇到相容性問題,以及類似播放結束這種不容易碰到的內部問題。