更改相机和设备方向

时间:2013-05-09 11:41:06

标签: ios objective-c ios6 rotation

我有一个基本上是视图的应用程序,当用户点击按钮时,摄像头可视化开始。

我希望在未显示相机时允许所有方向,但是当显示相机时,我需要强制应用程序进入纵向模式,因为如果它不在Portrait上,则视频会旋转。当相机关闭时,应用程序可能会再次旋转。

您知道我是否可以通过视频方向解决问题?

或者我如何强制应用程序进入纵向模式?我知道在早期的ios版本中,您可以使用[UIDevice setOrientation:],但是对于最新的ios,它已被弃用。

我如何为ios 5和ios 6执行此操作?

我试过了:

[self presentViewController:[UIViewController new] animated:NO 
completion:^{ [self dismissViewControllerAnimated:NO completion:nil]; }]; 

并在shouldAutorotateToInterfaceOrientation方法中:

if (state == CAMERA) {
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }else{
        return YES;
}

它工作正常并强制应用程序为肖像。但是当相机关闭时,它不能正常工作,它不能很好地旋转。

我的意思是,当相机关闭时,会发生这种情况:

  • 应用程序处于纵向
  • 如果我尝试旋转应用程序,则会旋转设备但不会旋转应用程序。我可以看到ipad的状态栏有关时间,电池等的信息被旋转但应用程序没有。
  • 如果我再次进入肖像画然后旋转设备,它就可以了。

你知道可能是什么问题吗?

提前致谢。

2 个答案:

答案 0 :(得分:3)

我想我已经找到了解决相机更换和设备方向问题的解决方案。

我在初始化相机时调用此代码,也在shouldAutorotateToInterfaceOrientation方法中调用此代码,我允许所有方向。

 AVCaptureVideoOrientation newOrientation;

    UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    NSLog(@"deviceOrientation %c",deviceOrientation);

    switch (deviceOrientation)
    {
        case UIInterfaceOrientationPortrait:
            NSLog(@"UIInterfaceOrientationPortrait");
            newOrientation = AVCaptureVideoOrientationPortrait;
            break;
        case UIInterfaceOrientationLandscapeRight:
            NSLog(@"UIInterfaceOrientationLandscapeRight");
            newOrientation = AVCaptureVideoOrientationLandscapeRight;
            break;
        case UIInterfaceOrientationLandscapeLeft:
            NSLog(@"UIInterfaceOrientationLandscapeLeft");
            newOrientation = AVCaptureVideoOrientationLandscapeLeft;
            break;
        default:
            NSLog(@"default");
            newOrientation = AVCaptureVideoOrientationPortrait;
            break;
    }

    if ([self.prevLayer respondsToSelector:@selector(connection)]){
        if ([self.prevLayer.connection isVideoOrientationSupported]){
            self.prevLayer.connection.videoOrientation = newOrientation;
        }else{
            NSLog(@"NO respond to selector connection");
        }
    }else{


if ([self.prevLayer isOrientationSupported]){
        self.prevLayer.orientation = newOrientation;
    }else{
        NSLog(@"NO isOrientationSupported");
    }

}

答案 1 :(得分:1)

请尝试使用以下代码进行定位,以便我认为您的问题可以解决。

   - (void)encodeVideoOrientation:(NSURL *)anOutputFileURL
    {
    CGAffineTransform rotationTransform;
    CGAffineTransform rotateTranslate;
    CGSize renderSize;

    switch (self.recordingOrientation)
    {
        // set these 3 values based on orientation

    }


    AVURLAsset * videoAsset = [[AVURLAsset alloc]initWithURL:anOutputFileURL options:nil];

    AVAssetTrack *sourceVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    AVAssetTrack *sourceAudioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

    AVMutableComposition* composition = [AVMutableComposition composition];

    AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                                   ofTrack:sourceVideoTrack
                                    atTime:kCMTimeZero error:nil];
    [compositionVideoTrack setPreferredTransform:sourceVideoTrack.preferredTransform];

    AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                                preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                                   ofTrack:sourceAudioTrack
                                    atTime:kCMTimeZero error:nil];



    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack];
    [layerInstruction setTransform:rotateTranslate atTime:kCMTimeZero];

    AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.frameDuration = CMTimeMake(1,30);
    videoComposition.renderScale = 1.0;
    videoComposition.renderSize = renderSize;
    instruction.layerInstructions = [NSArray arrayWithObject: layerInstruction];
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);
    videoComposition.instructions = [NSArray arrayWithObject: instruction];

    AVAssetExportSession * assetExport = [[AVAssetExportSession alloc] initWithAsset:composition
                                                                          presetName:AVAssetExportPresetMediumQuality];

    NSString* videoName = @"export.mov";
    NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName];

    NSURL * exportUrl = [NSURL fileURLWithPath:exportPath];

    if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath])
    {
        [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
    }

    assetExport.outputFileType = AVFileTypeMPEG4;
    assetExport.outputURL = exportUrl;
    assetExport.shouldOptimizeForNetworkUse = YES;
    assetExport.videoComposition = videoComposition;

    [assetExport exportAsynchronouslyWithCompletionHandler:
     ^(void ) {
         switch (assetExport.status)
         {
             case AVAssetExportSessionStatusCompleted:
                 //                export complete
                 NSLog(@"Export Complete");
                 break;
             case AVAssetExportSessionStatusFailed:
                 NSLog(@"Export Failed");
                 NSLog(@"ExportSessionError: %@", [assetExport.error localizedDescription]);
                 //                export error (see exportSession.error)
                 break;
             case AVAssetExportSessionStatusCancelled:
                 NSLog(@"Export Failed");
                 NSLog(@"ExportSessionError: %@", [assetExport.error localizedDescription]);
                 //                export cancelled
                 break;
         }
     }];

    }

希望这可以帮助你。!!