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];

    }

}
4

2 回答 2

1

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

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

编辑:无论如何,恕我直言,最重要的方面是强调 withExtension 在 ofType 不起作用的情况下起作用的原因:第一个返回由指定名称和文件扩展名标识的资源的文件 URL,其中-pathForResource:ofType:返回资源的完整路径名由指定的名称和文件扩展名标识。但是,您需要一个 NSURL 对象来初始化它AVPlayerAVQueuePlayer它是 AVPlayer 的子类,用于按顺序播放多个项目。

于 2014-12-14T09:26:20.723 回答
0

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

我基本上做了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];  

祝你好运朋友。

编辑-
我不是以英语为母语的人,所以我会尽力说清楚,
如果有不清楚的地方,请告诉我,我会尝试改写。

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

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

所以现在两者array1都有array2相同的项目。

如果我没记错的话,从 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:],最终会创建一个新数组,

然后,使用“新”@[]语法,您创建了另一个新数组,其中包含所有AVPlayerItem对象,
并“告诉”该music数组,以包含该新数组的内容。

因此,在这个“一行”代码中,您实际上创建了 2 个不同的数组。
“新”未命名数组可能在该行之后被释放的原因是因为您在任何地方都没有对该数组的任何引用(您只是在新创建的数组中引用了它的对象)
和 ARC自动释放引用计数为零的对象。

因此,您可能不会感觉到任何内存/性能问题,
但我认为值得指出的是,因为它是不必要的,这不是实现您正在尝试的“正确”方法,现在代码看起来更干净,更具可读性。

顺便说一句-
这不是您的代码不起作用的原因。
您的问题在于,您的原始代码是NSURL使用路径作为字符串生成的:/PATH/TO/MY/MP3
但是AVPlayerItem期望路径作为 URL:(file:///PATH/TO/MY/MP3
您可以NSLog通过新旧调用来验证不同的输出)

于 2014-12-14T09:39:22.427 回答