本文主要介绍ffmpeg在Ubuntu上的安装并编译出.a静态文件,通过Android ndk cmake的方式使用的过程。
安装
安装各个依赖库
sudo apt-get install nasm
sudo apt-get install yasm
sudo apt-get install libx264-dev
sudo apt-get install libx265-dev libnuma-dev
sudo apt-get install libvpx-dev
sudo apt-get install libfdk-aac-dev
sudo apt-get install libmp3lame-dev
sudo apt-get install libopus-dev
#安装ffplay
sudo apt install libsdl2-dev
下载ffmpeg的源码
git clone git://source.ffmpeg.org/ffmpeg.git
或直接到官网下载 http://ffmpeg.org/
当前下载的版本是4.0.5,ndk的版本为17c
配置:
进入下载的源码文件目录中
./configure --enable-shared --prefix=/usr/local/ffmpeg --enable-gpl --enable-libx264 --enable-libx265
make
make install
增加安装目录的动态链接库:
export LD_LIBRARY_PATH=/usr/local/ffmpeg/lib:$LD_LIBRARY_PATH
查看指令依赖的动态库
ldd ffmpeg
如果此时报错so找不到
~/tmp/ffmpeg/ffmpeg/host/bin$ ldd ffmpeg
linux-vdso.so.1 => (0x00007fffcfeaf000)
libavdevice.so.57 => not found
libavfilter.so.6 => not found
libavformat.so.57 => not found
libavcodec.so.57 => not found
libswresample.so.2 => not found
libswscale.so.4 => not found
libavutil.so.55 => not found
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f41d6d9e000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f41d6b7f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f41d67b9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f41d70c7000)
则需要关联so到usr/lib下
总结下来主要有3种方法:
- 用ln将需要的so文件链接到/usr/lib或者/lib这两个默认的目录下边
ln -s /where/you/install/lib/*.so /usr/lib
sudo ldconfig
2.修改LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/where/you/install/lib:$LD_LIBRARY_PATH
sudo ldconfig
3.修改/etc/ld.so.conf,然后刷新
vim /etc/ld.so.conf
add /where/you/install/lib
sudo ldconfig
转载地址 https://www.cnblogs.com/smartvessel/archive/2011/01/21/1940868.html
第一种测试通过
测试
进入usr/local/ffmpeg/bin
ffmpeg –version
ffplay测试
ffpaly rtmp:xxxxxxxxx
如果未找到ffmpeg或者ffplay命令,可将安装目录bin文件夹下的对应文件复制到 usr/bin
例如 /usr/local/ffmpeg/bin/ffmpeg -> /usr/bin
可用的直播流地址
通常我们进行 RTMP/RTSP 开发时,除了可以自己搭建视频服务器来进行测试外。也可以直接使用一些电视台的直播地址,省时省力。
下面是我收集汇总的一些视频直播地址,亲测可用。
1,RTMP协议直播源
韩国GoodTV,rtmp://mobliestream.c3tv.com:554/live/goodtv.sdp
韩国朝鲜日报,rtmp://live.chosun.gscdn.com/live/tvchosun1.stream
美国1,rtmp://ns8.indexforce.com/home/mystream
美国2,rtmp://media3.scctv.net/live/scctv_800
美国中文电视,rtmp://media3.sinovision.net:1935/live/livestream
湖南卫视 rtmp://58.200.131.2:1935/livetv/hunantv
2,RTSP协议直播源
大熊兔(点播):rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov
例如播放 湖南卫视 rtmp://58.200.131.2:1935/livetv/hunantv
ffplay -window_title "播放测试" rtmp://58.200.131.2:1935/livetv/hunantv
编译
Android 工程中只支持导入 .so 结尾的动态库,形如:libavcodec-57.so 。但是FFmpeg 编译生成的动态库默认格式为 xx.so.版本号 ,形如:libavcodec.so.57 , 所以需要修改 FFmpeg 根目录下的 configure 文件,使其生成以 .so 结尾格式的动态库:
将 configure 文件中的:
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)'
替换为:
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
编写脚本:在下载目录下创建脚本文件
#!/bin/bash
NDK_ROOT=/home/wangzw/wzw/tmac_files/android-ndk-r17c-linux-x86_64/android-ndk-r17c
TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
ANDROID_API=16
PREFIX=./android/armeabi-v7a
./configure \
--prefix=$PREFIX \
--enable-small \
--disable-programs \
--disable-avdevice \
--disable-encoders \
--disable-muxers \
--disable-filters \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--disable-shared \
--enable-static \
--sysroot=$NDK_ROOT/platforms/android-$ANDROID_API/arch-arm \
--extra-cflags="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=$ANDROID_API -U_FILE_OFFSET_BITS -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fPIC" \
--arch=arm \
--target-os=android
make clean
make
make install
具体的解释可以参考 https://www.jianshu.com/p/f23c62820b79
进入下载的目录 执行
sh 脚本文件名.sh
编译的成功与否有时候和版本关系很大 当前编译成功后会在下载目录多出一个android的文件夹.当前编译的版本为 ffmpeg+ndk17c 或者ndk
静态库在Android中使用
在Android Studio中新建 Native C++ 工程
在src/main目录下将自动生成cpp目录,该目录下自动生成了两个文件:CMakeLists.txt 和 native-lib.cpp。
在ffmpeg目录中的android文件夹底下有刚刚生成的一些文件.
1在src/main/cpp下创建 armeabi-v7a文件夹并将生成的6个.a的静态库文件拷贝,
2将include(包含了所需要的头文件)文件夹拷贝到src/main/cpp下.

3修改CMakeLists.txt文件内容
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
native-lib.cpp)
find_library(
log-lib
log)
# 引入FFmpeg的头文件
include_directories(include)
# 引入FFmpeg的库文件,设置内部的方式引入,指定库的目录是 -L 指定具体的库-l
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/${CMAKE_ANDROID_ARCH_ABI}")
sudo apt install libsdl2-dev
target_link_libraries(
native-lib
# 具体的库文件,链接到总库
# 这样写会报错,有坑
# avcodec avfilter avformat avutil swresample swscale
# 先把有依赖的库,先依赖进来
avformat avcodec avfilter avutil swresample swscale
${log-lib})
4 添加build.gradle相关配置
defaultConfig {
....
externalNativeBuild {
cmake {
cppFlags ""
abiFilters "armeabi-v7a"
}
}
}
5编写native-lib.cpp代码
#include <jni.h>
#include <string>
extern "C" {
#include <libavcodec/avcodec.h>
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_yaxon_ffmpegproj_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = av_version_info();
return env->NewStringUTF(hello.c_str());
}
打印的是当前ffmpeg的版本号
ffmpeg学习地址
https://blog.csdn.net/leixiaohua1020/article/details/15811977
https://www.jianshu.com/p/f23c62820b79
网友评论