ffmpeg命令行

windows环境下,下载static版本解压即可使用ffmpeg,但是ffplay播放audio的时候需要设置环境变量 SDL_AUDIODRIVER=directsound

 

FFmpeg command-line tools

 

ffmpeg

fast audio and video encoder/decoder

ffplay

media player

ffprobe

shows media files characteristics

ffserver

broadcast server for multimedia streaming using HTTP and RTSP protocols

 

 

FFmpeg software libraries

 

libavcodec

software library for various multimedia codecs 

用于各种类型声音/图像编解码

libavdevice

software library for devices

libavfilter

software library containing filters

libavformat

software library for media formats

用于各种音视频封装格式的生成和解析,包括获取解码所需信息以生成解码上下文结构和读取音视频帧等功能,包含demuxers和muxer库;

libavutil

software library containing various utilities

包含一些公共的工具函数;

libpostproc

software library for post processing

用于后期效果处理;

libswresample

software library for audio resampling

libswscale

software library for media scaling

 

ffmpeg command line

基本语法(ffmpeg -h full   或者 man ffmpeg)

ffmpeg -i

 

 

 

1.FFmpeg的转码流程是什么?

2.常见的视频格式包含哪些内容?

3.如何把这些内容从视频文件中抽取出来?

4.如何从一种格式转换为另一种格式?

5.如何放大和缩小视频?

6.如何旋转,翻转,填充,裁剪,模糊,锐化视频?

7.如何给视频加logo,删除logo?

8.如何给视频加文本,动态文本?

9.如何处理图片?

10.如何录像,添加动态logo,截图,马赛克视频?

 

 

容器(Container): 容器就是一种文件格式,比如flv,mkv等。包含文件头信息以及5种流。

流(Stream) : 是一种视频数据信息的传输方式,5种流:音频,视频,字幕,附件,数据。

帧(Frame) : 帧代表一幅静止的图像,分为I帧,P帧,B帧。

编解码器(Codec) : 是对视频进行压缩或者解压缩,CODEC =COde (编码) +DECode(解码)

复用/解复用(mux/demux) : 把不同的流按照某种容器的规则放入容器,这种行为叫做复用(mux) 把不同的流从某种容器中解析出来,这种行为叫做解复用(demux)

 

ffprobe

  • ffprobe sintel.ts    查看一个文件的信息
  • ffprobe -show_format abc.mp4   格式化显示文件的基本信息
  • ffprobe -print_format json -show_streams abc.mp4   以json格式显示文件中的流信息
  • ffprobe -print_format json -show_frames abc.mp4    以json格式显示文件中的frame(解码了的packet)信息
  • ffprobe -print_format json -show_packets abc.mp4  以json格式显示文件中的包(未解码的frame)信息

ffplay

  • ffplay abc.mp4  播放文件,播放过程中可以:点击(seek),右键(快进10s),左键(快退10s),上键(快进1min),下键(快退1min),w(绘制audio波形),s(frame-step模式,每按s播放一帧,p继续播放)。q/esc退出
  • ffplay abc.mp4 -loop 10   播放结束后从头再播,loop 10 次
  • ffplay abc.mp4 -ast 1 -vst 0  播放文件中的第二路audio和第一路video
  • ffplay abc.pcm -f s16le -channels 2 -ar 44100   播放raw pcm audio 文件,-f 指定格式,-channels 指定通道数,-ar指定采样率
  • ffplay -f rawvideo -pixel_format yuv420p -s 480*480 abc.yuv 播让 raw yuv video 文件,-f指定格式,-pixel_format 指定表示格式, -s指定宽高
  • ffplay -f rawvideo -pixel_format rgb24 -s 480*480 abc.rgb
  • ffplay abc.mp4 -sync audio  播放文件,默认就是以audio为时间轴做同步(还可以选择 video/ext)

ffmpeg

-f     指定格式,-i之前指示输入文件格式,-i之后指定输出文件格式。eg. mpegts(普通文件), v4l2, x11grab, alsa
-i   指定输入文件名。eg. abc.mp4,/dev/video0(摄像头),:0.0(屏幕的(0,0)偏移处),pulse(麦克风)
-ss xxx    从指定时间开始(秒)(输入为普通文件时常用)
-t xxx     指定时长(秒)(输入为普通文件时常用)
-re      按照帧率发送,作为推流工具时需要加入此参数,否则按最高速率不停发送
-map 0:0    map本身指代一路输出流(后方跟输出文件),指示第0个输入的第0个stream(可通过ffprobe查看)
-y      覆盖已有输出文件
-fs    设置大小上限
  • ffmpeg -formats   显示可用的容器格式(demux / mux)
  • ffmpeg -codecs 显示可用的编解码器 (eg.DEV.LS,  D表示decoder,E 表示 encoder,V 表示 video)
  • ffmpeg -i sintel.ts 查看一个文件的信息
