livego
livego copied to clipboard
如何查询流是否已经可以被请求
例如,首先使用ffmpeg发布流到livego服务器,然后这边浏览器请求流,问题出在后边,浏览器请求流,由于第一步发布流还没喂进去数据,浏览器就请求了,这时由于流没有发布,所以请求是跨域阻止的。对应的源代码如下:
func (server *Server) handleConn(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Error("http flv handleConn panic: ", r)
}
}()
url := r.URL.String()
u := r.URL.Path
if pos := strings.LastIndex(u, "."); pos < 0 || u[pos:] != ".flv" {
http.Error(w, "invalid path", http.StatusBadRequest)
return
}
path := strings.TrimSuffix(strings.TrimLeft(u, "/"), ".flv")
paths := strings.SplitN(path, "/", 2)
log.Debug("url:", u, "path:", path, "paths:", paths)
if len(paths) != 2 {
http.Error(w, "invalid path", http.StatusBadRequest)
return
}
// 判断视屏流是否发布,如果没有发布,直接返回404
msgs := server.getStreams(w, r)
if msgs == nil || len(msgs.Publishers) == 0 {
http.Error(w, "invalid path", http.StatusNotFound)
return
} else {
include := false
for _, item := range msgs.Publishers {
if item.Key == path {
include = true
break
}
}
if include == false {
http.Error(w, "invalid path", http.StatusNotFound)
return
}
}
w.Header().Set("Access-Control-Allow-Origin", "*")
writer := NewFLVWriter(paths[0], paths[1], url, w)
server.handler.HandleWriter(writer)
writer.Wait()
}
这里w.Header().Set("Access-Control-Allow-Origin", "*")
只会在最后设置跨域头,所以前面,如果流没发布,直接就浏览器跨域阻止了。
这里的代码,能不能弄一个单独查询流是否可以被播放的就绪接口:
// 判断视屏流是否发布,如果没有发布,直接返回404
msgs := server.getStreams(w, r)
if msgs == nil || len(msgs.Publishers) == 0 {
http.Error(w, "invalid path", http.StatusNotFound)
return
} else {
include := false
for _, item := range msgs.Publishers {
if item.Key == path {
include = true
break
}
}
if include == false {
http.Error(w, "invalid path", http.StatusNotFound)
return
}
}
这样请求flv直播的流程就变成了,首先推流,然后查询流是否可以被播放,最后就是播放。
这样的好处就是,可以不在播放时,由于流没有就绪(可以播放),所导致前面返回invalid path
而没有设置跨域头引起的浏览器阻止而拦截请求的情况。这样,浏览器客户端js写代码之前,也可以setinternal来循环判断流的状态,从而恢复直播播放,因为流可能被中断,网络断开或者其它任何影响客户端连续播放的原因。
同问