2011-11-04 123 views
52

我正在研究一個需要使用AVFoundation框架播放一些聲音的iOS應用程序。在Xcode 4的工作空間結構,包含兩個項目:AVAudioPlayer不播放任何聲音

  • 工作區
    • 應用程序本身(主體工程)
    • 一個實用程序庫

建立實用程序庫後,導致在主應用程序中使用靜態庫作爲框架。

因此,當試圖通過使用下面的代碼在主應用程序內播放聲音時,它按預期工作。

NSString *resourcePath = [[NSBundle mainBundle] resourcePath]; 
NSString *path = [NSString stringWithFormat:@"%@/sound.mp3", resourcePath]; 

NSURL *url = [NSURL fileURLWithPath:path]; 
NSError *error = nil; 

AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url 
                    error:&error]; 
[audioPlayer play]; 

相反,試圖精確地發揮效用庫中相同的聲音(或任何其他)使用與上述相同的代碼的時候,沒有任何聲音都玩過,即使錯誤是audioPlayer屬性值是正確的(通道數量,持續時間)。

我確定AVFoundation框架在兩個項目中。

而且,我的類使用AVAudioPlayerDelegate協議,實現了這兩種方法:

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag; 
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error; 

這些方法都試圖播放聲音後調用。

如果我使用AudioToolbox框架來代替,那麼它會播放聲音。但我有興趣使用AVFoundation有幾個原因。

有什麼想法發生了什麼?我是否錯過了AVFoundation?它可能與在靜態庫中使用AVAudioPlayer有關嗎?

在此先感謝。

+0

你能告訴我們什麼是錯誤變量輸出? AVAudioPlayer * audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; –

+0

@Maudicus,正如我所說,播放聲音後錯誤爲零。我找到了解決方案,它與我沒有提及但沒有考慮的事情有關:我正在編譯ARC。 ARC向音頻播放器插入一個釋放調用,所以在離開創建它的方法之後,釋放調用被解除分配,如[在這裏]解釋的那樣(http://stackoverflow.com/questions/7692866/avaudioplayer-stops-playing-immediately -with-arc) – msoler

+0

對不起,我複製了你的代碼,它工作。錯過了關於錯誤的陳述是零。我很高興它解決了 –

回答

139

我找到了解決方案,它與我沒有提及但沒有考慮的事情有關:我正在使用自動引用計數(ARC)進行編譯。

ARC向音頻播放器插入釋放呼叫,因此它在離開創建方法後立即釋放。它與AVAudioPlayer無關,但與ARC。

爲了解決這個問題,我剛創建了一個AVAudioPlayer屬性來處理聲音,以便它不再被ARC發佈。至少,這個類在發佈之前不會被釋放。

有關ARC的更多信息,請參閱Automatic Reference Counting: Zeroing Weak References,詳細說明爲什麼出現此問題。

+1

這在我以前發生過,與AVAudioPlayer沒有任何關係,甚至在AVAudioPlayer出現問題時我甚至忘了這個解決方案,而這個問題莫名其妙地不能播放聲音。關於ARC的好記事! –

+0

我知道這是一個古老的話題,而不是創造一個新的問題提出同樣的問題,你能像我五歲那樣向我解釋這是什麼意思?我做了一個iOS應用程序,我有一個提交按鈕,當計算完成時,它會播放聲音。我首先做了一個簡化的版本作爲一個OS X應用程序運行良好,但作爲一個iOS應用程序,使用AVAudioPlayer而不是NSSound或它不起作用,50%的時間會導致應用程序崩潰。 –

+0

@JonathanWeinraub對不起,但很難說沒有看到任何代碼。您的崩潰和AVAudioPlayer問題可能與幾個原因有關。 – msoler

16

你配置了AVAudioSession嗎?

我有一個類似的問題,使用這樣的固定它:

AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:NULL]; 

[audioSession setCategory:AVAudioSessionCategoryPlayback error:NULL]; 

希望它能幫助。

+0

我已經回答了Madicus這件事,但是我沒有把它作爲對我的問題的直接回答,因爲我不能(可能是因爲StackOverflow在第一個小時/天內不允許自動應答)。官方的答案現在在這裏。 :) 不管怎麼說,還是要謝謝你! – msoler

+0

將其添加到您的viewDidLoad方法中。在錄製之後但在播放之前設置會話不起作用。此外,沒有設置會話,它在模擬器中工作,但不在設備上。 –

33

是的,絕對; ARC也是我的代碼的原因。

我介紹了一個屬性:

@property (strong, nonatomic) AVAudioPlayer *audioPlayer; 

,這讓一切都迎刃而解。

+0

很好的回答! –

+0

你還在做alloc initWithContentsOfUrl嗎? –

24

使用這一點,肯定會工作....

AVAudioSession *session = [AVAudioSession sharedInstance]; 
[session setCategory:AVAudioSessionCategoryPlayback error:nil]; 

NSURL *url = [NSURL fileURLWithPath:@"path of the sound file :)"]; 
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; 
[_player setDelegate:self]; 
[_player prepareToPlay]; 
[_player play]; 
+3

'AVAudioSession'爲我做了訣竅。沒有它,我只能在模擬器中播放聲音,而不能在設備上播放。 –

+1

謝謝你'prepareToPlay' – Alexmelyon

+0

這對我有很大的幫助! –

-1

請留一段在頁面上時間,我面臨同樣的問題。並使用睡眠來解決它。


NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] 
              pathForResource:@"sounds-1027-are-you-kidding" 
              ofType:@"mp3"]]; 
     AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] 
             initWithContentsOfURL:url 
             error:nil]; 
     [audioPlayer play]; 
     sleep(2); 

+1

儘量避免使用'sleep','dispatch_after'是一個更好的選擇。 –

+0

這段代碼將使audioPlayer實例活着2秒。這使得代碼依賴於音頻文件的長度,並且不適用於任何音頻文件。此外,它會暫停2秒的調用線程,在大多數情況下,它不會是所需的行爲。 – msoler

+0

這是一個駭人但富有創意的解決方案,它有其優點和缺點。在我的情況下,我試圖提醒用戶注意新信息。在播放警報聲音的同時,凍結應用程序中的所有活動一秒鐘,實際上是獲得用戶注意力的好方法。所以這實際上符合我的需求。它不值得投票。 –

0

迅速解決:

import AVFoundation 

    // define your player in class 
    var player = AVAudioPlayer() 

    override func viewDidLoad() { 
    super.viewDidLoad() 
    } 
0

我有同樣的問題。我曾在.h文件中加入下面一行解決它:

@property (strong, nonatomic) AVAudioPlayer *audioPlayer; 

而且在.m文件:在類範圍內聲明

NSError *error; 
NSString *soundFilePath = [NSString stringWithFormat:@"%@/dancepechance.mp3", 
           [[NSBundle mainBundle] resourcePath]]; 
    NSURL *url = [NSURL fileURLWithPath:soundFilePath]; 
    self.audioPlayer = [[AVAudioPlayer alloc] 
            initWithContentsOfURL:url 
            error:&error]; 
    NSLog(@"Error %@",error); 
    [self.audioPlayer prepareToPlay]; 
    [self.audioPlayer play]; 
2

即使有audioPlayer變種,它不會玩。 至少在iOS 10 iPhone 5c物理設備上。

play()結果是true所以沒有錯誤出現。

不得不添加此(斯威夫特3,4),現在它正確播放聲音。

let session = AVAudioSession.sharedInstance() 
try! session.setCategory(AVAudioSessionCategoryPlayback)