Take the following steps to create and run a multimedia capture DVR application using the LEADTOOLS Multimedia CaptureCtrl and PlayCtrl controls and 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 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.