Go中通过管道处理MOV文件时遇Pipe Input Error求助
解决Go中通过管道调用ffmpeg处理MOV文件的异常问题
问题原因
MOV/MP4这类容器格式依赖文件内部的索引结构(比如moov原子),当用管道作为输入时,ffmpeg只能顺序读取数据流,无法像访问本地文件那样随机跳转到文件末尾读取索引信息,导致无法正确解析视频编码参数,进而报出"partial file"、"Invalid data found"这类错误。直接用文件路径时ffmpeg可以自由定位文件指针,所以能正常工作。
解决方案
修改ffmpeg的命令参数,让它适配流式输入的场景:
- 显式指定输入格式为
mov,避免自动探测失败 - 增大
analyzeduration和probesize的值,确保ffmpeg能读取足够的头部数据来解析参数
修改后的Go代码片段:
func main() { inputPath := "video.MOV" fileOutput := "output.mp4" fileBytes, err := os.Open(inputPath) if err != nil { fmt.Println(err) return } defer fileBytes.Close() // 补充关闭输入文件,避免资源泄漏 outFile, err := os.Create(fileOutput) if err != nil { fmt.Println(err) return } defer outFile.Close() cmd := exec.Command( "ffmpeg", "-y", "-analyzeduration", "100M", // 增大分析时长,确保读取足够头部信息 "-probesize", "100M", // 增大探测数据量,覆盖MOV索引区域 "-f", "mov", // 显式指定输入格式为MOV,跳过自动探测 "-i", "pipe:0", "-vf", fmt.Sprintf("scale=-1:%s", "480"), "-c:v", "libx264", "-crf", "23", "-c:a", "aac", "-strict", "experimental", "-f", "mp4", "-movflags", "empty_moov", "pipe:1", ) cmd.Stderr = os.Stderr cmd.Stdin = fileBytes stdout, err := cmd.StdoutPipe() if err != nil { fmt.Println(err) return } if err := cmd.Start(); err != nil { fmt.Println(err) } if _, err := io.Copy(outFile, stdout); err != nil { fmt.Println(err) return } if err := cmd.Wait(); err != nil { fmt.Println(err) } }
额外说明
analyzeduration和probesize的值可根据视频文件大小调整,不需要固定100M,只要能覆盖MOV文件的头部索引区域即可-movflags empty_moov是为了让ffmpeg支持流式输出MP4(无需先写入末尾索引),如果不需要流式输出场景,可去掉该参数,输出文件的兼容性会更好
内容的提问来源于stack exchange,提问作者BJKang
相关产品推荐
相关产品推荐

