Go 保存来自ffmpeg image2pipe的连续图像流
我正在尝试将ffmpeg image2pipe中的序列/连续图像保存到go中。下面代码的问题是,由于io.Copy的阻塞性质,它只保存流中的第一个图像,因为它等待读卡器或写入器关闭Go 保存来自ffmpeg image2pipe的连续图像流,go,ffmpeg,Go,Ffmpeg,我正在尝试将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() {
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代码实现了自己的保存和复制功能
然后我将主函数中的for循环更新为下面的块,但仍然只得到序列中的第一个图像。由于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
}
}
我怀疑你的问题与阻止复制有关。如果ffmepg要输出多个文件,您如何知道一个文件何时停止,另一个文件何时启动?复制就是简单地复制它读取的所有内容,直到管道关闭,所以我怀疑您有一个包含多个图像的文件。我明白了,现在想想看,我怀疑ffmpeg正在将图像数据通过管道传输到stdout,中间有行断开。不太可能。图像是二进制数据,将包含多个换行符。我建议您了解ffmpeg如何在没有管道的情况下编写其输出。我猜它会将其写入多个文件,试图从管道处理此类输出可能是徒劳的。我怀疑您的问题与阻止复制有关。如果ffmepg要输出多个文件,您如何知道一个文件何时停止,另一个文件何时启动?复制就是简单地复制它读取的所有内容,直到管道关闭,所以我怀疑您有一个包含多个图像的文件。我明白了,现在想想看,我怀疑ffmpeg正在将图像数据通过管道传输到stdout,中间有行断开。不太可能。图像是二进制数据,将包含多个换行符。我建议您了解ffmpeg如何在没有管道的情况下编写其输出。我的猜测是,它会将其写入多个文件,而试图从管道处理此类输出可能是徒劳的。
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
}
}