0x0000 背景
- 項目需要引入直播功能,而Android原生的VideoView本身是不支持RTMP格式的流媒體播放的瞬女。
- 市面上的開源播放器還是挺好選擇的,相比較于IjkPlayer,其他例如Vitamio咐蝇、VLC的SDK無論使用便利性還是社區(qū)的支持都差得遠(yuǎn),自己用ffmpeg寫成本難以接受巷查。
- 但是嘹害!IjkPlayer在Github上的README文檔真心坑,完全按那個文檔做連編譯都過不了吮便。笔呀。
- 阿里巴巴20年春招啟動!歡迎有想法的同學(xué)勾搭髓需!詳見文末二維碼许师,Android/Java/前端都要!
0x0001 致謝
- 感謝Bilibili工程師的無私開源
- 本博文參照了:
Android Studio中如何將ijkplayer 0.6.3導(dǎo)入自己的項目中并使用
感謝hisonedumobile博主 - 轉(zhuǎn)載請注明
作者和平北路
原文點擊鏈接
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)如圖
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作為一個新項目導(dǎo)入Android Studio俯逾,運行ijkplayer-example,是可以作為一個獨立app run起來的
我們先把example加入工程:
File-New-Import Module-/android/ijkplayer/ijkplayer-example
當(dāng)然我們希望能把IjkPlayer當(dāng)做一個第三方庫引入舅逸,而不是在example工程的基礎(chǔ)上實現(xiàn)我們的需求桌肴,那么就需要搞清楚各個module的依賴關(guān)系:
說的直白一點,arm64等5個module一看命名大家就明白是基于不同CPU編譯產(chǎn)出的so
為了簡化依賴琉历,我們把這幾個module的so文件拷貝到example module下坠七,同時刪除這幾個module,完成后的example目錄結(jié)構(gòu)如圖
-
改造example module
現(xiàn)在的example module是作為application存在的旗笔,如果要作為library引入彪置,要處理以下三點
-
加入依賴庫
File-Project Structure-app-Dependencies-添加ijkplayer-example
0x0005 開發(fā)
IjkVideoView本身繼承自FrameLayout,可以和普通的View一樣在layout的xml文件中直接加入
對大多數(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;
}
}
增加一個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年春招的猛,請用支付寶掃碼投遞簡歷