Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Silverlight media player with frame counter

Tags:

silverlight

I am trying to write a simple Silverlight media player, but I need the timestamp to be hh:mm:ss:ff where FF is Frame count.

I used a timer in order to get ticks and calculate the frame I am in, but it seems very inaccurate. How can I count reliably the frame I am in?

Does anyone know of a free Silverlight player that will do that?

like image 551
Himberjack Avatar asked Jul 22 '11 07:07

Himberjack


1 Answers

Silverlight is designed to update at irregular intervals and catch-up any animation or media playing to the current elapsed time when the next frame is rendered.

To calculate the current frame (a frame is just a specific fraction of a second) it is simply a matter of multiplying total elapsed time, since the playback started, by the number of frames-per-second encoded in the video then finding the remainder of frames within that second to get the current frame.

e.g. Current frame = (Elapsed-Time-in-seconds * FramesPerSecond) % FramesPerSecond;

So if 20.12 seconds has elapsed, on a video that has 24 frames per second, you are on Frame 482 (actually 482.88 but only whole frames matter).

Take the Modulus of that by the Frames-per-second and you get the remaining number of frames (e.g. 2) so you are on frame number 2 in second number 20 (or 00:00:20:02).

You need to do the multiply using doubles (or floats) and the final modulus on an integer value so it will be like this in C# code:

int framesPerSecond = 24; // for example
double elapsedTimeInSeconds = ...; /// Get the elapsed time...
int currentFrame = ((int)(elapsedTimeInSeconds * (double)framesPerSecond)) % framesPerSecond;

As the question has changed (in comment) to a fractional frame rate the maths will be as per this console app:

using System;

namespace TimeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            double framesPerSecond = 29.97;

            for (double elapsedTime = 0; elapsedTime < 5; elapsedTime+=0.01)
            {
                int currentFrame = (int)((elapsedTime*framesPerSecond) % framesPerSecond);
                Console.WriteLine("Time: {0} = Frame: {1}", elapsedTime, currentFrame);
            }
        }
    }
}

Note: You are not guaranteed to display every frame number, as the framerate is not perfect, but you can only see the rendered frames so it does not matter. The frames you see will have the correct frame numbers.

like image 197
Gone Coding Avatar answered Oct 09 '22 09:10

Gone Coding