Take the following steps to create and run a multimedia Player DVR application application using the LEADTOOLS Multimedia ConvertCtrl and PlayCtrl controls and the DVR Add-on module.
- Start Visual Studio .NET.
- Choose File->New->Project... from the menu.
- In the New Project dialog box, choose either "Visual C# Projects" or "Visual Basic 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 choose OK.
- To add a reference to the Leadtools.Multimedia.dll right-click on 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:
- LEAD MPEG-2 Transport Multiplexer Library
- LEAD MPEG2 Transport Demultiplexer Library
- LEAD DVR Sink Library
- Make sure Form1 is in design view. Go to the toolbox (View->Toolbox) and drag and drop 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\DotNet\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 and drop 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 and drop 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 and drop 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 and drop 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 select View Code) and add the following lines at the beginning of the file: [Visual Basic]
Imports Leadtools.Multimedia Imports System.Runtime.InteropServices Imports LMMpg2MxTLib Imports LMMpgDmxTLib Imports LMDVRSinkLib
[C#]using Leadtools.Multimedia; using System.Runtime.InteropServices; using LMMpg2MxTLib; using LMMpgDmxTLib; using LMDVRSinkLib;
- Declare the following private variable:
[Visual Basic]
Private Const SLIDER_MAX As Integer = 10000 Private _streaming As Boolean = False Private _firstPTS As Double Private _lastPTS As Double
[C#]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:
[Visual Basic]
Private Sub _convertCtrl_Started(ByVal sender As Object, ByVal e As EventArgs) Handles _convertCtrl.Started _streaming = True _buttonBrowse.Enabled = False _buttonPlayMPEG2StreamWithDVRBuffer.Enabled = True _buttonSetDVRBufferLocations.Enabled = True _buttonCopyBufferedDVRData.Enabled = True End Sub
[C#]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:
[Visual Basic]
Private Sub _convertCtrl_Complete(ByVal sender As Object, ByVal e As EventArgs) Handles _convertCtrl.Complete If _streaming = True Then _convertCtrl.StartConvert() Else _buttonStartStop.Text = "Start" _buttonBrowse.Enabled = True _buttonPlayMPEG2StreamWithDVRBuffer.Enabled = False _buttonSetDVRBufferLocations.Enabled = False _buttonCopyBufferedDVRData.Enabled = False End If End Sub
[C#]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:
[Visual Basic]
Private Sub _playctrl_TrackingPositionChanged(ByVal sender As Object, ByVal e As TrackingPositionChangedEventArgs) Handles _playctrl.TrackingPositionChanged Dim demux As LMMpgDmxT = TryCast(_playctrl.GetSubObject(PlayObject.Splitter), LMMpgDmxT) If Not demux Is Nothing Then demux.RefreshPosition(0) _firstPTS = demux.FirstStreamPTS _lastPTS = demux.LastStreamPTS _track.Value = PTSToSliderPosition(demux.CurrentStreamPTS) Marshal.ReleaseComObject(demux) End If End Sub
[C#]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:
[Visual Basic]
Private Sub _track_Scroll(ByVal sender As Object, ByVal e As EventArgs) Handles _track.Scroll Dim demux As LMMpgDmxT = TryCast(_playctrl.GetSubObject(PlayObject.Splitter), LMMpgDmxT) If Not demux Is Nothing Then demux.RefreshPosition(0) demux.CurrentStreamPTS = SliderPositionToPTS(_track.Value) Marshal.ReleaseComObject(demux) End If End Sub
[C#]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:
[Visual Basic]
Private Function PTSToSliderPosition(ByVal curPTS As Double) As Integer Dim retVal As Integer = 0 If curPTS <= _firstPTS Then retVal = 0 ElseIf curPTS >= _lastPTS Then retVal = SLIDER_MAX Else retVal = CInt(((curPTS - _firstPTS) * SLIDER_MAX) / (_lastPTS - _firstPTS) + 0.5) End If Return retVal End Function Private Function SliderPositionToPTS(ByVal nPos As Integer) As Double Return _firstPTS + CDbl(nPos) * (_lastPTS - _firstPTS) / CDbl(SLIDER_MAX) End Function
[C#]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:
[Visual Basic]
Private Sub _btnBrowse_Click(ByVal sender As Object, ByVal e As EventArgs) Handles _buttonBrowse.Click Dim ofn As OpenFileDialog = New OpenFileDialog() ofn.FileName = _txtSrcFile.Text ofn.FilterIndex = 0 If _txtSrcFile.Text <> String.Empty Then ofn.InitialDirectory = Path.GetDirectoryName(_txtSrcFile.Text) Else ofn.InitialDirectory = Directory.GetCurrentDirectory() End If 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 Then _txtSrcFile.Text = ofn.FileName End If End Sub
[C#]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:
[Visual Basic]
Private Sub _btnStartStop_Click(ByVal sender As Object, ByVal e As EventArgs) Handles _buttonStartStop.Click Dim srcFile As String = _txtSrcFile.Text If _streaming = False Then If srcFile <> String.Empty AndAlso File.Exists(srcFile) Then _convertCtrl.SourceFile = srcFile _convertCtrl.AllowedStreams = StreamFormatType.AudioVideoCC _convertCtrl.PreferredMPEG2Splitter = Leadtools.Multimedia.Constants.Filter_MPEG2_Transport_Demux _convertCtrl.TargetFormat = TargetFormatType.MPEG2Transport _convertCtrl.Preview = True _convertCtrl.TargetFile = "udp://127.0.0.1:9005" Dim mux As LMMpg2MxT = TryCast(_convertCtrl.GetSubObject(ConvertObject.TargetFilter), LMMpg2MxT) If Not mux Is Nothing Then mux.OutputType = CInt(LMMpg2MxTLib.Mpg2MxT_OutputType.Mpg2MxT_OutputType_Broadcast) mux.ResyncInterval = 10 Marshal.ReleaseComObject(mux) End If Try _convertCtrl.StartConvert() _buttonStartStop.Text = "Stop" _buttonBrowse.Enabled = False Catch e1 As Exception End Try End If Else If _streaming = True Then _convertCtrl.StopConvert() _buttonStartStop.Text = "Start" _buttonBrowse.Enabled = True End If End If End Sub
[C#]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:
[Visual Basic]
Private Sub _buttonStop_Click(ByVal sender As Object, ByVal e As EventArgs) Handles _buttonStop.Click If _playctrl.State = PlayState.Running Then _playctrl.Stop() End If End Sub
[C#]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:
[Visual Basic]
Private Sub _buttonPlayMPEG2StreamWithDVRBuffer_Click(ByVal sender As Object, ByVal e As EventArgs) Handles _buttonPlayMPEG2StreamWithDVRBuffer.Click Try ' Open the UDP Stream, but don't auto start _playctrl.AutoStart = False _playctrl.SourceFile = "udp://127.0.0.1:9005" Dim DVRSink As LMDVRSinkLib.LMDVRSink DVRSink = DirectCast(_playctrl.GetSubObject(PlayObject.SourceFilter), LMDVRSinkLib.LMDVRSink) ' 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.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 ex As Exception MessageBox.Show(Me, ex.Message) End Try End Sub
[C#]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:
[Visual Basic]
Private Sub _buttonPlayDVRBufferFile_Click(ByVal sender As Object, ByVal e As EventArgs) Handles _buttonPlayDVRBufferFile.Click Try ' Set the source file on the player _playctrl.SourceFile = "C:\Temp\DVR\Capture.LBL" ' Run the player _playctrl.Run() Catch ex As Exception MessageBox.Show(Me, ex.Message) End Try End Sub
[C#]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:
[Visual Basic]
Private Sub _buttonSetDVRBufferLocations_Click(ByVal sender As Object, ByVal e As EventArgs) Handles _buttonSetDVRBufferLocations.Click Try ' Open the UDP Stream, but don't auto start _playctrl.AutoStart = false _playctrl.SourceFile = "udp://127.0.0.1:9005" Dim DVRSink As LMDVRSinkLib.LMDVRSink DVRSink = DirectCast(_playctrl.GetSubObject(PlayObject.SourceFilter), LMDVRSinkLib.LMDVRSink) ' 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.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.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 ex As Exception MessageBox.Show(Me, ex.Message) End Try End Sub
[C#]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:
[Visual Basic]
Private Sub _buttonCopyBufferedDVRData_Click(ByVal sender As Object, ByVal e As EventArgs) Handles _buttonCopyBufferedDVRData.Click Try Dim first As Double Dim last As Double Dim total As Double _playctrl.AutoStart = False _playctrl.SourceFile = "udp://127.0.0.1:9005" Dim DVRSink As LMDVRSinkLib.LMDVRSink DVRSink = DirectCast(_playctrl.GetSubObject(PlayObject.SourceFilter), LMDVRSinkLib.LMDVRSink) ' Get available range to copy DVRSink.GetAvailabilityInfo(first, last, total) ' Copy the data to the new file DVRSink.CopyBufferToFile("C:\Temp\DVR\Copied_Capture.mpg", first, last) Catch ex As Exception MessageBox.Show(Me, ex.Message) End Try End Sub
[C#]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.