0

answered

I am having a hard time with Mongodb and Gridfs, using it with Go's http package. I am trying to store a .mp4 file into Gridfs, then pull it out into the browser for playback.

Heres what I am doing now. It successfully pulls the file from database, I could even write it correctly to a download location.

// Connect to database
// Session to database

func movie(w http.ResponseWriter r *http.Request) {
    file, err := db.GridFS("fs").Open("movie.mp4")
    if err != nil {
        log.Println(err)
    }
    defer file.Close()

    w.Header.Set("Content-type", "video/mp4")
    if _, err := io.Copy(w, file); err != nil {
    log.Println(err)
    } 
    // I am trying to send it to the browser.
    // I want to achieve same thing as, http://localhost/view/movie.mp4, 
    as if you did that.
}

If the file was on the server, I would just do something like this. But instead I am trying to store it in Mongodb, for all around easier use involving metadata.

func movie(w http.ResponseWriter r *http.Request) {
    http.ServeFile("./uploads/movie.mp4") // Easy
}

The browser is receiving something, but its just malformed or corrupted. Just shows the video player with an error message. Any help would be appreciated, I have only been programming a week.

Here is a picture of the error, no console error messages.

enter image description here

Unless someone has an alternative to storing video files for playback in browser somewhere other than MongoDB or Amazon S3. Please let me know, thanks.

ABC
  • 2,068
  • 1
  • 10
  • 21
  • Please show the webconsole error. – Roman Kiselenko Dec 26 '17 at 07:44
  • I uploaded the picture of the error, Browser is safari. It does not have any console error messages. I don't know why this happens, but if I do **http.ServeFile(".mp4")** you can visit the /video.mp4 url and it loads the default safari player. – ABC Dec 26 '17 at 07:53
  • This `io.Copy(w, r)` is a typo right? You're not actually trying to write the request to the response but the `file`, right? – mkopriva Dec 26 '17 at 08:21
  • And please do check the error returned from `io.Copy`. – mkopriva Dec 26 '17 at 08:23
  • io.Copy has no error, and no the io.Copy is not a typo. I am new and thats what I thought I was supposed to do, to write the file into the browser. I want the file written in the response, and be able to play. – ABC Dec 26 '17 at 08:38
  • Do this instead: `if _, err := io.Copy(w, file); err != nil { // handle error` – mkopriva Dec 26 '17 at 08:40
  • I added the if your error handling, it still does not send the file in the **response** correctly. This must be browser problem, something with the headers maybe? – ABC Dec 26 '17 at 08:41
  • `r` is not the file, `r` is the request you got from the client, copying that into `w` makes little sense. – mkopriva Dec 26 '17 at 08:43
  • Oh if I did that sorry I re-typed it for stack overflow incorrectly. But, yes were are writing out to the browser not the request. Do I need to read over the bytes first and decode it, then send it out? I wouldn't even know how to begin with that. I am thinking it must be a header issue, with **content-length** and bytes. – ABC Dec 26 '17 at 08:47
  • Try the solution from this question: https://stackoverflow.com/questions/38069584/golang-http-webserver-provide-video-mp4 – mkopriva Dec 26 '17 at 16:21
  • I can not use ServeFile, because I am using a database. – ABC Dec 26 '17 at 20:38

1 Answers1

1

You may want to check http.ServeContent. It will handle all the mess (content-type, content-length, partial data, cache) automaticlly and save you a lot of time. It takes a ReadSeeker to serve, which GridFile already implented. So your code may simply change to the below.

func movie(w http.ResponseWriter r *http.Request) {
    file, err := db.GridFS("fs").Open("movie.mp4")
    if err != nil {
        log.Println(err)
    }
    defer file.Close()

    http.ServeContent(w,r,"movie.mp4",file.UploadDate(),file)

}

If that doesn't work, please use tools like curl or wget to download the served content and compare it to the orignal one (in db).

leaf bebop
  • 7,643
  • 2
  • 17
  • 27