音视频开发

FFMPEG进阶系列02-ffmpeg命令详解3

2018-10-04  本文已影响347人  C_GO流媒体后台开发

更多音视频知识请点击专注音视频开发

ffmpeg 的封装转换

FFmpeg的封装转换部分,主要是通过libavformat这部分来完成的功能,通过libavformat库进行mux和demux操作,多媒体文件的格式有很多种,但是还是有好多demux与mux的操作参数是公用的,下面来详细介绍一下这些公用的参数:
通过查看ffmpeg的help full参数,找到AVFormatContext参数部分,在这个参数下面的所有的参数均为封装转换可使用的参数

ffmpeg的编转码

FFmpeg的编解码部分主要是通过libavcodec这个库来完成的功能,通过libavcodec库进行encode与decode操作,多媒体的编码格式种类很多,但是还是有好多基本的操作参数是共同可以设置的,下面来详细介绍一下这些公用的参数:
通过查看ffmpeg的help full参数可以看到AVCodecContext AVOptions,在这个选项下面的所有参数均为编解码可以使用的参数:

ffmpeg 的基本编转码原理

ffmpeg工具主要用途为编码、解码、转码,常用ffmpeg做的为转码操作,使用ffmpeg转码主要原理为:


转码原理

通过前两节介绍的参数,可以设置转码的相关参数,如果转码操作则涉及到封装的改变,从而可以通过设置AVCodec与AVFormat的操作参数进行封装与编码的改变,下面举一个例子:ffmpeg.exe -i test.mp4 -vcodec mpeg4 -b:v 1000k -r 15 -acodec copy output.mp4
编码为mpeg4 视频码流为1000k,帧率为15,音频不变

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 1
    compatible_brands: isom
    creation_time   : 2015-05-06T01:12:21.000000Z
    encoder         : FormatFactory : www.pcfreetime.com
  Duration: 00:00:11.01, start: 0.000000, bitrate: 2364 kb/s
    Stream #0:0(und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 968x544 [SAR 1:1 DAR 121:68], 2252 kb/
s, 25 fps, 25 tbr, 25k tbn, 25 tbc (default)
    Metadata:
      creation_time   : 2015-05-06T01:12:21.000000Z
      handler_name    : video
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
    Metadata:
      creation_time   : 2015-05-06T01:12:21.000000Z
      handler_name    : sound
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg4 (native) -> mpeg4 (native))
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
Output #0, mp4, to 'output.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 1
    compatible_brands: isom
    encoder         : Lavf58.12.100
    Stream #0:0(und): Video: mpeg4 (mp4v / 0x7634706D), yuv420p, 968x544 [SAR 1:1 DAR 121:68], q=2-31, 1000 kb/s, 15 fps
, 15360 tbn, 15 tbc (default)
    Metadata:
      creation_time   : 2015-05-06T01:12:21.000000Z
      handler_name    : video
      encoder         : Lavc58.18.100 mpeg4
    Side data:
      cpb: bitrate max/min/avg: 0/0/1000000 buffer size: 0 vbv_delay: -1
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
    Metadata:
      creation_time   : 2015-05-06T01:12:21.000000Z
      handler_name    : sound
Past duration 0.799995 too large
frame=  166 fps=0.0 q=1.6 Lsize=    1585kB time=00:00:11.00 bitrate=1180.4kbits/s dup=0 drop=107 speed=22.9x
video:1410kB audio:169kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.361811%
左边为原视频,右边为转码后的视频

如果视频转码为h264,命令使用:ffmpeg.exe -i test.mp4 -vcodec mpeg4 -b:v 1000k -r 15 -acodec copy output.mp4


mpeg4和h264对比

过滤器链(filter chain)

语法:filter chain=逗号分隔的一组filter

  1. 第一步:源视频宽带扩大两倍
    ffmpeg -i test.mp4 -t 10 -vf pad=2*iw output.mp4


    output.mp4播放效果
  2. 第二步:源视频水平翻转
    ffmpeg -i test.mp4 -t 10 -vf hflip output2.mp4


    output2.mp4水平翻转
  3. 第三步:水平翻转视频覆盖output.mp4
    ffmpeg -i output.mp4 -i output2.mp4 -filter_complex overlay=w compare.mp4


    compare.mp4效果

码率/帧率和文件大小

帧率

  1. 用-r参数设置帧率
    格式:ffmpeg -i input -r fps output
    范例:ffmpeg-i test.mp4 -r 15 output.mp4
  2. 用fps filter设置帧率
    格式:ffmpeg -r input -vf fps=
    范例:ffmpeg.exe -i test.mp4 -vf fps=fps=25 output.mp4
  3. 帧率的预定义值:
‘ntsc’
30000/1001 
‘pal’
25/1 
‘qntsc’
30000/1001 
‘qpal’
25/1 
‘sntsc’
30000/1001 
‘spal’
25/1 
‘film’
24/1 
‘ntsc-film’
24000/1001 
ffmpeg -i test.mp4 -r 29.97 output.mp4
ffmpeg -i test.mp4 -r 3000/1001 output.mp4
ffmpeg -i test.mp4 -r ntsc output.mp4

