Переключение видео в AVPlayer создает Flash при изменении
Я использую AVFoundation AVPlayer для воспроизведения 2 видеоклипов, сделанных из 1 более длинного видео (так что конец первого совпадает с началом второго)
Когда первое видео заканчивается и пользовательские нажатия, я создаю новый AVPlayer и назначаю его моему PlayerView и начинаю играть второй клип.
Все это работает, однако, есть видный экран "мерцание".
Мое предположение заключается в том, что это вызвано просмотром плеера, снимающим первый клип, а затем показывающим второй клип.
Мне нужно, чтобы этот мерцание не появлялся, так что между двумя клипами не получается.
Кто-нибудь знает, есть ли способ остановить этот flickr, либо через классы AVPlayer *, либо способ "подделать" его, сделав что-то, чтобы сделать это, чтобы это не было видно.
Спасибо
Ниже приведен код моего метода загрузки и воспроизведения:
- (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 tracks were not loaded:\n%@", [error localizedDescription]);
}
}];
}
Ответы
Ответ 1
Вам не нужно повторно создавать AVPlayer
для этой задачи. Вы можете просто иметь несколько AVPlayerItem
, а затем переключиться, какой из них осуществляется через [AVPlayer replaceCurrentItemWithPlayerItem:item]
.
Кроме того, вы можете наблюдать, когда текущий элемент изменился с помощью кода ниже.
static void* CurrentItemObservationContext = &CurrentItemObservationContext;
...
После создания игрока зарегистрируйте наблюдателя:
[player1 addObserver:self
forKeyPath:kCurrentItemKey
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:CurrentItemObservationContext];
...
- (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];
}
}
}
Ответ 2
Есть два обходных пути, которые я нашел. Для меня оба подхода работали, и я предпочитаю второй.
Во-первых, как отметил @Alex Kennberg, создайте два набора AVPlayerLayer
и AVPlayer
. и переключая их при переключении между видео. Обязательно установите цвет фона для очистки цвета.
Во-вторых, используйте UIImageView
как вид владельца AVPlayerLayer
. Создайте эскиз видео и установите его в изображение перед переключением видео. Убедитесь, что режим просмотра установлен правильно.
Ответ 3
Я попробовал это, и это сработало для меня.
if (layerView1.playerLayer.superlayer) {
[layerView1.playerLayer removeFromSuperlayer];
}
Но я также выделяю свой собственный AVPlayerLayer вместо того, чтобы использовать IB для этого.