将FFmpeg输出导入命名Windows管道

11

这个问题与我的之前的问题有关:将原始帧转换为WebM实时流

我想将视频导入到ffmpeg中,并通过另一个管道读取返回数据,但是我无法在Windows上将ffmpeg.exe的输出导出到命名管道。

C#中我的管道定义:

NamedPipeServerStream p_to_ffmpeg;
NamedPipeServerStream p_from_ffmpeg;
p_to_ffmpeg = new NamedPipeServerStream("to_ffmpeg", PipeDirection.Out, 1, PipeTransmissionMode.Byte);
p_from_ffmpeg = new NamedPipeServerStream("from_ffmpeg", PipeDirection.In, 1, PipeTransmissionMode.Byte);

然后我使用以下选项在单独的进程中启动ffmpeg.exe-f rawvideo -vcodec rawvideo -video_size 656x492 -r 10 -pix_fmt rgb24 -i \\.\pipe\to_ffmpeg -c:v libvpx -pass 1 -f webm \\.\pipe\from_ffmpeg

ffmpeg.exe拒绝写入管道并显示以下错误:File '\\.\pipe\from_ffmpeg' already exists. Overwrite ? [y/N]

当我将“输出管道”替换为文件名时,它可以正常运行:-f rawvideo -vcodec rawvideo -video_size 656x492 -r 10 -pix_fmt rgb24 -i \\.\pipe\to_ffmpeg -c:v libvpx -pass 1 -f webm output.webm

如何让ffmpeg在Windows中写入命名管道?

编辑:当我强制使用-y选项向管道写入时,会出现以下错误:Could not write header for output file #0 (incorrect codec parameters?): Error number -32 occurred


1
请删除“-pass 1”参数,因为您没有进行双通编码,请发布完整的控制台输出。 - aergistal
@aergistal:感谢您的评论。看起来我已经解决了这个问题。我必须指定管道的缓冲区大小。为什么要删除“-pass 1”?我认为这个选项会确保libvpx只进行一次通行。现在我遇到了ffmpeg停止处理的问题。但我不能排除这不是接收管道的问题,因为该管道在读取函数上阻塞。 - Lucas
@aergistal:控制台输出:输入#0,rawvideo,来自'\\.\pipe\to_ffmpeg': Duration: N/A, start: 0.000000, bitrate: 77460 kb/s Stream #0:0: Video: rawvideo (RGB[24] / 0x18424752), rgb24, 656x492, 77460 k b/s, 10 tbr, 10 tbn, 10 tbc [libvpx @ 03a9ff80] v1.4.0 输出#0,webm,到'\\.\pipe\from_ffmpeg': Metadata: encoder : Lavf56.40.101 Stream #0:0: Video: vp8 (libvpx),yuv420p,656x492,q=-1--1,pass 1,200 kb/ s,10 fps,1k tbn,10 tbc Metadata: encoder : Lavc56.58.100 libvpx 流映射: Stream #0:0 -> #0:0 (rawvideo (native) -> vp8 (libvpx)) - Lucas
1
默认情况下是一遍编码。如果您指定了“-pass 1”,它会创建一个日志文件,用于保留第二遍(“-pass 2”)视频统计信息,但实际上不会进行第二遍编码。在两遍编码中,第一遍分析视频(您可以放弃其输出),而第二遍进行实际编码。 - aergistal
1个回答

7
似乎可以通过在ffmpeg命令中添加"-y"(覆盖)选项并为管道指定缓冲区大小来解决问题。
我的ffmpeg命令(参见aergistal的评论,我还删除了"-pass 1"标志):
"-y -f rawvideo -vcodec rawvideo -video_size 656x492 -r 10 -pix_fmt rgb24 -i \\.\pipe\to_ffmpeg -c:v libvpx -f webm \\.\pipe\from_ffmpeg"
然后按以下方式定义命名管道:
p_from_ffmpeg = new NamedPipeServerStream('from_ffmpeg', 
    PipeDirection.In, 
    1, 
    PipeTransmissionMode.Byte, 
    System.IO.Pipes.PipeOptions.WriteThrough, 
    10000, 10000);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接