2011-10-27 42 views
8

Próbowałem dowiedzieć się, co tak naprawdę dzieje się od tygodni i nie mam pojęcia, dlaczego nie mogę kontynuować odtwarzania po przerwie, więc pewnie znacie odpowiedź. AudioSessionSetActive (TRUE) zawsze zwraca "! Cat", który jest kAudioSessionIncompatibleCategory podczas ponownej aktywacji, jeśli moja aplikacja gra w tle i jestem w innej aplikacji. Mimo że działa dobrze i kontynuuje odtwarzanie, jeśli podczas korzystania z aplikacji złapię przerwę.AudioSessionSetActive kończy się niepowodzeniem po przerwie

Oryginalny kod posiada wszystkie wywołania AudioSession i AudioQueue owinięte w makra, które wyświetlają OSStatus, jeśli oznacza to błąd, ale usunąłem go dla lepszej czytelności. Ponadto, [self pause] po prostu przełącza pauzę, więc w zasadzie wywołuje funkcję AudioQueueStart (audioQueue, NULL) w momencie wznowienia, ale to nie działa w przypadku niepowodzenia AudioSession.

audio kod inicjalizacji sesji:

AudioSessionInitialize(NULL, NULL, _audioSessionInterruptionListener, self); 
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback; 
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory); 
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, _audioSessionPropertyListener, self); 
AudioSessionSetActive(TRUE); 

Przerwanie kod obsługi:

- (void)handleInterruptionChangeToState:(AudioQueuePropertyID)inInterruptionState 
{ 
    if(inInterruptionState == kAudioSessionBeginInterruption) 
    { 

     NSLog(@"+Interruption"); 

     if(self.state == NX_STATE_PLAY) 
     { 
      [self pause]; 
      AudioSessionSetActive(FALSE); 

      isPausedByInterruption = YES; 
     } 
    } 
    else if(inInterruptionState == kAudioSessionEndInterruption) 
    { 
     if(isPausedByInterruption) 
     { 
      AudioSessionSetActive(TRUE); 
      [self pause]; 

      isPausedByInterruption = FALSE; 
     } 

     NSLog(@"-Interruption"); 
    } 
} 

Ten kod źródłowy streamer można znaleźć tutaj https://bitbucket.org/and/amaudiostreamer/src/122de41fe6c0/AMAudioStreamer/AMAudioStreamer/Classes/NxAudioStreamer.m jeśli to będzie jakoś pomóc rozwiązać problem ..

Odpowiedz

0

Spróbuj aktywować sesję audio w w przeciwnym razie, jeśli stanie się następująca:

AVAudioSession *session = [AVAudioSession sharedInstance]; 
NSError *error = nil; 

[session setCategory: AVAudioSessionCategoryPlayback error: &error]; 
if (error != nil) 
    NSLog(@"Failed to set category on AVAudioSession"); 

// AudioSession and AVAudioSession calls can be used interchangeably 
OSStatus result = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, RouteChangeListener, self); 
if (result) NSLog(@"Could not add property listener! %d\n", result); 

BOOL active = [session setActive: YES error: nil]; 
if (!active) 
    NSLog(@"Failed to set category on AVAudioSession"); 

Ale wierzę, że to może nie zadziałać, ponieważ w moim przypadku to, co się wydarzyło, było wtedy, gdy byłem w tle, nie było sesji. Ale spróbuj przeanalizować wersję aurioTouch example firmy Apple i przejrzyj tylko plik AppDelegate i spróbuj przeanalizować metodę (void)rioInterruptionListener wyjaśniającą ten sam problem.

Czy korzystasz z transmisji audio na żywo? wtedy poleciłbym ci przejść przez moją question's answer, gdzie problem z uruchamianiem kolejki rozwiązuje się przez obsługę błędu podanego w mojej odpowiedzi.

Nadzieja na to może być pomocna.

+0

Zgodnie z oczekiwaniami, nie działa i daje mi ten sam błąd w bardziej modny sposób: "Nie udało się ustawić kategorii na AVAudioSession. Nie można ukończyć operacji (błąd OSStatus 560161140.)". Spróbuję przeanalizować rioInterruptionListener .. Myślę, że właśnie przegapiłem jakąś małą rzecz. – Andy

+0

potem wierzę, że najpierw musisz spróbować tego w odpowiedzi na moje pytanie. Ale tutaj będzie zbyt ciężko, aby uzyskać dokładny problem. Musisz określić, gdzie "dokładnie" chcesz zmodyfikować kod. było to dla mnie wyzwaniem, kiedy zrobiłem ... Najlepsze szczęście dla ciebie ... Mam nadzieję, że rozwiążesz ten problem ... – DShah

0

KAudioSessionEndInterruption może, ale nie musi uderzyć twój kod, nie jest to niezawodny sposób kontrolowania twoich stanów odtwarzania, po prostu nie wyłączaj sesji audio w swoim kodzie, wznowi sesję, gdy będzie mógł ponownie przejąć kontrolę, w twoim przypadku, po prostu skomentuj AudioSessionSetActive (FALSE).

+0

