You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过标准输入向FFmpeg传递多个输入流?

如何通过C#的Process向FFmpeg传递多个输入文件

当你需要用FFmpeg处理多个输入(对应命令行参数-i - -i -)时,直接通过单一的StandardInput流无法实现——FFmpeg会将整个流视为第一个输入的内容,直到流结束才会尝试读取第二个输入,但此时流已关闭,无法写入第二个文件。

最可靠的解决方案是使用命名管道(Named Pipes),为每个输入文件创建独立的管道,让FFmpeg从不同的管道读取数据,实现多输入的独立传递。

修改后的代码示例

using System.IO;
using System.IO.Pipes;
using System.Diagnostics;
using System.Threading.Tasks;

public async void MergeVideoAndAudio()
{
    var videoInputPath = @"C:\testvideo.avi";
    var audioInputPath = @"C:\testaudio.mp3";
    var outputFile = @"C:\outputFile.mp4";

    // 创建两个命名管道,分别用于视频和音频输入
    using var videoPipe = new NamedPipeServerStream("ffmpeg_video_pipe", PipeDirection.Out, 1, PipeTransmissionMode.Byte);
    using var audioPipe = new NamedPipeServerStream("ffmpeg_audio_pipe", PipeDirection.Out, 1, PipeTransmissionMode.Byte);

    var process = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            RedirectStandardInput = false, // 不再依赖标准输入,改用命名管道
            UseShellExecute = false,
            CreateNoWindow = true,
            // Windows下命名管道的路径格式为\\.\pipe\[管道名]
            Arguments = $"-y -i \\\\.\\pipe\\ffmpeg_video_pipe -i \\\\.\\pipe\\ffmpeg_audio_pipe {outputFile}",
            FileName = _ffmpeg
        },
        EnableRaisingEvents = true
    };

    process.Start();

    // 并行向两个管道写入数据
    var videoTask = Task.Run(async () =>
    {
        await videoPipe.WaitForConnectionAsync(); // 等待FFmpeg连接管道
        using var videoFile = new FileStream(videoInputPath, FileMode.Open);
        await videoFile.CopyToAsync(videoPipe);
        videoPipe.WaitForPipeDrain(); // 确保数据全部写入管道
        videoPipe.Close(); // 关闭管道,告知FFmpeg该输入流结束
    });

    var audioTask = Task.Run(async () =>
    {
        await audioPipe.WaitForConnectionAsync();
        using var audioFile = new FileStream(audioInputPath, FileMode.Open);
        await audioFile.CopyToAsync(audioPipe);
        audioPipe.WaitForPipeDrain();
        audioPipe.Close();
    });

    await Task.WhenAll(videoTask, audioTask);
    process.WaitForExit();
}

关键说明

  1. 命名管道的优势:每个输入对应独立的数据流,FFmpeg可以分别读取,不会出现流混淆的问题,适用于任意格式的输入文件合并(比如视频+音频)。
  2. 管道连接逻辑:必须等待FFmpeg与管道建立连接(WaitForConnectionAsync)后再写入数据,避免数据丢失。
  3. 流结束标记:写入完成后关闭管道,FFmpeg会识别到该输入流的EOF,继续处理下一个输入。

补充:单一StandardInput流的局限性

如果强行使用单一StandardInput流,仅能通过FFmpeg的concat协议处理同格式的文件,但需要先构造一个文本清单文件传递给FFmpeg,再依次写入实际文件数据,这种方式仅适用于特定场景,通用性远不如命名管道。

内容的提问来源于stack exchange,提问作者Stiven Diplet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 11:40:51