use*_*667 7 bundle ios avplayer avasset avplayeritem
我刚发现一个非常奇怪的问题,
从本地存储加载mp3文件时,
avplayeritem始终处于未知状态,如果文件放在文档文件夹中则无法播放.
方式1:
//AVAsset *asset = [[AVURLAsset alloc] initWithURL:_URL options:nil];
//AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:_URL];
//line 1
while (playerItem.status!=AVPlayerItemStatusReadyToPlay
&& playerItem.status!=AVPlayerItemStatusFailed) {
NSLog(@"avplayer: %@ status: %d", playerItem, playerItem.status);
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
//line 2
NSLog(@"avplayer status: %d item: %@", playerItem.status, _URL);
NSArray *metadata = [playerItem.asset commonMetadata];
Run Code Online (Sandbox Code Playgroud)
方式2:
AVAsset *asset = [[AVURLAsset alloc] initWithURL:_URL options:nil];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
/*
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:_URL];
//line 1
while (playerItem.status!=AVPlayerItemStatusReadyToPlay
&& playerItem.status!=AVPlayerItemStatusFailed) {
NSLog(@"avplayer: %@ status: %d", playerItem, playerItem.status);
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
//line 2
*/
NSLog(@"avplayer status: %d item: %@", playerItem.status, _URL);
NSArray *metadata = [playerItem.asset commonMetadata];
Run Code Online (Sandbox Code Playgroud)
输出:
2015-03-19 00:42:49.243 goodnightfm[6737:353911] avplayer: <AVPlayerItem: 0x7fdc3bbd5c00, asset = <AVURLAsset: 0x7fdc3bbd8a50, URL = file:///Users/galenzhao/Library/Developer/CoreSimulator/Devices/123A77A7-DC61-4795-8D9A-E71002E261DA/data/Containers/Data/Application/4CCEED79-1D5A-4D00-BC5E-FC52BD5393F9/Documents/CMStorage/70efdf2ec9b086079795c442636b55fb>> status: 0
Run Code Online (Sandbox Code Playgroud)
但如果mp3文件在应用程序包中,那么way2代码效果很好,即使状态仍然在未知,
2015-03-19 00:45:35.977 goodnightfm[6783:355678] avplayer status: 0 item: file:///Users/galenzhao/Library/Developer/CoreSimulator/Devices/123A77A7-DC61-4795-8D9A-E71002E261DA/data/Containers/Bundle/Application/F2446C29-49F3-4B92-A7B0-7EFCC1A19274/goodnightfm.app/demo5.mp3
Run Code Online (Sandbox Code Playgroud)
我确定应用程序包和文档中的文件是相同的,它可以在任何其他软件中播放,
通过使用way2,捆绑文件和文档文件之间唯一不同的是,
如果mp3文件放在bundle中,这个函数可以返回元数据
NSArray *metadata = [playerItem.asset commonMetadata];
Run Code Online (Sandbox Code Playgroud)
但是使用文档URL返回nil
首先,您需要向播放器项目添加一个观察者以适当地检查其状态:
[playerItem addObserver:self
forKeyPath:@"status"
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:nil];
Run Code Online (Sandbox Code Playgroud)
或者向 AVPlayer 对象添加一个观察者:
[player addObserver:self
forKeyPath:@"currentItem.status"
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:nil];
Run Code Online (Sandbox Code Playgroud)
然后添加一个观察者方法,如下所示:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([object isKindOfClass:[AVPlayerItem class]] && [keyPath isEqualToString:@"status"]) {
AVPlayerItem *playerItem = (AVPlayerItem *)object;
NSLog(@"avplayer: %@ status: %d", playerItem, playerItem.status);
}
else if ([object isKindOfClass:[AVPlayer class]] && [keyPath isEqualToString:@"currentItem.status"]) {
AVPlayer *player = (AVPlayer *)object;
NSLog(@"avplayer: %@ status: %d", player.currentItem, player.currentItem.status);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您仍然没有准备好播放器项目,请确保音频文件确实存在于 URL 指定的文档目录路径中。