Build FFmpeg+rist for iOS

对比了RTSP、SRT、RIST几个协议之后,最终选用RIST作为我们的设备音视频传输协议;ffmpeg在4.4以后才支持rist,OBS也要2.8.0以后才行,VLC要4.0版本才能支持;
因为rist是一个比较新的流媒体传输协议,所以在使用的时候遇到了不少问题,这里记录一下编译rist进ffmpeg遇到的问题;
librist官网:https://code.videolan.org/rist/librist

* 设置rist环境路径

将librist.pc放在/usr/local/lib/pkgconfig路径下,这个librist.pc是rist build的产物,终端输入以下命令可以下载并编译librist,执行完之后,会在/usr/local/lib下生成一个librist.a静态库,/usr/local/include目录下产生头文件;

git clone https://code.videolan.org/rist/librist.git && \

cd librist && \

mkdir build && \

cd build && \

meson .. --default-library=static --buildtype=release -Db_lto=true && \

ninja install

设置环境变量,终端输入:

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH

修改librist.pc,因为cjson是可选的库,所以为了保证顺利编译成功,libs先干掉-lcjson;修改完成后的如下;

image

// 第一次踩坑

1、编译ffmpeg+rist

脚本下载地址: https://github.com/kewlbear/FFmpeg-iOS-build-script

image
image

macOS 解决 No package 'openssl' found 错误

configure删除openssl、librist的require_pkg_config判断;

暂时没用到audiotoolbox,全部先注释了; --disable-audiotoolbox --disable-videotoolbox

image

metal也不需要用到,删了就可以;

image

需要重新配置openssl路径信息,需要在/usr/local目录下创建opt目录,把brew install的openssl拖进该目录下;

Mac 操作系统 fatal error: 'openssl/ssl.h' file not found

