A webserver was created using GoLang that serves HTML/JS/CSS and images. When the server attempted to provide an MP4 video file, the video failed to load, showing only video controls.
Upon examining the video files, it was discovered that the smaller video worked while the larger video did not. The issue was related to the video size and the browser's default buffering behavior.
Range Request Support:
For videos larger than a certain size, the browser requires the server to support Range requests (partial content serving). This allows the browser to fetch only the portion of the video needed for playback, preventing the entire file from being loaded into memory.
In this case, the GoLang code was not configured to handle Range requests. The provided implementation simply served the entire file as a single response. As a result, the browser was not able to play the larger video.
To resolve the issue, the following steps were taken:
Alternatively, if http.FileServe() is not preferred, custom range request handling can be implemented. This involves setting the following headers in the response:
For Range requests, the server should return an HTTP status code of 206 Partial Content instead of 200 OK.
Custom range request handling was implemented in the following manner:
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)))
}
}
Looping Video:
To ensure that the video loops, the following logic was added:
if contentType == "video/mp4" {
http.ServeFile(w, r, path)
} else {
w.Header().Add("Content-Type", contentType)
w.Write(data)
}
This uses http.ServeFile() for MP4 videos, which correctly handles looping.
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3