帧率和文件大小

  1. 设置码率-b参数
  1. 控制输出文件大小
  1. 计算输出文件大小

调整视频分辨率

调整视频分辨率

  1. 用-s 或-video_size参数设置视频分辨率,参数值WxH, W宽度单位是像素,H高度单位是像素
    ffmpeg -i test.mp4 -s 320x240 output.mp4
  2. 预定义的视频尺寸
‘ntsc’
720x480 
‘pal’
720x576 
‘qntsc’
352x240 
‘qpal’
352x288 
‘sntsc’
640x480 
‘spal’
768x576 
‘film’
352x240 
‘ntsc-film’
352x240 
‘sqcif’
128x96 
‘qcif’
176x144 
‘cif’
352x288 
‘4cif’
704x576 
‘16cif’
1408x1152 
‘qqvga’
160x120 
‘qvga’
320x240 
‘vga’
640x480 
‘svga’
800x600 
‘xga’
1024x768 
‘uxga’
1600x1200 
‘qxga’
2048x1536 
‘sxga’
1280x1024 
‘qsxga’
2560x2048 
‘hsxga’
5120x4096 
‘wvga’
852x480 
‘wxga’
1366x768 
‘wsxga’
1600x1024 
‘wuxga’
1920x1200 
‘woxga’
2560x1600 
‘wqsxga’
3200x2048 
‘wquxga’
3840x2400 
‘whsxga’
6400x4096 
‘whuxga’
7680x4800 
‘cga’
320x200 
‘ega’
640x350 
‘hd480’
852x480 
‘hd720’
1280x720 
‘hd1080’
1920x1080 
‘2k’
2048x1080 
‘2kflat’
1998x1080 
‘2kscope’
2048x858 
‘4k’
4096x2160 
‘4kflat’
3996x2160 
‘4kscope’
4096x1716 
‘nhd’
640x360 
‘hqvga’
240x160 
‘wqvga’
400x240 
‘fwqvga’
432x240 
‘hvga’
480x320 
‘qhd’
960x540 
‘2kdci’
2048x1080 
‘4kdci’
4096x2160 
‘uhd2160’
3840x2160 
‘uhd4320’
7680x4320 

scale filter调整分辨率

1.下面两条命令有相同效果
ffmpeg -i input.mp4 -s 320x240 output.mp4
ffmpeg -i input.mp4 -vf scale=320:240 output.mp4
2. 输出视频为源视频的宽高的一半大小
ffmpeg -i input.mp4 -vf scale=iw/2:ih/2 output.mp4
3. 输出视频为源视频的宽高的90%
ffmpeg -i input.mp4 -vf scale=iw0.9:ih0.9 output.mp4
4. 在未知视频的分辨率时,保证调整的分辨率与源视频有相同的横纵比

裁剪/填充视频

裁剪视频crop filter

从输入文件中选取你想要的矩形区域到输出文件中,常见用来去视频黑边。 语法:crop:ow[:oh[:x[:y:[:keep_aspect]]]]   


举例

自动检测裁剪区域

ffplay input.mp4 -vf cropdetect

[Parsed_cropdetect_0 @ 12922cc0] x1:0 x2:967 y1:0 y2:543 w:960 h:544 x:4 y:0 pts:2000 t:0.080000 crop=960:544:4:0
[Parsed_cropdetect_0 @ 12922cc0] x1:0 x2:967 y1:0 y2:543 w:960 h:544 x:4 y:0 pts:3000 t:0.120000 crop=960:544:4:0
[Parsed_cropdetect_0 @ 12922cc0] x1:0 x2:967 y1:0 y2:543 w:960 h:544 x:4 y:0 pts:4000 t:0.160000 crop=960:544:4:0
[Parsed_cropdetect_0 @ 12922cc0] x1:0 x2:967 y1:0 y2:543 w:960 h:544 x:4 y:0 pts:5000 t:0.200000 crop=960:544:4:0

得到 crop=960:544:4:0
然后用检测到的值来裁剪视频
ffplay input.mp4 –vf crop=960:544:4:0

填充视频(pad)

说明:在视频帧上增加一快额外额区域,经常用在播放的时候显示不同的横纵比
语法:pad=width[:height:[:x[:y:[:color]]]]


视频纵横比4:3到16:9

1. 4:3到16:9

2. 16:9到4:3

翻转和旋转

翻转

旋转

模糊,锐化

模糊

注意:luma_r和alpha_r半径取值范围是0~min(w,h)/2, chroma_r半径的取值范围是0~min(cw/ch)/2

锐化

覆盖(画中画)

覆盖,

ffmpeg -i input.mp4 -i logo.png -filter_complex "[1:v][0:v]scale2ref=(iw/ih)*ih/8/sar:ih/8[wm][base];[base][wm]overlay=10:10" pair11.mp4 ffmpeg -i Titanic.ts -i logo.png -filter_complex "[1:v][0:v]scale2ref=(iw/ih)*ih/8/sar:ih/8[wm][base];[base][wm]overlay=10:10" pair12.mp4 ffmpeg -i Titanic.ts -i logo.png -filter_complex "[1:v][0:v]scale2ref=ih/8/sar:ih/8[wm][base];[base][wm]overlay=10:10" pair13.mp4

