ビデオファイルを提供するために、この単純なhttpサーバーを作成しました。
_package main
import (
"net/http"
"os"
"bytes"
"io"
"fmt"
)
func handler(w http.ResponseWriter, r *http.Request) {
rangeValue := r.Header.Get("range")
fmt.Println("Range:")
fmt.Println(rangeValue)
buf := bytes.NewBuffer(nil)
f, _ := os.Open("oceans_1.webm")
io.Copy(buf, f) // Error handling elided for brevity.
f.Close()
w.Header().Set("Accept-Ranges","bytes")
w.Header().Set("Content-Type", "video/webm")
w.Header().Set("Content-Length","22074728")
w.Header().Set("Last-Modified", "Wed, 29 Nov 2017 17:10:44 GMT")
w.WriteHeader(206)
w.Write(buf.Bytes())
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
_
ビデオは完璧に提供されますが、ビデオの時間を変更することはできません。タイムラインビデオカーソルをクリックしても、位置が変更されず、ビデオが特定の時間にジャンプしません。
http.ServeFile(w, r, "oceans_1.webm")
を使用してビデオを配信すると、すべてが完璧に機能します。ビデオの時間を変更できます。
このさまざまな動作は、net/http
パッケージの ServeContent のドキュメントに直接記載されています(私の強調):
ServeContentは、提供されたReadSeekerのコンテンツを使用してリクエストに応答します。 io.CopyよりもServeContentの主な利点は、範囲リクエストを適切に処理し、MIMEタイプを設定し、If-Match、If-Unmodified-を処理することです。以降、If-None-Match、If-Modified-Since、およびIf-Rangeリクエスト。
net/http
コードを確認すると、 ServeFile
が serveContent
を呼び出すことがわかります serveFile
)、これは ServeContent
によって呼び出される同じエクスポートされていない関数です。
さまざまな動作の理由については詳しく調べていませんが、パッケージのドキュメントでは、io.Copy
戦略が機能していないのにhttp.ServeFile
が機能している理由が明確になっています。