目錄
一、目的
二、解決方案
2.1 什么是FFmpeg
2.2 FFmpeg主要功能
2.3 使用Xabe.FFmpeg調用FFmpeg功能
2.4 使用 FFmpeg 的 drawbox 濾鏡來繪制 ROI
三、總結
一、目的
當前市場上有很多目標檢測智能識別的相關算法,當前調用一個醫療行業的AI識別算法后返回了一堆對應幀上的ROI數據,因此為了展示算法識別效果,把返回的Roi畫到對應幀上進行展示,這里使用FFmpeg對視頻進行處理,基于FFmpeg 的 drawbox 濾鏡來繪制 ROI。
????????展示:
處理前:

處理后:

二、解決方案
2.1 什么是FFmpeg
FFmpeg 本身是一個多媒體處理工具,它可以對視頻流進行各種處理(如裁剪、濾鏡、編碼等),以及 視頻流推送到 RTMP 服務器或從 RTMP 服務器拉取流。
2.2 FFmpeg主要功能
FFmpeg 主要用于以下幾個方面:
- 推流:將本地視頻文件或實時視頻流推送到 RTMP 服務器。
- 拉流:從 RTMP 服務器拉取視頻流并進行處理(如轉碼、轉封裝等)。
- 處理流:對視頻流進行各種處理(如裁剪、濾鏡、編碼等)。
2.3 使用Xabe.FFmpeg調用FFmpeg功能
Xabe.FFmpeg 是一個基于 .NET Standard 的 FFmpeg 封裝庫,旨在簡化媒體處理任務。它允許開發者在不了解 FFmpeg 工作原理的情況下,通過 .NET Core 應用程序調用 FFmpeg 功能,并傳遞自定義參數。Xabe.FFmpeg 提供了豐富的 API,支持視頻和音頻的轉換、剪輯、合并等操作,適用于各種媒體處理需求。
本項目中使用版本為:5.2.6
dotnet add package Xabe.FFmpeg
????????簡單使用示例:簡單展示了獲取視頻第一幀保存為圖像存儲在本地(這里也可以獲取任何特定幀)。
using AI.Demo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xabe.FFmpeg;namespace AI.Demo.Common
{public class FFmpegutil{static FFmpegutil(){//獲取存放本地ffmpg.exe路徑的文件夾路徑//如果是使用Nuget包安裝的FFmpeg,默認路徑是當前應用程序的根目錄//如果是手動下載的FFmpeg,需要將ffmpeg.exe放在應用程序的根目錄下var ffmpegPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ffmpeg.exe");if(File.Exists(ffmpegPath)){//如果ffmpeg.exe存在,則設置FFmpeg的可執行文件路徑FFmpeg.SetExecutablesPath(System.IO.Path.GetDirectoryName(ffmpegPath)); //設置FFmpeg的可執行文件路徑}else{throw new Exception("ffmpeg.exe not found in the application directory.");}}/// <summary> /// 獲取視頻第一幀 /// </summary> /// <param name="inputFile">輸入文件路徑</param> /// <param name="outputFile">輸出文件路徑</param> /// <returns>FFmpeg命令行參數</returns> public static async Task<string> GetVideoFrame(string inputFile){//根據傳入的視頻文件地址,獲取該視頻的第一幀圖片,并保存到指定的輸出文件路徑 if (string.IsNullOrEmpty(inputFile)){throw new ArgumentException("Input and output file paths must be provided.");}if (!File.Exists(inputFile)){throw new ArgumentException("file Not Exist");}//輸出文件路徑 string outputFile = System.IO.Path.ChangeExtension(inputFile, ".jpg");// 替換為使用 FFmpeg 的截圖功能 await FFmpeg.Conversions.New().AddParameter($"-i \"{inputFile}\" -frames:v 1 \"{outputFile}\"").Start();return outputFile;}}
}
2.4 使用 FFmpeg 的 drawbox 濾鏡來繪制 ROI
基于drawbox的enable參數來控制在特定幀上繪制,drawbox格式: “drawbox=enable='eq(n,frameIndex)':x:y:w:h:color:thickness”
/// <summary>/// 使用 FFmpeg 的 drawbox 濾鏡來繪制 ROI/// </summary>/// <param name="inputFile"></param>/// <param name="outputFile"></param>/// <param name="locations"></param>/// <returns></returns>/// <exception cref="ArgumentException"></exception>public static async Task<bool> DrawRoiByLocation(string inputFile,ref string analyseVdeofile, List<Location> locations){if (string.IsNullOrEmpty(inputFile)){throw new ArgumentException("Input file paths must be provided.");}if (!File.Exists(inputFile)){throw new ArgumentException("file Not Exist");}//改變輸入文件的名字,增加后綴以區分輸出文件string outputFile = System.IO.Path.ChangeExtension(inputFile, "_analyse.mp4");analyseVdeofile = outputFile;try{// 構建FFmpeg濾鏡命令StringBuilder filterBuilder = new StringBuilder();// 對每個Location(幀)和ROI處理foreach (var location in locations){int frameIndex = location.Index;// 對該幀中的每個ROI進行處理foreach (var roi in location.Rois){// 使用drawbox的enable參數來控制在特定幀上繪制// 格式:drawbox=enable='eq(n,frameIndex)':x:y:w:h:color:thicknessstring boxFilter = $"drawbox=enable='eq(n,{frameIndex})':x={roi.X}:y={roi.Y}:w={roi.W}:h={roi.H}:color=red:thickness=2";if (filterBuilder.Length > 0)filterBuilder.Append(",");filterBuilder.Append(boxFilter);}}// 創建轉換命令,直接使用輸入文件路徑而不是GetMediaInfovar conversion = FFmpeg.Conversions.New().AddParameter($"-i \"{inputFile}\"").SetOutput(outputFile);// 如果有濾鏡,添加到命令中if (filterBuilder.Length > 0){conversion.AddParameter($"-vf \"{filterBuilder}\"").AddParameter("-c:v libx264") // 使用H.264編碼器.AddParameter("-preset medium") // 編碼速度和質量的平衡.AddParameter("-crf 23") // 控制質量,值越低質量越高.AddParameter("-pix_fmt yuv420p") // 設置像素格式,提高兼容性.AddParameter("-c:a aac") // 使用AAC音頻編碼器.AddParameter("-movflags +faststart"); // 優化網絡播放}else{// 即使沒有濾鏡,也確保使用正確的編解碼器conversion.AddParameter("-c:v libx264").AddParameter("-preset medium").AddParameter("-crf 23").AddParameter("-pix_fmt yuv420p").AddParameter("-c:a aac").AddParameter("-movflags +faststart");}// 執行命令并等待完成await conversion.Start();return File.Exists(outputFile);}catch (Exception ex){Console.WriteLine($"Error drawing ROI: {ex.Message}");return false;}}
三、總結
FFmpeg是一個強大的 多媒體處理工具,以上的處理只是它整體功能中的一小部分。結合 Xabe.FFmpeg可以進行視頻的格式轉換、裁剪、增加濾鏡多種功能。同時支持在桌面應用、Web應用、Api服務、云服務多種場景下的處理需求。
????????
? ? ? ? 把之所學以文載之,歡迎大家多多交流~