广告也精彩
目录

前言

不同项目不同需求,有些客户接受平台限制的音视频解码格式,但如果作为外销,那就需要支持更多的,因此扩展音视频支持的格式。

引入第三方的so库有如下几种方式:

  1. APP直接使用第三方开源的so库
  2. 在framework层进行集成

第一种方式简单,开源的也比较多,比如bilibili的ijkplayer,google的ExoPlayer,以及还有VLC-Android,各有优缺点;至于用第二种方式,这个就比较麻烦些,目前我没有移植过,后续可能会尝试一下。

本文主要是简单的介绍记录一下,编译bilibili/ijkPlayer,编译教程官方上都有详细描述。

编译环境:Ubuntu 18.3

正文

ijkplayer 官方

官方GitHub的仓库:https://github.com/bilibili/ijkplayer

编译ijkplayer

搭建Ubuntu

如果你有现成的Ubuntu,那就跳过。

我是用Workstation 14 Pro虚拟机(自己百度)。

Ubuntu下载链接:http://old-releases.ubuntu.com/releases/

安装编译环境

  1. 安装git 这个就不多说了 都懂的
  1. 安装JDK
sudo apt-get install openjdk-8-jdk

配置环境变量

sudo gedit  /etc/profile 

# 末尾加入如下内容
export  JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

一般情况,为了刷新更改的配置,可以使用如下命令

source /etc/profile
  1. 安装SDK

下载Linux版的SDK:

  1. http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
  2. https://pan.baidu.com/s/1mhTCTja

两个都可以下载,速度都很快。

上传到Ubuntu并解压,然后配置一下/etc/profile。

sudo gedit  /etc/profile 

# 末尾加入如下内容
export ANDROID_SDK=/home/water/AndroidPlayer/sdk_ndk/android-sdk-linux
export PATH=${PATH}:$ANDROID_SDK/tools:$ANDROID_SDK/platform-tools

PS: 记得修改为你自己的路径咯。

一般情况,为了刷新更改的配置,可以使用如下命令

source /etc/profile
  1. 安装NDK

google官方下载NDK,由于IJKPlayer编译不需要最新的NDK,因此我们需要下载历史的NDK版本。

NDK链接:https://developer.android.google.cn/ndk/downloads/older_releases

上面链接中有各种版本,但我们需要下载android-ndk-r14b,这个版本我是编译ok的。

上传到Ubuntu并解压,然后配置一下/etc/profile。

sudo gedit  /etc/profile 
# 末尾加入如下内容

export ANDROID_NDK=/home/water/AndroidPlayer/sdk_ndk/android-ndk-r14b
export PATH=$ANDROID_NDK:$PATH

PS: 记得修改为你自己的路径咯。

一般情况,为了刷新更改的配置,可以使用如下命令

source /etc/profile

综合上诉,我们的环境都配置完成了,下面展示我配置的完整文件。

......
//开头的略

#JDK
export  JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

#SDK
export ANDROID_SDK=/home/water/AndroidPlayer/sdk_ndk/android-sdk-linux
export PATH=${PATH}:$ANDROID_SDK/tools:$ANDROID_SDK/platform-tools

#NDK
export ANDROID_NDK=/home/water/AndroidPlayer/sdk_ndk/android-ndk-r14b
export PATH=$ANDROID_NDK:$PATH

下载ijkplayer-android

在需要创建仓库的目录执行如下命令

  1. 下载ijkplayer-android
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android

执行后会出现一个ijkplayer-android目录

  1. 初始化FFmpeg和IjkPlayer代码
# 进入刚才拉取的仓库
cd ijkplayer-android

# 拉取代码
./init-android.sh

拉取代码看网速,有时候很快有时候很慢。

./init-android.sh: line 37: cd: android/contrib/ffmpeg-armv7a: No such file or directory

如果类似上诉的提示出错(基本是网络问题),那就一直使用init-android.sh初始化,直到拉取完成。

  1. 配置ffmpeg信息
cd config 

默认的配置如下:

module-default.sh
module-lite-hevc.sh
module-lite.sh
module.sh -> module-lite.sh

从上面知道,module.sh是软引用文件,用的module-lite.sh,这个是比较小的一种配置。

如果你需要修改,可以用下面命令修改:

# 删除之前的软引用
rm -r module.sh

# 新创建软引用
ln -s module-default.sh module.sh

编译 ffmpeg 代码

接着上面,由于我们之前在config目录,因此需要回退一下,在进入对应的编译目录。

cd ..

cd android/contrib/

# 一般先clean,再编译对应的so库,我们这里只armv7a 

