iOS编译ffmpeg支持smb问题ERROR: libsmbc

2024-06-21  本文已影响0人  生命不止运动不息

引子

需求是在iOS上播放smb中的视频,不想使用VLCMobileKit,所以考虑ffmpeg

但找了一圈,可以直接拿来用的只有一个CYPlayer,封装的挺好,但不太合适。所以想自行编译FFMpeg并支持smb。

FFmpeg是支持smb协议的,但编译时需要提前准备好smb的库文件等。

smb库文件也可以自己编译,大多数都是基于kxsmb编译的。这里我直接找来线程的smb库直接用了。

关于ffmpeg的编译教程也挺多,参考以下:
https://zhuanlan.zhihu.com/p/615573274
https://www.cnblogs.com/machao/p/5385689.html

想在ffmepg中支持smb,在执行 ./configure时,添加以下参数
--enable-libsmbclient --enable-gpl --enable-version3

这样ffmepg就支持smb了

编译遇到的问题:

兴高采烈的执行编译了。结果报错: libsmbclient not found

错误原因

没有指定smb的库路径以及头文件的路径


smb库
如何指定头文件以及lib路径?

依然是在执行./configure命令时,后面跟参数:
--extra-ldflags 指定lib目录以及链接库文件
--extra-cflags 指定头文件目录

示例:
--extra-ldflags="-Lxxxpath -lxxxb“ 指定库路径xxxpath,链接库libxxxb.a
--extra-cflags="-Ixxxxheader" 指定头文件路径xxxxheader

实际上我的(是一段脚本)

SMB_HEADERS="/Users/wkun/Desktop/ffmpegcodes/SGPlayer-master/build/libs/iOS/Smbclient/libsmbclient"
SMB_LIBS="/Users/wkun/Desktop/ffmpegcodes/SGPlayer-master/build/libs/iOS/Smbclient"
FFMPEG_CFLAGS="$FFMPEG_CFLAGS -I${SMB_HEADERS}"
FFMPEG_DEP_LIBS="$FFMPEG_DEP_LIBS -L${SMB_LIBS} -lsmbclient -ltalloc -ltdb -ltevent -lwbclient"

执行时就是如下:

--extra-ldflags="-L/Users/wkun/Desktop/ffmpegcodes/SGPlayer-master/build/libs/iOS/Smbclient -lsmbclient -ltalloc -ltdb -ltevent -lwbclient"
--extra-cflags="-I/Users/wkun/Desktop/ffmpegcodes/SGPlayer-master/build/libs/iOS/Smbclient/libsmbclient"

这就指定了smb库和头文件的路径,同时链接了所有的库。

这里注意:

-L是指定库路径,-I(大写的i)是指定头文件路径,-l(小写的le)是链接静态库
例如 -ltevent 就是链接libevent.a的库,注意实际文件名是lib开头,链接时省去lib了

开开心心再去编译。又报了同样的错误。

再次遇到libsmbclient not found

很懵逼,该检查的都检查了,路径都没问题。
最后仔细观察终端,根据提示,发现了config.log日志,在ffbuild目录下,这个目录有好几个,别搞错了。

错误

打开日志,滑动到最底部,看到了libsmbclient not found


libsmbclient not found

继续往上滑动,我们看到了Undefined symbol .... ,大概知道了又是某些方法么定义了。
贴出关键错误:

