C# WPF 获取视频的第一帧的两种方式
方式一:调用ffmpeg
在WPF中调用FFmpeg获取视频封面,你可以使用FFmpeg的命令行接口。以下是一个简单的例子,展示了如何在C#代码中调用FFmpeg来提取视频封面(首帧)并将其显示在WPF应用程序中。
首先,确保你已经安装了FFmpeg。可以从官网下载并添加到系统的环境变量中,这样就可以在命令行中直接调用ffmpeg命令。
接下来,在你的WPF项目中,你可以使用Process类来执行FFmpeg命令。以下是一个简单的WPF窗口,它包含一个Image控件来显示提取出的封面。
/// <summary>
/// 导出封面图
/// </summary>
/// <param name="ffmpegFileName">FFmpeg.exe路径</param>
/// <param name="videoFileName">视频文件路径</param>
/// <returns>封面图</returns>
public static async Task<BitmapImage> GetVideoFace(string videoFileName)
{
var ffmpeg = Directory.GetCurrentDirectory() + "\\ffmpeg.exe";
//startInfo.Arguments = " -i " + srcName + " -y -f image2 -ss " + cutTimeFrame + " -t 0.001 -s " + widthAndHeight + " " + objName;
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(videoFileName);
string baseDirectory = Directory.GetCurrentDirectory();
if (!Directory.Exists(baseDirectory)) Directory.CreateDirectory(baseDirectory);
string thumbFileName = Path.Combine(baseDirectory, fileNameWithoutExtension + ".jpg");
ProcessStartInfo processStartInfo = new ProcessStartInfo(ffmpeg);
processStartInfo.UseShellExecute = false;
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
processStartInfo.CreateNoWindow = true;
processStartInfo.ErrorDialog = false;
processStartInfo.RedirectStandardError = true;
processStartInfo.Arguments = string.Format("-i \"{0}\" -y -f image2 -ss 1 \"{1}\"", new object[]
{
videoFileName,
thumbFileName
});// 第1帧
Process.Start(processStartInfo).WaitForExit(100); ; //Process.Start(processStartInfo).WaitForExit(500);
BitmapImage bitmap = await SetImage(thumbFileName);
return bitmap;
}
方式二:基于OpenCVSharp对视频进行帧提取
要使用OpenCvSharp在WPF中获取视频封面,你需要首先安装OpenCvSharp包,然后使用VideoCapture类来读取视频,并使用Mat类来获取帧。以下是一个简单的示例代码,展示了如何获取视频的第一帧作为封面:
/// <summary>
/// 取视频帧
/// </summary>
/// <param name="path">视频地址</param>
/// <returns></returns>
public static Task<BitmapImage> GetPicFromVideo(string path)
{
return Task.Run(() =>
{
BitmapImage bitmapImage = new BitmapImage();
using (var cap = new VideoCapture())
{
using (Mat image = new Mat())
{
if (cap.Open(path))//输入视频进行捕获
{
bool state = true;
while (state)
{
cap.Read(image);//输出捕获帧
if (!image.Empty())
{
state = false;
using (Bitmap bitmap = image.ToBitmap())
{
//bitmapImage = ConvertBitmapToBitmapImage(bitmap);
using (MemoryStream memoryStream = new MemoryStream())
{
// 将Bitmap保存到MemoryStream中
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
// 从MemoryStream创建BitmapImage
//BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
bitmapImage.Freeze();
bitmap.Dispose();
return bitmapImage;
}
}
}
}
}
}
}
return bitmapImage;
});
}