2013-04-08 13 views
11

Sto tentando di ruotare il video prima di caricarlo sul mio dispositivo iOS perché altre piattaforme (come Android) non interpretano correttamente le informazioni di rotazione nei video registrati da iOS e, di conseguenza, riproducono ruotati impropriamente.AVAssetExportSession ignora videoComposizione rotazione e stripping metadati

Ho guardato i seguenti posti di stack, ma non ho avuto successo applicare qualsiasi di loro per il mio caso:


ho affrontato il campione Apple AVSimpleEditor progetto, ma purtroppo tutto ciò che accade mai è, sulla creazione di un AVAssetExportSession e chiamando exportAsynchronouslyWithCompletionHandler, non viene eseguita alcuna rotazione, e quel che è peggio, i metadati di rotazione è spogliato fuori dalla risultante file.

Ecco il codice che viene eseguito l'esportazione:

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

I valori _mutableComposition e _mutableVideoComposition vengono inizializzati con questo metodo qui:

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

ho tirato questo metodo da AVSERotateCommand from here. Qualcuno può suggerire perché questo metodo non potrebbe ruotare il mio video con i necessari 90 gradi?

+0

Ho gli stessi problemi che ho riscontrato e la risposta suggerita di seguito (passando ad AVAssetExportPresetMediumQuality per esempio) non risolve il problema. Ho provato ad aggiungere setOpacity: 0 anche a layerInstruction, ma sembra che le istruzioni vengano ignorate durante l'esportazione del film. –

+0

ho anche lo stesso problema, hai qualche soluzione? – user3306145

risposta

6

poiché si utilizza AVAssetExportPresetPassthrough il AVAssetExportSession ignorerà videoComposition, utilizzare qualsiasi altra preimpostazione.

+0

Questo non sembra fare più alcuna differenza. –

Problemi correlati