AVPlayer reproduce el resultado de la composición de video incorrectamente

Necesito una cosa simple:reproducir un video mientras gira y aplicaCIFilter en eso.

Primero, creo el elemento del jugador:

AVPlayerItem *item = [AVPlayerItem playerItemWithURL:videoURL];

// DEBUG LOGGING
AVAssetTrack *track = [[item.asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
NSLog(@"Natural size is: %@", NSStringFromCGSize(track.naturalSize));
NSLog(@"Preffered track transform is: %@", NSStringFromCGAffineTransform(track.preferredTransform));
NSLog(@"Preffered asset transform is: %@", NSStringFromCGAffineTransform(item.asset.preferredTransform));

Entonces necesito aplicar la composición del video. Originalmente, estaba pensando en crear unAVVideoComposition con 2 instrucciones, una será laAVVideoCompositionLayerInstruction para la rotación y el otro seráCIFilter solicitud. Sin embargo, recibí una excepción diciendo"Esperar que la composición de video contenga solo AVCoreImageFilterVideoCompositionInstruction" lo que significa que Apple no permite combinar esas 2 instrucciones. Como resultado, combiné ambos bajo el filtrado, aquí está el código:

AVAsset *asset = playerItem.asset;
CGAffineTransform rotation = [self transformForItem:playerItem];

AVVideoComposition *composition = [AVVideoComposition videoCompositionWithAsset:asset applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest * _Nonnull request) {
    // Step 1: get the input frame image (screenshot 1)
    CIImage *sourceImage = request.sourceImage;

    // Step 2: rotate the frame
    CIFilter *transformFilter = [CIFilter filterWithName:@"CIAffineTransform"];
    [transformFilter setValue:sourceImage forKey: kCIInputImageKey];
    [transformFilter setValue: [NSValue valueWithCGAffineTransform: rotation] forKey: kCIInputTransformKey];
    sourceImage = transformFilter.outputImage;
    CGRect extent = sourceImage.extent;
    CGAffineTransform translation = CGAffineTransformMakeTranslation(-extent.origin.x, -extent.origin.y);
    [transformFilter setValue:sourceImage forKey: kCIInputImageKey];
    [transformFilter setValue: [NSValue valueWithCGAffineTransform: translation] forKey: kCIInputTransformKey];
    sourceImage = transformFilter.outputImage;

    // Step 3: apply the custom filter chosen by the user
    extent = sourceImage.extent;
    sourceImage = [sourceImage imageByClampingToExtent];
    [filter setValue:sourceImage forKey:kCIInputImageKey];
    sourceImage = filter.outputImage;
    sourceImage = [sourceImage imageByCroppingToRect:extent];

    // Step 4: finish processing the frame (screenshot 2)
    [request finishWithImage:sourceImage context:nil];
}];

playerItem.videoComposition = composition;

Las capturas de pantalla que hice durante la depuración muestran que la imagen se ha rotado con éxito y se aplica el filtro (en este ejemplo, se trataba de un filtro de identidad que no cambia la imagen). Aquí están la captura de pantalla 1 y la captura de pantalla 2 que se tomaron en los puntos marcados en los comentarios anteriores:

Como puede ver, la rotación es exitosa, la extensión del marco resultante también fue correcta.

El problema comienza cuando intento reproducir este video en un reproductor. Esto es lo que obtengo:

Parece que todos los cuadros están escalados y desplazados hacia abajo. El área verde es la información del marco vacío, cuando lo aprieto para hacer que el marco tenga un tamaño infinito, muestra píxeles de borde en lugar de verde. Tengo la sensación de que el jugador todavía toma información de tamaño anterior antes de la rotación delAVPlayerItem, es por eso que en el primer fragmento de código anterior estaba registrando los tamaños y las transformaciones, están los registros:

Natural size is: {1920, 1080}
Preffered track transform is: [0, 1, -1, 0, 1080, 0]
Preffered asset transform is: [1, 0, 0, 1, 0, 0]

El reproductor está configurado así:

layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
layer.needsDisplayOnBoundsChange = YES;

TENGA EN CUENTA lo más importante: esto solo sucede con los videos que fueron grabados por la aplicación usando la cámaraen el paisaje iPhone [6s] orientación y guardado en el almacenamiento del dispositivo anteriormente. Los videos que la aplicación graba en modo vertical están totalmente bien (por cierto, ¡los videos de retrato tienen exactamente el mismo tamaño y se transforman en el registro como videos de paisajes! Extraño ... tal vez el iPhone pone la información de rotación en el video y lo arregla). Por lo tanto, hacer zoom y cambiar el video parece una combinación de "relleno de aspecto" e información de resolución anterior antes de la rotación. Por cierto, los cuadros de video de retrato se muestran parcialmente debido a la escala para llenar el área del reproductor que tiene una relación de aspecto diferente, pero este es el comportamiento esperado.

Déjame saber lo que piensas sobre esto y, si conoces una mejor manera de lograr lo que necesito, sería genial saberlo.

Respuestas a la pregunta(1)

Su respuesta a la pregunta