I see two problem with your code:
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];
}
});
}];
this code above you add observer and remove after. so should change two:
[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];
}
});
}];
Problem 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;
}
}
In this loop just check eveything load and return if have failed. In this case have 2 key, you code like this will add two childviewcontroller
and it will play two item player. So change code to it:
- (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;
}
}
I pretty sure that with your demo. Change like this, it will work ok.