ffmpeg命令格式:
ffmpeg -i [输入文件名] [参数选项] -f [格式] [输出文件]
ffmpeg [[options][`-i' input_file]]... {[options] output_file}...
(1) h264: 表示输出的是h264的视频裸流
(2) mp4: 表示输出的是mp4的视频
(3)mpegts: 表示ts视频流
主要参数:
-i 设定输入流
-f 设定输出格式
-ss 开始时间
-c 指定输出文件的编码
视频参数:
-b 设定视频流量,默认为200Kbit/s
-r 设定帧速率,默认为25
-s 设定画面的宽与高
-aspect 设定画面的比例
-vn 不处理视频
-vcodec ( -c:v )设定视频编解码器,未设定时则使用与输入流相同的编解码器,一般后面加copy表示拷贝 参数值详解
音频参数:
-ar 设定采样率
-ac 设定声音的Channel数
-acodec 设定声音编解码器,未设定时则使用与输入流相同的编解码器,一般后面加copy表示拷贝 参数值详解
-an 不处理音频
基本选项: | |
---|---|
-formats | 输出所有可用格式 |
-f fmt | 指定格式(音频或视频格式) |
-i filename | 指定输入文件名,在linux下当然也能指定:0.0(屏幕录制)或摄像头 |
-y | 覆盖已有文件 |
-t duration | 记录时长为t |
-fs limit_size | 设置文件大小上限 |
-ss time_off | 从指定的时间(s)开始, [-]hh:mm:ss[.xxx]的格式也支持 |
-itsoffset time_off | 设置时间偏移(s),该选项影响所有后面的输入文件。该偏移被加到输入文件的时戳,定义一个正偏移意味着相应的流被延迟了 offset秒。 [-]hh:mm:ss[.xxx]的格式也支持 |
-title string | 标题 |
-timestamp time | 时间戳 |
-author string | 作者 |
-copyright string | 版权信息 |
-comment string | 评论 |
-album string | album名 |
-v verbose | 与log相关的 |
-target type | 设置目标文件类型("vcd", "svcd", "dvd", "dv", "dv50", "pal-vcd", "ntsc-svcd", ...) |
-dframes number | 设置要记录的帧数 |
视频选项: | |
-b | 指定比特率(bits/s),似乎ffmpeg是自动VBR的,指定了就大概是平均比特率 |
-bitexact | 使用标准比特率 |
-vb | 指定视频比特率(bits/s) |
-vframes number | 设置转换多少桢(frame)的视频 |
-r rate | 帧速率(fps) (可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97) |
-s size | 指定分辨率 (320x240) |
-aspect aspect | 设置视频长宽比(4:3, 16:9 or 1.3333, 1.7777) |
-croptop size | 设置顶部切除尺寸(in pixels) |
-cropbottom size | 设置底部切除尺寸(in pixels) |
-cropleft size | 设置左切除尺寸 (in pixels) |
-cropright size | 设置右切除尺寸 (in pixels) |
-padtop size | 设置顶部补齐尺寸(in pixels) |
-padbottom size | 底补齐(in pixels) |
-padleft size | 左补齐(in pixels) |
-padright size | 右补齐(in pixels) |
-padcolor color | 补齐带颜色(000000-FFFFFF) |
-vn | 取消视频 |
-vcodec codec | 强制使用codec编解码方式('copy' to copy stream) |
-sameq | 使用同样视频质量作为源(VBR) |
-pass n | 选择处理遍数(1或者2)。两遍编码非常有用。第一遍生成统计信息,第二遍生成精确的请求的码率 |
-passlogfile file | 选择两遍的纪录文件名为file |
-newvideo | 在现在的视频流后面加入新的视频流 |
高级视频选项 | |
-pix_fmt format | set pixel format, 'list' as argument shows all the pixel formats supported |
-intra | 仅适用帧内编码 |
-qscale q | 以<数值>质量为基础的VBR,取值0.01-255,约小质量越好 |
-loop_input | 设置输入流的循环数(目前只对图像有效) |
-loop_output | 设置输出视频的循环数,比如输出gif时设为0表示无限循环 |
-g int | 设置图像组大小 |
-cutoff int | 设置截止频率 |
-qmin int | 设定最小质量,与-qmax(设定最大质量)共用,比如-qmin 10 -qmax 31 |
-qmax int | 设定最大质量 |
-qdiff int | 量化标度间最大偏差 (VBR) |
-bf int | 使用frames B 帧,支持mpeg1,mpeg2,mpeg4 |
音频选项: | |
-ab | 设置比特率(单位:bit/s,也许老版是kb/s)前面-ac设为立体声时要以一半比特率来设置,比如192kbps的就设成96,转换 默认比特率都较小,要听到较高品质声音的话建议设到160kbps(80)以上。 |
-aframes number | 设置转换多少桢(frame)的音频 |
-aq quality | 设置音频质量 (指定编码) |
-ar rate | 设置音频采样率 (单位:Hz),PSP只认24000 |
-ac channels | 设置声道数,1就是单声道,2就是立体声,转换单声道的TVrip可以用1(节省一半容量),高品质的DVDrip就可以用2 |
-an | 取消音频 |
-acodec codec | 指定音频编码('copy' to copy stream) |
-vol volume | 设置录制音量大小(默认为256) <百分比> ,某些DVDrip的AC3轨音量极小,转换时可以用这个提高音量,比如200就是原来的2倍 |
-newaudio | 在现在的音频流后面加入新的音频流 |
字幕选项: | |
-sn | 取消字幕 |
-scodec codec | 设置字幕编码('copy' to copy stream) |
-newsubtitle | 在当前字幕后新增 |
-slang code | 设置字幕所用的ISO 639编码(3个字母) |
Audio/Video 抓取选项: | |
-vc channel | 设置视频捕获通道(只对DV1394) |
-tvstd standard | 设置电视标准 NTSC PAL(SECAM) |
1、查看电脑设备:
ffmpeg -list_devices true -f dshow -i dummy
可以看到我的我的电脑有一个HD Camera摄像头和一个麦克风:麦克风 (Realtek(R) Audio)
如果设备名称有中文,可能会出现乱码,想看设备原名,可以去设备管理器中查看,又可以利用第三方工具查看(graphedit),推荐后者。
2、测试摄像头是否可用
ffplay -f dshow -i video="HD Camera" 或者 ffplay -f vfwcap -i 0
如果成功弹出播放窗口,则代表设备可用,否则可能是设备不可用或者设备被占用
3、查看摄像头信息
ffmpeg -list_options true -f dshow -i video="HD Camera"
4、查看麦克风信息
ffmpeg -list_options true -f dshow -i audio="麦克风 (Realtek(R) Audio)"
5、本地视频的推流
把视频推流至rtmp://192.168.0.108:1935/live/room1
(192.168.0.108:1935为rtmp服务器地址、live为nginx配置节点、room1当做密钥,推流拉流地址一样即可播放),语句如下
#使用该方式推流会进行二次编码,并且原视频会有一定的画质损失 ffmpeg.exe -re -i demo.mp4 -f flv rtmp://192.168.0.108:1935/live/room1.flv #推原视频不失真的方法如下 #-re 使音视频始终同步 #-vcodec copy -acodec coyp使其不重复编码,防止视频音频失真 ffmpeg -re -i E:\视频\舞蹈\demo.mp4 -vcodec copy -acodec copy -f flv rtmp://192.168.0.108:1935/live/room1
#只推流音频
ffmpeg -re -i demo.m4a -vcodec copy -acodec copy -f flv rtmp://192.168.0.108:1935/live/room1
6、摄像头推流(没有音频)
ffmpeg -f dshow -i video="HD Camera" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://192.168.0.108:1935/live/room1
7、麦克风推流
ffmpeg -f dshow -i audio="麦克风 (Realtek(R) Audio)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://192.168.0.108:1935/live/room1
8、摄像头与麦克风推流
ffmpeg -f dshow -i video="HD Camera" -f dshow -i audio="麦克风 (Realtek(R) Audio)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://192.168.0.108:1935/live/room1 #或者 ffmpeg -f dshow -i video="HD Camera":audio="麦克风 (Realtek(R) Audio)" -vcodec libx264 -r 25 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://192.168.0.108:1935/live/room1
9、其他常用命令
#查看视频信息 ffmpeg -i video.avi #提取视频中的音频(注意此时输出的格式应该与视频中的音频格式保持一致,否则会报错) ffmpeg -i .\demo.mkv -vn -y -acodec copy output.m4a ffmpeg -i .\demo.mp4 -vn -y -acodec copy output.m4a
提取视频中的音频,并指定格式输出
ffmpeg -i demo.mp4 -acodec mp3 -vn output.mp3
#视频合并(默认两个视频是横向拼接的,视频的宽度为两个视频的宽度相加,但是只保留了前面一个的音频)
ffmpeg -i .\demo1.mp4 -i .\demo.mp4 -lavfi hstack output.mp4
#视频剪切,下面的命令,可以从时间为00:00:15开始,截取5秒钟的视频
-ss表示开始切割的时间,-t表示要切多少。上面就是从15秒开始,切5秒钟出来ffmpeg -ss 00:00:15 -t 00:00:05 -i input.mp4 -vcodec copy -acodec copy output.mp4
#ps: 如果540不写,写成-1,即scale=960:-1, 那也是可以的,ffmpeg会通知缩放滤镜在输出时保持原始的宽高比
#获取视频图片 (-ss 表示获取视频第40秒处的图片)
ffmpeg -i bbb.mp4 -frames:v 1 -ss 40 -f image2 bbb.jpg
#改变视频宽高,将输入的1920x1080缩小到960x540输出ffmpeg -i input.mp4 -vf scale=960:540 output.mp4
#视频编码格式转换
#比如一个视频的编码是MPEG4,想用H264编码,咋办?
ffmpeg -i input.mp4 -vcodec h264 output.mp4
#相反也一样
ffmpeg -i input.mp4 -vcodec mpeg4 output.mp4
#改变视频的容器格式为 flv ,视频和音频编码保持原有编码不变 (copy的作用)
ffmpeg -i aaa3.mp4 -acodec copy -vcodec copy aaa33.flv
#同样也可以改变视频格式
ffmpeg -i input.mp4 -vcodec h264 output.mkv
#ffmpeg 逐帧抽取视频,并保存为图片(%d 表示从1累加)
ffmpeg -i aaa.MP4 ./aaa/pic_%d.png
#将上条命令保存的图片转换为视频
ffmpeg -f image2 -i pic_%d.png -vcodec libx264 -crf 15 -pix_fmt yuv420p output.mp4
#获取视频的第一帧,并保存为图片
ffmpeg -i .\aaa2.mp4 -frames:v 1 -f image2 aaa.jpg
10、以下命令待验证
合并视频和音频 1、直接合并 视频文件中没有音频 ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental output.mp4video.mp4,audio.wav分别是要合并的视频和音频,output.mp4是合并后输出的音视频文件。 下面的命令是用audio音频替换video中的音频ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a:0 output.mp4 2、先提取视频中的音频,将两个音频合并成一个音频,然后将合并的音频与视频进行合并 #获取视频中的音频 ffmpeg -i input.mp4 -vn -y -acodec copy output.aac #去掉视频中的音频 ffmpeg -i input.mp4 -an output.mp4 #合并两个音频 ffmpeg -i input1.mp3 -i output.aac -filter_complex amerge -ac 2 -c:a libmp3lame -q:a 4 output.mp3 #合并音频和视频 ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental output.mp4 3、合并视频 #横向合并视频 ffmpeg -i input1.mp4 -i input2.mp4 -lavfi hstack output.mp4 上面的命令虽然可以合并视频,两个视频可以正常播放,但是只保留了前面一个的音频。 #合并多个视频,可以使用下面命令行: ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -lavfi hstack=inputs=3 output.mp4 #纵向合并视频 ffmpeg -i input1.mp4 -i input2.mp4 -lavfi vstack output.mp4 #网格合并视频,来源:https://www.zhihu.com/question/300182407 当多个视频时,还可以合并成网格状,比如2x2,3x3这种。但是视频个数不一定需要是偶数,如果是奇数,可以用黑色图片来占位。 ffmpeg -f lavfi -i color=c=black:s=1280x720 -vframes 1 black.png 该命令将创建一张1280*720的图片 然后就可以使用下面这个命令来合并成网格视频了,如果只有三个视频,可以选择上面创建的黑色图片替代。 ffmpeg -i top_left.mp4 -i top_right.mp4 -i bottom_left.mp4 -i bottom_right.mp4 \ -lavfi "[0:v][1:v]hstack[top];[2:v][3:v]hstack[bottom];[top][bottom]vstack" -shortest 2by2grid.mp4 上面创建的是正规的2x2网格视频。想象一下,现在只有三个视频,我想把第一个视频摆放在第一行的中间,然后把第二、三个视频摆放在第二行。那么就可以使用下面两个命令了。 ffmpeg -f lavfi -i color=c=black:s=640x720 -vframes 1 black.png ffmpeg -i black.png -i top_center.mp4 -i bottom_left.mp4 -i bottom_right.mp4 -lavfi "[0:v][1:v][0:v]hstack=inputs=3[top];[2:v][3:v]hstack[bottom];[top][bottom]vstack" -shortest 3_videos_2x2_grid.mp4 4、怎么合并两个视频并保留两个视频中的音频,注意视频的分辨率和格式必须一样。 #合并两个视频,只有一个声音; 纵向合并视频 ffmpeg -i input1.mp4 -i input2.mp4 -lavfi vstack output.mp4 #抽取两个视频中的音频,然后合并成一个音频; ffmpeg -i input_1.mp4 -vn -y -acodec copy output_a1.m4a ffmpeg -i input_2.mp4 -vn -y -acodec copy output_a2.m4a ffmpeg -i output_a1.m4a -i output_a2.m4a -filter_complex amerge -ac 2 -c:a copy -q:a 4 output_a.m4a #将这个音频替换到之前的合并视频中; ffmpeg -i video.mp4 -i output_a.m4a -c:v copy -c:a aac -strict experimental output.mp4 5、音频拼接 #两个拼接 /usr/local/ffmpeg/bin/ffmpeg -i d1.mp3 -i d2.mp3 -filter_complex '[0:0] [1:0] concat=n=2:v=0:a=1 [a]' -map [a] j5.mp3 #三个拼接 /usr/local/ffmpeg/bin/ffmpeg -i 片头.wav -i 内容.WAV -i 片尾.wav -filter_complex '[0:0] [1:0] [2:0] concat=n=3:v=0:a=1 [a]' -map [a] 合成.wav #多文件拼接 ffmpeg -f concat -ilist.txt -c copycutebaby.mp3 list.txt文件内容:à按顺序连接cutebaby_1.mp3, football.mp3,cutebaby_2.mp3,cutebaby_3.mp3 #拼接不同格式的文件,下面的命令合并了三种不同格式的文件,FFmpeg concat 过滤器会重新编码它们。注意这是有损压缩。 [0:0] [0:1] [1:0] [1:1] [2:0] [2:1] 分别表示第一个输入文件的视频、音频、第二个输入文件的视频、音频、第三个输入文件的视频、音频。concat=n=3:v=1:a=1 表示有三个输入文件,输出一条视频流和一条音频流。[v] [a] 就是得到的视频流和音频流的名字,注意在 bash 等 shell 中需要用引号,防止通配符扩展。 ffmpeg -i input1.mp4 -i input2.webm -i input3.avi -filter_complex '[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] concat=n=3:v=1:a=1 [v] [a]' -map '[v]' -map '[a]' <编码器选项> output.mkv
11、使用ffmpeg从mp4文件中提取视频流到h264文件中(输出的文件是一个h264原始流文件,H264原始码流是由一个个NALU单元组成 每个NALU单元基本就是一帧)
ffmpeg -i demo.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 tmp.h264
注释:
- -i 2018.mp4: 是输入的MP4文件
- -codec copy: 从mp4中拷贝
- -bsf: h264_mp4toannexb: 从mp4拷贝到annexB封装
- -f h264: 采用h264格式
- tmp.264: 输出的文件