FFmpeg是很是强大的音视频处理工具,咱们可使用它来处理视频合成、剪辑、加特效等等操做。html
官方文档至上 FFmpeg的官方文档git
FFmpeg的官方文档命令真的是太多太多,并且都是英文,感受精通完这些命令,都够学一门新语言了!github
SO 为了让一些小伙伴们快速的用上FFmpeg,我整理了一些FFmpeg的经常使用的知识和大部分平常用到的命令供你们查阅!算法
还不收藏吗?废话很少说上干货!bash
FFmpeg的环境集成挺麻烦的推荐你们使用这个库,一键集成FFmpeg! Skr~ide
RxFFmpeg工具
在音视频领域,咱们把一路音/视频称为一路流。如咱们小时候常用VCD看港片,在里边能够选择粤语或国语声音,其实就是CD视频文件中存放了两路音频流,用户能够选择其中一路进行播放。oop
咱们熟悉的mp4,rmvb,mkv,avi是多媒体容器文件格式(或称多媒体封装格式),所谓容器是指将不一样的数据流(视频流,音频流,字幕流等)封装在一个文件(载体)中。 播放时各类流分别进行解码等处理后,而后输出到显示器和音响等设备进行播放。多媒体容器格式不一样于编码格式,一个容器中能够封装多种编码格式的媒体流。 流封装了实际的媒体数据,如视频流,音频流和字幕流等。通常状况下,流中的数据只能使用一种编码格式。性能
是音频中的概念,称之为声道。在一路音频流中,能够有单声道,双声道或立体声。测试
帧率(frames per second, fps)是每秒画面刷新的次数,帧率越高视频越流畅。通常来讲30fps就是能够接受的,60fps则能够明显提高交互感和逼真感,可是通常超过75fps通常就不容易察觉到有明显的流畅度提高了。
分辨率表示画面的精细程度,一般用像素密度来表示,经常使用的单位为ppi(像素每英寸)。一般像素密度越高画面越精细,模糊程度越低。对于视频文件而言,像素密度是没法控制的(由播放器和显示设备决定)。咱们一般用视频的像素数来表示它的分辨率如1080x640, 640x320等。
比特率(bit rate)又称码率,表示多媒体流每秒输出的字节数,单位为KB/s,Kbps等。一样的压缩算法下,比特率越高音视频的质量越好。
指的是编码器的输出码率能够根据输入源信号的复杂度进行自适应调整,以在输出质量保持不变的条件下尽量减小数据量。VBR适用于存储,不太适用流式传输。
指的是编码器输出码率固定,CBR不适合存储,对于复杂内容可能没有足够码率进行编码,从而致使质量降低,同时会在简单内容部分浪费一些码率。
每秒钟对音频信号的采样次数,采样频率越高声音还原度越高,声音更加天然,单位是赫兹 Hz。音频文件通常使用的采样率是 44.1kHz,也就是一秒钟采样44100次,实验发现低于这个值就会有较明显的损失,而高于这个值人的耳朵已经很难分辨,并且增大了数字音频所占用的空间。
视频流能够看作图片的序列,咱们把这个序列中的一张图片称为一帧。若存储视频中全部帧则会数据量过大,不便于存储和传输。所幸统计代表大多数视频相邻帧之间的区别并不大,因此对于一段变化不大的视频,咱们能够先完整编码帧A,其后的B帧只须要编码与A帧不一样的部分,B帧后的C帧则只编码与B帧的差别。如此递推,将一段视频编码为一个序列。当某个图像与以前的图像变化很大没法参考前面的帧来生成,咱们就结束上一个序列将该帧完整编码开始一个新的序列。
过滤器会对已解码的帧进行处理,处理后的帧会被从新编码输出
指定操做源的大小,iw指定按整型取视频的宽度,ih指定按整型取视频的高度。-1为按原图比例变化 例:iw/2:-1视频缩小一倍
指定操做源摆放的位置 overlay=30:10 main_w和main_h为底层视频的宽和高,overlay_w和overlay_h为叠加视频的宽和高
删除水印 例:delogo=x=800:y=20:w=70:h=80
裁剪 格式:crop=out_w:out_h: x :y out_w: 输出的宽度。可使用 in_w 表式输入视频的宽度。 out_h: 输出的高度。可使用 in_h 表式输入视频的高度。 x : X坐标 y : Y坐标 x和y 设置为 0,说明从左上角开始裁剪。若是不写是从中心点裁剪
setpts=0.5*PTS表示每帧视频的pts时间戳都乘0.5,也就是视频加快一倍
可用于处理复杂输出,如能够将指定的多路流输出到一个输出文件,也能够指定输出到多个文件。"[v]" 复杂滤镜输出的别名做为输出文件的一路流。上面 map的用法是将复杂滤镜输出的视频和音频输出到指定文件中。
crop=iw/2:ih:0:0,split[left][tmp];[tmp]hflip[right]
curves='vintage'(复古) 'strong_contrast'(强对比度)'lighter'(变亮) 'negate'(底片) 'none' 'color_negative'(彩色底片);
colorlevels=rimin=0.058:gimin=0.058:bimin=0.058
fftfilt=dc_Y=0:weight_Y='exp(-4 * ((Y+X)/(W+H)))
hqdn3d=luma_spatial=15.0
fftfilt=dc_Y=0:weight_Y='1+squish(1-(Y+X)/100)'
fftfilt=dc_Y=0:weight_Y='squish((Y+X)/100-1)'
fftfilt=dc_Y=128:weight_Y='squish(1-(Y+X)/100)'
例:fade=in:0:25, fade=out:975:25 从0桢开始淡入25帧,从975开始淡出25帧 fade=in:5:20:color=yellow 开始淡入前为黄色 fade=in:0:25:alpha=1 淡入完成后过去15帧的透明度 fade=t=in:st=5.5:d=0.5 5.5秒开始,淡入0.5秒 d为时长
fps滤镜经过删除帧或者复制帧的方法强制设置帧率 例:ffmpeg -y -i test.mp4 -vf "fps=60" out.mp4
ffmpeg -i out.mp4 -y out.avi
视频转Gif
ffmpeg -i out.mp4 -y out.gif
从0开始截10s转Gif
ffmpeg -i out.mp4 -ss 00:00:00 -t 10 -y out.gif
ffmpeg -i input_test.mp4 -vf fps=1 out%03d.png
ffmpeg -i input_test.mp4 -vf fps=1/60 out%03d.png
ffmpeg -ss 2 -i test.mp4 -t 10 -y -f out_test.mp4
截取从2s开始10秒的视频
ffmpeg -i test.mp4 -c copy -map 0 -f segment -segment_time 10 video/part-%d.mp4
ffmpeg -ss 2 -i test.mp4 -r 1 -t 2 -y -f image2 image-%3.jpeg
ffmpeg -loop 1 -i img%3d.png -t 10-y output.mp4
ffmpeg -i input.gif -y output.mp4
ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4
ffmpeg -i input_test.mp4 -s 320*240 out_test.mp4
ffmpeg -i input.mp4 -i input1.mp3 -y output.mp4
ffmpeg -i test.mp4 -vn -a:c copy out.mp3
ffmpeg -i input.mp4 -vn -vcodec copy output.mp4
ffmpeg -i "concat:test1.mp3|test2.mp3" -acodec copy output.mp3
ffmpeg -i input_01.wav -i input_02.wav -filter_complex amix=inputs=2:duration=shortest:dropout_transition=3 output.wav
以两个音频文件时长较短的音频文件时长做为最终输出的时长
ffmpeg -y -i test.mp4 -vf "drawtext=fontfile=CourierNew.ttf:text='hello world':x=100:y=50:fontsize=24" out.mp4
因为Android端字体库的缘由,我能够经过把文字转成图片,再加到视频上的方式来添加,如下是文字转图片的源码:
/**
* 文本转成Bitmap
* @param text 文本内容
* @param context 上下文
* @return 图片的bitmap
*/
private static Bitmap textToBitmap(String text , Context context) {
float scale = context.getResources().getDisplayMetrics().scaledDensity;
TextView tv = new TextView(context);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(layoutParams);
tv.setText(text);
tv.setTextSize(scale * TEXT_SIZE);
tv.setGravity(Gravity.CENTER_HORIZONTAL);
tv.setDrawingCacheEnabled(true);
tv.setTextColor(TEXT_COLOR);
tv.setBackgroundColor(Color.WHITE);
tv.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
tv.buildDrawingCache();
Bitmap bitmap = tv.getDrawingCache();
int rate = bitmap.getHeight() / 20;
return Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/rate, 20, false);
}
/**
* 文字生成图片
* @param filePath filePath
* @param text text
* @param context context
* @return 生成图片是否成功
*/
public static boolean textToPicture(String filePath, String text , Context context){
Bitmap bitmap = textToBitmap(text , context);
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(filePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
return false;
}finally {
try {
if(outputStream != null){
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
复制代码
添加单个图片水印
ffmpeg -i input.mp4 -i water.png -filter_complex "[0:v][1:v]overlay=main_w-overlay_w-10:10" -y output.mp4
添加多个图片水印
ffmpeg -i input.mp4 -i photo1.png -i photo2.png -filter_complex "[0:v]fade=in:st=0:d=2,curves=vintage[img];[1:v]scale=300:-1[img1];[img][img1]overlay=10:10[out1];[out1][2:v]overlay=main_w:main_h" -y output.mp4
添加了两张图片图片,第一张设置为宽度300,高度-1为根据原图片比例缩放,在视频左上角,第二张图片在视频右下角,fade是淡入淡出效果器,视频效果为从0s开始淡入,淡入2s,视频为复古效果curves=vintage
ffmpeg -i video2.mp4 -i logo.png -filter_complex "[1:v]scale=50*50[logo];[0:v]scale=200*200[bg];[bg][logo]overlay=x='if(gte(t,0),-overlay_w+(mod(n,main_w+overlay_w))+5,NAN)':y=0" -y output.mp4
含义: 时间t大于0,那么就开始从子内容的宽度的x-overlay_w位置开始,而后每一帧n计数,帧数n除以(背景main_w+子内容背景overlay_w)求除数+1设置为x坐标,便可循环 overlay=30:10 main_w和main_h为底层视频的宽和高,overlay_w和overlay_h为叠加视频的宽和高
ffmpeg -i test.flv -vf delogo=x=20:y=20:w=70:h=80 output.flv
x,y :指定水印的位置,即图片左上角的坐标 w,h:给出水印的宽高
ffmpeg -y -i test.mp4 -t 10 -loop 1 -framerate 6 -i test_%3d.png -filter_comple 'overlay=10:main_h-overlay_h-10' out.mp4
将多张图片(test_001.png, ani002.png...)组成动画, 而后将这个动画叠加在视频的左下角。-t 10 -loop 1会循环播放动画,持续10s
ffmepg -i input.wav -filter_complex afade=t=in:ss=0:d-4 output.wav
(淡入)把 input 文件的前5s 作一个淡入效果,输出到 output.wav 中
ffmpeg -i input.wav -filter_complex afade=t=out:st=200:d=5 output.wav
(淡出)将input.wav文件从200s开始,作5s的淡出效果,并放到output.wav文件中
ffmpeg -i input.flv -c:v libx264 -b:v 800k -c:a libfdk_aac -vf eq=brightness=0.25 -f mp4 output.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 output.mp4
对比度参数是contrast,取值范围是从-2.0到2.0,默认值是1.0
ffmpeg -i input.mp4 -an -vf "crop=480:480:120:0" -vcodec libx264 -b:v 800k output.mp4
ffmpeg -i input.mp4 -vf "transpose=1" -b:v 600k output.mp4
ffmpeg -i input.mp4 -af 'volume=0.5' output.mp4
视频压缩主要是改变视频的码率和分辨率去压缩,可是须要控制好缩小的码率和分辨率,以保证视频的质量符合你的需求 ffmpeg -i input.mp4 -b:v 600k -y output.mp4
FFmpeg十分强大,本文的知识只是FFmpeg的一小部分,对于初识FFmpeg的同窗用于常见的视频操做仍是彻底OK的,精通音视频仍是有很长的路要走,更多的FFmpeg知道请移步FFmpeg的官方文档!
欢迎靓仔靓女们收藏一波,谢谢~