ffmpeg -i abc.mp4
-ss 00:00:15 -t 10    //从15秒开始,截取10s
-c copy
out.mp4
//剪切视频
ffmpeg -i abc.mp4
-vn -acodec copy     //video丢弃,audio 不做转码
out.aac
//抽取audio stream
ffmpeg -i abc.mp4 
-an
-vcodec copy -bsf:v h264_mp4toannexb    //使用h264_mp4toannexb这个bit stream filter转换为原始h264数据
out.h264
//抽取video stream 并导出为裸的h264数据包
ffmpeg -i test.aac -i test.h264
-acodec copy -bsf:a aac_adtstoasc
-vcodec copy
-f mp4 out.mp4
//使用aac音频和h264视频合成mp4

使用map

ffmpeg -i abc.ts -i def.ts
-map 0:0    //#0输入的stream0(abc的video),-map 0:v可以指代所有video stream
-map 0:1    //#0输入的stream1(abc的第一路audio),-map 0:a 可以指代所有audio stream
-map 0:1    //#0输入的stream1(abc的第一路audio,第二路audio被丢弃)
-map 1:0    //#1输入的stream0(def的stream0)
-map 1:1    //#1输入的stream1(def的stream1)
-c copy      //对所有码流默认做copy处理
-c:v libx264    //对所有video码流默认编码为h264
-c:a:0 libmp3lame -b:a:0 128k    //特定于第0个audio,编码为mp3(128kbps)
-c:a:1 libfaac -b:a:1 96k        //特定于第1个audio,编码为aac(96kbps)
-c:v:1 mpeg2video    //特定于第1个video,编码为mp2
out.ts    //out.ts中流的顺序会和map顺序一致
//使用abc.ts和def.ts合成一路 out.ts,并对其中的码流做转码处理
ffmpeg -i abc.mp4
-filter_complex "[0:0] scale=100x100[smaller_sized]" -map "[smaller_sized]"
out.mp4
//结合滤镜,map指定滤镜输出,作为输出stream
ffmpeg -i abc.mkv
-map 0:0
-c copy    //不加也可,默认就是copy
video_only.mkv
-map 0:1 -map 0:2
-c copy
audio_only.mkv
ffmpeg -i abc.ts -i def.ts
-map 0:0 -map 0:1 -map 1:0 -map 0:2    //分别是st0,st1,st2,st3
-c copy
-program title=pro001:program_num=1:st=0:st=1
-program title=pro002:program_num=2:st=2:st=3
-f mpegts two_program.ts
//创建具有多个program的ts流

 关于 map的使用(eg精确指定输入的哪一路stream)可以参考这里  https://blog.csdn.net/xiaoluer/article/details/81136478

使用 video filter

[a]pad=width:high:x:y:color[b]
宽和高指的是结果视频尺寸(b),xy指的是源视频添加到结果视频所在位置,color为填充颜色,输入视频(a)的宽高为iw*ih

overlays视频叠加, [a][b]overlay=x:y[c]
-i input0.mp4 -i input1.avi -filter_complex overlay=x:y output.mp4
-i input0.mp4 -i input1.avi -filter_complex "[0:0][1:0]overlay=x:y" output.mp4
将前景窗口(第二输入b,宽高为overlay_w/w overlay_h/h)覆盖在
背景窗口(第一输入a,宽高为main_w/W main_h/H)的指定位置(水平x,垂直y)
"overlay=x='if(gte(t,2),(t-2)*20-w,NAN)':y=0"

[a]scale=640:320[b]
对输入视频a的宽高做缩放得到结果视频b,也可写作 [a]scale=640x320[b]

[a]crop=320:240:0:0[b]
剪裁 视频源a 中 0:0开始的320*240的矩形,作为输出 b

[a]hflip[b]
将源视频做horizon镜像翻转

[a]split[b][c]
根据输入a 产生bc两份拷贝
//[0:0]缩放后放在左下角,[0:6]缩放后放在左上角,[0:4]水平翻转并缩放后占据整个右边。
//最终视频的尺寸是640*480
ffmpeg -i 411.ts        \
-filter_complex "[0:0] scale=320:240[a];[a]pad=2*iw:2*ih:0:ih[b];       \
                 [0:4] hflip,scale=320:480[c];[b][c]overlay=320:0[d];           \
                 [0:6] scale=320:240[e];[d][e]overlay=0:0[o]"           \
