提问人:alex 提问时间:11/8/2023 最后编辑:alex 更新时间:11/8/2023 访问量:65
将 ffmpeg 执行结果写入 io 时冻结。管
Freeze when writing ffmpeg execution result to io.Pipe
问:
我正在编写一个包装器来使用.包装器旨在简化文件系统的工作,我想转换一个视频,将转换结果写入,在 goroutine 中读取它并传输它以预览新转换后的文件。为此,我使用 .但是我遇到了一个问题,当我开始测试时,执行只是挂起,我无法获得任何结果,但没有错误,一切都挂起。exec.Cmd
io.Pipe
io.Pipe
FFmpeg
CmdRunner 源代码
type CmdRunner struct {
commander Commander
StdIn io.ReadCloser
StdoutWriter io.WriteCloser
StdErrWriter io.Writer
}
func (c *CmdRunner) RunByPipe(ctx context.Context) error {
//done := make(chan error)
name, args := c.commander.Command()
cmd := exec.CommandContext(ctx, name, args...)
if c.StdIn != nil {
fmt.Print("RunByPipe STDIN\n")
cmd.Stdin = c.StdIn
}
if c.StdoutWriter != nil {
fmt.Print("RunByPipe STDOUT\n")
cmd.Stdout = c.StdoutWriter
}
stderr := bytes.Buffer{}
cmd.Stderr = &stderr
if err := cmd.Start(); err != nil {
return err
}
if err := cmd.Wait(); err != nil {
return err
}
if stderr.String() != "" {
return fmt.Errorf("want empty stderr, but got %s", stderr.String())
}
return nil
}
单元测试代码
type TestCommander struct {
name string
args []string
}
func (c *TestCommander) SetCommand(name string, args []string) {
c.name = name
c.args = args
}
func (c *TestCommander) Command() (string, []string) {
return c.name, c.args
}
func TestConvert(t *testing.T) {
ctx := context.Background()
filePath := "testdata/input_mp4.mp4"
data, err := convertFile(filePath, ctx)
outFile := "testdata/output_mp4.mp4"
if err != nil {
fmt.Print("ERR: ", err, "\n")
}
os.WriteFile(outFile, data, 0644)
}
func convertFile(filePath string, ctx context.Context) (bytes []byte, err error) {
// Create a CmdRunner instance with your custom Commander.
runner := &CmdRunner{}
commander := &TestCommander{}
args := []string{
"-nostats",
"-i", filePath,
"-y",
"-loglevel", "0",
"-filter:v", "fps=30, crop=trunc(iw/2)*2:trunc(ih/2)*2",
"-c:v", "libx264",
"-c:a", "aac",
"-pix_fmt", "yuv420p",
"-movflags", "frag_keyframe+faststart",
"-bufsize", "24M",
"-maxrate", "12M",
"-f", "mp4",
"pipe:1",
}
commander.SetCommand("ffmpeg", args)
runner.SetCommander(commander)
outputPipeReader, outputPipeWriter := io.Pipe()
runner.SetStdOutWriter(outputPipeWriter)
wg := &sync.WaitGroup{}
wg.Add(1)
go func() {
defer outputPipeReader.Close()
defer wg.Done()
// Read data from output pipe
bytes, err = io.ReadAll(outputPipeReader)
if err != nil {
fmt.Print("\nReadAll err: ", err, "\n")
}
}()
err = runner.RunByPipe(ctx)
if err != nil {
fmt.Print("\nRunByPipe err: ", err, "\n")
return
}
wg.Wait()
return
}
我找不到可能出了什么问题的线索。
PS:但是如果我删除然后问题就消失了,但是不会有数据,因为没有写入任何内容。为什么?if err := cmd.Wait(); err != nil { return err }
io.Pipe
答: 暂无答案
评论