FFmpeg的Static版本的bin文件夹中只有三个.exe文件,分别是:ffmpeg.exe,ffplay.exe和ffprobe.exe,各功能如下:
ffmpeg.exe:音视频转码、转换器
ffplay.exe:简单的音视频播放器
ffprobe.exe :多媒体码流分析器
以下实现了基于ffmpeg.exe和ffprobe.exe的视频总帧数获取和取某一帧的图像方法,可根据需求进行扩展。
cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace VideoCheck
{
public class CFFmpeg
{
string ffmpegPath = "";
string ffprobePath = "";
public CFFmpeg()
{
if (System.IntPtr.Size == 4)
{
ffmpegPath = Environment.CurrentDirectory + "\\ffmpeg\\x86\\ffmpeg.exe";
ffprobePath = Environment.CurrentDirectory + "\\ffmpeg\\x86\\ffprobe.exe";
}
else if (System.IntPtr.Size == 8)
{
ffmpegPath = Environment.CurrentDirectory + "\\ffmpeg\\x64\\ffmpeg.exe";
ffprobePath = Environment.CurrentDirectory + "\\ffmpeg\\x64\\ffprobe.exe";
}
}
const int SW_HIDE = 0;
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
/// <summary>
/// 获取视频有效总帧数
/// </summary>
/// <param name="videoPath"></param>
/// <returns></returns>
public int GetTotalFrameCnt(string videoPath)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = new System.Diagnostics.ProcessStartInfo(ffprobePath);
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
//示例:ffprobe - v error - count_frames - select_streams v: 0 - show_entries stream = nb_read_frames - of default = nokey = 1:noprint_wrappers = 1 C: \Users\whf\Desktop\大和路Y430 - Y428.ASF
string args = " -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 " + "\"" + videoPath + "\"";
process.StartInfo.Arguments = args.Replace("\\", "/");
try
{
process.Start();
while (process.MainWindowHandle == IntPtr.Zero)
{
process.Refresh();
}
ShowWindow(process.MainWindowHandle, SW_HIDE);
StringBuilder sb = new StringBuilder();
while (!process.HasExited)
{
sb.Append(process.StandardOutput.ReadToEnd());
}
string str = sb.ToString().Trim();
int num = 0;
bool ret = int.TryParse(str,out num);
return num;
}
catch (Exception ex)
{
return 0;
}
}
/// <summary>
/// 截取视频图片
/// </summary>
/// <param name="videoPath">视频路径</param>
/// <param name="videoFrameIndex">视频帧号</param>
/// <param name="outImagePath">图像输出路径</param>
/// <returns></returns>
public bool CatchImage(string videoPath,int videoFrameIndex, string outImagePath)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath);
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
if (File.Exists(outImagePath))
File.Delete(outImagePath);
else
{
FileInfo fileInfo = new FileInfo(videoPath);
if (!Directory.Exists(fileInfo.DirectoryName))
Directory.CreateDirectory(fileInfo.DirectoryName);
}
int sec = (int)(videoFrameIndex / 25.0f);
//-ss后跟的时间单位为秒 ,放前面可加快速度
string args = " -y -ss " + sec+ " -i " + "\""+ videoPath +"\""+ " -frames 1 -f image2 " + "\"" + outImagePath+"\"";
process.StartInfo.Arguments = args.Replace("\\","/");
try
{
process.Start();
process.WaitForExit();
}
catch(Exception ex)
{
return false;
};
if (System.IO.File.Exists(outImagePath))
{
return true;
}
return false;
}
}
}