2013-06-23 56 views
5

Tôi không biết nguyên nhân của sự cố là gì, thời điểm trình phát cố gắng phát tệp âm thanh thử nghiệm mà nó gặp sự cố, nhưng chỉ trong trình mô phỏng. Trên thiết bị thực nó chạy tốt. Tôi đã dán mã dưới đây nếu bạn muốn có một cái nhìn, bao gồm các thông tin gỡ lỗi nhỏ nó mang lại cho tôi ... Nếu tôi không tìm thấy nguồn gốc của vụ tai nạn này, nó sẽ vượt qua thủ tục QA của Apple miễn là nó chạy tốt trên chính thiết bị?AVAudioPlayer chạy trên thiết bị iOS, gặp sự cố trong trình mô phỏng. Tôi có nên lo lắng không?

enter image description here

có thể điều này isa -> lớp chưa biết là vấn đề?

Nó bị treo trên [p play] trong phương pháp này:

-(void)startPlaybackForPlayer:(AVAudioPlayer*)p 
{ 

    if ([p play]) 
    { 
     [self updateViewForPlayerState:p]; 
    } 
    else 
     NSLog(@"Could not play %@\n", p.url); 
} 

-

#import "AudioPlayerViewController.h" 

@interface AudioPlayerViewController() 
{ 
    //AVAudioPlayer *player; 
} 
@property (nonatomic,strong) AVAudioPlayer *player; 

@end 

@implementation AudioPlayerViewController 



-(void)updateCurrentTimeForPlayer:(AVAudioPlayer *)p 
{ 
    self.currentTime.text = [NSString stringWithFormat:@"%d:%02d", (int)p.currentTime/60, (int)p.currentTime % 60, nil]; 
    self.progressBar.value = p.currentTime; 
} 

- (void)updateCurrentTime 
{ 
    [self updateCurrentTimeForPlayer:self.player]; 
} 

- (void)updateViewForPlayerState:(AVAudioPlayer *)p 
{ 
    [self updateCurrentTimeForPlayer:p]; 

    if (self.updateTimer) 
     [self.updateTimer invalidate]; 

    if (p.playing) 
    { 
     [self.playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal]; 
     //[lvlMeter_in setPlayer:p]; 
     self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(updateCurrentTime) userInfo:p repeats:YES]; 
    } 
    else 
    { 
     [self.playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal]; 
     //[lvlMeter_in setPlayer:nil]; 
     self.updateTimer = nil; 
    } 

} 

- (void)updateViewForPlayerStateInBackground:(AVAudioPlayer *)p 
{ 
    [self updateCurrentTimeForPlayer:p]; 

    if (p.playing) 
    { 
     [self.playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal]; 
    } 
    else 
    { 
     [self.playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal]; 
    } 
} 

-(void)updateViewForPlayerInfo:(AVAudioPlayer*)p 
{ 
    self.duration.text = [NSString stringWithFormat:@"%d:%02d", (int)p.duration/60, (int)p.duration % 60, nil]; 
    self.progressBar.maximumValue = p.duration; 
    self.volumeSlider.value = p.volume; 
} 

- (void)rewind 
{ 
    //AVAudioPlayer *p = rewTimer.userInfo; 
    //p.currentTime-= SKIP_TIME; 
    //[self updateCurrentTimeForPlayer:p]; 
} 

- (void)ffwd 
{ 
    //AVAudioPlayer *p = ffwTimer.userInfo; 
    //p.currentTime+= SKIP_TIME; 
    //[self updateCurrentTimeForPlayer:p]; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    NSLog(@"### AudioPlayerViewController Initiallized"); 


    playBtnBG = [UIImage imageNamed:@"play.png"]; // Retain, maybe make strong 
    pauseBtnBG = [UIImage imageNamed:@"pause.png"]; 

    [self.playButton setImage:playBtnBG forState:UIControlStateNormal]; 

    [self registerForBackgroundNotifications]; 

    self.updateTimer = nil; 
    //rewTimer = nil; 
    //ffwTimer = nil; 

    self.duration.adjustsFontSizeToFitWidth = YES; 
    self.currentTime.adjustsFontSizeToFitWidth = YES; 
    self.progressBar.minimumValue = 0.0; 

    // Load the the sample file, use mono or stero sample 
#warning samplefile does not exist 
    NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:@"bubbles" ofType:@"m4a"]]; 
    //NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:@"sample2ch" ofType:@"m4a"]]; 

    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil]; 
    if (self.player) 
    { 
     self.fileName.text = [NSString stringWithFormat: @"%@ (%d ch.)", [[self.player.url relativePath] lastPathComponent], self.player.numberOfChannels, nil]; 
     [self updateViewForPlayerInfo:self.player]; 
     [self updateViewForPlayerState:self.player]; 
     self.player.numberOfLoops = 1; 
     self.player.delegate = self; 
    } 

    OSStatus result = AudioSessionInitialize(NULL, NULL, NULL, NULL); 
    if (result) 
     NSLog(@"Error initializing audio session! %ld", result); 

    [[AVAudioSession sharedInstance] setDelegate: self]; 
    NSError *setCategoryError = nil; 
    [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError]; 
    if (setCategoryError) 
     NSLog(@"Error setting category! %@", setCategoryError); 

