1. 程式人生 > >音訊開發ijkplayer小結 android

音訊開發ijkplayer小結 android

1. Gradle匯入

# required
allprojects {
    repositories {
        jcenter()
    }
}

dependencies {
    # required, enough for most devices.
    compile 'tv.danmaku.ijk.media:ijkplayer-java:0.5.0'
    compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.5.0'

    # Other ABIs: optional
    compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.5.0'
compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.5.0' compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.5.0' compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.5.0' # ExoPlayer as IMediaPlayer: optional, experimental compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.5.0' }

2. ijkplayer支援的操作:

1. 目前支援MediaPlayer的基本操作且引數一致如:

public native boolean isPlaying(); 
public native void seekTo(long msec) throws IllegalStateException;
public native long getCurrentPosition();
public native long getDuration();
public void pause() throws IllegalStateException 
public void prepareAsync() throws IllegalStateException
public void start
() throws IllegalStateException

這些方法位於IjkMediaPlayer類中,最終實現是由jni呼叫底層c++程式碼。當然還有些高階用法,這裡給大家同時挖個坑,因為我也只使用了基本的功能。

2. 小坑:

MediaPlayer的isPlaying條件 : (1)playing 正在播放
ijkplayer的isPlaying 方法返回為true條件是: (1)prepare or (2)playing 正在播放
下面是c++原始碼:

 if (mp->mp_state == MP_STATE_PREPARED ||
        mp->mp_state == MP_STATE_STARTED) {
        return true;
    }

3. CallBack 回撥介面也是基本一致的。

interface OnPreparedListener {
        void onPrepared(IMediaPlayer mp);
    }

    interface OnCompletionListener {
        void onCompletion(IMediaPlayer mp);
    }

    interface OnBufferingUpdateListener {
        void onBufferingUpdate(IMediaPlayer mp, int percent);
    }

    interface OnSeekCompleteListener {
        void onSeekComplete(IMediaPlayer mp);
    }

    interface OnVideoSizeChangedListener {
        void onVideoSizeChanged(IMediaPlayer mp, int width, int height,
                                int sar_num, int sar_den);
    }

    interface OnErrorListener {
        boolean onError(IMediaPlayer mp, int what, int extra);
    }

    interface OnInfoListener {
        boolean onInfo(IMediaPlayer mp, int what, int extra);
    }

3. 特殊需求,這個與player無關。

1. 耳機插拔監聽,比如耳機拔掉時關閉播放器。可參考:

2. 切換音訊源或播放其他資源時暫停等需求。

具體是實現AudioManager.OnAudioFocusChangeListener介面方法:
public void onAudioFocusChange(int focusChange)
繼續偷下懶,就不在重複寫了。細節問題需要給位看官根據實際情形做決定:
http://www.jianshu.com/p/32a67329307e

4 最近遇到的一個大坑:ANR

哎,沒遇到ANR Android程式猿的人生是不完整的,最近使用0.4.5版時,由於產品需要切換播放源,如果快速切換,就會造成ANR,主要原因是由於,切換是釋放資源我呼叫了其reset(),該方法在主執行緒釋放資源超時。目前我看官方issue的建議是,重新new 一個ijkMeadiaPlayer,不呼叫reset,只調用release()方法。也有人提到使用線上程中reset。 我的一個workaround是延遲執行操作。