Я бы хотел сделать несколько видео в формате H264 mp4 одновременно для нескольких просмотров. Цель состоит в том, чтобы прочитать около 8 коротких видеороликов, каждое размером 100x100 пикселей, и позволить им одновременно отображать свой контент в нескольких местах на экране.
Представьте себе 24 квадрата на экране, каждый из которых показывает одно видео из пула из 8 видео.
MoviePlayer не работает, поскольку он показывает только одно полноэкранное видео. AVPlayer с несколькими слоями AVPlayerLayers ограничен, потому что только последний созданный слой будет отображать его содержимое на экране (согласно документации и моему тестированию).
Итак, я написал короткий класс видео и создал экземпляр для каждого файла .mp4 в моем пакете, используя AVAssetReader для чтения его содержимого. При обновлении каждый видеокадр извлекается, преобразуется в UIImage и отображается в соответствии с частотой кадров видео. Кроме того, эти изображения кэшируются для быстрого доступа к циклу.
- (id) initWithAsset:(AVURLAsset*)asset withTrack:(AVAssetTrack*)track
{
self = [super init];
if (self)
{
NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA], (NSString*)kCVPixelBufferPixelFormatTypeKey, nil];
mOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:track outputSettings:settings];
mReader = [[AVAssetReader alloc] initWithAsset:asset error:nil];
[mReader addOutput:mOutput];
BOOL status = [mReader startReading];
}
return self;
}
- (void) update:(double)elapsed
{
CMSampleBufferRef buffer = [mOutput copyNextSampleBuffer];
if (buffer)
{
UIImage* image = [self imageFromSampleBuffer:sampleBuffer];
}
[...]
}
На самом деле это работает довольно хорошо, но только для 4 видео. Пятый никогда не появляется. Сначала я подумал о проблемах с памятью, но я протестировал его на следующих устройствах:
- iPhone 3GS
- iPhone 4
- iPad
- iPad 2
У меня было одинаковое поведение на каждом устройстве: 4 видео воспроизводились плавно, без различий
Если бы это была проблема с памятью, я бы ожидал, что по крайней мере либо iPad 2 покажет 5 или 6 видео (из-за более качественного оборудования), либо 3GS покажет только 1, либо где-нибудь произойдет сбой.
Симулятор показывает все видео.
Отладка на устройстве показывает, что
BOOL status = [mReader startReading];
возвращает false для видео 5,6,7 и 8.
Итак, есть ли какая-то аппаратная настройка (или ограничение), которая не допускает более 4 AVAssetReaders одновременно? Потому что я не могу объяснить это поведение. Я не думаю, что все устройства имеют одинаковый объем видеопамяти.