iOS 16 - stopRecordVideo() returns nothing
Describe the bug
On iOS, when you call stopRecordVideo(), nothing is returned.
Expected behavior Should return a file path or base64 video
Smartphone (please complete the following information):
- Device: iPhone 12
- OS: 16.5.1
Additional context
To Native -> CameraPreview stopRecordVideo 105993178
The native function gets called but no response
The same problem. Verified also on Android and there problem not occurs.
From the source code that I checked, there was some video capturing logic implemented on ios, but it was commented out, so I think it just isn't supported right now.
func captureVideo(completion: @escaping (URL?, Error?) -> Void) { guard let captureSession = self.captureSession, captureSession.isRunning else { completion(nil, CameraControllerError.captureSessionIsMissing) return } let path = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0] let identifier = UUID() let randomIdentifier = identifier.uuidString.replacingOccurrences(of: "-", with: "") let finalIdentifier = String(randomIdentifier.prefix(8)) let fileName="cpcp_video_"+finalIdentifier+".mp4" let fileUrl = path.appendingPathComponent(fileName) try? FileManager.default.removeItem(at: fileUrl) /*videoOutput!.startRecording(to: fileUrl, recordingDelegate: self) self.videoRecordCompletionBlock = completion*/ }
Wow, we must all be on the same page today. Correct, the video recording stuff is commented out.
commit 92a56a229fe7aea9d9b549688b6e3a69675b7b50 Author: Anthony F Date: Sun Jun 6 11:07:38 2021 +0200
diff --git a/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java b/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java
index 1b0b2af..1f057ba 100644
--- a/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java
+++ b/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java
@@ -1,6 +1,7 @@
package com.ahm.capacitor.camera.preview;
...skipping...
jsObject.put("videoFilePath", file);
- pluginCall.success(jsObject);
+ pluginCall.resolve(jsObject);
}
@Override
public void onStopRecordVideoError(String error) {
@@ -404,7 +390,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
@PluginMethod()
public void startRecordVideo(final PluginCall call) {
if(this.hasCamera(call) == false){
- call.error("Camera is not running");
+ call.reject("Camera is not running");
return;
}
final String filename = "videoTmp";
@@ -425,17 +411,19 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
}
});
- call.success();
+ call.resolve();
}
@PluginMethod()
public void stopRecordVideo(PluginCall call) {
if(this.hasCamera(call) == false){
- call.error("Camera is not running");
+ call.reject("Camera is not running");
...skipping...
- videoOutput!.startRecording(to: fileUrl, recordingDelegate: self)
- self.videoRecordCompletionBlock = completion
+ /*videoOutput!.startRecording(to: fileUrl, recordingDelegate: self)
+ self.videoRecordCompletionBlock = completion*/
}
func stopRecording(completion: @escaping (Error?) -> Void) {
@@ -412,7 +412,7 @@ extension CameraController {
completion(CameraControllerError.captureSessionIsMissing)
return
}
- self.videoOutput?.stopRecording()
+ //self.videoOutput?.stopRecording()
}
}
How do I get this running locally? I'd like to test things out
Any updates?
I have tried fixing the issue here: https://github.com/mario-deaconescu/camera-preview stopRecordVideo() now returns a path to the recorded video. I have not yet tested if the video actually displays correctly, because I am using Capacitor with Angular right now, and I don't know how to display a local file in a video tag. Perhaps by using the Capacitor filesystem plugin, but I haven't gone into it at the moment. Feel free to look over the code, test it, and propose changes. If all goes well I will issue a pr to solve the issue.
@mario-deaconescu I reviewed your changes and pulled in your "ios-video-recording" branch. I still don't see any return data / path. Looks like stopRecording may be promise, but I'm not getting data back from a ".then" either. Are you actually seeing an *.mp4 path returning?
@ttgsgmafe Yes, I am receiving a .mp4 path in Library/Cache. Are you receiving any errors? I tried setting it up such that anything that results in no video throws an error. And if you're actually not receiving anything, does the iOS plugin return a path that's not received by the typescript promise, or is it not even returning anything from the native code?
Can confirm it works @mario-deaconescu! 🎉
End the recording:
const result = await CameraPreview.stopRecordVideo();
const fileName = result.value.substring(result.value.lastIndexOf("/") + 1);
const file = await Filesystem.readFile({
directory: Directory.Cache,
path: fileName,
});
Show the footage:
{file.data && (
<video
autoPlay
loop
src={`data:video/mp4;base64,${file.data}`}
style={{
width: "100%",
height: "100%",
position: "absolute",
top: 0,
opacity: videoBase64 ? 1 : 0,
}}
/>
)}
Thank you!
@mario-deaconescu @alexandargyurov Thanks for the super quick responses! I figured out my problem. I had manually replaced the "@capacitor-community/camera-preview" with the Git URL, removed the node_modules, and reinstalled. However, it was still pulling the original camera-preview from my package-lock.json. I'm returning the path now.
This is awesome! Thanks again!
i'm having the same issue. I dont get what you guys did to make it work. We are using ionic/angular/capacitor. The function stopRecordVideo() is returning nothing, and also we cant get errors within try catch. Can anyone help ?