2013-04-08 37 views
11

Próbuję obrócić wideo przed przesłaniem na moim urządzeniu z systemem iOS, ponieważ inne platformy (takie jak Android) nie interpretują odpowiednio informacji o rotacji w nagraniach wideo iOS, aw rezultacie odtwarzają zostały nieprawidłowo obrócone.AVAssetExportSession ignorowanie wideokompozycji rotacji i usuwania metadanych

Mam spojrzał na następujących stanowiskach stosu, ale nie miał powodzenia zastosowanie któregokolwiek z nich do mojego przypadku:


I poradził sobie próbkę Apple AVSimpleEditor projektu, ale niestety wszystko, co kiedykolwiek się dzieje, po stworzenie AVAssetExportSession i nazywając exportAsynchronouslyWithCompletionHandler nie rotacja jest wykonywana, a co gorsza, metadane obrót jest usuwany z otrzymaną plik.

Oto kod, który działa na eksport:

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

_mutableComposition wartości i _mutableVideoComposition są inicjowane za pomocą tej metody tutaj:

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

wyciągnąłem tę metodę od AVSERotateCommand from here. Czy ktoś może zasugerować, dlaczego ta metoda nie pozwoliłaby na obrócenie mojego filmu o wymagane 90 stopni?

+0

Mam takie same problemy, jak Ty, a sugerowana odpowiedź poniżej (zmiana na AVAssetExportPresetMediumQuality na przykład) nie rozwiązuje problemu. Próbowałem dodać setOpacity: 0 również w warstwieInstruction, ale wydaje się, że instrukcje są ignorowane podczas eksportowania filmu. –

+0

Mam również ten sam problem, czy masz jakieś rozwiązanie? – user3306145

Odpowiedz

6

ponieważ używasz AVAssetExportPresetPassthroughAVAssetExportSession zignoruje videoComposition, użyj dowolnego innego ustawienia.

+0

To już nie ma znaczenia. –