可以使用重载的 GetVideoThumbnail 方法从视频中的任何位置提取帧:
GetVideoThumbnail(String inputFilePath, String outputFilePath, Nullable<Single> frameTime)
其中 frameTime 是 API 文档中所述的视频位置(以秒为单位):FFMpegConverter.GetVideoThumbnail Method (String, String, Nullable<Single>)
因此,要将 1 秒的帧提取到名为 TestVideo.mp4 的视频中,您可以使用:
FFMpegConverter ffmpeg = new NReco.VideoConverter.FFMpegConverter();
ffmpeg.GetVideoThumbnail(@"C:\TestVideo.mp4", @"C:\ExtractedFrame.jpeg", 1.0f);
从字面上提取中间帧有点复杂,因为您需要先找到总视频长度。这可以通过使用 ffprobe(在 FFmpeg 下载中找到,参见 ffmpeg.org)来完成。在How to extract duration time from ffmpeg output? 和How to spawn a process and capture its STDOUT in .NET? 的帮助下,我们可以设置一个进程来运行 ffprobe 并将持续时间字符串解析为浮点数,如下所示:
public void ExtractMiddleFrame()
{
float duration = GetVideoDuration();
FFMpegConverter ffmpeg = new NReco.VideoConverter.FFMpegConverter();
ffmpeg.GetVideoThumbnail(@"C:\TestVideo.mp4", @"C:\ExtractedFrame.jpeg", duration/2.0f);
}
private float GetVideoDuration()
{
float duration = 0.0f;
Process ffprobe = new Process();
ffprobe.StartInfo.FileName = @"C:\ffmpeg-20150606-git-f073764-win32-static\bin\ffprobe.exe";
ffprobe.StartInfo.Arguments = string.Format("-i {0} -show_entries format=duration -v quiet -of csv=\"p=0\"", @"C:\TestVideo.mp4");
ffprobe.StartInfo.UseShellExecute = false;
ffprobe.StartInfo.RedirectStandardOutput = true;
ffprobe.OutputDataReceived += (sender, args) =>
{
if (args.Data != null)
duration = ParseDurationString(args.Data);
};
ffprobe.Start();
ffprobe.BeginOutputReadLine();
ffprobe.WaitForExit();
return duration;
}
private float ParseDurationString(string durationString)
{
float duration = 0.0f;
if (float.TryParse(durationString, out duration) == false)
throw new Exception("Could not parse duration string.");
return duration;
}