Skip to main content
Version: 4.0 (Archived) 📦

Live Streaming Transcode

SRS可以对推送到SRS的RTMP流进行转码,然后输出到RTMP服务器(也可以是SRS自己)。

Use Scenario

FFMPEG的重要应用场景包括:

  • 推送一路高码率,转多路输出。譬如:游戏直播中,推送一路1080p流到SRS,SRS可以转码输出1080p/720p/576p多路,低码率可以给移动设备观看。这样节省了推流带宽(一般源站为BGP带宽,很贵),也减轻了客户端压力(譬如客户端边玩游戏边直播)。
  • 支持多屏输出。譬如:网页推流(主播)编码为vp6/mp3或speex,推流到SRS后无法支持HLS(要求h264+aac),可以转码成h264+aac后切片成HLS或者推送到其他服务器再分发。
  • 加水印。适用于需要对流进行加水印的情况,譬如打上自己的logo。SRS支持文字水印和图片水印,也可以支持视频作为水印,或者将两路流叠加(参考ffmpeg的用法)。
  • 截图:参考使用Transcoder截图
  • 其他滤镜:SRS支持所有ffmpeg的滤镜。

Workflow

SRS转码的主要流程包括:

  1. 编码器推送RTMP流到SRS的vhost。
  2. SRS的vhost若配置了转码,则进行转码。
  3. 转码后,按照配置,推送到SRS本身或者其他RTMP服务器。

Transcode Config

SRS可以对vhost的所有的流转码,或者对某些app的流转码,或者对某些流转码。

listen              1935;
vhost __defaultVhost__ {
# the streaming transcode configs.
transcode {
# whether the transcode enabled.
# if off, donot transcode.
# default: off.
enabled on;
# the ffmpeg
ffmpeg ./objs/ffmpeg/bin/ffmpeg;
# the transcode engine for matched stream.
# all matched stream will transcoded to the following stream.
# the transcode set name(ie. hd) is optional and not used.
# we will build the parameters to fork ffmpeg:
# ffmpeg <perfile>
# -i <iformat>
# <vfilter>
# -vcodec <vcodec> -b:v <vbitrate> -r <vfps> -s <vwidth>x<vheight> -profile:v <vprofile> -preset <vpreset>
# <vparams>
# -acodec <acodec> -b:a <abitrate> -ar <asample_rate> -ac <achannels>
# <aparams>
# -f <oformat>
# -y <output>
engine example {
# whether the engine is enabled
# default: off.
enabled on;
# pre-file options, before "-i"
perfile {
re;
rtsp_transport tcp;
}
# input format, can be:
# off, do not specifies the format, ffmpeg will guess it.
# flv, for flv or RTMP stream.
# other format, for example, mp4/aac whatever.
# default: flv
iformat flv;
# ffmpeg filters, follows the main input.
vfilter {
# the logo input file.
i ./doc/ffmpeg-logo.png;
# the ffmpeg complex filter.
# for filters, @see: http://ffmpeg.org/ffmpeg-filters.html
filter_complex 'overlay=10:10';
}
# video encoder name. can be:
# libx264: use h.264(libx264) video encoder.
# png: use png to snapshot thumbnail.
# copy: donot encoder the video stream, copy it.
# vn: disable video output.
vcodec libx264;
# video bitrate, in kbps
# @remark 0 to use source video bitrate.
# default: 0
vbitrate 1500;
# video framerate.
# @remark 0 to use source video fps.
# default: 0
vfps 25;
# video width, must be even numbers.
# @remark 0 to use source video width.
# default: 0
vwidth 768;
# video height, must be even numbers.
# @remark 0 to use source video height.
# default: 0
vheight 320;
# the max threads for ffmpeg to used.
# default: 1
vthreads 12;
# x264 profile, @see x264 -help, can be:
# high,main,baseline
vprofile main;
# x264 preset, @see x264 -help, can be:
# ultrafast,superfast,veryfast,faster,fast
# medium,slow,slower,veryslow,placebo
vpreset medium;
# other x264 or ffmpeg video params
vparams {
# ffmpeg options, @see: http://ffmpeg.org/ffmpeg.html
t 100;
# 264 params, @see: http://ffmpeg.org/ffmpeg-codecs.html#libx264
coder 1;
b_strategy 2;
bf 3;
refs 10;
}
# audio encoder name. can be:
# libfdk_aac: use aac(libfdk_aac) audio encoder.
# copy: donot encoder the audio stream, copy it.
# an: disable audio output.
acodec libfdk_aac;
# audio bitrate, in kbps. [16, 72] for libfdk_aac.
# @remark 0 to use source audio bitrate.
# default: 0
abitrate 70;
# audio sample rate. for flv/rtmp, it must be:
# 44100,22050,11025,5512
# @remark 0 to use source audio sample rate.
# default: 0
asample_rate 44100;
# audio channel, 1 for mono, 2 for stereo.
# @remark 0 to use source audio channels.
# default: 0
achannels 2;
# other ffmpeg audio params
aparams {
# audio params, @see: http://ffmpeg.org/ffmpeg-codecs.html#Audio-Encoders
# @remark SRS supported aac profile for HLS is: aac_low, aac_he, aac_he_v2
profile:a aac_low;
bsf:a aac_adtstoasc;
}
# output format, can be:
# off, do not specifies the format, ffmpeg will guess it.
# flv, for flv or RTMP stream.
# image2, for vcodec png to snapshot thumbnail.
# other format, for example, mp4/aac whatever.
# default: flv
oformat flv;
# output stream. variables:
# [vhost] the input stream vhost.
# [port] the intput stream port.
# [app] the input stream app.
# [stream] the input stream name.
# [engine] the tanscode engine name.
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
}
}
}

