Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
[Funkcja skojarzona z tą stroną, DirectShow, jest starszą funkcją. Został zastąpiony przez MediaPlayer, IMFMediaEnginei Audio/Video Capture w Media Foundation. Te funkcje zostały zoptymalizowane pod kątem systemów Windows 10 i Windows 11. Firma Microsoft zdecydowanie zaleca, aby nowy kod używał MediaPlayer, IMFMediaEngine i Audio/Video Capture w programie Media Foundation zamiast DirectShow, jeśli to możliwe. Firma Microsoft sugeruje, że istniejący kod, który używa starszych interfejsów API, należy przepisać go do korzystania z nowych interfejsów API, jeśli to możliwe.]
W tej sekcji opisano sposób implementowania paska wyszukiwania dla aplikacji odtwarzacza multimediów. Pasek wyszukiwania jest implementowany jako kontrolka paska śledzenia. Aby zapoznać się z omówieniem wyszukiwania w programie DirectShow, zobacz Szukanie wykresu filtru.
Po uruchomieniu aplikacji zainicjuj pasek śledzenia:
void InitSlider(HWND hwnd)
{
// Initialize the trackbar range, but disable the
// control until the user opens a file.
hScroll = GetDlgItem(hwnd, IDC_SLIDER1);
EnableWindow(hScroll, FALSE);
SendMessage(hScroll, TBM_SETRANGE, TRUE, MAKELONG(0, 100));
}
Pasek śledzenia jest wyłączony, dopóki użytkownik nie otworzy pliku multimedialnego. Zakres suwaka jest ustawiony od 0 do 100. Podczas odtwarzania pliku aplikacja obliczy pozycję odtwarzania jako procent czasu trwania pliku i odpowiednio zaktualizuje pasek śledzenia. Na przykład pozycja paska śledzenia "50" zawsze odpowiada środku pliku.
Gdy użytkownik otworzy plik, skompiluj graf odtwarzania plików przy użyciu RenderFile. Kod do tego jest pokazany w Jak odtworzyć plik. Następnie wykonaj zapytanie dotyczące menedżera filtrów programu Graph dla interfejsu IMediaSeeking i zapisz wskaźnik interfejsu:
IMediaSeeking *g_pSeek = 0;
hr = pGraph->QueryInterface(IID_IMediaSeeking, (void**)&g_pSeek);
Aby określić, czy plik można wyszukać, wywołaj metodę IMediaSeeking::CheckCapabilities lub metodę IMediaSeeking::GetCapabilities. Te metody robią prawie to samo, ale ich semantyka jest nieco inna. W poniższym przykładzie użyto CheckCapabilites:
// Determine if the source is seekable.
BOOL bCanSeek = FALSE;
DWORD caps = AM_SEEKING_CanSeekAbsolute | AM_SEEKING_CanGetDuration;
bCanSeek = (S_OK == pSeek->CheckCapabilities(&caps));
if (bCanSeek)
{
// Enable the trackbar.
EnableWindow(hScroll, TRUE);
// Find the file duration.
pSeek->GetDuration(&g_rtTotalTime);
}
Flaga AM_SEEKING_CanSeekAbsolute sprawdza, czy plik źródłowy można wyszukiwać, a flaga AM_SEEKING_CanGetDuration sprawdza, czy czas trwania pliku można określić z wyprzedzeniem. Jeśli obie funkcje są obsługiwane, aplikacja włącza pasek śledzenia i pobiera czas trwania pliku.
Jeśli wykres jest możliwy do wyszukiwania, aplikacja użyje czasomierza, aby zaktualizować położenie paska śledzenia podczas odtwarzania. Po uruchomieniu grafu filtru w celu odtworzenia pliku uruchom zdarzenie czasomierza, wywołując jedną z funkcji czasomierza systemu Windows, taką jak SetTimer. Aby uzyskać więcej informacji na temat czasomierzy, zobacz temat "Czasomierze" w zestawie SDK platformy.
void StartPlayback(HWND hwnd)
{
pControl->Run();
if (bCanSeek)
{
StopTimer(); // Make sure an old timer is not still active.
nTimerID = SetTimer(hwnd, IDT_TIMER1, TICK_FREQ, (TIMERPROC)NULL);
if (nTimerID == 0)
{
/* Handle Error */
}
}
}
void StopTimer()
{
if (wTimerID != 0)
{
KillTimer(g_hwnd, wTimerID);
wTimerID = 0;
}
}
Użyj zdarzenia czasomierza, aby zaktualizować położenie paska śledzenia. Wywołaj IMediaSeeking::GetCurrentPosition, aby pobrać bieżące położenie odtwarzania, a następnie oblicz pozycję jako procent czasu trwania pliku.
case WM_TIMER:
if (wParam == IDT_TIMER1)
{
// Timer should not be running unless we really can seek.
ASSERT(bCanSeek == TRUE);
REFERENCE_TIME timeNow;
if (SUCCEEDED(pSeek->GetCurrentPosition(&timeNow)))
{
long sliderTick = (long)((timeNow * 100) / g_rtTotalTime);
SendMessage( hScroll, TBM_SETPOS, TRUE, sliderTick );
}
}
break;
Użytkownik może również przenieść pasek śledzenia, aby wyszukać plik. Gdy użytkownik przeciąga lub klika kontrolkę suwaka, aplikacja odbiera zdarzenie WM_HSCROLL. Niskim wyrazem parametru wParam jest komunikat powiadomienia paska śledzenia. Na przykład TB_ENDTRACK jest wysyłany na końcu akcji suwaka, a TB_THUMBTRACK jest wysyłany ciągle, gdy użytkownik przeciąga suwak. Poniższy kod przedstawia jeden ze sposobów obsługi komunikatu WM_HSCROLL:
static OAFilterState state;
static BOOL bStartOfScroll = TRUE;
case WM_HSCROLL:
short int userReq = LOWORD(wParam);
if (userReq == TB_ENDTRACK || userReq == TB_THUMBTRACK)
{
DWORD dwPosition = SendMessage(hTrackbar, TBM_GETPOS, 0, 0);
// Pause when the scroll action begins.
if (bStartOfScroll)
{
pControl->GetState(10, &state);
bStartOfScroll = FALSE;
pControl->Pause();
}
// Update the position continuously.
REFERENCE_TIME newTime = (g_rtTotalTime/100) * dwPosition;
pSeek->SetPositions(&newTime, AM_SEEKING_AbsolutePositioning,
NULL, AM_SEEKING_NoPositioning);
// Restore the state at the end.
if (userReq == TB_ENDTRACK)
{
if (state == State_Stopped)
pControl->Stop();
else if (state == State_Running)
pControl->Run();
bStartOfScroll = TRUE;
}
}
}
Jeśli użytkownik przeciągnie pasek trackbar, aplikacja wystawia serię poleceń wyszukiwania, po jednym dla każdego TB_THUMBTRACK komunikatu, który otrzymuje. Aby zapewnić bezproblemowe działanie wyszukiwania, aplikacja wstrzymuje graf. Wstrzymanie odtwarzania grafu powoduje zatrzymanie odtwarzania, ale gwarantuje, że okno wideo zostanie zaktualizowane. Gdy aplikacja odbiera komunikat TB_ENDTRACK, przywraca graf do stanu pierwotnego.