2016-08-12 2 views
2

Ich versuche ein quadratisches Video mit AVCaptureSession zu erstellen und erhalte erfolgreich Video, aber das Problem ist, dass wenn mein Gerät im Hochformat ist und ich Videos dann einspiele Die Ausrichtung ist korrekt, aber wenn mein Gerät im Querformat ist und ich Videoaufnahmen mache, möchte ich diese Videoausrichtung in Hochformat ändern. Im Anschluss an Code, den ich für den Pflanzenbau verwende ein Video nach der Aufnahme:Viereckige Videoausrichtung ändert sich nicht von Querformat zu Hochformat mit AVAsset/AVCaptureSession

-(void)cropView:(NSURL*)outputfile 
{ 
    AVAsset *asset = [AVAsset assetWithURL:outputfile]; 
    AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition]; 
    videoComposition.frameDuration = CMTimeMake(1, 30); 
    videoComposition.renderSize =CGSizeMake(clipVideoTrack.naturalSize.height, clipVideoTrack.naturalSize.height); 


    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30)); 

    // rotate to portrait 
    AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack]; 
    CGAffineTransform t1 = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.height, -(clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height) /2); 
    CGAffineTransform t2 = CGAffineTransformRotate(t1, M_PI_2); 

    CGAffineTransform finalTransform = t2; 
    [transformer setTransform:finalTransform atTime:kCMTimeZero]; 
    instruction.layerInstructions = [NSArray arrayWithObject:transformer]; 
    videoComposition.instructions = [NSArray arrayWithObject: instruction]; 


    NSString *outputPath = [NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), @"video.mp4"]; 
    NSURL *exportUrl = [NSURL fileURLWithPath:outputPath]; 

    [[NSFileManager defaultManager] removeItemAtURL:exportUrl error:nil]; 


    //Export 
    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality] ; 
    exporter.videoComposition = videoComposition; 
    exporter.outputURL = exportUrl; 
    exporter.outputFileType = AVFileTypeMPEG4; 


    [exporter exportAsynchronouslyWithCompletionHandler:^ 
    { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      //Call when finished 
      [self exportDidFinish:exporter]; 
     }); 
    }]; 
} 

Antwort

2

ich nur das Problem beheben, indem Folge Code und Schritte:

Zuerst mein Gerät Orientierung ist Schloss und meine app ist nur im Hochformat so unterstützen i ich glaube, ich Video von Landschaftsmodus erfassen jedoch nur im Hochformat erhalten so Core-motion mit i folgenden Code

#import <CoreMotion/CoreMotion.h>

@interface ViewController() 
{ 
    AVCaptureVideoOrientation orientationLast, orientationAfterProcess; 
    CMMotionManager *motionManager; 
} 

@implementation ViewController 

- (void)initializeMotionManager{ 
    motionManager = [[CMMotionManager alloc] init]; 
    motionManager.accelerometerUpdateInterval = .2; 
    motionManager.gyroUpdateInterval = .2; 

    [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] 
             withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { 
              if (!error) { 
               [self outputAccelertionData:accelerometerData.acceleration]; 
              } 
              else{ 
               NSLog(@"%@", error); 
              } 
             }]; 
} 
- (void)outputAccelertionData:(CMAcceleration)acceleration{ 
    AVCaptureVideoOrientation orientationNew; 

    if (acceleration.x >= 0.75) { 
     orientationNew = AVCaptureVideoOrientationLandscapeLeft; 
    } 
    else if (acceleration.x <= -0.75) { 
     orientationNew =AVCaptureVideoOrientationLandscapeRight; 
    } 
    else if (acceleration.y <= -0.75) { 
     orientationNew =AVCaptureVideoOrientationPortrait; 
    } 
    else if (acceleration.y >= 0.75) { 
     orientationNew =AVCaptureVideoOrientationPortraitUpsideDown; 
    } 
    else { 
     // Consider same as last time 
     return; 
    } 

    if (orientationNew == orientationLast) 
     return; 

    orientationLast = orientationNew; 
} 
bekommen Geräteausrichtung mit

basierend auf der Gerätedrehung, die orientationLast Gerät Ausrichtung aktualisieren. Danach, wenn ich Knopf für Videoaufnahme tippe, stelle ich die AVCaptureConnection Orientierung ein.

