Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Since I encountered this issue and the previous answer is not complete (doesn't cover live stream case) - here is my improvement on top of it:</p> <pre><code>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 } } </code></pre> <p> Do note - this however will only let you show a local Audio only screen. When playing a live stream - the Artwork for the audio only is supposed to come from the stream, so my code is more towards this:</p> <pre><code>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]; } } </code></pre> <p>Add observation code:</p> <pre><code>[item addObserver:self forKeyPath:@"timedMetadata" options:0 context:NULL]; [item addObserver:self forKeyPath:@"tracks" options:0 context:NULL]; </code></pre> <p>Remove observation code:</p> <pre><code>@try { [item removeObserver:self forKeyPath:@"timedMetadata"]; [item removeObserver:self forKeyPath:@"tracks"]; } </code></pre> <p>hasVideoTracks code (Inside a category over AVPlayerItem):</p> <pre><code>- (BOOL)hasVideoTracks{ BOOL hasVideoTracks = NO; for (AVPlayerItemTrack* track in [self tracks]){ if ([track.assetTrack.mediaType isEqual:AVMediaTypeVideo]){ hasVideoTracks = YES; break; } } return hasVideoTracks; } </code></pre> <p>Note:</p> <ol> <li>DON'T use presentationSize to detect audio only - in iOS 7 it no longer becomes CGSizeZero when moving to audio only - but gives some funky sizes instead. It's not a reliable method.</li> <li>Show/Hide audioOnlySlide is pretty straight forward and should contain your implementation.</li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload