Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ios video logic #86

Merged
merged 15 commits into from
Oct 3, 2024
Merged

Ios video logic #86

merged 15 commits into from
Oct 3, 2024

Conversation

parveshneedhoo
Copy link
Contributor

No description provided.

@parveshneedhoo parveshneedhoo self-assigned this Sep 5, 2024
@YushraJewon YushraJewon changed the base branch from master to video-ios-poc September 5, 2024 09:47
@parveshneedhoo parveshneedhoo changed the base branch from video-ios-poc to master September 5, 2024 10:23
[self.sessionManager startRecordingToOutputFileURL:fileURL recordingDelegate:self];
} else {
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Session not initialized or already recording"];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setKeepCallback true

same in the other methods

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we keep it same logic as with Androids and the single callback

src/ios/SimpleCameraPreview.m Show resolved Hide resolved
src/ios/SimpleCameraPreview.m Show resolved Hide resolved
CMTime time = CMTimeMakeWithSeconds(1.0, 600);
NSError *error = nil;
CMTime actualTime;
CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:&actualTime error:&error];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:&actualTime error:&error];
CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:&actualTime error:&error];

src/ios/SimpleCameraPreview.m Show resolved Hide resolved
}

UIImage *thumbnail = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CGImageRelease(imageRef);
CGImageRelease(imageRef);

src/ios/SimpleCameraPreview.m Show resolved Hide resolved
src/ios/SimpleCameraPreview.m Show resolved Hide resolved
} else {
NSString *thumbnail = [self generateThumbnailForVideoAtURL:outputFileURL];
NSString *filePath = [outputFileURL path];
NSDictionary *result = @{@"nativePath": filePath, @"thumbnail": thumbnail};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check if we actually have the thumbnail generated before adding it to the dictionary?

we can return null if we get errors from the generateThumbnailForVideoAtURL method

YushraJewon and others added 4 commits September 12, 2024 14:31
Co-authored-by: Parvesh Needhoo <116141944+parveshneedhoo@users.noreply.github.com>
…plugin-simple-camera-preview into ios-video-logic
Copy link
Contributor

@sc-nick sc-nick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good for me

Copy link
Member

@HashirRajah HashirRajah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few comments but it can all be treated as improvements/refactoring for later.

Everything seems to work except

  • when I start recording on iOS and put the app in background, it does not stop recording and when opening the app again timer stops at 0 but stays there.

@@ -12,6 +12,8 @@
- (BOOL) deviceHasUltraWideCamera;
- (void) deallocSession;
- (void) updateOrientation:(AVCaptureVideoOrientation)orientation;
- (void) startRecordingToOutputFileURL:(NSURL *)fileURL recordingDelegate:(id<AVCaptureFileOutputRecordingDelegate>)recordingDelegate;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- (void) startRecordingToOutputFileURL:(NSURL *)fileURL recordingDelegate:(id<AVCaptureFileOutputRecordingDelegate>)recordingDelegate;
- (void) startRecording:(NSURL *)fileURL recordingDelegate:(id<AVCaptureFileOutputRecordingDelegate>)recordingDelegate;

Can this method be renamed to startRecording ?


AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *audioError = nil;
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&audioError];
Copy link
Member

@HashirRajah HashirRajah Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should audioInput be declared in the header file like videoDeviceInput?

AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *audioError = nil;
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&audioError];
if (audioInput && [self.session canAddInput:audioInput]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (audioInput && [self.session canAddInput:audioInput]) {
if ([self.session canAddInput:audioInput]) {

Will this be enough? When looking at similar code blocks, only this check is done. For example on line 93:

if ([self.session canAddInput:videoDeviceInput]) {
    [self.session addInput:videoDeviceInput];
    self.videoDeviceInput = videoDeviceInput;
}

@@ -10,6 +10,7 @@ - (CameraSessionManager *)init {
[self.session setSessionPreset:AVCaptureSessionPresetPhoto];
}
self.filterLock = [[NSLock alloc] init];
self.movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why this line is not done in the setupSession function instead?

Im taking the example of imageOutput. The allocation and checks are all done in setupSession on line 98:

AVCapturePhotoOutput *imageOutput = [[AVCapturePhotoOutput alloc] init];
if ([self.session canAddOutput:imageOutput]) {
    [self.session addOutput:imageOutput];
    self.imageOutput = imageOutput;
}

Comment on lines +243 to +248
if (!self.movieFileOutput.isRecording) {
AVCaptureConnection *connection = [self.movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
if ([connection isVideoOrientationSupported]) {
connection.videoOrientation = [self getCurrentOrientation];
}
[self.movieFileOutput startRecordingToOutputFileURL:fileURL recordingDelegate:recordingDelegate];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do an early return?

if (self.movieFileOutput.isRecording) return;

// logic to start recording

}

- (void)startVideoCapture:(CDVInvokedUrlCommand*)command {
if (self.sessionManager != nil && !self.sessionManager.movieFileOutput.isRecording) {
Copy link
Member

@HashirRajah HashirRajah Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can invert the condition and make an early return instead of having an if and an else block

if (self.sessionManager == nil || self.sessionManager.movieFileOutput.isRecording) {
  CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Session not initialized or already recording"];
  [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  return;
}
// other logic

Copy link
Member

@HashirRajah HashirRajah Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition should be an || condition when reversing.

}

- (void)stopVideoCapture:(CDVInvokedUrlCommand*)command {
if (self.sessionManager != nil && self.sessionManager.movieFileOutput.isRecording) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments for the if part as above.

if (error) {
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.localizedDescription];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.videoCallbackContext.callbackId];
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can add a return in the if instead of an else block.

} else {
NSString *thumbnail = [self generateThumbnailForVideoAtURL:outputFileURL];
NSString *filePath = [outputFileURL path];
NSDictionary *result = @{@"nativePath": filePath, @"thumbnail": thumbnail};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can remove recording in the onStop for Android too.

@YushraJewon YushraJewon merged commit 1e24fd9 into master Oct 3, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants