@@ -345,6 +345,7 @@ @interface FLTCam : NSObject <FlutterTexture,
345
345
346
346
@implementation FLTCam {
347
347
dispatch_queue_t _dispatchQueue;
348
+ UIDeviceOrientation _deviceOrientation;
348
349
}
349
350
// Format used for video and image streaming.
350
351
FourCharCode videoFormat = kCVPixelFormatType_32BGRA ;
@@ -353,6 +354,7 @@ @implementation FLTCam {
353
354
- (instancetype )initWithCameraName : (NSString *)cameraName
354
355
resolutionPreset : (NSString *)resolutionPreset
355
356
enableAudio : (BOOL )enableAudio
357
+ orientation : (UIDeviceOrientation)orientation
356
358
dispatchQueue : (dispatch_queue_t )dispatchQueue
357
359
error : (NSError **)error {
358
360
self = [super init ];
@@ -370,6 +372,7 @@ - (instancetype)initWithCameraName:(NSString *)cameraName
370
372
_exposureMode = ExposureModeAuto;
371
373
_focusMode = FocusModeAuto;
372
374
_lockedCaptureOrientation = UIDeviceOrientationUnknown;
375
+ _deviceOrientation = orientation;
373
376
374
377
NSError *localError = nil ;
375
378
_captureVideoInput = [AVCaptureDeviceInput deviceInputWithDevice: _captureDevice
@@ -389,10 +392,11 @@ - (instancetype)initWithCameraName:(NSString *)cameraName
389
392
AVCaptureConnection *connection =
390
393
[AVCaptureConnection connectionWithInputPorts: _captureVideoInput.ports
391
394
output: _captureVideoOutput];
395
+
392
396
if ([_captureDevice position ] == AVCaptureDevicePositionFront) {
393
397
connection.videoMirrored = YES ;
394
398
}
395
- connection. videoOrientation = AVCaptureVideoOrientationLandscapeRight;
399
+
396
400
[_captureSession addInputWithNoConnections: _captureVideoInput];
397
401
[_captureSession addOutputWithNoConnections: _captureVideoOutput];
398
402
[_captureSession addConnection: connection];
@@ -406,6 +410,8 @@ - (instancetype)initWithCameraName:(NSString *)cameraName
406
410
[_motionManager startAccelerometerUpdates ];
407
411
408
412
[self setCaptureSessionPreset: _resolutionPreset];
413
+ [self updateOrientation ];
414
+
409
415
return self;
410
416
}
411
417
@@ -417,6 +423,40 @@ - (void)stop {
417
423
[_captureSession stopRunning ];
418
424
}
419
425
426
+ - (void )setDeviceOrientation : (UIDeviceOrientation)orientation {
427
+ if (_deviceOrientation == orientation) {
428
+ return ;
429
+ }
430
+
431
+ _deviceOrientation = orientation;
432
+ [self updateOrientation ];
433
+ }
434
+
435
+ - (void )updateOrientation {
436
+ if (_isRecording) {
437
+ return ;
438
+ }
439
+
440
+ UIDeviceOrientation orientation = (_lockedCaptureOrientation != UIDeviceOrientationUnknown)
441
+ ? _lockedCaptureOrientation
442
+ : _deviceOrientation;
443
+
444
+ [self updateOrientation: orientation forCaptureOutput: _capturePhotoOutput];
445
+ [self updateOrientation: orientation forCaptureOutput: _captureVideoOutput];
446
+ }
447
+
448
+ - (void )updateOrientation : (UIDeviceOrientation)orientation
449
+ forCaptureOutput : (AVCaptureOutput *)captureOutput {
450
+ if (!captureOutput) {
451
+ return ;
452
+ }
453
+
454
+ AVCaptureConnection *connection = [captureOutput connectionWithMediaType: AVMediaTypeVideo];
455
+ if (connection && connection.isVideoOrientationSupported ) {
456
+ connection.videoOrientation = [self getVideoOrientationForDeviceOrientation: orientation];
457
+ }
458
+ }
459
+
420
460
- (void )captureToFile : (FlutterResult)result API_AVAILABLE(ios(10 )) {
421
461
AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings ];
422
462
if (_resolutionPreset == max) {
@@ -437,18 +477,6 @@ - (void)captureToFile:(FlutterResult)result API_AVAILABLE(ios(10)) {
437
477
return ;
438
478
}
439
479
440
- AVCaptureConnection *connection = [_capturePhotoOutput connectionWithMediaType: AVMediaTypeVideo];
441
-
442
- if (connection) {
443
- if (_lockedCaptureOrientation != UIDeviceOrientationUnknown) {
444
- connection.videoOrientation =
445
- [self getVideoOrientationForDeviceOrientation: _lockedCaptureOrientation];
446
- } else {
447
- connection.videoOrientation =
448
- [self getVideoOrientationForDeviceOrientation: [[UIDevice currentDevice ] orientation ]];
449
- }
450
- }
451
-
452
480
[_capturePhotoOutput capturePhotoWithSettings: settings
453
481
delegate: [[FLTSavePhotoDelegate alloc ] initWithPath: path
454
482
result: result]];
@@ -812,9 +840,11 @@ - (void)startVideoRecordingWithResult:(FlutterResult)result {
812
840
- (void )stopVideoRecordingWithResult : (FlutterResult)result {
813
841
if (_isRecording) {
814
842
_isRecording = NO ;
843
+
815
844
if (_videoWriter.status != AVAssetWriterStatusUnknown) {
816
845
[_videoWriter finishWritingWithCompletionHandler: ^{
817
846
if (self->_videoWriter .status == AVAssetWriterStatusCompleted) {
847
+ [self updateOrientation ];
818
848
result (self->_videoRecordingPath );
819
849
self->_videoRecordingPath = nil ;
820
850
} else {
@@ -854,12 +884,18 @@ - (void)lockCaptureOrientationWithResult:(FlutterResult)result
854
884
result (getFlutterError (e));
855
885
return ;
856
886
}
857
- _lockedCaptureOrientation = orientation;
887
+
888
+ if (_lockedCaptureOrientation != orientation) {
889
+ _lockedCaptureOrientation = orientation;
890
+ [self updateOrientation ];
891
+ }
892
+
858
893
result (nil );
859
894
}
860
895
861
896
- (void )unlockCaptureOrientationWithResult : (FlutterResult)result {
862
897
_lockedCaptureOrientation = UIDeviceOrientationUnknown;
898
+ [self updateOrientation ];
863
899
result (nil );
864
900
}
865
901
@@ -1101,6 +1137,7 @@ - (BOOL)setupWriterForPath:(NSString *)path {
1101
1137
if (_enableAudio && !_isAudioSetup) {
1102
1138
[self setUpCaptureSessionForAudio ];
1103
1139
}
1140
+
1104
1141
_videoWriter = [[AVAssetWriter alloc ] initWithURL: outputURL
1105
1142
fileType: AVFileTypeMPEG4
1106
1143
error: &error];
@@ -1109,11 +1146,9 @@ - (BOOL)setupWriterForPath:(NSString *)path {
1109
1146
[_methodChannel invokeMethod: errorMethod arguments: error.description];
1110
1147
return NO ;
1111
1148
}
1112
- NSDictionary *videoSettings = [NSDictionary
1113
- dictionaryWithObjectsAndKeys: AVVideoCodecH264, AVVideoCodecKey,
1114
- [NSNumber numberWithInt: _previewSize.width], AVVideoWidthKey,
1115
- [NSNumber numberWithInt: _previewSize.height], AVVideoHeightKey,
1116
- nil ];
1149
+
1150
+ NSDictionary *videoSettings = [_captureVideoOutput
1151
+ recommendedVideoSettingsForAssetWriterWithOutputFileType: AVFileTypeMPEG4];
1117
1152
_videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType: AVMediaTypeVideo
1118
1153
outputSettings: videoSettings];
1119
1154
@@ -1124,14 +1159,7 @@ - (BOOL)setupWriterForPath:(NSString *)path {
1124
1159
}];
1125
1160
1126
1161
NSParameterAssert (_videoWriterInput);
1127
- CGFloat rotationDegrees;
1128
- if (_lockedCaptureOrientation != UIDeviceOrientationUnknown) {
1129
- rotationDegrees = [self getRotationFromDeviceOrientation: _lockedCaptureOrientation];
1130
- } else {
1131
- rotationDegrees = [self getRotationFromDeviceOrientation: [UIDevice currentDevice ].orientation];
1132
- }
1133
1162
1134
- _videoWriterInput.transform = CGAffineTransformMakeRotation (rotationDegrees * M_PI / 180 );
1135
1163
_videoWriterInput.expectsMediaDataInRealTime = YES ;
1136
1164
1137
1165
// Add the audio input
@@ -1194,21 +1222,6 @@ - (void)setUpCaptureSessionForAudio {
1194
1222
}
1195
1223
}
1196
1224
}
1197
-
1198
- - (int )getRotationFromDeviceOrientation : (UIDeviceOrientation)orientation {
1199
- switch (orientation) {
1200
- case UIDeviceOrientationPortraitUpsideDown:
1201
- return 270 ;
1202
- case UIDeviceOrientationLandscapeRight:
1203
- return 180 ;
1204
- case UIDeviceOrientationLandscapeLeft:
1205
- return 0 ;
1206
- case UIDeviceOrientationPortrait:
1207
- default :
1208
- return 90 ;
1209
- };
1210
- }
1211
-
1212
1225
@end
1213
1226
1214
1227
@interface CameraPlugin ()
@@ -1257,7 +1270,13 @@ - (void)startOrientationListener {
1257
1270
1258
1271
- (void )orientationChanged : (NSNotification *)note {
1259
1272
UIDevice *device = note.object ;
1260
- [self sendDeviceOrientation: device.orientation];
1273
+ UIDeviceOrientation orientation = device.orientation ;
1274
+
1275
+ if (_camera) {
1276
+ [_camera setDeviceOrientation: orientation];
1277
+ }
1278
+
1279
+ [self sendDeviceOrientation: orientation];
1261
1280
}
1262
1281
1263
1282
- (void )sendDeviceOrientation : (UIDeviceOrientation)orientation {
@@ -1318,6 +1337,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re
1318
1337
FLTCam *cam = [[FLTCam alloc ] initWithCameraName: cameraName
1319
1338
resolutionPreset: resolutionPreset
1320
1339
enableAudio: [enableAudio boolValue ]
1340
+ orientation: [[UIDevice currentDevice ] orientation ]
1321
1341
dispatchQueue: _dispatchQueue
1322
1342
error: &error];
1323
1343
0 commit comments