0

I want to get the thumbnail of the middle of my video with NReco.VideoConverter. This is my code:

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

But I can only get the thumbnail of the first frame.

Any idea? Thanks in advance...

1 Answers1

2

Frames can be extracted from anywhere within the video by using the overloaded GetVideoThumbnail method:

GetVideoThumbnail(String inputFilePath, String outputFilePath, Nullable<Single> frameTime)

where frameTime is the video position (in seconds) as described in the API documentation: FFMpegConverter.GetVideoThumbnail Method (String, String, Nullable<Single>)

So to extract the frame 1 second into a video called TestVideo.mp4, you would use:

FFMpegConverter ffmpeg = new NReco.VideoConverter.FFMpegConverter();
ffmpeg.GetVideoThumbnail(@"C:\TestVideo.mp4", @"C:\ExtractedFrame.jpeg", 1.0f);

To literally extract the middle frame is a bit more involved as you need to find the total video length first. This can be done by using ffprobe (found in the FFmpeg download, see ffmpeg.org). With the help of How to extract duration time from ffmpeg output? and How to spawn a process and capture its STDOUT in .NET? we can setup a process to run ffprobe and parse the duration string to a float as follows:

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;
}
Community
  • 1
  • 1
ChrisM
  • 235
  • 5
  • 13