2010-09-22 64 views
2

我正在使用iOS SDK中的AVAudioPlayer在每次點擊tableView行時播放短音。 我已經手動在每一行的按鈕上啓動了@selector,它啓動了方法playSound:(id)receiver {}。從接收器我得到聲音的URL,所以我可以播放它。iPhone AVAudioPlayer應用程序在第一次播放時凍結

這種方法看起來像這樣:

- (void)playSound:(id)sender { 
    [audioPlayer prepareToPlay]; 
    UIButton *audioButton = (UIButton *)sender; 
    [audioButton setImage:[UIImage imageNamed:@"sound_preview.png"] forState:UIControlStateNormal]; 
    NSString *soundUrl = [[listOfItems objectForKey:[NSString stringWithFormat:@"%i",currentPlayingIndex]] objectForKey:@"sound_url"]; 

    //here I get mp3 file from http url via NSRequest in NSData 
    NSData *soundData = [sharedAppSettingsController getSoundUrl:defaultDictionaryID uri:soundUrl]; 
    NSError *error; 
    audioPlayer = [[AVAudioPlayer alloc] initWithData:soundData error:&error]; 
    audioPlayer.numberOfLoops = 0; 
    if (error) { 
     NSLog(@"Error: %@",[error description]); 
    } 
    else { 
     audioPlayer.delegate = self; 
     [audioPlayer play]; 
    } 
} 

一切正常,除了一些聲音的第一齣戲精。應用程序凍結約2秒鐘,並播放聲音。第二和其他聲音播放正好在點擊聲音按鈕後正常工作。

我想知道爲什麼在應用程序啓動時第一次播放時會停留約2秒?

如果你認爲我拿錯解,請告訴我正確的選擇。

問候

回答

2

從您的代碼片段中,audioPlayer必須是ivar,對不對?

在該方法的頂部,您調用-prepareToPlay對現有的audioPlayer實例(可能爲零,至少在第一次通過時)。

在後面的方法中,您將用現有的音頻播放器替換爲全新的AVAudioPlayer實例。之前的-prepareToPlay被浪費了。而且,每個新的AVAudioPlayer都在泄漏內存。

而不是緩存聲音數據或URL,我會嘗試創建一個AVAudioPlayer對象的緩存,每個聲音一個。在-playSound:方法中,獲取表格行的相應音頻播放器的引用,並獲取-play

您可以使用-tableView:cellForRowAtIndexPath:作爲適當的點來獲取該行的AVAudioPlayer實例,可能會延遲創建實例並將其緩存到那裏。

您可以嘗試-tableView:willDisplayCell:forRowAtIndexPath:作爲您在該行的AVAudioPlayer實例上調用-prepareToPlay的點。

或者你可以只做-tableView:cellForRowAtIndexPath:的準備。試驗一下,看看哪個效果最好。

+0

謝謝,我會試試這個... – 2010-09-23 08:38:26

0

這有時會發生在模擬器對我來說太。一切似乎都在設備上正常工作。你在實際的硬件上測試過嗎?

+0

你說得對。可能我應該在真實的設備上測試這個。感謝您的建議... – 2010-09-23 08:39:42

2

確定你是否在功能上異步獲取數據..

NSData *soundData = [sharedAppSettingsController getSoundUrl:defaultDictionaryID uri:soundUrl]; 

如果您收到異步執行將被阻止,直到它會得到數據。

+0

這也應該是一個問題。我會盡力改變這種... – 2010-09-23 08:39:14

1

如果您的音頻小於30秒的長度長,是線性PCM或IMA4格式,並且被打包成的.caf,.wav或.AIFF您可以使用系統聲音:

導入AudioToolbox框架

在你的。.h文件創建此變量:

SystemSoundID mySound; 

在您.m文件中實現它的init方法:

-(id)init{ 
if (self) { 
//Get path of VICTORY.WAV <-- the sound file in your bundle 
NSString* soundPath = [[NSBundle mainBundle] pathForResource:@"VICTORY" ofType:@"WAV"]; 
//If the file is in the bundle 
if (soundPath) { 
    //Create a file URL with this path 
    NSURL* soundURL = [NSURL fileURLWithPath:soundPath]; 

    //Register sound file located at that URL as a system sound 
    OSStatus err = AudioServicesCreateSystemSoundID((CFURLRef)soundURL, &mySound); 

     if (err != kAudioServicesNoError) { 
      NSLog(@"Could not load %@, error code: %ld", soundURL, err); 
     } 
    } 
} 
return self; 
} 

在你IBAction爲方法,你打電話的聲音與此:

AudioServicesPlaySystemSound(mySound); 

這適用於我,播放聲音非常接近當按鈕被按下。希望這可以幫助你。

相關問題