我想用NReco.VideoConverter获取视频中间的缩略图。 这是我的代码:
var ffMpeg = new NReco.VideoConverter.FFMpegConverter();
ffMpeg.GetVideoThumbnail(videoPath, thumbnailPath);
但我只能得到第一帧的缩略图。
有什么想法吗?提前谢谢......
答案 0 :(得分:2)
可以使用重载的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的过程,并将持续时间字符串解析为float,如下所示:
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;
}