Android集成IjkPlayer


0x0000 背景

  • 項(xiàng)目需要引入直播功能,而Android原生的VideoView本身是不支持RTMP格式的流媒體播放的。
  • 市面上的開源播放器還是挺好選擇的,相比較于IjkPlayer,其他例如Vitamio、VLC的SDK無論使用便利性還是社區(qū)的支持都差得遠(yuǎn),自己用ffmpeg寫成本難以接受。
  • 但是!IjkPlayer在Github上的README文檔真心坑,完全按那個(gè)文檔做連編譯都過不了。。
  • 阿里巴巴20年春招啟動!歡迎有想法的同學(xué)勾搭!詳見文末二維碼,Android/Java/前端都要!

0x0001 致謝


0x0002 源碼鏈接

Github:Bilibili/ijkplayer


0x0003 編譯

  • 安裝homebrew、git、yasm
    非核心內(nèi)容,請自行百度或谷歌
  • 配置Android SDK、NDK環(huán)境變量,在.bash_profile增加如下兩行
export ANDROID_SDK=/your/sdk/path
export ANDROID_NDK=/your/ndk/path
  • 下載源碼
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android
cd ijkplayer-android
git checkout -B latest k0.7.8.1
  • 初始化
./init-android.sh
  • 編譯ffmpeg
cd android/contrib
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
  • 編譯IjkPlayer
cd ..
./compile-ijk.sh all

到此為止,完成了對源碼的編譯,ijkplayer-android的目錄結(jié)構(gòu)如圖


工程結(jié)構(gòu)

0x0004 配置

  • 拷貝gradle文件
    復(fù)制/android/ijkplayer/tools文件夾到工程根目錄
  • 在工程根目錄下的build.gradle文件中增加配置
ext {
    compileSdkVersion = 25
    buildToolsVersion = "25.0.2"
    targetSdkVersion = 25
    versionCode = 700801
    versionName = "0.7.8.1"
}

前三條和你的app module的build.gradle保持一致
后兩條和IjkPlayer源碼工程中的build.gradle保持一致

  • 依賴關(guān)系
    回到剛才我們編譯成功的源碼目錄,如果將/android/ijkplayer作為一個(gè)新項(xiàng)目導(dǎo)入Android Studio,運(yùn)行ijkplayer-example,是可以作為一個(gè)獨(dú)立app run起來的
    我們先把example加入工程:
    File-New-Import Module-/android/ijkplayer/ijkplayer-example
    當(dāng)然我們希望能把IjkPlayer當(dāng)做一個(gè)第三方庫引入,而不是在example工程的基礎(chǔ)上實(shí)現(xiàn)我們的需求,那么就需要搞清楚各個(gè)module的依賴關(guān)系:


    各module依賴關(guān)系

    說的直白一點(diǎn),arm64等5個(gè)module一看命名大家就明白是基于不同CPU編譯產(chǎn)出的so
    為了簡化依賴,我們把這幾個(gè)module的so文件拷貝到example module下,同時(shí)刪除這幾個(gè)module,完成后的example目錄結(jié)構(gòu)如圖


    example目錄結(jié)構(gòu)
  • 改造example module
    現(xiàn)在的example module是作為application存在的,如果要作為library引入,要處理以下三點(diǎn)


    調(diào)整example build.gradle

    example增加gradle.properties
  • 加入依賴庫
    File-Project Structure-app-Dependencies-添加ijkplayer-example


    依賴example module

0x0005 開發(fā)

IjkVideoView本身繼承自FrameLayout,可以和普通的View一樣在layout的xml文件中直接加入
對大多數(shù)人來說,平時(shí)怎么使用VideoView,現(xiàn)在就怎么使用IjkVideoView即可


0x0006 問題

  • 如何讓播放器填滿IjkVideoView展示
    改造SurfaceRenderView的onMeasure方法
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (this.getWidth() != 0) {
        setMeasuredDimension(this.getWidth(), this.getHeight());
        return;
    }
    int width = getDefaultSize(0, widthMeasureSpec);
    int height = getDefaultSize(0, heightMeasureSpec);
    setMeasuredDimension(width, height);
}
  • 啟動之后crash
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

在AndroidManifest.xml中設(shè)置Activity的theme屬性

<activity
    android:name=".MainActivity"
    android:theme="@style/Theme.AppCompat.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
  • 視頻流截圖(適用于api14+)
    IjkVideoView改造setRender
public void setRender(int render) {
    switch (render) {
        case RENDER_NONE:
            setRenderView(null);
            break;
        case RENDER_SURFACE_VIEW:
        case RENDER_TEXTURE_VIEW: {
            TextureRenderView renderView = new TextureRenderView(getContext());
            if (mMediaPlayer != null) {
                renderView.getSurfaceHolder().bindToMediaPlayer(mMediaPlayer);
                renderView.setVideoSize(mMediaPlayer.getVideoWidth(), mMediaPlayer.getVideoHeight());
                renderView.setVideoSampleAspectRatio(mMediaPlayer.getVideoSarNum(), mMediaPlayer.getVideoSarDen());
                renderView.setAspectRatio(mCurrentAspectRatio);
            }
            setRenderView(renderView);
            break;
        }
        default:
            Log.e(TAG, String.format(Locale.getDefault(), "invalid render %d\n", render));
            break;
    }
}

增加一個(gè)public方法

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
public Bitmap getShortcut() {
    if (mRenderView instanceof TextureRenderView) {
        return ((TextureRenderView) mRenderView).getBitmap();
    }
    return null;
}

0x0007 后記

Android播放器的坑太多,慢慢踩,與君共勉
阿里巴巴20年春招,請用支付寶掃碼投遞簡歷


阿里校招.jpeg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,326評論 25 708
  • afinalAfinal是一個(gè)android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,898評論 2 45
  • 每天給自己一個(gè)時(shí)間空間了解自己 昨天我們說“當(dāng)你擺對位置你的世界就對了”。我們來看企業(yè)的“企”字,企業(yè)止于人。一個(gè)...
    家銘老師閱讀 289評論 0 0
  • 五一的假期,有多少人奔走在回家的路上?車站交錯(cuò)的人群中有你嗎?我是其中一人。 有人說你想了解真正的自己嗎?那就去旅...
    浮語泛花閱讀 545評論 4 2
  • 今天是2017年7月1日,我在這個(gè)房子里住了一個(gè)星期。 迄今為止,這個(gè)家里來過兩個(gè)訪客,一個(gè)是政穎,一個(gè)是絲基。 ...
    玖_編號7913閱讀 293評論 0 0

友情鏈接更多精彩內(nèi)容