-map "[o]"      \
-map 0:1        \
-c:v libx264 -c:a mp2   \
-y out.ts
#左上角是第一路摄像头,右上角是第二路摄像头
#下方播放视频文件
ffmpeg -f v4l2 -i /dev/video0 -f v4l2 -i /dev/video1 -i cuc_ieschool.mkv  \
-filter_complex "[0:0] scale=320:240[a];[a]pad=2*iw:3*ih[b];       \
                 [1:0] scale=320:240[c];[b][c]overlay=320:0[d];           \
                 [2:v] scale=640:480[e];[d][e]overlay=0:240[o]"           \
-map "[o]"      \
-c:v libx264 -c:a mp2   \
-y out.ts
#使用ffmpeg推流,左上角是第一路摄像头,右上角是第二路摄像头
#下方是视频文件播放,声音也来自视频文件
ffmpeg -re  \
-f v4l2 -i /dev/video0 -f v4l2 -i /dev/video1 -i cuc_ieschool.mkv  \
-filter_complex "[0:0] scale=320:240[a];[a]pad=2*iw:3*ih[b];       \
                 [1:0] scale=320:240[c];[b][c]overlay=320:0[d];           \
                 [2:v] scale=640:480[e];[d][e]overlay=0:240[o]"           \
-map "[o]"      \
-map 2:a      \
-c:v libx264 -c:a mp2   \
-f mpegts udp://127.0.0.1:1234

#使用ffplay播放ffmpeg的处理结果
#ffplay -protocol_whitelist "file,udp,rtp" -i udp://127.0.0.1:1234
#https://blog.csdn.net/zhoubotong2012/article/details/86711097
ffmpeg -i test1.mp4 -i test2.mp4 -i test3.mp4 -i test4.mp4
-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
fplay p629100.mp3 -af atempo=0.5    //audio filter 0.5倍速率进行播放

ffplay -i cuc_ieschool.mkv -vf setpts=PTS/3 -af atempo=3
将一段视频按照3倍速率播放,音频也是3倍速率。时长缩减为原来的1/3

ffplay -i sintel.ts -vf transpose=1   //使用 ffplay播放一个视频,-vf 使用 video filter 将输入顺时针旋转90度后再播放

ffplay -i sintel.ts -vf hflip //使用 ffplay播放一个视频,-vf 使用 video filter 将输入做horizon镜像翻转后再播放

ffplay -i sintel.ts -vf hflip,transpose=1   //使用 ffplay播放一个视频,-vf 使用 video filter 将输入视频先镜像翻转,再旋转,最后播放

ffmpeg -i sintel.ts -t 10 -vf pad=2*iw output.ts  

使用ffmpeg处理输入视频,-t 处理输入视频的前10s,-vf 使用 video filter 将源视频宽度扩大两倍得到output.ts

(-y有强制覆盖的意思) pad=width:high:x:y:color,宽和高指的是结果视频尺寸,xy指的是源视频添加到结果视频所在位置,color为填充颜色

(结果是视频右侧被填充了与源视频等宽的黑色,高度没变)

ffmpeg -i sintel.ts -t 10 -vf hflip output2.ts 

使用 ffmpeg处理输入视频,-t 处理输入视频的前10s,-vf 使用 video filter 将源视频做horizon镜像翻转 得到output2.ts

-filter_complex 参数解析认为:  w就是最后输入的width,等同overlay_w。W为最先输入的width,等同 main_w。(height同理)   [0:v] 就是第0号输入的video流,[0:1]第0号输入的第1号流。

ffmpeg -i output.ts -i output2.ts -filter_complex overlay=w output3.ts  

使用 ffmpeg处理两个输入视频,-filter_complex 使用 video filter 将 1号输入覆盖到0号输入, 覆盖起始位置在 w:0 处。

ffplay -i sintel.ts -vf "split[a][b];[a]pad=2*iw[1];[b]hflip[2];[1][2]overlay=w"   

使用ffmplay播放视频,播放前使用video filter处理:split[a][b]根据输入 产生ab两份拷贝,[a]pad=2*iw[1]   a路输入经过pad=2*iw处理得到[1],  [b]hflip[2]  b路经过hflip处理得到[2],    [1][2]overlay=w     [2]号覆盖到[1]上,覆盖起始位置w:0   (这个和刚刚使用ouput.ts + output2.ts 得到output3.ts是等同了,只不过此处没有使用复杂过滤器,ffmpeg推荐复杂过滤器,效率高)

