用法概览

ffmpeg有两种用法,一种是复制流,一种是编码流。

复制流

如果采用复制流,其参数简单,工作效率会极高,而且处理器占用率极低,往往能够每秒复制几千帧,是视频播放速度的几百倍。这种方法非常推荐。

但是,复制流无法修改视频的码率、分辨率,也无法改变视频格式。

如果需要直播,建议先将视频编码为可以直播的视频,再使用复制流的方法推流。

其中,

一般RTMP直播服务器接受的视频格式有:h.264编码的所有视频,一般为mp4格式或flv格式。
一般RTMP直播服务器接受的音频格式有:aac编码的所有视频,一般为aac格式或mp4格式。

警告:其中Lavc57.89编码器编码的所有mp3格式音频无法推流。

编码流

如果采用编码流,其参数复杂,工作效率极低,处理器占用率极高,一般能够达到和视频播放速度相当或显著低于视频播放速度。这种方法仅适合于非直播场景。

但是,编码流,可以修改流的码率、分辨率,可以改变流的格式。

 

复制流法推流

> ffmpeg \
-re \
-i ./small.mp4 \
-c copy \
-f flv\
"rtmp://aaaaa"

其中ffmpeg表示ffmpeg程序本身
-re参数表示模拟实时输入源,ffmpeg默认阅读源的速度是尽可能快,该参数能够将其阅读速度限制在一倍以内。
-i是其输入的视频,这里假定该视频格式为.mp4格式
-f是强制修改格式,RTMP直播需要输出flv格式
-c copy表示复制流
最后填写RTMP地址即可,注意,如果是Media Service的地址,必须要在复制得到的推流地址后增加一个/随机字符串,否则会返回IO错误。

如果遇到服务器不接受该流,很可能是没有将格式转为flv。一般H.264编码的视频可以直接推流,如果视频不是H.264编码,尝试去掉-c copy参数并增加-c:v h264参数。

如果遇到服务器不接受该流,很可能是没有将音频格式转为aac。一般aac编码的音频可以直接推流,mp3格式不行,如果音频不是aac编码,尝试去掉-c copy参数并增加-c:a aac参数。

推流时实时编码

> ffmpeg \
-re \
-i ./small.mp4 \
-f flv \
-s 1280x720 \
-c:v libx264 \
-c:a aac \
-b:v 2000k \
-b:a 128k \
"rtmp://channel42/fff"

说明

其中ffmpeg表示ffmpeg程序本身
-re参数表示模拟实时输入源,ffmpeg默认阅读源的速度是尽可能快,该参数能够将其阅读速度限制在一倍以内。
-i是其输入的视频,这里假定该视频格式为.mp4格式
-f是强制修改格式,RTMP直播需要输出flv格式
-s表示目标编码码率,不要超过1280x720,否则推流带宽达不到标准。
-c:v表示视频编码器,如果输入视频是mp4格式,使用h264编码器即可。
-c:a表示音频编码器,如果输入视频是mp4格式,一般其音频编码都是aac,使用aac编码器即可。
-b:v表示视频比特率,建议不要超过2000k。
-b:a表示音频比特率,建议不要超过200k
最后填写RTMP地址即可,注意,如果是Media Service的地址,必须要在复制得到的推流地址后增加一个/随机字符串,否则会返回IO错误。

错误捕获

0x20200194 空流
0x2020019c 流断了

整合视频和音频

ffmpeg \
-i ./voice.mp3 \
-i ./s.mp4 \
-map 0:a \
-map 1:v \
-c:v h264 \
-c:a aac \
-shortest \
-c copy \
test.mp4

说明

其中ffmpeg表示ffmpeg程序本身
-i表示指定两个输入
-map表示映射流
0:a表示从第一个输入中取出,映射音频,第一个输入就是声音
1:v表示从第二个输入中取出,映射视频,第二个输入就是视频
-c copy表示不实时编码,只复制流。假若声音的格式和视频的格式都没有变化,可以增加此参数,否则应当向上面一个命令那样,手动指定音频编码器、视频编码器、码率。
-shortest表示映射后的总长度为所有流中较短的流的长度,较长的流的末尾会抛弃。可选填写

结合上面推流的命令,可以实现将整合后的媒体实时推流

命令示例:

ffmpeg \
-re -i ./m.mp3 \
-re -i ./v.mp4 \
-map 0:a \
-map 1:v \
-c:v copy \
-c:a aac \
-f flv \
rtmp://autobatcd1265fd66/fff

整合视频和字幕

ffmpeg -i subtitle.vtt subtitle.ass

Then burn the subtitles to the video:

ffmpeg -i video.mp4 -vf ass=subtitle.ass out.mp4

or

fmpeg -i input.mp4 -vf "subtitles=sub.vtt" output.mp4

将音频烧制到视频上

ffmpeg adelay document

ffmpeg amix document

ffmpeg loudnorm document

adaplay=milliseconds

inputs: The number of inputs. If unspecified, it defaults to 2.

ffmpeg.exe -i spring_no_audio.mp4 -i laizhe.mp3 -i jiuwen.mp3 -filter_complex "[1]adelay=1000[a1];[2]adelay=5000[a2];[a1][a2]amix=inputs=2,loudnorm[a]" -map 0:v -map "[a]"  -c:v copy output.mp4

调整视频速度

ffmpeg -i input.mkv -filter:v "setpts=PTS/60" output.mkv

剪取视频

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

用ffmepg扣取一个视频区域

Use the crop filter:

ffmpeg -i in.mp4 -filter:v "crop=out_w:out_h:x:y" out.mp4

Where the options are as follows:

  • out_w is the width of the output rectangle
  • out_h is the height of the output rectangle
  • x and y specify the top left corner of the output rectangleplex "[0:v:0][1:a:0][2:v:0][2:a:0]concat=n=2:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" output.mp4