为什么要这样修改呢?当然是有特别的场景需要。比如某一个直播,推流中断。这时,
服务器直接用一个广告推流来替代。当直播恢复后,强行踢掉广告流。
因为主播流和广告流是使用的同一个直播地址,因此,需要这个踢流机制。
原来的播主网络恢复了,他要继续推流。如何处理呢?最好的办法不是发消息让广告进程停止注入。
而是强迫广告进程让出原来的播主频道。
srs原来提供了一个kickoff流的http-api。那是利用coroutine的机制来实现的,感觉非常危险。
容易易导致程序crash。并且,也没有必要那样做,只需要想办法exit rtmp-publishing处理线程
就可以了。关键算法程序如下:
srs_error_t SrsRtmpConn::stream_service_cycle()
{
...
srs_trace("find a source for source-ip:%s, type=%d",ip.c_str(),info->type);
int ret=0;
SrsSource* source = NULL;
if (info->type == SrsRtmpConnUnknown){
return srs_error_new(ERROR_RTMP_STREAM_NOT_FOUND, "rtmp: unknown stream");
}
else if (info->type == SrsRtmpConnPlay){
ret = _srs_sources->find_for_play(req, server, &source);
}
else{
if ((ip == "127.0.0.1")){
_srs_sources->local_create(req, server, &source);
}else{
srs_warn("%s/%s:Force local-publisher quit!",req->app.c_str(),req->stream.c_str());
string local_pusher_url = "127.0.0.1-" + req->app + "/" + req->stream;
std::map<string,int>::iterator it;
it = gRtmpConnExitFlagTbl.find(local_pusher_url);
if (it != gRtmpConnExitFlagTbl.end()){
gRtmpConnExitFlagTbl.at(local_pusher_url) = 111111; //force quit if exist
usleep(30000);
}
if ((ret = _srs_sources->fetch_or_create(req, server, &source)) <0) {
return srs_error_new(ERROR_RTMP_ACCESS_DENIED, "rtmp: fetch source");
}
}
}
...
}
经测试,播主和中断式广告相互切换非常流畅。
08-02
885
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
11-20
6361
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
01-27