首页 > 解决方案 > Get frame from video bytes

问题描述

I'm extracting a frame from a video using ffmpeg and golang. If I have a video in bytes instead of saved on disk as an .mp4, how do I tell ffmpeg to read from those bytes without having to write the file to disk, as that is much slower?

I have this working reading from a file, but I'm not sure how to read from bytes.

I've looked at the ffmpeg documentation here but only see output examples instead of input examples.

func ExtractImage(fileBytes []byte){

    // command line args, path, and command
    command = "ffmpeg"
    frameExtractionTime := "0:00:05.000"
    vframes := "1"
    qv := "2"
    output := "/home/ubuntu/media/video-to-image/output-" + time.Now().Format(time.Kitchen) + ".jpg"

    // TODO: use fileBytes instead of videoPath
    // create the command
    cmd := exec.Command(command,
        "-ss", frameExtractionTime,
        "-i", videoPath,
        "-vframes", vframes,
        "-q:v", qv,
        output)

    // run the command and don't wait for it to finish. waiting exec is run
    // ignore errors for examples-sake
    _ = cmd.Start()
    _ = cmd.Wait()
}

标签: goffmpeg

解决方案


通过指定选项的值,您可以ffmpeg从标准输入读取数据而不是从磁盘读取文件。然后只需将您的视频字节作为标准输入传递给命令。--i

func ExtractImage(fileBytes []byte){

    // command line args, path, and command
    command := "ffmpeg"
    frameExtractionTime := "0:00:05.000"
    vframes := "1"
    qv := "2"
    output := "/home/ubuntu/media/video-to-image/output-" + time.Now().Format(time.Kitchen) + ".jpg"

    cmd := exec.Command(command,
        "-ss", frameExtractionTime,
        "-i", "-",  // to read from stdin
        "-vframes", vframes,
        "-q:v", qv,
        output)

    cmd.Stdin = bytes.NewBuffer(fileBytes)

    // run the command and don't wait for it to finish. waiting exec is run
    // ignore errors for examples-sake
    _ = cmd.Start()
    _ = cmd.Wait()
}

您可能需要运行ffmpeg -protocols以确定pipe您的 ffmpeg 版本是否支持该协议(从标准输入读取)。


推荐阅读