2012-06-04 14 views
6

Mam aplikację odtwarzającą muzykę odtwarzającą muzykę za pomocą MPMoviePlayerController. Muszę zaktualizować interfejs użytkownika na podstawie pozycji odtwarzania. Najlepsze, co mogę powiedzieć, nie ma sposobu, aby aktywnie otrzymać te informacje od gracza z wywołaniem zwrotnym lub czymś podobnym, i zasadniczo muszę sondować dla siebie.Jak monitorować postęp odtwarzania MPMoviePlayerController, nie zabijając baterii?

Więc pomyślałem, że użyłbym prostego timera, biegnącego co sekundę, do tego. Kod jest takie:

Gdzieś w kodzie konfiguracji:

[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updatePlaybackProgressFromTimer:) userInfo:nil repeats:YES]; 

A potem:

- (void) updatePlaybackProgressFromTimer:(NSTimer *)timer { 

    if (([UIApplication sharedApplication].applicationState == UIApplicationStateActive) && (player.playbackState == MPMoviePlaybackStatePlaying)) { 

     CGFloat progress = player.currentPlaybackTime/player.duration; 
     // do something useful with this info    
    } 

}

Timer prowadzony jest co sekundę, nawet gdy aplikacja jest w tło. Metoda najpierw sprawdza, czy aplikacja jest aktywna, a odtwarzacz odtwarza, a następnie aktualizuje niektóre interfejsy.

Czy w ten sposób ma miejsce żywotność baterii co sekundę? Czy powinienem być bardziej pracowity i próbować oderwać licznik, wchodząc w tło i ponownie aktywując go podczas aktywacji aplikacji? Jestem pewien, że jest jakiś efekt życia na baterii, ale realistycznie, jak poważny jest? Czy jest jakiś inny zalecany sposób robienia tego rodzaju rzeczy?

+1

wystarczy użyć czasomierza jako sugerowane przez @ChrisGummer. Nie ma KVO dla struktury MPMoviePlayerController lub podobnych wywołań zwrotnych. Jest jednak coś takiego dla AVFlayer (AVPlayer) - nadal nie ma potrzeby rezygnacji z timera z podanych powodów. – Till

Odpowiedz

7

Nie mogę sobie wyobrazić, że użycie NSTimer znacząco wpłynie na żywotność baterii - chyba że praca wykonywana w momencie wyzwolenia ma wpływ na żywotność baterii. Timer jest po prostu dodawany do bieżącej pętli:

Zegar nie jest mechanizmem działającym w czasie rzeczywistym; uruchamia się tylko wtedy, gdy działa jeden z trybów pracy pętli, do których dodano timer, i może sprawdzać, czy upłynął czas świecenia licznika.

NSTimer Class Reference

Zgodnie z dokumentacją, powinieneś być zatrzymując wszystkie zegary, gdy aplikacja ma zamiar zrezygnować swój status aktywnego:

W odpowiedzi na tę zmianę, aplikacja powinien zrobić idąc w jego applicationWillResignActive: metoda:

  • Zatrzymaj timery i inne zadania okresowe.
  • Zatrzymaj wszelkie uruchomione zapytania o metadane.
  • Nie inicjuj nowych zadań.
  • Wstrzymać odtwarzanie filmu (z wyjątkiem odtwarzania za pomocą funkcji AirPlay).
  • Przejdź do stanu wstrzymania, jeśli Twoja aplikacja jest grą.
  • Przepustnica w tył Szybkość klatek OpenGL ES.
  • Zawieszenie wszystkich kolejek wywoławczych lub kolejek operacyjnych wykonujących niekrytyczny kod. (Możesz kontynuować przetwarzanie żądań sieciowych i innych zadań tła zależnych od czasu, gdy są nieaktywne.)

Kiedy aplikacja zostanie przeniesiona z powrotem do stanu aktywnego, jego applicationDidBecomeActive: metoda powinna odwrócić każdy z kroków podjętych w applicationWillResignActive: metoda. Tak więc po ponownym uruchomieniu , Twoja aplikacja powinna ponownie uruchomić liczniki czasu, wznowić wysyłanie kolejki i ponownie zwiększyć przepustowość klatek OpenGL ES. Jednak gry nie powinny być automatycznie wznawiane; powinny one zostać wstrzymane, dopóki użytkownik nie zdecyduje się je wznowić.

iOS App Programming Guide

+0

+1 całkowicie poprawna i dobrze powiązana odpowiedź – Till

Powiązane problemy