FFmpeg是目前最牛逼的开源跨平台音视频处理工具。

准备知识

我不是音视频编解码出身的,对于这一块非常的不了解,导致在学习FFmpeg的时候云里雾里的,所以学习之前最好看些资料对音视频编解码有点认识。

安装

Windows和MacOS用户可以从Builds - Zeranoe FFmpeg下载编译好的FFmpeg,解压加入环境变量PATH即可使用。

同时安装包我上传到百度云中,还有一些测试用的视频:

链接: https://pan.baidu.com/s/1nwLh4hF 密码: v7yt

播放视频,FFplay

学习FFmpeg免不了要看效果,而windows的自带播放器又垃圾得一匹,而且我们会需要看视频的元数据,看他的编码,用一般的这播放器,能看但是不是很方便。其实FFmpeg自带了一个播放器FFplay!

FFplay是结合FFmpeg和SDL实现的一个简易的跨平台播放器。使用起来特别简单:

ffplay [选项] ['输入文件']

而且控制台会打印出视频的各种信息,对于我们查看视频转换结果非常有帮助。

FFplay具体文档:

获取视频信息,FFprobe

FFplay命令中会打印出视频的元数据,那如果我们只是想获取这些数据而不想播放视频呢?比如在程序中我们想获取视频的时长,要用什么命令?用FFprobe命令。

ffprobe [选项] ['输入文件']

看输出一定觉得很熟悉,因为和FFplay打印出的信息一模一样:

我们还可以使用一些参数:

  • -v quiet:不打印日志,这样默认的输出就不会显示了,就不会干扰我们想要输出的信息
  • -print_format json:用JSON格式打印出信息。还支持xml,csv,flat,ini格式
  • -show_format:打印出输入的格式信息
  • -show_streams:打印出每个流的信息

默认的输出是比较简略的,我们可以使用-show_format-show_streams打印出我们想要的详细信息,比如:

ffprobe -v quiet -show_format -print_format json res\BCSPA039_pre.mp4

然后我们程序读取解析json,获取duration字段就是视频的时长。

视频操作,FFmpeg

ffmpeg命令的语法:

ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...

ffmepg支持多个输入源(文件,管道,网络流,采集设备),通过-i指定输入。ffmpeg支持多个输出,命令行中所有无法被解析为参数的字段都会被作为输出的url。

参数一般作用于且只作用于下一个指定的文件,所以参数的位置是非常重要的。所以全局生效的参数要在最前面。

ffmpeg命令完整的说明参考:

ffmpeg的参数太多了,我们还是通过常用命令来学习会比较好。

ffmpeg例子

分离音视频

ffmpeg -i input_file -vcodec copy -an output_file_video  //只输出视频
ffmpeg -i input_file -acodec copy -vn output_file_audio  //分输出音频

参数解释:

  • -i:指定输入文件
  • -vcodec:指定视频编码器,这里指定copy是一个特殊值,表示复制输入的视频流到输出不做更改
  • -an:关闭音频输出
  • -vn:关闭视频输出

视频转码

ffmpeg -i input_file output_file

这是最简单的视频转码命令,ffmpeg会从input的内容推测格式,从output_file的后缀名推测格式,然后进行转码输出。

来看一个我在工作中接触的比较复杂的视频转码命令:

ffmpeg -i "#src#" -y -s 1920x1080 -vcodec libx264 -c:a libvo_aacenc -b:a 48k -ar 44100 -ac 2 -qscale 4 -f #targetFmt# -movflags faststart -map 0:v:0 -map 0:a? "#destDir#/1080p/#fileNameNoEx#.mp4"