简单解决:fatal error: ‘openssl/***.h‘ file not found等综合疑难问题-pudn.com

image
image
image

Makefile删除下面的:

OBJS-$(CONFIG_YADIF_VIDEOTOOLBOX_FILTER) += vf_yadif_videotoolbox.o \

metal/vf_yadif_videotoolbox.metallib.o \

metal/utils.o \

yadif_common.o

2、使用Rist

编译得到FFmpeg-iOS,直接拖入工程中,配置头文件目录,静态库地址;

image
image

编译:

image
image

尝试引入rist、openssl源码

image

设置header search path

image

新的问题

image

因为之前是把audiotoolbox.m的文件都注释了,所以此处找不到,放开ff_audiotoolbox_muxer,然后重新输入./build-ffmpeg.sh编译,导入新的库,编译通过;

image

跑起来了,可以open成功;

但是崩溃在find_stream了,怀疑是没有加入ff_audiotoolbox_muxer的原因,又绕回来了;

断言在avpriv_packet_list_put;

image.png

前面暴力删除audiotoolbox的办法看来不可行,只能针对audiotoolbox缺什么补什么了

问题点:修复audiotoolbox的报错,新增以下代码

typedef UInt32  AudioObjectID;
typedef AudioObjectID   AudioDeviceID;
struct  AudioObjectPropertyAddress
{
    UInt32 mSelector;
    UInt32    mScope;
    UInt32  mElement;
};
typedef struct AudioObjectPropertyAddress   AudioObjectPropertyAddress;

UInt32 kAudioHardwarePropertyDevices = 'dev#';
UInt32 kAudioObjectPropertyScopeGlobal = 'glob';
UInt32 kAudioObjectPropertyElementMaster = 0;
UInt32 kAudioObjectSystemObject  = 1;
UInt32 kAudioDevicePropertyScopeInput = 'inpt';
UInt32 kAudioDevicePropertyDeviceUID      = 'uid ';
UInt32 kAudioDevicePropertyDeviceNameCFString = 'lnam';

extern OSStatus
AudioObjectGetPropertyDataSize( AudioObjectID                       inObjectID,
                                const AudioObjectPropertyAddress*   inAddress,
                                UInt32                              inQualifierDataSize,
                                const void* __nullable              inQualifierData,
                                UInt32*                             outDataSize)                    __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);

extern OSStatus
AudioObjectGetPropertyData( AudioObjectID                       inObjectID,
                            const AudioObjectPropertyAddress*   inAddress,
                            UInt32                              inQualifierDataSize,
                            const void* __nullable              inQualifierData,
                            UInt32*                             ioDataSize,
                            void*                               outData)                            __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);

新增完以上内容之后,可以成功open_input,不会出现闪退问题;

新的问题,初始化重采样上下文失败

image

尝试修改配置参数,写死ch_layout、rate、sample_fmt等;

AVChannelLayout src_ch_layout = AV_CHANNEL_LAYOUT_STEREO, dst_ch_layout = AV_CHANNEL_LAYOUT_SURROUND;
    int src_rate = 48000, dst_rate = 44100;
    enum AVSampleFormat src_sample_fmt = AV_SAMPLE_FMT_DBL, dst_sample_fmt = AV_SAMPLE_FMT_S16;

    acodecContext->sample_rate = src_rate;
    acodecContext->ch_layout = src_ch_layout;
    acodecContext->sample_fmt = src_sample_fmt;

    desPcm->sample_rate = dst_rate;
    desPcm->ch_layout = dst_ch_layout;
    desPcm->format = dst_sample_fmt;

经过以上修改,swr_init成功;

但是又遇到了新的问题,在接收音频数据的时候崩溃了

image

很明显的,编的库有问题,换个思路再试试吧;

* 重新出发

之前使用的现成库:FFmpegKit自定义library

脚本下载地址:https://github.com/arthenica/ffmpeg-kit/

1、编译脚本

./ios.sh --enable-custom-library-1-name=librist --enable-custom-library-1-repo=https://code.videolan.org/rist/librist --enable-custom-library-1-repo-tag=v0.2.7 --enable-custom-library-1-package-config-file-name=librist --enable-custom-library-1-ffmpeg-enable-flag=librist --enable-custom-library-1-license-file=README.md

注:编译带x264、openssl、gpl的,不加入x264,会导致编码的时候找不到264编码器

./ios.sh --enable-custom-library-1-name=librist --enable-custom-library-1-repo=https://code.videolan.org/rist/librist --enable-custom-library-1-repo-tag=v0.2.7 --enable-custom-library-1-package-config-file-name=librist --enable-custom-library-1-ffmpeg-enable-flag=librist --enable-custom-library-1-license-file=README.md --enable-x264 --enable-openssl --enable-gpl

image

error1:x264 not found using pkg-config

image

enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&

require_cpp_condition libx264 x264.h "X264_BUILD >= 118" && {

[ "$toolchain" != "msvc" ] ||

require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&

check_cpp_condition libx262 x264.h "X264_MPEG2"

ERROR: OpenSSL <3.0.0 is incompatible with the gpl

enabled openssl && { { check_pkg_config openssl "openssl >= 3.0.0" openssl/ssl.h OPENSSL_init_ssl &&

{ enabled gplv3 || ! enabled gpl || enabled nonfree || die "ERROR: OpenSSL >=3.0.0 requires --enable-version3"; }; } ||

{ enabled gpl && ! enabled nonfree && die "ERROR: OpenSSL <3.0.0 is incompatible with the gpl"; } ||

check_pkg_config openssl openssl openssl/ssl.h OPENSSL_init_ssl ||

check_pkg_config openssl openssl openssl/ssl.h SSL_library_init ||

check_lib openssl openssl/ssl.h OPENSSL_init_ssl -lssl -lcrypto ||

check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto ||

check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 ||

check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||

die "ERROR: openssl not found"; }

libavformat/hlsenc.c:33:10: fatal error: 'openssl/rand.h' file not found

libavcodec/allcodecs.c:789:10: fatal error: 'x264.h' file not found

解决:将x264、openssl拖入libavformat同级目录;

image

Undefined symbols for architecture arm64:

image

将libx264.a库放入当前配置的libs路径下,并在终端输入:

export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig"

image

参考:Mac FFmpeg编译支持x264编码

error2: 'librist/librist.h' file not found

比较简单的方法就把librist头文件放在libavformat同一级目录下,因为librist.c是在该目录下面;

image
image

此处因为官方编出来的.a库不支持iOS arm64(忘截图了),所以需要自己编库;

2、编译支持iOS架构的rist静态库

创建静态库工程

既然rist官方提供的方法编译出来的静态库不支持iOS,我们只能自己动手,丰衣足食了;

image

将rist源码拖入library工程中;配置Search Paths

image
image
image

bitcode支持

ffmpeg编译默认开启bitcode支持,所以我们编译的库也要支持bitcode才行;
当然我现在还没找到哪里可以关闭的,有找到的朋友可以留言互相探讨下。

image
image

找不到执行文件

image

需要通过下载librist资源文件,同时我们自己编译生成的librist.a库也要有;

image

x86是mac下的架构,具体可参考下面两篇文章,选择mac,在build,是可以生成x86_64架构的静态库;

https://www.jianshu.com/p/369b84ee0fd6

编译ios平台的支持arm64和x86_64的通用静态库

image

但是与现在的需求不符,这个也不能直接拖过来用,因为现在是要编译iOS可以的库,除非提取这个库的x86_64架构跟iphoneos的arm64、arm64e合并才能使用,所有这里的做法是:

直接改脚本,将x86_64的架构先剔除掉

通过关键词检索ffmpegkit目录,找到在main-ios.sh进行实际编译;

image
image

找到执行main-ios.sh的地方

image

通过关键词检索,在function.sh中找到0..12分别代表什么意思;

image

有了这个认知,发现8-12都是目前不需要编译的架构,所以就把ios.sh做一番调整,修改完成后如下:

image

/ffmpeg-kit/src/librist/LICENSE.md: No such file or directory

值得注意的是,运行脚本的时候, --enable-custom-library-1-license-file一定要写,在librist目录下面,可以新建一个LICENSE.md ,也可以直接使用README.md,即--enable-custom-library-1-license-file=README.md

image

错误示范:不带--enable-custom-library-1-license-file,编出来的库不完整,不会携带librist

./ios.sh --enable-custom-library-1-name=librist --enable-custom-library-1-repo=~~~~https://code.videolan.org/rist/librist --enable-custom-library-1-repo-tag=v0.2.7 --enable-custom-library-1-package-config-file-name=librist --enable-custom-library-1-ffmpeg-enable-flag=librist

编译成功!

image

prebuilt目录下apple-framework-ios就是我们要的库文件;

image

3、导入rist到工程中

直接将编译好的库拖入工程中,配置好header search path跟library search path,cmd+B编译;

image

运行,动态库没有加载成功

查看.app文件,发现framesworks确实没有;

image

参考下面这篇文章,手动copy Files,配置Runpath Search Paths->@executable_path/Frameworks;

image

参考:dyld: Library not loaded: @rpath/xxx.framework 动态库

4、测试

obs输入手机ip地址,然后开始直播

image

手机通过rist://@0.0.0.0:8888可以成功拉取到视频流数据;

image

5、编译源文件

librist.a静态库编译源码:https://github.com/xghbq-yang/build-rist-lib

修改完的脚本下载地址:https://github.com/xghbq-yang/ffmpeg-rist-for-ios

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容