I developed a webserver using golang. Pretty plain stuff, it just provides html/js/css and images which works perfectly fine:
func main() {
http.Handle("/", new(viewHandler))
http.ListenAndServe(":8080", nil)
}
func (vh *viewHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path[1:]
log.Println(path)
data, err := ioutil.ReadFile(string(path))
if err == nil {
var contentType string
if strings.HasSuffix(path, ".html") {
contentType = "text/html"
} else if strings.HasSuffix(path, ".css") {
contentType = "text/css"
} else if strings.HasSuffix(path, ".js") {
contentType = "application/javascript"
} else if strings.HasSuffix(path, ".png") {
contentType = "image/png"
} else if strings.HasSuffix(path, ".jpg") {
contentType = "image/jpeg"
}
w.Header().Add("Content-Type", contentType)
w.Write(data)
} else {
log.Println("ERROR!")
w.WriteHeader(404)
w.Write([]byte("404 - " + http.StatusText(404)))
}
}
I tried to add a video in mp4 format to my website in the same way:
<video width="685" height="525" autoplay loop style="margin-top: 20px">
<source src="../public/video/marketing.mp4" type="video/mp4">Your browser does not support the video tag.</video>
and enhanced the content type part of my go application with:
else if strings.HasSuffix(path, ".mp4") {
contentType = "video/mp4"
}
When I open the html file directly in Chrome the Video is playing correctly, but if I open the website by calling the Web Server at http://localhost... it can not be loaded and therefor not played.
There is no video loaded, if I try to hit it directly the browser just shows some video contols without loading the file:
Any ideas on this? thanks in advance.
UPDATE:
As suggested I also tried another video which is working perfectly fine! but I have no clue why, I compared both videos:
Could it be the size??
Cheers and thanks!
UPDATE2:
icza is right and I marked his post as correct answer to my question. But let me explain what I finally did to get it working:
I tried to solve my problem without using the http.FileServe method. Therefore I implemented like so:
} else 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)
}
}
w.Header().Add("Content-Type", contentType)
w.Write(data)
That worked for the first time I played the video. But since I want it to loop it should directly start from the beginning but it stuck at the very last frame of the video.
So I implemented the ServeFile() method like:
if contentType == "video/mp4" {
http.ServeFile(w, r, path)
} else {
w.Header().Add("Content-Type", contentType)
w.Write(data)
}
The video is also playing in a loop correctly now. But I still have no idea why ServeFile() is working and the other method not though the response is exactly the same for both methods. Nevertheless the content is looking like that now:
Cheers and thanks to all of you who helped me.
http.ServeFile()
which supports serving Range requests (required for videos to be able to seek). See related question: How to serve http partial content with Go? – IndefeasibleRange
header other than0-
then of course that is the issue. – Lysischrome://media-internals/
in a new tab - that shows the internal info for all the opened media sinks. You will most probably be able to see what exactly went wrong. – LysisFileServe()
yet in your code you call it. Another problem here is that you callw.WriteHeader()
which commits the headers (so you can't change response headers after that) and you callhttp.ServeFile()
after this - but it won't be able to change headers. – Indefeasible