2015-04-28 12 views
7

Ich versuche, eine Video-Galerie zu erstellen.AVAssetImageGenerator Leistungsproblem

Um Videos anzuzeigen verwende ich eine UICollectionView. Jede UICollectionViewCell hat einen Hintergrund mit Video-Miniaturansicht. Um einen Video-Thumbnail zu erzeugen ich eine Methode, mit der Logik bin mit:

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]; 

Ich habe bemerkt, dass generateCGImagesAsynchronouslyForTimes nicht vollständig asynchron arbeiten. Dort wird ein Zeitabstand zwischen dieser Methode aufgerufen. Dies verursacht eine große Verzögerung, während ich Tabellenansichtszellen lade. Wenn ich die Zeile [generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:time]] completionHandler:handler] kommentiere, dann gibt es keine sichtbare Verzögerung (noch Bilder).

Wie kann ich dieses Leistungsproblem lösen?

+0

Können Sie angeben, was genau Lags? Leidet die Scroll-Performance oder dauert es nur sehr lange zwischen der Anfrage und dem Aufruf des Handlers? Können Sie die Ergebnisse des Time Profiler-Instruments hinzufügen? – jszumski

+0

Es gibt Zeit Zwischenräume zwischen 'generateCGImagesAsynchronouslyForTimes' Anrufe ... –

+0

@TomKortney Haben Sie eine Lösung gefunden? mit dem gleichen Problem konfrontiert – Sam

Antwort

3

Der AVAssetImageGeneratorCompletionHandler Block garantiert nicht auf dem Haupt-Thread genannt werden:

Concurrent Programming mit AV Foundation

Callouts von AV Foundation-Invokationen von Blöcken, Schlüssel-Wert-Beobachter, und Benachrichtigungshandler - werden nicht garantiert, dass sie in einem bestimmten Thread oder einer bestimmten Warteschlange ausgeführt werden. Stattdessen ruft AV Foundation diese Handler für Threads oder Warteschlangen auf, auf denen sie ihre internen Aufgaben ausführt. Sie sind dafür verantwortlich, zu testen, ob der Thread oder die Warteschlange, für die ein Handler aufgerufen wird, für die Aufgaben geeignet ist, die Sie ausführen möchten. Wenn dies nicht der Fall ist (z. B. wenn Sie die Benutzeroberfläche aktualisieren möchten und das Callout nicht im Hauptthread ist), müssen Sie die Ausführung Ihrer Aufgaben an einen sicheren Thread oder eine Warteschlange umleiten, die Sie kennen oder die Sie für die Anwendung erstellen Zweck.

Hat success und failure mit dispatch_async Aufruf zu beheben das Problem?

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

'dispatch_async' hinzufügen löst dieses Leistungsproblem nicht. Ich habe immer noch Verzögerungen, sogar mit "dispatch_asinc". –

0

Es gibt eine Reihe von Möglichkeiten, um die asynchrone Bilderzeugungsanfrage zu einem anderen Thread, eine davon ist die Verkapselung der Funktion Umleitung innerhalb eines NSBlockOperation mit der ihrer zugrunde liegenden Warteschlange zu einem NSOperationQueue hinzugefügt gesetzt, was am besten geeignet ist für deine App

Die am besten geeignete Warteschlange sollte relativ einfach zu erraten sein, wenn Sie es nicht wissen, da es dort nur wenige Möglichkeiten gibt.