ijkplayer编译和使用

这段时间研究视频播放功能,android系统自带的播放器功能少,
支持的视频格式又有限制,只能放弃,网上一些成熟的第三方库商用后收费,
几番寻找后发现免费的开源库ijkplayer,这是Bilibili的一款基于ffmpeg视频编解码库的
轻量级Android/IOS播放器控件,Bilibili作为我大天朝最大异(tong)性交友平台,对开源界也是有贡献的。
ijkplayer提供了录制、转换以及流化音视频的完整解决方案,
可以开发出弹幕,视频旋转,位移,缩放控制,视频宽高比例设置,视频进度等功能。
但实践过程中遇到了很多坑,官方文档又不详尽,比如视频的多种格式支持,cpu架构的兼容等问题。
网上编译的so库也是存在问题,无奈之下,只能自己重新去编译一遍ijkplayer的源码。

准备工作

系统环境

linux环境:Ubuntu 18.04 (window下使用cygwin坑更多)
Android NDK:android-ndk-r14b
注意:此项目目前最高支持NDK14的版本,以上版本编译时报错:You need the NDKr9 or later
如果不能确定linux是64还是32位,打开终端:Ctrl+Alt+T,输入:sudo uname –m,结果为i686为32位,X86_64则为64位
Android SDK:选择Linux的版本

配置环境变量

方法一:(推荐)
打开主文件夹目录,按Ctrl+H打开隐藏文件,找到.bashrc文件,打开
在最后加上你自己的android ndk和android sdk的路径,比如我的:

1
2
3
4
5
ANDROID_NDK=/home/threetree/Downloads/android-ndk-r14b
export ANDROID_NDK
ANDROID_SDK=/home/threetree/Downloads/android-sdk-linux
export ANDROID_SDK
PATH=${PATH}:${ANDROID_NDK}:${ANDROID_SDK}

保存完成

方法二
在终端使用:sudo gedit /etc/profile(这里我遇到使用vi,vim指令打开文件进行修改,无法修改只读文件)
在配置文件末尾加入如下部分并保存:

1
2
export PATH=~/Downloads/android-sdk-linux:$PATH
export PATH=~/Downloads/android-ndk-r14b:$PATH

让环境变量立即生效
source /etc/profile

测试sdk是否配置成功:
adb -version
如未安装adb,根据提示安装adb,安装完成后重复上面指令

测试ndk是否配置成功:
ndk-build -v

安装若干软件

1
2
3
4
sudo apt-get install openjdk-8-jre-headless
sudo apt-get update
sudo apt-get install git
sudo apt-get install yasm

下载ijkplayer-android(最新版为k0.8.8)

下载ijkplayer源代码:

1
2
3
4
cd
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android
cd ijkplayer-android
git checkout -B latest k0.8.8

下载相关的android ffmpeg源代码:
./init-android.sh

如果视频播放需要支持Https协议的还需要执行一遍如下初始化脚本:
./init-android-openssl.sh

下载过程可能需要一段时间,去撸几局炉石传说吧~

开始编译

如果视频播放不需要支持Https协议,可跳过这一步

编译各个平台的openssl

1
2
cd android/contrib
./compile-openssl.sh clean

全平台编译:
./compile-openssl.sh all

分平台编译:

1
2
3
4
5
./compile-openssl.sh armv7a
./compile-openssl.sh armv5
./compile-openssl.sh arm64
./compile-openssl.sh x86
./compile-openssl.sh x86_64

编译各个平台的ffmpeg(坑最多的就是这一步啦)

选择解码包

根据官方的说法,我们根据需要选择解码包,
默认的情况是较少的codec/format,生成较小尺寸的包。
选择默认,可以跳过这一步。

在默认基础上包含hevc功能,执行下面命令:

1
2
3
4
cd ../..
cd config/
rm module.sh
ln -s module-lite-hevc.sh module.sh

最多的codec/format,执行下面命令:

1
2
3
4
cd ../..
cd config/
rm module.sh
ln -s module-default.sh module.sh

编译ffmpeg

1
2
3
cd ..
cd android/contrib/
./compile-ffmpeg.sh clean

选择平台,执行相应的命令:

1
2
3
4
5
6
./compile-ffmpeg.sh all
./compile-ffmpeg.sh armv7a
./compile-ffmpeg.sh armv5
./compile-ffmpeg.sh arm64
./compile-ffmpeg.sh x86
./compile-ffmpeg.sh x86_64

如果一切顺利,恭喜你

如报错:fatal error: linux/perf_event.h: No such file or directory
执行:$ vim ~/ijkplayer-android/config/module.sh
在结尾加入这一行:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-linux-perf"
保存后重新clean,重新编译

如报错:ERROR: Failed to create toolchain.
sudo apt-get install python
安装python后再执行编译即可

编译ijkplayer native代码

选择平台,执行相应的命令:

1
2
3
4
5
6
./compile-ijk.sh all
./compile-ijk.sh armv7a
./compile-ijk.sh armv5a
./compile-ijk.sh arm64
./compile-ijk.sh x86
./compile-ijk.sh x86_64

编译好后就能在android/ijkplayer目录中,找到libs
里面就是我们需要的编译好的so库

开始使用

开始精简工程,将官方demo里相关的文件拿来使用
找到下载好的ijkplayer源码,找到目录android-》ijkplayer-》ijkplayer-example
找到里面的java源码,根据下图文件,导入到我们自己的工程:
ijkplayer

接下来把我们编译好的so库文件引入到相应cpu架构的文件夹下面

稍微配置下gradle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "com.muyan.ijk"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
//设置支持的SO库架构
abiFilters "armeabi-v7a", "x86","arm64-v8a","x86_64"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}

根据平台,添加相应的依赖:

1
2
3
4
5
6
7
8
    compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'

// compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
// compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
// compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
// compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8'

简单的使用IjkVideoView:
xml:

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--播放控件 IjkVideoView -->
<com.muyan.ijk.media.IjkVideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

javaCode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
		mVideoView = (IjkVideoView) findViewById(R.id.video_view);

/** 普通播放 start **/
mVideoView.setAspectRatio(IRenderView.AR_ASPECT_FIT_PARENT);

String url5 = "http://stream1.grtn.cn/tvs2/sd/live.m3u8?_ts&time=1518428696629";
// mVideoView.setVideoURI(Uri.parse(url5));//播放流

String name = "city.avi";
// String name = "mars2.mp4";
// String name = "dog.flv"
mVideoView.setVideoPath(FileUtil.getAdFilePath(name));//播放本地视频

mVideoView.start();

这一切之后,简单的播放多种格式视频的demo就跑起来了,
接下来,根据业务以及ijkplayer相关的api开始开发吧

坚持原创分享,您的支持将鼓励我继续创作!