Проблема производительности AVAssetImageGenerator

Я пытаюсь создать видео галерею.

Для отображения видео я использую UICollectionView, каждый UICollectionViewCell имеет фон с миниатюрой видео. Для создания миниатюры видео я использую метод с логикой:

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];

AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

generator.appliesPreferredTrackTransform = YES;

CMTime time = CMTimeMakeWithSeconds(0,15);

AVAssetImageGeneratorCompletionHandler handler = ^(CMTime timeRequested, CGImageRef image, CMTime timeActual, AVAssetImageGeneratorResult result, NSError *error)
{
    NSLog(@"handler^()");

    if (result == AVAssetImageGeneratorSucceeded)
    {
        thumbnail = [UIImage imageWithCGImage: image];

        success(thumbnail);
    }

    else
    {
        failure(error);
    }
};

CGSize maximumSize = CGSizeMake(CLIPBOARD_COLLECTION_VIEW_CELL_WIDTH, CLIPBOARD_COLLECTION_VIEW_CELL_HEIGHT);

generator.maximumSize = maximumSize;

NSLog(@"generateCGImagesAsynchronouslyForTimes:");
[generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:time]] completionHandler:handler];

Я заметил что generateCGImagesAsynchronouslyForTimes не работает полностью асинхронно. Между вызовами этого метода есть промежуток времени. Это вызывает большую задержку при загрузке ячеек табличного представления. Если я прокомментирую строку [generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:time]] completionHandler:handler] тогда нет видимых лагов (ни изображений).

Как я могу решить эту проблему производительности?

2 ответа

AVAssetImageGeneratorCompletionHandler блок не гарантированно вызывается в главном потоке:

Параллельное программирование с AV Foundation

Вызовы из AV Foundation - вызовы блоков, наблюдателей значения ключа и обработчиков уведомлений - не гарантированно выполняются в каком-либо конкретном потоке или очереди. Вместо этого AV Foundation вызывает эти обработчики в потоках или очередях, в которых он выполняет свои внутренние задачи. Вы несете ответственность за проверку соответствия потока или очереди, в которой вызывается обработчик, задачам, которые вы хотите выполнить. Если это не так (например, если вы хотите обновить пользовательский интерфейс, а выноска отсутствует в главном потоке), вы должны перенаправить выполнение ваших задач в безопасный поток или очередь, которые вы распознаете, или которые вы создаете для цель.

Звонит success а также failure с dispatch_async исправить проблему?

dispatch_async(dispatch_get_main_queue(), ^{
    if (success) {
        success();
    }
)};

Существует несколько способов перенаправить запрос асинхронной генерации изображения в другой поток, одним из которых является инкапсуляция функции в NSBlockOperation, добавленной в NSOperationQueue с базовой очередью, настроенной на то, что наиболее подходит для вашего приложения.

Наиболее подходящую очередь должно быть относительно легко угадать, если вы не знаете, так как там только несколько вариантов.

Другие вопросы по тегам