Perform the following steps to create and run a multimedia convert application to concatenate two video files using two LEADTOOLS Multimedia ConvertCtrl controls.
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 Concatenate Videos" 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 two ConvertCtrl controls on the form. NOTE: If you do not have ConvertCtrl control in your toolbox, select Tools->Choose Toolbox Items from the menu. Click Browse and then select Leadtools.Multimedia.dll from "<LEADTOOLS_INSTALLDIR>\Bin\Dotnet4\Win32" and then click Open and then click OK. After adding these controls to the form, set the following properties:
Property | Value |
---|---|
Name | _convertctrl1 |
Name | _convertctrl2 |
Go to the toolbox (View->Toolbox) and drag a ProgressBar control on the form (below the convert control) and set the following properties:
Property | Value |
---|---|
Name | _progress |
Anchor | Bottom, Left, Right |
Step | 1 |
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 | _buttonProcessor |
Text | Processor... |
Anchor | Bottom, Right |
Name | _buttonConvert |
Text | Convert |
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.Multimedia
using Leadtools.Multimedia;
Declare the following private variable:
Private _sourceFile1 As String
Private _sourceFile2 As String
Private _targetFile As String
private string _sourceFile1;
private string _sourceFile2;
private string _targetFile;
Add an event handler to the _convertctrl2 Progress event and code it as follows:
Private Sub _convertctrl2_Progress(ByVal sender As System.Object, ByVal e As ProgressEventArgs) Handles _convertctrl2.Progress
_progress.Value = CInt((_progress.Maximum * e.percent / 100))
End Sub
private void _convertctrl2_Progress(object sender, ProgressEventArgs e)
{
_progress.Value = (int)(_progress.Maximum * e.percent / 100);
}
Add an event handler to the _convertctrl2 Complete event and code it as follows:
Private Sub _convertctrl2_Complete(ByVal sender As System.Object, ByVal e As EventArgs) Handles _convertctrl2.Complete
MessageBox.Show("Concatenation Complete")
_buttonConvert.Enabled = True
End Sub
private void _convertctrl2_Complete(object sender, EventArgs e)
{
MessageBox.Show("Concatenation Complete");
_buttonConvert.Enabled = true;
}
Add an event handler to the _buttonConvert Click event and code it as follows:
Private Sub _buttonConvert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _buttonConvert.Click
Dim pConvert1 As ConvertCtrl = _convertctrl1
Dim pConvert2 As ConvertCtrl = _convertctrl2
Dim pMSSource As MultiStreamSource
Dim pMSTarget As MultiStreamTarget
Dim lStart As Int64
Dim pmt As MediaType
Dim pInsertedMediaType As MediaType
pMSSource = New MultiStreamSource()
pMSTarget = New MultiStreamTarget()
' set the start time to be 0
lStart = 0
' set the input filename
pConvert1.SourceFile = _sourceFile1
' set the output sample to a target object
pMSTarget.StreamCount = 2
' set the target media types for video and audio streams
pmt = New MediaType()
pmt.Type = Leadtools.Multimedia.Constants.MEDIATYPE_Video
pMSTarget.SetAcceptedMediaType(0, pmt)
pmt.Type = Leadtools.Multimedia.Constants.MEDIATYPE_Audio
pMSTarget.SetAcceptedMediaType(1, pmt)
pmt = Nothing
' get the inserted media type for the first stream
pInsertedMediaType = pMSTarget.GetAcceptedMediaType(0)
pInsertedMediaType = Nothing
' set convert 1 target object
pConvert1.TargetObject = pMSTarget
' start the source conversion, so we can get the media sample format
pConvert1.StartConvert()
' initialize convert 2
' get the output media sample format and put it into the source object
pMSSource.StreamCount = 2
pmt = pMSTarget.GetConnectedMediaType(0)
pMSSource.SetMediaType(0, pmt)
pmt = Nothing
pmt = pMSTarget.GetConnectedMediaType(1)
pMSSource.SetMediaType(1, pmt)
pmt = Nothing
' get the inserted media type for the first stream
pInsertedMediaType = pMSSource.GetMediaType(0)
pInsertedMediaType = Nothing
' set the output filename
pConvert2.TargetFile = _targetFile
' set the source for convert 2
pConvert2.SourceObject = pMSSource
' start the dest conversion
pConvert2.StartConvert()
' convert first file
ConcateFile(pConvert1, pMSTarget, pMSSource, lStart)
'
'Restrict the output format to the media type of the source for the first file
'That is because the two files must have the same media type for both video and audio
'With video, you have to make sure the files have the same frame rate! Minor changes in
'the frame rate might make the connection fail!
'The control will tolerate differences in frame rate if you comment the next line
'
pmt = pMSTarget.GetConnectedMediaType(0)
pMSTarget.SetAcceptedMediaType(0, pmt)
pmt = Nothing
pmt = pMSTarget.GetConnectedMediaType(1)
pMSTarget.SetAcceptedMediaType(1, pmt)
pmt = Nothing
' change the source file to second file
pConvert1.SourceFile = _sourceFile2
' start converting again
pConvert1.StartConvert()
' convert second file
ConcateFile(pConvert1, pMSTarget, pMSSource, lStart)
' deliver end of sample to stop the conversion
pMSSource.DeliverEndOfStream(0, 1000)
pMSSource.DeliverEndOfStream(1, 1000)
If pConvert2.State = ConvertState.Running Then
pConvert2.StopConvert()
End If
' free the source and target objects
pConvert2.ResetSource()
pConvert1.ResetTarget()
pMSSource.Dispose()
pMSTarget.Dispose()
End Sub
private void _buttonConvert_Click(object sender, System.EventArgs e)
{
ConvertCtrl pConvert1 = _convertctrl1;
ConvertCtrl pConvert2 = _convertctrl2;
MultiStreamSource pMSSource;
MultiStreamTarget pMSTarget;
Int64 lStart;
MediaType pmt;
MediaType pInsertedMediaType;
pMSSource = new MultiStreamSource();
pMSTarget = new MultiStreamTarget();
// set the start time to be 0
lStart = 0;
// set the input filename
pConvert1.SourceFile = _sourceFile1;
// set the output sample to a target object
pMSTarget.StreamCount = 2;
// set the target media types for video and audio streams
pmt = new MediaType();
pmt.Type = Constants.MEDIATYPE_Video;
pMSTarget.SetAcceptedMediaType(0, pmt);
pmt.Type = Constants.MEDIATYPE_Audio;
pMSTarget.SetAcceptedMediaType(1, pmt);
pmt = null;
// get the inserted media type for the first stream
pInsertedMediaType = pMSTarget.GetAcceptedMediaType(0);
pInsertedMediaType = null;
// set convert 1 target object
pConvert1.TargetObject = pMSTarget;
// start the source conversion, so we can get the media sample format
pConvert1.StartConvert();
// initialize convert 2
// get the output media sample format and put it into the source object
pMSSource.StreamCount = 2;
pmt = pMSTarget.GetConnectedMediaType(0);
pMSSource.SetMediaType(0, pmt);
pmt = null;
pmt = pMSTarget.GetConnectedMediaType(1);
pMSSource.SetMediaType(1, pmt);
pmt = null;
// get the inserted media type for the first stream
pInsertedMediaType = pMSSource.GetMediaType(0);
pInsertedMediaType = null;
// set the output filename
pConvert2.TargetFile = _targetFile;
// set the source for convert 2
pConvert2.SourceObject = pMSSource;
// start the destination conversion
pConvert2.StartConvert();
// convert first file
ConcateFile(pConvert1, pMSTarget, pMSSource, ref lStart);
/*
Restrict the output format to the media type of the source for the first file
That is because the two files must have the same media type for both video and audio
With video, you have to make sure the files have the same frame rate! Minor changes in
the frame rate might make the connection fail!
The control will tolerate differences in frame rate if you comment the next line
*/
pmt = pMSTarget.GetConnectedMediaType(0);
pMSTarget.SetAcceptedMediaType(0, pmt);
pmt = null;
pmt = pMSTarget.GetConnectedMediaType(1);
pMSTarget.SetAcceptedMediaType(1, pmt);
pmt = null;
// change the source file to second file
pConvert1.SourceFile = _sourceFile2;
// start converting again
pConvert1.StartConvert();
// convert second file
ConcateFile(pConvert1, pMSTarget, pMSSource, ref lStart);
// deliver end of sample to stop the conversion
pMSSource.DeliverEndOfStream(0, 1000);
pMSSource.DeliverEndOfStream(1, 1000);
if (pConvert2.State == ConvertState.Running)
pConvert2.StopConvert();
// free the source and target objects
pConvert2.ResetSource();
pConvert1.ResetTarget();
pMSSource.Dispose();
pMSTarget.Dispose();
}
Add the following helper methods for the concatenation work:
Private Sub ConcateFile(ByVal pConvert1 As ConvertCtrl, ByVal pMSTarget As MultiStreamTarget, ByVal pMSSource As MultiStreamSource, ByRef lStart As Long)
Dim pmsSrc As MediaSample = Nothing
Dim pmsDst As MediaSample = Nothing
Dim MediaTimeStart As Long
Dim MediaTimeStop As Long
Dim LastStart As Long
Dim LastStop As Long
Dim lSampleStream As Integer
Dim lActualDataLength As Integer
LastStop = 0
Do
' get the sample, allowing 10 s for the operation to complete
Try
lSampleStream = pMSTarget.WaitForSample(1000)
Catch cex As COMException
If cex.ErrorCode = CInt(ErrorCode.VFW_E_TIMEOUT) Then
' end of the stream
Exit Do
End If
Exit Do
End Try
Try
' get the target sample
pmsSrc = pMSTarget.GetSample(lSampleStream, 0)
' get the source buffer
pmsDst = pMSSource.GetSampleBuffer(lSampleStream, 2000)
Catch e1 As Exception
Exit Do
End Try
' get the media time
pmsSrc.GetMediaTime(MediaTimeStart, MediaTimeStop)
' get the source sample time
pmsSrc.GetTime(LastStart, LastStop)
' set the destination sample time
pmsDst.SetTime(lStart + LastStart, lStart + LastStop)
' copy the data
lActualDataLength = pmsSrc.ActualDataLength
' set the destination buffer
' we could Marshal the unmanaged buffer here, but no need since we are merely
' setting the destination to the source buffer contents (unaltered data)
pmsDst.SetData(lActualDataLength, pmsSrc.GetData(lActualDataLength))
' copy the other flags
pmsDst.Discontinuity = pmsSrc.Discontinuity
pmsDst.Preroll = pmsSrc.Preroll
pmsDst.SyncPoint = pmsSrc.SyncPoint
' release the source sample
pmsSrc = Nothing
' deliver the destination sample
pMSSource.DeliverSample(lSampleStream, 1000, pmsDst)
' release the destination sample
pmsDst = Nothing
Loop While True
pConvert1.StopConvert()
lStart = LastStop
End Sub
void ConcateFile(ConvertCtrl pConvert1, MultiStreamTarget pMSTarget, MultiStreamSource pMSSource, ref long lStart)
{
MediaSample pmsSrc = null;
MediaSample pmsDst = null;
long MediaTimeStart;
long MediaTimeStop;
long LastStart;
long LastStop;
int lSampleStream;
int lActualDataLength;
LastStop = 0;
do
{
// get the sample, allowing 10 s for the operation to complete
try
{
lSampleStream = pMSTarget.WaitForSample(1000);
}
catch (COMException cex)
{
if (cex.ErrorCode == (int)ErrorCode.VFW_E_TIMEOUT)
{
// end of the stream
break;
}
break;
}
try
{
// get the target sample
pmsSrc = pMSTarget.GetSample(lSampleStream, 0);
// get the source buffer
pmsDst = pMSSource.GetSampleBuffer(lSampleStream, 2000);
}
catch (Exception)
{
break;
}
// get the media time
pmsSrc.GetMediaTime(out MediaTimeStart, out MediaTimeStop);
// get the source sample time
pmsSrc.GetTime(out LastStart, out LastStop);
// set the destination sample time
pmsDst.SetTime(lStart + LastStart, lStart + LastStop);
// copy the data
lActualDataLength = pmsSrc.ActualDataLength;
// set the destination buffer
// we could Marshal the unmanaged buffer here, but no need since we are merely
// setting the destination to the source buffer contents (unaltered data)
pmsDst.SetData(lActualDataLength, pmsSrc.GetData(lActualDataLength));
// copy the other flags
pmsDst.Discontinuity = pmsSrc.Discontinuity;
pmsDst.Preroll = pmsSrc.Preroll;
pmsDst.SyncPoint = pmsSrc.SyncPoint;
// release the source sample
pmsSrc = null;
// deliver the destination sample
pMSSource.DeliverSample(lSampleStream, 1000, pmsDst);
// release the destination sample
pmsDst = null;
}
while (true);
pConvert1.StopConvert();
lStart = LastStop;
}
Build, and Run the program to test it.