You are currently browsing the category archive for the 'SMPTE' category.

It’s been a  very busy week. I have not had a chance to post anything, so I thought I would at least put something simple out there…

Check out this nice little site by Chris Pirazzi that my MediaRoom friend Joel Schonbrunn pointed me to.  Thanks Joel! Very handy.

http://lurkertech.com/lg/video-systems/

I have done a lot of work with Windows Media files in the past where it was a requirement to capture, embed, transmit, and display the actual timecode that was generated on a broadcast tape for the purpose of logging a file remotely. 

This use case is common in the broadcast world where it is very cost effective to have a browser-based proxy viewer instead of $20k DigiBeta deck to do simple shot logging and commenting.

In the Windows Media 9 days we (MSFT) provided tools in the Windows Media 9 encoder, and in the Windows Format SDK, to allow for this type of workflow. The Data Unit Extension (DUE) in the Format SDK was provided for this purpose and allowed the developer or encoder to inject the SMPTE timecode into the per-frame DUE by populating the WMT TIMECODE EXTENSION DATA structure with the appropriate range, timecode and custom flags that you wanted.  This was very useful and was implemented by a number of encoder manufacturers.  The nice part about this was that it also provided support for time code breaks on a tape, which is a common scenario with older tape based cameras (new cameras just create a seperate MXF digital file each time I stop and start the camera, so it is not a big issue any more).

So, in our past we developed all of this wonderful code to embed SMPTE timecode into our files and a way to read it out in Windows applications that used the Format SDK and even support in the Windows Media Player OCX browser control to read and navigate this timecode.   Then along comes Silverlight(tm) 1 and 2.

In Silverlight we now have the MediaElement.  It does not do all of the cool stuff that the old WMP.ocx allowed with SMPTE timecode, but I have provided a workaround to that in our IMM solution. That workaround has now graduated to the Expression Encoder 2.0 SP1 and is available (in source!) as part of the Silverlight 2 Media Player template.

You can easily convert the TimeSpan object that is reported back from Silverlight’s MediaElement to SMPTE 12M timecode using this Timecode class that I created. You can also use it to seek a specific SMPTE timecode, build a Silverlight Rough Cut Editor, or build a timecode calculator application. 

If you have Expression Encoder 2.0 SP1 installed go to this location to find the Timecode class.

C:\Program Files (x86)\Microsoft Expression\Encoder 2\Templates\en\SL2Standard\Source\MediaPlayer\TimeCode.cs

This is a struct that works just like the TimeSpan in .NET.  You pass it the TotalSeconds from the CurrentPosition timespan of the MediaElement and the SMPTE 12M framerate that you want calculated (say for example SMPTE 29.97 Drop Frame), and the Struct will give you back a valid SMPTE timecode string. 

You can also use it in reverse. Pass it a time and framerate that you want to go to, and get back the Absolute time in seconds, then set the current position to that.

As an example of using the Timecode.cs file, I have created a very simple Silverlight 2.0 player application in Blend 2.0 SP1.

It has a single MediaElement, a Slider control, a Play and Pause Button, and a timecode display.

image

 

For this example I am using a file that I created in Sony Vegas that is just a window burn of SMPTE timecode running at 29.97 Drop Frame.  Drop frame is the hardest algorithm to do, so let’s stick with that one for now.

I uploaded the file to Silverlight Streaming so that you can use it also in your testing.

http://silverlight.services.live.com/1535/SMPTE_NTSC_Drop/video.wmv

In my XAML page’s code behind, I added a DispatcherTimer to fire an event to update the Timecode display every 500ms.

public partial class Page : UserControl
{
    private readonly DispatcherTimer timer;
    private bool isSliderDragging = false;

    public Page()
    {
        InitializeComponent();
        this.Player.AutoPlay = true;
        this.timer = new DispatcherTimer { Interval = new TimeSpan(500) };
        this.timer.Tick += new EventHandler(this.Timer_Tick);
        this.timer.Start();
    }

 

 

When my Timer ticks I update the Timecode display by grabbing the value of the TimeSpan in the Player.CurrentPosition and then pass it to the Timecode struct with the proper SMPTE 12M framerate that I want calculated.  The struct then returns back a formatted SMPTE 12M timecode string.

private void UpdateTimecode()
{
    var tc = SmpteTimecode.TimeCode.FromTimeSpan(Player.Position,
               SmpteFrameRate.Smpte2997Drop);
    TimeCode.Text = tc.ToString();
}

One thing to note is that I actually added a new function to the Timecode.cs file in this case to directly pass a TimeSpan in. This was not in the original code that shipped in SP1.  It just passes the value of TotalSeconds to the constructor of TimeCode that takes a double in seconds.

public static TimeCode FromTimeSpan(TimeSpan value, SmpteFrameRate rate)
{
    return new TimeCode(value.TotalSeconds, rate);
}

The result looks like this. You can drag the slider around in this file and see that  the reported SMPTE 12M NTSC drop frame timecode in green perfectly matches the window burn inside of the video file (the number at the top is framecount). 

image

Unfortunately my hosted WordPress is not allowing me to embed Silverlight Streaming applications right now, so you can play with it live here.
(Note: if you are on a slow connection you should wait for the whole file to download or the seeking won’t be accurate).

Now, the obvious limitation is that we can’t easily deal with timecode breaks. One workaround for this that I have used is to embed the timecode breaks into the VC-1 file as Markers.  In the marker you can specify that this is a break, and then in a custom Silverlight player when you hit that break you will easily be able to update the timecode that is being displayed by using the Timecode struct class as a Timecode “calculator”. Store the offset time in a Timecode and just add it to the current position and you will have a properly offset timecode to display!

Enjoy. It took me a long time to put all of those math operator precedence parentheses into this file so please send me email if you end up using this in your own projects. I would love to hear.

Also, you may have already considered this, but this class alone is a great base for a Silverlight based Rough Cut Editor solution. Just build a timeline control and playback engine based on the Timecode class.

Twitter Updates

Pages

 

July 2010
M T W T F S S
« Jun    
 1234
567891011
12131415161718
19202122232425
262728293031