How to set a frame rate of 25 per second with timer ?

eshesh michael 60 Reputation points
2023-04-13T20:47:57.4266667+00:00

I'm trying to use a timer to add frames to the pictureBox1. the mp4 video file in the code is set to frame rate of 25. I don't know what is the original real framerate of the video file and how to get it in the code. I have two questions:

  1. the way I'm using the timer now is it realy 25 frames per second ?
  2. how to find the real frame rate of the video file in the code and how to set it and using when extracting the frames so it will display the frames in the pictureBox1 in real time once the frames extracted add them to the pictureBox so it will looks like a video. I want to control the frame rate.

using Accord.IO;
using Accord.Video;
using Accord.Video.FFMPEG;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Extract_Frames
{
    public partial class Form1 : Form
    {
        Bitmap frame = null;
        Graphics frameGraphics = null;
        bool isVideoRunning = false;
        IProgress<Bitmap> videoProgress = null;
        private CancellationTokenSource cts = null;
        private readonly object syncRoot = new object();
        private static long pause = 0;

        public Form1() => InitializeComponent();

        int counter = 0;
        private async void buttonStart_Click(object sender, EventArgs e)
        {
            int t = 25;
            t += 1 / 60 * 1000;
            timer1.Interval = t;
            timer1.Enabled = true;

            string fileName = textBox1.Text;

            if (isVideoRunning) return;
            isVideoRunning = true;

            using (var videoReader = new VideoFileReader())
            {
                videoReader.Open(fileName);
                frame = new Bitmap(videoReader.Width + 2, videoReader.Height + 2);
                trackBar1.Maximum = (int)videoReader.FrameCount;
            }
            
            videoProgress = new Progress<Bitmap>(Updater);
            cts = new CancellationTokenSource();
            try
            {
                frameGraphics = Graphics.FromImage(frame);
                // Set the frame rate to 25 frames per second
                int frameRate = 1000 / 25;
                await GetVideoFramesAsync(videoProgress, fileName, frameRate, cts.Token);
            }
            finally
            {
                StopPlayback(false);
                frameGraphics?.Dispose();
                pictureBox1.Image?.Dispose();
                pictureBox1.Image = null;
                buttonPause.Text = "Pause";
                pause = 0;
                isVideoRunning = false;
            }
        }

        private void buttonStop_Click(object sender, EventArgs e) => StopPlayback(true);

        private void buttonPause_Click(object sender, EventArgs e)
        {
            if (pause == 0)
            {
                buttonPause.Text = "Resume";
                Interlocked.Increment(ref pause);
            }
            else
            {
                Interlocked.Decrement(ref pause);
                buttonPause.Text = "Pause";
            }
        }

        private void StopPlayback(bool cancel)
        {
            lock (syncRoot)
            {
                if (cancel) cts?.Cancel();
                cts?.Dispose();
                cts = null;
            }
        }

        private void Updater(Bitmap videoFrame)
        {
            using (videoFrame) frameGraphics.DrawImage(videoFrame, Point.Empty);
            counter++;
            label1.Text = counter.ToString();
            trackBar1.Value = counter;
            pictureBox1.Invalidate();
        }

        private async Task GetVideoFramesAsync(IProgress<Bitmap> updater, string fileName, int intervalMs, CancellationToken token = default)
        {
            using (var videoReader = new VideoFileReader())
            {
                if (token.IsCancellationRequested) return;
                videoReader.Open(fileName);

                while (!token.IsCancellationRequested)
                {
                    // Resumes on a ThreadPool Thread
                    await Task.Delay(intervalMs, token).ConfigureAwait(false);

                    if (Interlocked.Read(ref pause) == 0)
                    {
                        var frame = videoReader.ReadVideoFrame();
                        if (frame is null) break;
                        updater.Report(frame);
                    }
                }
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            if (isVideoRunning) StopPlayback(true);
            base.OnFormClosing(e);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.InitialDirectory = "c:\\";
                openFileDialog.Filter = "video files (*.mp4)|*.mp4|All files (*.*)|*.*";
                openFileDialog.FilterIndex = 2;
                openFileDialog.RestoreDirectory = true;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    textBox1.Text = openFileDialog.FileName;
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            pictureBox1.Image = frame;
        }
    }
}

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,873 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,648 questions
{count} votes