This tutorial shows how to take two media files, one video and one audio, and combines them into one media file in a C# Windows Console application using the LEADTOOLS Multimedia SDK.
| Overview | |
|---|---|
| Summary | This tutorial covers how to combine media files in a C# Windows Console application. |
| Completion Time | 30 minutes |
| Visual Studio Project | Download tutorial project (5 KB) |
| Platform | Windows C# Console Application |
| IDE | Visual Studio 2019, 2022 |
| Development License | Download LEADTOOLS |
| Try it in another language |
|
Get familiar with the basic steps of creating a project by reviewing the Add References and Set a License tutorial, before working on the Combine Video and Audio from Separate Sources - Console C# tutorial.
Start with a copy of the project created in the Add References and Set a License tutorial. If you do not have that project, follow the steps in that tutorial to create it.
The references needed depend upon the purpose of the project. References can be added using local DLL references, the following DLLs are needed.
The DLLs are located at <INSTALL_DIR>\LEADTOOLS22\Bin\Dotnet4\x64:
Leadtools.dllLeadtools.Multimedia.dllFor a complete list of which DLL files are required for your LEADTOOLS Multimedia application, refer to Multimedia Files to be Included with your Application.
The License unlocks the features needed for the project. It must be set before any toolkit function is called. For details, including tutorials for different platforms, refer to Setting a Runtime License.
There are two types of runtime licenses:
With the project created, the references added, and the license set, coding can begin.
In Solution Explorer, open Program.cs, then add using Leadtools.Multimedia; to the using block at the top.
using System;using System.IO;using Leadtools;using Leadtools.Multimedia;
Add a new method inside the Program class named CombineAudioandVideo(string _videoFile, string _audioFile, string _targetFile). Call this new method inside the Main() method after the call to the SetLicense() method. The string values passed into the new method are going to be the file paths to the video file, audio file, and target file path for the combined media file. Ensure that you add STAThreadAttribute to indicate to the COM components that the application is of single-thread threading model.
[STAThread]static void Main(string[] args){string videoFile = @"FILE PATH TO VIDEO SOURCE FILE";string audioFile = @"FILE PATH TO AUDIO SOURCE FILE";string targetFile = @"FILE PATH TO COMBINED OUTPUT MEDIA FILE";SetLicense();CombineAudioandVideo(videoFile, audioFile, targetFile);}
For the purposes of this tutorial, you may use this audio file and this video file.
Add the code below in the CombineAudioandVideo() method to create the SampleTargets for the audio and video files, and start the ConvertCtrls.
static void CombineAudioandVideo(string _videoFile, string _audioFile, string _targetFile){ConvertCtrl vidConvert = new ConvertCtrl();ConvertCtrl audConvert = new ConvertCtrl();// Init the SampleTargets. The Video and Audio data from our files will write to theseSampleTarget vidTarget = new SampleTarget();SampleTarget audTarget = new SampleTarget();// Set the Media Type of the VideoTarget to VideoMediaType mt = new MediaType();mt.Type = Constants.MEDIATYPE_Video;vidTarget.SetAcceptedMediaType(mt);vidConvert.TargetObject = vidTarget;// Clearmt = null;// Set the Media type for our AudioTarget to Audiomt = new MediaType();mt.Type = Constants.MEDIATYPE_Audio;audTarget.SetAcceptedMediaType(mt);audConvert.TargetObject = audTarget;// Clearmt = null;// Set the ConvertCtrls to point to the Files as their sourcesvidConvert.SourceFile = _videoFile;audConvert.SourceFile = _audioFile;// Start running the two conversion controls. These are writing to the Sample TargetsvidConvert.StartConvert();audConvert.StartConvert();// Enter the Combine MethodCombineFiles(vidTarget, audTarget, _targetFile);// Stop running the ConvertCtrlsif (vidConvert.State == ConvertState.Running)vidConvert.StopConvert();if (audConvert.State == ConvertState.Running)audConvert.StopConvert();// Dispose of the targets we wrote the data tovidTarget.Dispose();audTarget.Dispose();// Dispose of the ConvertCtrls that read the file data into the SampleTarget BuffersvidConvert.Dispose();audConvert.Dispose();}
After the above code has been added, create a new method named CombineFiles(SampleTarget _vidTarget, SampleTarget _audTarget, string _targetFile). This method will be called inside the CombineAudioandVideo() method code, as shown above. Add the code below to the new method to use the ConvertCtrl to combine the two media files.
static void CombineFiles(SampleTarget _vidTarget, SampleTarget _audTarget, string _targetFile){MultiStreamSource pMSSource;ConvertCtrl combine;// Initialize the MultiStreamSource. This is the data that our Combine ConvertCtrl will be reading and then finnally writing to fill// We have two streams. 0 = Video 1 = AudiopMSSource = new MultiStreamSource();pMSSource.StreamCount = 2;// Set the MediaType of the Sources Video Stream to that of the data connected to the VideoTargetMediaType mt = _vidTarget.GetConnectedMediaType();pMSSource.SetMediaType(0, mt);// Clearmt = null;// Set the Mediatype of the Sources Audio Stream to that of the data connected to the AudioTargetmt = _audTarget.GetConnectedMediaType();pMSSource.SetMediaType(1, mt);// Clearmt = null;// Init the Combine ConvertCtrl that will output our file. This ConvertCtrl will take in the MultiStream Source and output a file on diskcombine = new ConvertCtrl();combine.SourceObject = pMSSource;combine.TargetFile = _targetFile;combine.VideoCompressors.H264.Selected = true;combine.AudioCompressors.AAC.Selected = true;combine.TargetFormat = TargetFormatType.MPEG2Transport;// Our MediaSamples. Both a source retrieved from our SampleTargets and a destination that will be written to the MultiStreamSourceMediaSample pmsSrc = null;MediaSample pmsDst = null;long LastStart;long LastStop;int lActualDataLength;// Begin the running the Combine ConvertCtrlcombine.StartConvert();// Video Writewhile (true){try{// Get the target sample.// Note if we hit the end of the data stream an exception will trigger and break the loop. This is how we know to stop writing to the bufferpmsSrc = _vidTarget.GetSample(6000);// Get the source bufferpmsDst = pMSSource.GetSampleBuffer(0, 2000);}catch (Exception){break;}try{// get the source sample timepmsSrc.GetTime(out LastStart, out LastStop);// Set the destination sample timepmsDst.SetTime(LastStart, LastStop);}catch (Exception){pmsDst.ResetTime();}// Copy the datalActualDataLength = 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 flagspmsDst.Discontinuity = pmsSrc.Discontinuity;pmsDst.Preroll = pmsSrc.Preroll;pmsDst.SyncPoint = pmsSrc.SyncPoint;// Release the source samplepmsSrc = null;// Deliver the destination samplepMSSource.DeliverSample(0, 1000, pmsDst);// Release the destination samplepmsDst = null;}// Audio Writewhile (true){try{// Get the target sample// Note if we hit the end of the data stream an exception will trigger and break the loop. This is how we know to stop writing to the bufferpmsSrc = _audTarget.GetSample(6000);// Get the source bufferpmsDst = pMSSource.GetSampleBuffer(1, 2000);}catch (Exception){break;}try{// Get the source sample timepmsSrc.GetTime(out LastStart, out LastStop);// Set the destination sample timepmsDst.SetTime(LastStart, LastStop);}catch (Exception){pmsDst.ResetTime();}// Copy the datalActualDataLength = 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 flagspmsDst.Discontinuity = pmsSrc.Discontinuity;pmsDst.Preroll = pmsSrc.Preroll;pmsDst.SyncPoint = pmsSrc.SyncPoint;// Release the source samplepmsSrc = null;// Deliver the destination samplepMSSource.DeliverSample(1, 1000, pmsDst);// Release the destination samplepmsDst = null;}// Deliver end of sample to stop the conversionpMSSource.DeliverEndOfStream(0, 1000);pMSSource.DeliverEndOfStream(1, 1000);// Stop the Combine ConvertCtrl if it hasn't been alreadyif (combine.State == ConvertState.Running)combine.StopConvert();// Reset the Sourcecombine.ResetSource();// DisposepMSSource.Dispose();combine.Dispose();}
Run the project by pressing F5, or by selecting Debug -> Start Debugging.
If the steps were followed correctly, the application runs and converts the audio and video source files to one media file. If you used the sample files above, this is the expected output media file.
This tutorial showed how to combine two media files, one video and one audio, to one file using the ConvertCtrl class.