关注TSINGSEE青犀视频的小伙伴应该知道,我们在其他的博文有提到过EasyGBS可以在演示平台下,设置播放超过三分钟就自动停播的功能,其实在 EasyDSS 开发过程中,我们同样遇到了这种需求:播放一段时间后自动关闭。
EasyDSS的flv流内部设计为:kernel 提供 flv 服务,应用层进行反向代理为浏览器层提供 flv 服务。即浏览器请求 flv 流时,首先经过应用层,应用层收到 flv 流请求后,将该请求反向代理到 kernel 中,最终提供 flv 请求。
针对用户需求,需要在应用层的反向代理中根据配置中断时间,自动中断 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青犀视频进行了解,也欢迎随时咨询我们。