ios video orientation avassetwriter avassetexportsession

ios - AVAssetExportSession ignorando el video Rotación de la composición y eliminación de metadatos



orientation avassetwriter (1)

Intento girar el video antes de cargarlo en mi dispositivo iOS porque otras plataformas (como Android) no interpretan correctamente la información de rotación en videos grabados con iOS y, como resultado, los reproducen incorrectamente.

He analizado las siguientes publicaciones pero no he tenido éxito en aplicar ninguna de ellas a mi caso:

Cubrí el ejemplo del proyecto Apple AVSimpleEditor , pero desafortunadamente todo lo que sucede es que al crear una AVAssetExportSession y llamar a exportAsynchronouslyWithCompletionHandler, no se realiza ninguna rotación, y lo que es peor, los metadatos de rotación se eliminan del archivo resultante.

Aquí está el código que ejecuta la exportación:

AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:[_mutableComposition copy] presetName:AVAssetExportPresetPassthrough]; exportSession.outputURL = outputURL; exportSession.outputFileType = AVFileType3GPP; exportSession.shouldOptimizeForNetworkUse = YES; exportSession.videoComposition = _mutableVideoComposition; [exportSession exportAsynchronouslyWithCompletionHandler:^(void) { NSLog(@"Status is %d %@", exportSession.status, exportSession.error); handler(exportSession); [exportSession release]; }];

Los valores _mutableComposition y _mutableVideoComposition se inicializan con este método aquí:

- (void) getVideoComposition:(AVAsset*)asset { AVMutableComposition *mutableComposition = nil; AVMutableVideoComposition *mutableVideoComposition = nil; AVMutableVideoCompositionInstruction *instruction = nil; AVMutableVideoCompositionLayerInstruction *layerInstruction = nil; CGAffineTransform t1; CGAffineTransform t2; AVAssetTrack *assetVideoTrack = nil; AVAssetTrack *assetAudioTrack = nil; // Check if the asset contains video and audio tracks if ([[asset tracksWithMediaType:AVMediaTypeVideo] count] != 0) { assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo][0]; } if ([[asset tracksWithMediaType:AVMediaTypeAudio] count] != 0) { assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0]; } CMTime insertionPoint = kCMTimeZero; NSError *error = nil; // Step 1 // Create a composition with the given asset and insert audio and video tracks into it from the asset // Check whether a composition has already been created, i.e, some other tool has already been applied // Create a new composition mutableComposition = [AVMutableComposition composition]; // Insert the video and audio tracks from AVAsset if (assetVideoTrack != nil) { AVMutableCompositionTrack *compositionVideoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetVideoTrack atTime:insertionPoint error:&error]; } if (assetAudioTrack != nil) { AVMutableCompositionTrack *compositionAudioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetAudioTrack atTime:insertionPoint error:&error]; } // Step 2 // Translate the composition to compensate the movement caused by rotation (since rotation would cause it to move out of frame) t1 = CGAffineTransformMakeTranslation(assetVideoTrack.naturalSize.height, 0.0); // Rotate transformation t2 = CGAffineTransformRotate(t1, degreesToRadians(90.0)); // Step 3 // Set the appropriate render sizes and rotational transforms // Create a new video composition mutableVideoComposition = [AVMutableVideoComposition videoComposition]; mutableVideoComposition.renderSize = CGSizeMake(assetVideoTrack.naturalSize.height,assetVideoTrack.naturalSize.width); mutableVideoComposition.frameDuration = CMTimeMake(1, 30); // The rotate transform is set on a layer instruction instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mutableComposition duration]); layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:(mutableComposition.tracks)[0]]; [layerInstruction setTransform:t2 atTime:kCMTimeZero]; // Step 4 // Add the transform instructions to the video composition instruction.layerInstructions = @[layerInstruction]; mutableVideoComposition.instructions = @[instruction]; TT_RELEASE_SAFELY(_mutableComposition); _mutableComposition = [mutableComposition retain]; TT_RELEASE_SAFELY(_mutableVideoComposition); _mutableVideoComposition = [mutableVideoComposition retain]; }

Saqué este método de AVSERotateCommand desde aquí . ¿Alguien puede sugerir por qué este método no rotó con éxito mi video en los 90 grados necesarios?


porque está utilizando AVAssetExportPresetPassthrough través de AVAssetExportPresetPassthrough ignorará el videoComposition , usará cualquier otro preajuste.