参数解释:

  • -y:覆盖输出文件
  • -s 1920x1080:设置帧的大小,也就是视频分辨率,格式为WxH
  • -vcodec libx264:设置视频编码器,-codec:v libx264是另外一种写法
  • -c:a libvo_aacenc:设置音频编码器
  • -b:a 48k:设置音频的比特率
  • -ar 44100:设置音频采样率为44100
  • -ac 2:设置声道数
  • -f #targetFmt#:设定输出的格式。如果不指定,则会输入文件从内容中推测,输出文件通过后缀名推测。
  • -movflags faststart:把MOV/MP4文件的索引信息放到文件前面以支持边下边播
  • -map 0:v:0:选择输入文件的第一个视频流输出
  • -map 0:a?:选择输入文件的音频流输出,如果没有不报错
  • qscale <数值> 以<数值>质量为基础的VBR,取值0.01-255,越小质量越好

在mp4转ogv的时候,如果没有指定-qscale 4,转出来的视频画面比较差,有很多噪点,而且有卡顿。

视频截图

指定时间截取一帧作为输出:

ffmpeg -i input.flv -ss 00:00:14.435 -vframes 1 out.png

参数解释:

  • -ss:如果作用于输入文件表示seek输入文件到这个位置,但是很多格式不支持seek的,所以只能做个大概。如果作用于输出文件,则输入会被解码,但是指定时间之前的数据都会被忽略。这里是作用于输出文件,所以相当于00:00:14.435之前的内容都被忽略了
  • -vframes 1:指定输出多少帧,这里就输出一帧。-vframes-frames:v的别名。

每隔一段时间截一张图:

# 每一秒输出一帧图像为图片, 图片命名为 out1.png, out2.png, out3.png,依次顺序输出:
ffmpeg -i input.flv -vf fps=1 out%d.png # 每一分钟截一次图, 命名 img001.jpg, img002.jpg, img003.jpg, 依次顺序递增:
ffmpeg -i myvideo.avi -vf fps=1/60 img%03d.jpg # 每十分钟输出一张图片:
ffmpeg -i test.flv -vf fps=1/600 thumb%04d.bmp

参数解释:

  • -vf fps=1:设置视频的filter为fps。后面参数表示一秒几帧。这里设置为1,表示一秒一帧。-vf-filter:v的别名
  • out%d.png:输出多个图片,%d占位符表示数字,从1开始。还可以使用%2d指定固定两位

fps过滤器的文档:fps Documentation

多说一句

在学习ffmpeg的过程中,阅读了几篇非常好的博客,然后发现作者都是雷霄骅。没想到他竟然在2016年的时候去世了。唉,又是一个业内悲剧,而且他竟然是在大学里猝死的,真的是太拼了。努力虽好,也得注意身体啊。

这里引用如何看待雷霄骅之死?里的一句话

天妒英才,不夸张的说,如果不知道雷霄骅,可能你音视频还没入门

的确,他的文章对我入门使用ffmpeg起了很大的帮助。谢谢雷神,一路走好。

参考资料

测试视频下载地址

网上随便找的能下载到小容量视频并且多种格式的网站:

本文独立博客地址:FFmpeg笔记-基本使用 | 木杉的博客