ffmpeg -i sintel.ts -filter_complex scale=320:320 -y out.ts 

处理输入视频,将视频源缩放到320:320大小,然后输出

ffmpeg -i sintel.ts -filter_complex crop=320:240:0:0 -y out.ts    

 处理输入视频,剪裁 视频源中 0:0开始的320*240的矩形,作为输出

 

ffmpeg -i sintel.ts -i frame23.ppm -filter_complex overlay=w/2 -y output.ts  

将一张ppm格式的图片贴到ts视频流 w/2:0 的位置这个w应该就是所贴图片的width)

ffmpeg -i a.ts -i frame23.ppm -filter_complex "overlay=(main_w-overlay_w)/2+t*20:0" -y out2.ts  

将一张图片贴到视频流,x起始位置在正中, 且随着时间推移向右移动

ffmpeg -i a.ts -i frame23.ppm -filter_complex "overlay=x='if(gte(t,2),10,NAN)':(main_h-overlay_h)/2" -y out2.ts      

将一张图片贴到视频流,当t>2秒时开始贴,贴到x=10位置,y在正中央

ffmpeg -i a.ts -i frame23.ppm -filter_complex "[1:v]scale=100:100[img1];[0:v][img1]overlay=x='if(gte(t,2),10,NAN)':(main_h-overlay_h)/2" -y out2.ts     

将一张图片贴到视频流,两路输入分别为0,1。 对1号输入的视频信息(就是那个图片了)缩放到100*100得到img1,再将img1覆盖到0号输入的视频流中,贴到x=10, y在正中央。t>2时才开始贴

ffmpeg -i sintel.ts -i abc.ts -filter_complex "[1:v]scale=100:100[vv];[0:v][vv]overlay=(main_w-overlay_w):0" -y out-pip.ts

将1号输入的video流缩放到100*100得到流vv,再将vv覆盖到0号输入的右上角,搞出一个类似pip的效果

 

从容器中抽取流(还是使用map)

ffmpeg -i sintel.ts -strict -2 -y sintel.mp4   

格式转换的时候ffmpeg会默认从输入文件中抽取最高质量的video流和audio流组合到输出文件中
(-strict -2 只是ffmpeg aac格式是实验性质的,强制使用就加上,可忽略)
ffmpeg -i Titanic.mkv -map 0:0  out.ts 

将输入文件中0号节目的视频流原封不动拷贝到out.ts,
音频流被丢弃(-map 0:v  也是指代0号节目中的video)
ffmpeg -i Titanic.mkv
-map 0:0 -map 0:1 -map 0:1
-c:v mpeg2video
-c:a:0 mp2 -b:a:0 128k
-c:a:1 copy -b:a:1 96k
out.ts    

输入文件经过 -map 0:0 -map 0:1 -map 0:1 处理得到一路video stream 和 两路audio,
-c:v mpeg2video 指定节目中的 video流的 codec 使用 mpeg2video(或者 h264 if 安装了x264),
-c:a:0 mp2 -b:a:0 128k  指定节目中0号audio的 codec为mp2,且码率为128k
ffmpeg -i Titanic.mkv -map 0:1 -map 0:0 -c copy -y out.ts     

只是将流做一下倒排序(需要保证源audio/video使用的编解码器 ffmpeg也都有才行!
h264编码器没有的话会报错,ffmpeg -cdoecs 可以查看,如果前面有 DEA.L. mp2 xxxx,
代表 decode & encode都有)
ffmpeg -i Titanic.mkv -map 0 -c copy -c:v mpeg2video out.ts       

重新编码0号节目里的视频流,其它流直接复制
ffmpeg -i out.ts -map 0:0 video_only.ts -map 0:1 audio_only.ts   

将输入文件中的视频流和音频流单独抽取存放到对应的ts文件
ffmpeg -i Titanic.mkv -filter_complex "[0:0]scale=100:100[small_video]" -map "[small_video]" out.ts

抽取filter之后的结果

 

录制屏幕:

#record.sh

