12

私はかなり簡単だと思ったAVAudioPlayerでMP3を再生しようとしています。残念ながら、それはかなりうまく機能していません。ここに私がしたのはすべてです:AVAudioPlayerはすぐにARCで再生を停止します

  • テストのために、Xcodeに新しいiOSアプリケーション( ビュー)を作成しました。
  • は私がプロジェクトにAVFoundationフレームワークだけでなく、私はAppsのドキュメント」フォルダにMP3ファイルを追加 ViewController.m

  • から#import <AVFoundation/AVFoundation.h>を追加しました。

  • 私は次のようにViewControllersviewDidLoad:を変更:

コード:

- (void)viewDidLoad 
{ 
    [super viewDidLoad];   

    NSString* recorderFilePath = [NSString stringWithFormat:@"%@/MySound.mp3", [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]];  

    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:recorderFilePath] error:nil]; 
    audioPlayer.numberOfLoops = 1; 

    [audioPlayer play]; 

    //[NSThread sleepForTimeInterval:20]; 
} 

を、それが再生を開始した後、残念ながら、オーディオは明らかに右に停止します。 sleepForTimeIntervalのコメントを外すと、20秒間再生されたあと停止します。この問題は、ARCを使用してコンパイルする場合にのみ発生します。それ以外の場合は、問題なく動作します。

+0

音声を再生するために別のスレッドを開始する必要はありません。何かが記録されているかどうかを確認するためにエラーポインタを提供しようとしましたか? – isaac

+0

あなたはどんなエラーを受けていますか? – Daniel

+0

はい、initWithContensOfURLにNSErrorを渡しました。しかし、それは無限にとどまっています...だから私は何の誤りもなく、ただちに再生を止めます。 – Phlibbo

答えて

7

問題がARCでコンパイルするとき、あなたがrelease呼び出しを挿入することによって、あなたは、コンパイラが自動的に「アンバランス」修正allocうとして生き続けたいのインスタンスへの参照を保持することを確認する必要があるということです(少なくとも概念的に、Mikes Ash blog post for more detailsを読みます)。これを解決するには、インスタンスをプロパティまたはインスタンス変数に割り当てます。いかなる参照が残っていない場合には、割り当てを解除につれて、それはすぐに再生を停止します

- (void)viewDidLoad 
{ 
    [super viewDidLoad];   
    NSString* recorderFilePath = [NSString stringWithFormat:@"%@/MySound.mp3", [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]];  
    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:recorderFilePath] error:nil]; 
    audioPlayer.numberOfLoops = 1; 
    [audioPlayer play]; 
    [audioPlayer release]; // inserted by ARC 
} 

そしてAVAudioPlayer

Phlibboケースのコードは、に変換されます。

私はARCを自分で使用しておらず、ちょうどそれについて簡単に読んだことがあります。あなたがこれについてもっと知っているなら、私の答えにコメントしてください。私はそれをもっと情報で更新します。

詳しいARC情報:
Transitioning to ARC Release Notes
LLVM Automatic Reference Counting

+0

あなたは絶対に正しいです。上記のコメントのように。 ;) – yinkou

+0

私はARCを使用せず、あなたが書くのと同じ方法で短い音を再生しようとしました。私は最初のサウンドだけを聞いています(AVAudioPlayerのバグのおかげで初めて音が鳴ります)。だから最善の方法でコードはオーディオの最初の秒をカットし、最悪の場合はサウンドが停止する前に再生を停止します。 – Gargo

+0

@Gargo:マティアスは彼の記事で次のように書いています。なぜなら、プレーヤーが私の場合にはうまくいかなかった理由を説明するコードであり、故意に間違っています。 AVAudioPlayerチュートリアルは、経験がなければ見てください。 – Phlibbo

3

strongとヘッダファイル内IVARとしてAVAudioPlayerを使用してください:あなたが同時にプレイする複数のAVAudioPlayersが必要な場合は、

@property (strong,nonatomic) AVAudioPlayer *audioPlayer 
3

作成NSMutableDictionaryです。キーをファイル名に設定します。デリゲートコールバック経由で辞書から削除する:

-(void)playSound:(NSString*)soundNum { 


    NSString* path = [[NSBundle mainBundle] 
         pathForResource:soundNum ofType:@"m4a"]; 
    NSURL* url = [NSURL fileURLWithPath:path]; 

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

    audioPlayer.delegate = self; 

    if (_dictPlayers == nil) 
     _dictPlayers = [NSMutableDictionary dictionary]; 
    [_dictPlayers setObject:audioPlayer forKey:[[audioPlayer.url path] lastPathComponent]]; 
    [audioPlayer play]; 

} 

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {   
    [_dictPlayers removeObjectForKey:[[player.url path] lastPathComponent]]; 
} 
+0

これは同時にサウンドを再生するのに最適なソリューションです。 AVAudioPlayerをプロパティとして使用すると、オブジェクトが次のサウンドを再生するときに解放され、AudioServicesPlaySystemSoundを使用している人もいるものの、リンゴはアプリケーションを拒否しているため、デバイスがミュートされているときに再生され、ミュートされました。 – Zeeshan

関連する問題