2011-10-27 40 views
8

Tôi đã cố gắng tìm ra những gì thực sự xảy ra trong nhiều tuần và tôi không biết tại sao tôi không thể tiếp tục phát lại sau khi bị gián đoạn, vì vậy có lẽ các bạn biết câu trả lời. AudioSessionSetActive (TRUE) luôn trả về '! Cat' là kAudioSessionIncompatibleCategory trong khi kích hoạt lại nếu ứng dụng của tôi phát ở chế độ nền và tôi đang ở trong ứng dụng khác. Mặc dù nó hoạt động tốt và tiếp tục phát lại nếu tôi bị gián đoạn khi đang ở trong ứng dụng của mình.AudioSessionSetActive không thành công sau khi bị gián đoạn

Mã gốc thực sự có tất cả các cuộc gọi AudioSession và AudioQueue được bao bọc trong các macro in OSStatus nếu nó có nghĩa là lỗi, nhưng tôi đã xóa nó để dễ đọc hơn. Ngoài ra, [tự tạm dừng] chỉ cần tắt tạm dừng, vì vậy về cơ bản nó gọi AudioQueueStart (audioQueue, NULL) trên upause nhưng nó không hoạt động ofcourse nếu AudioSession thất bại.

âm thanh đang phiên khởi tạo:

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

gián đoạn mã xử lý:

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

mã nguồn streamer này có thể được tìm thấy ở đây https://bitbucket.org/and/amaudiostreamer/src/122de41fe6c0/AMAudioStreamer/AMAudioStreamer/Classes/NxAudioStreamer.m nếu nó sẽ giúp đỡ bằng cách nào đó để giải quyết một vấn đề ..

Trả lời

0

Thử kích hoạt AudioSession ở nếu điều kiện khác là như sau:

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

Nhưng tôi tin rằng điều này có thể không hiệu quả vì trong trường hợp của tôi điều xảy ra là khi tôi ở chế độ nền, nó không nhận được bất kỳ phiên nào. Nhưng hãy thử phân tích số aurioTouch example của Apple và chỉ xem qua tệp AppDelegate và cố gắng phân tích phương pháp (void)rioInterruptionListener giải thích cùng một vấn đề.

Bạn có đang sử dụng Phát trực tiếp âm thanh không ?? sau đó tôi sẽ khuyên bạn nên đi qua question's answer của tôi, nơi mà một vấn đề của hàng đợi bắt đầu là giải quyết bằng cách xử lý các lỗi như được đưa ra trong câu trả lời của tôi.

Hy vọng điều này có thể hữu ích cho bạn.

+0

Như bạn mong đợi, nó không hoạt động và mang lại cho tôi cùng một lỗi theo cách thời trang hơn: "Không đặt được danh mục trên AVAudioSession. Không thể hoàn tất thao tác. (OSStatus error 560161140.)". Tôi sẽ cố gắng phân tích rioInterruptionListener .. Tôi nghĩ rằng tôi chỉ bỏ lỡ một số điều nhỏ nhặt. – Andy

+0

sau đó tôi tin rằng trước tiên bạn phải cố gắng điều trong câu trả lời câu hỏi của tôi. Nhưng ở đây sẽ có quá khó khăn để có được vấn đề chính xác. Bạn cần phải xác định nơi 'chính xác' bạn muốn sửa đổi mã. đây là một thách thức đối với tôi khi tôi đã làm ... Tốt nhất của may mắn cho bạn ... Hy vọng bạn sẽ có thể giải quyết vấn đề ... – DShah

0

kAudioSessionEndInterruption có thể hoặc không thể nhấn mã của bạn, đây không phải là cách đáng tin cậy để kiểm soát trạng thái phát của bạn, chỉ cần tắt phiên âm thanh trong mã của bạn, nó sẽ tiếp tục phiên sau khi nó có thể giành lại quyền kiểm soát, trong trường hợp của bạn, chỉ cần bình luận ra AudioSessionSetActive (FALSE) sẽ giúp bạn.

+0

