Replace Audio using IltmmMultiStreamSource and IltmmMultiStreamTarget Example for C++
void Convert(CString strVid, CString strAud, CString strDest)
{
IltmmConvert* pVideoConvert;
IltmmConvert* pAudioConvert;
IltmmConvert* pDestConvert;
pVideoConvert = NULL;
pAudioConvert = NULL;
pDestConvert = NULL;
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pVideoConvert);
if(FAILED(hr))
{
AfxMessageBox(_T("Can't instantiate convert library"));
}
hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pAudioConvert);
if(FAILED(hr))
{
AfxMessageBox(_T("Can't instantiate convert library"));
}
hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pDestConvert);
if(FAILED(hr))
{
AfxMessageBox(_T("Can't instantiate convert library"));
}
IltmmSampleTarget* pVideoTarget = NULL;
IltmmSampleTarget* pAudioTarget = NULL;
IltmmMultiStreamSource *pVideoAndAudioSource = NULL;
hr = CoCreateInstance(CLSID_ltmmMultiStreamSource, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMultiStreamSource, (void**) &pVideoAndAudioSource);
if(FAILED(hr))
{
AfxMessageBox(_T("Can't instantiate convert library"));
}
pVideoAndAudioSource->put_StreamCount(2);
SetWindowText("Prepare the video control...");
/*
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, strVid.GetBuffer(strVid.GetAllocLength()), (char*)ltmmMEDIATYPE_Video, &pVideoTarget, pVideoAndAudioSource, 0);
SetWindowText("Prepare the audio control...");
/*
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, strAud.GetBuffer(strAud.GetAllocLength()), (char*)ltmmMEDIATYPE_Audio, &pAudioTarget, pVideoAndAudioSource, 1);
SetWindowText("Prepare the destination control...");
// prepare the destination file
pDestConvert->put_SourceObject(pVideoAndAudioSource);
pDestConvert->put_TargetFormat(ltmmConvert_TargetFormat_Avi);
BSTR bstr = strDest.AllocSysString();
pDestConvert->put_TargetFile(bstr);
SysFreeString(bstr);
pDestConvert->StartConvert();
SetWindowText("Copy the video samples...");
// Copy all the video samples from the Video file to the destination file
CopySamples(pVideoConvert, pVideoTarget, pVideoAndAudioSource, 0);
SetWindowText("Copy the audio samples...");
// Copy all the audio samples from the Audio file to the destination file
CopySamples(pAudioConvert, pAudioTarget, pVideoAndAudioSource, 1);
hr = pVideoAndAudioSource->DeliverEndOfStream(0, 5000);
hr = pVideoAndAudioSource->DeliverEndOfStream(1, 5000);
// wait for the destination control to stop the conversion
long lState;
pDestConvert->get_State(&lState);
while (lState == ltmmConvert_State_Running)
{
Sleep(5000);
pDestConvert->get_State(&lState);
pDestConvert->StopConvert();
}
pDestConvert->ResetSource();
SetWindowText("Done.");
if (pVideoConvert)
{
pVideoConvert->Release();
pVideoConvert = NULL;
}
if (pAudioConvert)
{
pAudioConvert->Release();
pAudioConvert = NULL;
}
if (pDestConvert)
{
pDestConvert->Release();
pDestConvert = NULL;
}
if (pVideoAndAudioSource)
{
pVideoAndAudioSource->Release();
pVideoAndAudioSource = NULL;
}
CoUninitialize();
}
void PrepareSampleAndTarget(IltmmConvert* pSourceConvert, char pszSourceFile[256], char mtType[40], IltmmSampleTarget** ppSampleTarget, IltmmMultiStreamSource* pVideoAndAudioSource, long lStream)
{
IltmmMediaTypeDisp *pInsertedMeidaType;
IltmmMediaTypeDisp *pmt;
USES_CONVERSION;
BSTR bstrSourceFile = A2BSTR(pszSourceFile);
pSourceConvert->put_SourceFile(bstrSourceFile);
SysFreeString(bstrSourceFile);
HRESULT 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
BSTR bstrType;
bstrType = A2BSTR(mtType);
pmt->put_Type(bstrType);
SysFreeString(bstrType);
// make the SampleTarget object accept connections of this media type
hr = (*ppSampleTarget)->SetAcceptedMediaType(pmt);
pmt->Release();
pmt = NULL;
// set the output target object to be sample target
pSourceConvert->put_TargetObject(*ppSampleTarget);
// start the conversion, so I know the exact media type
pSourceConvert->StartConvert();
// set the media type for the source stream to be the same as the media type in the input file (video or audio)
(*ppSampleTarget)->GetConnectedMediaType(&pmt);
pVideoAndAudioSource->SetMediaType(lStream, pmt);
pVideoAndAudioSource->GetMediaType(0, &pInsertedMeidaType);
if (pInsertedMeidaType)
pInsertedMeidaType->Release();
}
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;
do
{
hr = pSampleTarget->GetSample(3000, &pmsSrc);
if (!pmsSrc)
break;
// get a source sample
hr = pVideoAndAudioSource->GetSampleBuffer(lStream, 2000, &pmsDst);
if (hr == E_FAIL)
hr = pVideoAndAudioSource->GetSampleBuffer(lStream, 3000, &pmsDst);
// copy the data to the source sample
VARIANT vBuffer;
long lActualDataLength;
hr = pmsSrc->get_Buffer(&vBuffer);
hr = pmsSrc->get_ActualDataLength(&lActualDataLength);
hr = pmsDst->SetData(lActualDataLength, vBuffer);
// copy the sample time
pmsSrc->GetTime(&lStartTimeHi, &lStartTimeLo, &lStopTimeHi, &lStopTimeLo);
pmsDst->SetTime(lStartTimeHi, lStartTimeLo, lStopTimeHi, lStopTimeLo);
// copy the other flags
VARIANT_BOOL vBool;
pmsSrc->get_Discontinuity(&vBool);
pmsDst->put_Discontinuity(vBool);
pmsSrc->get_Preroll(&vBool);
pmsDst->put_Preroll(vBool);
pmsSrc->get_SyncPoint(&vBool);
pmsDst->put_SyncPoint(vBool);
//release the source sample
pmsSrc->Release();
pmsSrc = NULL;
// deliver the source sample
pVideoAndAudioSource->DeliverSample(lStream, 2000, pmsDst);
// release the source sample
pmsDst->Release();
pmsDst = NULL;
}
while (1);
// stop the conversion in the source control
pSourceCtrl->StopConvert();
// deliver end of stream for the current source stream
//hr = pVideoAndAudioSource->DeliverEndOfStream(lStream, 5000);
}