右上角:    
ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=W-w pair2.mp4
左下角:
ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=0:H-h pair2.mp4
右下角:
ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=W-w:H-h pair2.mp4

删除logo

ffplay -i pair1.mp4 -vf delogo=5:5:60:60:0

添加文本

动态文本

用 t (时间秒)变量实现动态文本

  1. 顶部水平滚动

    ffplay -i input.mp4 -vf drawtext="fontfile=arial.ttf:text='Dynamic RTL text':x=w-t*50:fontcolor=darkorange:fontsize=30" image.png
  2. 底部水平滚动

    ffplay -i input.mp4 -vf drawtext="fontfile=arial.ttf:text='Dynamic RTL text':x=w-t*50:y=h-th:fontcolor=darkorange:fontsize=30"
  3. 垂直从下往上滚动

    ffplay input.mp4 -vf drawtext="fontfile=arial.ttf:text='Dynamic RTL text':x=(w-tw)/2:y=h-t*100:fontcolor=white:fontsize=30"
  4. 实现右上角显示当前时间?

    • 动态文本 在右上角显示当前时间 localtime

      ffplay input.mp4 -vf drawtext="fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text='%{localtime:%H\:%M\:%S}'"
    • 每隔3秒显示一次当前时间

      ffplay input.mp4 -vf drawtext="fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text='%{localtime:%H\:%M\:%S}':enable=lt(mod(t,3),1)" image.png

图片处理

图片支持

FFmpeg支持绝大多数图片处理, 除LJPEG(无损JPEG)之外,其他都能被解码,除了EXR,PIC,PTX之外,所有的都能被编码。

ffmpeg -f lavfi -i smptebars smpte.png image.png ffmpeg -i rgb.png -i smpte.png -filter_complex overlay=(W-w)/2:(H-h)/2 rgb_smpte.png image.png

其他高级技巧

屏幕录像

[dshow @ 0136d680] DirectShow video devices (some may be both video and audio devices)
[dshow @ 0136d680]  "Integrated Webcam"
[dshow @ 0136d680]     Alternative name "@device_pnp_\\?\usb#vid_0bda&pid_5689&mi_00#6&233dd6c7&0&0000#{65e8773d-8f56-11
d0-a3b9-00a0c9223196}\global"
[dshow @ 0136d680]  "screen-capture-recorder"
[dshow @ 0136d680]     Alternative name "@device_sw_{860BB310-5D01-11D0-BD3B-00A0C911CE86}\{4EA6930A-2C8A-4AE6-A561-56E4
B5044439}"
[dshow @ 0136d680] DirectShow audio devices
[dshow @ 0136d680]  "楹﹀厠椋?(Realtek Audio)"
[dshow @ 0136d680]     Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{2BC3D9A6-4A74-4179-9DDC
-3E0B44B5FA5E}"
[dshow @ 0136d680]  "virtual-audio-capturer"
[dshow @ 0136d680]     Alternative name "@device_sw_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\{8E14549B-DB61-4309-AFA1-3578
E927E935}"
dummy: Immediate exit requested

获取到摄像头为:"Integrated Webcam"
屏幕录制为:"screen-capture-recorder"

ffplay -i input.mp4 -vf crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2+((in_h-out_h)/2)*sin(n/7)
ffplay -i input.mp4 -vf hue="H=2*PI*t:s=sin(2*PI*t)+1"

马赛克视频

ffmpeg  -i cuc_ieschool.flv -i  input.mp4 -i Titanic.ts -i ds.mov -filter_complex "nullsrc=size=640x480 [base]; [0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]; [1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright]; [2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft]; [3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright]; [base][upperleft] overlay=shortest=1 [tmp1]; [tmp1][upperright] overlay=shortest=1:x=320 [tmp2]; [tmp2][lowerleft] overlay=shortest=1:y=240 [tmp3]; [tmp3][lowerright] overlay=shortest=1:x=320:y=240" -c:v libx264 output.mkv

Logo动态移动

ffplay -i cuc_ieschool.flv  -vf movie=logo.png[logo];[in][logo]overlay=x='if(gte(((t-2)*80)-w\,W)\,0\,((t-2)*80)-w)':y=0
ffmpeg -y -t 60 -i cuc_ieschool.flv -i logo.png -i logo2.png -filter_complex "overlay=x=if(lt(mod(t\,20)\,10)\,10\,NAN):y=10,overlay=x=if(gt(mod(t\,20)\,10)\,W-w-10\,NAN ) :y=10" overlay.mp4

更多资料,更多分享

音视频技术交流群1 已满
音视频技术交流群2 已满
音视频技术交流群3 群号782508536

参考

[1] ffmpeg:编解码过程,基本用法
[2] http://www.ffmpeg.org/ffmpeg-utils.html
[3] FFmpeg Filters官方文档

上一篇 下一篇

猜你喜欢

热点阅读