如何使用NReco.VideoConverter(或其他库)获取视频中间的缩略图?

时间:2015-06-03 11:08:48

标签: c# video thumbnails

我想用NReco.VideoConverter获取视频中间的缩略图。 这是我的代码:

var ffMpeg = new NReco.VideoConverter.FFMpegConverter();
ffMpeg.GetVideoThumbnail(videoPath, thumbnailPath);

但我只能得到第一帧的缩略图。

有什么想法吗?提前谢谢......

1 个答案:

答案 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;
}