./compile-ffmpeg.sh clean

./compile-ffmpeg.sh armv7a

执行上面就可以编译了,直到提示编译ok。

下面讲解一下./compile-ffmpeg.sh所有的命令可带的参数:

compile-ffmpeg.sh armv5|armv7a|arm64|x86|x86_64
compile-ffmpeg.sh all|all32
compile-ffmpeg.sh all64
compile-ffmpeg.sh clean
compile-ffmpeg.sh check

编译ijkplayer so库

在上面基础上,回退到android目录

cd ..

# 上面只编译armv7a
./compile-ijk.sh armv7a

提示成功,就编译完成了。

我们编译成功的so库就在:

android/ijkplayer/ijkplayer-armv7a/src/main/libs/armeabi-v7a/

由于我们编译的是默认的配置,因此so库都比较大。

使用so库

PS: 我这里只使用so库,IjkPlayer的demo我就不导入AS了。

把armeabi-v7a整个目录复制到对应工程的libs中。

然后在build.gradle中配置一下:

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

编译时遇到的问题

下面就简单的列举我遇到的问题。

问题一: Failed to create toolchain.

build on Linux x86_64
ANDROID_NDK=/home/water/ijkdir/ndk-sdk-tool/android-ndk-r14b
IJK_NDK_REL=14.1.3816874
NDKr14.1.3816874 detected
HOST_OS=linux
HOST_EXE=
HOST_ARCH=x86_64
HOST_TAG=linux-x86_64
HOST_NUM_CPUS=4
BUILD_NUM_CPUS=8
Auto-config: --arch=arm
ERROR: Failed to create toolchain.

解决方式:

apt-get install python

然后重新编译即可

问题二:disable-ffserver

开始编译FFmpeg时出现:

/home/water/AndroidPlayer/ijkplayer-dir/ttt/ijkplayer-android/android/contrib/build/ffmpeg-armv7a/toolchain/bin//arm-linux-androideabi-gcc
Unknown option "--disable-ffserver".
See ./configure --help for available options.

解决方式:

修改config中软引用的配置文件,从上面知道我们使用的是默认的编译文件module-default.sh

修改后,git diff module-default.sh 时显示的,注释掉[--disable-ffserver]

-export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffserver"
+# delete water
+#export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffserver"

问题三:--disable-vda

修改上面问题后,重新编译时

/home/liuys/AndroidPlayer/ijkplayer-dir/ttt/ijkplayer-android/android/contrib/build/ffmpeg-armv7a/toolchain/bin//arm-linux-androideabi-gcc
Unknown option "--disable-vda".
See ./configure --help for available options.

解决方式跟上面一下,也是注释掉[--disable-vda]

git diff module-default.sh 时显示的

-export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-vda"
+# water delete
+#export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-vda"

问题四first use in this function

上面我们只编译armv7a就出现上面问题,但如果我编译all时,还出现如下问题(日志节选):

/home/water/AndroidPlayer/ijkplayer-dir/ijkplayer-android/android/contrib/build/ffmpeg-arm64/toolchain/sysroot/usr/include/asm-generic/termbits.h:142:0: note: this is the   location of the previous definition
 #define B0 0000000

libavcodec/hevc_mvs.c:208:15: error: 'y0000000' undeclared (first use in this function)
libavcodec/hevc_mvs.c:207:15: error: 'x0000000' undeclared (first use in this function)

上面提示了B0已经在termbits.h中宏定义了。所以FFmpeg中B0就变成了0000000。

参考网上的,有两种方式解决问题。

  1. 把\ijkplayer-master\android\contrib\ffmpeg-arm64\libavcodec的opus_pvq.c和hevc_mvs.c,将B0替换成b0 (我选用的是这种方式,编译通过)
  2. 将系统文件里面的#B0注释掉之后再编译 (没有验证,但不建议)

参考文章

  1. ijkplayer
  2. Android JNI 篇 - 编译 bilibili/ijkPlayer
  3. ijkplayer遇到的问题合集
  4. 编译ijkplayer时出现Failed to create toolchain

 历史上的今天

版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站文章: 部分来源于网络,仅供站长学习和参考,若侵权请留言
广告也精彩

相关文章

广告也精彩

1 条评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

暂无评论...

网站升级中

公告

近期网站升级中,可能存在一些bug。欢迎反馈 https://www.91es.com/we.html

本站域名

本站域名 : 91es.com3xcn.com。本站邮箱 : 站长邮箱 i@oorr.cn,通知邮箱we@oorr.cn ,如有更新,请看公告 。