Сохранение непрерывного потока изображений из ffmpeg image2pipe - PullRequest
1 голос
/ 11 февраля 2020

Я пытаюсь сохранить последовательность / непрерывные изображения из ffmpeg image2pipe в go. Проблема с кодом ниже в том, что он сохраняет только первое изображение в потоке из-за блокирующего характера io.Copy, так как он ожидает закрытия читателя или писателя.

package main

import (
    "fmt"
    "io"
    "log"
    "os"
    "os/exec"
    "strconv"
    "time"
)

//Trying to get png from stdout pipe

func main() {
    fmt.Println("Running the camera stream")
    ffmpegCmd := exec.Command("ffmpeg", "-loglevel", "quiet", "-y", "-rtsp_transport", "tcp", "-i", "rtsp://admin:123456@192.168.1.41:554/h264Preview_01_main", "-r", "1", "-f", "image2pipe", "pipe:1")

    ffmpegOut, err := ffmpegCmd.StdoutPipe()
    if err != nil {
        return
    }

    err = ffmpegCmd.Start()

    if err != nil {
        log.Fatal(err)
    }

    count := 0
    for {
        count++
        t := time.Now()
        fmt.Println("writing image" + strconv.Itoa(count))
        filepath := "image-" + strconv.Itoa(count) + "-" + t.Format("20060102150405.png")

        out, err := os.Create(filepath)
        if err != nil {
            log.Fatal(err)
        }
        defer out.Close()

        _, err = io.Copy(out, ffmpegOut)
        if err != nil {
            log.Fatalf("unable to copy to file: %s", err.Error())
        }
    }
    if err := ffmpegCmd.Wait(); err != nil {
        log.Fatal("Error while waiting:", err)
    }
}

Я реализовал свой собственная функция сохранения и копирования, основанная на коде io.Copy https://golang.org/src/io/io.go

func copyAndSave(w io.Writer, r io.Reader) error {
    buf := make([]byte, 1024, 1024)
    for {
        n, err := r.Read(buf[:])
        if n == 0 {

        }
        if n > 0 {
            d := buf[:n]
            _, err := w.Write(d)
            if err != nil {
                return err
            }
        }
        if err != nil {
            return err
        }

    }
    return nil
}

, затем я обновил для l oop в своей основной функции блок, показанный ниже, но все же я Я получаю только первое изображение в последовательности. из-за того, что r.Read(buf[:]) является блокирующим вызовом.

for {
        count++
        t := time.Now()
        fmt.Println("writing image" + strconv.Itoa(count))
        filepath := "image-" + strconv.Itoa(count) + "-" + t.Format("20060102150405.png")

        out, err := os.Create(filepath)
        if err != nil {
            log.Fatal(err)
        }
        defer out.Close()

        err = copyAndSave(out, ffmpegOut)
        if err != nil {
            if err == io.EOF {
                break
            }
            log.Fatalf("unable to copy to file: %s", err.Error())
            break
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...