diff --git a/package/ios/CameraView.swift b/package/ios/CameraView.swift index 8dd947e..8ad8111 100644 --- a/package/ios/CameraView.swift +++ b/package/ios/CameraView.swift @@ -62,6 +62,7 @@ public final class CameraView: UIView, CameraSessionDelegate { @objc var onStarted: RCTDirectEventBlock? @objc var onStopped: RCTDirectEventBlock? @objc var onViewReady: RCTDirectEventBlock? + @objc var onVideoChunkReady: RCTDirectEventBlock? @objc var onCodeScanned: RCTDirectEventBlock? // zoom @objc var enableZoomGesture = false { @@ -335,6 +336,25 @@ public final class CameraView: UIView, CameraSessionDelegate { } #endif } + + func onVideoChunkReady(chunk: ChunkedRecorder.Chunk) { + ReactLogger.log(level: .info, message: "Chunk ready: \(chunk)") + + guard let onVideoChunkReady = onVideoChunkReady else { + return + } + + switch chunk.type { + case .initialization: + // FIXME: send initialization segment + return + case .data(index: let index): + onVideoChunkReady([ + "filepath": chunk.url.path, + "index": index, + ]) + } + } func onCodeScanned(codes: [CameraSession.Code], scannerFrame: CameraSession.CodeScannerFrame) { guard let onCodeScanned = onCodeScanned else { diff --git a/package/ios/CameraViewManager.m b/package/ios/CameraViewManager.m index fa2e9ca..5e87503 100644 --- a/package/ios/CameraViewManager.m +++ b/package/ios/CameraViewManager.m @@ -55,6 +55,7 @@ RCT_EXPORT_VIEW_PROPERTY(onInitialized, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onStarted, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onStopped, RCTDirectEventBlock); RCT_EXPORT_VIEW_PROPERTY(onViewReady, RCTDirectEventBlock); +RCT_EXPORT_VIEW_PROPERTY(onVideoChunkReady, RCTDirectEventBlock); // Code Scanner RCT_EXPORT_VIEW_PROPERTY(codeScannerOptions, NSDictionary); RCT_EXPORT_VIEW_PROPERTY(onCodeScanned, RCTDirectEventBlock); diff --git a/package/ios/Core/CameraSession+Video.swift b/package/ios/Core/CameraSession+Video.swift index 00ff941..0b4b8e0 100644 --- a/package/ios/Core/CameraSession+Video.swift +++ b/package/ios/Core/CameraSession+Video.swift @@ -33,6 +33,14 @@ extension CameraSession { } let enableAudio = self.configuration?.audio != .disabled + + // Callback for when new chunks are ready + let onChunkReady: (ChunkedRecorder.Chunk) -> Void = { chunk in + guard let delegate = self.delegate else { + return + } + delegate.onVideoChunkReady(chunk: chunk) + } // Callback for when the recording ends let onFinish = { (recordingSession: RecordingSession, status: AVAssetWriter.Status, error: Error?) in @@ -89,6 +97,7 @@ extension CameraSession { // Create RecordingSession for the temp file let recordingSession = try RecordingSession(url: tempURL, fileType: options.fileType, + onChunkReady: onChunkReady, completion: onFinish) // Init Audio + Activate Audio Session (optional) diff --git a/package/ios/Core/CameraSessionDelegate.swift b/package/ios/Core/CameraSessionDelegate.swift index 2c1a0b2..b72c2ec 100644 --- a/package/ios/Core/CameraSessionDelegate.swift +++ b/package/ios/Core/CameraSessionDelegate.swift @@ -33,6 +33,10 @@ protocol CameraSessionDelegate: AnyObject { Called for every frame (if video or frameProcessor is enabled) */ func onFrame(sampleBuffer: CMSampleBuffer) + /** + Called whenever a new video chunk is available + */ + func onVideoChunkReady(chunk: ChunkedRecorder.Chunk) /** Called whenever a QR/Barcode has been scanned. Only if the CodeScanner Output is enabled */ diff --git a/package/ios/Core/RecordingSession.swift b/package/ios/Core/RecordingSession.swift index 154155b..5224705 100644 --- a/package/ios/Core/RecordingSession.swift +++ b/package/ios/Core/RecordingSession.swift @@ -74,13 +74,12 @@ class RecordingSession { init(url: URL, fileType: AVFileType, + onChunkReady: @escaping ((ChunkedRecorder.Chunk) -> Void), completion: @escaping (RecordingSession, AVAssetWriter.Status, Error?) -> Void) throws { completionHandler = completion do { - recorder = try ChunkedRecorder(url: url.deletingLastPathComponent()) { segment in - ReactLogger.log(level: .info, message: "Chunk ready: \(segment)") - } + recorder = try ChunkedRecorder(url: url.deletingLastPathComponent(), onChunkReady: onChunkReady) assetWriter = AVAssetWriter(contentType: UTType(fileType.rawValue)!) assetWriter.shouldOptimizeForNetworkUse = false assetWriter.outputFileTypeProfile = .mpeg4AppleHLS