Perform the following steps to create and run a multimedia player DVR application using the LEADTOOLS Multimedia ConvertCtrl and PlayCtrl controls and the DVR components of the LEADTOOLS MPEG-2 Transport Module.
Start Visual Studio.
Choose File->New->Project... from the menu.
In the New Project dialog box, choose either "Visual C# Projects" or "VB Projects" in the Projects Type List, and choose "Windows Forms Application " in the Templates List.
Type the project name as "Multimedia Player DVR" in the Project Name field, and then choose OK. If desired, type a new location for your project or select a directory using the Browse button, and then click OK.
To add a reference to the Leadtools.Multimedia.dll right-click the "References" folder in the Solution Explorer window. Select "Add Reference..." from the context menu. In the "Add Reference" dialog box, select the ".NET" tab and select Leadtools.Multimedia.dll and click OK.
Next, add the reference to the LEADTOOLS COM Objects. Right-click the "References" folder, and select "Add Reference..." from the context menu. In the "Add Reference" dialog box, select the "COM" tab and select the following:
Note: The above COM objects must be registered; in case they were not; using regsvr32. For more information, refer to DirectShow Registry-free Activation. Next click OK to add the references.
Make sure Form1 is in design view. Go to the toolbox (View->Toolbox) and drag a ConvertCtrl control and a PlayCtrl control on the form. NOTE: If you do not have ConvertCtrl or PlayCtrl controls in your toolbox, select Tools->Choose Toolbox Items from the menu. Click Browse and then select Leadtools.Multimedia.dll from "<LEADTOOLS_INSTALLDIR>\Bin\Dotnet4\Win32" and then click Open and then click OK. After adding these controls to the form, set the following properties:
Property | Value |
---|---|
Name | _convertctrl |
Anchor | Top, Left |
BackColor | Black |
Name | _playctrl |
Anchor | Top, Bottom, Left, Right |
AutoStart | False |
Go to the toolbox (View->Toolbox) and drag a Text control on the form (below the convert control) and set the following properties:
Property | Value |
---|---|
Name | _txtSrcFile |
Anchor | Bottom, Left |
Locked | True |
Go to the toolbox (View->Toolbox) and drag a Button control to the right of the text control and set the following properties:
Property | Value |
---|---|
Name | _buttonBrowse |
Text | ... |
Anchor | Bottom, Left |
Go to the toolbox (View->Toolbox) and drag a TrackBar control on the form (below the play control) and set the following properties:
Property | Value |
---|---|
Name | _track |
Anchor | Bottom, Left, Right |
Maximum | 10000 |
Go to the toolbox (View->Toolbox) and drag six Button controls to the bottom of the form (first one below the convert control and the others below the play control) and set the following properties:
Property | Value |
---|---|
Name | _buttonStartStop |
Text | Start |
Anchor | Bottom, Left |
Property | Value |
---|---|
Name | _buttonStop |
Text | Stop |
Anchor | Bottom, Right |
Property | Value |
---|---|
Name | _buttonPlayMPEG2StreamWithDVRBuffer |
Text | Play MPEG2 Stream With DVR Buffer |
Anchor | Bottom, Right |
Property | Value |
---|---|
Name | _buttonPlayDVRBufferFile |
Text | Play DVR Buffer File |
Anchor | Bottom, Right |
Property | Value |
---|---|
Name | _buttonSetDVRBufferLocations |
Text | Set DVR Buffer Locations |
Anchor | Bottom, Right |
Property | Value |
---|---|
Name | _buttonCopyBufferedDVRData |
Text | Copy Buffered DVR Data |
Anchor | Bottom, Right |
Switch Form1 to code view (right-click Form1 in the Solution Explorer then choose View Code) and add the following lines to the beginning of the file:
using Leadtools.Multimedia;
using System.Runtime.InteropServices;
using LMMpg2MxTLib;
using LMMpgDmxTLib;
using LMDVRSinkLib;
Declare the following private variable:
Private const int SLIDER_MAX = 10000;
Private bool _streaming = false;
Private double _firstPTS;
Private double _lastPTS;
Add an event handler to the _convertctrl Started event and add the following code:
void _convertCtrl_Started(object sender, EventArgs e)
{
_streaming = true;
_buttonBrowse.Enabled = false;
_buttonPlayMPEG2StreamWithDVRBuffer.Enabled = True;
_buttonSetDVRBufferLocations.Enabled = True;
_buttonCopyBufferedDVRData.Enabled = True;
}
Add an event handler to the _convertctrl Complete event and add the following code:
void _convertCtrl_Complete(object sender, EventArgs e)
{
if (_streaming == true)
_convertCtrl.StartConvert();
else
{
_buttonStartStop.Text = "Start";
_buttonBrowse.Enabled = true;
_buttonPlayMPEG2StreamWithDVRBuffer.Enabled = False;
_buttonSetDVRBufferLocations.Enabled = False;
_buttonCopyBufferedDVRData.Enabled = False;
}
}
Add an event handler to the _playctrl TrackingPositionChanged event and add the following code:
void _playctrl_TrackingPositionChanged(object sender, TrackingPositionChangedEventArgs e)
{
LMMpgDmxT demux = _playctrl.GetSubObject(PlayObject.Splitter) as LMMpgDmxT;
if (demux != null)
{
demux.RefreshPosition(0);
_firstPTS = demux.FirstStreamPTS;
_lastPTS = demux.LastStreamPTS;
_track.Value = PTSToSliderPosition(demux.CurrentStreamPTS);
Marshal.ReleaseComObject(demux);
}
}
Add an event handler to the _track Scroll event and add the following code:
private void _track_Scroll(object sender, EventArgs e)
{
LMMpgDmxT demux = _playctrl.GetSubObject(PlayObject.Splitter) as LMMpgDmxT;
if (demux != null)
{
demux.RefreshPosition(0);
demux.CurrentStreamPTS = SliderPositionToPTS(_track.Value);
Marshal.ReleaseComObject(demux);
}
}
Add the following helper methods for use by the _track control's scroll and _playctrl track positioning handlers:
private int PTSToSliderPosition(double curPTS)
{
int retVal = 0;
if (curPTS <= _firstPTS)
retVal = 0;
else if (curPTS >= _lastPTS)
retVal = SLIDER_MAX;
else
retVal = (int)(((curPTS - _firstPTS) * SLIDER_MAX) / (_lastPTS - _firstPTS) + 0.5);
return retVal;
}
private double SliderPositionToPTS(int nPos)
{
return _firstPTS + (double)nPos * (_lastPTS - _firstPTS) / (double)SLIDER_MAX;
}
Add an event handler to the _buttonBrowse Click event and add the following code:
private void _btnBrowse_Click(object sender, EventArgs e)
{
OpenFileDialog ofn = new OpenFileDialog();
ofn.FileName = _txtSrcFile.Text;
ofn.FilterIndex = 0;
if (_txtSrcFile.Text != string.Empty)
ofn.InitialDirectory = Path.GetDirectoryName(_txtSrcFile.Text);
else
ofn.InitialDirectory = Directory.GetCurrentDirectory();
ofn.Multiselect = false;
ofn.Title = "Select Source Video";
ofn.CheckFileExists = true;
ofn.Filter = "MPEG2 Video Files (*.mpg)|*.mpg | All files (*.*)|*.*";
if (ofn.ShowDialog() == DialogResult.OK)
{
_txtSrcFile.Text = ofn.FileName;
}
}
Add an event handler to the _buttonStartStop Click event and add the following code:
private void _btnStartStop_Click(object sender, EventArgs e)
{
string srcFile = _txtSrcFile.Text;
if (_streaming == false)
{
if (srcFile != string.Empty && File.Exists(srcFile))
{
_convertCtrl.SourceFile = srcFile;
_convertCtrl.AllowedStreams = StreamFormatType.AudioVideoCC;
_convertCtrl.PreferredMPEG2Splitter = Constants.Filter_MPEG2_Transport_Demux;
_convertCtrl.TargetFormat = TargetFormatType.MPEG2Transport;
_convertCtrl.Preview = true;
_convertCtrl.TargetFile = @"udp://127.0.0.1:9005";
LMMpg2MxT mux = _convertCtrl.GetSubObject(ConvertObject.TargetFilter) as LMMpg2MxT;
if (mux != null)
{
mux.OutputType = (int)LMMpg2MxTLib.Mpg2MxT_OutputType.Mpg2MxT_OutputType_Broadcast;
mux.ResyncInterval = 10;
Marshal.ReleaseComObject(mux);
}
try
{
_convertCtrl.StartConvert();
_buttonStartStop.Text = "Stop";
_buttonBrowse.Enabled = false;
}
catch (Exception) { }
}
}
else
{
if (_streaming == true)
{
_convertCtrl.StopConvert();
_buttonStartStop.Text = "Start";
_buttonBrowse.Enabled = true;
}
}
}
Add an event handler to the _buttonStop Click event and code it as follows:
private void _buttonStop_Click(object sender, EventArgs e)
{
if (_playctrl.State == PlayState.Running)
{
_playctrl.Stop();
}
}
Add an event handler to the _buttonPlayMPEG2StreamWithDVRBuffer Click event to play a UDP MPEG2 Stream with DVR Buffering and add the following code:
private void _buttonPlayMPEG2StreamWithDVRBuffer_Click(object sender, EventArgs e)
{
try
{
// Open the UDP Stream, but don't auto start
_playctrl.AutoStart = false;
_playctrl.SourceFile = "udp://127.0.0.1:9005";
LMDVRSinkLib.LMDVRSink DVRSink;
DVRSink = (LMDVRSinkLib.LMDVRSink)(_playctrl.GetSubObject(PlayObject.SourceFilter));
// Tell the DVR Sink that settings are about to change
DVRSink.StartChangingAttributes();
// Set only one DVR buffer folder
DVRSink.FolderCount = 1;
// Set the buffer base file name to 'Capture.LBL'
DVRSink.BaseName = "Capture.LBL";
// Set the buffer folder location to 'C:\Temp\DVR'
DVRSink.set_FolderName(0, "C:\\Temp\\DVR");
// Set the buffer folder to have 5 buffer data files, each at 100MB max size
DVRSink.SetBufferSize(0, 5, 102400000);
// Commit the changed settings now
DVRSink.StopChangingAttributes(false);
// Run the stream
_playctrl.Run();
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message);
}
}
Add an event handler to the _buttonPlayDVRBufferFile Click event to play a DVR buffer file and add the following code:
private void _buttonPlayDVRBufferFile_Click(object sender, EventArgs e)
{
try
{
// Set the source file on the player
_playctrl.SourceFile = "C:\\Temp\\DVR\\Capture.LBL";
// Run the stream
_playctrl.Run();
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message);
}
}
Add an event handler to the _buttonSetDVRBufferLocations Click event to Set DVR Buffer Locations on More Than One Physical Disk and code it as follows:
private void _buttonSetDVRBufferLocations_Click(object sender, EventArgs e)
{
try
{
// Open the UDP Stream, but don't auto start
_playctrl.AutoStart = false;
_playctrl.SourceFile = "udp://127.0.0.1:9005";
LMDVRSinkLib.LMDVRSink DVRSink;
DVRSink = (LMDVRSinkLib.LMDVRSink)(_playctrl.GetSubObject(PlayObject.SourceFilter));
// Tell sink we are starting to change settings
DVRSink.StartChangingAttributes();
// Set Two buffer locations
DVRSink.FolderCount = 2;
// Set base file name
DVRSink.BaseName = "Capture.LBL";
// Set buffer folder 1 location
DVRSink.set_FolderName(0, "C:\\Temp\\DVR");
// Set buffer folder 1 to have 2 buffer data files, each at 16MB max file size
DVRSink.SetBufferSize(0, 2, 16 * 1024000);
// Set buffer folder 2 location
DVRSink.set_FolderName(1, "D:\\Temp\\DVR");
// Set buffer folder 2 to have 4 buffer data files, each at 8MB max file size
DVRSink.SetBufferSize(1, 4, 8192000);
// Tell sink to apply the changes
DVRSink.StopChangingAttributes(false);
// Run the player
_playctrl.Run();
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message);
}
}
Add an event handler to the _buttonCopyBufferedDVRData Click event to play a DVR buffer file and add the following code:
private void _buttonCopyBufferedDVRData_Click(object sender, EventArgs e)
{
try
{
double first;
double last;
double total;
// Open the UDP Stream, but don't auto start
_playctrl.AutoStart = false;
_playctrl.SourceFile = "udp://127.0.0.1:9005";
LMDVRSinkLib.LMDVRSink DVRSink;
DVRSink = (LMDVRSinkLib.LMDVRSink)(_playctrl.GetSubObject(PlayObject.SourceFilter));
// Get available range to copy
DVRSink.GetAvailabilityInfo(out first, out last, out total);
// Copy the data to the new file
DVRSink.CopyBufferToFile("C:\\Temp\\DVR\\Copied_Capture.mpg", first, last);
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message);
}
}
Build, and Run the program to test it. Click the [...] browse button to locate a video file for the convert / streaming output. Then click the Start button to begin streaming. Click the Play MPEG2 Stream With DVR Buffer button to test playing a UDP MPEG2 Stream with DVR Buffering. Click the Play DVR Buffer button to test playing a DVR buffer file. Click the Set DVR Buffer Locations button to test Setting DVR Buffer Locations on More Than One Physical Disk and play a UDP MPEG2 Stream with DVR Buffering. Click the Copy Buffered DVR Data button to test copy buffered DVR data to a new file. Finally, drag the track bar control to reposition the stream playback.