一、搭建ffmpeg环境
总有很多人想要了解学习音视频,却悻悻不知改从哪里入手,今天我们就一起来揭开它神秘的面纱😄。
刚一开始我们可以不用急着去编译源码、调试源码,那样子会遇到困难反而会半途而废;这里我们就直接使用命令来搭建ffmpeg环境,
mac下的命令如下:
brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-libass --with-libvorbis --with-libvpx --with-opus --with-x265
ubuntu下命令
sudo apt install ffmpeg
通过下面的命令,可以测试是否安装成功
ffplay
-f 用于指定文件格式. 可用”ffmpeg -formats”是看能支持的文件格式
-i 用于指定输入文件或设备名
-y 用于不用确认直接替换存在的输出文件
-t 用于指定输入或输出文件的持续时间.
-ss 用于指定视频文件从什么时间开始
-to 用于指定视频文件在什么时间结束
-vframes number 用于指定输出多少帧数据到输出文件
-framerate number 用于指定输入文件或设备的帧率
-r 用于指定输入或输出文件的帧率,多少帧每秒(fps)
// -re 是指按播放的速度来读取输入帧数据并传输
-s和-video_size 用于指定图像的分辨率, 如”-video_size 640x480”
// -video_size 只能用于指定输入文件或设备的分辨率, -s可用于指定输入和输出
-aspect 用于指定图像比例. “4:3”, “16:9”
-vn 用于指定没有视频图像输出.
-vcodec codec 用于指定输出文件使用什么编码格式. “-vcodec copy”表示使用原文件的编码格式, “-vcodec h264”表示使用h264编码
-pix_fmt 用于指定输入或输出的图像像素格式。可用”ffmpeg -pix_fmts”查看支持的像素格式.
-an 用于指定没有声音数据输出
-acodec codec 指定使用的声音编解码器
-b 100k 用于指定输出视频文件的码率为100k, 数字越大越清晰.
-b:v可用于指定视频的码率
-b:a 可用于指定音频的码率
ffmpeg -i source.mp4 -vcodec copy -an videoonly.mp4
ffmpeg -i output20.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 outh264.h264
ffmpeg -i thread12.mp4 -vcodec copy -map 0:0 test.h264
ffmpeg -i in.mp4 -ss 0 -t 10 -vn -acodec pcm_s16le -f s16le -ar 44100
-ac 1 a.pcm -ss 0 -t 10 -an -vcodec rawvideo -f rawvideo -s 640x480 -pix_fmtnv21 a.yuv
ffmpeg -i test.h264 -vcodec copy -f mp4 test.mp4
ffmpeg -i stereo25fps.mp4 -threads 6 -movflags faststart -vcodec h264 -b:v 500000 -r 25 -s 480x360 -pix_fmt yuv420p -allow_sw 1 -acodec copy -f mp4 thread_6.mp4
(time ffmpeg -y -threads 2 -i stereo25fps.mp4 -s 320x240 out290.mp4) 2>&1 | tee 1.txt
ffmpeg -i source.mp4 -acodec copy -vn audioonly.mp4
ffmpeg -i output20.mp4 -acodec copy -vn audioonly1.m4a
ffmpeg -i output20.mp4 -acodec copy -vn audioonly2.aac
ffmpeg -i zaoshenenzhi1.ts -vn -acodec copy -absf aac_adtstoasc zaoshenenzhi1.m4a
ffmpeg -i source1.mp4 -i audioonly.mp4 -f mp4 -map 0:0 -map 0:1 -map 1:0 -acodec aac -strict -2 -vcodec h264 mergeaudiotoanothermp4h264acc2.mp4
ffmpeg -i stereo25fps.mp4 -i h264_ape_25_44100.mp4 -map 0:0 -map 0:1 -map 1:1 stereo25fpss.mp4
注意输入的两个流的编码方式 及 帧率 是否一致;
ffmpeg -i face_aac.m4a -ab 64 stereo25fps.mp4 -ab 128 stereo25fps.mp4 -map 0:0 -map 1:0
把img.[001-100].jpg序列帧和001.mp3音频文件利用mpeg4编码方式合成视频文件darkdoor.avi:
$ ffmpeg -i 001.mp3 -i img.%3d.jpg -s 1024x768 -author test -vcodec mpeg4 test.avi
ffmpeg -ss START -t DURATION -i INPUT -vcodec copy -acodec copy OUTPUT
ffmpeg -ss 00:00:00 -t 00:00:30 -i test.mp4 -vcodec copy -acodec copy output.mp4
对上面的命令稍做个解释。
-ss 开始时间,如: 00:00:20,表示从20秒开始;
-t 时长,如: 00:00:10,表示截取10秒长的视频;如果不设定,表示裁剪到文件尾
-i 输入,后面是空格,紧跟着就是输入视频文件;
-vcodec copy 和 -acodec copy表示所要使用的视频和音频的编码格式,这里指定为copy表示原样拷贝;
INPUT,输入视频文件;
OUTPUT,输出视频文件;
每一帧图片从指定文件中
ffmpeg -i source3.mp4 -vcodec png -pix_fmt rgba foo-%03d.png
截图
每隔一秒截一张图
ffmpeg -i input.flv -f image2 -vf fps=1 out%d.png
每隔20秒截一张图
ffmpeg -i input.flv -f image2 -vf fps=fps=1/20 out%d.png
多张截图合并到一个文件里(2x3) 每隔一千帧(秒数=1000/fps25)即40s截一张图
ffmpeg -i jidu.mp4 -frames 3 -vf "select=not(mod(n\,1000)),scale=320:240,tile=2x3" out.png
另外,通过指定-ss,和-vframes也可以达到同样的效果。
这时候-ss参数后跟的时间有两种写法,hh:mm:ss 或 直接写秒数 :
ffmpeg -i test.asf -y -f image2 -ss 00:01:00 -vframes 1 test1.jpg
or
ffmpeg -i test.asf -y -f image2 -ss 60 -vframes 1 test1.jpg
使用-ss参数,可以从指定的时间开始处理转换任务.如:
ffmpeg -i test2.asf -y -f image2 -ss 08.010 -t 0.001 -s 352x240 b.jpg
那么从任意一帧截图的问题也就解决了.只要-ss后的时间参数是随机产生,并且在视频的有效时间内,就可以了.
ffmpeg -ss 5 -i input.mp4 -t 10 -c:v copy -c:a copy output.mp4
上面的命令把-ss 5放到-i前面,与原来的区别是,这样会先跳转到第5秒在开始解码输入视频,而原来的会从开始解码,只是丢弃掉前5秒的结果。 而-c:v copy -c:a copy标示视频与音频的编码不发生改变,而是直接复制,这样会大大提升速度,因为这样就不需要完全解码视频(视频剪切也不需要完全解码)。
不透明:
ffmpeg -ss 20 -t 3 -i stereo25fps.mp4 -vf scale=300:-1 -gifflags -transdiff bbb-notrans.gif
透明:
ffmpeg -ss 20 -t 3 -i stereo25fps.mp4 -vf scale=300:-1 -gifflags +transdiff bbb-trans.gif
上面两种动态gif都是只播一次,想让其无限循环播,可再加一个参数:-loop_output 0。
ffmpeg -f rawvideo -video_size 256x256 -pixel_format yuv444p -i allcolor_xu_yv_zy_256x256_yuv444p.yuv -vf alphaextract -pix_fmt rgba -vcodec png alphaextract444p.mp4
alphaextract
alphamerge
截取一张352x240尺寸大小的,格式为jpg的图片
ffmpeg -i test.asf -y -f image2 -t 0.001 -s 352x240 a.jpg
把视频的前30帧转换成一个Animated Gif
ffmpeg -i test.asf -vframes 30 -y -f gif a.gif
截取指定时间的缩微图
ffmpeg -i test.avi -y -f image2 -ss 8 -t 0.001 -s 350x240 test.jpg
-ss后跟的时间单位为秒
屏幕录制:
ffmpeg -f avfoundation -framerate 30 -i "1:0" \-f avfoundation -framerate 30 -video_size 640x480 -i "0" \-c:v libx264 -preset ultrafast \-filter_complex 'overlay=main_w-overlay_w-10:main_h-overlay_h-10' -acodec aac -ar 44100 -ac 1 -f flv flv.flv;ffplay flv.flv
音频视频合流
ffmpeg -i stereo25fps.mp4 -i h264_wmav2_200_15s.mp4 -filter_complex overlay=10:10 -filter_complex amix=inputs=2 h264_overlay_10_10_track2_AV_0.mp4
声音延迟 双声道要同时延迟
ffmpeg -i stereo25fps.mp4 -i h264_wmav2_200_15s.mp4 -filter_complex overlay=10:10 -filter_complex "adelay=5000|5000" h264_overlay_10_10_track2_V0_A5.mp4
amix 和 adelay 同时使用出错
ffmpeg -i stereo25fps.mp4 -i h264_wmav2_200_15s.mp4 -filter_complex overlay=10:10 -filter_complex "[1:a]adelay=5000|5000" -filter_complex amix=inputs=2 h264_overlay_10_10_track2_V0_A5_1a.mp4
reba 透明度
ffmpeg -i stereo25fps.mp4 -i png_rgba.mp4 -filter_complex "[1]geq=r='r(X,Y)':a='0.5*alpha(X,Y)'[a]"; [0][a] overlay output2.mp4
ffmpeg \
-i in1.mp4 -i in2.mp4 \
-filter_complex " \
[0:v]setpts=PTS-STARTPTS, scale=480x360[top]; \
[1:v]setpts=PTS-STARTPTS, scale=480x360, \
format=yuva420p,colorchannelmixer=aa=0.5[bottom]; \
[top][bottom]overlay=shortest=1" \
-acodec libvo_aacenc -vcodec libx264 out.mp4
ffmpeg -i 105moov.mp4 -i 105moov.mp4 -i mm -i 105moov.mp4 -strict -2 -filter_complex "[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=w[b];[b][2:v]overlay=0:h[c];[c][3:v]overlay=w:h" out.mp4
宽度变为2倍,右边黑边补充 480360变为960360 录制10s
ffmpeg -i output20.mp4 -strict -2 -t 10 -vf pad=2*iw:ih:0:0 outputpadwidth.mp4
pad 第一个参数为 输出视频的width,第二个参数为height,第三四个参数为视频左上角为原点的坐标;这里为坐标为(0,0),宽度为之前的2倍,高度不变;
指定时间点合成某图片
ffmpeg -i 105moov.mp4 -i mushroom.jpg -filter_complex "overlay=x='if(between(t,1,3),60,-500)':y=50" -f mp4 left1.mp4
源视频水平翻转,hflip为filter名字(vflip)
ffmpeg -i output20.mp4 -strict -2 -t 10 -vf hflip outputhflip.mp4
上下翻转
ffmpeg -i snapshot_6.png -strict -2 -vf vflip snapshot_6_vflip.png
How to rotate a video 180° with FFmpeg?
用ffplay直接观看结果:
ffplay -f lavfi -i testsrc -vf split[a][b];[a]pad=2*iw[1];[b]hflip[2];[1][2]overlay=w
F1: split过滤器创建两个输入文件的拷贝并标记为[a],[b]
F2: [a]作为pad过滤器的输入,pad过滤器产生2倍宽度并输出到[1].
F3: [b]作为hflip过滤器的输入,vflip过滤器水平翻转视频并输出到[2].
F4: 用overlay过滤器把 [2]覆盖到[1]的旁边.
ffmpeg –i input –r fps output
上面的命令,不论原始视频帧率是多少,输出视频都会是30帧每秒。这种情况之下视频的时间轴不会变化,不会有慢动作或快动作的效果。
ffmpeg -r 30 -i input.mp4 output.mp4
上面这种条换顺序之后的写法比较有意思,-r 30放在输入文件之前表示影响的是输入文件,而非输出文件。(这样子,视频帧会变快,音频流播放速度不变,导致音视频不同步。) 这样的命令表达的是,把输入文件当做30帧每秒,而忽略它的原始帧率。这样如果原来的视频FPS是25,被视作30之后,输出的视频会有快进的效果。 这个命令没有指定输出视频的FPS,默认会与输入文件保持一样,可以与本节第一个命令和在一起,写两个-r参数,第一个指定输入FPS,第二个指定 输出FPS即可既控制播放速度,又控制输出帧率。
ffmpeg -i clip.mpg -vf fps=fps=25 clip.webm
设置码率 –b 参数
ffmpeg -i film.avi -b 1.5M film.mp4
设置视频码率为1500kbps
ffmpeg -i input.avi -b:v 1500k output.mp4
-fs (file size首字母缩写)
ffmpeg -i input.avi -fs 1024K output.mp4
计算输出文件大小
(视频码率+音频码率) * 时长 /8 = 文件大小K
1)、用-s参数设置视频分辨率,参数值wxh,w宽度单位是像素,h高度单位是像素
ffmpeg -i input_file -s 320x240 output_file
ffmpeg -i "480360.mp4" -pix_fmt yuv420p -vcodec h264 -vsync 1 -s 960x540 -r 25 -acodec aac -async 1 960540_2.mp4
使用视频filter时,不可以处理音频流,故需要将其去掉,提示如下所示:
Filtergraph 'scale=960x540' was defined for audio output stream 0:1 but codec copy was selected.
Filtering and streamcopy cannot be used together.
用例:
ffmpeg -i "480360.mp4" -pix_fmt yuv420p -vcodec h264 -filter scale=960x540 -an -r 25 960540.mp4
2)、预定义的视频尺寸
下面两条命令有相同效果
ffmpeg -i input.avi -s 640x480 output.avi
ffmpeg -i input.avi -s vga output.avi
3) 在未知视频的分辨率时,保证调整的分辨率与源视频有相同的横纵比。
宽度固定400,高度成比例:
ffmpeg -i input.avi -vf scale=400:400/a
ffmpeg -i input.avi -vf scale=400:-1
相反地,高度固定300,宽度成比例:
ffmpeg -i input.avi -vf scale=-1:300
ffmpeg -i input.avi -vf scale=300*a:300
4.创建一个30个像素的粉色宽度来包围一个200*200尺寸的图片jpg
ffmpeg -i mushroom.jpg -vf pad=260:260:30:30:pink framedphtot.jpg
ffmpeg -i framedphtotp.png -vf unsharp=13:13:-2 framedphtotpunsharp.png
语法:-vf unsharp=l_msize_x:l_msize_y:l_amount:c_msize_x:c_msize_y:c_amount
所有的参数是可选的,默认值是5:5:1.0:5:5:0.0
l_msize_x:水平亮度矩阵,取值范围3-13,默认值为5
l_msize_y:垂直亮度矩阵,取值范围3-13,默认值为5
l_amount:亮度强度,取值范围-2.0-5.0,负数为模糊效果,默认值1.0
c_msize_x:水平色彩矩阵,取值范围3-13,默认值5
c_msize_y:垂直色彩矩阵,取值范围3-13,默认值5
c_amount:色彩强度,取值范围-2.0-5.0,负数为模糊效果,默认值0.0
语法:boxblur=luma_r:luma_p[:chroma_r:chram_p[:alpha_r:alpha_p]]
ffplay -f lavfi -i testsrc -vf boxblur=1:10:4:10
注意:luma_r和alpha_r半径取值范围是0~min(w,h)/2, chroma_r半径的取值范围是0~min(cw/ch)/2
语法:overlay[=x[:y]
所有的参数都是可选,默认值都是0
右上角
ffmpeg -i output20.mp4 -i framedphtotp.png -strict -2 -filter_complex overlay=W-w pair00.mp4
左下角:overlay=0:H-h 右下角:overlay=W-w:H-h 左上角:overlay
显示多幅图片(不同位置)
ffmpeg -y -i boss.mp4 -i left.png -i left.png -filter_complex "overlay=5:5,overlay=0:0" -f mp4 output.mp4
-filter_complex:使用复合滤镜
“overlay=5:5,overlay=0:0”:第一个图片的x、y坐标为(5,5),第二个为(0,0)
ffmpeg -y -i 1.avi -i 1.png -filter_complex "overlay=x='if(between(t,1,3),60,-500)':y=50" -f mp4 left1.mp4
命令行中可以使用表达式,参考:http://ffmpeg.org/ffmpeg-all.html#Expression-Evaluation
具体意思是时间t在1到3秒内,图片的x坐标为60,否则为-500(移出屏幕),y坐标一直为50不变
ffmpeg -i ogg.ogg -i 1.avi -filter_complex "adelay=3000|3000" output.avi
-filter_complex “adelay=3000|3000”:对前面的ogg音频的两个声道都延迟3000毫秒
http://ffmpeg.org/ffmpeg-all.html#adelay
ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex amix=inputs=3:duration=first:dropout_transition=3 OUTPUT
inputs=3:三个输入
duration=first:输出长度为第一个输入的长度
dropout_transition=3:声音淡出时间为3秒
语法:-vf delogo=x:y:w:h[:t[:show]]
x:y 离左上角的坐标
w:h logo的宽和高
t: 矩形边缘的厚度默认值4
show:若设置为1有一个绿色的矩形,默认值0.
ffplay -i jidu.mp4 -vf delogo=50:51:60:60:100:0
如果你想要一个变换的字幕,那么无疑外挂字幕是最合适的。外挂字幕格式很多种,纯文本的就有srt, ssa, ass,二进制的有sub(DVD的外挂字幕用的是这种)。最简单的是srt字幕,就是电影字幕那种效果。如果你想带点效果,那么只好用ass了,很多动漫OP字幕特效用的就是ass字幕特效。
详细参考官方文档: HowToBurnSubtitlesIntoVideo
ffmpeg -i pair00.mp4 -strict -2 -vf subtitles=rgb.srt outputs.mp4
rgb.srt 文件
1
00:00:00,000 —> 00:00:03,000
大家好,我是宅鸟
2
00:00:05,000 —> 00:00:09,000
我们可以使用ffmpeg,在视频中嵌入字幕
3
00:00:11,000 —> 00:00:15,000
http://www.cnblogs.com/duwei/p/ffmpeg_commands.html
ffmpeg -pix_fmts|grep rgb
ffmpeg -codecs | grep jpeg
ffmpeg -i img.png -pix_fmt rgb8 -vcodec png img_rgb8.png
ffmpeg -i img0.jpg -filter_complex scale=1:1 img1_1.png
http://davidaq.com/tutorial/2014/11/20/ffmpeg-commands.html
http://326301045.iteye.com/blog/2172957
一种方法是连接到一起
ffmpeg64.exe -i "concat:123.mp3|124.mp3" -acodec copy output.mp3
解释:-i代表输入参数
contact:123.mp3|124.mp3代表着需要连接到一起的音频文件
-acodec copy output.mp3 重新编码并复制到新文件中
另一种方法是混合到一起
ffmpeg64.exe -i 124.mp3 -i 123.mp3 -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f mp3 remix.mp3
解释:-i代表输入参数
-filter_complex ffmpeg滤镜功能,非常强大,详细请查看文档
amix是混合多个音频到单个音频输出
inputs=2代表是2个音频文件,如果更多则代表对应数字
duration 确定最终输出文件的长度
longest(最长)|shortest(最短)|first(第一个文件)
dropout_transition
The transition time, in seconds, for volume renormalization when an input stream ends. The default value is 2 seconds.
-f mp3 输出文件格式
音频文件截取指定时间部分
ffmpeg64.exe -i 124.mp3 -vn -acodec copy -ss 00:00:00 -t 00:01:32 output.mp3
解释:-i代表输入参数
-acodec copy output.mp3 重新编码并复制到新文件中
-ss 开始截取的时间点
-t 截取音频时间长度
音频文件格式转换
ffmpeg64.exe -i null.ape -ar 44100 -ac 2 -ab 16k -vol 50 -f mp3 null.mp3
解释:-i代表输入参数
-acodec aac(音频编码用AAC)
-ar 设置音频采样频率
-ac 设置音频通道数
-ab 设定声音比特率
-vol <百分比> 设定音量
ffmpeg -i face_mp3.mp3 -ar 44100 -ac 2 -ab 1413 -acodec pcm_s16be -f caf o.caf
ffmpeg -i in.mov -vf "transpose=1" out.mov
转置的参数文件,可以使用:
0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip
slice 线程个数
ffmpeg -i stereo25fps.mp4 -threads 12 outputT12.mp4
-threads:1 4将会把第二个流的线程数设置为 4.
使用ffmpeg录像屏幕
ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s 1024x768 ~/test.avi
:其中,-vd x11:0,0 指录制所使用的偏移为 x=0 和 y=0,-s 1024×768 指录制视频的大小为 1024×768。录制的视频文件为 test.avi,将保存到用户主目录中
如果你只想录制一个应用程序窗口或者桌面上的一个固定区域,那么可以指定偏移位置和区域大小。使用xwininfo -frame命令可以完成查找上述参数。
重新调整视频尺寸大小
ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -i ~/test.avi -s 800×600 ~/test-800-600.avi
注:ffmpeg的屏幕录制功能只能在Linux环境下有效。
视频采集
把摄像头的实时视频录制下来,存储为文件
ffmpeg -f video4linux -s 320*240 -r 10 -i /dev/video0 test.asf
ffmpeg -i face_pcm_s16be.caf -i message_pcm_s16be.caf -filter_complex amix=inputs=2:duration=longest:dropout_transition=2 -ab 12.2k -ar 8000 -ac 1 1_2.mp3
ffmpeg -i face_pcm_s16le.wav -i aac_vorbis30.wav -filter_complex "amovie=1.wav [l]; amovie=2.wav [r]; [l] [r] amerge" 1_2_amerge.mp3
ffmpeg -i message_pcm_s16be.caf -i message_pcm_s16be.caf -filter_complex amix=inputs=2:duration=longest:dropout_transition=2 -ab 14.1k -ar 44100 -ac 2 1_1.mp3
ffmpeg -ss 00:00:18.300 -i music.mp3 -loop 1 -i bg.mp4 -i ac%d.png -i dust.mp4 -filter_complex "[1:0]scale=1600:ih*1200/iw, crop=1600:900[a];[a][2:0] overlay=0:0[b]; [3:0] scale=1600:ih*1600/iw, crop=1600:900,setsar=1[c]; [b][c] blend=all_mode='overlay':all_opacity=0.2" -shortest -y output.mp4
Declaring the inputs:
ffmpeg -ss 00:00:18.300 -i music.mp3 -loop 1 -i bg.mp4 -i ac%d.png -i dust.mp4
Adding the filter complex. First part: [1,0] is the second element of the inputs (bg.mp4) and scaling to get the max values, and then cropping with the size I need, the result of this opperation, is in the [a] element.
[1:0]scale=1600:ih*1600/iw, crop=1600:900, setsar=1[a];
Second Part: Put the PNGs sequence over the resized video (bg.mp4, now [a]) and saving the resunt in the [b] element.
[a][2:0] overlay=0:0[b];
Scaling and cropping the fourth input (overlay.mp4) and saving in the [c] element.
[3:0]scale=1600:ih*1600/iw, crop=1600:900,setsar=1[c];
Mixing the first result with the overlay video with an “overlay” blending mode, and with an opacity of 0.1 because the video has gray tones and makes the result so dark.
[b][c] blend=all_mode=’overlay’:all_opacity=0.1
使用ffmpeg的silenceremove滤镜移除MP3文件首尾的静音,文件开头的静音能够移除,但文件末尾的一直没处理好
ffmpeg -i a.mp3 -af silenceremove=1:0:-50dB:1:0:-50dB out.mp3
采用上面的命令,结果把从中间静音开始到末尾的音频都抹掉了。
如果是 ffmpeg -i a.mp3 -af silenceremove=1:0:-50dB:-1:0:-50dB out.mp3
则把所有的静音全抹掉了。
ffmpeg -i input.mp3 -af aecho=0.8:0.9:1000:0.3 output.mp3
ffplay -fflags nobuffer -i input.mp4
generated by haroopad