我有一个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];
}
}
答案 0 :(得分:1)
尝试以这种方式构建数组:
music = [[NSMutableArray alloc] initWithArray:@[[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM1" withExtension:@"mp3"]],...]];
编辑:
无论如何,恕我直言,最重要的方面是突出显示withExtension工作的原因,其中ofType不能:第一个返回由指定名称和文件扩展名标识的资源的文件URL,其中-pathForResource:ofType:
返回完整路径名对于由指定名称和文件扩展名标识的资源。但是,您需要一个NSURL对象来初始化AVPlayer
,而AVQueuePlayer
是AVPlayer的子类,您可以使用它来按顺序播放多个项目。
答案 1 :(得分: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:]
,而是使用{{1}简单地创建一个包含对象的数组语法。
所以我们上面的例子看起来像这样:
@[]
那么你在原始代码中做了什么,基本上是调用NSArray *array1 = @[@"One", @"Two", @"Three"]; // Notice that 'nil' is not necessary
NSArray *array2 = [[NSArray alloc] initWithArray:array2];
,最终会创建一个新数组,
然后,使用' new' [[NSMutableArray alloc] initWithObjects:]
语法,您已创建另一个包含所有@[]
个对象的新数组,
并且'告诉' AVPlayerItem
数组,以包含该新数组的内容。
所以在这个'单行'代码,你实际上创建了2个不同的数组
这个' new'未命名的数组可能在该行之后被释放,因为你在任何地方都没有任何对该数组的引用(你只是在新创建的数组中引用了它的对象),
ARC自动释放引用计数为零的对象。
由于这个原因,您可能不会感到任何记忆/性能问题 但我认为有必要指出这一点,因为它是不必要的,它并不是“正确的”。实现你正在尝试的方法,现在代码看起来更干净,更可读。
BTW-
这不是您的代码无法正常工作的原因
您遇到的问题是您的原始代码生成music
并将路径作为字符串:NSURL
但/PATH/TO/MY/MP3
期望路径为网址:AVPlayerItem
(您可以file:///PATH/TO/MY/MP3
新旧呼叫来验证不同的输出)