Android直播开发之旅(16):使用FFmpeg保存网络流到本地文件

本文详细介绍了如何在Android上使用FFmpeg裁剪移植,以减小so体积,并提供了一个将网络流保存到本地MP4文件的实战案例,包括FFmpeg的配置选项、关键结构体和函数的使用。
摘要由CSDN通过智能技术生成

Amdroid直播开发之旅(5):详解ffmpeg编译与在Android平台上的移植Android直播开发之旅(12):初探FFmpeg开源框架文章中,我们分别探讨了FFmpeg的编译移植、FFmpeg框架和相关重要结构体。本文就在此基础上,将详细阐述FFmpeg的裁剪移植,以便剔除不必要的功能,达到为APK"瘦身"的效果,同时,写了一个将网络流保存到本地文件的实战案例,以加深对FFmpeg相关结构体、功能函数的理解。

1 . FFmpeg裁剪移植

 在详解ffmpeg编译与在Android平台上的移植一文中,我们简单地讲解了下如何在Linux系统中编译FFmpeg,但是编译出来的so体积太大,而且得到的多个so不便于使用。本节在此基础上,将详细讲解在编译FFmpeg时如何对相关模块作裁剪以精简so的体积,并且编译只生成一个so文件。首先,我们来看下在配置编译选项时,configure的具体配置信息,可以进入FFmpeg源码根目录执行./configure --help命令可得到,部分配置选项如下:

  • Standar Options
  --logfile=FILE           指定日志文件输出路径[ffbuild/config.log]
  --disable-logging        不记录配置调试信息
  --fatal-warnings         如果配置出现警告,就认为失败
  --prefix=PREFIX          编译得到的库文件输出路径[/usr/local]
  --bindir=DIR             二进制文件输出路径 [PREFIX/bin]
  --datadir=DIR            数据输出路径[PREFIX/share/ffmpeg]
  --docdir=DIR             文档输出路径[PREFIX/share/doc/ffmpeg]
  --libdir=DIR             libs输出路径[PREFIX/lib]
  --shlibdir=DIR           动态库输出路径 [LIBDIR]
  --incdir=DIR             头文件输出路径 [PREFIX/include]
  --mandir=DIR             帮助文档输出路径 [PREFIX/share/man]
  --pkgconfigdir=DIR       pkg-config文件输出路径[LIBDIR/pkgconfig]
  • Configuration options
  --disable-static         禁止编译静态库
  --enable-shared          开启编译动态库
  --enable-small           开启优化大小
  --disable-runtime-cpudetect 禁用在运行时检测CPU功能
  --enable-gray            启用全灰度支持(slower color)
  --disable-swscale-alpha  禁止在swscale中支持alpha通道
  --disable-all            禁止编译所有组件(components)、库(libraries)、程序(programs)
  --disable-autodetect     禁用自动检测到的外部库

 这里用得较多的是--disable-static--enable-shared--enable-small选项,其中,--disable-static用于是否使能编译静态库文件(.a);--enable-shared用于使能编译动态库文件(.so)。

  • Program options
  --disable-programs       禁止编译programs
  --disable-ffmpeg         禁止编译ffmpeg
  --disable-ffplay         禁止编译ffplay
  --disable-ffprobe        禁止编译ffprobe

 通常,我们会使用禁止编译ffmpeg、ffplay和ffprobe,其中,ffplay是一个使用了FFmpeg和SDL库的、简单的、可移植的媒体播放器;ffprobe用于查看多媒体文件的信息。

  • Component options
  --disable-avdevice       禁止编译libavdevice模块
  --disable-avcodec        禁止编译libavcodec模块
  --disable-avformat       禁止编译libavformat模块
  --disable-swresample     禁止编译libswresample模块
  --disable-swscale        禁止编译libswscale模块
  --disable-postproc       禁止编译libpostproc模块
  --disable-avfilter       禁止编译libavfilter模块
  --enable-avresample      该模块已被弃用
  --disable-pthreads       禁止pthreads [autodetect]
  --disable-w32threads     禁止Win32 threads [autodetect]
  --disable-os2threads     禁止OS/2 threads [autodetect]
  --disable-network        禁止network支持
  --disable-dct            禁止DCT代码模块
  --disable-dwt            DWT代码模块
  --disable-error-resilience error resilience code
  --disable-lsp            禁止LSP代码模块
  --disable-lzo            禁止LZO decoder代码模块
  --disable-mdct           禁止MDCT代码模块
  --disable-rdft           禁止RDFT代码模块
  --disable-fft            禁止FFT代码模块
  --disable-faan           禁止floating point AAN (I)DCT代码模块
  --disable-pixelutils     禁止libavutil模块中的pixel工具

 这部分类似一个全局开关,用于对模块进行管控,假如我们非常明确编译的ffmpeg有明确的功能(不考虑未来扩展),那么,就可以对某些模块进行裁剪,以最大化精简so的大小、功能。

  • Individual component options
  --disable-everything     禁止所有的组件,就是下面列出来的这些
  --disable-encoder=NAME   禁用名称为NAME的编码器
  --enable-encoder=NAME    使能名称为NAME的编码器
  --disable-encoders       禁用所有编码器,可通过指定NAME具体开启
  --disable-decoder=NAME   禁用名称为NAME的解码器
  --enable-decoder=NAME    使能名称为NAME的解码器
  --disable-decoders       禁用所有解码器,可通过指定NAME具体开启
  --disable-hwaccel=NAME   禁用名称为NAME的hwaccel
  --enable-hwaccel=NAME    使能名称为NAME的hwaccel
  --disable-hwaccels       禁用所有hwaccel,可通过指定NAME具体开启
  --disable-muxer=NAME     muxer NAME
  --enable-muxer=NAME      enable muxer NAME
  --disable-muxers         禁用所有复用器,可通过指定NAME具体开启
  --disable-demuxer=NAME   demuxer NAME
  --enable-demuxer=NAME    enable demuxer NAME
  --disable-demuxers       禁用所有解复用器,可通过指定NAME具体开启
  --enable-parser=NAME     enable parser NAME
  --disable-parser=NAME    parser NAME
  --disable-parsers        禁用所有解析器,可通过指定NAME具体开启
  --enable-bsf=NAME        enable bitstream filter NAME
  --disable-bsf=NAME       bitstream filter NAME
  --disable-bsfs           禁用所有位流过滤器,可通过指定NAME具体开启
  --enable-protocol=NAME   enable protocol NAME
  --disable-protocol=NAME  protocol NAME
  --disable-protocols      禁用所有协议,可通过指定NAME具体开启
  --enable-indev=NAME      enable input device NAME
  --disable-indev=NAME     input device NAME
  --disable-indevs         禁用所有输入设备,可通过指定NAME具体开启
  --enable-outdev=NAME     enable output device NAME
  --disable-outdev=NAME    output device NAME
  --disable-outdevs        禁用所有输出设备,可通过指定NAME具体开启
  --disable-devices        禁用所有设备,包括输入、输出
  --enable-filter=NAME     enable filter NAME
  --disable-filter=NAME    filter NAME
  --disable-filters        禁用所有过滤器,可通过指定NAME具体开启

 本部分的配置主要是选择那些组件需要编译,比如编码器、解码器、复用器、解复用器等等。举个栗子:

