Perform the following steps to create and run a multimedia capture DVR application using the LEADTOOLS Multimedia CaptureCtrl and PlayCtrl controls and 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 Application " in the Templates List.
Type the project name as "Multimedia DVR" in the Project Name field, and then click OK. If desired, type a new location for your project or select a directory using the Browse button, and then click OK.
In the "Solution Explorer" window, right-click the "References" folder, and select "Add Reference..." from the context menu. In the "Add Reference" dialog box, select the ".NET" tab and select Leadtools.Multimedia and click OK. Also, 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:
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.
Make sure Form1 is in design view. Go to the toolbox (View->Toolbox) and drag a CaptureCtrl control and a PlayCtrl control on the form. After adding it to the form, set the following properties on the controls:
| Property | Value |
|---|---|
| Name | _capturectrl |
| Anchor | Top, Bottom, Left |
| Name | _playctrl |
| Anchor | Top, Bottom, Right |
| AutoStart | false |
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 |
Go to the toolbox (View->Toolbox) and drag two Button controls to the bottom of the form and set the following properties:
| Property | Value |
|---|---|
| Name | _buttonCapture |
| Text | Capture |
| Anchor | Bottom, Right |
| Name | _buttonPlay |
| Text | Play |
| 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:
Imports Leadtools.MultimediaImports LMMpgDmxTLibImports LMDVRSinkLibImports LMMPEG2EncoderLib
using Leadtools.Multimedia;using LMMpgDmxTLib;using LMDVRSinkLib;using LMMPEG2EncoderLib;
Declare the following private variables:
Private Const SLIDER_MAX As Integer = 10000Private _targetFile As StringPrivate _targetFolder As StringPrivate _capturing As BooleanPrivate _mpegDemux As LMMpgDmxTPrivate _dvrSink As ILMDVRSinkPrivate _firstPTS As DoublePrivate _lastPTS As Double
private const int SLIDER_MAX = 10000;private string _targetFile;private string _targetFolder;private bool _capturing;private LMMpgDmxT _mpegDemux;private ILMDVRSink _dvrSink;private double _firstPTS;private double _lastPTS;
Add an event handler to the Form1 Load event and code it as follows:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.LoadIf _capturectrl.VideoDevices.Count = 0 ThenThrow New Exception("No capture devices available")End IfIf _capturectrl.VideoDevices("Analog") Is Nothing ThenThrow New Exception("No Analog TV capture devices available")End If_capturectrl.VideoDevices("Analog").Selected = True_capturectrl.UseVideoDeviceAudio = True_capturing = False_targetFolder = Path.Combine(Directory.GetCurrentDirectory(), "DVRFolder")If (Not Directory.Exists(_targetFolder)) ThenDirectory.CreateDirectory(_targetFolder)End If_targetFile = "capture.lbl"_capturectrl.PreviewTap = CapturePreviewTap.Source_capturectrl.Preview = True_capturectrl.PreviewSource = CapturePreview.VideoEnd Sub
private void Form1_Load(object sender, System.EventArgs e){if (_capturectrl.VideoDevices.Count == 0)throw new Exception("No capture devices available");if (_capturectrl.VideoDevices["Analog"] == null)throw new Exception("No Analog TV capture devices available");_capturectrl.VideoDevices["Analog"].Selected = true;_capturectrl.UseVideoDeviceAudio = true;_capturing = false;_targetFolder = Path.Combine(Directory.GetCurrentDirectory(), "DVRFolder");if (!Directory.Exists(_targetFolder))Directory.CreateDirectory(_targetFolder);_targetFile = "capture.lbl";_capturectrl.PreviewTap = CapturePreviewTap.Source;_capturectrl.Preview = true;_capturectrl.PreviewSource = CapturePreview.Video;}
Add the following helper methods as follows:
Private Function IsStreaming() As BooleanReturn (_capturectrl.VideoCaptureStreamType = Leadtools.Multimedia.Constants.MEDIATYPE_Stream)End FunctionPrivate Function PTSToSliderPosition(ByVal curPTS As Double) As IntegerDim retVal As Integer = 0If curPTS <= _firstPTS ThenretVal = 0ElseIf curPTS >= _lastPTS ThenretVal = SLIDER_MAXElseretVal = CInt(((curPTS - _firstPTS) * SLIDER_MAX) / (_lastPTS - _firstPTS) + 0.5)End IfReturn retValEnd FunctionPrivate Function SliderPositionToPTS(ByVal nPos As Integer) As DoubleReturn _firstPTS + CDbl(nPos) * (_lastPTS - _firstPTS) / CDbl(SLIDER_MAX)End Function
private bool IsStreaming(){return (_capturectrl.VideoCaptureStreamType == Constants.MEDIATYPE_Stream);}private int PTSToSliderPosition(double curPTS){int retVal = 0;if (curPTS <= _firstPTS)retVal = 0;else if (curPTS >= _lastPTS)retVal = SLIDER_MAX;elseretVal = (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 _capturectrl Progress event and code it as follows:
Private Sub _capturectrl_Progress(ByVal sender As Object, ByVal e As ProgressEventArgs) Handles _capturectrl.ProgressIf Not _mpegDemux Is Nothing Then_mpegDemux.RefreshPosition(0)Dim curPTS As Double = _mpegDemux.CurrentStreamPTS_firstPTS = _mpegDemux.FirstStreamPTS_lastPTS = _mpegDemux.LastStreamPTSIf curPTS < _firstPTS AndAlso _playctrl.State = PlayState.Paused Then_playctrl.Run()End IfEnd IfEnd Sub
private void _capturectrl_Progress(object sender, ProgressEventArgs e){if (_mpegDemux != null){_mpegDemux.RefreshPosition(0);double curPTS = _mpegDemux.CurrentStreamPTS;_firstPTS = _mpegDemux.FirstStreamPTS;_lastPTS = _mpegDemux.LastStreamPTS;if (curPTS < _firstPTS && _playctrl.State == PlayState.Paused)_playctrl.Run();}}
Add an event handler to the _playctrl TrackingPositionChanged event and code it as follows:
Private Sub _playctrl_TrackingPositionChanged(ByVal sender As System.Object, ByVal e As TrackingPositionChangedEventArgs) Handles _playctrl.TrackingPositionChangedIf Not _mpegDemux Is Nothing Then_mpegDemux.RefreshPosition(0)Dim curPTS As Double = _mpegDemux.CurrentStreamPTS_firstPTS = _mpegDemux.FirstStreamPTS_lastPTS = _mpegDemux.LastStreamPTS_track.Value = PTSToSliderPosition(curPTS)End IfEnd Sub
private void _playctrl_TrackingPositionChanged(object sender, TrackingPositionChangedEventArgs e){if (_mpegDemux != null){_mpegDemux.RefreshPosition(0);double curPTS = _mpegDemux.CurrentStreamPTS;_firstPTS = _mpegDemux.FirstStreamPTS;_lastPTS = _mpegDemux.LastStreamPTS;_track.Value = PTSToSliderPosition(curPTS);}}
Add an event handler to the _track Scroll event and code it as follows:
Private Sub _track_Scroll(ByVal sender As System.Object, ByVal e As EventArgs) Handles _track.ScrollIf Not _mpegDemux Is Nothing ThenDim ptsPos As Double = SliderPositionToPTS(_track.Value)_mpegDemux.CurrentStreamPTS = ptsPosEnd IfEnd Sub
private void _track_Scroll(object sender, EventArgs e){if (_mpegDemux != null){double ptsPos = SliderPositionToPTS(_track.Value);_mpegDemux.CurrentStreamPTS = ptsPos;}}
Add an event handler to the _capturectrl Complete event and code it as follows:
Private Sub _capturectrl_Complete(ByVal sender As System.Object, ByVal e As EventArgs) Handles _capturectrl.CompleteMessageBox.Show("Capture Complete")_buttonCapture.Enabled = trueEnd Sub
private void _capturectrl_Complete(object sender, EventArgs e){MessageBox.Show("Capture Complete");_buttonCapture.Enabled = true;}
Add an event handler to the _playctrl StateChanged event and code it as follows:
Private Sub _playctrl_StateChanged(ByVal sender As Object, ByVal e As StateChangedEventArgs) Handles _playctrl.StateChangedIf e.state = PlayState.Running Then_mpegDemux = Nothing_mpegDemux = TryCast(_playctrl.GetSubObject(PlayObject.Splitter), LMMpgDmxT)End IfEnd Sub
private void _playctrl_StateChanged(object sender, StateChangedEventArgs e){if (e.state == PlayState.Running){_mpegDemux = null;_mpegDemux = _playctrl.GetSubObject(PlayObject.Splitter) as LMMpgDmxT;}}
Add an event handler to the _buttonCapture Click event and code it as follows:
Private Sub _buttonCapture_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _buttonCapture.ClickTryIf _capturing = True Then_capturectrl.StopCapture()ElseDim recVideoComp As String = String.EmptyDim recAudioComp As String = String.EmptyIf IsStreaming() Then_capturectrl.TargetFormats.DVR.Selected = True_capturectrl.TargetFormat = TargetFormatType.DVR_capturectrl.VideoCompressors.Selection = -1_capturectrl.AudioCompressors.Selection = -1Else_capturectrl.TargetFormats.DVRTransport.Selected = TruerecVideoComp = _capturectrl.TargetFormats.DVRTransport.RecommendedVideoCompressorrecAudioComp = _capturectrl.TargetFormats.DVRTransport.RecommendedAudioCompressor_capturectrl.TargetFormat = TargetFormatType.DVRTransportIf recVideoComp <> String.Empty Then_capturectrl.VideoCompressors(recVideoComp).Selected = TrueEnd IfIf recAudioComp <> String.Empty Then_capturectrl.AudioCompressors(recAudioComp).Selected = TrueEnd IfIf _capturectrl.VideoCompressors.Mpeg2.Selected = True ThenDim mpeg2Encoder As LMMPEG2Encoder = TryCast(_capturectrl.GetSubObject(CaptureObject.VideoCompressor), LMMPEG2Encoder)If Not mpeg2Encoder Is Nothing Thenmpeg2Encoder.EncodingThreads = eMpeg2EncodingThreads.MPEG2_THREAD_AUTOmpeg2Encoder.VideoFormat = eMPEG2VIDEOFORMAT.MPEG2_VF_NTSCMarshal.ReleaseComObject(mpeg2Encoder)End IfEnd IfEnd If_capturectrl.Preview = True_capturectrl.TargetFile = _targetFile_capturectrl.ReadyCapture(CaptureMode.VideoAndAudio Or CaptureMode.InhibitRun)_dvrSink = TryCast(_capturectrl.GetSubObject(CaptureObject.Sink), ILMDVRSink)If Not _dvrSink Is Nothing ThenDim dBuffSize As Double = 102400000 ' 100 MBDim lFileCount As Integer = 8 ' 8 buffer files_dvrSink.StartChangingAttributes()_dvrSink.FolderCount = 1_dvrSink.FolderName(0) = _targetFolder_dvrSink.SetBufferSize(0, lFileCount, dBuffSize)_dvrSink.StopChangingAttributes(False)Dim bufferFolder As String = _dvrSink.BaseNameEnd If_capturectrl.RunCapture()_buttonCapture.Enabled = False_capturing = TrueEnd IfCatch ex As ExceptionMessageBox.Show(ex.Message)End TryEnd Sub
private void _buttonCapture_Click(object sender, System.EventArgs e){try{if (_capturing == true)_capturectrl.StopCapture();else{string recVideoComp = string.Empty;string recAudioComp = string.Empty;if (IsStreaming()){_capturectrl.TargetFormats.DVR.Selected = true;_capturectrl.TargetFormat = TargetFormatType.DVR;_capturectrl.VideoCompressors.Selection = -1;_capturectrl.AudioCompressors.Selection = -1;}else{_capturectrl.TargetFormats.DVRTransport.Selected = true;recVideoComp = _capturectrl.TargetFormats.DVRTransport.RecommendedVideoCompressor;recAudioComp = _capturectrl.TargetFormats.DVRTransport.RecommendedAudioCompressor;_capturectrl.TargetFormat = TargetFormatType.DVRTransport;if (recVideoComp != string.Empty)_capturectrl.VideoCompressors[recVideoComp].Selected = true;if (recAudioComp != string.Empty)_capturectrl.AudioCompressors[recAudioComp].Selected = true;if (_capturectrl.VideoCompressors.Mpeg2.Selected == true){LMMPEG2Encoder mpeg2Encoder = _capturectrl.GetSubObject(CaptureObject.VideoCompressor) as LMMPEG2Encoder;if (mpeg2Encoder != null){mpeg2Encoder.EncodingThreads = eMpeg2EncodingThreads.MPEG2_THREAD_AUTO;mpeg2Encoder.VideoFormat = eMPEG2VIDEOFORMAT.MPEG2_VF_NTSC;Marshal.ReleaseComObject(mpeg2Encoder);}}}_capturectrl.Preview = true;_capturectrl.TargetFile = _targetFile;_capturectrl.ReadyCapture(CaptureMode.VideoAndAudio | CaptureMode.InhibitRun);_dvrSink = _capturectrl.GetSubObject(CaptureObject.Sink) as ILMDVRSink;if (_dvrSink != null){double dBuffSize = 102400000; // 100 MBint lFileCount = 8; // 8 buffer files_dvrSink.StartChangingAttributes();_dvrSink.FolderCount = 1;_dvrSink.set_FolderName(0, _targetFolder);_dvrSink.SetBufferSize(0, lFileCount, dBuffSize);_dvrSink.StopChangingAttributes(false);string bufferFolder = _dvrSink.BaseName;}_capturectrl.RunCapture();_buttonCapture.Enabled = false;_capturing = true;}}catch (Exception ex){MessageBox.Show(this, ex.Message);}}
Add an event handler to the _buttonPlay Click event and code it as follows:
Private Sub _buttonPlay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _buttonPlay.ClickTry_mpegDemux = Nothing_playCtrl.ResetSource()_playCtrl.PreferredMPEG2Splitter = Leadtools.Multimedia.Constants.Filter_MPEG2_Transport_Demux_playctrl.SourceFile = Path.Combine(_targetFolder, _targetFile)_playctrl.RunCatch ex As ExceptionMessageBox.Show(ex.Message)End TryEnd Sub
private void _buttonPlay_Click(object sender, System.EventArgs e){try{_mpegDemux = null;_playCtrl.ResetSource();_playCtrl.PreferredMPEG2Splitter = Constants.Filter_MPEG2_Transport_Demux;_playctrl.SourceFile = Path.Combine(_targetFolder, _targetFile);_playctrl.Run();}catch (Exception ex){MessageBox.Show(this, ex.Message);}}
Build, and Run the program to test it.