首页 文章

AVQueuePlayer音频无法播放

提问于
浏览
0

我有一个 AVQueuePlayer 属性,设置如下 . NSLog 语句报告音频应该正常播放(当应用程序运行时)但是在模拟器和iOS设备本身(iPhone 5s iOS 8.1.1)上进行测试时,没有音频播放 .

我已经确认该设备没有静音,并且已达到最大音量 . 我正在使用Xcode 6和iOS 8 SDK . 我在“链接二进制文件”部分导入AVFoundation框架并将其导入我的类 .

-(void)viewDidLoad
{
   [super viewDidLoad];
   [self music];
   // other setup code
}


- (void)music
{
    music = [[NSMutableArray alloc]initWithArray:@[
                                                   [AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM1"
                                                                                                                                        ofType:@"mp3" ]]],

                                                   [AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM2"
                                                                                                                                        ofType:@"mp3" ]]],
                                                   [AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM3"
                                                                                                                                        ofType:@"mp3" ]]],

                                                   [AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM4"
                                                                                                                                        ofType:@"mp3" ]]],
                                                   [AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM5"
                                                                                                                                        ofType:@"mp3" ]]],

                                                   [AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM6"
                                                                                                                                        ofType:@"mp3" ]]],



                                                   [AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM7"
                                                                                                                                        ofType:@"mp3" ]]]



                                                   ]];


    for(AVPlayerItem *a in music)
    {

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:a];

    }

    [music shuffle];

    self.audio  = [[AVQueuePlayer alloc]initWithItems:music];


    [self.audio play];



    NSLog(@"Now playing%@",[self.audio currentItem]);

    NSLog(@"%@",self.audio);









}
-(void)playerItemFinished:(NSNotification *)notification
{
    if([[self.audio currentItem] isEqual:[music lastObject]])
    {

        self.audio = nil;

        [music shuffle];

        self.audio = [[AVQueuePlayer alloc]initWithItems:music];


        [self.audio play];

    }

}

2 回答

  • 1

    好吧,我已经从上面的评论中创建了一个代码片段,因此您可以将其复制粘贴到您的项目中 .

    我基本上做了2次改动 .
    数组创建已从 initWithArray: 更改为 initWithObjects: ,因此您不会创建一个新的不必要的未使用的数组,该数组可能在此方法调用后释放 .
    另外,不是在该数组中的每个对象上调用 [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:ofType:]]] ,而只是调用 [[NSBundle mainBundle] URLForResource:withExtension:

    music = [[NSMutableArray alloc] initWithObjects:
                              [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM1" withExtension:@"mp3"]],
                              [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM2" withExtension:@"mp3"]],
                              [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM3" withExtension:@"mp3"]],
                              [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM4" withExtension:@"mp3"]],
                              [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"MP5" withExtension:@"mp3"]],
                              [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"MP6" withExtension:@"mp3"]],
                              [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"MP7" withExtension:@"mp3"]],
                              nil];
    

    祝你好运 .

    编辑-
    我'm not a native english speaker so I'我会尽力清楚,
    如果有什么事情没有't clear, tell me, and I' ll试着改写它 .

    initWithArray 所做的是创建一个新数组,包含给定数组的内容,
    例如:

    NSArray *array1 = [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil]];  
    NSArray *array2 = [[NSArray alloc] initWithArray:array1];
    

    所以现在 array1array2 都有相同的项目 .

    如果我没弄错,自Xcode 4以来,引入了一种创建数组的新方法,现在,不是调用 [[NSArray alloc] initWithObjects:] ,而是可以使用 @[] 语法简单地创建一个包含对象的数组 .
    所以我们上面的例子看起来像这样:

    NSArray *array1 = @[@"One", @"Two", @"Three"]; // Notice that 'nil' is not necessary  
    NSArray *array2 = [[NSArray alloc] initWithArray:array2];
    

    那你在原始代码中做了什么,基本上是调用 [[NSMutableArray alloc] initWithObjects:] ,最终会创建一个新的数组,

    然后,使用'new' @[] 语法,您创建了另一个包含所有 AVPlayerItem 对象的新数组,
    并'told' music 数组,以获取该新数组的内容 .

    所以在这个'one-line'代码中,你实际创建了2个不同的数组 .
    'new'未命名数组可能在该行之后被释放的原因是因为您在任何地方都没有对该数组的任何引用(您只是在新创建的数组中引用了它的对象),
    ARC自动释放引用计数为零的对象 .

    因此,您可能不会感到任何内存/性能问题,
    但我认为有必要指出这一点,因为它是不必要的,它不是正确的方式来实现你正在尝试的东西,现在代码看起来更干净,更具可读性 .

    BTW-
    这不是您的代码不起作用的原因 .
    您遇到的问题是您的原始代码生成 NSURL ,路径为字符串: /PATH/TO/MY/MP3
    AVPlayerItem 期待路径为URL: file:///PATH/TO/MY/MP3
    (您可以 NSLog 新旧呼叫来验证不同的输出)

  • 0

    尝试以这种方式构建数组:

    music = [[NSMutableArray alloc] initWithArray:@[[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM1" withExtension:@"mp3"]],...]];
    

    编辑:无论如何,恕我直言,最重要的方面是突出显示withExtension工作的原因,其中ofType没有:第一个返回由指定名称和文件扩展名标识的资源的文件URL,其中 -pathForResource:ofType: 返回完整路径名由指定的名称和文件扩展名标识的资源 . 但是,您需要一个NSURL对象来初始化 AVPlayerAVQueuePlayer 是AVPlayer的子类,您可以使用它来按顺序播放多个项目 .

相关问题