–disable-encoders
–enable-encoder=h263
–enable-encoder=libx264
–enable-encoder=aac
–enable-encoder=mpeg4
–enable-encoder=mjpeg
–enable-encoder=png
–enable-encoder=gif
–enable-encoder=bmp
–disable-muxers
–enable-muxer=h264
–enable-muxer=flv
–enable-muxer=gif
–enable-muxer=mp3
–enable-muxer=dts
–enable-muxer=mp4
–enable-muxer=mov
–enable-muxer=mpegts
–disable-decoders
–enable-decoder=aac
–enable-decoder=aac_latm
–enable-decoder=mp3
–enable-decoder=h263
–enable-decoder=h264
–enable-decoder=mpeg4
–enable-decoder=mjpeg
–enable-decoder=gif
–enable-decoder=png
–enable-decoder=bmp
–enable-decoder=yuv4
–disable-demuxers
–enable-demuxer=image2
–enable-demuxer=h263
–enable-demuxer=h264
–enable-demuxer=flv
–enable-demuxer=gif
–enable-demuxer=aac
–enable-demuxer=ogg
–enable-demuxer=dts
–enable-demuxer=mp3
–enable-demuxer=mov
–enable-demuxer=m4v
–enable-demuxer=concat
–enable-demuxer=mpegts
–enable-demuxer=mjpeg
–enable-demuxer=mpegvideo
–enable-demuxer=rawvideo
–enable-demuxer=yuv4mpegpipe
–enable-demuxer=rtsp
–disable-parsers
–enable-parser=aac
–enable-parser=ac3
–enable-parser=h264
–enable-parser=mjpeg
–enable-parser=png
–enable-parser=bmp
–enable-parser=mpegvideo
–enable-parser=mpegaudio
–disable-protocols
–enable-protocol=file
–enable-protocol=hls
–enable-protocol=concat
–enable-protocol=rtp
–enable-protocol=rtmp
–enable-protocol=rtmpt
–disable-filters
–disable-filters
–enable-filter=aresample
–enable-filter=asetpts
–enable-filter=setpts
–enable-filter=ass
–enable-filter=scale
–enable-filter=concat
–enable-filter=atempo
–enable-filter=movie
–enable-filter=overlay
–enable-filter=rotate
–enable-filter=transpose
–enable-filter=hflip

  • External library support
--enable-libopencv       enable video filtering via libopencv [no]
--enable-libopenh264     enable H.264 encoding via OpenH264 [no]
--enable-libopenjpeg     enable JPEG 2000 de/encoding via OpenJPEG [no]
--enable-libx264         enable H.264 encoding via x264 [no]
--enable-libx265         enable HEVC encoding via x265 [no]
--enable-librtmp         enable RTMP[E] support via librtmp [no]
...

 FFmpeg框架中集成了非常多的第三方库,本部分选项主要是开启是否使用某些第三方库,以完成特定的功能。

  • Toolchain options
  --arch=ARCH              指定架构
  --cpu=CPU                指定CPU型号
  --cross-prefix=PREFIX    交叉编译工具的前缀(PREFIX)
  --progs-suffix=SUFFIX    program name suffix []
  --enable-cross-compile   使能交叉编译
  --sysroot=PATH           root of cross-build tree
  --sysinclude=PATH        cross-build系统头文件路径
  --target-os=OS           指定编译的系统类型
  --target-exec=CMD        指定在系统上运行可执行程序的命令
  --target-path=DIR        指定系统上查看编译路径
  --target-samples=DIR     指定系统上samples的目录
  --toolchain=NAME         根据NAME设置工具默认值
                           (gcc-asan, clang-asan, gcc-msan, clang-msan,
                           gcc-tsan, clang-tsan, gcc-usan, clang-usan,
                           valgrind-massif, valgrind-memcheck,
                           msvc, icl, gcov, llvm-cov, hardened)
  --nm=NM                  指定nm工具,名称为NM
  --ar=AR                  指定ar工具,名称为ARuse archive tool AR [ar]
  --as=AS                  指定汇编程序assembler AS []
  --ln_s=LN_S              指定符号连接工具 LN_S [ln -s -f]
  --strip=STRIP            指定strip工具STRIP [strip]
  --windres=WINDRES        指定windows资源编译器WINDRES [windres]
  --x86asmexe=EXE          指定nasm-compatible汇编EXE [nasm]
  --cc=CC                  指定C编译器use C compiler CC [gcc]
  --cxx=CXX                use C compiler CXX [g++]
  --objcc=OCC              use ObjC compiler OCC [gcc]
  --dep-cc=DEPCC           use dependency generator DEPCC [gcc]
  --nvcc=NVCC              use Nvidia CUDA compiler NVCC [nvcc]
  --ld=LD                  use linker LD []
  --pkg-config=PKGCONFIG   use pkg-config tool PKGCONFIG [pkg-config]
  --pkg-config-flags=FLAGS pass additional flags to pkgconf []
  --extra-cflags=ECFLAGS   add ECFLAGS to CFLAGS []
  --extra-cxxflags=ECFLAGS add ECFLAGS to CXXFLAGS []
  --extra-objcflags=FLAGS  add FLAGS to OBJCFLAGS []
  --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS []
  --extra-ldexeflags=ELDFLAGS add ELDFLAGS to LDEXEFLAGS []
  --extra-ldsoflags=ELDFLAGS add ELDFLAGS to LDSOFLAGS []
  --extra-libs=ELIBS       add ELIBS []
  --extra-version=STRING   version string suffix []
  ...

 这部分用于配置编译选项,比如配置交叉编译工具、指定编译架构、CPU型号以及其他编译参数等。对于比较常见的选项,我大概列举了一下,具体介绍如下:

–arch=ARCH

 用于指定CPU的架构,常见的架构有armarm64x86等,其中,arm对应的CPU型号分为armv7-aarmv5tearmv6等;arm64对应的CPU型号为armv8-a

–cpu

 用于指定CPU的型号,比如armv7-aarmv5tearmv8-a等。

–target-os

 用于指定编译的系统平台,比如linux、win32等。

–cross-prefix

 用于指定编译工具前缀,比如–cross-prefix=/home/jiangdg/opt/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-

–sysroot

 用于指定Android平台的目录,便于在编译过程中需要引用相关的库或者头文件,就会在--sysroot指定的目录下去搜索,如:–sysroot=/home/jiangdg/opt/android-ndk-r14b/platforms/

一: 使用javacv来实现,最终也是用过ffmpeg来进行编码和推,javacv实现到可以直接接收摄像头的帧数据 需要自己实现的代码只是打开摄像头,写一个SurfaceView进行预览,然后实现PreviewCallback将摄像头每一帧的数据交给javacv即可 javacv地址:https://github.com/bytedeco/javacv demo地址:https://github.com/beautifulSoup/RtmpRecoder/tree/master 二: 使用Android自带的编码工具,可实现硬编码,这里有一个国内大神开源的封装很完善的的库yasea,第一种方法需要实现的Camera采集部分也一起封装好了,进行一些简单配置就可以实现编码推,并且yasea目前已经直接支持摄像头的热切换,和各种滤镜效果 yasea地址(内置demo):https://github.com/begeekmyfriend/yasea 服务器 媒体服务器我用的是srs,项目地址:https://github.com/ossrs/srs 关于srs的编译、配置、部署、在官方wiki中已经写的很详细了,并且srs同样是国内开发人员开源的项目,有全中文的文档,看起来很方便 这里有最基本的简单编译部署过程 Android直播实现(二)srs媒体服务器部署 播放器 android端的播放使用vitamio,还是国内的开源播放器,是不是感觉国内的前辈们越来越屌了^~^! vitamio支持几乎所有常见的的视频格式和媒体协议 vitamio地址(内置demo):https://github.com/yixia/VitamioBundle 这里使用的是yaesa库,先介绍一下直播实现的程:
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值