Replace Audio using IltmmMultiStreamSource and IltmmMultiStreamTarget Example for C
int ReplaceAudio()
{
IltmmConvert* pVideoConvert;
IltmmConvert* pAudioConvert;
IltmmConvert* pDestConvert;
HRESULT hr;
IltmmSampleTarget* pVideoTarget = NULL;
IltmmSampleTarget* pAudioTarget = NULL;
IltmmMultiStreamSource *pVideoAndAudioSource = NULL;
BSTR bstr;
long lState;
pVideoConvert = NULL;
pAudioConvert = NULL;
pDestConvert = NULL;
CoInitialize(NULL);
hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pVideoConvert);
if(FAILED(hr))
{
MessageBox(0, "Can't instantiate convert library", "Error", 0);
return -1;
}
hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pAudioConvert);
if(FAILED(hr))
{
MessageBox(0, "Can't instantiate convert library", "Error", 0);
return -1;
}
hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pDestConvert);
if(FAILED(hr))
{
MessageBox(0, "Can't instantiate convert library", "Error", 0);
return -1;
}
hr = CoCreateInstance(&CLSID_ltmmMultiStreamSource, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMultiStreamSource, (void**) &pVideoAndAudioSource);
if(FAILED(hr))
{
MessageBox(0, "Can't instantiate convert library", "Error", 0);
return -1;
}
IltmmMultiStreamSource__put_StreamCount(pVideoAndAudioSource, 2);
/*
Prepare pVideoConvert and set its source file to VideoFile.
Convert only the video stream
Create a new pVideoTarget object and set as the sample target object in pVideoConvert
Set the stream media type for pin 0 of VideoAndAudioSource to be the same as the video media type
Also starts the conversion in pVideoConvert
*/
PrepareSampleAndTarget(pVideoConvert, "c:\\Video.avi", (char*)ltmmMEDIATYPE_Video, &pVideoTarget, pVideoAndAudioSource, 0);
/*
Prepare AudioCtrl and set its source file to AudioFile.
Convert only the audio stream
Create a new AudioTarget object and set as the sample target object in AudioCtrl
Set the stream media type for pin 1 of VideoAndAudioSource to be the same as the audio media type
Also starts the conversion in AudioCtrl
*/
PrepareSampleAndTarget(pAudioConvert, "C:\\Voice.wav", (char*)ltmmMEDIATYPE_Audio, &pAudioTarget, pVideoAndAudioSource, 1);
// prepare the destination file
IltmmConvert__put_SourceObject(pDestConvert, pVideoAndAudioSource);
IltmmConvert__put_TargetFormat(pDestConvert, ltmmConvert_TargetFormat_Avi);
bstr = T2OLE("C:\\Video_And_Voice.avi");
IltmmConvert__put_TargetFile(pDestConvert, bstr);
SysFreeString(bstr);
IltmmConvert_StartConvert(pDestConvert);
// Copy all the video samples from the Video file to the destination file
CopySamples(pVideoConvert, pVideoTarget, pVideoAndAudioSource, 0);
// Copy all the audio samples from the Audio file to the destination file
CopySamples(pAudioConvert, pAudioTarget, pVideoAndAudioSource, 1);
// wait for the destination control to stop the conversion
IltmmConvert__get_State(pDestConvert, &lState);
if( lState == ltmmConvert_State_Running )
{
IltmmConvert_StopConvert(pDestConvert);
}
IltmmConvert_ResetSource(pDestConvert);
if (pVideoConvert)
{
IltmmConvert_Release(pVideoConvert);
pVideoConvert = NULL;
}
if (pAudioConvert)
{
IltmmConvert_Release(pAudioConvert);
pAudioConvert = NULL;
}
if (pDestConvert)
{
IltmmConvert_Release(pDestConvert);
pDestConvert = NULL;
}
if (pVideoAndAudioSource)
{
IltmmMultiStreamSource_Release(pVideoAndAudioSource);
pVideoAndAudioSource = NULL;
}
CoUninitialize();
return 0;
}
void PrepareSampleAndTarget(IltmmConvert* pSourceConvert, char pszSourceFile[256], char mtType[40], IltmmSampleTarget** ppSampleTarget, IltmmMultiStreamSource* pVideoAndAudioSource, long lStream)
{
IltmmMediaTypeDisp *pInsertedMeidaType;
IltmmMediaTypeDisp *pmt;
BSTR bstrSourceFile;
HRESULT hr;
BSTR bstrType;
bstrSourceFile = T2OLE(pszSourceFile);
IltmmConvert__put_SourceFile(pSourceConvert, bstrSourceFile);
SysFreeString(bstrSourceFile);
hr = CoCreateInstance(&CLSID_ltmmSampleTarget, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmSampleTarget, (void**) ppSampleTarget);
if(FAILED(hr))
{
return;
}
hr = CoCreateInstance(&CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMediaTypeDisp, (void**) &pmt);
if(FAILED(hr))
{
return;
}
// create a ltmmMediaType and indicate the accepted type
bstrType = T2OLE(mtType);
IltmmMediaTypeDisp__put_Type(pmt, bstrType);
SysFreeString(bstrType);
// make the SampleTarget object accept connections of this media type
hr = IltmmSampleTarget_SetAcceptedMediaType(*ppSampleTarget, pmt);
IltmmMediaTypeDisp_Release(pmt);
pmt = NULL;
// set the output target object to be sample target
IltmmConvert__put_TargetObject(pSourceConvert, *ppSampleTarget);
// start the conversion, so I know the exact media type
IltmmConvert_StartConvert(pSourceConvert);
// set the media type for the source stream to be the same as the media type in the input file (video or audio)
IltmmSampleTarget__getConnectedMediaType(*ppSampleTarget, &pmt);
IltmmMultiStreamSource_SetMediaType(pVideoAndAudioSource, lStream, pmt);
// check set sucess:
IltmmMultiStreamSource__getMediaType(pVideoAndAudioSource, lStream, &pInsertedMeidaType);
if (pInsertedMeidaType)
IltmmMediaTypeDisp_Release(pInsertedMeidaType);
}
void CopySamples(IltmmConvert* pSourceCtrl, IltmmSampleTarget* pSampleTarget, IltmmMultiStreamSource *pVideoAndAudioSource, long lStream)
{
IltmmMediaSampleDisp* pmsSrc = NULL;
IltmmMediaSampleDisp* pmsDst = NULL;
long lStartTimeHi;
long lStartTimeLo;
long lStopTimeHi;
long lStopTimeLo;
HRESULT hr;
VARIANT vBuffer;
long lActualDataLength;
VARIANT_BOOL vBool;
do
{
hr = IltmmSampleTarget__getSample(pSampleTarget, 3000, &pmsSrc);
if (!pmsSrc)
break;
// get a source sample
hr = IltmmMultiStreamSource__getSampleBuffer(pVideoAndAudioSource, lStream, 2000, &pmsDst);
// copy the data to the source sample
hr = IltmmMediaSampleDisp__get_Buffer(pmsSrc, &vBuffer);
hr = IltmmMediaSampleDisp__get_ActualDataLength(pmsSrc, &lActualDataLength);
hr = IltmmMediaSampleDisp_SetData(pmsDst, lActualDataLength, vBuffer);
// copy the sample time
IltmmMediaSampleDisp__getTime(pmsSrc, &lStartTimeHi, &lStartTimeLo, &lStopTimeHi, &lStopTimeLo);
IltmmMediaSampleDisp_SetTime(pmsDst, lStartTimeHi, lStartTimeLo, lStopTimeHi, lStopTimeLo);
// copy the other flags
IltmmMediaSampleDisp__get_Discontinuity(pmsSrc, &vBool);
IltmmMediaSampleDisp__put_Discontinuity(pmsDst, vBool);
IltmmMediaSampleDisp__get_Preroll(pmsSrc, &vBool);
IltmmMediaSampleDisp__put_Preroll(pmsDst, vBool);
IltmmMediaSampleDisp__get_SyncPoint(pmsSrc, &vBool);
IltmmMediaSampleDisp__put_SyncPoint(pmsDst, vBool);
//release the source sample
IltmmMediaSampleDisp_Release(pmsSrc);
pmsSrc = NULL;
// deliver the source sample
IltmmMultiStreamSource_DeliverSample(pVideoAndAudioSource, lStream, 2000, pmsDst);
// release the source sample
IltmmMediaSampleDisp_Release(pmsDst);
pmsDst = NULL;
}
while (1);
// stop the conversion in the source control
IltmmConvert_StopConvert(pSourceCtrl);
// deliver end of stream for the current source stream
hr = IltmmMultiStreamSource_DeliverEndOfStream(pVideoAndAudioSource, lStream, 5000);
}