AudioSessionSetActive kesintiden sonra başarısız oluyor

Haftalar boyunca gerçekte ne olduğunu anlamaya çalışıyordum ve neden ara vermeden sonra oynatmaya devam edemediğim konusunda hiçbir fikrim yok, muhtemelen siz de bir cevap biliyorsunuz. SesSessionSetActive (TRUE), uygulamanızın arka planda oynatılması durumunda yeniden aktivasyon yaparken kAudioSessionIncompatibleCategory olan '! Cat' öğesini döndürür ve farklı bir uygulamadayım. Her ne kadar iyi çalışıyor ve uygulamamdayken kesintiye uğrarsam oynatmaya devam ediyor.

Orijinal kod aslında, hata anlamına geldiğinde OSStatus'u basan makrolara sarılmış tüm AudioSession ve AudioQueue çağrılarına sahiptir, ancak daha iyi okunabilirlik için onu kaldırdım. Ayrıca, [otomatik duraklama] sadece duraklatmayı değiştirir, bu nedenle temelde AudioQueueStart (audioQueue, NULL) işlevini upause olarak çağırır, ancak AudioSession başarısız olursa, bu işlev çalışmaz.

Ses Oturumu başlatma kodu:

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

Kesinti işleyici kodu:

- (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");
    }
}

Bu flama kaynak kodu burada bulunabilir https://bitbucket .org/ve/amaudiostreamer/src/122de41fe6c0/AMAudioStreamer/AMAudioStreamer/Sınıflar/NxAudioStreamer.m Bir sorunu çözmek için bir şekilde yardımcı olacaksa ..

8

6 cevap

AudioQueue API'sini kullanıyorsanız, bazı faktörlere bağlı olarak bazı ekstra adımlar atmanız gerekir. Bunu hiç yapmadım, bu yüzden açıklamayı uzmana bırakacağım:
Apple Developer web sitesinde söz konusu sorunun tamamını kapsayan bir video var. WWDC 2010 oturumu 412 45 dakika içinde iPhone OS bölüm 1 için Ses Geliştirme bu konuda oldukça iyi bir açıklama var.

3
katma
Bu videoda çok fazla şey var, doğru hatırlıyorsam AudioSession kategorisinde bir bölüm var, belki orada bir şeyler bulacaksınız.
katma yazar Vincent Bernier, kaynak
Hala neden AudioSessionSetActive (true); kedi döndürür, muhtemelen ne döndürdüğü önemli değil, sadece oynatmaya devam etmem gerekiyor. Bu yüzden temelde donanım codec'i kullanırken AudioQueue'yi imha etmek ve yeniden oluşturmak zorundayım. Bu çok önemlidir, cevabınız için teşekkürler.
katma yazar Andy, kaynak

Bir problem yaşadım, Alarm uygulama sırasında geldiğinde, kullanıcı sadece cihaz güç düğmesine basarak uykuya geçiyor. Ardından, uykudan çıktıktan sonra AudioSessionSetActive , bu audiosession türü kullanılamaz gibi bir şeyle başarısız olur. Interruptionlistener'da AudioSessionSetActive (true) 'dan önce audiosession set özelliğini eklemeyi denedim, ancak şans yok. Sonunda ekledim

retry(~1000 times :) 

ftw)

AudioSessionSetActive(true), 

ve benim problemimi çözdü.

2
katma
O günlerde çalışmayı tamamen başaramadığımı düşünüyorum, oldukça rastgele bir davranıştı. Daha sonra çalışmakta olan AVFoundation ve AVSession'a geçtim. Dürüst olmak gerekirse, Apple'ın SDK'sında hatalar olduğunu ve bu kodun iOS 6'da düzgün bir şekilde çalışacağını sanıyorum, ancak sadece varsayım.
katma yazar Andy, kaynak

Aşağıdaki gibi else if koşullarında AudioSession'ı etkinleştirmeyi deneyin:

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");

Ama bunun işe yaramayacağına inanıyorum çünkü benim durumumda ne olduysa arka planda olduğum zaman herhangi bir seans almıyordu. Ancak, Apple'ın aurioTouch örneğini analiz etmeye çalışın. ve sadece AppDelegate dosyasından geçip aynı soruyu açıklayan (void) rioInterruptionListener yöntemini çözümlemeye çalışın.

