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:
using Leadtools.Multimedia;
using LMMpgDmxTLib;
using LMDVRSinkLib;
using LMMPEG2EncoderLib;
Declare the following private variables:
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 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 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:
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 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 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 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 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 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:
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.