我正在使用 AVPlayer 通过 url 播放远程音频和视频文件。使用我目前的实现,在 iOS8.4 及更高版本上一切都很好,唯一的问题是在 iOS8.3 上出现视频但音频在后台运行。
我创建一个AVURLAsset
这样的:
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:soundURL options:nil];
NSArray *keys = @[@"playable", @"duration"];
avAsset = asset;
[avAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^() {
NSError *error = nil;
AVKeyValueStatus playableStatus = [asset statusOfValueForKey:@"playable" error:&error];
AVKeyValueStatus durationStatus = [asset statusOfValueForKey:@"duration" error:&error];
switch (playableStatus) {
case AVKeyValueStatusLoaded:{
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:avAsset];
if (!mediaPlayer) {
mediaPlayer = [[AVPlayer alloc] initWithPlayerItem:item];
mediaPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
[item addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[mediaPlayer currentItem]];
} else {
if (isNewURL) {
[mediaPlayer replaceCurrentItemWithPlayerItem:item];
}
}
[mediaPlayer seekToTime:kCMTimeZero];
break;
}
case AVKeyValueStatusLoading:
[SBNotificationMessenger notifyMessage:@"Buffering..."];
break;
case AVKeyValueStatusFailed:
[SBNotificationMessenger notifyError:error.localizedDescription];
break;
default:
break;
}
if (durationStatus == AVKeyValueStatusLoaded) {
dispatch_async(dispatch_get_main_queue(), ^{
startedPlaying(YES);
});
}
}];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (object == mediaPlayer.currentItem) {
if ([keyPath isEqualToString:@"status"]) {
[self handleMediaPlayerStatus];
} else if ([keyPath isEqualToString:@"rate"]) {
[self handleMediaPlayerRateStatus];
}
}
}
- (void)handleMediaPlayerStatus
{
if (mediaPlayer.status == AVPlayerStatusFailed) {
DDLogError(@"Media player status: failed!");
} else if (mediaPlayer.status == AVPlayerStatusReadyToPlay) {
DDLogInfo(@"Media player status: ready!");
[mediaPlayer play];
} else if (mediaPlayer.status == AVPlayerItemStatusUnknown) {
DDLogInfo(@"Media player status: unknown");
}
}