2012-04-17 92 views
2

我試圖播放和MP3文件,我從我的服務器檢索我的應用程序執行以下操作:iOS的 - 在嘗試播放MP3文件失敗

- (IBAction)play:(UIButton *)sender { 
    dispatch_queue_t downloadQueue = dispatch_queue_create("audio data downloader", NULL); 
    dispatch_async(downloadQueue, ^{ 
     NSURL *audioURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@/%@.mp3", FONYK_FILES_URL, [self.voicenote valueForKeyPath:@"Fonyker.fonykid"], [self.voicenote valueForKeyPath:@"Voicenote.vnid"]]]; 
     NSData *audioData = [NSData dataWithContentsOfURL:audioURL]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      NSError *error = nil; 
      AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData:audioData error:&error]; 
      NSLog(@"%@", error); 
      audioPlayer.delegate = self; 
      [audioPlayer play]; 
     }); 
    }); 
} 

播放失敗,意味着沒有發出聲音,我調試一步我的應用程序一步時得到這樣的輸出:

Catchpoint 2 (exception thrown).Single stepping until exit from function __cxa_throw, which has no line number information. 

當我的NSLog在模擬器中的錯誤此出現:

Error Domain=NSOSStatusErrorDomain Code=-50 "The operation couldn’t be completed. (OSStatus error -50.)" 

沒有別的表明它只是失敗,任何想法?

UPDATE:修改我的代碼按J_D答案,並在模擬器得到這個:

Error loading /System/Library/Extensions/AudioIPCDriver.kext/Contents/Resources/AudioIPCPlugIn.bundle/Contents/MacOS/AudioIPCPlugIn: dlopen(/System/Library/Extensions/AudioIPCDriver.kext/Contents/Resources/AudioIPCPlugIn.bundle/Contents/MacOS/AudioIPCPlugIn, 262): Symbol not found: ___CFObjCIsCollectable 
    Referenced from: /System/Library/Frameworks/Security.framework/Versions/A/Security 
    Expected in: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation 
in /System/Library/Frameworks/Security.framework/Versions/A/Security 
2012-04-17 15:03:43.054 Fonyk[8238:15307] Error loading /System/Library/Extensions/AudioIPCDriver.kext/Contents/Resources/AudioIPCPlugIn.bundle/Contents/MacOS/AudioIPCPlugIn: dlopen(/System/Library/Extensions/AudioIPCDriver.kext/Contents/Resources/AudioIPCPlugIn.bundle/Contents/MacOS/AudioIPCPlugIn, 262): Symbol not found: ___CFObjCIsCollectable 
    Referenced from: /System/Library/Frameworks/Security.framework/Versions/A/Security 
    Expected in: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation 
in /System/Library/Frameworks/Security.framework/Versions/A/Security 

UPDATE:真正的問題我沒有創建和AVAudioSession例如設置在我的代碼回放,這樣做與我接受的更正答案一起工作。

回答

5

我看到至少有一個問題與您的代碼,用線

NSURL *fileURL = [NSURL URLWithString:filePath]; 

它試圖用一個本地文件路徑創建一個URL。它可能會返回零。你應該改用:

NSURL *fileURL = [NSURL fileURLWithPath:filePath]; 

現在,即使是這樣,你的代碼也不會運行(我試過了,得到了同樣的錯誤)。我自己並沒有使用過AVAudioPlayer,所以我不知道你爲什麼會發生特定的錯誤。

然而,我用你的代碼嘗試一個非常小的例子,我能正確播放MP3。相反,數據下載到文件,從文件加載AVAudioPlayer的,你可以使用AVAudioPlayer的initWithData構造:

AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData:[NSData dataWithContentsOfURL:audioURL] error:&error]; 

這工作在我身邊很好,假設audioURL是有效的。我指着一個MP4我爲我的測試服務器上。

所以用這個initWithData重寫你的代碼給出:

- (IBAction)play:(UIButton *)sender { 
    dispatch_queue_t downloadQueue = dispatch_queue_create("audio data downloader", NULL); 
    dispatch_async(downloadQueue, ^{ 
     NSURL *audioURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@/%@.mp3", FONYK_FILES_URL, [self.voicenote valueForKeyPath:@"Fonyker.fonykid"], [self.voicenote valueForKeyPath:@"Voicenote.vnid"]]]; 
     NSData *audioData = [NSData dataWithContentsOfURL:audioURL]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      NSError *error = nil; 
      AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData:audioData error:&error]; 
      NSLog(@"%@", error); 
      audioPlayer.delegate = self; 
      [audioPlayer play]; 
     }); 
    }); 
} 

正如最後一個音符:您正在下載您之前就開始播放整個文件,這可能需要一段時間,消耗了大量的堆(或存儲如果你把它保存在一個文件)

如果要傳輸,你可以使用的MPMoviePlayerController,但你不重視視圖到您的視圖層次。這樣,您將只擁有音頻,並且不會更改應用程序的任何視覺效果。

一個例子是:

NSURL *audioURL = [NSURL URLWithString:@"MY_MP3_URL"]; 
MPMoviePlayerController* player = [[MPMoviePlayerController alloc] initWithContentURL:audioURL]; 
[player play]; 

同樣,就在我身邊,在模擬器,它工作正常。

不要忘記釋放播放器。您也可以爲代表註冊重要通知。

詳情點擊這裏:http://developer.apple.com/library/ios/#documentation/mediaplayer/reference/MPMoviePlayerController_Class/Reference/Reference.html

+0

謝謝,我會試試看。關於你最後的觀察,任何想法如何我可以流文件? – 8vius 2012-04-17 18:04:28

+0

這樣做,它停止在AVAudioPlayer實例化並打印出:Catchpoint 10(拋出異常)。單步執行,直到退出函數__cxa_throw, (沒有行號信息)。如果我繼續,它什麼都不做。 – 8vius 2012-04-17 18:09:58

+0

我不知道爲什麼它能正常工作,然後我使用了與我的答案完全相同的代碼,只是我使用了自己的URL。也許這與這個URL的內容有關。我也在模擬器5.0上進行測試。要回答關於流式傳輸的問題,請使用MPMoviePlayerController。我將添加另一個答案來獲得一些可讀代碼。 – 2012-04-17 18:29:20

1

您正在某處收到EXC_BAD_ACCESS。我建議刪除所有異步代碼並查看發生了什麼。實際上,就異步調用而言,我的思維過程有點困惑。

請注意,AVAudioPlayer僅適用於LOCAL文件。似乎你可能會設置它從服務器播放音頻文件,這將無法正常工作。

另外,你爲什麼不嘗試NSLog的錯誤變量?

+0

得到這個錯誤域= NSOSStatusErrorDomain代碼= -43 「的操作無法完成(OSStatus錯誤-43)。」。不知道當地的文件交易。我會更新我的代碼和我發現的問題。而且我沒有在任何地方獲得EXC_BAD_ACCESS,所以我不知道。看看。還有,你爲什麼會對我的思維過程感到困惑? – 8vius 2012-04-17 16:55:25

+0

我猜OP應該使用AVPlayer而不是AVAudioPlayer播放來自遠程位置的流。 – 2012-04-17 16:59:48

+0

根據Michael的新信息修改了我的問題。 – 8vius 2012-04-17 17:10:16