该配置对频道的所有流转码。譬如:

  • 推送流:rtmp://dev:1935/live/livestream
  • 观看原始流:rtmp://dev:1935/live/livestream
  • 观看转码流:rtmp://dev:1935/live/livestream_ff

输出配置使用了变量替换,主要的参数是:

  • [vhost] 输入流的vhost。譬如:dev
  • [port] 输入流的端口。譬如:1935
  • [app] 输入流的app。譬如:live
  • [stream] 输入流名称。譬如:livestream
  • [engine] 转码engine名称,engine后面就是名称。譬如:ff 注意:转码会使用自动检测,保证推送到自己的流不会被再次转码。但转码推送到SRS自己的流可以被切片成HLS。譬如,若开启了HLS,上面的live/livestream,和转码出来的流live/livestream_ff都能观看HLS。

对app或流转码时,只要在transcode后面加app和stream就可以。譬如:

listen              1935;
vhost __defaultVhost__ {
# 对app为live的所有流转码
transcode live{
}
}

以及对指定的流转码:

listen              1935;
vhost __defaultVhost__ {
# 对app为live并且流名称为livestream的流转码
transcode live/livestream{
}
}

Transcode Rulers

SRS的转码参数全是FFMPEG的参数,有些参数SRS做了自定义,见下表。

SRS参数FFMPEG参数实例说明
vcodecvcodecffmpeg ... -vcodec libx264 ...指定视频编码器
vbitrateb:vffmpeg ... -b:v 500000 ...输出的视频码率
vfpsrffmpeg ... -r 25 ...输出的视频帧率
vwidth/vheightsffmpeg ... -s 400x300 -aspect 400:300 ...输出的视频宽度x高度,以及宽高比
vthreadsthreadsffmpeg ... -threads 8 ...编码线程数
vprofileprofile:vffmpeg ... -profile:v high ...编码x264的profile
vpresetpresetffmpeg ... -preset medium ...编码x264的preset
acodecacodecffmpeg ... -acodec libfdk_aac ...音频编码器
abitrateb:affmpeg ... -b:a 70000 ...音频输出码率。libaacplus:16-72k。libfdk_aac没有限制。
asample_ratearffmpeg ... -ar 44100 ...音频采样率
achannelsacffmpeg ... -ac 2 ...音频声道

另外,还有四个是可以加其他ffmpeg参数:

  • perfile: 添加在iformat之前的参数。譬如指定rtsp的transport为tcp。
  • vfilter:添加在vcodec之前的滤镜参数。
  • vparams:添加在vcodec之后,acodec之前的视频编码参数。
  • aparams:添加在acodec之后,-y之前的音频编码参数。

这些参数应用的顺序是:

ffmpeg <perfile> -f flv -i <input_rtmp> {vfilter} -vcodec ... {vparams} -acodec ... {aparams} -f flv -y {output}

具体参数可以查看SRS的日志,譬如:

