私はこの問題に遭遇し、以前の回答は完全ではありません (ライブ ストリームのケースはカバーしていません) - これが私の改善点です。
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
}
}
注意してください - ただし、これはローカルの音声のみの画面しか表示できません。ライブ ストリームを再生する場合 - オーディオのみのアートワークはストリームから取得されるため、私のコードは次のようになります。
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"];
}
hasVideoTracks コード (AVPlayerItem のカテゴリ内):
- (BOOL)hasVideoTracks{
BOOL hasVideoTracks = NO;
for (AVPlayerItemTrack* track in [self tracks]){
if ([track.assetTrack.mediaType isEqual:AVMediaTypeVideo]){
hasVideoTracks = YES;
break;
}
}
return hasVideoTracks;
}
ノート:
- オーディオのみを検出するためにpresentationSizeを使用しないでください.iOS 7では、オーディオのみに移行するときにCGSizeZeroにはなりません. 信頼できる方法ではありません。
- Show/Hide audioOnlySlide は非常に簡単で、実装を含める必要があります。