Skip to content

Latest commit

 

History

History
221 lines (157 loc) · 10.6 KB

BUILD_SO.md

File metadata and controls

221 lines (157 loc) · 10.6 KB
1、前言

为什么要编译?因为默认IJK居然不带HTTPS?Why?因为爱情,不会轻易悲伤···这就是爱吧((/- -)/。

编译IJK的动态链接库,绝对是对于win党最大的打击,经常是裤子脱了一半,发现拉链卡住,而且还很痛,上也不是,不上也不是的蛋碎感(ノಠ益ಠ)ノ彡┻━┻,官方都说了:on Cygwin (unmaintained),Linux和Mac的胜利。如果你坚持,也许你就会遇上它们:

  • 安装Cygwin的时候,记得把make选上。

  • $'\r': 未找到命令 : dos2unix xxx,把所有你会编译到的.sh都轮一遍,你以为完了?不,编译生成出来的version.sh和configure也需要。

  • mingw32-gcc.exe: error: CreateProcess: No such file or directory,据说是文件路径太深了,然而IJK的路径,本来就好深,所以你要把IJK的环境在整一遍,反正到这里我就放弃了治疗啦(ˉ ̄~) 。

2、VMware + Ubuntu编译环境

  如果作为一个win党,头顶青天,推荐把虚拟机搬出来了,一般装的是Ubuntu,加上VMtools,妥妥的,环境搭建我就不唠叨了,这里走起《VMware安装Ubuntu教程,Linux下搭建Android开发环境》。家中常备,总有一天你会用得上。注意NDK r10e以上,虚拟机硬盘尽量选大一点,不然后面扩展容量又是一番功夫。  

Mac 环境下编译也是完美,强烈推荐。(新版本 Mac 系统用旧版 ndk 会面临一些权限兼容问题,建议在设置上全部允许,弹出来的多点几次吧),建议用 sudo spctl --master-disable 来在 mac 上信任所有来源从而支持执行。 

ndk 版本必须是 android-ndk-r13b ,不要问为什么。 如果是新版 macOS,就用最低的 android-ndk-r10e 具体看你系统支持。

执行 sudo spctl --master-disable 关闭安全检验

  • 引用大佬问题分析: “这两天又把Ijkplayer捡起来,在macOS Monterey上编译带openssl的Ijkplayer,也遇到了和帖主一样的问题。通过谷歌找到了这。经过仔细分析,发现造成这个问题的原因是libcrypto.a这个静态库里缺少了一些函数的实现。阅读编译失败时的输出内容,发现失败的时候会有两个创建libcrypto.a这个库的动作,两次挨着的,成功的时候只有一次创建的日志。猜测是make多线程的问题,两个线程都在创建静态库,导致有一个线程失败了。找到do-compile-openssl.sh里设置make线程数的地方,发现是由IJK_MAKE_FLAG这个变量传递的,再搜索“IJK_MAKE_FLAG”,找到了是在do-detect-env.sh这个脚本里设置的,在Darwin(也就是苹果)平台上是通过系统命令“sysctl -n machdep.cpu.thread_count”来获取并设置编译线程数的,这里强制改成1,问题不再出现,应该是解决了。究其根本原因,猜测是Ijkplayer使用的这个版本的openssl的make文件写得不够严谨,导致多线程编译是有风险的。”
    具体为 android/contrib/tools/do-detect-env.sh 下的 IJK_MAKE_FLAG 改为 :export IJK_MAKE_FLAG=-j1

  • 还有需要注意,需要 python2 执行环境,mac 默认 python3 的话可以直接下载一个 python2 的安装包安装就好了

  • M1 机器可以参考 : https://www.jianshu.com/p/22405a692c18 , :/Users/xxx/env/android-sdk/ndk/android-ndk-xxxx/ndk-build 高版本:

      #!/bin/sh
      DIR="$(cd "$(dirname "$0")" && pwd)"
      $DIR/build/ndk-build "$@"
    
      修改为:
      #!/bin/sh
      DIR="$(cd "$(dirname "$0")" && pwd)"
      arch -x86_64 /bin/bash $DIR/build/ndk-build "$@"
    

    低版本

      HOST_ARCH=$(uname -m)
      case $HOST_ARCH in
          i?86) HOST_ARCH=x86;;
          x86_64|amd64) HOST_ARCH=x86_64;;
          *) echo "ERROR: Unknown host CPU architecture: $HOST_ARCH"
             exit 1
      esac
      log "HOST_ARCH=$HOST_ARCH"
      把 x86_64|amd64) 这里加一个,改成 x86_64|amd64|arm64)
    
  • 如果有出现 awk 过期的问题,去prebuilt/drawom-x86_64/bin 下把它删了就好

  • 在mac OS系统上编译,如果出现 yasm/nasm not found or too old. Use --disable-yasm for a crippled build.,安装就好了: brew install yasm

macOS 环境下新配置介绍:

默认情况下,IJKPlayer 推荐的是 android-ndk-r10e ,这也是我用它做例子的原因,因为它够“古老”,而在现在的 macOS 上,如果你想使用 android-ndk-r10e ,你「可能」需要:

  • 从网页下载,因为 Android Studio 的 SDK Manager 里不支持下载 r10
  • 配置 android-ndk-r10e 到环境变量 export ANDROID_NDK="$HOME/Library/Android/sdk/ndk/android-ndk-r10e"
  • 修改编译脚本, android/contrib/tools/do-detect-env.sh 下的 IJK_MAKE_FLAG 改为 :export IJK_MAKE_FLAG=-j1
  • 执行 sudo spctl --master-disable 关闭 macOS 的安全检验,在 mac 上信任所有来源从而支持执行。 
  • 将 python 环境变为默认 python2
  • 如果出现 awk 过期的问题,去 prebuilt/drawom-x86_64/bin 下把它删了
  • 如果出现 yasm/nasm not found or too old. Use --disable-yasm for a crippled build.,安装 brew install yasm
  • 如果 ndk-build 无法执行,可以修改 ./compile-ijk.sh 为:
       case $SUB_CMD in
         prof)
-            $ANDROID_NDK/ndk-build $FF_MAKEFLAGS
+           arch -x86_64 /bin/bash  $ANDROID_NDK/ndk-build $FF_MAKEFLAGS
         ;;
         clean)
-            $ANDROID_NDK/ndk-build clean
+           arch -x86_64 /bin/bash  $ANDROID_NDK/ndk-build clean
         ;;
         rebuild)
-            $ANDROID_NDK/ndk-build clean
-            $ANDROID_NDK/ndk-build $FF_MAKEFLAGS
+           arch -x86_64 /bin/bash  $ANDROID_NDK/ndk-build clean
+           arch -x86_64 /bin/bash  $ANDROID_NDK/ndk-build $FF_MAKEFLAGS
         ;;
         *)
-            $ANDROID_NDK/ndk-build $FF_MAKEFLAGS
+          arch -x86_64 /bin/bash   $ANDROID_NDK/ndk-build $FF_MAKEFLAGS
         ;;
     esac
 }

升级 r21

想通过 r21 编译,对于 IJKPlayer ,理论上你会遇到以下问题:

  • tools/do-detect-env.sh 文件下增加你想支持的 ndk 版本: 11*|12*|13*|14*|15*|16*|21*|22*|25*|26*|27*)
  • Bad file descriptor error: invalid argument '-std=c99 :此时你需要在所有 Android.mk 下将所有的 LOCAL_CFLAGS += -std=c99 去掉,因为 GCC 早在 r18 就被移除了
  • Invalid NDK_TOOLCHAIN_VERSION value: 4.9 :同样是因为 GCC 已经移除,所以需要将 Application.mk 下的 NDK_TOOLCHAIN_VERSION=4.9 移除
  • APP_STL := stlport_static is not supported :同样在 r18 的时候,stlport 也已经被移除,所以我们需要将 Application.mk 下的 APP_STL 修改为 APP_STL := c++_static ,采用 libc++ 实现
  • 从 r21开始 ndk-bundle/build/tools/make-standalone-toolchain.sh 中会调用 ndk-bundle/build/tools/make-standalone-toolchain.py ,所以需要把 tools/do-compile-ffmpeg.sh 下对应的 FF_ANDROID_PLATFORM 修改为 FF_ANDROID_PLATFORM=android-21 ,同理还是有 tools/do-compile-openssl.sh

升级 r22

升级到 r22 ,还需要添加 -WI,-Bsymbolic 来解决问题: FF_EXTRA_LDFLAGS="$FF_EXTRA_LDFLAGS -WI,-Bsymbolic"

新版本 FFMpeg

  • 升级之前,首先需要手动删除 contrib 下 openssl-arm64 文件
  • 然后修改 init-android-openssl 里的 git 链接和版本
  • 之后初始化后,修改 do-compile-openssl.sh 的 FF_CFG_FLAGS="$FF_CFG_FLAGS --prefix=$FF_PREFIX"
  • 最后编译 ffmpeg 的时候,调整 configure 文件的 check_lib openssl openssl/ssl.h OPENSSL_init_ssl -lssl -lcrypto

支持 16K 编译

https://juejin.cn/post/7396306532671094793

3、编译带HTTPS的so

到了这里你就简单多了,因为是亲生的啊,这时候就是机械化流程啦(✿‿)。

  • 打开终端命令,安装需要程序。
sudo apt-get install git
sudo apt-get install yasm
  • 下载IJKPlayer源码,在命令终端里cd到ijk的根目录
  • 切换到release版本的tag下,当然,你也可以直接在master
git checkout -B k0.7.5  //这个版本参考ijk的依赖库版本
  • 流程化脚本编译

1、编译前选择你的配置

If you prefer more codec/format

cd config
rm module.sh
ln -s module-default.sh module.sh

If you prefer less codec/format for smaller binary size (include hevc function)

cd config
rm module.sh
ln -s module-lite-hevc.sh module.sh

If you prefer less codec/format for smaller binary size (by default)

cd config
rm module.sh
ln -s module-lite.sh module.sh

2、初始化openSSL和FFMPEG

这里会同步下载对应的代码,所以可能会比较耗时哟,

./init-android-openssl.sh
./init-android.sh

3、编译

cd到android/contrib下,执行清除命令,然后编译需要的so,这里的all是生成所有版本的,如果只需要对应版本的,可以把all替换成armv7a等你需要的版本。编译需要一段时间,这时候你可以找个妹子先吹吹水。︿( ̄︶ ̄)︿

./compile-openssl.sh clean//清除
./compile-ffmpeg.sh clean//清除
./compile-openssl.sh all//编译
./compile-ffmpeg.sh all//编译

4、生成对应so

切换到android目录下,执行脚本就可以生成so啦,感觉一路顺畅,一泻千里有木有。

./compile-ijk.sh all

生成的so每种类型有三个,传说,ffmepg的so大于3M就是https成功的标志啦!

最后注意

1、最后不要忘记,在你的gradle里面加入下方的配置哟,不然app会找不到你的so的。

2、如果你觉得你的包so太大了,可以使用下图的ndk过滤,随时控制你想支持的so,具体可参看Android蹲坑的疑难杂症集锦(兼Gradle) 二

3、如果需要编译其他播放类型支持,可以修改module.sh下的配置来使能。

4、IJKplayer 编译rtsp、rmvb支持

相关的so已经集成到播放器里面,需要的可以直接拿出来用,下方链接走起<( ̄︶ ̄)>,点我点我。

https://github.com/CarGuo/GSYVideoPlayer

多日♂不见