12

我正在尝试通过播放 MP3AVAudioPlayer我认为相当简单的 MP3。不幸的是,它并不完全有效。这是我所做的一切:

  • 为了测试,我在 Xcode 中创建了一个新的 iOS 应用程序(Single View)。
  • #import <AVFoundation/AVFoundation.h>我将 AVFoundation 框架添加到项目以及ViewController.m

  • 我在 Apps 'Documents' 文件夹中添加了一个 MP3 文件。

  • 我将其更改ViewControllers viewDidLoad:为以下内容:

代码:

- (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 编译时才会出现此问题,否则,它可以完美运行。

4

3 回答 3

7

问题是,在使用ARC编译时,您需要确保保留对您想要保持活动状态的实例的引用,因为编译器将alloc通过插入release调用自动修复“不平衡”(至少在概念上,阅读Mikes Ash 博客文章了解更多详细信息)。您可以通过将实例分配给属性或实例变量来解决此问题。

在 Phlibbo 的情况下,代码将被转换为:

- (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它会立即停止播放,因为当没有参考时它会被释放。

我自己没有使用过 ARC,只是简要地阅读了它。如果您对此有更多了解,请评论我的回答,我会用更多信息更新它。

更多 ARC 信息:
过渡到 ARC 发行说明
LLVM 自动引用计数

于 2011-10-12T18:37:09.923 回答
3

使用 AVAudioPlayer 作为头文件中的 ivar strong

@property (strong,nonatomic) AVAudioPlayer *audioPlayer
于 2012-03-30T22:46:34.657 回答
3

如果你需要多个 AVAudioPlayer 同时播放,创建一个 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]];
}
于 2013-07-10T09:04:48.493 回答