我使用AVPlayerViewController
创建了一个示例视频应用。它工作正常。但问题是在完成视频后AVPlayerViewController
视图未删除。其他问题是在横向模式全屏幕中为纵向默认大小设置AVPlayerViewController
的约束。我是新约束的。请下载项目并运行项目记录器显示约束问题。
答案 0 :(得分:1)
我发现你的代码存在两个问题:
asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler: ^{
dispatch_async(
dispatch_get_main_queue(), ^{
if (!asset.playable) {
return;
} else {
[self prepareToPlayAsset: asset withRequestedKeys: requestedKeys];
}
if (videoPlayerItem) {
[videoPlayerItem removeObserver:self forKeyPath:kkStatusKey];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:AVPlayerItemDidPlayToEndTimeNotification
object: videoPlayerItem];
}
});
}];
上面的代码添加观察者并删除之后。所以应该改变两个:
[asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler: ^{
dispatch_async(
dispatch_get_main_queue(), ^{
if (videoPlayerItem) {
[videoPlayerItem removeObserver:self forKeyPath:kkStatusKey];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:AVPlayerItemDidPlayToEndTimeNotification
object: videoPlayerItem];
}
if (!asset.playable) {
return;
} else {
[self prepareToPlayAsset: asset withRequestedKeys: requestedKeys];
}
});
}];
问题2:
- (void)prepareToPlayAsset: (AVURLAsset *)asset withRequestedKeys: (NSArray *)requestedKeys {
for (NSString *thisKey in requestedKeys) {
NSError *error = nil;
AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error];
switch (keyStatus) {
case AVKeyValueStatusUnknown:
NSLog(@"%@ AVKeyValueStatusUnknown", thisKey);
break;
case AVKeyValueStatusFailed:
NSLog(@"Error! PlayAsset failed.\nAVKey : %@.\nError: %@", thisKey, error);
return;
break;
case AVKeyValueStatusLoading:
NSLog(@"%@ AVKeyValueStatusLoading", thisKey);
break;
case AVKeyValueStatusCancelled:
NSLog(@"%@ AVKeyValueStatusCancelled", thisKey);
break;
case AVKeyValueStatusLoaded: {
videoPlayerItem = [AVPlayerItem playerItemWithAsset: asset];
[videoPlayerItem addObserver:self forKeyPath: kkStatusKey options:0 context:nil];
videoPlayer = [AVPlayer playerWithPlayerItem: videoPlayerItem];
/**
* Creating the videoAdplayer through passing the avplayer object
*/
[self createVideoPlayer: videoPlayer];
if ([thisKey isEqualToString: @"duration"]) {
} else if ([thisKey isEqualToString: @"tracks"]) {
NSLog(@"\n\n asset.tracks : %@ \n\n", asset.tracks);
} else if ([thisKey isEqualToString: @"metadata"]) {
NSLog(@"\n\n assetMetadata : %@ \n\n", asset.metadata);
}
}
break;
default:
break;
}
}
if (!asset.playable) {
return;
}
}
在此循环中,只需检查eveything加载,如果失败则返回。在这种情况下有2个键,你这样的代码将添加两个childviewcontroller
,它将播放两个项目播放器。所以改变代码:
- (void)prepareToPlayAsset: (AVURLAsset *)asset withRequestedKeys: (NSArray *)requestedKeys {
for (NSString *thisKey in requestedKeys) {
NSError *error = nil;
AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error];
switch (keyStatus) {
case AVKeyValueStatusUnknown:
NSLog(@"%@ AVKeyValueStatusUnknown", thisKey);
break;
case AVKeyValueStatusFailed:
NSLog(@"Error! PlayAsset failed.\nAVKey : %@.\nError: %@", thisKey, error);
return;
break;
case AVKeyValueStatusLoading:
NSLog(@"%@ AVKeyValueStatusLoading", thisKey);
break;
case AVKeyValueStatusCancelled:
NSLog(@"%@ AVKeyValueStatusCancelled", thisKey);
break;
case AVKeyValueStatusLoaded: {
}
break;
default:
break;
}
}
videoPlayerItem = [AVPlayerItem playerItemWithAsset: asset];
[videoPlayerItem addObserver:self forKeyPath: kkStatusKey options:0 context:nil];
videoPlayer = [AVPlayer playerWithPlayerItem: videoPlayerItem];
/**
* Creating the videoAdplayer through passing the avplayer object
*/
[self createVideoPlayer: videoPlayer];
if (!asset.playable) {
return;
}
}
我非常肯定你的演示。像这样改变,它会正常工作。