菜鸟教程小白 发表于 2022-12-12 11:53:28

ios - 使用 AVAsset/AVCaptureSession 的方形视频方向不会从横向变为纵向


                                            <p><p>我正在尝试使用 <code>AVCaptureSession</code> 创建方形视频,并且我成功捕获了视频,但问题是如果我的设备是纵向模式并且我正在捕获视频,那么它的方向记录正确,但如果我的设备是横向的,我捕捉视频我想将此视频方向更改为纵向。以下代码用于在捕获后裁剪视频:</p>

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


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

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

    CGAffineTransform finalTransform = t2;
    ;
    instruction.layerInstructions = ;
    videoComposition.instructions = ;


    NSString *outputPath = ;
    NSURL *exportUrl = ;

    [removeItemAtURL:exportUrl error:nil];


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


    [exporter exportAsynchronouslyWithCompletionHandler:^
   {
         dispatch_async(dispatch_get_main_queue(), ^{
             //Call when finished
             ;
         });
   }];
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我只是通过使用以下代码和步骤来解决问题:</p>

<p>首先我的设备方向是锁定的,我的应用程序只支持纵向,所以我认为我只能获得纵向但是我通过横向模式捕获视频,所以使用 <code>Core-motion</code> 我使用以下方法获取设备方向代码</p>

<p><code>#import <CoreMotion/CoreMotion.h></code></p>

<pre><code>@interface ViewController ()
{
   AVCaptureVideoOrientation orientationLast, orientationAfterProcess;
CMMotionManager *motionManager;
}

@implementation ViewController

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

   
                                        withHandler:^(CMAccelerometerData*accelerometerData, NSError *error) {
                                          if (!error) {
                                                ;
                                          }
                                          else{
                                                NSLog(@&#34;%@&#34;, error);
                                          }
                                        }];
}
- (void)outputAccelertionData:(CMAcceleration)acceleration{
    AVCaptureVideoOrientation orientationNew;

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

    if (orientationNew == orientationLast)
      return;

    orientationLast = orientationNew;
}
</code></pre>

<p>所以基于设备旋转 <code>orientationLast</code> 更新设备方向。之后,当我点击录制视频的按钮时,我设置了 <code>AVCaptureConnection</code> 方向。</p>

<pre><code>AVCaptureConnection *CaptureConnection = ;

    if ()
    {
      ;
    }
</code></pre>

<p>现在拍摄视频后。我做了以下代码的裁剪时间,效果很好。</p>

<pre><code>-(void)cropView:(NSURL*)outputfile
{
   AVAsset *asset = ;


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

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

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

    if (videoSize.width &gt; 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 = ;

    UIImageOrientation videoOrientation = ;

    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(@&#34;no supported orientation has been found in this video&#34;);
            break;
    }

    CGAffineTransform finalTransform = t2;
    ;

    //add the transformer layer instructions, then add to video composition
    instruction.layerInstructions = ;
    videoComposition.instructions = ;


    NSString *outputPath = ;
    NSURL *exportUrl = ;

    [removeItemAtURL:exportUrl error:nil];


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


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

}

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

    if (size.width == txf.tx &amp;&amp; size.height == txf.ty)
      return UIImageOrientationLeft; //return UIInterfaceOrientationLandscapeLeft;
    else if (txf.tx == 0 &amp;&amp; txf.ty == 0)
      return UIImageOrientationRight; //return UIInterfaceOrientationLandscapeRight;
    else if (txf.tx == 0 &amp;&amp; txf.ty == size.width)
      return UIImageOrientationDown; //return UIInterfaceOrientationPortraitUpsideDown;
    else
      return UIImageOrientationUp;//return UIInterfaceOrientationPortrait;
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 使用 AVAsset/AVCaptureSession 的方形视频方向不会从横向变为纵向,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/38912280/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/38912280/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 使用 AVAsset/AVCaptureSession 的方形视频方向不会从横向变为纵向