使用 GoLang 创建了一个提供 HTML/JS/CSS 和图像的 Web 服务器。当服务器尝试提供 MP4 视频文件时,视频加载失败,仅显示视频控件。
检查视频文件后,发现较小的视频可以正常工作,而较大的视频没有。该问题与视频大小和浏览器的默认缓冲行为有关。
范围请求支持:
对于大于特定大小的视频,浏览器需要服务器支持范围请求(部分内容服务)。这允许浏览器仅获取播放所需的视频部分,从而防止整个文件加载到内存中。
在这种情况下,GoLang 代码未配置为处理 Range 请求。所提供的实现只是将整个文件作为单个响应提供。因此,浏览器无法播放较大的视频。
为了解决该问题,采取了以下步骤:
或者,如果不首选 http.FileServe(),则可以实现自定义范围请求处理。这涉及在响应中设置以下标头:
对于 Range 请求,服务器应返回 HTTP 状态代码 206部分内容而不是 200 OK。
自定义范围请求处理是通过以下方式实现的:
<code class="go">func (vh *viewHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { path := r.URL.Path[1:] data, err := ioutil.ReadFile(string(path)) if err == nil { var contentType string if strings.HasSuffix(path, ".mp4") { contentType = "video/mp4" size := binary.Size(data) if size > 0 { requestedBytes := r.Header.Get("Range") w.Header().Add("Accept-Ranges", "bytes") w.Header().Add("Content-Length", strconv.Itoa(size)) w.Header().Add("Content-Range", "bytes "+requestedBytes[6:len(requestedBytes)]+strconv.Itoa(size-1)+"/"+strconv.Itoa(size)) w.WriteHeader(206) } } else { w.Header().Add("Content-Type", contentType) w.Write(data) } } else { log.Println("ERROR!") w.WriteHeader(404) w.Write([]byte("404 - " + http.StatusText(404))) } }</code>
循环视频:
为了确保视频循环,添加了以下逻辑:
<code class="go">if contentType == "video/mp4" { http.ServeFile(w, r, path) } else { w.Header().Add("Content-Type", contentType) w.Write(data) }</code>
这对 MP4 视频使用 http.ServeFile(),它可以正确处理循环。
以上是为什么我的 GoLang 网络服务器无法提供大型 MP4 视频?的详细内容。更多信息请关注PHP中文网其他相关文章!