在ASP.NET Core中借助FFmpeg处理视频流生成缩略图及获取视频信息
基于FFmpeg流处理的解决方案
核心实现思路
FFmpeg/FFprobe本身支持标准输入(stdin)作为输入源、标准输出(stdout)作为输出目标,完全不需要依赖本地磁盘文件,可以直接对接内存流或者Azure Blob的网络流完成处理,完全适配你的业务场景,处理2M以内的短视频延迟通常在几十毫秒级别,远快于Azure Media Services。
具体实现方案
你可以借助CliWrap类库简化FFmpeg进程的调用和流对接操作,示例代码如下:
1. 直接从上传流生成缩略图
[HttpPost] [Route("test_upload")] public async Task<IActionResult> TestUpload(IFormFile mediaFile) { // 1. 读取上传视频流,不需要存本地 await using var videoStream = mediaFile.OpenReadStream(); using var thumbnailStream = new MemoryStream(); // 2. 调用FFmpeg从流生成缩略图 var ffmpegCmd = Cli.Wrap("ffmpeg") // 参数说明:从stdin读输入,取第1秒的帧,输出1帧jpg到stdout .WithArguments("-i - -ss 00:00:01 -vframes 1 -f image2pipe -vcodec mjpeg -") .WithStandardInputPipe(PipeSource.FromStream(videoStream)) .WithStandardOutputPipe(PipeTarget.ToStream(thumbnailStream)) // 可选:设置超时时间,避免异常进程卡住 .WithValidation(CommandResultValidation.None); await ffmpegCmd.ExecuteAsync(); // 3. 缩略图流重置位置后直接上传到Azure Blob thumbnailStream.Position = 0; // 此处省略上传缩略图到Azure Blob的代码 // 4. 原视频流也可以直接上传到Azure Blob,不需要本地中转 videoStream.Position = 0; // 此处省略上传原视频到Azure Blob的代码 return Ok(); }
2. 从流提取视频基础信息
可以搭配FFprobe直接从流解析元数据,无需写本地文件:
await using var videoStream = mediaFile.OpenReadStream(); using var metaOutput = new MemoryStream(); var ffprobeCmd = Cli.Wrap("ffprobe") // 参数说明:输出json格式的视频元信息,从stdin读输入 .WithArguments("-v quiet -print_format json -show_format -show_streams -i -") .WithStandardInputPipe(PipeSource.FromStream(videoStream)) .WithStandardOutputPipe(PipeTarget.ToStream(metaOutput)); await ffprobeCmd.ExecuteAsync(); // 解析输出的json即可获取时长、分辨率、码率等所有基础信息 metaOutput.Position = 0; using var reader = new StreamReader(metaOutput); var metaJson = await reader.ReadToEndAsync();
部署注意事项
部署服务时,需要将对应系统版本的FFmpeg、FFprobe二进制文件放到程序运行目录,或者配置系统环境变量让进程可以找到执行文件即可。如果视频已经上传到Azure Blob,也可以直接调用BlobClient.OpenReadAsync()获取可读流传入FFmpeg,不需要下载到本地。
现有临时方案的潜在风险
你当前使用临时文件夹中转文件的方案在测试环境可以正常运行,但生产环境高并发场景下会存在以下问题:
- 磁盘IO开销:频繁读写小文件会增加不必要的IO消耗,拖慢接口响应速度,并发量高时可能出现IO瓶颈
- 临时文件泄漏:如果程序中途崩溃、抛出异常没有走到删除逻辑,会产生大量冗余临时文件,长期运行会占满磁盘空间
- 权限限制:如果部署在Azure App Service等PaaS环境,部分目录默认没有写入权限,会直接导致功能报错
- 并发冲突:如果没有使用唯一标识命名临时文件,高并发场景下可能出现文件覆盖、读取错误的问题
内容的提问来源于stack exchange,提问作者Gaetano Lenoci
相关产品推荐
相关产品推荐

