2

One of my APIs accepts an mp4 video file and then uploads the file to my cloud (AWS-S3). I read the video from the body, which means the whole video is in a raw []byte format, and then directly pipe it to my storage. The problem is, those videos are quite large and when the user wants to download the video, he needs to wait quite a long time. Showing a black screen with a progress bar for 30 seconds obviously hurts the user experience. I need to show him at least some kind of preview in the form of a thumbnail.

Now that's my problem. I don't find any resources on how to pick the first frame of a video and then render it to an image.

A user from Stackoverflow asked this question 2 years go: First frame of video used ffmpeg to achieve this, but his context and problem were different. He needed to get the first frame from a static file, while I have the video in plain [] byte format from a http body. The answer to his question, can therefor not be applied to mine.

Don't get me wrong, I'm not asking you to do it for me so I can copy and paste it into my code base. I just need some kind of clue.

Thank you for your help.

(EDIT: I tried piping it to ffmpeg :

    log.Print("Creating thumbnail..")
    width := 640
    height := 360
    var imageBuffer bytes.Buffer
    log.Print("Size of the video: ", len(videoData))

    cmd := exec.Command("ffmpeg", "-i", "pipe:0", "-vframes", "1", "-s", fmt.Sprintf("%dx%d", width, height), "-f", "singlejpeg", "-")
    cmd.Stdout = &imageBuffer

    stdinPipe, pipeError := cmd.StdinPipe()
    _ = pipeError
    defer  stdinPipe.Close()

    log.Print("write to pipe..")
    err := cmd.Start()

    n, writingErr := stdinPipe.Write(videoData)

        if writingErr != nil {
            log.Panic("WRITING ERROR")

        }
    log.Print("Bytes written: ", n)


    log.Print("pipe has been written to")
    cmd.Wait()
    log.Print("Waited..")

    if err != nil {
        ErrorLogger.ReportErrorAndWait(ErrorLogger.ErrorMessage{Error: err, Message: "Unable to create thumbnail.", Priority: ErrorLogger.HIGH_PRIORITY, Category: "upload"})
        log.Panic("ERROR")
        go UploadThumbnail(videoData, fileNameWithoutType)
    }

    imageBytes := imageBuffer.Bytes()
    log.Print("Size of the image: ", len(imageBytes))

But the output was an empty image.

2018/04/14 12:41:50 Size of the image: 0

thelearner
  • 1,440
  • 3
  • 27
  • 58
  • 1
    Is dumping the video to file an option? If yes, then you got your answer. If not, is dumping the beginning of it (e.g. the first 100KB) an option? If yes, `ffmpeg` will most likely be able to render the first frame from it. – icza Apr 12 '18 at 14:15
  • You can adapt that answer, just use a StdinPipe() and write your []bytes to it until ffmpeg is done. – Michael Hampton Apr 12 '18 at 17:34
  • 2
    https://github.com/bakape/thumbnailer – thelearner Apr 16 '18 at 08:04

0 Answers0