I've written this simple http server to serve video file:
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)
}
The video is served perfect, but I can not change time of the video. When I click on the timeline video cursor it doesn't change the position and the video doesn't jump to specific time.
When I serve the video using http.ServeFile(w, r, "oceans_1.webm")
everything works perfect - I can change video time.
This different behavior is directly addressed on the net/http
package, on the documentation for ServeContent (emphasis mine):
ServeContent replies to the request using the content in the provided ReadSeeker. The main benefit of ServeContent over io.Copy is that it handles Range requests properly, sets the MIME type, and handles If-Match, If-Unmodified-Since, If-None-Match, If-Modified-Since, and If-Range requests.
If you check the net/http
code, you'll see that ServeFile
calls serveContent
(through serveFile
), which is the same unexported function called by ServeContent
.
I've not digged into the reason for the different behaviors, but the documentation on the package makes quite clear why your io.Copy
strategy is not working, while the http.ServeFile
does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With