[2014-02-28 21:38:09.603][4][trace][start] start transcoder, 
log: ./objs/logs/encoder-__defaultVhost__-live-livestream.log,
params: ./objs/ffmpeg/bin/ffmpeg -f flv -i
rtmp://127.0.0.1:1935/live?vhost=__defaultVhost__/livestream
-vcodec libx264 -b:v 500000 -r 25.00 -s 768x320 -aspect 768:320
-threads 12 -profile:v main -preset medium -acodec libfdk_aac
-b:a 70000 -ar 44100 -ac 2 -f flv
-y rtmp://127.0.0.1:1935/live?vhost=__defaultVhost__/livestream_ff

FFMPEG Log Path

FFMPEG启动后,SRS会将stdout和stderr都定向到日志文件,譬如./objs/logs/encoder-__defaultVhost__-live-livestream.log,有时候日志会比较大。可以配置ffmpeg输出较少日志:

listen              1935;
vhost __defaultVhost__ {
transcode {
enabled on;
ffmpeg ./objs/ffmpeg/bin/ffmpeg;
engine ff {
enabled on;
vfilter {
# -v quiet
v quiet;
}
vcodec libx264;
vbitrate 500;
vfps 25;
vwidth 768;
vheight 320;
vthreads 12;
vprofile main;
vpreset medium;
vparams {
}
acodec libfdk_aac;
abitrate 70;
asample_rate 44100;
achannels 2;
aparams {
}
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
}
}
}

对ffmpeg添加-v quiet参数即可。

Copy Without Transcode

可以配置vcodec/acodec copy,实现不转码。譬如,视频为h264编码,但是音频是mp3/speex,需要转码音频为aac,然后切片为HLS输出。

listen              1935;
vhost __defaultVhost__ {
transcode {
enabled on;
ffmpeg ./objs/ffmpeg/bin/ffmpeg;
engine ff {
enabled on;
vcodec copy;
acodec libfdk_aac;
abitrate 70;
asample_rate 44100;
achannels 2;
aparams {
}
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
}
}
}

或者拷贝视频和音频:

listen              1935;
vhost __defaultVhost__ {
transcode {
enabled on;
ffmpeg ./objs/ffmpeg/bin/ffmpeg;
engine ff {
enabled on;
vcodec copy;
acodec copy;
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
}
}
}

Drop Video or Audio

可以禁用视频或者音频,只输出音频或视频。譬如,电台可以丢弃视频,对音频转码为aac后输出HLS。

可以配置vcodec为vn,acodec为an实现禁用。例如:

listen              1935;
vhost __defaultVhost__ {
transcode {
enabled on;
ffmpeg ./objs/ffmpeg/bin/ffmpeg;
engine vn {
enabled on;
vcodec vn;
acodec libfdk_aac;
abitrate 45;
asample_rate 44100;
achannels 2;
aparams {
}
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
}
}
}

该配置只输出纯音频,编码为aac。

Other Transcode Config

conf/full.conf中有很多FFMPEG转码配置的实例,也可以参考ffmpeg的命令行。

  • mirror.transcode.srs.com 将视频流上半截,翻转到下半截,看起来像个镜子。
  • drawtext.transcode.srs.com 加文字水印。
  • crop.transcode.srs.com 剪裁视频。
  • logo.transcode.srs.com 添加图片logo。
  • audio.transcode.srs.com 只对音频转码。
  • copy.transcode.srs.com 不转码只转封装,类似于SRS的Forward。
  • all.transcode.srs.com 转码参数的详细说明。
  • ffempty.transcode.srs.com 一个ffmpeg的mock,不转码只打印参数。
  • app.transcode.srs.com 对指定的app的流转码。
  • stream.transcode.srs.com 对指定的流转码。
  • vn.transcode.srs.com 只输出音频,禁止视频输出。

FFMPEG Transcode the Stream by Flash encoder

flash可以当作编码器推流,参考演示中的编码器或者视频会议。flash只支持speex/nellymoser/pcma/pcmu,但flash会有一个特性,没有声音时就没有音频包。FFMPEG会依赖于这些音频包,如果没有会认为没有音频。

所以FFMPEG用来转码flash推上来的RTMP流时,可能会有一个问题:ffmpeg认为没有音频。

另外,FFMPEG取flash的流的时间会很长,也可能是在等待这些音频包。

FFMPEG

FFMPEG相关链接:

Winlin 2015.6