Так как я столкнулся с этой проблемой, и предыдущий ответ не является полным (не относится к случаю прямой трансляции) - вот мое улучшение поверх этого:
if ([keyPath isEqual:@"tracks"])
{
BOOL hasVideoTrack = NO;
for (AVPlayerItemTrack* track in [[yourPlayer.currentItem] tracks])
{
if ([track.assetTrack.mediaType isEqual:AVMediaTypeVideo])
{
hasVideoTrack = YES;
break;
}
}
if (hasVideoTrack)
{
// Remove audio only view
} else {
// Show audio only view
}
}
Обратите внимание - это, однако, будет толькопозволяет вам показывать только локальный экран Audio.При воспроизведении в прямом эфире - обложка только для аудио должна исходить из потока, поэтому мой код ближе к этому:
if ([keyPath isEqualToString:@"timedMetadata"] == YES){
for (AVMetadataItem *metadata in self.player.currentItem.timedMetadata) {
if ([[metadata commonKey] isEqualToString:@"artwork"]) {
UIImage *overlayImage = [UIImage imageWithData:metadata.dataValue];
UIImageView *overlayImageView = [[UIImageView alloc] initWithImage:overlayImage];
overlayImageView.contentMode = UIViewContentModeScaleAspectFit;
// If an audio only slide is already there, make it disappear.
[self hideAudioOnlySlide];
self.audioOnlyView = overlayImageView;
[self showAudioOnlySlide];
self.audioOnlyView.size = _playerView.size;
break;
}
}
}else if ([keyPath isEqualToString:@"tracks"] == YES){
NSArray *tracks = self.player.currentItem.tracks;
if ([self.player.currentItem hasVideoTracks] == NO) {
// Check if there is timed metadata with artwork that indicates audio only is handled at the stream level.
BOOL hasAudioOnlyFromStream = NO;
for (AVMetadataItem *metadata in self.player.currentItem.timedMetadata) {
if ([[metadata commonKey] isEqualToString:@"artwork"]) {
hasAudioOnlyFromStream = YES;
break;
}
}
// If we don't have audio only slide from the stream - carry on to show audio only slide.
//Otherwise - this is handled by the timed metadata check for artwork.
if (hasAudioOnlyFromStream == NO) {
[self showAudioOnlySlide];
}
} else {
[self hideAudioOnlySlide];
}
}
Добавить код наблюдения:
[item addObserver:self forKeyPath:@"timedMetadata" options:0 context:NULL];
[item addObserver:self forKeyPath:@"tracks" options:0 context:NULL];
Удалить код наблюдения:
@try {
[item removeObserver:self forKeyPath:@"timedMetadata"];
[item removeObserver:self forKeyPath:@"tracks"];
}
имеет код VideoTracks (внутри категории через AVPlayerItem):
- (BOOL)hasVideoTracks{
BOOL hasVideoTracks = NO;
for (AVPlayerItemTrack* track in [self tracks]){
if ([track.assetTrack.mediaType isEqual:AVMediaTypeVideo]){
hasVideoTracks = YES;
break;
}
}
return hasVideoTracks;
}
Примечание:
- НЕ использовать презентациюРазмер для обнаружениятолько аудио - в iOS 7 он больше не становится CGSizeZero при переходе только на аудио - но вместо этого дает несколько нестандартных размеров.Это ненадежный метод.
- Показать / Скрыть audioOnlySlide довольно прост и должен содержать вашу реализацию.