【从零冲击音视频开发】FFmpeg的介绍和基本使用

前言

这篇文章写了有一下子了,可是我手头做业要写不完了,下周三以前估计最多也就更新一下个人面经了,由于今天晚上还要抖音的三面,阿里的下周一估计也要到hr面了。周六周天的时间,个人计组和电路学做业都还没开动,再不学我就要凉了,时间真的太紧了,见谅见谅。java

文章内容参考书目《音视频开发进阶指南 -- 基于 Android 与 iOS 平台的实践》git

GitHub传送门

目录

【1】【从零冲击音视频开发】音视频开发必备知识基础github

【2】【从零冲击音视频开发】移动环境搭建面试

【3】【从零冲击音视频开发】FFmpeg的介绍和基本使用json

FFmpeg的环境搭建

材料清单:
1. 10.15.2的OSX系统
2. HomeBrew(安装姿式:/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)")
3. ffmpeg的依赖(安装姿式: brew install ffmpeg;文件路径: /usr/local/Cellar)
4. ffmpeg-4.2.2的源码(官网下)
5. NDK-r20
复制代码

这是一个用于本地使用的环境,里面放置有很多的样例,可是不建议使用在开发。ruby

我使用过了不少次,.a的静态库在XCode上能直接玩,在AS上就直接整不起来。因此这里要推一个交叉编译详解的文章。bash

FFmpeg模块介绍

bin

命令行工具所在的位置,ffplayffmpegffprobe等等。工具

// ffprobe各类命令
> ffprobe 文件 // 显示文件头信息
> ffprobe -show_format 文件 // 显示输出格式、时间长度、文件大小、比特率等信息
> ffprobe -pirnt_format json -show_streams 文件 // 以json格式输出具体每个流的信息
> ffprobe -show_frames 文件 // 显示帧信息
> ffprobe -show_packets 文件 // 显示包信息
//。。。。。

// ffplay
> ffplay 文件 // 播放
> ffplay 文件 -loop 10 // 循环播放10次
> ffplay 文件 -ast 0 // 播放第0路音频流,其余路没有流的话会静音
> ffplay 文件 -vst 0 // 播放第0路视频流,其余路没有流的话会黑屏
> ffplay 文件.pcm -f s16le -channels 2 -ar 44100 // 播放pcm格式文件的方式,须要设置格式(-f),声道数(-channels),采样率(-ar)
> ffplay -f rawvideo -pixel_format yuv420p -s 480*480 文件.yuv(文件.rgb) // 查看一帧的视频帧(这个没有调试经过)
> ffplay 文件 -sync audio // 以音频为基准进行音视频同步(默认方案)
> ffplay 文件 -sync video // 以视频为基准进行音视频同步
> ffplay 文件 -sync ext // 之外部时钟为基准进行音视频同步
> ffplay 文件 -ss 50 // 跳过50s的内容
//。。。。。

// ffmpeg
// 会有不少的经过参数以图片给出,具体使用后期会慢慢看到,就再也不演示
复制代码

inlcude -> 8大模块

存放的是已经编译结束的静态库文件的头文件

  1. AVCodec: 用于编码解码
  2. AVDevice: 输入输出设备
  3. AVFilter: 音视频滤镜库,提供音视频特效的处理。
  4. AVFormat: 文件格式和协议库。封装了Protocol层和DemuxerMuxer层。
  5. AVResample: 用于音频重采样 (书上说老版本才会编译出来,已经废弃,可是个人版本是最新的,有待考察)
  6. AVUtil: 核心工具
  7. PostProc: 用于后期处理,是使用AVFilter时要开启的模块。
  8. SwResample: 用于音频重采样,对音频进行声道数、数据格式、采样率等基本信息转化。
  9. SWScale: 将图像进行格式转换,好比YUV -> RGB

lib

存放的是已经编译完成的静态库文件,在连接阶段会使用到。

share

其实就是一个 example的位置,用于讲解 FFmpeg各个工具的使用方法,还有使用样例等等。

FFmpeg的使用

前面讲了不少东西,可是咱们真正要在Java代码中如何进行使用却彻底尚未进行过,因此这里就要进行的是Java代码中的测试了。

第一步:导包和引用

而后 CMakeList.txt中导入咱们须要加载的 so

cmake_minimum_required(VERSION 3.4.1)

# 定义变量
set(ffmpeg_lib_dir ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
set(ffmpeg_head_dir ${CMAKE_SOURCE_DIR}/ffmpeg)

add_library( # Sets the name of the library.
        audioencoder
        SHARED
        # lame
        lame/bitstream.c lame/encoder.c lame/gain_analysis.c
        lame/lame.c lame/id3tag.c lame/mpglib_interface.c
        lame/newmdct.c lame/presets.c lame/psymodel.c
        lame/quantize.c lame/fft.c lame/quantize_pvt.c
        lame/reservoir.c lame/set_get.c lame/tables.c
        lame/takehiro.c lame/util.c lame/vbrquantize.c
        lame/VbrTag.c lame/version.c
        # mine
        audioencoder/audioencoder.cpp
        audioencoder/mp3_encoder.cpp)

# 添加ffmpeg相关的so库
add_library( avutil
        SHARED
        IMPORTED )
set_target_properties( avutil
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavutil.so )

add_library( swresample
        SHARED
        IMPORTED )
set_target_properties( swresample
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libswresample.so )

add_library( avcodec
        SHARED
        IMPORTED )
set_target_properties( avcodec
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavcodec.so )

add_library( avfilter
        SHARED
        IMPORTED)
set_target_properties( avfilter
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavfilter.so )

add_library( swscale
        SHARED
        IMPORTED)
set_target_properties( swscale
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libswscale.so )

add_library( avformat
        SHARED
        IMPORTED)
set_target_properties( avformat
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavformat.so )

add_library( avdevice
        SHARED
        IMPORTED)
set_target_properties( avdevice
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavdevice.so )


find_library( # Sets the name of the path variable.
        log-lib
        log)

# 引入头文件
include_directories(${ffmpeg_head_dir}/include)

target_link_libraries( # Specifies the target library.
        audioencoder
        # ffmpeg
        avutil
        swresample
        avcodec
        avfilter
        swscale
        avformat
        avdevice

        ${log-lib})
复制代码

第二步:使用

固然使用方案上来讲仍是同样的,可是这里咱们存在须要注意的地方,由于FFmpeg是由C编写而成的,而咱们去编译的倒是使用的C++,因此套上一层extern "C"是必需要作的事情。

这里的源码直接抄的猫哥的,作一个示范。

Github中带了一个用FFmpeg去解码mp3->pcm的样例,固然里面有不少功能感受也没用到吧,主要作了一个解释,详细看关注点,固然我也在源码中提了一些问题,你要是知道怎么解决,或者有什么新的问题,发评论啊、发邮件之类的,我会继续探索的。

以后理解的差很少了就会本身再开一个项目动手开发的,但愿这个学习项目大家也能star,嘿嘿嘿。

以上就是个人学习成果,若是有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。


相关文章推荐:

【从零冲击音视频开发】移动环境搭建

面试官问我:“泛型擦除是什么,会带来什么问题?”

【从零冲击音视频开发】音视频开发必备知识基础

相关文章
相关标签/搜索