Canlı Ses Akışı kullanıyor musunuz? daha sonra, kuyruğa başlama sorununun çözüldüğü sorunun cevabını geçirmenizi öneririz. Cevabımda verilen hatayı ele alarak.

Umarım ikisinden biri size yardımcı olabilir.

0
katma
o zaman ben öncelikle sorunun cevabındaki şeyi denemen gerektiğini düşünüyorum. Ama burada kesin sorunu çözmek için çok zor olacak. Kodu değiştirmek istediğiniz tam olarak yerini belirlemelisiniz. Yaptığım zaman bu benim için bir meydan okuma oldu ... Şansın en iyisi ... Umarım sorunu çözebilirsin ...
katma yazar DShah, kaynak
Beklediğiniz gibi çalışmıyor ve aynı hatayı daha moda bir şekilde veriyor: "AVAudioSession'da kategori belirlenemedi. İşlem tamamlanamadı. (OSStatus error 560161140.)". Ben rioInterruptionListener analiz etmeye çalışacağız .. Ben sadece küçük bir şey özledim düşünüyorum.
katma yazar Andy, kaynak

Benim için nasıl çalıştığını biraz anladım, riskini deneyebilirsin.

İşlevinde

void _audioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState)

Kaldır

[(NxAudioStreamer*)inClientData handleInterruptionChangeToState:inInterruptionState];

no need to call handleInterruptionChangeToState when you can directly handle it in audioSessionInterruptionListener because audioSessionInterruptionListener has inInterruptionState as a parameter. So modify your to 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
katma
Ben bu konuda vazgeçtim ve iOS 3 artık benim için önemli değil beri AVFoundation kullanın. Yine de cevap için teşekkürler.
katma yazar Andy, kaynak

Liste 7-16'da bir kesinti dinleyicisi geri arama işlevi 'e bakarsanız, Sesli Oturum Programlama Kılavuzu yemek kitabı bölümü , kod örneği (durumunuzla uyumlu gibi görünüyor, kAudioSessionCategory_MediaPlayback kullanarak) aslında gerçekleştirmiyor

AudioSessionSetActive(FALSE);

kAudioSessionBeginInterruption durumunda arama yapın ve

AudioSessionSetActive(TRUE);

kAudioSessionEndInterruption durumunda arayın. Bunu yapman gerektiğini gerçekten düşünmüyorum. Bu gönderi Bu problemi de açıklıyor gibi görünüyor (kAudioSessionIncompatibleCategory). Bu iki çağrıyı da açıklarsanız ne olur?

Uygulamanız arka planda, ön planda değilken bir gizem olduğunda sorun oluşması nedenidir. Belki de durumu takip etmelisiniz (NX_STATE_PLAY ile yaptığınız gibi), daha sonra iki farklı yönteme sahip olmalısınız ([duraklama] ve [kendi kendine oynatma]), belki de [kendini duraklatma] (oyun durumu arasında geçiş) beklenmedik sayıda kez.

0
katma
[self duraklat] iki kez çağrıldı, böylece temelde AudioQueuePause kesinti başlangıcında ve AudioQueueStart kesinti sonunda, kontrol ettim, orada problem yok. AudioSessionSetActive (FALSE) kodunu kodumdan kaldırdım ve hala bu şeyleri günlüğümde alıyorum: VERIFY_OSS AudioSessionSetActive (true) - '! Cat' VERIFY_OSS AudioQueueStart (audioQueue, NULL) - -12985
katma yazar Andy, kaynak

kAudioSessionEndInterruption kodunuza çarpabilir veya girmeyebilir, oyun durumlarınızı kontrol etmenin güvenilir bir yolu değildir, sadece ses oturumunu kodunuzda kapatmayın, sizin durumunuzda tekrar kontrolü ele geçirdikten sonra oturuma devam edecektir. Sadece AudioSessionSetActive (FALSE) yorum size yardımcı olacaktır.

0
katma
Senin noktasını görüyorum, ama ses oturumunu geri almam ve oynatmaya devam etmeme yardımcı olmuyor :(
katma yazar Andy, kaynak