Skip to content

Commit ad6866d

Browse files
author
chaos
committed
fix camera streaming may failed to work on IOS. refer to PR flutter#8733
1 parent 5743798 commit ad6866d

File tree

4 files changed

+48
-26
lines changed

4 files changed

+48
-26
lines changed

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,8 @@ extension CameraPlugin: FCPCameraApi {
307307
public func startImageStream(completion: @escaping (FlutterError?) -> Void) {
308308
captureSessionQueue.async { [weak self] in
309309
guard let strongSelf = self else { return }
310-
strongSelf.camera?.startImageStream(with: strongSelf.messenger)
311-
completion(nil)
310+
strongSelf.camera?
311+
.startImageStream(with: strongSelf.messenger, completion: completion)
312312
}
313313
}
314314

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -845,13 +845,17 @@ - (CVPixelBufferRef)copyPixelBuffer {
845845

846846
- (void)startVideoRecordingWithCompletion:(void (^)(FlutterError *_Nullable))completion
847847
messengerForStreaming:(nullable NSObject<FlutterBinaryMessenger> *)messenger {
848-
if (!_isRecording) {
849-
if (messenger != nil) {
850-
[self startImageStreamWithMessenger:messenger];
851-
}
848+
if (_isRecording){
849+
completion([FlutterError errorWithCode:@"Error"
850+
message:@"Video is already recording"
851+
details:nil]);
852+
return;
853+
}
852854

855+
// Main logic to setup the video recording in a block to reuse in the completion block.
856+
void (^videoRecordingSetupWithCompletion)(void) = ^void(void) {
853857
NSError *error;
854-
_videoRecordingPath = [self getTemporaryFilePathWithExtension:@"mp4"
858+
self->_videoRecordingPath = [self getTemporaryFilePathWithExtension:@"mp4"
855859
subfolder:@"videos"
856860
prefix:@"REC_"
857861
error:error];
@@ -871,20 +875,25 @@ - (void)startVideoRecordingWithCompletion:(void (^)(FlutterError *_Nullable))com
871875
// didOutputSampleBuffer had chance to call startWriting and lag at start of video
872876
// https://github.com/flutter/flutter/issues/132016
873877
// https://github.com/flutter/flutter/issues/151319
874-
[_videoWriter startWriting];
875-
_isFirstVideoSample = YES;
876-
_isRecording = YES;
877-
_isRecordingPaused = NO;
878-
_videoTimeOffset = CMTimeMake(0, 1);
879-
_audioTimeOffset = CMTimeMake(0, 1);
880-
_videoIsDisconnected = NO;
881-
_audioIsDisconnected = NO;
878+
[self->_videoWriter startWriting];
879+
self->_isFirstVideoSample = YES;
880+
self->_isRecording = YES;
881+
self->_isRecordingPaused = NO;
882+
self->_videoTimeOffset = CMTimeMake(0, 1);
883+
self->_audioTimeOffset = CMTimeMake(0, 1);
884+
self->_videoIsDisconnected = NO;
885+
self->_audioIsDisconnected = NO;
882886
completion(nil);
883-
} else {
884-
completion([FlutterError errorWithCode:@"Error"
885-
message:@"Video is already recording"
886-
details:nil]);
887+
};
888+
889+
if (messenger != nil) {
890+
[self startImageStreamWithMessenger:messenger
891+
completion:^(FlutterError *_Nullable error) {
892+
videoRecordingSetupWithCompletion();
893+
}];
894+
return;
887895
}
896+
videoRecordingSetupWithCompletion();
888897
}
889898

890899
- (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable,
@@ -1176,14 +1185,17 @@ - (void)setExposureOffset:(double)offset {
11761185
[_captureDevice unlockForConfiguration];
11771186
}
11781187

1179-
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger {
1188+
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger
1189+
completion:(void (^)(FlutterError *))completion {
11801190
[self startImageStreamWithMessenger:messenger
11811191
imageStreamHandler:[[FLTImageStreamHandler alloc]
1182-
initWithCaptureSessionQueue:_captureSessionQueue]];
1192+
initWithCaptureSessionQueue:_captureSessionQueue]
1193+
completion:completion];
11831194
}
11841195

11851196
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger
1186-
imageStreamHandler:(FLTImageStreamHandler *)imageStreamHandler {
1197+
imageStreamHandler:(FLTImageStreamHandler *)imageStreamHandler
1198+
completion:(void (^)(FlutterError *))completion {
11871199
if (!_isStreamingImages) {
11881200
id<FLTEventChannel> eventChannel = [FlutterEventChannel
11891201
eventChannelWithName:@"plugins.flutter.io/camera_avfoundation/imageStream"
@@ -1196,19 +1208,27 @@ - (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messen
11961208
[threadSafeEventChannel setStreamHandler:_imageStreamHandler
11971209
completion:^{
11981210
typeof(self) strongSelf = weakSelf;
1199-
if (!strongSelf) return;
1211+
if (!strongSelf) {
1212+
completion(nil);
1213+
return;
1214+
}
12001215

12011216
dispatch_async(strongSelf.captureSessionQueue, ^{
12021217
// cannot use the outter strongSelf
12031218
typeof(self) strongSelf = weakSelf;
1204-
if (!strongSelf) return;
1219+
if (!strongSelf) {
1220+
completion(nil);
1221+
return;
1222+
}
12051223

12061224
strongSelf.isStreamingImages = YES;
12071225
strongSelf.streamingPendingFramesCount = 0;
1226+
completion(nil);
12081227
});
12091228
}];
12101229
} else {
12111230
[self reportErrorMessage:@"Images from camera are already streaming!"];
1231+
completion(nil);
12121232
}
12131233
}
12141234

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ NS_ASSUME_NONNULL_BEGIN
9999
withCompletion:(void (^)(FlutterError *_Nullable))completion
100100
NS_SWIFT_NAME(setFocusPoint(_:completion:));
101101
- (void)setExposureOffset:(double)offset;
102-
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger;
102+
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger
103+
completion:(nonnull void (^)(FlutterError *_Nullable))completion;
103104
- (void)stopImageStream;
104105
- (void)setZoomLevel:(CGFloat)zoom withCompletion:(void (^)(FlutterError *_Nullable))completion;
105106
- (void)setUpCaptureSessionForAudioIfNeeded;

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam_Test.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151

5252
/// Start streaming images.
5353
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger
54-
imageStreamHandler:(FLTImageStreamHandler *)imageStreamHandler;
54+
imageStreamHandler:(FLTImageStreamHandler *)imageStreamHandler
55+
completion:(void (^)(FlutterError *))completion;
5556

5657
@end

0 commit comments

Comments
 (0)