7

, "ördek yavrusu" uygulamasını uygulamaya çalışıyorum: Uygulamam kısa bir "komut benzeri" ses çalarken, herhangi bir arka plan müziği ses seviyesinde düşürülmeli. Sesi bitirdikten sonra, müzik sesi orijinal değerine geri dönmelidir. Uygulandığı gibi, ördekleme temel olarak beklendiği gibi çalışır. Ancak, audioPlayerDidFinishPlaying'de AudioSessionSetActive (NO) öğesini çağırdığımda: Örmeyi bitirmek için, bu zaman noktasında meydana gelen UI güncelleştirmelerinde küçük bir duraklama olur. Bu özel çizim yanı sıra, ex için içerir. otomatik metin kaydırma vb.iOS AudioSessionSetActive() ana iş parçacığını engelliyor mu? IOS uygulamasında

bu iOS6 bilinen bir sorun var mı:

Şimdi, işte soru? Bu kodu, bu davranışı görmediğim bir iPod/iOS5'te çalıştırıyorum. Yoksa koddan bir şey özlüyorum mu? Belki de biriniz aynı problemle karşılaşmış ve işe yarar bir çözüm bulmuş olabilirsiniz.

teşekkürler tür destek için bir sürü

Goetz

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 

    //... 

    NSError *err = nil; 
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&err]; 

    //... 

} 

- (void) playSound { 

    // Enable ducking of music playing in the background (code taken from the Breadcrumb iOS Sample) 
    UInt32 value = kAudioSessionCategory_MediaPlayback; 
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(value), &value); 

    // Required if using kAudioSessionCategory_MediaPlayback 
    value = YES; 
    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(value), &value); 

    UInt32 isOtherAudioPlaying = 0; 
    UInt32 size = sizeof(isOtherAudioPlaying); 
    AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &size, &isOtherAudioPlaying); 

    if (isOtherAudioPlaying) {   
     AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(value), &value); 
    } 

    AudioSessionSetActive(YES); 

    // Initialization of the AVAudioPlayer 
    NSString  *soundFileName = [[NSBundle mainBundle] pathForResource:@"Beep" ofType:@"caf"]; 
    NSURL     *soundFileURL  = [[NSURL alloc] initFileURLWithPath:soundFileURL]; 
    self.soundPlayer  = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil]; 
    [self.soundPlayer setDelegate:self]; 
    [self.soundPlayer setVolume:[80.0/100.0]; 
    [self.soundPlayer play]; 
} 


- (void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { 

    // Callback coming from the AVAudioPlayer 

    // This will block the main thread; however, it is necessary to disable ducking again 
    AudioSessionSetActive(NO);     
} 
+0

Bu soruna bir çözüm buldunuz mu? Bende aynı sorunu yaşıyorum. –

+0

AudioSessionSetActive (NO) öğesini çağırmazsam, UI'm yanıt vermeye devam eder ve kareleri düşürmez. Metod çağrısı yaptığımda, ses çaldığında yaklaşık 5 saniye sürer. Ama dediğin gibi, eğer sesini çağırmazsan, ses dalgalı kalır. –

cevap

3

bazı çizilmeye kafası ve ayıklama sonra, ben bu sorunun cevabını buldum. Asıl soru olarak, ses seviyesini ördükten sonra geri getirmek için ses oturumunu devre dışı bırakmanız gerekir.

Sorun, oturumu devre dışı bırakmanın, ses yürütülürken .5 saniye gecikmesine neden olur; bu, UI iş parçacığını engeller ve uygulamanın yanıt vermemesine neden olur (benim durumumda, bir zamanlayıcı, .5 saniye ve kesikler kaybeder).

Sorunu çözmek için, aramamın zamanlayıcıyı ayrı bir iş parçacığında devre dışı bırakmasını sağlıyorum. Bu, UI engelleme sorununu giderir ve sesin beklendiği gibi gitmesini sağlar. Aşağıdaki kod çözümü göstermektedir. Not, bu şimdiye Xamarin kullandığım için C# kodu, ancak kolayca aynı sonuç için Objective-C veya Swift çevrilen olabilir: Benim AVAudioPlayer kadar Tel öncesi ve benim oyuncu bir kez ActivateAudioSession diyoruz

 private void ActivateAudioSession() 
     { 
      var session = AVAudioSession.SharedInstance(); 
      session.SetCategory(AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.DuckOthers); 
      session.SetActive(true); 
     } 

     private void DeactivateAudioSession() 
     { 
      new System.Threading.Thread(new System.Threading.ThreadStart(() => 
       { 
        var session = AVAudioSession.SharedInstance(); 
        session.SetActive(false); 
       })).Start(); 
     } 

oyun bitti, ben deactivateAudioSession (ses seviyesini geri getirmek için gerekli olan) diyorum. Yeni bir iş parçacığı üzerindeki deaktivasyonun başlatılması ses seviyesini geri alır ancak UI'yi engellemez.

+0

Arka plan kuyruğu ile bunun yerine dağıtım kuyruğunu kullanabilir miyiz? –

İlgili konular