在AVPlayer中切换视频时更改时会创建Flash

kdb*_*las 17 video avfoundation ios

我正在使用AVFoundation的AVPlayer播放由1个较长视频制作的2个视频片段(因此第一个片段的结尾与第二个片段的开头相匹配)

当第一个视频结束并且用户点击时,我创建一个新的AVPlayer并将其分配给我的PlayerView,并开始播放第二个剪辑.

这一切都有效,然而,有一个突出的屏幕"闪烁".

我的假设是,这是由玩家视图删除第一个剪辑然后显示第二个剪辑引起的.

我需要的是这个闪烁没有出现,因此在两个剪辑之间进行无缝连接.

有没有人知道是否有办法通过AVPlayer*类来阻止这个flickr,或者通过做某事来"伪造"它以使其不可见.

谢谢

下面是我的加载和播放方法的代码:

- (void)loadAssetFromFile
{
    NSURL *fileURL = nil;

    switch (playingClip)
    {
        case 1:
            fileURL = [[NSBundle mainBundle] URLForResource:@"wh_3a" withExtension:@"mp4"];
        break;

        case 2:
            fileURL = [[NSBundle mainBundle] URLForResource:@"wh_3b" withExtension:@"mp4"];
        break;

        case 3:
            fileURL = [[NSBundle mainBundle] URLForResource:@"wh_3c" withExtension:@"mp4"];
        break;

        case 4:
            fileURL = [[NSBundle mainBundle] URLForResource:@"wh_3d" withExtension:@"mp4"];
        break;

        default:
            return;
        break;
    }

    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];
    NSString *tracksKey = @"tracks";

    [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:tracksKey] completionHandler:
 ^{
     // The completion block goes here.
     NSError *error = nil;
     AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error];

     if (status == AVKeyValueStatusLoaded)
     {
         self.playerItem = [AVPlayerItem playerItemWithAsset:asset];

         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];

         self.player = [AVPlayer playerWithPlayerItem:playerItem];
         [playerView setPlayer:player];

         [self.player seekToTime:kCMTimeZero];

         [self play];
     }
     else {
         // Deal with the error appropriately.
         NSLog(@"The asset's tracks were not loaded:\n%@", [error localizedDescription]);
     }
 }];
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*erg 5

您无需AVPlayer为此任务重新创建.您可以只有多个AVPlayerItems,然后切换哪个是当前通过[AVPlayer replaceCurrentItemWithPlayerItem:item].

此外,您可以使用以下代码观察当前项目的更改时间.

 static void* CurrentItemObservationContext = &CurrentItemObservationContext;
Run Code Online (Sandbox Code Playgroud)

...创建播放器后,注册观察者:

 [player1 addObserver:self 
                   forKeyPath:kCurrentItemKey 
                      options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                      context:CurrentItemObservationContext];
Run Code Online (Sandbox Code Playgroud)

...

 - (void)observeValueForKeyPath:(NSString*) path 
                  ofObject:(id)object 
                    change:(NSDictionary*)change 
                   context:(void*)context {
     if (context == CurrentItemObservationContext) {
         AVPlayerItem *item = [change objectForKey:NSKeyValueChangeNewKey];
         if (item != (id)[NSNull null]) {
             [player1 play];
         }
     }
 }
Run Code Online (Sandbox Code Playgroud)

  • 请不要一次创建多个`AVPlayers`,设备上的硬件限制最多为4,并且你不想让它变得更糟. (4认同)
  • 使用`AVPlayerItem`似乎可以在模拟器上运行,但在设备上我仍然可以看到闪存. (3认同)
  • 这似乎无法解决闪烁问题.感谢您尝试解决方案 (2认同)