FFmpeg笔记-基本使用的更多相关文章

  1. FFmpeg笔记--vcodec和-c:v,-acodec和-c:a的区别?

    在看ffmpeg命令的时候经常会看到有些地方使用--vcodec指定视频解码器,而有些地方使用-c:v指定视频解码器,那这两个有没有区别呢? ffmpeg的官方文档: -vcodec codec (o ...

  2. FFmpeg笔记:使用MSVC工具链编译Windows版本静态库、动态库

    2019年3月开始,为了将音视频编解码功能集成到Cocos2d-x中,开始接触到FFmpeg: 当时开发环境还在Mac下,编译FFmpeg相比现在用Windows平台要方便的多: 最近,公司内部有个U ...

  3. ffmpeg笔记

    1.视频降低质量,减小体积: ffmpeg -i aaa.mp4 -strict -2 -qscale 20 -y outfile.mp4

  4. FFMpeg笔记(七) 代码结构分析,以HLS为例

    HLS流在播放时是先解协议(hls.c)后解封装(mpegts.c),libavformat下的hls.c和mpegts.c实际上是同一个级别的,同属于demuxer. 一.解HLS协议 1. FFm ...

  5. FFMpeg笔记(六) 滤镜命名规则及使用libavfilter对视频尺寸进行裁切

    在ffmpeg框架中,滤镜(filter)功能通过libavfilter库实现. 一个filter可以同时有多个输入和输出.以图为例: 图中的一系列操作共使用了四个filter,分别是    spli ...

  6. FFMpeg笔记(五) 录制小视频时几个问题解决

    1. YUV数据在使用avfilter scale时在特定的分辨率下UV分量不对 由于是小视频,那么分辨率不需要太高,但是有的视频源是1080p,甚至有的是4K的,所以对视频源进行scale非常有必要 ...

  7. FFMpeg笔记(三) 音频处理基本概念及音频重采样

    Android放音的采样率固定为44.1KHz,录音的采样率固定为8KHz,因此底层的音频设备驱动需要设置好这两个固定的采样率.如果上层传过来的采样率不符的话,需要进行resample重采样处理. 几 ...

  8. ffmpeg笔记——UDP组播接收总结

    ffmpeg在avformat_open_input里面已经实现了UDP的协议,所以只需要设置好参数,将url传递进去就可以了. 和打开文件的方式基本一样: 01 AVCodecContext *pV ...

  9. FFMpeg笔记(二) 使用FFmpeg对视频进行编解码的一般流程

    1. 编码: 1.对编码资源的初始化 AVCodec* m_pVideoEncoder;// 特定编码器的参数信息 AVCodecContext* m_pVideoEncoderContext;// ...

随机推荐

  1. 树莓派实现SIM868 ppp拨号上网

    环境:raspbian-stretch(2018-06-27) 树莓派:3代B型 SIM868模块具有GPRS数据传输功能(2G网络),但是模块是通过AT指令控制的,在树莓派上用AT指令控制会非常不方 ...

  2. 实现在vue中element-ui的el-dialog弹框拖拽

    参考:实现在vue中element-ui的el-dialog弹框拖拽 1.在 utils 中新建 directives.js 文件 import Vue from 'vue' // v-dialogD ...

  3. 洛谷 P1063 能量项链(区间DP)

    嗯... 题目链接:https://www.luogu.com.cn/problem/P1063 这道题首先要读懂题目,然后往上套区间dp,要转换成链式. AC代码: #include<cstd ...

  4. LeetCode练题——53. Maximum Subarray

    1.题目 53. Maximum Subarray——Easy Given an integer array nums, find the contiguous subarray (containin ...

  5. 理解CART决策树

    CART算法 原理 CART全称为Classification and Regression Tree. 回归树 相比ID3,CART遍历所有的特征和特征值,然后使用二元切分法划分数据子集,也就是每个 ...

  6. iOS 与 js交互的其一方法 WebViewJavascriptBridge的使用

    #import <WebViewJavascriptBridge.h> /// @interface ZWBridgeViewController ()<WKNavigationDe ...

  7. Springboot学习:SpringMVC自动配置

    Spring MVC auto-configuration Spring Boot 自动配置好了SpringMVC 以下是SpringBoot对SpringMVC的默认配置:==(WebMvcAuto ...

  8. 【代码总结】MYSQL数据库的常见操作

    ============================== MYSQL数据库的常见操作 ============================== 一.mysql的连接与关闭 -h:指定所连接的服 ...

  9. Spring Boot 学习方法论-如何正确的入门 Spring Boot

    想要入门 Spring Boot,那么什么样的教程是符合初学者学习的(没有太多的Java基础但有一些程序基础或者软件编程知识). 这恰好能够勾出很多问题,比如是文章图文教程适合还是视频教程适合零基础初 ...

  10. string的一些特殊点

    无论是String还是new String最终都指向了String constant pool中,只不过是String直接指向了Stringconstant pool中.而new String是在He ...