mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
[Media Picker] Fix some retain cycles and fix implicit self warnings.
This commit is contained in:
parent
fca2437adc
commit
87a6d13855
2 changed files with 144 additions and 120 deletions
|
@ -75,32 +75,10 @@
|
|||
*/
|
||||
+ (instancetype)mediaPickerViewController;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIScrollView *mainScrollView;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *captureViewContainer;
|
||||
//@property (weak, nonatomic) IBOutlet NSLayoutConstraint *captureViewContainerHeightConstraint;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *cameraPreviewContainerView;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *cameraPreviewContainerAspectRatio;
|
||||
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *cameraActivityIndicator;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *closeButton;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *cameraSwitchButton;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *cameraCaptureButton;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *cameraCaptureButtonWidthConstraint;
|
||||
@property (weak, nonatomic) IBOutlet MXKPieChartView *cameraVideoCaptureProgressView;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *recentCapturesCollectionContainerView;
|
||||
@property (weak, nonatomic) IBOutlet UICollectionView *recentCapturesCollectionView;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *recentCapturesCollectionContainerViewHeightConstraint;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *libraryViewContainer;
|
||||
@property (weak, nonatomic) IBOutlet UITableView *userAlbumsTableView;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *libraryViewContainerViewHeightConstraint;
|
||||
|
||||
/**
|
||||
The delegate for the view controller.
|
||||
*/
|
||||
@property (nonatomic) id<MediaPickerViewControllerDelegate> delegate;
|
||||
@property (nonatomic, weak) id<MediaPickerViewControllerDelegate> delegate;
|
||||
|
||||
/**
|
||||
The array of the media types supported by the picker (default value is an array containing kUTTypeImage).
|
||||
|
|
|
@ -94,6 +94,27 @@ static void *RecordingContext = &RecordingContext;
|
|||
BOOL isStatusBarHidden;
|
||||
}
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIScrollView *mainScrollView;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *captureViewContainer;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *cameraPreviewContainerView;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *cameraPreviewContainerAspectRatio;
|
||||
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *cameraActivityIndicator;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *closeButton;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *cameraSwitchButton;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *cameraCaptureButton;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *cameraCaptureButtonWidthConstraint;
|
||||
@property (weak, nonatomic) IBOutlet MXKPieChartView *cameraVideoCaptureProgressView;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *recentCapturesCollectionContainerView;
|
||||
@property (weak, nonatomic) IBOutlet UICollectionView *recentCapturesCollectionView;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *recentCapturesCollectionContainerViewHeightConstraint;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *libraryViewContainer;
|
||||
@property (weak, nonatomic) IBOutlet UITableView *userAlbumsTableView;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *libraryViewContainerViewHeightConstraint;
|
||||
|
||||
@property (nonatomic) UIBackgroundTaskIdentifier backgroundRecordingID;
|
||||
|
||||
@end
|
||||
|
@ -163,19 +184,24 @@ static void *RecordingContext = &RecordingContext;
|
|||
|
||||
[self setBackgroundRecordingID:UIBackgroundTaskInvalid];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe UIApplicationWillEnterForegroundNotification to refresh captures collection when app leaves the background state.
|
||||
UIApplicationWillEnterForegroundNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self reloadRecentCapturesCollection];
|
||||
[self reloadUserLibraryAlbums];
|
||||
|
||||
|
||||
}];
|
||||
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
[self userInterfaceThemeDidChange];
|
||||
}
|
||||
|
@ -292,7 +318,7 @@ static void *RecordingContext = &RecordingContext;
|
|||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
|
||||
[self.cameraActivityIndicator stopAnimating];
|
||||
cameraPreviewLayer.hidden = NO;
|
||||
self->cameraPreviewLayer.hidden = NO;
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -318,7 +344,7 @@ static void *RecordingContext = &RecordingContext;
|
|||
if (granted)
|
||||
{
|
||||
// Load recent captures if this is not already done
|
||||
if (!recentCaptures.count)
|
||||
if (!self->recentCaptures.count)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
|
@ -564,9 +590,13 @@ static void *RecordingContext = &RecordingContext;
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
dispatch_async(userAlbumsQueue, ^{
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// List user albums which are not empty
|
||||
PHFetchResult *albums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
|
||||
|
||||
|
@ -575,9 +605,9 @@ static void *RecordingContext = &RecordingContext;
|
|||
|
||||
// Set up fetch options.
|
||||
PHFetchOptions *options = [[PHFetchOptions alloc] init];
|
||||
if ([_mediaTypes indexOfObject:(NSString *)kUTTypeImage] != NSNotFound)
|
||||
if ([self->_mediaTypes indexOfObject:(NSString *)kUTTypeImage] != NSNotFound)
|
||||
{
|
||||
if ([_mediaTypes indexOfObject:(NSString *)kUTTypeMovie] != NSNotFound)
|
||||
if ([self->_mediaTypes indexOfObject:(NSString *)kUTTypeMovie] != NSNotFound)
|
||||
{
|
||||
options.predicate = [NSPredicate predicateWithFormat:@"(mediaType == %d) || (mediaType == %d)", PHAssetMediaTypeImage, PHAssetMediaTypeVideo];
|
||||
}
|
||||
|
@ -586,7 +616,7 @@ static void *RecordingContext = &RecordingContext;
|
|||
options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d",PHAssetMediaTypeImage];
|
||||
}
|
||||
}
|
||||
else if ([_mediaTypes indexOfObject:(NSString *)kUTTypeMovie] != NSNotFound)
|
||||
else if ([self->_mediaTypes indexOfObject:(NSString *)kUTTypeMovie] != NSNotFound)
|
||||
{
|
||||
options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d",PHAssetMediaTypeVideo];
|
||||
}
|
||||
|
@ -626,11 +656,11 @@ static void *RecordingContext = &RecordingContext;
|
|||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
userAlbums = updatedUserAlbums;
|
||||
if (userAlbums.count)
|
||||
self->userAlbums = updatedUserAlbums;
|
||||
if (self->userAlbums.count)
|
||||
{
|
||||
self.userAlbumsTableView.hidden = NO;
|
||||
self.libraryViewContainerViewHeightConstraint.constant = (userAlbums.count * 74);
|
||||
self.libraryViewContainerViewHeightConstraint.constant = (self->userAlbums.count * 74);
|
||||
[self.libraryViewContainer needsUpdateConstraints];
|
||||
|
||||
[self.userAlbumsTableView reloadData];
|
||||
|
@ -759,13 +789,13 @@ static void *RecordingContext = &RecordingContext;
|
|||
}];
|
||||
}
|
||||
|
||||
isValidationInProgress = NO;
|
||||
self->isValidationInProgress = NO;
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"[MediaPickerVC] didSelectAsset: Failed to get image for asset");
|
||||
isValidationInProgress = NO;
|
||||
self->isValidationInProgress = NO;
|
||||
|
||||
// Alert user
|
||||
NSError *error = info[@"PHImageErrorKey"];
|
||||
|
@ -815,20 +845,20 @@ static void *RecordingContext = &RecordingContext;
|
|||
[self.delegate mediaPickerController:self didSelectVideo:[avURLAsset URL]];
|
||||
}
|
||||
|
||||
isValidationInProgress = NO;
|
||||
self->isValidationInProgress = NO;
|
||||
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"[MediaPickerVC] Selected video asset is not initialized from an URL!");
|
||||
isValidationInProgress = NO;
|
||||
self->isValidationInProgress = NO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"[MediaPickerVC] didSelectAsset: Failed to get image for asset");
|
||||
isValidationInProgress = NO;
|
||||
self->isValidationInProgress = NO;
|
||||
|
||||
// Alert user
|
||||
NSError *error = info[@"PHImageErrorKey"];
|
||||
|
@ -1103,8 +1133,12 @@ static void *RecordingContext = &RecordingContext;
|
|||
|
||||
[self.cameraActivityIndicator startAnimating];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
dispatch_async(cameraQueue, ^{
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Get the Camera Device
|
||||
AVCaptureDevice *frontCamera = nil;
|
||||
AVCaptureDevice *backCamera = nil;
|
||||
|
@ -1151,42 +1185,42 @@ static void *RecordingContext = &RecordingContext;
|
|||
}
|
||||
}
|
||||
|
||||
currentCameraInput = nil;
|
||||
self->currentCameraInput = nil;
|
||||
NSError *error = nil;
|
||||
if (frontCamera)
|
||||
{
|
||||
frontCameraInput = [[AVCaptureDeviceInput alloc] initWithDevice:frontCamera error:&error];
|
||||
self->frontCameraInput = [[AVCaptureDeviceInput alloc] initWithDevice:frontCamera error:&error];
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"[MediaPickerVC] Error: %@", error);
|
||||
}
|
||||
|
||||
if (frontCameraInput == nil)
|
||||
if (self->frontCameraInput == nil)
|
||||
{
|
||||
NSLog(@"[MediaPickerVC] Error creating front camera capture input");
|
||||
}
|
||||
else
|
||||
{
|
||||
currentCameraInput = frontCameraInput;
|
||||
self->currentCameraInput = self->frontCameraInput;
|
||||
}
|
||||
}
|
||||
|
||||
if (backCamera)
|
||||
{
|
||||
error = nil;
|
||||
backCameraInput = [[AVCaptureDeviceInput alloc] initWithDevice:backCamera error:&error];
|
||||
self->backCameraInput = [[AVCaptureDeviceInput alloc] initWithDevice:backCamera error:&error];
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"[MediaPickerVC] Error: %@", error);
|
||||
}
|
||||
|
||||
if (backCameraInput == nil)
|
||||
if (self->backCameraInput == nil)
|
||||
{
|
||||
NSLog(@"[MediaPickerVC] Error creating back camera capture input");
|
||||
}
|
||||
else
|
||||
{
|
||||
currentCameraInput = backCameraInput;
|
||||
self->currentCameraInput = self->backCameraInput;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1194,38 +1228,38 @@ static void *RecordingContext = &RecordingContext;
|
|||
self.cameraSwitchButton.hidden = (!frontCamera || !backCamera);
|
||||
});
|
||||
|
||||
if (currentCameraInput)
|
||||
if (self->currentCameraInput)
|
||||
{
|
||||
// Create the AVCapture Session
|
||||
captureSession = [[AVCaptureSession alloc] init];
|
||||
self->captureSession = [[AVCaptureSession alloc] init];
|
||||
|
||||
if (isPictureCaptureEnabled)
|
||||
if (self->isPictureCaptureEnabled)
|
||||
{
|
||||
[captureSession setSessionPreset:AVCaptureSessionPresetPhoto];
|
||||
[self->captureSession setSessionPreset:AVCaptureSessionPresetPhoto];
|
||||
}
|
||||
else if (isVideoCaptureEnabled)
|
||||
else if (self->isVideoCaptureEnabled)
|
||||
{
|
||||
[captureSession setSessionPreset:AVCaptureSessionPresetHigh];
|
||||
[self->captureSession setSessionPreset:AVCaptureSessionPresetHigh];
|
||||
}
|
||||
|
||||
cameraPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession];
|
||||
cameraPreviewLayer.masksToBounds = NO;
|
||||
cameraPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//AVLayerVideoGravityResizeAspect;
|
||||
cameraPreviewLayer.backgroundColor = [[UIColor blackColor] CGColor];
|
||||
self->cameraPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self->captureSession];
|
||||
self->cameraPreviewLayer.masksToBounds = NO;
|
||||
self->cameraPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//AVLayerVideoGravityResizeAspect;
|
||||
self->cameraPreviewLayer.backgroundColor = [[UIColor blackColor] CGColor];
|
||||
// cameraPreviewLayer.borderWidth = 2;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
[[cameraPreviewLayer connection] setVideoOrientation:(AVCaptureVideoOrientation)[[UIApplication sharedApplication] statusBarOrientation]];
|
||||
[cameraPreviewLayer connection].videoScaleAndCropFactor = 1.0;
|
||||
cameraPreviewLayer.frame = self.cameraPreviewContainerView.bounds;
|
||||
cameraPreviewLayer.hidden = YES;
|
||||
[[self->cameraPreviewLayer connection] setVideoOrientation:(AVCaptureVideoOrientation)[[UIApplication sharedApplication] statusBarOrientation]];
|
||||
[self->cameraPreviewLayer connection].videoScaleAndCropFactor = 1.0;
|
||||
self->cameraPreviewLayer.frame = self.cameraPreviewContainerView.bounds;
|
||||
self->cameraPreviewLayer.hidden = YES;
|
||||
|
||||
[self.cameraPreviewContainerView.layer addSublayer:cameraPreviewLayer];
|
||||
[self.cameraPreviewContainerView.layer addSublayer:self->cameraPreviewLayer];
|
||||
|
||||
});
|
||||
|
||||
[captureSession addInput:currentCameraInput];
|
||||
[self->captureSession addInput:self->currentCameraInput];
|
||||
|
||||
AVCaptureDevice *audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
|
||||
AVCaptureDeviceInput *audioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
|
||||
|
@ -1235,36 +1269,36 @@ static void *RecordingContext = &RecordingContext;
|
|||
NSLog(@"[MediaPickerVC] Error: %@", error);
|
||||
}
|
||||
|
||||
if ([captureSession canAddInput:audioDeviceInput])
|
||||
if ([self->captureSession canAddInput:audioDeviceInput])
|
||||
{
|
||||
[captureSession addInput:audioDeviceInput];
|
||||
[self->captureSession addInput:audioDeviceInput];
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(caughtAVRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(AVCaptureSessionDidStartRunning:) name:AVCaptureSessionDidStartRunningNotification object:nil];
|
||||
|
||||
[captureSession startRunning];
|
||||
[self->captureSession startRunning];
|
||||
|
||||
movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
|
||||
if ([captureSession canAddOutput:movieFileOutput])
|
||||
self->movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
|
||||
if ([self->captureSession canAddOutput:self->movieFileOutput])
|
||||
{
|
||||
[captureSession addOutput:movieFileOutput];
|
||||
AVCaptureConnection *connection = [movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
|
||||
[self->captureSession addOutput:self->movieFileOutput];
|
||||
AVCaptureConnection *connection = [self->movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
|
||||
if ([connection isVideoStabilizationSupported])
|
||||
{
|
||||
// Available on iOS 8 and later
|
||||
[connection setPreferredVideoStabilizationMode:YES];
|
||||
}
|
||||
}
|
||||
[movieFileOutput addObserver:self forKeyPath:@"recording" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:RecordingContext];
|
||||
[self->movieFileOutput addObserver:self forKeyPath:@"recording" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:RecordingContext];
|
||||
|
||||
stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
|
||||
if ([captureSession canAddOutput:stillImageOutput])
|
||||
self->stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
|
||||
if ([self->captureSession canAddOutput:self->stillImageOutput])
|
||||
{
|
||||
[stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}];
|
||||
[captureSession addOutput:stillImageOutput];
|
||||
[self->stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}];
|
||||
[self->captureSession addOutput:self->stillImageOutput];
|
||||
}
|
||||
[stillImageOutput addObserver:self forKeyPath:@"capturingStillImage" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:CapturingStillImageContext];
|
||||
[self->stillImageOutput addObserver:self forKeyPath:@"capturingStillImage" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:CapturingStillImageContext];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1273,7 +1307,7 @@ static void *RecordingContext = &RecordingContext;
|
|||
});
|
||||
}
|
||||
|
||||
isCaptureSessionSetupInProgress = NO;
|
||||
self->isCaptureSessionSetupInProgress = NO;
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -1300,23 +1334,24 @@ static void *RecordingContext = &RecordingContext;
|
|||
}
|
||||
|
||||
dispatch_sync(cameraQueue, ^{
|
||||
frontCameraInput = nil;
|
||||
backCameraInput = nil;
|
||||
captureSession = nil;
|
||||
|
||||
self->frontCameraInput = nil;
|
||||
self->backCameraInput = nil;
|
||||
self->captureSession = nil;
|
||||
|
||||
if (movieFileOutput)
|
||||
if (self->movieFileOutput)
|
||||
{
|
||||
[movieFileOutput removeObserver:self forKeyPath:@"recording" context:RecordingContext];
|
||||
movieFileOutput = nil;
|
||||
[self->movieFileOutput removeObserver:self forKeyPath:@"recording" context:RecordingContext];
|
||||
self->movieFileOutput = nil;
|
||||
}
|
||||
|
||||
if (stillImageOutput)
|
||||
if (self->stillImageOutput)
|
||||
{
|
||||
[stillImageOutput removeObserver:self forKeyPath:@"capturingStillImage" context:CapturingStillImageContext];
|
||||
stillImageOutput = nil;
|
||||
[self->stillImageOutput removeObserver:self forKeyPath:@"capturingStillImage" context:CapturingStillImageContext];
|
||||
self->stillImageOutput = nil;
|
||||
}
|
||||
|
||||
currentCameraInput = nil;
|
||||
self->currentCameraInput = nil;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureSessionRuntimeErrorNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureSessionDidStartRunningNotification object:nil];
|
||||
|
@ -1342,7 +1377,7 @@ static void *RecordingContext = &RecordingContext;
|
|||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
|
||||
[self.cameraActivityIndicator stopAnimating];
|
||||
cameraPreviewLayer.hidden = NO;
|
||||
self->cameraPreviewLayer.hidden = NO;
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -1357,45 +1392,45 @@ static void *RecordingContext = &RecordingContext;
|
|||
if (frontCameraInput && backCameraInput)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!canToggleCamera)
|
||||
if (!self->canToggleCamera)
|
||||
{
|
||||
return;
|
||||
}
|
||||
canToggleCamera = NO;
|
||||
self->canToggleCamera = NO;
|
||||
|
||||
AVCaptureDeviceInput *newInput = nil;
|
||||
AVCaptureDeviceInput *oldInput = nil;
|
||||
if (currentCameraInput == frontCameraInput)
|
||||
if (self->currentCameraInput == self->frontCameraInput)
|
||||
{
|
||||
newInput = backCameraInput;
|
||||
oldInput = frontCameraInput;
|
||||
newInput = self->backCameraInput;
|
||||
oldInput = self->frontCameraInput;
|
||||
}
|
||||
else
|
||||
{
|
||||
newInput = frontCameraInput;
|
||||
oldInput = backCameraInput;
|
||||
newInput = self->frontCameraInput;
|
||||
oldInput = self->backCameraInput;
|
||||
}
|
||||
|
||||
dispatch_async(cameraQueue, ^{
|
||||
dispatch_async(self->cameraQueue, ^{
|
||||
|
||||
[captureSession beginConfiguration];
|
||||
[captureSession removeInput:oldInput];
|
||||
if ([captureSession canAddInput:newInput]) {
|
||||
[captureSession addInput:newInput];
|
||||
currentCameraInput = newInput;
|
||||
[self->captureSession beginConfiguration];
|
||||
[self->captureSession removeInput:oldInput];
|
||||
if ([self->captureSession canAddInput:newInput]) {
|
||||
[self->captureSession addInput:newInput];
|
||||
self->currentCameraInput = newInput;
|
||||
}
|
||||
[captureSession commitConfiguration];
|
||||
[self->captureSession commitConfiguration];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
[self.cameraActivityIndicator stopAnimating];
|
||||
cameraPreviewLayer.hidden = NO;
|
||||
canToggleCamera = YES;
|
||||
self->cameraPreviewLayer.hidden = NO;
|
||||
self->canToggleCamera = YES;
|
||||
});
|
||||
});
|
||||
|
||||
[self.cameraActivityIndicator startAnimating];
|
||||
cameraPreviewLayer.hidden = YES;
|
||||
self->cameraPreviewLayer.hidden = YES;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1404,10 +1439,15 @@ static void *RecordingContext = &RecordingContext;
|
|||
{
|
||||
self.cameraCaptureButton.enabled = NO;
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
dispatch_async(cameraQueue, ^{
|
||||
if (![movieFileOutput isRecording])
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
if (![self->movieFileOutput isRecording])
|
||||
{
|
||||
lockInterfaceRotation = YES;
|
||||
self->lockInterfaceRotation = YES;
|
||||
|
||||
if ([[UIDevice currentDevice] isMultitaskingSupported])
|
||||
{
|
||||
|
@ -1425,14 +1465,14 @@ static void *RecordingContext = &RecordingContext;
|
|||
}
|
||||
|
||||
// Update the orientation on the movie file output video connection before starting recording.
|
||||
[[movieFileOutput connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[cameraPreviewLayer connection] videoOrientation]];
|
||||
[[self->movieFileOutput connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[self->cameraPreviewLayer connection] videoOrientation]];
|
||||
|
||||
// Turning OFF flash for video recording
|
||||
[MediaPickerViewController setFlashMode:AVCaptureFlashModeOff forDevice:[currentCameraInput device]];
|
||||
[MediaPickerViewController setFlashMode:AVCaptureFlashModeOff forDevice:[self->currentCameraInput device]];
|
||||
|
||||
// Start recording to a temporary file.
|
||||
NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[@"movie" stringByAppendingPathExtension:@"mov"]];
|
||||
[movieFileOutput startRecordingToOutputFileURL:[NSURL fileURLWithPath:outputFilePath] recordingDelegate:self];
|
||||
[self->movieFileOutput startRecordingToOutputFileURL:[NSURL fileURLWithPath:outputFilePath] recordingDelegate:self];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1440,9 +1480,10 @@ static void *RecordingContext = &RecordingContext;
|
|||
- (void)stopMovieRecording
|
||||
{
|
||||
dispatch_async(cameraQueue, ^{
|
||||
if ([movieFileOutput isRecording])
|
||||
|
||||
if ([self->movieFileOutput isRecording])
|
||||
{
|
||||
[movieFileOutput stopRecording];
|
||||
[self->movieFileOutput stopRecording];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1451,15 +1492,20 @@ static void *RecordingContext = &RecordingContext;
|
|||
{
|
||||
self.cameraCaptureButton.enabled = NO;
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
dispatch_async(cameraQueue, ^{
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Update the orientation on the still image output video connection before capturing.
|
||||
[[stillImageOutput connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[cameraPreviewLayer connection] videoOrientation]];
|
||||
[[self->stillImageOutput connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[self->cameraPreviewLayer connection] videoOrientation]];
|
||||
|
||||
// Flash set to Auto for Still Capture
|
||||
[MediaPickerViewController setFlashMode:AVCaptureFlashModeAuto forDevice:[currentCameraInput device]];
|
||||
[MediaPickerViewController setFlashMode:AVCaptureFlashModeAuto forDevice:[self->currentCameraInput device]];
|
||||
|
||||
// Capture a still image.
|
||||
[stillImageOutput captureStillImageAsynchronouslyFromConnection:[stillImageOutput connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
|
||||
[self->stillImageOutput captureStillImageAsynchronouslyFromConnection:[self->stillImageOutput connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
|
||||
|
||||
if (imageDataSampleBuffer)
|
||||
{
|
||||
|
@ -1504,10 +1550,10 @@ static void *RecordingContext = &RecordingContext;
|
|||
- (void)runStillImageCaptureAnimation
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[cameraPreviewLayer setOpacity:0.0];
|
||||
[self->cameraPreviewLayer setOpacity:0.0];
|
||||
|
||||
[UIView animateWithDuration:.25 animations:^{
|
||||
[cameraPreviewLayer setOpacity:1.0];
|
||||
[self->cameraPreviewLayer setOpacity:1.0];
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
@ -1535,18 +1581,18 @@ static void *RecordingContext = &RecordingContext;
|
|||
{
|
||||
self.cameraSwitchButton.enabled = NO;
|
||||
|
||||
videoRecordStartDate = [NSDate date];
|
||||
self->videoRecordStartDate = [NSDate date];
|
||||
|
||||
self.cameraVideoCaptureProgressView.hidden = NO;
|
||||
updateVideoRecordingTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateVideoRecordingDuration) userInfo:nil repeats:YES];
|
||||
self->updateVideoRecordingTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateVideoRecordingDuration) userInfo:nil repeats:YES];
|
||||
|
||||
self.cameraCaptureButton.enabled = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.cameraVideoCaptureProgressView.hidden = YES;
|
||||
[updateVideoRecordingTimer invalidate];
|
||||
updateVideoRecordingTimer = nil;
|
||||
[self->updateVideoRecordingTimer invalidate];
|
||||
self->updateVideoRecordingTimer = nil;
|
||||
self.cameraVideoCaptureProgressView.progress = 0;
|
||||
|
||||
// The preview will be restored during captureOutput:didFinishRecordingToOutputFileAtURL: callback.
|
||||
|
|
Loading…
Reference in a new issue