Widzę twoją sprawę, ale nie pomaga mi uzyskać sesji audio cofnij i kontynuuj odtwarzanie :( – Andy

0

Jeśli spojrzeć na Listing 7-16 An interruption listener callback function w Audio Session Programming Guide cookbook section próbka kodu (co wydaje się być zgodny z danej sytuacji, korzystając kAudioSessionCategory_MediaPlayback) nie wykonują połączenia w przypadku kAudioSessionBeginInterruption

AudioSessionSetActive(FALSE); 

i w przypadku wywołanie. Naprawdę nie sądzę, że powinieneś to robić. This post wydaje się również zilustrować ten problem (uzyskanie kategorii niewskazanej przez kAudioSessionIncompatibleCategory). Co się stanie, jeśli skomentujesz oba połączenia?

Powód, dla którego problem występuje, gdy aplikacja w tle, a nie pierwszy plan, jest zagadką. Powinieneś prawdopodobnie śledzić stan (jak wydaje się, że robisz z NX_STATE_PLAY), a następnie masz dwie różne metody ([pauza własna] i [samodzielna gra]), ponieważ być może [samo pauza] (przełączany stan gry) jest nazywany nieoczekiwana liczba razy.

+0

[self pause] wywoływana tylko dwa razy, więc w zasadzie AudioQueuePause przy rozpoczęciu przerwania i AudioQueueStart na końcu przerwań, sprawdziłem to, żadnych problemów nie usunąłem Usunąłem AudioSessionSetActive (FALSE) z mojego kodu i wciąż otrzymuję to w moim dzienniku. VERIFY_OSS AudioSessionSetActive (true) - '! kota VERIFY_OSS AudioQueueStart (audioQueue, NULL) - -12985 – Andy

0

Mam dla ciebie trochę pracy, możesz spróbować ryzykować.

W funkcji

void _audioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState) 

usunąć

[(NxAudioStreamer*)inClientData handleInterruptionChangeToState:inInterruptionState]; 

nie ma potrzeby, aby zadzwonić handleInterruptionChangeToState kiedy można bezpośrednio obsługiwać go w audioSessionInterruptionListener ponieważ audioSessionInterruptionListener ma inInterruptionState jako parametr. Tak zmodyfikować, aby audioSessionInterruptionListener

void _audioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState) 
{ 
    if(inInterruptionState == kAudioSessionBeginInterruption) 
    { 

        NSLog(@"+Interruption"); 

        if(self.state == NX_STATE_PLAY) 
        { 
            [self pause]; 
            AudioSessionSetActive(FALSE); 

            isPausedByInterruption = YES; 
        } 
    } 
    else if(inInterruptionState == kAudioSessionEndInterruption) 
    { 
        if(isPausedByInterruption) 
        { 
            AudioSessionSetActive(TRUE); 
            [self pause]; 

            isPausedByInterruption = FALSE; 
        } 

        NSLog(@"-Interruption"); 
    } 
} 
+0

myślę dałem się na to i używać AVFoundation od iOS 3 nie jest ważne dla mnie więcej Dzięki za i tak odpowiedzieć – Andy

3

Jeśli używasz API AudioQueue trzeba zrobić jakieś dodatkowe kroki, które zależy od jakiegoś czynnika. Nigdy tego nie robiłem, więc zostawię wyjaśnienie ekspertowi:
jest film na ten temat na stronie internetowej programisty Apple, który omawia dokładnie ten problem. Sesja WWDC 2010 412 Rozbudowa audio dla iPhone OS część 1 około 45 minut. Masz całkiem niezłe wyjaśnienie w tej sprawie.

+0

Nadal nie mogę zrozumieć, dlaczego AudioSessionSetActive (true); zwraca! cat, prawdopodobnie nie ma nawet znaczenia, co zwraca, wszystko co muszę zrobić, to kontynuować odtwarzanie. Więc zasadniczo muszę się pozbyć i odtworzyć AudioQueue podczas korzystania ze sprzętowego kodeka. To bardzo ważne, dziękuję za odpowiedź. – Andy

+0

W tym filmie jest dużo, jeśli dobrze pamiętam, istnieje sekcja o kategorii AudioSession, może tam coś znajdziesz. –

2

Miałem problem, gdy alarm przychodzi podczas uruchamiania aplikacji, użytkownik naciska przycisk zasilania urządzenia, co powoduje zasypianie. Następnie po wznowieniu ze stanu uśpienia mój AudioSessionSetActive kończy się niepowodzeniem z czymś w rodzaju "this audiosession type can't be used". Próbowałem dodać właściwość set audiosession przed AudioSessionSetActive(true) w Interruptlistener, ale bez powodzenia. końcu dodałem

retry(~1000 times :) 

ftw)

AudioSessionSetActive(true), 

i rozwiązać mój problem.

+0

Myślę, że nie udało mi się w pełni sprawić, by działało to w tamtych czasach, było to dość przypadkowe zachowanie. Później przełączyłem się na AVFoundation i AVSession, które wydają się działać. Szczerze myślę, że Apple miał błędy w SDK i wydaje mi się, że ten kod działa poprawnie na iOS 6, ale to tylko założenie. – Andy

Powiązane problemy