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

C#调用FFmpeg管道读取字节流输入报错问题求助

使用FFmpeg Pipe功能处理字节数组输入时报错

问题背景

我尝试用FFmpeg的pipe功能跳过磁盘写入,实现了两种输入方式(文件路径、字节数组)、输出方法和执行方法。文件路径输入正常,但字节数组输入时触发报错。

错误信息

[mov,mp4,m4a,3gp,3g2,mj2 @ 00000137385a10c0] stream 1, offset 0x30: partial file
Error demuxing input file 0: Invalid data found when processing input
pipe:.mp4: Invalid data found when processing input
Cannot determine format of input stream 0:0 after EOF
Error marking filters as finished

相关代码实现

输入方法

public FFMPEG input(string path)
{
    parameters.Add($"-i {path}");
    return this;
}
public FFMPEG input(byte[] file)
{
    parameters.Add("-i pipe:.mp4");
    files.Add(file);
    return this;
}

输出方法

public FFMPEG output(string format)
{
    _output = $"-f {format} -";
    return this;
}

执行方法

public byte[] run()
{
    if (_output == "")
    {
        throw new Exception("missing output format");
    }

    var process = new Process()
    {
        StartInfo =
        {
            FileName = @"ffmpeg.exe",
            Arguments = String.Join(" ", parameters) + " " + _output,
            RedirectStandardOutput = true,
            RedirectStandardInput = true,
            UseShellExecute = false,
        }
    };

    process.Start();

    foreach (var item in files)
    {
        process.StandardInput.BaseStream.Write(item);
    }

    byte[] result;
    using(var memstream = new MemoryStream())
    {
        process.StandardOutput.BaseStream.CopyTo(memstream);
        result = memstream.ToArray();
    }
    process.WaitForExit();

    return result;
}

调用示例

  • 正常运行的文件输入调用:
var result = new FFMPEG()
.input("./assets/video.mp4")
.output("avi")
.run();
  • 报错的字节数组输入调用:
var result = new FFMPEG()
    .input(File.ReadAllBytes("./assets/video.mp4"))
    .output("avi")
    .run();

问题原因及解决办法

核心问题

  1. Pipe语法错误:-i pipe:.mp4是错误写法,FFmpeg的标准输入pipe应为-i -,后缀.mp4完全多余,FFmpeg会自动识别输入流格式,也可通过-f mp4 -i -手动指定格式。
  2. 未关闭输入流:写入字节数组后未关闭StandardInput,FFmpeg会一直等待更多输入,判定数据不完整,触发"partial file"报错。
  3. 死锁风险:同步读取输出流的逻辑可能导致进程因输出缓冲区满而阻塞。

修改后的代码

输入方法调整

public FFMPEG input(byte[] file)
{
    // 基础写法:让FFmpeg自动识别输入格式
    parameters.Add("-i -");
    // 若自动识别失败,可手动指定格式:parameters.Add("-f mp4 -i -");
    files.Add(file);
    return this;
}

执行方法调整

public byte[] run()
{
    if (_output == "")
    {
        throw new Exception("missing output format");
    }

    var process = new Process()
    {
        StartInfo =
        {
            FileName = @"ffmpeg.exe",
            Arguments = String.Join(" ", parameters) + " " + _output,
            RedirectStandardOutput = true,
            RedirectStandardInput = true,
            RedirectStandardError = true, // 开启后可读取错误日志,方便调试
            UseShellExecute = false,
            CreateNoWindow = true
        }
    };

    byte[] result = null;
    // 异步读取输出流,避免死锁
    var outputTask = Task.Run(() => 
    {
        using(var memstream = new MemoryStream())
        {
            process.StandardOutput.BaseStream.CopyTo(memstream);
            result = memstream.ToArray();
        }
    });

    process.Start();

    // 写入所有输入数据后立即关闭标准输入,告知FFmpeg数据已发送完毕
    foreach (var item in files)
    {
        process.StandardInput.BaseStream.Write(item);
    }
    process.StandardInput.Close();

    outputTask.Wait();
    process.WaitForExit();

    // 调试时可打印错误信息
    // string errorLog = process.StandardError.ReadToEnd();
    // Console.WriteLine(errorLog);

    return result;
}

内容的提问来源于stack exchange,提问作者thiago kaique

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:25:19