如何把这个内存流播放改成可以连续播放多个的?(100分)

  • 主题发起人 主题发起人 bo717
  • 开始时间 开始时间
B

bo717

Unregistered / Unconfirmed
GUEST, unregistred user!
if not OpenDialog1.Execute then
exit;
NilAll;
CheckDSError(CoCreateInstance(TGUID(CLSID_FilterGraph), NIL, CLSCTX_INPROC,
TGUID(IID_IGraphBuilder), g_GraphBuilder)) ;
CheckDSError(g_GraphBuilder.QueryInterface(IID_IMediaControl, g_MediaControl));
CheckDSError(CoCreateInstance(CLSID_DSPlayerAsyncSource,NIL, CLSCTX_INPROC,
IID_IBaseFilter, g_DSPlayerFileSource));
CheckDSError(g_DSPlayerFileSource.QueryInterface(IID_IFilesourcefilter,
g_FileSource));
CheckDSError(g_FileSource.Load(StringToOleStr(OpenDialog1.FileName),NIL));
CheckDSError(g_DSPlayerFileSource.FindPin(pinID, g_Pin));
CheckDSError(g_GraphBuilder.AddFilter(g_DSPlayerFileSource,
StringToOleStr('DSPlayer Async FileSource')));
CheckDSError(g_GraphBuilder.Render(g_Pin));
CheckDSError(g_MediaControl.Run);
if g_count = 0 then
begin

g_count := g_count+1;
CheckDSError(dsutil.ShowFilterPropertyPage(0,g_DSPlayerFileSource));
end;


如何实现打开多个视频然后用内存流无间断播放呢?上边的代码只能播一个。
 
我也是刚在研究流媒体服务器,正找RTSP协议的东西,delphi相关的几乎找不到,哪位大侠有呢,指点一下啊
 
这个容易 下面是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, &amp;(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(&amp;llPos, AM_SEEKING_AbsolutePositioning,
&amp;llPos, AM_SEEKING_NoPositioning);
}

// Start the graph
if(SUCCEEDED(hr))
{
hr = g_pMediaControl->Run();
}

return S_OK;

}
 
帮顶,关注学习一下。
 
接受答案了.
 
后退
顶部