使用FFmpeg命令处理音视频
文章目录
- 前言
- 一、ffprobe相关命令
- 1.使用ffprobe查看音频文件的信息
- 2.使用ffprobe查看视频文件的信息
- 二、ffplay相关命令
- 1.基本的ffplay命令
- 2.音视频同步命令
- 三、ffmpeg相关命令
- 1.ffmpeg通用参数
- 2.ffmpeg视频参数
- 3.ffmpeg音频参数
- 4.ffmpeg示例
- 总结
前言
FFmpeg是一套可以用来记录处理数字音频,视频,并将其转换为流的开源框架,提供了录制,转换以及流化音视频的完整解决方案.可以用在Linux服务器,Windows,MacOS X等PC上以及Android和IOS等移动端设备.跨平台特性非常强大.本节主要介绍如何使用FFmpeg命令处理音视频.
如上图所示,本文主要介绍ffmprob,ffplay,ffmpeg三类命令的使用,读者可以自己手动敲下这些命令实践下,当用熟悉这些命令,对音视频的开发调试会特别方便.
一、ffprobe相关命令
ffprobe用于查看媒体文件的头信息.
1.使用ffprobe查看音频文件的信息
示例: 查看音频信息
ffprobe sunday-jayzhou.mp3
运行截图:
运行命令后结果如上图所示,我们主要看下下面这行信息:
Duration: 00:04:29.79, start: 0.025057, bitrate: 320 kb/s
这行信息表明,该音频时长为4分29秒790毫秒,开始播放的时间是0.025057,比特率是320kb/s.
接着看紧跟着的下一行:
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
这行信息表明第一个流是音频流,编码格式为MP3格式,采样率是44100 HZ,声道为立体声,采样表示格式是float的4字节平铺格式,这路流的比特率是320 kb/s
2.使用ffprobe查看视频文件的信息
示例:查看视频信息
ffprobe sunday-jayzhou.mp4
运行截图:
我们只关注重点的信息,输入上面的命令后,我们可以找到这样一部分信息:
Metadata:
major_brand : isom
minor_version : 1
compatible_brands: isomavc1
creation_time : 2012-10-21T06:38:01.000000Z
album : Yinyuetai
artist : yinyuetai.com
comment : Yinyuetai Fukai
date : 10/21/12 02:38:02
这部分信息是该文件的Metadata信息,就是视频的一些基础的信息
然后接下来的一行是:
Duration: 00:05:16.39, start: 0.000000, bitrate: 781 kb/s
这行信息表明,视频的时长是5分16秒390毫秒,开始时间是0,比特率是781 kb/s
紧接着:
Stream #0:0(chi): Video: h264 (Main) (avc1 / 0x31637661), yuv420p,
576x432, 682 kb/s, 23 fps, 23 tbr, 23k tbn, 46 tbc (default)
这行信息表示第一个stream是视频流,编码方式是h264格式(封装格式是AVC1)每一帧的数据表示是YUV420P的格式,分辨率是576x432,这路流的比特率是682 kb/s,帧率是每秒23帧
扩展知识:tbr代表帧率;1200k tbn代表文件层(st)的时间精度,和duration相关; tbc代表视频层(st->codec)的时间精度,和strem->duration和时间戳相关
看了视频流我们再看下该MP4文件中的音频流:
Stream #0:1(chi): Audio: aac (HE-AAC) (mp4a / 0x6134706D), 44100 Hz,
stereo, fltp, 95 kb/s (default)
上面的信息表示第二个流是音频流,编码方式是aac(封装格式是mp4a),采样率是44100 Hz,声道是立体声,数据表示格式是浮点型平铺格式,比特率为95 kb/s
示例:输出视频的格式信息
ffprobe -show_format sunday-jayzhou.mp4
运行截图:
上面的命令可以输出格式信息format_name,时间长度duration,文件大小size,比特率bit_rate,流的数目nb_stream等
示例:以json形式输出具体每一个流的详细信息
ffprobe -print_format json -show_streams sunday-jayzhou.mp4
运行这个命令会得到一个json格式的信息,里面会包含视频的宽高信息,是否有B帧,视频帧的总数目,视频的编码格式,显示比例,比特率等信息,音频中会有音频的编码格式,表示格式,声道数,时间长度,比特率,帧的总数目等信息.
示例:显示视频的帧信息
ffprobe -show_frames sunday-jayzhou.mp4
运行截图:部分
利用这个命令可以查看视频每一帧的信息
示例:查看包信息
ffprobe -show_packets sunday-jayzhou.mp4
运行截图:部分
二、ffplay相关命令
ffplay 是以FFmpeg框架为基础,外加渲染音视频的库libSDL来构建的媒体文件播放器.所以在安装ffplay之前需要安装对应版本的libSDL作为其依赖的组件,然后就可以使用ffplay播放媒体文件了,这个命令相当强大,比需要付费才能用的播放器爽多了.
1.基本的ffplay命令
示例:播放音频文件
ffplay sunday-jayzhou.mp3
运行截图:
运行命令的时候会弹出一个窗口,一边播放MP3文件一边播放声音的语谱图画,在该窗口中,右键点击任意一个位置,ffplay会根据点击的位置计算出时间进度,然后跳到这个时间点播放,按空白键是暂停,键盘左键默认会后退10秒,键盘右键默认会快进10秒,按上键默认快进1分钟,下键默认后退1分钟,按ESC键是退出,按W键可以切换音频的波形图和谱图:
谱图:
音频波形图:
示例:ffplay播放视频
ffplay sunday-jayzhou.mp4
运行此条命令会直接在新弹出的窗口上播放该视频,如果想同时播放多个视频,只需多开几个命令行,同时执行上面的命令就行了,这样可以对比多个视频的质量,如果在视频播放的窗口范围内按下S键,则会进入frame-step模式,即按S键一次就会播放下一帧图像
示例:循环播放视频
ffplay sunday-jayzhou.mp4 -loop 3
运行这个命令视频会在播放结束后从头再次播放共循环播放3次
ffplay 也可以指定使用某一路音频流或者视频流
示例:播放第一路音频流
ffplay sunday-jayzhou.mp4 -ast 1
如果ast参数后面跟的是2,那么就播放第二路音频流,如果没有第二路音频流的话就会静音.
示例:播放第一路视频流
ffplay sunday-jayzhou.mp4 -vst 1
如果vst后面跟的是2,就表示播放第二路视频流,如果没有第二路视频流,就会是黑屏什么也不显示
示例:播放pcm音频文件
ffplay sunday.pcm -f s16le -channels 2 -ar 44100
需要注意的是,格式(-f),声道数(-channel)和采样率(-ar)必须设置正确,否则得不到正常的播放效果:原因是,如果是WAV格式的音频文件,可以直接播放,而WAV格式其实就是在PCM的头部加44个字节,用于标识PCM数据的采样表示格式,声道数和采样率等信息.,所以播放PCM的话,需要添加这三个主要的信息才能正常播放
示例:播放YUV420P格式的视频帧
ffplay -f rawvideo -pixel_format yuv420p -s 1280*720 xxx.yuv
yuv的测试数据太大,我没找到能用的数据,有兴趣的读者可以自己去找找播放下试试.我找到的话会分享的
参数解释:
-f rawvideo:表示原始格式
-pixel_format yuv420p:表示格式
-s 1280*720:表示视频宽高
ffplay还可以播放图片:
示例:播放一张rgb的原始数据
ffplay -f rawvideo -pixel_format rgb24 -s 1280*720 xxx.rgb
2.音视频同步命令
我们平时使用的视频播放器,都毫无疑问的有个很重要的问题,那就是音画同步,在ffplay中的音画同步的实现方式有3种,分别是以音频为主时间轴作为同步源,以视频为主时间轴作为同步源,以外部时钟为主时间轴作为同步源.
假设以音频为主时间轴作为同步源,同步对其策略如下
当播放器接收到视频帧或者是音频帧的时候,内部都会有展示时间戳,(PTS),用于表示它实际应该在什么时候进行展示.音画的对齐策略为:比较视频当前的播放时间和音频当前的播放时间,如果视频播放过快,则通过加大延迟或者是重复播放来降低视频播放速度,如果视频播放慢了,则通过减小延迟或者丢帧来追赶音频播放的时间点.关键在于音频时间的比较以及延迟的计算,在比较的过程中会设置一个阈值,若超过阈值就应该做出调整.
示例:指定ffplay以音频为准进行音视频同步,播放MP4视频
ffplay sunday-jayzhou.mp4 -sync audio
上面的命令添加了参数-sync audio,这也是ffplay的默认参数,写和不写都是一样的效果
示例:指定ffplay 以视频为准进行音视频同步播放MP4视频
ffplay sunday-jayzhou.mp4 -sync video
示例:以外部时钟作为音视频同步的方式播放视频
ffplay sunday-jayzhou.mp4 -sync ext
三、ffmpeg相关命令
ffmpeg是三个命令行工具中最强大的一个,它可以转换任何格式的媒体文件,并且可以用自己的AudioFilter以及VideoFilter进行处理和编辑.我们接下来先看下总体的参数:
1.ffmpeg通用参数
-f fmt: 指定格式(音频或者视频格式)
-i filename: 指定输入文件名
-y: 覆盖已有文件
-t duration: 指定时长
-fs limit size: 设置文件大小的上限
-ss time_off:从指定的时间开始(以秒为单位)
-re: 代表按照帧率发送,尤其是在作为推流工具的时候一定要加入这个参数,否则ffmpeg会按照最高速率向流媒体服务器发送数据
-map: 指定输出文件的流映射关系.例如:“-map 1:0 -map 1:1” ,表示将第二个输入文件的第一个流和第二个流写入输出文件
2.ffmpeg视频参数
-b: 指定比特率(bit/s),ffmpeg是自动使用VBR的,若指定了这个参数则使用平均比特率
-bitexact: 使用标准比特率
-vb: 指定视频比特率
-r rate: 帧速率(fps)
-s size: 指定分辨率(1280x720)
-aspect aspect:设置视频的长宽比(4:3.16:9或者1.3333,1.7777
-croptop size: 设置顶部切除尺寸(使用像素表示)
-cropbottom size:设置底部切除尺寸(使用像素表示)
-corpleft size: 设置左切除尺寸(使用像素表示)
-cropright size: 设置右切除尺寸(使用像素表示)
-padtop size: 设置顶部补齐尺寸(使用像素表示)
-padbottom size: 设置底部补齐尺寸(使用像素表示)
-padleft size:左补齐(使用像素表示)
-padright size:右补齐(使用像素表示)
-padcolor color: 补齐带颜色(000000-FFFFFF)
-vn: 取消视频输出
-vcodec codec: 强制使用codec编解码方式(‘copy’ 代表不进行重新编码
3.ffmpeg音频参数
-ab: 设置比特率(单位:bit/s,老版本的单位可能是Kbit/s),对于MP3格式,若要听到较高品质的声音,建议设置为160Kbit/s(单声道设置为80Kbit/s)以上
-aq: 设置音频质量(指定编码)
-ar rate:设置音频采样率(单位为Hz)
-ac channels:设置声道数,1是单声道,2是立体声
-an: 取消音频轨
-acodec codec:指定音频编码('copy’表示不做音频转码,直接复制)
-vol volume:设置录制音量大小(默认为256)(百分比)
4.ffmpeg示例
示例:列出ffmpeg 支持的所有格式
ffmpeg -formats
示例:剪切一段媒体,可以是视频或者音频文件
ffmpeg -i sunday-jayzhou.mp4 -ss 00:00:50.0 -codec copy -t 20 out.mp4
这条命令表示将视频sunday-jayzhou.mp4从第50秒开始剪切20秒时间,输出到文件out.mp4中,其中 -ss指定偏移时间(time offset),-t 指定时长(duration)
假设我们录制了一段较长的视频在微信中无法分享,因为微信分享长视频有限制,那么我们可以使用ffmpeg将视频切割为多个文件
ffmpeg -i sunday-jayzhou.mp4 -t 00:00:50 -c copy small-1.mp4 -ss 00:00:50 -codec copy small-2.mp4
结果
示例:提取视频文件中的音频文件
ffmpeg -i small-1.mp4 -vn -acodec copy sunday.m4a
示例:使视频中的音频静音,即只保留视频
ffmpeg -i small-1.mp4 -an -vcodec copy zxj.mp4
上面的代码执行后会在当前目录下生成一个zxj.mp4,这个视频文件就是没有声音的
示例:从MP4 文件中抽取视频流导出为裸H264数据
ffmpeg -i small-1.mp4 -an -vcodec copy -bsf:v h264_mp4toannexb zhongxj.h264
注意,使用ffplay播放这个,h264文件是没有声音的,因为它是纯视频裸数据
示例:使用AAC音频数据和H264视频生成MP4文件
ffmpeg -i test.aac -i test.h264 -acodec copy -bsf:a aac_adtstoasc -vcodec copy -f mp4 out.mp4
示例:对音频编码格式做转换
ffmpeg -i input.wav -acodec libfdk_aac output.aac
示例:从WAV音频文件中导出PCM裸数据
ffmpeg -i input.wav -acodec pcm_s16le -f s16le output.pcm
示例:重新编码视频文件,复制音频流,同时封装到MP4格式的文件中
ffmpeg -i input.flv -vcodec libx264 -acodec copy out.mp4
示例:将一个MP4格式的视频转换成gif格式的动态图
ffmpeg -i input.mp4 -vf scale=100:-1 -t 5 -r 10 image.gif
上面的命令按照分辨率不动,宽度改为100(使用VideoFilter的scaleFilter),帧率改为10(-r),只处理前5秒(-t)的视频生成gif
示例:将视频的画面部分生成图片,可用于视频每一帧的分析
ffmpeg -i input.mp4 -r 0.25 frames_%04d.png
上面的命令,每4秒钟节前一帧视频画面部分生成图片,生成的图片从frames_0001.png一直递增下去
示例:将一组图片组成gif
ffmpeg -i frames_%04d.png -r 5 out.gif
示例:使用音量效果器改变音频媒体文件的音量
ffmpeg -i input.wav -af 'volume=0.5' out.wav
将input.wav的音量减少一半输出到out.wav中
示例:将音频文件的前5秒做一个淡入效果,输出到out.wav中
ffmpeg -i input.wav -filter_complex afade=t=in:ss=0:d=5 out.wav
示例:将input.wav从第200秒开始,做5秒的淡出效果,输出到out.wav中
ffmpeg -i input.wav -filter_complex afade=t=out:st=200:d=5 out.wav
示例:将两路声音进行合并,比如给一段声音加背景音乐
ffmpeg -i vocal.wav -i accompany.wav -filter_complex amix=inputs=2:duration=shortest out.wav
将vocal.wav和accompany.wav两个文件进行混合按照时间长度较短的音频文件的时间长度作为最终输出的out.wav的时间长度.
示例:对声音进行变速但是不变调,将input.wav按照0.5倍的速度处理生成out.wav,时间长度会变为输入的两倍,但是音高是不变的
ffmpeg -i input.wav -filter_complex atempo=0.5 out.wav
示例:为视频增加水印
ffmpeg -i input.mp4 -i water_mark.png -filter_complex '[0:v][1:v]overlay=main_w-overlay_w-10:10:1[out]' -map
'[out]' out.mp4
上面命令的参数中main_w代表主视频宽度,overlay_w代表水印宽度,main_h代表主视频高度,overlay_h代表水印高度
示例:为视频做提亮效果
ffmpeg -i input.flv -c:v libx264 -b:v 800k -c:a libfdk_aac -vf eq=brightness=0.25 -f mp4 out.mp4
提亮参数是brightness,取值范围是-1.0到1.0,默认为0
示例:为视频增加对比度
ffmpeg -i input.flv -c:v libx264 -b:v 800k -c:a libfdk_aac -vf eq=contrast=1.5 -f mp4 out.mp4
对比度参数是contrast,取值范围是-2.0到2.0,默认为1.0
示例:为视频做旋转效果
ffmpeg -i input.mp4 -vf "transpose=1" -b:v 600k out.mp4
示例:视频裁剪效果器使用
ffmpeg -i input.mp4 -an -vf "crop=240:480:120:0" -vcodec libx264 -b:v 600k out.mp4
示例:将一张RGBA格式表示的数据转换为JPEG格式的图片
ffmpeg -f rawvideo -pix_fmt rgba -s 480*480 -i texture.rgb -f image2 -vcodec mjpeg out.jpg
示例:将一张yuv格式表示的数据转换为jpeg格式.
ffmpeg -f rawvideo -pix_fmt yuv420p -s 480*480 -i texture.yuv -f image2 -vcodec mpeg out.mp4
将一段视频推送到媒体服务器上
ffmpeg -re -i input.mp4 -acodec copy -vcodec copy -f flv rtmp://xxxx
上面的代码中,rtmp://xxx代表流媒体的服务器地址,加上-re参数表示将实际媒体文件的播放速度作为推流速度进行推送
示例:将流媒体上的流dump到本地
ffmpeg -i http://xxx/xxx.flv -acodec copy -vcodec copy -f flv out.flv
上面的代码中,http://xxx/xxx.flv代表一个可以访问的视频网络地址,可以按照复制视频流格式和音频流格式的方式将文件下载到out.flv中
示例:将两个音频文件以两路流的形式封装到一个文件中,比如在K歌场景中,原唱和伴唱实时切换,可以使用一个文件包含两路流,一路原唱流,一路伴唱流
ffmpeg -i A.mp3 -i B.mp3 -map 0:a -c:a:0 libfdk_aac -b:a:0 96k -map 1:a -c:a:1 libfdk_aac -b:a:1 64k -vn
-f mp4 out.m4a
总结
以上就是今天要讲的内容,本文仅仅简单介绍了ffprobe,ffplay,ffmpeg的使用,其实FFmpeg命令工具随意组合的话有很多种.本文中只是列举了部分.如果我们弄清楚了FFmpeg 能做什么,那么其具体的使用其实就一目了然了,只要是FFmpeg框架能够实现的功能,都可以使用FFmpeg命令行工具将其提供出来.如果读者对FFmpeg有更好的见解和体会,欢迎一起交流讨论.