我使用AVPlayer通过网址播放远程音频和视频文件。在我目前的实现中,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");
}
}