#warning did change here - migth cause bug 
    //result = AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, RouteChangeListener, (__bridge void *)(self)); 
    if (result) 
     NSLog(@"Could not add property listener! %ld", result); 





    /* 
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; 
    [[AVAudioSession sharedInstance] setActive: YES error: nil]; 

    self.player.delegate = self; 
    [self.player prepareToPlay]; 
    [self playAudio]; 
    */ 
} 

-(void)pausePlaybackForPlayer:(AVAudioPlayer*)p 
{ 
    [p pause]; 
    [self updateViewForPlayerState:p]; 
} 

-(void)startPlaybackForPlayer:(AVAudioPlayer*)p 
{ 

    if ([p play]) 
    { 
     [self updateViewForPlayerState:p]; 
    } 
    else 
     NSLog(@"Could not play %@\n", p.url); 
} 

- (IBAction)playButtonPressed:(UIButton *)sender 
{ 
    if (self.player.playing == YES) 
     [self pausePlaybackForPlayer: self.player]; 
    else 
     [self startPlaybackForPlayer: self.player]; 
} 

- (IBAction)rewButtonPressed:(UIButton *)sender 
{ 
    /* 
    if (rewTimer) [rewTimer invalidate]; 
    rewTimer = [NSTimer scheduledTimerWithTimeInterval:SKIP_INTERVAL target:self selector:@selector(rewind) userInfo:player repeats:YES]; 
    */ 
} 

- (IBAction)rewButtonReleased:(UIButton *)sender 
{ 
    /* 
    if (rewTimer) [rewTimer invalidate]; 
    rewTimer = nil; 
    */ 
} 

- (IBAction)ffwButtonPressed:(UIButton *)sender 
{ 
    /* 
    if (ffwTimer) [ffwTimer invalidate]; 
    ffwTimer = [NSTimer scheduledTimerWithTimeInterval:SKIP_INTERVAL target:self selector:@selector(ffwd) userInfo:player repeats:YES]; 
    */ 
} 

- (IBAction)ffwButtonReleased:(UIButton *)sender 
{ 
    /* 
    if (ffwTimer) [ffwTimer invalidate]; 
    ffwTimer = nil; 
    */ 
} 

- (IBAction)volumeSliderMoved:(UISlider *)sender 
{ 
    self.player.volume = [sender value]; 
} 

- (IBAction)progressSliderMoved:(UISlider *)sender 
{ 
    self.player.currentTime = sender.value; 
    [self updateCurrentTimeForPlayer:self.player]; 
} 



#pragma mark AudioSession handlers 
/** 
void RouteChangeListener( void *     inClientData, 
         AudioSessionPropertyID inID, 
         UInt32     inDataSize, 
         const void *   inData) 
{ 
    avTouchController* This = (avTouchController*)inClientData; 

    if (inID == kAudioSessionProperty_AudioRouteChange) { 

     CFDictionaryRef routeDict = (CFDictionaryRef)inData; 
     NSNumber* reasonValue = (NSNumber*)CFDictionaryGetValue(routeDict, CFSTR(kAudioSession_AudioRouteChangeKey_Reason)); 

     int reason = [reasonValue intValue]; 

     if (reason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) { 

      [This pausePlaybackForPlayer:This.player]; 
     } 
    } 
}*/ 

#pragma mark AVAudioPlayer delegate methods 

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)p successfully:(BOOL)flag 
{ 
    if (flag == NO) 
     NSLog(@"Playback finished unsuccessfully"); 

    [p setCurrentTime:0.]; 
    if (self.inBackground) 
    { 
     [self updateViewForPlayerStateInBackground:p]; 
    } 
    else 
    { 
     [self updateViewForPlayerState:p]; 
    } 
} 

- (void)playerDecodeErrorDidOccur:(AVAudioPlayer *)p error:(NSError *)error 
{ 
    NSLog(@"ERROR IN DECODE: %@\n", error); 
} 

// we will only get these notifications if playback was interrupted 
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)p 
{ 
    NSLog(@"Interruption begin. Updating UI for new state"); 
    // the object has already been paused, we just need to update UI 
    if (self.inBackground) 
    { 
     [self updateViewForPlayerStateInBackground:p]; 
    } 
    else 
    { 
     [self updateViewForPlayerState:p]; 
    } 
} 

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)p 
{ 
    NSLog(@"Interruption ended. Resuming playback"); 
    [self startPlaybackForPlayer:p]; 
} 

#pragma mark background notifications 
- (void)registerForBackgroundNotifications 
{ 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(setInBackgroundFlag) 
               name:UIApplicationWillResignActiveNotification 
               object:nil]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(clearInBackgroundFlag) 
               name:UIApplicationWillEnterForegroundNotification 
               object:nil]; 
} 

- (void)setInBackgroundFlag 
{ 
    self.inBackground = true; 
} 

- (void)clearInBackgroundFlag 
{ 
    self.inBackground = false; 
} 










- (void)playAudio 
{ 
    // Move operation to new thread 
    dispatch_queue_t playAudiofile = dispatch_queue_create("play audiofile", NULL); 
    dispatch_async(playAudiofile, ^{ 
     NSLog(@"Playing audiofile in new thread: %@", self.audiofile); 
     NSAssert(![self.audiofile isEqualToString:@""], @"audiofile must be specified."); 

     NSError *audioError; 
     NSString *soundFilePath = [[NSBundle mainBundle]pathForResource:self.audiofile ofType:@"mp3"]; 
     NSAssert(soundFilePath != NULL, @"Sound File Not found"); 
     NSURL *soundFileURL = [NSURL URLWithString:soundFilePath]; 

     self.player = [[AVAudioPlayer alloc]initWithContentsOfURL:soundFileURL error:&audioError]; 
     [self.player play]; 
    }); 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

frame #0: 0x020b4b54 libc++abi.dylib`__cxa_throw 
frame #1: 0x0e215a41 AudioCodecs`ACBaseCodec::GetProperty(unsigned long, unsigned long&, void*) + 757 
frame #2: 0x0e237618 AudioCodecs`ACMP4AACBaseDecoder::GetProperty(unsigned long, unsigned long&, void*) + 2458 
frame #3: 0x0e235b83 AudioCodecs`ACMP4AACLowComplexityDecoder::GetProperty(unsigned long, unsigned long&, void*) + 565 
frame #4: 0x0e28d4b4 AudioCodecs`GetProperty(void*, unsigned long, unsigned long*, void*) + 47 
frame #5: 0x001347a8 AudioToolbox`AudioCodecGetProperty + 88 
frame #6: 0x000392db AudioToolbox`CodecConverter::CheckInitialize(void const*, unsigned long) + 523 
frame #7: 0x00038f34 AudioToolbox`CodecConverter::CodecConverter(OpaqueAudioComponent*&, OpaqueAudioComponentInstance*, StreamDescPair const&, StreamDescPair const&, bool, AudioConverterPrimeInfo const&) + 676 
frame #8: 0x00038c7e AudioToolbox`CodecConverter::CodecConverter(OpaqueAudioComponent*&, OpaqueAudioComponentInstance*, StreamDescPair const&, StreamDescPair const&, bool, AudioConverterPrimeInfo const&) + 62 
frame #9: 0x0003ddf7 AudioToolbox`CodecDecoderFactory::BuildCodecConverterChain(StreamDescPair const&, ChainBuildSettings const&, AudioConverterChain*, PCMConverterFactory*) + 631 
frame #10: 0x0002647c AudioToolbox`ConverterRegistry::CreateConverter(StreamDescPair const&, AudioConverterChain**, unsigned long, AudioClassDescription const*) + 204 
frame #11: 0x00019ba0 AudioToolbox`_AudioConverterNewInternal + 352 
frame #12: 0x00060a00 AudioToolbox`AudioQueueObject::ConverterConnection::BuildConverter() + 416 
frame #13: 0x000607e2 AudioToolbox`AudioQueueObject::ConverterConnection::ConverterConnection(AudioQueueObject&, long&) + 130 
frame #14: 0x000620bc AudioToolbox`AudioQueueObject::IONodeConnection::GetConverterConnection_Init(long&) + 60 
frame #15: 0x00065803 AudioToolbox`AudioQueueObject::SetProperty(unsigned long, CADeserializer&) + 1123 
frame #16: 0x0008c44a AudioToolbox`AQServer_SetProperty + 106 
frame #17: 0x00092276 AudioToolbox`AudioQueueSetProperty + 374 
frame #18: 0x004c1d2b AVFoundation`AVAudioPlayerCpp::allocAudioQueue() + 683 
frame #19: 0x004c13be AVFoundation`AVAudioPlayerCpp::prepareToPlayQueue() + 26 
frame #20: 0x004bfebe AVFoundation`AVAudioPlayerCpp::prepareToPlay() + 84 
frame #21: 0x004129f7 AVFoundation`-[AVAudioPlayer prepareToPlay] + 59 
frame #22: 0x00006b7e SteinerAudio`-[AudioPlayerViewController viewDidLoad](self=0x07ad3cf0, _cmd=0x00b98a77) + 3694 at AudioPlayerViewController.mm:160 
frame #23: 0x006c71c7 UIKit`-[UIViewController loadViewIfRequired] + 536 
frame #24: 0x006c7232 UIKit`-[UIViewController view] + 33 
frame #25: 0x006c74da UIKit`-[UIViewController contentScrollView] + 36 
frame #26: 0x006de8e5 UIKit`-[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 36 
frame #27: 0x006de9cb UIKit`-[UINavigationController _layoutViewController:] + 43 
frame #28: 0x006dec76 UIKit`-[UINavigationController _updateScrollViewFromViewController:toViewController:] + 254 
frame #29: 0x006ded71 UIKit`-[UINavigationController _startTransition:fromViewController:toViewController:] + 72 
frame #30: 0x006df89b UIKit`-[UINavigationController _startDeferredTransitionIfNeeded:] + 386 
frame #31: 0x006dfe93 UIKit`-[UINavigationController pushViewController:transition:forceImmediate:] + 1030 
frame #32: 0x006dfa88 UIKit`-[UINavigationController pushViewController:animated:] + 62 
frame #33: 0x00a3be63 UIKit`-[UIStoryboardPushSegue perform] + 1111 
frame #34: 0x00a2db99 UIKit`-[UIStoryboardSegueTemplate _perform:] + 174 
frame #35: 0x00a2dc14 UIKit`-[UIStoryboardSegueTemplate perform:] + 115 
frame #36: 0x00695249 UIKit`-[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1134 
frame #37: 0x006954ed UIKit`-[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 201 
frame #38: 0x0109f5b3 Foundation`__NSFireDelayedPerform + 380 
frame #39: 0x0199f376 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22 
frame #40: 0x0199ee06 CoreFoundation`__CFRunLoopDoTimer + 534 
frame #41: 0x01986a82 CoreFoundation`__CFRunLoopRun + 1810 
frame #42: 0x01985f44 CoreFoundation`CFRunLoopRunSpecific + 276 
frame #43: 0x01985e1b CoreFoundation`CFRunLoopRunInMode + 123 
frame #44: 0x028557e3 GraphicsServices`GSEventRunModal + 88 
frame #45: 0x02855668 GraphicsServices`GSEventRun + 104 
frame #46: 0x005e5ffc UIKit`UIApplicationMain + 1211 
frame #47: 0x0000237d SteinerAudio`main(argc=1, argv=0xbffff3a0) + 141 at main.m:16 
+0

nó bị rơi ở đâu ???? –

+0

Tôi cho rằng bạn sử dụng ARC? Bạn có thể gửi một traceback của vụ tai nạn (loại 'bt' trong giao diện điều khiển LLDB)? Một vấn đề phổ biến là đối tượng đại biểu được gọi sau khi nó đã được deallocated (nó là yếu tham chiếu). – Krumelur

+0

@Krumelur Chắc chắn! –

Trả lời

9

Disable C++/Tất cả các điểm break ngoại lệ trong XCode. Hoặc chỉnh sửa điểm ngắt và đặt nó thành chỉ targetC.

+0

Tôi không thể tin rằng điều này ... vô hiệu hóa "Tất cả ngoại lệ" xử lý, và nó hoạt động. Cảm ơn bạn sẽ không đoán được trong một triệu năm. – n13

+1

Có thể sử dụng ngoại lệ C++ để điều khiển luồng chương trình. Đó là lý do tại sao ông ứng dụng không bị rơi nhưng ngoại lệ bị bắt. –

+0

Cảm ơn bạn có ý nghĩa hoàn hảo. Tôi có nghĩa là nó lame. Nhưng nó có ý nghĩa. Có thể XCode có thể được thiết lập để chỉ bắt các ngoại lệ chưa được nắm bắt. – n13

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