【问题标题】:"Undefined Reference" when compiling FFMPEG with librtmp on Android在 Android 上使用 librtmp 编译 FFMPEG 时出现“未定义的参考”
【发布时间】:2014-01-10 08:49:37
【问题描述】:

我已经搜索过了,虽然 Building FFMPEG with librtmp for android 回答了我的部分问题,但我在编译过程中进一步遇到了其他问题。

首先,我尝试使用this github repo 中的脚本,将标志更改为包含

  --enable-librtmp \
  --extra-cflags=-I/home/bradford/Development/FFMPEG/rtmp/rtmpdump/librtmp/ \
  --extra-ldflags=-L/home/bradford/Development/FFMPEG/rtmp/rtmpdump/librtmp"

我按照 S74ck3r 的 instructions on his github repo 和 stream-recorder thread 使用 polarSSL 构建 librtmp。这似乎工作正常,我有一个 librtmp.so、librtmp.a 和 rtmp.h

当我尝试用 librtmp 编译 ffmpeg 时,我得到了错误

ERROR: librtmp not found

This SO question helped,我修改了 ffmpeg 的配置文件,使其不会查看 pkg-config 的 librtmp(即使 pkg-config 知道 librtmp...):

#enabled librtmp    && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket

当我现在构建时,它开始成功,我得到了希望的线:

librtmp enabled           yes

后来我看到了更多好消息:

...
Enabled protocols:
applehttp       http            mmsh
cache           httpproxy       mmst
concat          librtmp         mmsu
crypto          librtmpe        pipe
fd          librtmps        rtp
file            librtmpt        tcp
gopher          librtmpte       udp
hls         md5
...

但最后,在编译完所有内容并在安装阶段,我得到了这些类型的错误:

INSTALL   libavutil/libavutil.pc
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_get_file_handle:libavformat/librtmp.c:190: error: undefined reference to 'RTMP_Socket'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_read_seek:libavformat/librtmp.c:180: error: undefined reference to 'RTMP_SendSeek'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_read_pause:libavformat/librtmp.c:161: error: undefined reference to 'RTMP_Pause'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_close:libavformat/librtmp.c:64: error: undefined reference to 'RTMP_Close'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_write:libavformat/librtmp.c:145: error: undefined reference to 'RTMP_Write'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_read:libavformat/librtmp.c:153: error: undefined reference to 'RTMP_Read'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_open:libavformat/librtmp.c:96: error: undefined reference to 'RTMP_LogSetLevel'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_open:libavformat/librtmp.c:97: error: undefined reference to 'RTMP_LogSetCallback'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_open:libavformat/librtmp.c:118: error: undefined reference to 'RTMP_Init'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_open:libavformat/librtmp.c:119: error: undefined reference to 'RTMP_SetupURL'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_open:libavformat/librtmp.c:127: error: undefined reference to 'RTMP_Connect'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_open:libavformat/librtmp.c:127: error: undefined reference to 'RTMP_ConnectStream'
/tmp/FFMPEG/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: libavformat/librtmp.o: in function rtmp_open:libavformat/librtmp.c:125: error: undefined reference to 'RTMP_EnableWrite'
collect2: ld returned 1 exit status

而且我无法超越他们。听起来它找不到 rtmp.h,其中包含对这些函数的引用,但它存在于它应该在的位置(afaik)。

另外,我的项目需要 librtmp - ffmpeg 的内置 rtmp 功能是不够的,因为我需要 librtmp 的身份验证功能。

【问题讨论】:

  • 你需要先编译librtmp,并链接.so或.a,如果你使用Vitamio 4.0+,你可以克隆github.com/yixia/FFmpeg-Vitamio,运行./build_android.sh
  • @CrossleSong - 谢谢。我看到回购已在过去 3 周内更新。我再试一次

标签: android bash ffmpeg rtmp


【解决方案1】:

感谢您将其分解为一个单独的问题并详细说明您的流程和问题。

根据提供的数据,您可以构建 FFmpeg 并执行二进制文件以查看协议列表。但是安装阶段失败了? rtmp.h 文件必须存在,因为二进制构建(编译时需要.h,而不是链接时或运行时)。

我最好的猜测是你编译的 FFmpeg 二进制文件是动态链接到 librtmp.so 的。您是否将 librtmp.so 复制到此系统上(假设此处为交叉编译)?如果存在,您是否运行/sbin/ldconfig 来注册库?运行 ldd ffmpeg 以查看 FFmpeg 二进制文件想要查看的 .so 库。是否缺少指向 librtmp.so 的链接?

【讨论】:

  • 对不起!我在我的问题上犯了一个错误,所以我编辑了它。我让它听起来像是编译成功。它没有。 ffmpeg 需要一些工作才能开始使用 librtmp 标志集进行编译,即使它看起来可以工作,但在安装阶段失败,可能是因为 rtmp.h 的问题,它引用了所有缺少的函数。
【解决方案2】:

我已经 documented 成功使用 librtmp for Android 构建 FFmpeg 2.1.3 的过程。

简单地说,一旦你构建了 Open/PolarSSL 和 librtmp,下载 the latest FFmpeg release 并对 FFmpeg 的 configure 进行以下更改:

# ffmpegX.X.X/configure
...
# Replace the following lines:

#SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
#LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
#SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
#SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'

# With: 

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'

...

# Replace this:
#enabled librtmp    && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
# With:
enabled librtmp    && require librtmp librtmp/rtmp.h RTMP_Socket -L/path/to/rtmpdump/librtmp/android/arm/lib -lrtmp

然后使用以下构建脚本编译FFmpeg:

# ffmpegX.X.X/build_ffmpeg_with_librtmp_for_android.sh
#!/bin/bash
NDK=/path/to/android-ndk-r9c
SYSROOT=$NDK/platforms/android-19/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64

OPENSSL_DIR=/path/to/openssl-android/
LIBRTMP_DIR=/path/to/rtmpdump/librtmp/
# Note: Change above variables to match your system
function build_one
{
./configure \
    --prefix=$PREFIX \
    --enable-librtmp \
    --enable-shared \
    --disable-static \
    --disable-doc \
    --disable-programs \
    --disable-doc \
    --disable-symver \
    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
    --target-os=linux \
    --arch=arm \
    --enable-cross-compile \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG
make clean
make -j8
make install
}
CPU=arm
PREFIX=$(pwd)/android/$CPU 
ADDI_CFLAGS="-marm -I${OPENSSL_DIR}include -I${LIBRTMP_DIR}android/arm/include -L${LIBRTMP_DIR}android/arm/lib -lrtmp"
ADDI_LFLAGS="-L${OPENSSL_DIR}libs/armeabi -L${LIBRTMP_DIR}android/arm/lib -lrtmp" 
build_one

非常感谢我的朋友 Chris 帮助我解决了这个问题。

【讨论】:

    【解决方案3】:

    我猜你没有在你的项目中链接库 rtmp。 你需要像这样链接rtmp库

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/src/main/cpp/libs/${CMAKE_ANDROID_ARCH_ABI}")

    target_link_libraries( native-lib avformat avcodec avfilter avutil swresample swscale z rtmp)

    【讨论】:

      猜你喜欢
      • 2013-04-14
      • 2014-06-21
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 2014-07-25
      相关资源
      最近更新 更多