Reputation: 505
I having app that records a video.
To handle phone rotation I have the following code:
// called on phone rotation
AVCaptureConnection *previewLayerConnection = [[self previewLayer] connection];
if ([previewLayerConnection isVideoOrientationSupported]) {
[previewLayerConnection setVideoOrientation:[self getVideoOrientation]];
}
and getVideoOrientation function:
- (AVCaptureVideoOrientation) getVideoOrientation {
UIInterfaceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
AVCaptureVideoOrientation newOrientation = AVCaptureVideoOrientationPortrait;
switch (deviceOrientation) {
case UIInterfaceOrientationPortrait:
NSLog(@"UIInterfaceOrientationPortrait");
newOrientation = AVCaptureVideoOrientationPortrait;
break;
case UIInterfaceOrientationLandscapeLeft:
NSLog(@"UIInterfaceOrientationLandscapeRight");
newOrientation = AVCaptureVideoOrientationLandscapeLeft;
break;
case UIInterfaceOrientationLandscapeRight:
NSLog(@"UIInterfaceOrientationLandscapeLeft");
newOrientation = AVCaptureVideoOrientationLandscapeRight;
break;
default:
NSLog(@"default");
newOrientation = AVCaptureVideoOrientationPortrait;
break;
}
return newOrientation;
}
This part of the app works properly (I see video as I should on any device orientation). But when I try to make a thumbnail (or play video) I have problems.
As I've read in other questions I do the following for each track:
AVAssetTrack* videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CGAffineTransform txf = [videoTrack preferredTransform];
CGFloat videoAngleInDegree = RadiansToDegrees(atan2(txf.b, txf.a));
if (txf.a == 0 && txf.b == 1.0 && txf.c == -1.0 && txf.d == 0) {
thumbOrientation = UIImageOrientationLeft;
}
if (txf.a == 0 && txf.b == -1.0 && txf.c == 1.0 && txf.d == 0) {
thumbOrientation = UIImageOrientationRight;
}
if (txf.a == 1.0 && txf.b == 0 && txf.c == 0 && txf.d == 1.0) {
thumbOrientation = UIImageOrientationUp;
}
if (txf.a == -1.0 && txf.b == 0 && txf.c == 0 && txf.d == -1.0) {
thumbOrientation = UIImageOrientationDown;
}
UIImage *image = [UIImage imageWithCGImage:im scale:1.0 orientation:thumbOrientation];
I have 2 sample files: 1 - landscape right, 2 - landscape left. I expect they have different orientations in code above, but unexpectedly they have the same (and videoAngleInDegree is the same for both of them).
Are there any workarounds?
Upvotes: 7
Views: 1549
Reputation: 4770
Are you sure it's working properly? The getVideoOrientation
there looks wrong -- AVCapture and UIDevice have opposite meanings for landscape left and right.
Here is a correct implementation from this question -- check the discussion there out and see if it helps.
- (void)deviceOrientationDidChange{
UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
AVCaptureVideoOrientation newOrientation;
if (deviceOrientation == UIDeviceOrientationPortrait){
NSLog(@"deviceOrientationDidChange - Portrait");
newOrientation = AVCaptureVideoOrientationPortrait;
}
else if (deviceOrientation == UIDeviceOrientationPortraitUpsideDown){
NSLog(@"deviceOrientationDidChange - UpsideDown");
newOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
}
// AVCapture and UIDevice have opposite meanings for landscape left and right (AVCapture orientation is the same as UIInterfaceOrientation)
else if (deviceOrientation == UIDeviceOrientationLandscapeLeft){
NSLog(@"deviceOrientationDidChange - LandscapeLeft");
newOrientation = AVCaptureVideoOrientationLandscapeRight;
}
else if (deviceOrientation == UIDeviceOrientationLandscapeRight){
NSLog(@"deviceOrientationDidChange - LandscapeRight");
newOrientation = AVCaptureVideoOrientationLandscapeLeft;
}
else if (deviceOrientation == UIDeviceOrientationUnknown){
NSLog(@"deviceOrientationDidChange - Unknown ");
newOrientation = AVCaptureVideoOrientationPortrait;
}
else{
NSLog(@"deviceOrientationDidChange - Face Up or Down");
newOrientation = AVCaptureVideoOrientationPortrait;
}
[self setOrientation:newOrientation];
}
Upvotes: 2