Cambio rápido entre videos usando AVFoundation
Estoy escribiendo una aplicación donde el usuario puede grabar hasta 6 videoclips cada uno con una duración de 2 segundos. Cuando se graban los videoclips, el usuario puede jugar con ellos usando 6 botones, uno para cada clip. El usuario puede grabar una película cambiando entre los 6 clips. El problema es que necesito un cambio casi instantáneo entre los 6 clips cuando el usuario presiona un botón; de lo contrario, se pierde la ilusión de jugar con los clips; la funcionalidad es algo similar a la aplicación llamada CamBox en la App Store.
Primero intenté inicializar cada clip con AVAsset en un AvPlayerItem en un AVPlayer cada vez que el usuario presionaba un botón. La salida del reproductor se dirigió a un AVPlayerLayer en mi vista principal. El problema es que el tiempo que tarda en cargarse y comenzar a reproducirse es bastante largo, lo que significa que el video se retrasa cuando el usuario presiona los botones en rápida sucesión.
I decidí intentar precargar todos los clips usando 5 AVPlayers y 5 AVPlayerLayers. Los 5 PlayerLayers se insertan en mi vista principal y cuando el usuario presiona un botón, el AVPlayer que se está reproduciendo se detiene y se rebobina y el AVPlayerLayer actualmente visible se oculta. Se inicia el nuevo AVPlayer y se muestra el AVPlayerLayer correspondiente. Funciona bastante bien, es mucho más rápido que mi primera solución, aunque no es instantánea, pero el problema es que solo puedo precargar 4 clips, lo que significa que cuando el usuario presiona el botón que reproduce los dos últimos, se retrasa mucho. A continuación se muestra mi código para precargar los clips
-(void)loadVideos
{
layers = [[NSMutableArray alloc] initWithCapacity:6];
players = [[NSMutableArray alloc] initWithCapacity:6];
for(int i = 1; i < 7; i++)
{
NSURL* fileURL = [NSURL fileURLWithPath:[self getFileName:i]];
AVPlayerItem* avPlayerItem = [[[AVPlayerItem alloc] initWithURL:fileURL] autorelease];
[avPlayerItem addObserver:self forKeyPath:@"status" options:0 context:nil];
AVPlayer *avPlayer = [[[AVPlayer alloc] initWithPlayerItem:avPlayerItem] autorelease];
[avPlayer addObserver:self forKeyPath:@"status" options:0 context:nil];
[avPlayer addObserver:self forKeyPath:@"currentItem" options:0 context:nil];
AVPlayerLayer* layer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
layer.frame = self.playerView.bounds;
[playerView.layer addSublayer:layer];
[layers addObject:layer];
[players addObject:avPlayer];
layer.hidden = YES;
}
}
El controlador de eventos para los 6 botones se ve así:
- (IBAction)takeBtnClicked:(id)sender {
int tag = ((UIButton*)sender).tag;
AVPlayer* player;
AVPlayerLayer* layer;
if (layerIndex > -1) {
player = [players objectAtIndex:layerIndex];
layer = [layers objectAtIndex:layerIndex];
[player pause];
layer.hidden = YES;
[player seekToTime:kCMTimeZero];
}
layerIndex = tag-1;
player = [players objectAtIndex:layerIndex];
layer = [layers objectAtIndex:layerIndex];
[player play];
layer.hidden = NO;
}
Estoy seguro de que la limitación de 4 videoclips precargados es una limitación de hardware, pero cuál es la alternativa. ¿Alguien tiene alguna idea? Gracias por adelantado