大概测试了一下,如果直接RenderFile播放的话,视频之间从上一个视频Stop到下一个视频Run之间 所需的时间为下面方法的至少3倍时间,
对于采用同一种视频编码的多个视频,可以采用只改变SourceFilter,而其他Filter不用改变的方式来切换视频。
实现方式如下,注意需要
DirectShowLibNET
DirectShowLibNET - A library to allow .NET applications to use DirectShow functions
- public void ChangeFileSource(string newfilename)
- {
-
- IPin nextOutPin = null;
- int hr = 0;
- IBaseFilter sourceFilter = null;
- hr = m_FilterGraph.AddSourceFilter(newfilename, newfilename, out sourceFilter);
- DsError.ThrowExceptionForHR(hr);
-
- hr = sourceFilter.FindPin("Output", out nextOutPin);
- DsError.ThrowExceptionForHR(hr);
-
-
- hr = m_mediaCtrl.Stop();
- DsError.ThrowExceptionForHR(hr);
-
-
- IEnumFilters enumFilters = null;
- hr = m_FilterGraph.EnumFilters(out enumFilters);
-
- int iFiltCount = 0;
-
- while (0 == enumFilters.Skip(1))
- {
- iFiltCount++;
- }
- enumFilters.Reset();
-
- int iPos = 0;
- IBaseFilter[] filters = new IBaseFilter[iFiltCount];
- while (iPos < iFiltCount)
- {
- int numFiltersToGet = 1;
- IBaseFilter[] filter = new IBaseFilter[numFiltersToGet];
- IntPtr fetched = IntPtr.Zero;
- hr = enumFilters.Next(1, filter, fetched);
- DsError.ThrowExceptionForHR(hr);
- filters[iPos] = filter[0];
- iPos++;
- }
-
-
- for (iPos = 0; iPos < iFiltCount; iPos++)
- {
- m_FilterGraph.RemoveFilter(filters[iPos]);
- if (filters[iPos] != m_currentSource)
- {
- m_FilterGraph.AddFilter(filters[iPos], null);
- }
- else
- {
- Marshal.ReleaseComObject(filters[iPos]);
- }
- }
-
- hr = m_FilterGraph.Render(nextOutPin);
- DsError.ThrowExceptionForHR(hr);
- m_currentSource = sourceFilter;
- sourceFilter = null;
-
- m_mediaCtrl.Run();
-
- if (enumFilters != null)
- {
- Marshal.ReleaseComObject(enumFilters);
- enumFilters = null;
- }
- }