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

如何使用MediaToolkit无需读写磁盘从内存视频中提取缩略图

内存视频缩略图提取方案(无磁盘读写)

核心思路是利用FFmpeg的标准输入输出能力,直接在内存中完成视频输入、帧提取、缩略图输出全流程,无需任何磁盘IO操作。

实现步骤

你无需额外引入MediaToolkit等封装库,仅需要准备FFmpeg可执行文件(无需安装,仅需放在程序可访问路径下),通过进程调用实现全内存操作:

  1. 优先直接使用IFormFile自带的Stream,不需要额外转成byte[],可以节省内存开销;如果已有byte[]格式的视频数据,包装成MemoryStream即可使用。
  2. 启动FFmpeg进程,配置为从标准输入读取视频数据,将提取到的缩略图输出到标准输出。
  3. 将内存中的视频流写入FFmpeg的标准输入,再从FFmpeg的标准输出读取缩略图二进制数据。

代码示例

using System.Diagnostics;
using System.IO;

/// <summary>
/// 从内存视频流提取缩略图
/// </summary>
/// <param name="videoStream">内存视频流</param>
/// <param name="frameOffsetSeconds">取第N秒的帧作为缩略图</param>
/// <param name="thumbnailWidth">缩略图宽度,高度自动适配宽高比</param>
/// <returns>JPEG格式的缩略图二进制数据</returns>
public async Task<byte[]> ExtractThumbnailAsync(Stream videoStream, int frameOffsetSeconds = 1, int thumbnailWidth = 320)
{
    // 替换为你的FFmpeg可执行文件路径
    var ffmpegExecutablePath = Path.Combine(AppContext.BaseDirectory, "ffmpeg.exe");

    var processStartInfo = new ProcessStartInfo
    {
        FileName = ffmpegExecutablePath,
        // 命令参数说明:
        // -ss {x} 跳转到第x秒,放在-i前可实现快速 seek 无需解码全视频
        // -i - 从标准输入读取视频数据
        // -vframes 1 仅提取1帧
        // -vf scale={w}:-1 保持宽高比缩放缩略图
        // -f image2pipe 以图片格式输出到管道
        // -q:v 2 最高JPEG质量
        // - 输出内容到标准输出
        Arguments = $"-ss {frameOffsetSeconds} -i - -vframes 1 -vf \"scale={thumbnailWidth}:-1\" -f image2pipe -q:v 2 -",
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        UseShellExecute = false,
        CreateNoWindow = true
    };

    using var ffmpegProcess = Process.Start(processStartInfo);
    if (ffmpegProcess == null)
    {
        throw new InvalidOperationException("FFmpeg进程启动失败");
    }

    // 将内存视频流写入FFmpeg标准输入
    await videoStream.CopyToAsync(ffmpegProcess.StandardInput.BaseStream);
    ffmpegProcess.StandardInput.Close();

    // 从标准输出读取生成的缩略图
    using var thumbnailStream = new MemoryStream();
    await ffmpegProcess.StandardOutput.BaseStream.CopyToAsync(thumbnailStream);

    await ffmpegProcess.WaitForExitAsync();
    if (ffmpegProcess.ExitCode != 0)
    {
        // 可通过 ffmpegProcess.StandardError.ReadToEnd() 查看错误详情
        throw new InvalidOperationException("缩略图提取失败,请检查视频格式是否合法");
    }

    return thumbnailStream.ToArray();
}

调用方法

  • 输入为IFormFile:直接传入formFile.OpenReadStream()即可调用方法
  • 输入为byte[]:传入new MemoryStream(videoByteArray)即可调用方法

注意事项

  • 如需输出PNG格式缩略图,将参数中的-f image2pipe替换为-f pngpipe即可
  • 可根据业务需求调整frameOffsetSeconds参数,避免取到黑帧
  • 该方案支持所有FFmpeg兼容的视频格式,兼容性优于大部分第三方封装库

内容的提问来源于stack exchange,提问作者Joe Morgan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 06:06:05