Tôi thấy quan điểm của bạn, nhưng nó không giúp tôi để có được phiên âm thanh trở lại và tiếp tục phát lại: ( – Andy

0

Nếu bạn nhìn vào Listing 7-16 An interruption listener callback function trong Audio Session Programming Guide cookbook section, mẫu mã (mà có vẻ là phù hợp với tình hình của bạn, sử dụng kAudioSessionCategory_MediaPlayback) không thực sự thực hiện các cuộc gọi

AudioSessionSetActive(FALSE); 

trong trường hợp kAudioSessionBeginInterruption, và số

AudioSessionSetActive(TRUE); 

gọi trong trường hợp kAudioSessionEndInterruption. Tôi thực sự không nghĩ rằng bạn nên làm điều này. This post dường như cũng minh họa cho vấn đề này (nhận được kAudioSessionIncompatibleCategory). Điều gì xảy ra nếu bạn nhận xét cả hai cuộc gọi này?

Lý do khiến sự cố xảy ra khi ứng dụng của bạn chạy ngầm, không phải tiền cảnh là một bí ẩn. Bạn có lẽ nên theo dõi trạng thái (như bạn đang làm với NX_STATE_PLAY), sau đó có hai phương pháp khác nhau ([tự tạm dừng] và [tự chơi]), có lẽ là [tự tạm dừng] (toggling play state) được gọi là số lần bất ngờ.

+0

[tự tạm dừng] được gọi là hai lần duy nhất để AudioQueuePause khởi động bị gián đoạn và AudioQueueStart khi ngắt kết thúc, tôi đã kiểm tra nó, không có vấn đề ở đó. trong nhật ký của tôi: VERIFY_OSS AudioSessionSetActive (true) - '! cat' VERIFY_OSS AudioQueueStart (audioQueue, NULL) - -12985 – Andy

0

Tôi đã biết cách làm việc cho tôi, bạn có thể thử rủi ro của mình.

Trong chức năng

void _audioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState) 

loại bỏ

[(NxAudioStreamer*)inClientData handleInterruptionChangeToState:inInterruptionState]; 

không cần phải gọi handleInterruptionChangeToState khi bạn có thể trực tiếp xử lý nó trong audioSessionInterruptionListeneraudioSessionInterruptionListenerinInterruptionState như một tham số. Vì vậy, sửa đổi của bạn để 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

Tôi nghĩ mình đã từ bỏ điều này và sử dụng AVFoundation vì iOS 3 không còn quan trọng với tôi nữa. – Andy

3

Nếu bạn đang sử dụng API AudioQueue bạn cần phải thực hiện một số bước bổ sung mà phụ thuộc vào một số yếu tố. Tôi chưa bao giờ làm điều đó, vì vậy tôi sẽ để lại lời giải thích cho chuyên gia:
có video về chủ đề đó trong trang web của Nhà phát triển Apple bao gồm vấn đề chính xác đó. WWDC 2010 phiên 412 phát triển âm thanh cho hệ điều hành iPhone phần 1 khoảng 45 phút bạn đã có một lời giải thích khá tốt về vấn đề đó.

+0

Tôi vẫn không thể hiểu tại sao AudioSessionSetActive (true); trả về con mèo, có lẽ nó thậm chí không quan trọng nó trả về cái gì, tất cả những gì tôi phải làm chỉ tiếp tục phát lại. Vì vậy, về cơ bản tôi phải vứt bỏ và tái tạo AudioQueue trong khi sử dụng codec phần cứng. Điều này rất quan trọng, cảm ơn bạn đã trả lời. – Andy

+0

Có rất nhiều trong video đó, nếu tôi nhớ chính xác có một phần về thể loại AudioSession, có thể ở đó bạn sẽ tìm thấy một cái gì đó. –

2

Tôi gặp sự cố, khi Báo thức đến trong khi chạy ứng dụng, người dùng chỉ cần nhấn nút nguồn của thiết bị để nó chuyển sang chế độ ngủ. Sau đó, sau khi tiếp tục từ giấc ngủ của tôi AudioSessionSetActive không thành công với một cái gì đó như "this audiosession type can't be used". Tôi đã cố gắng thêm tài sản set audiosession trước AudioSessionSetActive(true) trong Danh sách gián đoạn, nhưng không có may mắn. Cuối cùng tôi đã thêm

retry(~1000 times :) 

ftw)

AudioSessionSetActive(true), 

và nó giải quyết vấn đề của tôi.

+0

Tôi nghĩ rằng tôi đã không hoàn toàn quản lý để làm cho nó hoạt động những ngày đó, đó là hành vi khá ngẫu nhiên. Sau đó tôi chuyển sang AVFoundation và AVSession có vẻ như đang hoạt động. Thành thật mà nói, tôi nghĩ rằng Apple đã có lỗi trong SDK của họ và tôi đoán mã này sẽ hoạt động đúng trên iOS 6, nhưng đó chỉ là giả định. – Andy

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