- 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 Application " in the Templates List.
- Type the project name as "Multimedia 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.
- In the "Solution Explorer" window, right-click on 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 on the "References" folder, and select "Add Reference..." from the context menu. In the "Add Reference" dialog box, select the "COM" tab and select LEAD MPEG2 Transport Demultiplexer Library, LEAD DVR Sink Library and LEAD MPEG-2 Encoder Filter Library and click OK.
- Make sure Form1 is in design view. Go to the toolbox (View->Toolbox) and drag and drop 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 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 - Go to the toolbox (View->Toolbox) and drag and drop 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 select View Code) and add the following lines at the beginning of the file:
[Visual Basic]
Imports Leadtools.Multimedia Imports LMMpgDmxTLib Imports LMDVRSinkLib Imports LMMPEG2EncoderLib
[C#]using Leadtools.Multimedia; using LMMpgDmxTLib; using LMDVRSinkLib; using LMMPEG2EncoderLib;
- Declare the following private variables:
[Visual Basic]
Private Const SLIDER_MAX As Integer = 10000 Private _targetFile As String Private _targetFolder As String Private _capturing As Boolean Private _mpegDemux As LMMpgDmxT Private _dvrSink As ILMDVRSink Private _firstPTS As Double Private _lastPTS As Double
[C#]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:
[Visual Basic]
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load If _capturectrl.VideoDevices.Count = 0 Then Throw New Exception("No capture devices available") End If If _capturectrl.VideoDevices("Analog") Is Nothing Then Throw 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)) Then Directory.CreateDirectory(_targetFolder) End If _targetFile = "capture.lbl" _capturectrl.PreviewTap = CapturePreviewTap.Source _capturectrl.Preview = True _capturectrl.PreviewSource = CapturePreview.Video End Sub
[C#]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:
[Visual Basic]
Private Function IsStreaming() As Boolean Return (_capturectrl.VideoCaptureStreamType = Leadtools.Multimedia.Constants.MEDIATYPE_Stream) End Function 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 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; 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 _capturectrl Progress event and code it as follows:
[Visual Basic]
Private Sub _capturectrl_Progress(ByVal sender As Object, ByVal e As ProgressEventArgs) Handles _capturectrl.Progress If Not _mpegDemux Is Nothing Then _mpegDemux.RefreshPosition(0) Dim curPTS As Double = _mpegDemux.CurrentStreamPTS _firstPTS = _mpegDemux.FirstStreamPTS _lastPTS = _mpegDemux.LastStreamPTS If curPTS < _firstPTS AndAlso _playctrl.State = PlayState.Paused Then _playctrl.Run() End If End If End Sub
[C#]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:
[Visual Basic]
Private Sub _playctrl_TrackingPositionChanged(ByVal sender As System.Object, ByVal e As TrackingPositionChangedEventArgs) Handles _playctrl.TrackingPositionChanged If 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 If End Sub
[C#]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:
[Visual Basic]
Private Sub _track_Scroll(ByVal sender As System.Object, ByVal e As EventArgs) Handles _track.Scroll If Not _mpegDemux Is Nothing Then Dim ptsPos As Double = SliderPositionToPTS(_track.Value) _mpegDemux.CurrentStreamPTS = ptsPos End If End Sub
[C#]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:
[Visual Basic]
Private Sub _capturectrl_Complete(ByVal sender As System.Object, ByVal e As EventArgs) Handles _capturectrl.Complete MessageBox.Show("Capture Complete") _buttonCapture.Enabled = true End Sub
[C#]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:
[Visual Basic]
Private Sub _playctrl_StateChanged(ByVal sender As Object, ByVal e As StateChangedEventArgs) Handles _playctrl.StateChanged If e.state = PlayState.Running Then _mpegDemux = Nothing _mpegDemux = TryCast(_playctrl.GetSubObject(PlayObject.Splitter), LMMpgDmxT) End If End Sub
[C#]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:
[Visual Basic]
Private Sub _buttonCapture_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _buttonCapture.Click Try If _capturing = True Then _capturectrl.StopCapture() Else Dim recVideoComp As String = String.Empty Dim recAudioComp As String = String.Empty If IsStreaming() Then _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 Then _capturectrl.VideoCompressors(recVideoComp).Selected = True End If If recAudioComp <> String.Empty Then _capturectrl.AudioCompressors(recAudioComp).Selected = True End If If _capturectrl.VideoCompressors.Mpeg2.Selected = True Then Dim mpeg2Encoder As LMMPEG2Encoder = TryCast(_capturectrl.GetSubObject(CaptureObject.VideoCompressor), LMMPEG2Encoder) If Not mpeg2Encoder Is Nothing Then mpeg2Encoder.EncodingThreads = eMpeg2EncodingThreads.MPEG2_THREAD_AUTO mpeg2Encoder.VideoFormat = eMPEG2VIDEOFORMAT.MPEG2_VF_NTSC Marshal.ReleaseComObject(mpeg2Encoder) End If End If End 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 Then Dim dBuffSize As Double = 102400000 ' 100 MB Dim 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.BaseName End If _capturectrl.RunCapture() _buttonCapture.Enabled = False _capturing = True End If Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub
[C#]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 MB int 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:
[Visual Basic]
Private Sub _buttonPlay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _buttonPlay.Click Try _mpegDemux = Nothing _playCtrl.ResetSource() _playCtrl.PreferredMPEG2Splitter = Leadtools.Multimedia.Constants.Filter_MPEG2_Transport_Demux _playctrl.SourceFile = Path.Combine(_targetFolder, _targetFile) _playctrl.Run Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub
[C#]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.