如何使用FFMpegCore从视频MemoryStream/byte[]截取快照无需存储物理文件
问题根因
你遇到的错误由三个核心配置问题导致:
- ffmpeg读取管道流时默认的探测大小和分析时长不足,无法正确解析h264流的编码参数,错误日志也明确提示了需要调整
analyzeduration和probesize参数 - 输出配置冲突:你指定了视频编码为png,但强制输出格式为
rawvideo,两种格式不兼容导致输出流解析失败 - 管道流本身不支持随机seek,你在输入参数中添加的
Seek(captureTime)配置无法生效,ffmpeg读取管道时无法直接跳转到指定时间点
修复后的完整代码
首先修改BuildSnapshotArguments方法,补充流探测配置,调整seek逻辑:
private static (FFMpegArguments, Action<FFMpegArgumentOptions> outputOptions) BuildSnapshotArguments( IPipeSource input, IMediaAnalysis source, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0) { captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3); size = PrepareSnapshotSize(source, size); streamIndex ??= source.PrimaryVideoStream?.Index ?? source.VideoStreams.FirstOrDefault()?.Index ?? 0; return (FFMpegArguments .FromPipeInput(input, options => options // 增加流探测大小和分析时长,确保ffmpeg能正确识别编码参数 .WithProbeSize(100_000_000) // 100MB探测大小,可根据实际视频大小调整 .WithAnalyzeDuration(TimeSpan.FromSeconds(10))), // 最长10秒分析时长 options => options // 管道不支持输入侧seek,改为输出侧跳转到指定时间点 .Seek(captureTime) .SelectStream((int)streamIndex, inputFileIndex) .WithVideoCodec(VideoCodec.Png) .WithFrameOutputCount(1) .Resize(size)); }
然后修改SnapshotAsync方法的输出配置,修正格式冲突:
public static async Task<Bitmap> SnapshotAsync(Stream input, IMediaAnalysis source, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0) { input.Seek(0, SeekOrigin.Begin); var streamPipeSource = new FFMpegCore.Pipes.StreamPipeSource(input) { // 可选:调整块大小适配大体积视频 BlockSize = 4096 * 1024 }; var (arguments, outputOptions) = BuildSnapshotArguments(streamPipeSource, source, size, captureTime, streamIndex, inputFileIndex); using var ms = new MemoryStream(); await arguments // 输出格式改为image2匹配png编码,不要用rawvideo .OutputToPipe(new StreamPipeSink(ms), options => outputOptions(options .ForceFormat("image2"))) .ProcessAsynchronously().ConfigureAwait(false); ms.Position = 0; return new Bitmap(ms); }
调用说明
你现有的调用逻辑不需要修改,直接传入MemoryStream即可正常截取快照,不需要将视频写入物理磁盘。如果处理超大体积视频,可以适当上调WithProbeSize的参数值。
内容的提问来源于stack exchange,提问作者Akash Kadia
相关产品推荐
相关产品推荐

