ホームページ >バックエンド開発 >Golang >GoLang Web サーバーが大きな MP4 ビデオの配信に失敗するのはなぜですか?

GoLang Web サーバーが大きな MP4 ビデオの配信に失敗するのはなぜですか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-11-01 05:02:02436ブラウズ

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

MP4 ビデオを提供する GoLang HTTP Web サーバー

チャレンジ

HTML/JS/CSS および画像を提供する Web サーバーは GoLang を使用して作成されました。サーバーが MP4 ビデオ ファイルを提供しようとしたときに、ビデオの読み込みに失敗し、ビデオ コントロールのみが表示されました。

調査

ビデオ ファイルを調査したところ、小さいビデオが動作していることが判明しました。大きなビデオではそうではありませんでした。この問題は、ビデオ サイズとブラウザのデフォルトのバッファリング動作に関連していました。

範囲リクエストのサポート:

特定のサイズを超えるビデオの場合、ブラウザはサーバーを必要とします。 Range リクエスト (部分的なコンテンツの提供) をサポートします。これにより、ブラウザーは再生に必要なビデオの部分のみを取得できるようになり、ファイル全体がメモリに読み込まれるのを防ぎます。

この場合、GoLang コードは Range リクエストを処理するように構成されていませんでした。提供された実装は、ファイル全体を単一の応答として提供するだけでした。その結果、ブラウザは大きなビデオを再生できませんでした。

解決策

問題を解決するには、次の手順が実行されました:

  1. http.FileServe() を使用します: http.FileServe() メソッドは、デフォルトで Range リクエストを処理します。このメソッドを使用してビデオ ファイルを提供することにより、サーバーは部分的なコンテンツをブラウザに提供できました。
  2. カスタム範囲リクエスト処理の構成:

またはhttp.FileServe() が望ましくない場合は、カスタム範囲リクエストの処理を実装できます。これには、応答で次のヘッダーを設定することが含まれます:

  • Accept-Range: bytes
  • Content-Length (ファイルのサイズ)
  • Content-Range (バイト)範囲がリクエストされました)
  1. HTTP ステータス コード 206 を使用します:

範囲リクエストの場合、サーバーは 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 Web サーバーが大きな MP4 ビデオの配信に失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。