美文网首页
iOS 开发 ijkplayer-ios 编译 支持https

iOS 开发 ijkplayer-ios 编译 支持https

作者: yuanfeiyang | 来源:发表于2021-07-19 10:28 被阅读0次

    iOS 开发 ijkplayer-ios 编译 支持https  ---看本文就够了

    ##1. 编译环境

    Mac OS Catalina 10.15.6

    Xcode 12.4

    ##2. 安装 homebrew, git, yasm工具

    ```

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    brew install git

    brew install yasm

    ```

    ##3. 从github上下载ijkplayer源码

    ```

    #进入到自己保存ijkplayer源代码位置路径

    cd /Users/system/Workspace/Github

    下载ijkplayer源代码

    git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios

    #进入源码目录

    cd ijkplayer-ios

    # 切换分支(目前最新版本为k0.8.8,可以在ijkplayer-ios根目录下找到NEWS.md文件可以查看最新版本号)

    git checkout -B latest k0.8.8

    ```

    ##4. 配置编解码器格式

    默认为最少支持, 如果足够你使用, 可跳过:

    module-default.sh 更多的编解码器/格式

    module-lite-hevc.sh 较少的编解码器/格式(包括hevc)

    module-lite.sh 较少的编解码器/格式(默认情况)

    ```

    # 进入 config目录

    cd config

    删除当前的 module.sh 文件

    rm module.sh

    # 可根据需要替换为`module-default.sh`,`module-lite-hevc.sh`,`module-lite.sh`

    # 创建软链接 module.sh 指向 module-lite-hevc.sh

    ln-s module-lite.sh module.sh

    cd..

    cd iOS

    清空历史编译记录(如果有编译过)

    sh compile-ffmpeg.sh clean

    ```

    ##5. 获取 ffmpeg 并初始化

    ###此过程需要从网上拉取ffmpeg,需要花些时间

    ```

    cd ..

    ./init-ios.sh

    ```

    ##6. 获取 openssl 并初始化(增加HTTPS支持)

    ###编译完openssl后会生成支持 https 的静态文件 libcrypto.a 和 libssl.a,如不需要支持HTTPS可跳过此步骤:

    ```

    ./init-ios-openssl.sh

    cd ios

    在模块文件中添加一行配置 以启用 openssl 组件

    # 模块文件:

    # module-default.sh 更多的编解码器/格式

    module-lite-hevc.sh 较少的编解码器/格式(包括hevc)

    module-lite.sh 较少的编解码器/格式(默认情况)

    echo 'export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-openssl"' >> ../config/module.sh

    ./compile-ffmpeg.sh clean

    ```

    ##7. 编译

    ```

    # 如果下一步提示错误`xcrun: error: SDK "iphoneos"cannot be located`,请执行`sudo xcode-select--switch/Applications/Xcode.app/Contents/Developer/`,再重新执行下一步

    # 编译openssl, 如不需要https可跳过

    ./compile-openssl.sh all

    编译ffmpeg

    ./compile-ffmpeg.sh all

    ```

    ###如果编译ffmpeg提示如下错误:

    ```

    ./libavutil/arm/asm.S:50:9: error: unknown directive

            .arch armv7-a

            ^

    make: *** [libavcodec/arm/aacpsdsp_neon.o] Error 1

    ```

    ###最新的 Xcode 环境中iOS SDK最低支持从iOS 8.0开始了,弱化了对 32 位iOS系统的支持,解决方法:

    ```

    在compile-ffmpeg.sh中删除armv7, 修改如:

    FF_ALL_ARCHS_IOS8_SDK="arm64 i386 x86_64"

    再重新执行出现错误的命令: 

    ./compile-ffmpeg.sh all

    ```

    ##8. 打开 IJKMediaDemo 项目

    ```

    open IJKMediaPlayer/IJKMediaPlayer.xcodeproj

    ```

    也可以手动用 Xcode 打开 ios 目录下的 IJKMediaPlayer 项目.

    ##9.此步骤为了处理集成后,编译可能报错的问题处理

    ###按目录找到文件夹位置并删除

    IJKMediaPlayer->Classes->IJKFFMoviePlayerController->ffmpeg->lib

    ###按照上面的可以看到该文件夹,然后鼠标右击delete->Remove References.

    ###接下来,重新把ffmpeg编译的库静态.a文件和include中的头文件拖进来,找到ijkplayer-ios存放的目录,我这里是:

    /Users/system/Workspace/Project/ijkplayer-ios

    ###然后进入到ijkplayer-ios下的ios/build/universal,可以看到include和lib两个文件夹,然后把他们拖到IJKMediaDemo刚才的位置中:

    IJKMediaPlayer->Classes->IJKFFMoviePlayerController->ffmpeg

    ###此步骤不执行,集成后编译运行将出现错误

    ##10.打包framwork并合并

    大家会发现除了IJKMediaFramework这个目标,还有一个叫IJKMediaFrameworkWithSSL,但是不推荐使用这个,因为大部分基于ijkplayer的第三方框架都是使用的前者,你把后者导入项目还是会报找不到包的错误,就算你要支持https也推荐使用前者,然后按照上一步添加openssl即可支持

    ###10.1 配置发布模式如下图

    配置发布模式1 配置发布模式2

    ###10.2 打包真机框架

    选择真机编译

    如图操作,然后按键命令+ B编译即可

    真机编译会出现如下错误

    真机编译报错

    问题:链接库“xxx.a”缺少此目标所需的一个或多个体系结构:arm64、armv7

    处理方法:

    真机编译报错解决

    如上图,在Target-Build Settings-Excluded Architectures中添加以下代码

    EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64=arm64 arm64e armv7 armv7s armv6 armv8 EXCLUDED_ARCHS=$(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT))

    ###10.3 打包模拟器 framework

    选择模拟器编译

    如图操作,然后命令+ B编译即可

    ###10.4 合并框架

    如果只需要真机运行或者模拟器运行,可以不用合并,直接找到对应的框架导入项目即可; 一般我们为了方便会合并框架,这样就同时支持模拟器和真机运行。

    先找到生成框架的目录:

    查看framework位置 编译后framework位置

    打开终端, 先 cd 到 Products 目录下

    然后执行: lipo -create 真机framework路径 模拟器framework路径 -output 合并的文件路径

    ```

    lipo -create Release-iphoneos/IJKMediaFramework.framework/IJKMediaFramework Release-iphonesimulator/IJKMediaFramework.framework/IJKMediaFramework -output IJKMediaFramework

    ```

    合并报错如图:

    合并报错

    解决如图:

    合并报错解决

    设置Build Setting --> Excluded Architectures --> Release --> 添加上 arm64  

    重新编译,再合并。

    ###10.5 合并完成

    可以看到这里生成了一个大概两倍大小的文件, 将生成的 IJKMediaFramework 文件替换掉 真机framework 中的 IJKMediaFramework 文件,然后这个替换掉文件的 真机framework 就是我们需要的 通用的framework 了。

    合并后的文件


    替换framework

    ###10.6 导入 framework

    直接将 IJKMediaFramework.framework 拖入到工程中即可

    注意记得勾选 Copy items if needed 和 对应的 target

    添加下列依赖到工程

    需要添加的依赖

    ###10.7  测试地址

    点播

    http://static.tripbe.com/videofiles/20121214/9533522808.f4v.mp4

    http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4

    https://media.w3.org/2010/05/sintel/trailer.mp4

    直播:

    http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8


    ##11. 在测试播放的时候,xcode会打印 Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState] 子线程刷新UI的问题。

    解决方法:

    Xcode 9以后增加了新特性“主线程检测器(Main Thread Checker)”,这样在运行IJK时,就会报IJKSDLGLView里面,子线程获取“UIApplication的applicationState”、layer。

    有些人的做法是关闭检测器,但这并没有从根本上解决问题,就应该将这些操作改成使用主线程进行操作,下面是我的做法,直接修改IJKSDLGLView的源码。

    ###11.1 首先,增加个只在主线程操作的方法,这个方法里面就是先判断当前是否在主线程,如果是就直接执行,否则同步切换到主队列进行执行。

    ```

    static void IJKHanleInMainThread(dispatch_block_t mainThreadblock) {

        if ([NSThread currentThread] == [NSThread mainThread]){

            mainThreadblock();

        } else {

            dispatch_sync(dispatch_get_main_queue(), ^{

                mainThreadblock();

            });

        }

    }

    ```

    ###11.2 其次将方法- (BOOL)isApplicationActive里面改成这样:

    ```

    __block UIApplicationState appState = 0;

                IJKHanleInMainThread(^{

                    appState = [UIApplication sharedApplication].applicationState;

                });

    ```

    将方法- (void)displayInternal: (SDL_VoutOverlay *) overlay里面改成这样

    ```

    IJKHanleInMainThread(^{

            [[self eaglLayer] setContentsScale:_scaleFactor];

        });

    IJKHanleInMainThread(^{

                [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];

            });

    ```

    最后执行IJK的demo,发现子线程操作UI的那些警告就没有了。这样重新编译生成静态库。


    ##注:本文参考文章

    https://www.jianshu.com/p/73d8f2b35cb4

    https://www.jianshu.com/p/9a69af13835e

    https://blog.csdn.net/qcx321/article/details/113527386

    https://blog.csdn.net/yst19910702/article/details/109597568

    https://blog.csdn.net/mlcldh/article/details/101155942

    相关文章

      网友评论

          本文标题:iOS 开发 ijkplayer-ios 编译 支持https

          本文链接:https://www.haomeiwen.com/subject/wdqfrltx.html