「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > GoLang Web サーバーが大きな MP4 ビデオの配信に失敗するのはなぜですか?

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

2024 年 11 月 8 日に公開
ブラウズ:831

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

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

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

範囲リクエストの場合、サーバーは 200 OK ではなく 206 Partial Content の HTTP ステータス コードを返す必要があります。

実装

カスタム範囲リクエスト処理は次の方法で実装されました:

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)))
    }
}

ビデオのループ:

ビデオが確実にループするように、次のロジックが追加されました:

if contentType == "video/mp4" {
    http.ServeFile(w, r, path)
} else {
    w.Header().Add("Content-Type", contentType)
    w.Write(data)
}

これは MP4 ビデオに http.ServeFile() を使用し、ループを正しく処理します。

最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3