Я работаю над приложением, в котором в фиде есть зацикленные видео (внутри ячеек представления таблицы). Одновременно может присутствовать несколько видео, но может воспроизводиться только одно из них. Я создаю AVPlayer
в фоновом режиме и помещаю их playerLayer
в слой моего представления в качестве подпредставления и воспроизводю видео с наибольшей областью на экране, когда пользователь перестает прокручивать ленту.
Однако недавно я заметил, что видео не отображается в ленте, когда пользователь прекращает прокрутку. Звук начинается сразу, но видео не отображается. Я проверил границы слоя игрока, все в порядке. Я видел AVPlayerLayer показывает черный экран, но звук работает но этот вопрос относится только к более старой версии iOS. Я также видел видео AVPlayer пустое, но слышу звук, но этот вопрос решен поскольку ОП понял, что границы слоя были нулевыми прямоугольниками. Я добавил таймер для повторной печати границ моего видеоплеера, и границы верны, даже если видео не отображается.
После нескольких секунд воспроизведения только со звуком видео начинает воспроизводиться идеально. Я дважды проверил, что «включение» не совпадает с возвратом видео к 0:00. Он просто включается в случайной части видео. Я также перебирал все суперслои, пока не достиг слоя UIWindow
. Иерархия слоев правильно достигает слоя окна, и ни один из промежуточных слоев не имеет нулевого прямоугольника. Кроме того, когда видео запускается случайным образом, никакие из вышеперечисленных данных (суперслои, их прямоугольники) вообще не меняются. Просто чтобы быть уверенным, я добавил следующий код, и я не получаю никаких ошибок утверждения (у меня уже были NSLog
s в нем, так что да, он называется):
timer = [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSAssert(_playerLayer.bounds.size.width, @"bounds");
NSAssert(_playerLayer.bounds.size.height, @"bounds");
NSAssert(!_playerLayer.hidden, @"hidden");
BOOL inWindow = NO;
CALayer *layer = _playerLayer.superlayer;
while(layer){
layer = layer.superlayer;
NSAssert(layer.bounds.size.width, @"bounds");
NSAssert(layer.bounds.size.height, @"bounds");
NSAssert(!layer.hidden, @"hidden");
if(layer == [UIApplication sharedApplication].keyWindow.layer){
inWindow = YES;
break;
}
}
NSAssert(inWindow, @"not in window");
}];
Некоторые наблюдения и резюме:
- Видео всегда воспроизводится правильно с первой попытки. Проблема начинается, когда я играю другое видео, а затем возвращаюсь.
- Ни один из слоев/представлений не имеет нулевого прямоугольника, и он доходит до слоя окна. Я проверяю это в цикле с таймером 10 раз в секунду, и все выглядит идеально.
- Звук начинается сразу, без задержки, даже при последующих «проблемных» воспроизведениях. Вкратце: со звуком проблем нет вообще.
- Видео передаются через Интернет (из нашей собственной корзины S3), но уже загружены, так как их можно воспроизвести до конца и зациклить до того, как начнется проблема, так как проблема все равно не возникает при первом воспроизведении.
- Я использую комбинацию
AVPlayer
/AVPlayerLayer
и не снова создаю новые проигрыватели или слои для одного и того же видео, у меня есть словарь сопоставления URL-адреса с проигрывателем/слоем, и я использую их снова. - У меня iOS 11.2.5 и iPhone X, хотя я также пробовал симулятор, и проблема присутствует, поэтому я не думаю, что это связано с устройством.
В чем может быть проблема?