Add pinch-to-zoom in video message capture

This commit is contained in:
Ilya Laktyushin 2021-07-07 02:32:05 +03:00
parent 4fcb54c687
commit 3ad48b7550
3 changed files with 82 additions and 1 deletions

View File

@ -15,6 +15,9 @@
@property (nonatomic, copy) void (^micLevel)(CGFloat);
@property (nonatomic, readonly) bool isZoomAvailable;
@property (nonatomic, assign) CGFloat zoomLevel;
- (instancetype)initWithDelegate:(id<TGVideoCameraPipelineDelegate>)delegate position:(AVCaptureDevicePosition)position callbackQueue:(dispatch_queue_t)queue liveUploadInterface:(id<TGLiveUploadInterface>)liveUploadInterface;
- (void)startRunning;

View File

@ -864,6 +864,52 @@ static CGFloat angleOffsetFromPortraitOrientationToOrientation(AVCaptureVideoOri
return _recorder.videoDuration;
}
- (CGFloat)zoomLevel
{
if (![_videoDevice respondsToSelector:@selector(videoZoomFactor)])
return 1.0f;
return (_videoDevice.videoZoomFactor - 1.0f) / ([self _maximumZoomFactor] - 1.0f);
}
- (CGFloat)_maximumZoomFactor
{
return MIN(5.0f, _videoDevice.activeFormat.videoMaxZoomFactor);
}
- (void)setZoomLevel:(CGFloat)zoomLevel
{
zoomLevel = MAX(0.0f, MIN(1.0f, zoomLevel));
__weak TGVideoCameraPipeline *weakSelf = self;
[[TGVideoCameraPipeline cameraQueue] dispatch:^
{
__strong TGVideoCameraPipeline *strongSelf = weakSelf;
if (strongSelf == nil)
return;
[self _reconfigureDevice:_videoDevice withBlock:^(AVCaptureDevice *device) {
device.videoZoomFactor = MAX(1.0f, MIN([strongSelf _maximumZoomFactor], 1.0f + ([strongSelf _maximumZoomFactor] - 1.0f) * zoomLevel));
}];
}];
}
- (bool)isZoomAvailable
{
return [TGVideoCameraPipeline _isZoomAvailableForDevice:_videoDevice];
}
+ (bool)_isZoomAvailableForDevice:(AVCaptureDevice *)device
{
if (![device respondsToSelector:@selector(setVideoZoomFactor:)])
return false;
if (device.position == AVCaptureDevicePositionFront)
return false;
return true;
}
- (void)setCameraPosition:(AVCaptureDevicePosition)position
{
@synchronized (self)

View File

@ -91,6 +91,8 @@ typedef enum
TGVideoCameraGLView *_previewView;
TGVideoMessageRingView *_ringView;
UIPinchGestureRecognizer *_pinchGestureRecognizer;
UIView *_separatorView;
UIImageView *_placeholderView;
@ -344,7 +346,6 @@ typedef enum
[_circleWrapperView addSubview:_ringView];
CGRect controlsFrame = _controlsFrame;
// controlsFrame.size.width = _wrapperView.frame.size.width;
_controlsView = [[TGVideoMessageControls alloc] initWithFrame:controlsFrame assets:_assets slowmodeTimestamp:_slowmodeTimestamp slowmodeView:_slowmodeView];
_controlsView.pallete = self.pallete;
@ -417,12 +418,43 @@ typedef enum
[self.view addSubview:_switchButton];
}
_pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
_pinchGestureRecognizer.delegate = self;
[self.view addGestureRecognizer:_pinchGestureRecognizer];
void (^voidBlock)(void) = ^{};
_buttonHandler = [[PGCameraVolumeButtonHandler alloc] initWithUpButtonPressedBlock:voidBlock upButtonReleasedBlock:voidBlock downButtonPressedBlock:voidBlock downButtonReleasedBlock:voidBlock];
[self configureCamera];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer == _pinchGestureRecognizer)
return _capturePipeline.isZoomAvailable;
return true;
}
- (void)handlePinch:(UIPinchGestureRecognizer *)gestureRecognizer
{
switch (gestureRecognizer.state)
{
case UIGestureRecognizerStateChanged:
{
CGFloat delta = (gestureRecognizer.scale - 1.0f) / 1.5f;
CGFloat value = MAX(0.0f, MIN(1.0f, _capturePipeline.zoomLevel + delta));
[_capturePipeline setZoomLevel:value];
gestureRecognizer.scale = 1.0f;
}
break;
default:
break;
}
}
- (TGVideoMessageTransitionType)_transitionType
{
static dispatch_once_t onceToken;