概述
使用srs来进行直播流转码时,如果直接配置了转码,则无论有无客户端在拉取转码流,转码都会进行。
需要注意到,转码是一件非常消耗CPU资源的事情,所以实现按需转码(只有在转码流被拉取时,才进行转码)是一件非常值得的事情。
srs的FFmpeg转码时的推拉流逻辑
在srs的vhost中,可以配置transcode来使用FFmpeg对流进行转码。
例如下面配置:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | listen              1935;vhost www.transcode.com {
 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];
 }
 }
 }
 
 | 
假设一路流推送到rtmp://www.transcode.com/testapp/teststream,上面所配置的ffmpeg立即就会对这路流进行转码(即使没有人拉流),
因为它转码的逻辑是拉流到FFmpeg->转码->推流到output所定义的地方。
那么上面配置中的写法就表示:
- 从 rtmp://127.0.0.1:1935/testapp?vhost=www.transcode.com/teststream拉流。
- 转码。
- 推流到 rtmp://127.0.0.1:1935/testapp?vhost=www.transcode.com/teststream_ff
也就是转码后反推了一路流到 www.transcode.com这个vhost下面(由于output可以自定义,所以实际上想推到哪里都可以)。
所以转码一旦开始,就会不断拉流,转码,推流,与有没有人在拉流没有关系,它会持续占用CPU资源。
如何实现srs可控的FFmpeg转码
首先,如果在一个vhost下同时配置 remote 和 transcode,则会出来不先拉原始流就无法拉取转码流的问题:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 
 | vhost lrm.test.com {mode             remote;
 origin           192.168.90.229:2019;
 transcode {
 enabled     on;
 ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
 engine ff {
 enabled         on;
 vfilter {
 }
 vcodec          libx264;
 vbitrate        3500;
 vfps            60;
 vwidth          1920;
 vheight         1080;
 vthreads        2;
 vprofile        baseline;
 vpreset         superfast;
 vparams {
 }
 acodec          libfdk_aac;
 abitrate        45;
 asample_rate    44100;
 achannels       2;
 aparams {
 }
 output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
 }
 }
 }
 
 | 
如上面的配置,如果不先拉取rtmp://lrm.test.com/app/streamname的未转码流,则无法拉取rtmp://lrm.test.com/app/streamname_ff的转码流,
并且只要转码一旦开始,就不会停止。
所以,如果想要实现可控转码,则只能通过需要转码时,再下发转码配置来实现,只通过srs本身来控制貌似不行。
按需转码实现思路:
- 如何知道有用户拉流:用户拉流触发srs的HTTPCallBack->开启转码。
- 如何开启转码:在用于转码的srs节点上下发ingest配置从origin拉取原始流->进行转码后将转码流推回origin。
所以这里的关键在于两点:使用HTTPCallBack来获知拉流信息;使用ingest来拉取原流进行转码,转码操作不会影响srs集群的任何配置。
ingest配置一:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 
 | vhost lrm.test.com {ingest livestream {
 enabled      on;
 input {
 type    stream;
 url     rtmp://192.168.90.229:2019/persist?vhost=lrm.test.com/long;
 }
 ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
 engine 720_60 {
 enabled         on;
 vfilter {
 }
 vcodec          libx264;
 vbitrate        3500;
 vfps            60;
 vwidth          0;
 vheight         0;
 vthreads        12;
 vprofile        main;
 vpreset         fast;
 vparams {
 maxrate:v     3500k;
 minrate:v     3500k;
 bufsize:v     3500k;
 }
 acodec          libfdk_aac;
 abitrate        50;
 asample_rate    44100;
 achannels       2;
 aparams {
 }
 output          rtmp://192.168.90.229:2019/persist?vhost=lrm.test.com/long_720_60;
 }
 }
 }
 
 | 
ingest配置二:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 
 | vhost lrm.test.com {ingest livestream {
 enabled      on;
 input {
 type    stream;
 url     rtmp://192.168.90.229:2019/persist?vhost=lrm.test.com/long;
 }
 ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
 engine 1 {
 enabled         off;
 output          rtmp://127.0.0.1:2019/persist?vhost=www.transcode.com/long;
 }
 engine 2 {
 enabled         off;
 output          rtmp://127.0.0.1:2019/persist?vhost=www.transcode2.com/long;
 
 }
 }
 }
 
 vhost www.transcode.com {
 transcode {
 enabled      off;
 ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
 engine 720_60 {
 enabled         on;
 vfilter {
 }
 vcodec          libx264;
 vbitrate        3500;
 vfps            60;
 vwidth          0;
 vheight         0;
 vthreads        12;
 vprofile        main;
 vpreset         fast;
 vparams {
 maxrate:v     3500k;
 minrate:v     3500k;
 bufsize:v     3500k;
 }
 acodec          libfdk_aac;
 abitrate        50;
 asample_rate    44100;
 achannels       2;
 aparams {
 }
 output          rtmp://192.168.90.229:2019/persist?vhost=lrm.test.com/long_720_60;
 }
 }
 }
 
 vhost www.transcode2.com {
 transcode {
 enabled      on;
 ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
 engine 720_60_1 {
 enabled         on;
 vfilter {
 filter_complex  'scale=1280:-1';
 }
 vcodec          libx264;
 vbitrate        3500;
 vfps            60;
 vwidth          0;
 vheight         0;
 vthreads        12;
 vprofile        main;
 vpreset         fast;
 vparams {
 maxrate:v     3500k;
 minrate:v     3500k;
 bufsize:v     3500k;
 }
 acodec          libfdk_aac;
 abitrate        50;
 asample_rate    44100;
 achannels       2;
 aparams {
 }
 output          rtmp://192.168.90.229:2019/persist?vhost=lrm.test.com/long_720_60_1;
 }
 }
 }
 
 | 
虽然两种方式其实可以达到一样的效果(方式一中也可以添加多个engine),哪种方便用哪一种。