[Media Picker] Fix some retain cycles and fix implicit self warnings.

This commit is contained in:
SBiOSoftWhare 2019-04-24 17:56:03 +02:00
parent fca2437adc
commit 87a6d13855
2 changed files with 144 additions and 120 deletions

View file

@ -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).

View file

@ -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,9 +184,13 @@ 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];
@ -174,8 +199,9 @@ static void *RecordingContext = &RecordingContext;
// Observe user interface theme change.
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
[self userInterfaceThemeDidChange];
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(), ^{
@ -565,8 +591,12 @@ 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;
if (movieFileOutput)
self->frontCameraInput = nil;
self->backCameraInput = nil;
self->captureSession = nil;
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.