2013年1月8日 星期二

明明就 明明就 明明就播放了,怎麼會聽不到呢?

播放音樂,透過iOS的AVAudioPlayer物件,成為一件再簡單不過的事。以下為播放音樂的標準程序:


 NSString *path = [[NSBundle mainBundle] pathForResource:@"明明就.m4a" ofType:nil];
 NSURL *url = [NSURL fileURLWithPath:path ];
 AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
 [audioPlayer play];
說明:
(1) NSString *path = [[NSBundle mainBundle] pathForResource:@"明明就.m4a" ofType:nil];
      NSURL *url = [NSURL fileURLWithPath:path ];

取得周杰倫的最新主打歌”明明就”的檔案路徑,然後建立NSURL物件。

(2)  AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];

建立專長播放音樂的AVAudioPlayer物件audioPlayer,只要 透過檔案路徑的url點歌,它即可正確無誤的播出歌曲,完全不會忘詞。

(3)  [audioPlayer play];

開始播放

如此簡單的程序,彼得潘馬上寫了個測試程式,在畫面上加入周杰倫新專輯的封面圖片做為按鈕,在按鈕被點選時的Touch Up Inside event觸發呼叫method
  - (IBAction)playMusic:(id)sender, 而此method的定義當然就是剛剛那一段程式碼。



明明就 明明就 明明就播放了,怎麼會 怎麼會 怎麼會聽不到呢? 連前奏也不給我們聽。失戀已經夠難過了,更難過的是連失戀情歌都聽不到。難道連iPhone都如此無情嗎?

iPhone當然是有情有義呀。問題完全出在我們寫的程式碼裡,和iPhone無關。我們剛剛在playMusic: method裡宣告AVAudioPlayer物件, 因此它是一個local變數,它的生命週期將隨著method執行完畢而終結。iPhone CPU的快是名震天下的,此method不用一秒鐘的時間就執行完了,我們當然聽不到一丁點的音樂呀。

現在彼得潘在原來的[audioPlayer play];後加入以下程式碼,

    [NSThread sleepForTimeInterval:10];

此行程式碼將延長此method的執行時間,要10秒後此method才執行完畢。當我們再此執行App後,終於可以聽到前奏了,但是只維持了10秒,還來不及聽到周杰倫的歌聲。


為了聽到完整歌曲,我們是要把sleep的時間加大,變大到300秒嗎? 當然不是,這不是個好方法。尤其像這種失戀時聽的情歌,最好是24小時不間斷地重覆播放,我們永遠無法確定要傳入多大的數字,有些人可能失戀療傷只要一天,有些人卻需要一年365天一直聽”明明就”呀

一勞永逸的方法很簡單,我們只要將AVAudioPlayer物件宣告為物件的member,而不是local變數,即可讓此物件不會因method執行結束而跟著死去。在剛剛的例子裡,彼得潘將AVAudioPlayer物件宣告為負責主畫面的ViewController的member。

@interface ViewController : UIViewController
{
    AVAudioPlayer *audioPlayer ;
}

然後將ViewController的playMusic: method稍做修改

- (IBAction)playMusic:(id)sender {
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"明明就.m4a" ofType:nil];
    NSURL *url = [NSURL fileURLWithPath:path ];
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    audioPlayer.numberOfLoops = -1;
    [audioPlayer play];
    
}
說明:
(1)  audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];

audioPlayer不再是local變數,生命不再因playMusic: method執行結束而終結。

(2)  audioPlayer.numberOfLoops = -1;

將AVAudioPlayer物件的numberOfLoops設為負數時,音樂將不間斷地重覆播放,直到我們走出失戀情傷,結束App,才會停止音樂的播放。




沒有留言:

張貼留言