首页 >后端开发 >Golang >为什么我的 GoLang 网络服务器无法提供大型 MP4 视频?

为什么我的 GoLang 网络服务器无法提供大型 MP4 视频?

Linda Hamilton
Linda Hamilton原创
2024-11-01 05:02:02435浏览

Why does my GoLang webserver fail to serve large MP4 videos?

GoLang HTTP Web 服务器提供 MP4 视频

挑战

使用 GoLang 创建了一个提供 HTML/JS/CSS 和图像的 Web 服务器。当服务器尝试提供 MP4 视频文件时,视频加载失败,仅显示视频控件。

调查

检查视频文件后,发现较小的视频可以正常工作,而较大的视频没有。该问题与视频大小和浏览器的默认缓冲行为有关。

范围请求支持:

对于大于特定大小的视频,浏览器需要服务器支持范围请求(部分内容服务)。这允许浏览器仅获取播放所需的视频部分,从而防止整个文件加载到内存中。

在这种情况下,GoLang 代码未配置为处理 Range 请求。所提供的实现只是将整个文件作为单个响应提供。因此,浏览器无法播放较大的视频。

解决方案

为了解决该问题,采取了以下步骤:

  1. 使用http.FileServe(): http.FileServe()方法默认处理Range请求。通过使用此方法提供视频文件,服务器能够向浏览器提供部分内容。
  2. 配置自定义范围请求处理:

或者,如果不首选 http.FileServe(),则可以实现自定义范围请求处理。这涉及在响应中设置以下标头:

  • Accept-Ranges: bytes
  • Content-Length(文件大小)
  • Content-Range(字节) range request)
  1. 使用 HTTP 状态代码 206:

对于 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn