RTMP流媒体协议互联网直播/点播平台EasyDSS如何使用 ReverseProxy 中断 flv 流达到自动停播的效果?

关注青犀视频的小伙伴应该知道,我们在其他的博文有提到过EasyGBS可以在演示平台下,设置播放超过三分钟就自动停播的功能,其实在 EasyDSS 开发过程中,我们同样遇到了这种需求:播放一段时间后自动关闭。

EasyDSS加水印.png

EasyDSS的flv流内部设计为:kernel 提供 flv 服务,应用层进行反向代理为浏览器层提供 flv 服务。即浏览器请求 flv 流时,首先经过应用层,应用层收到 flv 流请求后,将该请求反向代理到 kernel 中,最终提供 flv 请求。

DSS7.png

针对用户需求,需要在应用层的反向代理中根据配置中断时间,自动中断 flv 流。应用层使用 Go 开发,使用以下代码进行反向代理:

proxy := &httputil.ReverseProxy{
   Director:     director,
   Transport:    tranport,
   ErrorHandler: errHandle,
}
// 反向代理
proxy.ServeHTTP(c.Writer, c.Request)

其中 Transport 为用于数据传输的流,只需要获取传输通道中 response 响应数据,在中断时间后,将 response 关闭掉,即可中断流的传输。
查看 Go 语言中 Transport 的代码,并未提供获取 response 的接口,因此需要重新封装 Transport 接口,可以获取到 response 响应数据。

// 可关闭 Transport
type ShutDownTransport struct {
   Trans    *http.Transport
   response *http.Response
}

// 覆盖上层 Transport
func (t *ShutDownTransport) RoundTrip(req *http.Request) (*http.Response, error) {
   res, err := t.Trans.RoundTrip(req)
   t.response = res
   return res, err
}

// 实现关闭方法
func (t *ShutDownTransport) ShutDown(d time.Duration) {
   time.AfterFunc(d, func() {
      res := t.response
      if res != nil {
         if res.Body != nil {
            res.Body.Close()
         }
      }
   })
}

以上代码使用组合模式将http.Transport和http.Response组合在一个结构体中,并实现RoundTrip()方法。RoundTrip()方法为代理需要实现的方法,从该方法中可以获取对应的 response。

在 ShutDown() 方法中启动一个定时操作,在 d 时间后,调用response.Body.Close() 方法强制中断流传输,实现了该功能。更多视频相关解决方案,可以访问TSINGSEE青犀视频进行了解,也欢迎随时咨询我们。

DSS2.png

猜你喜欢

转载自blog.csdn.net/EasyDSS/article/details/108648494