Потоковое видео с iPhone через iPhone: как показать неподвижное изображение при воспроизведении только аудио - PullRequest
2 голосов
/ 04 мая 2011

У меня есть приложение для iPad, воспроизводящее потоковое видео по протоколу http с использованием варианта списка воспроизведения, в котором есть несколько потоков с разной скоростью передачи данных для разных полос пропускания.Одним из них является только аудио поток для самой низкой полосы пропускания.Приложение использует AVPlayer для воспроизведения видео.По какой-то причине я не могу использовать MPMoviePlayerViewController.

Проблема, с которой я сталкиваюсь, заключается в том, что когда видеопроигрыватель воспроизводит поток только для аудио , на видео отображается черный экран, звук все еще воспроизводится.Что, я думаю, ужасно для пользователей, они не знают, что происходит.Я хочу отобразить неподвижное изображение вместо видеоплеера.как это

Standard iPad Video Player - Playing Audio Stream only

Можно ли как-то определить, когда проигрыватель переключается на другой поток?Или определить, является ли поток только аудио?

Ответы [ 3 ]

3 голосов
/ 24 декабря 2013

Так как я столкнулся с этой проблемой, и предыдущий ответ не является полным (не относится к случаю прямой трансляции) - вот мое улучшение поверх этого:

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;
}

Примечание:

  1. НЕ использовать презентациюРазмер для обнаружениятолько аудио - в iOS 7 он больше не становится CGSizeZero при переходе только на аудио - но вместо этого дает несколько нестандартных размеров.Это ненадежный метод.
  2. Показать / Скрыть audioOnlySlide довольно прост и должен содержать вашу реализацию.
2 голосов
/ 13 мая 2011

Вы можете настроить наблюдатель для свойства track в AVPlayerItem.

[yourPlayer.currentItem addObserver:self forKeyPath:@"tracks" options:0 context:nil];

Чем вам нужно реализовать метод, который будет вызываться каждый раз, когда треки будут изменены

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqual:@"tracks"])
    {
        for (AVPlayerItemTrack* track in [[yourPlayer.currentItem] tracks]) 
        {
            if ([track.assetTrack.mediaType isEqual:AVMediaTypeAudio]) 
            {
                 // Audio track available
            }
            if ([track.assetTrack.mediaType isEqual:AVMediaTypeVideo]) 
            {
                 // Video track available
            }
        }
    }
}

Есть немного места для настройки, взгляните на NSKeyValueObserving Protocol и AVPlayerItem

1 голос
/ 10 февраля 2015

Освоение воспроизведения современных медиа (WWDC 2014):

AVPlayer and AVPlayerItem
Deciding when to show audio-only UI
// Inside -observeValueForKeyPath:ofObject:change:context: implementation...
if (presentationSizeObservationContext == context) {
    // Check if new presentation size is CGSizeZero.
    CGSize size = change[NSKeyValueChangeNewKey].sizeValue;
    if (CGSizeEqualToSize(size, CGSizeZero)) {
       for (AVPlayerItemTrack *playerItemTrack in playerItem.tracks) {
          AVAssetTrack *track = playerItemTrack.assetTrack;
          if ([track hasMediaCharacteristic:AVMediaCharacteristicAudible]) {
              // Show audio-only UI.
          } 
       }
    }
}

Ссылка: https://developer.apple.com/videos/wwdc/2014/#503

...