这个容易 下面是C++,改成DELPHI应该没问题,
呵呵连注释都给你了
//------------------------------------------------------------------------------
// Name: SwapSourceFilter()
// Desc: This routine is used to change the source file in the current graph.
// First the graph is stopped, then
the current source filter is removed.
// The new source filter is added, the output pin on this filter is
// rendered, and playback is restarted.
//
// When this routine is called during initialization, there is no
// currently running graph. In that case, Stop becomes a no-op. The source
// filter is added to an empty graph. then
during the render call, all
// necessary filters required to play this source are added to the graph.
//
// On subsequent calls, Stopping the graph allows filters to be removed.
// When the old source filter is removed, all other filters are still
// left in the graph. The new source filter is added, and then
the render
// operation reconnects the graph. Since all of the necessary filters for
// playback are already in the graph (if the two files have the same file
// type), these filters are reused. Existing filters in the graph are
// always used first, if possible, during a Render operation. This avoids
// having to create new filter instances with each change.
//------------------------------------------------------------------------------
HRESULT SwapSourceFilter(void)
{
HRESULT hr = S_OK;
IPin *pPin = NULL;
int nNextFileIndex=0;
TCHAR szFilename[MAX_PATH];
WCHAR wFileName[MAX_PATH];
// Determine the file to load based on DirectX Media path (from SDK)
nNextFileIndex = g_iNextFile % g_iNumFiles;
_tcsncpy(szFilename, DXUtil_GetDXSDKMediaPath(), NUMELMS(szFilename));
_tcscat(szFilename, pstrFiles[nNextFileIndex]);
szFilename[MAX_PATH-1] = 0;
// Ensure NULL termination
_tcsncpy(g_szCurrentFile, pstrFiles[nNextFileIndex], NUMELMS(g_szCurrentFile));
g_iNextFile++;
// Make sure that this file exists
DWORD dwAttr = GetFileAttributes(szFilename);
if(dwAttr == (DWORD) -1)
{
TCHAR szMsg[MAX_PATH + 64];
wsprintf(szMsg, TEXT("Can't find the media file [%s]./0"), szFilename);
MessageBox(NULL, szMsg, TEXT("BGMusic Sample Error"), MB_OK | MB_ICONEXCLAMATION);
return E_FAIL;
}
USES_CONVERSION;
wcsncpy(wFileName, T2W(szFilename), MAX_PATH);
// OPTIMIZATION OPPORTUNITY
// This will open the file, which is expensive. To optimize, this
// should bedo
ne earlier, ideally as soon as we knew this was the
// next file to ensure that the file loaddo
esn't add to the
// filter swapping time &
cause a hiccup.
//
// Add the new source filter to the graph. (Graph can still be running)
hr = g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pSourceNext);
// Get the first output pin of the new source filter. Audio sources
// typically have only one output pin, so for most audio cases finding
// any output pin is sufficient.
if(SUCCEEDED(hr))
{
hr = g_pSourceNext->FindPin(L"Output", &pPin);
}
// Stop the graph
if(SUCCEEDED(hr))
{
hr = g_pMediaControl->Stop();
}
// Break all connections on the filters. You cando
this by adding
// and removing each filter in the graph
if(SUCCEEDED(hr))
{
IEnumFilters *pFilterEnum = NULL;
if(SUCCEEDED(hr = g_pGraphBuilder->EnumFilters(&pFilterEnum)))
{
int iFiltCount = 0;
int iPos = 0;
// Need to know how many filters. If we add/remove filters during the
// enumeration we'll invalidate the enumerator
while(S_OK == pFilterEnum->Skip(1))
{
iFiltCount++;
}
// Allocate space, then
pull out all of the
IBaseFilter **ppFilters = reinterpret_cast<IBaseFilter **>
(_alloca(sizeof(IBaseFilter *) * iFiltCount));
pFilterEnum->Reset();
while(S_OK == pFilterEnum->Next(1, &(ppFilters[iPos++]), NULL));
SAFE_RELEASE(pFilterEnum);
for(iPos = 0;
iPos < iFiltCount;
iPos++)
{
g_pGraphBuilder->RemoveFilter(ppFilters[iPos]);
// Put the filter back, unless it is the old source
if(ppFilters[iPos] != g_pSourceCurrent)
{
g_pGraphBuilder->AddFilter(ppFilters[iPos], NULL);
}
SAFE_RELEASE(ppFilters[iPos]);
}
}
}
// We have the new output pin. Render it
if(SUCCEEDED(hr))
{
// Release the old source filter, if it exists
SAFE_RELEASE(g_pSourceCurrent)
hr = g_pGraphBuilder->Render(pPin);
g_pSourceCurrent = g_pSourceNext;
g_pSourceNext = NULL;
}
SAFE_RELEASE(pPin);
SAFE_RELEASE(g_pSourceNext);
// In case of errors
// Re-seek the graph to the begin
ning
if(SUCCEEDED(hr))
{
LONGLONG llPos = 0;
hr = g_pMediaSeeking->SetPositions(&llPos, AM_SEEKING_AbsolutePositioning,
&llPos, AM_SEEKING_NoPositioning);
}
// Start the graph
if(SUCCEEDED(hr))
{
hr = g_pMediaControl->Run();
}
return S_OK;
}