7

trong ứng dụng iOS của tôi, tôi đang cố gắng triển khai "vịt": trong khi ứng dụng của tôi phát một âm thanh "giống như lệnh", mọi nhạc nền phải được giảm âm lượng. Sau khi phát xong âm thanh, âm lượng nhạc sẽ trở về giá trị ban đầu.iOS AudioSessionSetActive() chặn chủ đề chính?

Khi được triển khai, vịt hoạt động như mong đợi. Tuy nhiên, khi tôi gọi AudioSessionSetActive (NO) trong audioPlayerDidFinishPlaying: để kết thúc việc quay phim, có một tạm dừng nhỏ trong bất kỳ cập nhật giao diện người dùng nào xảy ra tại thời điểm này. Điều này liên quan đến bản vẽ tùy chỉnh, cũng như cho ex. tự động cuộn văn bản và v.v.

Bây giờ, đây là câu hỏi:

Đây có phải là sự cố đã biết trong iOS6 không? Tôi đang chạy cùng một mã trên một iPod/iOS5, nơi tôi không thấy hành vi này. Hoặc tôi thiếu một cái gì đó từ mã? Có thể một trong các bạn đã gặp vấn đề tương tự và tìm ra giải pháp khả thi.

Cảm ơn rất nhiều sự ủng hộ của các bạn,

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

Bạn đã bao giờ tìm ra giải pháp cho vấn đề này chưa? Tôi đang gặp vấn đề tương tự. –

+0

Nếu tôi không gọi AudioSessionSetActive (NO) giao diện người dùng của tôi vẫn đáp ứng và không thả khung hình. Khi tôi gọi phương thức đó, sẽ mất khoảng 0,5 giây khi âm thanh đang phát. Nhưng, như bạn đã nói, nếu bạn không gọi nó, âm thanh vẫn bị dìm. –

Trả lời

3

Sau khi một số người đứng đầu gãi, và gỡ lỗi, tôi thấy câu trả lời cho câu hỏi này. Như câu hỏi ban đầu nói, để mang lại mức âm thanh trở lại sau khi vịt, bạn phải tắt phiên âm thanh.

Vấn đề là việc hủy kích hoạt phiên sẽ gây ra 0,5 giây trễ khi âm thanh đang phát, chặn chuỗi giao diện người dùng và khiến ứng dụng không phản hồi (trong trường hợp của tôi, bộ hẹn giờ mất 0,5 giây và cửa sổ).

Để giải quyết vấn đề, tôi thực hiện cuộc gọi để tắt hẹn giờ trên một chuỗi riêng biệt. Điều này giải quyết vấn đề chặn giao diện người dùng và cho phép âm thanh phát ra như mong đợi. Mã dưới đây cho thấy giải pháp. Lưu ý, đây là mã C# vì tôi đang sử dụng Xamarin, nhưng nó có thể dễ dàng được dịch sang Objective-C hoặc Swift cho kết quả tương tự:

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

tôi gọi ActivateAudioSession trước khi tôi dây lên AVAudioPlayer của tôi và một lần nghe nhạc của tôi được thực hiện chơi, tôi gọi DeactivateAudioSession (đó là cần thiết để mang lại mức âm thanh sao lưu). Bắt đầu quá trình hủy kích hoạt trên một chuỗi mới sẽ tăng mức âm thanh lên, nhưng không chặn giao diện người dùng.

+0

Chúng tôi có thể sử dụng hàng đợi công văn thay vì điều này với hàng đợi nền không? –

Các vấn đề liên quan