Quick 180 rotation of iOS Device results in the camera viewing upside-down

后端 未结 2 923
囚心锁ツ
囚心锁ツ 2021-02-14 05:10

I\'ve implemented the code below to change the orientation of an AVCaptureVideoSession based upon the UIInterfaceOrientation:

- (AVCapt         


        
2条回答
  •  没有蜡笔的小新
    2021-02-14 06:11

    I had the same issue before here what solved my issue.

    I declared a global variable:

    @interface YourViewController ()
    {
        ...
        UIDevice *iOSDevice;
    }
    
    ..
    
    @end
    

    Under implementation (.m file) i declared NSNotification observer under -viewWillAppear like:

    @implementation YourViewController
    
    -(void)viewWillAppear:(BOOL)animated
    {
        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    
        [[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification  object:[UIDevice currentDevice]];
    
    }
    
    -(void)viewWillDisappear:(BOOL)animated
    {
        [[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
    }
    
    - (void)orientationChanged:(NSNotification *)notification
    {
        iOSDevice = notification.object;
    
        previewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation];
    
        //or
    
        [self setAutoVideoConnectionOrientation:YES];
    
    }
    

    I made a function that returns the orientation of the copied current device like:

    Take a loot at my -interfaceOrientationToVideoOrientation method, it converts the iOSDevice.orientation into AVCaptureVideoOrientation same with what you have there..


    (In my case i needed this functions below, but take a look at it might be useful to you for some reason)

    - (AVCaptureVideoOrientation)interfaceOrientationToVideoOrientation
    {
        switch (iOSDevice.orientation) {
    
            case UIInterfaceOrientationPortraitUpsideDown:
    
                return AVCaptureVideoOrientationPortraitUpsideDown;
    
            case UIInterfaceOrientationLandscapeLeft:
    
                return AVCaptureVideoOrientationLandscapeLeft;
    
            case UIInterfaceOrientationLandscapeRight:
    
                return AVCaptureVideoOrientationLandscapeRight;
    
            default:
            case UIDeviceOrientationPortrait:
                return AVCaptureVideoOrientationPortrait;
        }
    }
    
    - (AVCaptureConnection *)setAutoVideoConnectionOrientation:(BOOL)status
    {
        AVCaptureConnection *videoConnection = nil;
    
        //This is for me
        //for (AVCaptureConnection *connection in stillImageOutput.connections) {
    
        //This might be for you
        for (AVCaptureConnection *connection in previewLayer.connection) {
    
            for (AVCaptureInputPort *port in [connection inputPorts])
            {
                if ([[port mediaType] isEqual:AVMediaTypeVideo])
                {
                    videoConnection = connection;
    
                    if (status == YES)
                    {
                        [videoConnection setVideoOrientation:[self interfaceOrientationToVideoOrientation]];
                    }
                    else
                    {
                        [videoConnection setVideoOrientation:AVCaptureVideoOrientationPortrait];
                    }
                }
                if (videoConnection)
                {
                    break;
                }
            }
        }
        return videoConnection;
    }
    

    Edit

    For default orientation: You need to check the "current" orientation.

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        // assuming you finish setting the `previewLayer`
    
        ..
        // after all of that code, when the view is ready for displaying
        // if you implemented this approach the best thing to do is:
    
        // set this 
        iOSDevice = [UIDevice currentDevice];
    
        // then call 
        previewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation];
        // to update the `previewLayer.connection.videoOrientation ` for default orientation        
    
    }
    

    Note:

    Using NSNotificationCenter let the rotation of the device to be settled first before triggered..

    Hope this have help you..

提交回复
热议问题