AVCaptureConnection *CaptureConnection = [MovieFileOutput connectionWithMediaType:AVMediaTypeVideo]; 

    if ([CaptureConnection isVideoOrientationSupported]) 
    { 
     [CaptureConnection setVideoOrientation:orientationLast]; 
    } 

Jetzt nach Videoaufnahme. Erntezeit Ich habe folgenden Code und das funktioniert perfekt.

-(void)cropView:(NSURL*)outputfile 
{ 
    AVAsset *asset = [AVAsset assetWithURL:outputfile]; 


    AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition]; 
    videoComposition.frameDuration = CMTimeMake(1, 30); 

    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30)); 

    CGSize videoSize = [[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize]; 
    float scaleFactor; 

    if (videoSize.width > videoSize.height) { 

     scaleFactor = videoSize.height/320; 
    } 
    else if (videoSize.width == videoSize.height){ 

     scaleFactor = videoSize.height/320; 
    } 
    else{ 
     scaleFactor = videoSize.width/320; 
    } 



    CGFloat cropOffX = 0; 
    CGFloat cropOffY = 0; 
    CGFloat cropWidth = 320 *scaleFactor; 
    CGFloat cropHeight = 320 *scaleFactor; 

    videoComposition.renderSize = CGSizeMake(cropWidth, cropHeight); 

    AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack]; 

    UIImageOrientation videoOrientation = [self getVideoOrientationFromAsset:asset]; 

    CGAffineTransform t1 = CGAffineTransformIdentity; 
    CGAffineTransform t2 = CGAffineTransformIdentity; 

    switch (videoOrientation) { 
     case UIImageOrientationUp: 
      t1 = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.height - cropOffX, 0 - cropOffY); 
      t2 = CGAffineTransformRotate(t1, M_PI_2); 
      break; 
     case UIImageOrientationDown: 
      t1 = CGAffineTransformMakeTranslation(0 - cropOffX, clipVideoTrack.naturalSize.width - cropOffY); // not fixed width is the real height in upside down 
      t2 = CGAffineTransformRotate(t1, - M_PI_2); 
      break; 
     case UIImageOrientationRight: 
      t1 = CGAffineTransformMakeTranslation(0 - cropOffX, 0 - cropOffY); 
      t2 = CGAffineTransformRotate(t1, 0); 
      break; 
     case UIImageOrientationLeft: 
      t1 = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.width - cropOffX, clipVideoTrack.naturalSize.height - cropOffY); 
      t2 = CGAffineTransformRotate(t1, M_PI ); 
      break; 
     default: 
      NSLog(@"no supported orientation has been found in this video"); 
      break; 
    } 

    CGAffineTransform finalTransform = t2; 
    [transformer setTransform:finalTransform atTime:kCMTimeZero]; 

    //add the transformer layer instructions, then add to video composition 
    instruction.layerInstructions = [NSArray arrayWithObject:transformer]; 
    videoComposition.instructions = [NSArray arrayWithObject: instruction]; 


    NSString *outputPath = [NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), @"video.mp4"]; 
    NSURL *exportUrl = [NSURL fileURLWithPath:outputPath]; 

    [[NSFileManager defaultManager] removeItemAtURL:exportUrl error:nil]; 


    //Export 
    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality] ; 
    exporter.videoComposition = videoComposition; 
    exporter.outputURL = exportUrl; 
    exporter.outputFileType = AVFileTypeMPEG4; 


    [exporter exportAsynchronouslyWithCompletionHandler:^ 
    { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      //Call when finished 
      [self exportDidFinish:exporter]; 
     }); 
    }]; 

} 

- (UIImageOrientation)getVideoOrientationFromAsset:(AVAsset *)asset 
{ 
    AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    CGSize size = [videoTrack naturalSize]; 
    CGAffineTransform txf = [videoTrack preferredTransform]; 

    if (size.width == txf.tx && size.height == txf.ty) 
     return UIImageOrientationLeft; //return UIInterfaceOrientationLandscapeLeft; 
    else if (txf.tx == 0 && txf.ty == 0) 
     return UIImageOrientationRight; //return UIInterfaceOrientationLandscapeRight; 
    else if (txf.tx == 0 && txf.ty == size.width) 
     return UIImageOrientationDown; //return UIInterfaceOrientationPortraitUpsideDown; 
    else 
     return UIImageOrientationUp; //return UIInterfaceOrientationPortrait; 
} 
Verwandte Themen