Video avatar fixes

This commit is contained in:
Ilya Laktyushin
2020-06-24 18:06:08 +03:00
parent 4755ee4261
commit a34b7402be
62 changed files with 753 additions and 1962 deletions

View File

@@ -921,6 +921,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
case PGCameraModeVideo:
case PGCameraModeSquareVideo:
case PGCameraModeSquareSwing:
{
if (!_camera.isRecordingVideo)
{
@@ -994,7 +995,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
});
}];
}
else if (cameraMode == PGCameraModeVideo)
else if (cameraMode == PGCameraModeVideo || cameraMode == PGCameraModeSquareVideo || cameraMode == PGCameraModeSquareSwing)
{
if (!_camera.isRecordingVideo)
{
@@ -1009,12 +1010,16 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
if (success)
{
TGCameraCapturedVideo *capturedVideo = [[TGCameraCapturedVideo alloc] initWithURL:outputURL];
[strongSelf addResultItem:capturedVideo];
if (![strongSelf maybePresentResultControllerForItem:capturedVideo completion:nil])
if (strongSelf->_intent == TGCameraControllerAvatarIntent || strongSelf->_intent == TGCameraControllerSignupAvatarIntent)
{
strongSelf->_camera.disabled = false;
[strongSelf->_interfaceView setRecordingVideo:false animated:true];
[strongSelf presentPhotoResultControllerWithImage:capturedVideo metadata:nil completion:^{}];
} else {
[strongSelf addResultItem:capturedVideo];
if (![strongSelf maybePresentResultControllerForItem:capturedVideo completion:nil])
{
strongSelf->_camera.disabled = false;
[strongSelf->_interfaceView setRecordingVideo:false animated:true];
}
}
}
else
@@ -1655,15 +1660,29 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
#pragma mark - Legacy Photo Result
- (void)presentPhotoResultControllerWithImage:(UIImage *)image metadata:(PGCameraShotMetadata *)metadata completion:(void (^)(void))completion
- (void)presentPhotoResultControllerWithImage:(id<TGMediaEditableItem>)input metadata:(PGCameraShotMetadata *)metadata completion:(void (^)(void))completion
{
[[[LegacyComponentsGlobals provider] applicationInstance] setIdleTimerDisabled:false];
if (image == nil || image.size.width < FLT_EPSILON)
if (input == nil || ([input isKindOfClass:[UIImage class]] && ((UIImage *)input).size.width < FLT_EPSILON))
{
[self beginTransitionOutWithVelocity:0.0f];
return;
}
UIImage *image = nil;
if ([input isKindOfClass:[UIImage class]]) {
image = (UIImage *)input;
} else if ([input isKindOfClass:[TGCameraCapturedVideo class]]) {
AVAsset *asset = ((TGCameraCapturedVideo *)input).immediateAVAsset;
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform = true;
generator.maximumSize = CGSizeMake(640.0f, 640.0f);
CGImageRef imageRef = [generator copyCGImageAtTime:kCMTimeZero actualTime:NULL error:NULL];
image = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
}
id<LegacyComponentsOverlayWindowManager> windowManager = nil;
id<LegacyComponentsContext> windowContext = nil;
@@ -1679,179 +1698,101 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
_focusControl.ignoreAutofocusing = true;
switch (_intent)
{
case TGCameraControllerAvatarIntent:
case TGCameraControllerSignupAvatarIntent:
{
TGPhotoEditorControllerIntent intent = TGPhotoEditorControllerAvatarIntent;
if (_intent == TGCameraControllerSignupAvatarIntent) {
intent = TGPhotoEditorControllerSignupAvatarIntent;
}
TGPhotoEditorController *controller = [[TGPhotoEditorController alloc] initWithContext:windowContext item:image intent:(TGPhotoEditorControllerFromCameraIntent | intent) adjustments:nil caption:nil screenImage:image availableTabs:[TGPhotoEditorController defaultTabsForAvatarIntent] selectedTab:TGPhotoEditorCropTab];
controller.stickersContext = _stickersContext;
__weak TGPhotoEditorController *weakController = controller;
controller.beginTransitionIn = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return nil;
strongSelf->_previewView.hidden = true;
*referenceFrame = strongSelf->_previewView.frame;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:strongSelf->_previewView.frame];
imageView.image = image;
return imageView;
};
controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return nil;
CGRect startFrame = CGRectZero;
if (referenceFrame != NULL)
{
startFrame = *referenceFrame;
*referenceFrame = strongSelf->_previewView.frame;
}
[strongSelf transitionBackFromResultControllerWithReferenceFrame:startFrame];
return strongSelf->_previewView;
};
controller.didFinishEditing = ^(PGPhotoEditorValues *editorValues, UIImage *resultImage, __unused UIImage *thumbnailImage, bool hasChanges)
{
if (!hasChanges)
return;
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return;
TGDispatchOnMainThread(^
{
if (strongSelf.finishedWithPhoto != nil)
strongSelf.finishedWithPhoto(nil, resultImage, nil, nil, nil, nil);
if (strongSelf.shouldStoreCapturedAssets)
{
[strongSelf _savePhotoToCameraRollWithOriginalImage:image editedImage:[editorValues toolsApplied] ? resultImage : nil];
}
__strong TGPhotoEditorController *strongController = weakController;
if (strongController != nil)
{
[strongController updateStatusBarAppearanceForDismiss];
[strongSelf _dismissTransitionForResultController:(TGOverlayController *)strongController];
}
});
};
controller.requestThumbnailImage = ^(id<TGMediaEditableItem> editableItem)
{
return [editableItem thumbnailImageSignal];
};
controller.requestOriginalScreenSizeImage = ^(id<TGMediaEditableItem> editableItem, NSTimeInterval position)
{
return [editableItem screenImageSignal:position];
};
controller.requestOriginalFullSizeImage = ^(id<TGMediaEditableItem> editableItem, NSTimeInterval position)
{
if (editableItem.isVideo) {
if ([editableItem isKindOfClass:[TGMediaAsset class]]) {
return [TGMediaAssetImageSignals avAssetForVideoAsset:(TGMediaAsset *)editableItem];
} else if ([editableItem isKindOfClass:[TGCameraCapturedVideo class]]) {
return ((TGCameraCapturedVideo *)editableItem).avAsset;
} else {
return [editableItem originalImageSignal:position];
}
} else {
return [editableItem originalImageSignal:position];
}
};
overlayController = (TGOverlayController *)controller;
}
break;
default:
{
TGCameraPhotoPreviewController *controller = _shortcut ? [[TGCameraPhotoPreviewController alloc] initWithContext:windowContext image:image metadata:metadata recipientName:self.recipientName backButtonTitle:TGLocalized(@"Camera.Retake") doneButtonTitle:TGLocalized(@"Common.Next") saveCapturedMedia:_saveCapturedMedia saveEditedPhotos:_saveEditedPhotos] : [[TGCameraPhotoPreviewController alloc] initWithContext:windowContext image:image metadata:metadata recipientName:self.recipientName saveCapturedMedia:_saveCapturedMedia saveEditedPhotos:_saveEditedPhotos];
controller.allowCaptions = self.allowCaptions;
controller.shouldStoreAssets = self.shouldStoreCapturedAssets;
controller.suggestionContext = self.suggestionContext;
controller.hasTimer = self.hasTimer;
controller.hasSilentPosting = self.hasSilentPosting;
controller.hasSchedule = self.hasSchedule;
__weak TGCameraPhotoPreviewController *weakController = controller;
controller.beginTransitionIn = ^CGRect
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return CGRectZero;
strongSelf->_previewView.hidden = true;
return strongSelf->_previewView.frame;
};
controller.finishedTransitionIn = ^
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf != nil)
[strongSelf->_camera stopCaptureForPause:true completion:nil];
};
controller.beginTransitionOut = ^CGRect(CGRect referenceFrame)
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return CGRectZero;
[strongSelf->_camera startCaptureForResume:true completion:nil];
return [strongSelf transitionBackFromResultControllerWithReferenceFrame:referenceFrame];
};
controller.retakePressed = ^
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return;
[[[LegacyComponentsGlobals provider] applicationInstance] setIdleTimerDisabled:true];
};
controller.sendPressed = ^(TGOverlayController *controller, UIImage *resultImage, NSString *caption, NSArray *entities, NSArray *stickers, NSNumber *timer)
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return;
if (strongSelf.finishedWithPhoto != nil)
strongSelf.finishedWithPhoto(controller, resultImage, caption, entities, stickers, timer);
if (strongSelf->_shortcut)
return;
__strong TGOverlayController *strongController = weakController;
if (strongController != nil)
[strongSelf _dismissTransitionForResultController:strongController];
};
overlayController = controller;
}
break;
TGPhotoEditorControllerIntent intent = TGPhotoEditorControllerAvatarIntent;
if (_intent == TGCameraControllerSignupAvatarIntent) {
intent = TGPhotoEditorControllerSignupAvatarIntent;
}
TGPhotoEditorController *controller = [[TGPhotoEditorController alloc] initWithContext:windowContext item:input intent:(TGPhotoEditorControllerFromCameraIntent | intent) adjustments:nil caption:nil screenImage:image availableTabs:[TGPhotoEditorController defaultTabsForAvatarIntent] selectedTab:TGPhotoEditorCropTab];
controller.stickersContext = _stickersContext;
__weak TGPhotoEditorController *weakController = controller;
controller.beginTransitionIn = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return nil;
strongSelf->_previewView.hidden = true;
*referenceFrame = strongSelf->_previewView.frame;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:strongSelf->_previewView.frame];
imageView.image = image;
return imageView;
};
controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return nil;
CGRect startFrame = CGRectZero;
if (referenceFrame != NULL)
{
startFrame = *referenceFrame;
*referenceFrame = strongSelf->_previewView.frame;
}
[strongSelf transitionBackFromResultControllerWithReferenceFrame:startFrame];
return strongSelf->_previewView;
};
controller.didFinishEditing = ^(PGPhotoEditorValues *editorValues, UIImage *resultImage, __unused UIImage *thumbnailImage, bool hasChanges)
{
if (!hasChanges)
return;
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return;
TGDispatchOnMainThread(^
{
if (strongSelf.finishedWithPhoto != nil)
strongSelf.finishedWithPhoto(nil, resultImage, nil, nil, nil, nil);
if (strongSelf.shouldStoreCapturedAssets && [input isKindOfClass:[UIImage class]])
{
[strongSelf _savePhotoToCameraRollWithOriginalImage:image editedImage:[editorValues toolsApplied] ? resultImage : nil];
}
__strong TGPhotoEditorController *strongController = weakController;
if (strongController != nil)
{
[strongController updateStatusBarAppearanceForDismiss];
[strongSelf _dismissTransitionForResultController:(TGOverlayController *)strongController];
}
});
};
controller.requestThumbnailImage = ^(id<TGMediaEditableItem> editableItem)
{
return [editableItem thumbnailImageSignal];
};
controller.requestOriginalScreenSizeImage = ^(id<TGMediaEditableItem> editableItem, NSTimeInterval position)
{
return [editableItem screenImageSignal:position];
};
controller.requestOriginalFullSizeImage = ^(id<TGMediaEditableItem> editableItem, NSTimeInterval position)
{
if (editableItem.isVideo) {
if ([editableItem isKindOfClass:[TGMediaAsset class]]) {
return [TGMediaAssetImageSignals avAssetForVideoAsset:(TGMediaAsset *)editableItem allowNetworkAccess:true];
} else if ([editableItem isKindOfClass:[TGCameraCapturedVideo class]]) {
return ((TGCameraCapturedVideo *)editableItem).avAsset;
} else {
return [editableItem originalImageSignal:position];
}
} else {
return [editableItem originalImageSignal:position];
}
};
overlayController = (TGOverlayController *)controller;
if (windowManager != nil)
{
TGOverlayController *contentController = overlayController;
@@ -2375,6 +2316,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
case PGCameraModeSquarePhoto:
case PGCameraModeSquareVideo:
case PGCameraModeSquareSwing:
{
CGRect rect = [self _cameraPreviewFrameForScreenSize:screenSize mode:PGCameraModePhoto];
CGFloat topOffset = CGRectGetMidY(rect) - rect.size.width / 2;
@@ -2406,7 +2348,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
}
else
{
if (mode == PGCameraModeSquarePhoto || mode == PGCameraModeSquareVideo)
if (mode == PGCameraModeSquarePhoto || mode == PGCameraModeSquareVideo || mode == PGCameraModeSquareSwing)
return CGRectMake(0, (screenSize.height - screenSize.width) / 2, screenSize.width, screenSize.width);
return CGRectMake(0, 0, screenSize.width, screenSize.height);