#忽略文件覆盖提示,loglevel为info
#视频捕捉设备是x11grab, 捕捉帧率25, 视频帧率25, 视频尺寸1920x1080, 从输入屏幕(:0,0 指代屏幕)的0,0偏移处(+0+0)开始捕捉,视频同步方式为时间码
#音频捕捉设备是alsa, 频率 44100hz, 2 channel, -cutoff 12000低通滤波(不好使), 使用pulseaudio方法, 音频同步采样为20块/s
#video filter处理:先将输入视频缩放为640x480大小得到名为scaled的stream,再将图片作为movie得到名为watermark的stream,最后将二者叠加得到水印视频
#使用x264编码视频, 输出帧率25, 色彩编码yuv420p, 编码器设置为平衡速度和质量(配置差的可以设置为fast/veryfast), 编码器复杂度等级为 高(若是一些老设备eg.iphone4s也兼容可以设为main)
#视频编码器码率等级为5.1(最高)(若是一些老设备eg.iphone4s也兼容可以设为4.0),恒定质量级别为28(像23-28之间的crf值都比较合理(越低质量越好),直播的话还是要考虑一下观看直播的长城宽带用户的感受),最大码率为1500Kbps(斗鱼推荐值),并设置等大的编码缓冲区,调节Mac OS X系统解码器兼容性参数
#设置x264编码选项:启用蓝光兼容(改善与硬件解码的兼容性),启用开放式帧组(大幅降低静态画面的码率),视频同步方式为掉帧/插帧
#音频编码器是aac(./ffmpeg -codecs),频率44100Hz,变码率质量等级为6(像2-6这样的aq值都比较合理(越低质量越好)),听觉心理学模型全部启用(电脑配置差很多的话compression_level改为3。这样做对质量影响不大,能提高不少编码速度),音频同步采样为20块每秒。
#封装格式为FLV(若使用MP4封装,则最后一行为-f mp4 "record.mp4"。MP4不支持浏览器快速载入),并启用浏览器快速载入,文件名为record.flv(含路径)。


./ffmpeg \
-y -loglevel info \
-f x11grab -framerate 25 -r 25 -s 1920x1080 -i :0.0+0+0 -vsync vfr \
-f alsa -ar 44100 -ac 2 -i pulse -async 20 \
-vf "scale=640:480[scaled];movie=watermark.png[watermark];[scaled][watermark] overlay=0:0" \
-vcodec libx264 -r 25 -pix_fmt yuv420p -preset medium -profile:v high \
-level 5.1 -crf 28 -maxrate 1500k -bufsize 1500k -refs 4 -qmin 4 \
-x264opts bluray_compat=1:open_gop=1 -vsync cfr \
-acodec aac -ar 44100 -aq 6 -compression_level 0 -async 20 \
-f flv -movflags +faststart "abc.flv"

https://blog.csdn.net/isuker/article/details/51518161

http://trac.ffmpeg.org/wiki/Capture/Desktop

https://blog.csdn.net/junllee/article/details/7592775

 

摄像头拿取数据:

插上usb摄像头,正常情况下/dev/下会新增设备/dev/video0,且会出现新的目录 /dev/v4l2/,此时摄像头的驱动已经是ready状态

#忽略文件覆盖提示,loglevel为info
#视频捕捉设备是v4l2, 捕捉帧率15, 视频帧率15(在可能的范围内尽可能高,25帧率), 视频尺寸vga(640*480) (也可写作 -video_size vga), 从设备/dev/video中拿取数据
#video filter处理:先将输入视频缩放为640x480大小得到名为scaled的stream,再将图片作为movie得到名为watermark的stream,最后将二者叠加得到水印视频
#使用x264编码视频, 输出帧率15, 色彩编码yuv420p, 编码器设置为平衡速度和质量(配置差的可以设置为fast/veryfast), 编码器复杂度等级为 高(若是一些老设备eg.iphone4s也兼容可以设为main)
#视频编码器码率等级为5.1(最高)(若是一些老设备eg.iphone4s也兼容可以设为4.0),恒定质量级别为28(像23-28之间的crf值都比较合理(越低质量越好),直播的话还是要考虑一下观看直播的长城宽带用户的感受),最大码率为1500Kbps(斗鱼推荐值),并设置等大的编码缓冲区,调节Mac OS X系统解码器兼容性参数
#设置x264编码选项:启用蓝光兼容(改善与硬件解码的兼容性),启用开放式帧组(大幅降低静态画面的码率),视频同步方式为掉帧/插帧


./ffmpeg \
-y -loglevel info \
-f v4l2 -framerate 25 -r 25 -s vga -i /dev/video0 \
-vf "scale=640:480[scaled];movie=watermark.png[watermark];[scaled][watermark] overlay=0:0" \
-vcodec libx264 -r 25 -pix_fmt yuv420p -preset medium -profile:v high \
-level 5.1 -crf 28 -maxrate 1500k -bufsize 1500k -refs 4 -qmin 4 \
-x264opts bluray_compat=1:open_gop=1 -vsync cfr \
-f flv -movflags +faststart "abc.flv"

 

你可能感兴趣的:(ffmpeg学习)