xcrun -sdk iphoneos clang -arch arm64 -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 -miphoneos-version-min=13.0 -fembed-bitcode -I/Users/wkun/Desktop/ffmpegcodes/SGPlayer-master/build/libs/iOS/openssl-arm64/output/include -I/Users/wkun/Desktop/ffmpegcodes/SGPlayer-master/build/libs/iOS/Smbclient/libsmbclient -L/Users/wkun/Desktop/ffmpegcodes/SGPlayer-master/build/libs/iOS/Smbclient/ -lsmbclient -ltalloc -ltdb -ltevent -lwbclient -Wl,-dynamic,-search_paths_first -o /var/folders/2m/70fjr7b53fz2zql2dmrrz5_00000gn/T//ffconf.Xxq4k0fJ/test /var/folders/2m/70fjr7b53fz2zql2dmrrz5_00000gn/T//ffconf.Xxq4k0fJ/test.o -lsmbclient
Undefined symbols for architecture arm64:
  "_CFStringAppendCString", referenced from:
      _macosxfs_encoding_pull in libsmbclient.a(charset_macosxfs.o)
  "_CFStringAppendPascalString", referenced from:
      _macosxfs_encoding_pull in libsmbclient.a(charset_macosxfs.o)
  "_CFStringCreateMutable", referenced from:
      _macosxfs_encoding_pull in libsmbclient.a(charset_macosxfs.o)
  "_CFStringCreateMutableWithExternalCharactersNoCopy", referenced from:
      _macosxfs_encoding_push in libsmbclient.a(charset_macosxfs.o)
  "_CFStringDelete", referenced from:
      _macosxfs_encoding_pull in libsmbclient.a(charset_macosxfs.o)
  "_CFStringGetBytes", referenced from:
      _macosxfs_encoding_push in libsmbclient.a(charset_macosxfs.o)
  "_CFStringGetCharacters", referenced from:
      _macosxfs_encoding_pull in libsmbclient.a(charset_macosxfs.o)
  "_CFStringGetLength", referenced from:
      _macosxfs_encoding_pull in libsmbclient.a(charset_macosxfs.o)
      _macosxfs_encoding_push in libsmbclient.a(charset_macosxfs.o)
  "_CFStringNormalize", referenced from:
      _macosxfs_encoding_pull in libsmbclient.a(charset_macosxfs.o)
      _macosxfs_encoding_push in libsmbclient.a(charset_macosxfs.o)
  "_CFStringSetExternalCharactersNoCopy", referenced from:
      _macosxfs_encoding_push in libsmbclient.a(charset_macosxfs.o)
  "_deflate", referenced from:
      _ndr_push_compression_end in libsmbclient.a(ndr_compression.o)
  "_deflateInit2_", referenced from:
      _ndr_push_compression_end in libsmbclient.a(ndr_compression.o)
  "_deflateReset", referenced from:
      _ndr_push_compression_end in libsmbclient.a(ndr_compression.o)
  "_deflateSetDictionary", referenced from:
      _ndr_push_compression_end in libsmbclient.a(ndr_compression.o)
  "_iconv", referenced from:
      _sys_iconv in libsmbclient.a(iconv.o)
      _iconvert_talloc in libsmbclient.a(reg_parse_internal.o)
     (maybe you meant: _iconvert_talloc, _smb_iconv_handle_reinit , _set_iconv , _smb_iconv_open_ex , _global_iconv_handle , _lpcfg_iconv_handle , _smb_iconv_close , _smb_iconv_handle_reinit_lp , _smb_iconv_open , _get_iconv_testing_handle , _get_iconv_handle , _smb_iconv )
  "_iconv_close", referenced from:
      _smb_iconv_t_destructor in libsmbclient.a(iconv.o)
      _set_iconv in libsmbclient.a(reg_parse_internal.o)
     (maybe you meant: _smb_iconv_close)
  "_iconv_open", referenced from:
      _smb_iconv_open_ex in libsmbclient.a(iconv.o)
      _set_iconv in libsmbclient.a(reg_parse_internal.o)
     (maybe you meant: _smb_iconv_open_ex, _smb_iconv_open )
  "_inflate", referenced from:
      _ndr_pull_compression_start in libsmbclient.a(ndr_compression.o)
  "_inflateInit2_", referenced from:
      _ndr_pull_compression_start in libsmbclient.a(ndr_compression.o)
  "_inflateReset", referenced from:
      _ndr_pull_compression_start in libsmbclient.a(ndr_compression.o)
  "_inflateSetDictionary", referenced from:
      _ndr_pull_compression_start in libsmbclient.a(ndr_compression.o)
  "_kCFAllocatorDefault", referenced from:
      _macosxfs_encoding_pull in libsmbclient.a(charset_macosxfs.o)
      _macosxfs_encoding_push in libsmbclient.a(charset_macosxfs.o)
  "_kCFAllocatorNull", referenced from:
      _macosxfs_encoding_push in libsmbclient.a(charset_macosxfs.o)
  "_res_9_dn_expand", referenced from:
      _ads_dns_lookup_srv in libsmbclient.a(dnsquery.o)
      _ads_dns_parse_query in libsmbclient.a(dnsquery.o)
      _ads_dns_parse_rr in libsmbclient.a(dnsquery.o)
      _ads_dns_lookup_ns in libsmbclient.a(dnsquery.o)
  "_res_9_query", referenced from:
      _dns_send_req in libsmbclient.a(dnsquery.o)
  "_zError", referenced from:
      _ndr_pull_compression_start in libsmbclient.a(ndr_compression.o)
      _ndr_push_compression_end in libsmbclient.a(ndr_compression.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ERROR: libsmbclient not found

从未定义的函数名来看,也猜不到是缺啥,最后根据CYPlayer项目进行对比,因CYPLayer中使用了smb的库,会加些系统的依赖。
由此对比,得出结论:

libsmbclient.a还需要以下4个库的依赖:

CoreFoundation.framework,libz.tbd , libiconv.tbd, libresolv.tbd
这4个库,都是iOS系统上的代码库。

FFmpeg编译时,还可以链接 framework 和 tbd动态库

指定tbd动态库的路径(xcode中在某tbd文件右键在Finder显示,找到起路径)
与指定动态库的路径一样 也是使用 -L, 链接tbd文件也是使用 -l(L的小写)
指定framework的路径也是使用 -L
链接framework需要如此: -framework CoreFoundation
这就是链接CoreFoundation.framework,不需要写拓展名。

链接tbd动态库(libz.tbd , libiconv.tbd, libresolv.tbd )以及指定其目录代码

-L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib -lz -liconv -lresolv

链接CoreFoundation.framework以及其目录代码

-L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks -framework CoreFoundation

这回再次编译,漫长的等待,成功了!!!!

编译完成后,把smb的库和头文件与ffmpeg的一并添加到项目中。

就可以测试访问smb的文件了。

有个小提示

在使用libsmbclient.a 测试时,在打开smb文件时,首先给应用申请网络权限(就是可以打开网页),不然就会打开smb文件失败。

注意,以上代码都是跟在 ./configure 命令后的参数

总结:

当你都搞定了之后,就觉得一切都很简单。
当你没搞定之前,这都是什么垃圾啊。😁

感谢以下文章:
https://www.jianshu.com/p/63bec990ee9e
https://www.jianshu.com/p/636f35f428f7
https://github.com/libobjc/SGPlayer

上一篇 下一篇

猜你喜欢

热点阅读