2

バリアント プレイリストを使用して http ビデオ ストリーミングを再生する iPad アプリがあります。このプレイリストには、帯域幅ごとに異なるビット レートのマルチ ストリームがあります。そのうちの 1 つは、最低帯域幅の音声のみのストリームです。アプリはAVPlayerを使用してビデオを再生します。なぜかMPMoviePlayerViewControllerが使えません。

私が抱えている問題は、ビデオプレーヤーがオーディオのみのストリームを再生すると、ビデオが黒い画面に表示され、オーディオがまだ再生されていることです。これはユーザーにとってひどいことだと思います。ユーザーは何が起こっているのかわかりません。動画プレーヤーの代わりに静止画を表示したい。このような

標準の iPad ビデオ プレーヤー - オーディオ ストリームの再生のみ

プレーヤーが別のストリームに切り替わったことを検出する方法はありますか? または、ストリームがオーディオのみかどうかを検出しますか?

4

3 に答える 3

3

私はこの問題に遭遇し、以前の回答は完全ではありません (ライブ ストリームのケースはカバーしていません) - これが私の改善点です。

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

ノート:

  1. オーディオのみを検出するためにpresentationSizeを使用しないでください.iOS 7では、オーディオのみに移行するときにCGSizeZeroにはなりません. 信頼できる方法ではありません。
  2. Show/Hide audioOnlySlide は非常に簡単で、実装を含める必要があります。
于 2013-12-24T11:49:13.653 に答える
2

AVPlayerItem の track プロパティにオブザーバーを設定できます。

[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 ProtocolAVPlayerItemを見てください。

于 2011-05-13T02:57:24.317 に答える
1

最新のメディア再生をマスターする (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

于 2015-02-10T09:57:46.310 に答える