@capgo/camera-preview 8.1.2 → 8.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1520,6 +1520,31 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
|
|
|
1520
1520
|
|
|
1521
1521
|
@Override
|
|
1522
1522
|
public void onCameraStarted(int width, int height, int x, int y) {
|
|
1523
|
+
// Always transition window and WebView backgrounds to transparent when the camera starts,
|
|
1524
|
+
// regardless of whether there is a pending JS call. This is critical for the
|
|
1525
|
+
// background/foreground resume cycle: on resume, handleOnResume() sets backgrounds to
|
|
1526
|
+
// black (to prevent flicker) and then restarts the camera session, but
|
|
1527
|
+
// cameraStartCallbackId is null at that point. Without this unconditional block the
|
|
1528
|
+
// window and WebView stay black after every background/foreground transition.
|
|
1529
|
+
// Both backgrounds are set together in the same UI thread operation to avoid race
|
|
1530
|
+
// conditions and compositor layering issues.
|
|
1531
|
+
if (isToBackMode()) {
|
|
1532
|
+
getBridge()
|
|
1533
|
+
.getActivity()
|
|
1534
|
+
.runOnUiThread(() -> {
|
|
1535
|
+
try {
|
|
1536
|
+
// Set window background to transparent
|
|
1537
|
+
getBridge().getActivity().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
|
1538
|
+
// Set webview background to almost-transparent for MIUI compatibility
|
|
1539
|
+
// Use alpha=1 instead of 0 to work around MIUI/Xiaomi rendering issues
|
|
1540
|
+
// where Color.TRANSPARENT (alpha=0) is not rendered correctly
|
|
1541
|
+
getBridge().getWebView().setBackgroundColor(Color.argb(1, 255, 255, 255));
|
|
1542
|
+
} catch (Exception e) {
|
|
1543
|
+
Log.w(TAG, "Failed to set backgrounds to transparent", e);
|
|
1544
|
+
}
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1523
1548
|
PluginCall call = bridge.getSavedCall(cameraStartCallbackId);
|
|
1524
1549
|
if (call != null) {
|
|
1525
1550
|
// Convert pixel values back to logical units
|
|
@@ -1650,26 +1675,6 @@ public class CameraPreview extends Plugin implements CameraXView.CameraXViewList
|
|
|
1650
1675
|
")"
|
|
1651
1676
|
);
|
|
1652
1677
|
|
|
1653
|
-
// Transition window and webview backgrounds to transparent now that camera is ready
|
|
1654
|
-
// This prevents flickering during camera initialization
|
|
1655
|
-
// Both are set together in the same UI thread operation to avoid race conditions
|
|
1656
|
-
if (isToBackMode()) {
|
|
1657
|
-
getBridge()
|
|
1658
|
-
.getActivity()
|
|
1659
|
-
.runOnUiThread(() -> {
|
|
1660
|
-
try {
|
|
1661
|
-
// Set window background to transparent
|
|
1662
|
-
getBridge().getActivity().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
|
1663
|
-
// Set webview background to almost-transparent for MIUI compatibility
|
|
1664
|
-
// Use alpha=1 instead of 0 to work around MIUI/Xiaomi rendering issues
|
|
1665
|
-
// where Color.TRANSPARENT (alpha=0) is not rendered correctly
|
|
1666
|
-
getBridge().getWebView().setBackgroundColor(Color.argb(1, 255, 255, 255));
|
|
1667
|
-
} catch (Exception e) {
|
|
1668
|
-
Log.w(TAG, "Failed to set backgrounds to transparent", e);
|
|
1669
|
-
}
|
|
1670
|
-
});
|
|
1671
|
-
}
|
|
1672
|
-
|
|
1673
1678
|
call.resolve(result);
|
|
1674
1679
|
bridge.releaseCall(call);
|
|
1675
1680
|
cameraStartCallbackId = null; // Prevent re-use
|
|
@@ -976,6 +976,15 @@ extension CameraController {
|
|
|
976
976
|
captureSession.sessionPreset = desiredPreset
|
|
977
977
|
}
|
|
978
978
|
|
|
979
|
+
// Re-attach movie file output so its connection is bound to the new input.
|
|
980
|
+
if let fileVideoOutput = self.fileVideoOutput,
|
|
981
|
+
captureSession.outputs.contains(where: { $0 === fileVideoOutput }) {
|
|
982
|
+
captureSession.removeOutput(fileVideoOutput)
|
|
983
|
+
if captureSession.canAddOutput(fileVideoOutput) {
|
|
984
|
+
captureSession.addOutput(fileVideoOutput)
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
979
988
|
// Keep orientation correct
|
|
980
989
|
self.updateVideoOrientation()
|
|
981
990
|
}
|
|
@@ -2200,6 +2209,20 @@ extension CameraController {
|
|
|
2200
2209
|
throw CameraControllerError.fileVideoOutputNotFound
|
|
2201
2210
|
}
|
|
2202
2211
|
|
|
2212
|
+
// Ensure audio session is configured for recording before starting a movie,
|
|
2213
|
+
// only when we are actually recording audio (disableAudio was false).
|
|
2214
|
+
// This reclaims the microphone even if other parts of the app changed the
|
|
2215
|
+
// AVAudioSession category (e.g. for UI sound effects) between recordings.
|
|
2216
|
+
if self.audioInput != nil {
|
|
2217
|
+
do {
|
|
2218
|
+
let audioSession = AVAudioSession.sharedInstance()
|
|
2219
|
+
try audioSession.setCategory(.playAndRecord, mode: .videoRecording, options: [.defaultToSpeaker])
|
|
2220
|
+
try audioSession.setActive(true)
|
|
2221
|
+
} catch {
|
|
2222
|
+
print("[CameraPreview] Failed to configure AVAudioSession for video recording: \(error)")
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2203
2226
|
// Ensure the movie file output is attached to the active session.
|
|
2204
2227
|
// If the camera was started without cameraMode=true, the output may not have been added yet.
|
|
2205
2228
|
if !captureSession.outputs.contains(where: { $0 === fileVideoOutput }) {
|
|
@@ -2213,12 +2236,17 @@ extension CameraController {
|
|
|
2213
2236
|
captureSession.commitConfiguration()
|
|
2214
2237
|
}
|
|
2215
2238
|
|
|
2216
|
-
// cpcp_video_A6C01203 - portrait
|
|
2217
|
-
//
|
|
2218
2239
|
if let connection = fileVideoOutput.connection(with: .video) {
|
|
2219
2240
|
if connection.isEnabled == false { connection.isEnabled = true }
|
|
2220
2241
|
// Goes off accelerometer now
|
|
2221
2242
|
connection.videoOrientation = self.getPhysicalOrientation()
|
|
2243
|
+
|
|
2244
|
+
// Front camera: mirror the recorded video so it looks natural (selfie style).
|
|
2245
|
+
if self.currentCameraPosition == .front, connection.isVideoMirroringSupported {
|
|
2246
|
+
connection.isVideoMirrored = true
|
|
2247
|
+
} else {
|
|
2248
|
+
connection.isVideoMirrored = false
|
|
2249
|
+
}
|
|
2222
2250
|
}
|
|
2223
2251
|
|
|
2224
2252
|
let identifier = UUID()
|
|
@@ -34,7 +34,7 @@ extension UIWindow {
|
|
|
34
34
|
*/
|
|
35
35
|
@objc(CameraPreview)
|
|
36
36
|
public class CameraPreview: CAPPlugin, CAPBridgedPlugin, CLLocationManagerDelegate {
|
|
37
|
-
private let pluginVersion: String = "8.1.
|
|
37
|
+
private let pluginVersion: String = "8.1.4"
|
|
38
38
|
public let identifier = "CameraPreviewPlugin"
|
|
39
39
|
public let jsName = "CameraPreview"
|
|
40
40
|
public let pluginMethods: [CAPPluginMethod] = [
|