diff --git a/README.md b/README.md
index ae6d467..9844ce1 100644
--- a/README.md
+++ b/README.md
@@ -286,12 +286,14 @@ addListener(eventName: 'onVolumeInput', listenerFunc: (event: { value: number; }
#### VideoRecorderOptions
-| Prop | Type |
-| ------------------- | --------------------------------------------------------------------- |
-| **`camera`** | VideoRecorderCamera
|
-| **`quality`** | VideoRecorderQuality
|
-| **`autoShow`** | boolean
|
-| **`previewFrames`** | VideoRecorderPreviewFrame[]
|
+| Prop | Type | Description | Default |
+| ------------------- | --------------------------------------------------------------------- | ------------------------------ | -------------------- |
+| **`camera`** | VideoRecorderCamera
| | |
+| **`quality`** | VideoRecorderQuality
| | |
+| **`autoShow`** | boolean
| | |
+| **`previewFrames`** | VideoRecorderPreviewFrame[]
| | |
+| **`videoBitrate`** | number
| The default bitrate is 4.5Mbps | 4500000
|
+
#### VideoRecorderPreviewFrame
diff --git a/android/src/main/java/com/capacitorcommunity/videorecorder/VideoRecorder.java b/android/src/main/java/com/capacitorcommunity/videorecorder/VideoRecorder.java
deleted file mode 100644
index 51af48c..0000000
--- a/android/src/main/java/com/capacitorcommunity/videorecorder/VideoRecorder.java
+++ /dev/null
@@ -1,469 +0,0 @@
-package com.capacitorcommunity.videorecorder;
-
-import android.graphics.Color;
-import android.net.Uri;
-import android.util.DisplayMetrics;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import com.getcapacitor.FileUtils;
-import com.getcapacitor.JSArray;
-import com.getcapacitor.JSObject;
-import com.getcapacitor.NativePlugin;
-import com.getcapacitor.Plugin;
-import com.getcapacitor.PluginCall;
-import com.getcapacitor.PluginMethod;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.HashMap;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import androidx.coordinatorlayout.widget.CoordinatorLayout;
-import co.fitcom.fancycamera.CameraEventListenerUI;
-import co.fitcom.fancycamera.EventType;
-import co.fitcom.fancycamera.FancyCamera;
-import co.fitcom.fancycamera.PhotoEvent;
-import co.fitcom.fancycamera.VideoEvent;
-
-@NativePlugin(
- requestCodes = {
- VideoRecorder.REQUEST_CODE
- }
-)
-public class VideoRecorder extends Plugin {
- static final int REQUEST_CODE = 868;
- private FancyCamera fancyCamera;
- private PluginCall call;
- private HashMap previewFrameConfigs;
- private FrameConfig currentFrameConfig;
- private FancyCamera.CameraPosition cameraPosition = FancyCamera.CameraPosition.FRONT;
- private Timer audioFeedbackTimer;
- private boolean timerStarted;
-
- PluginCall getCall() {
- return call;
- }
-
- @Override
- protected void handleRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
- super.handleRequestPermissionsResult(requestCode, permissions, grantResults);
- if (fancyCamera.hasPermission()) {
- if (getCall() != null) {
- getCall().success();
- } else if (savedLastCall != null) {
- savedLastCall.success();
- }
- startCamera();
- } else {
- if (getCall() != null) {
- getCall().reject("");
- } else if (savedLastCall != null) {
- savedLastCall.reject("");
- }
- }
- }
-
- private void startCamera() {
- if (fancyCamera == null || fancyCamera.cameraStarted()) return;
- fancyCamera.start();
- }
-
- private void startTimer() {
- if (timerStarted) {
- return;
- }
-
- if (audioFeedbackTimer != null) {
- audioFeedbackTimer.cancel();
- audioFeedbackTimer = null;
- }
-
- audioFeedbackTimer = new Timer();
- audioFeedbackTimer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- timerStarted = true;
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- JSObject object = new JSObject();
- double db = fancyCamera != null ? fancyCamera.getDB() : 0;
- object.put("value", db);
- //notifyListeners("onVolumeInput", object);
- }
- });
- }
- }, 0, 100);
- }
-
- private void stopTimer() {
- if (audioFeedbackTimer != null) {
- audioFeedbackTimer.cancel();
- audioFeedbackTimer = null;
- }
- timerStarted = false;
- }
-
- @Override
- public void load() {
- super.load();
- }
-
- @PluginMethod()
- public void initialize(final PluginCall call) {
- JSObject defaultFrame = new JSObject();
- defaultFrame.put("id", "default");
- currentFrameConfig = new FrameConfig(defaultFrame);
- previewFrameConfigs = new HashMap<>();
-
- fancyCamera = new FancyCamera(this.getContext());
- fancyCamera.setDisableHEVC(true);
- fancyCamera.setListener(new CameraEventListenerUI() {
- public void onCameraOpenUI() {
- if (getCall() != null) {
- getCall().success();
- }
- startTimer();
- updateCameraView(currentFrameConfig);
- for (FrameConfig f : previewFrameConfigs.values()) {
- updateCameraView(f);
- }
- }
-
- public void onCameraCloseUI() {
- if (getCall() != null) {
- getCall().success();
- }
- stopTimer();
- }
-
- @Override
- public void onPhotoEventUI(PhotoEvent event) {
-
- }
-
- @Override
- public void onVideoEventUI(VideoEvent event) {
- if (event.getType() == EventType.INFO &&
- event
- .getMessage().contains(VideoEvent.EventInfo.RECORDING_FINISHED.toString())) {
- if (getCall() != null) {
- JSObject object = new JSObject();
- String path = FileUtils.getPortablePath(getContext(), bridge.getLocalUrl(), Uri.fromFile(event.getFile()));
- object.put("videoUrl", path);
- getCall().resolve(object);
- } else {
- if (event.getType() == co.fitcom.fancycamera.EventType.ERROR) {
- getCall().reject(event.getMessage());
- }
- }
-
- } else if (event.getType() == EventType.INFO &&
- event
- .getMessage().contains(VideoEvent.EventInfo.RECORDING_STARTED.toString())) {
- if (getCall() != null) {
- getCall().success();
- }
-
- }
- }
- });
- final FrameLayout.LayoutParams cameraPreviewParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ((CoordinatorLayout) bridge.getWebView().getParent()).addView(fancyCamera, cameraPreviewParams);
- bridge.getWebView().bringToFront();
- bridge.getWebView().getParent().requestLayout();
- ((CoordinatorLayout) bridge.getWebView().getParent()).invalidate();
- }
- });
-
-
- defaultFrame = new JSObject();
- defaultFrame.put("id", "default");
- JSArray defaultArray = new JSArray();
- defaultArray.put(defaultFrame);
- JSArray array = call.getArray("previewFrames", defaultArray);
- int size = array.length();
- for (int i = 0; i < size; i++) {
- try {
- JSONObject obj = (JSONObject) array.get(i);
- FrameConfig config = new FrameConfig(JSObject.fromJSONObject(obj));
- previewFrameConfigs.put(config.id, config);
- } catch (JSONException ignored) {
-
- }
- }
-
- fancyCamera.setCameraPosition(1);
- if (fancyCamera.hasPermission()) {
- // Swapping these around since it is the other way for iOS and the plugin interface needs to stay consistent
- if (call.getInt("camera") == 1) {
- fancyCamera.setCameraPosition(0);
- } else if (call.getInt("camera") == 0) {
- fancyCamera.setCameraPosition(1);
- } else {
- fancyCamera.setCameraPosition(1);
- }
-
- if (!fancyCamera.cameraStarted()) {
- startCamera();
- }
- } else {
- fancyCamera.requestPermission();
- }
-
- this.call = call;
- }
-
- @PluginMethod()
- public void destroy(PluginCall call) {
- makeOpaque();
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ((ViewGroup) bridge.getWebView().getParent()).removeView(fancyCamera);
- }
- });
- fancyCamera.release();
- call.success();
- }
-
- private void makeOpaque() {
- this.bridge.getWebView().setBackgroundColor(Color.WHITE);
- }
-
- @PluginMethod()
- public void showPreviewFrame(PluginCall call) {
- int position = call.getInt("position");
- int quality = call.getInt("quality");
- fancyCamera.setCameraPosition(position);
- fancyCamera.setQuality(quality);
- bridge.getWebView().setBackgroundColor(Color.argb(0, 0, 0, 0));
- if (fancyCamera != null && !fancyCamera.cameraStarted()) {
- startCamera();
- this.call = call;
- } else {
- call.success();
- }
- }
-
- @PluginMethod()
- public void hidePreviewFrame(PluginCall call) {
- makeOpaque();
- fancyCamera.stop();
- this.call = call;
- }
-
- @PluginMethod()
- public void togglePip(PluginCall call) {
-
- }
-
- @PluginMethod()
- public void startRecording(PluginCall call) {
- this.call = call;
- fancyCamera.startRecording();
- // call.success();
- }
-
- @PluginMethod()
- public void stopRecording(PluginCall call) {
- this.call = call;
- fancyCamera.stopRecording();
- }
-
- @PluginMethod()
- public void flipCamera(PluginCall call) {
- fancyCamera.toggleCamera();
- call.success();
- }
-
- @PluginMethod()
- public void getDuration(PluginCall call) {
- JSObject object = new JSObject();
- object.put("value", fancyCamera.getDuration());
- call.resolve(object);
- }
-
- @PluginMethod()
- public void setPosition(PluginCall call) {
- int position = call.getInt("position");
- fancyCamera.setCameraPosition(position);
- }
-
- @PluginMethod()
- public void setQuality(PluginCall call) {
- int quality = call.getInt("quality");
- fancyCamera.setQuality(quality);
- }
-
- @PluginMethod()
- public void addPreviewFrameConfig(PluginCall call) {
- if (fancyCamera != null && fancyCamera.cameraStarted()) {
- String layerId = call.getString("id");
- if (layerId.isEmpty()) {
- call.error("Must provide layer id");
- return;
- }
-
- FrameConfig config = new FrameConfig(call.getData());
-
- if (previewFrameConfigs.containsKey(layerId)) {
- editPreviewFrameConfig(call);
- return;
- } else {
- previewFrameConfigs.put(layerId, config);
- }
- call.success();
- }
- }
-
- @PluginMethod()
- public void editPreviewFrameConfig(PluginCall call) {
- if (fancyCamera != null && fancyCamera.cameraStarted()) {
- String layerId = call.getString("id");
- if (layerId.isEmpty()) {
- call.error("Must provide layer id");
- return;
- }
-
- FrameConfig updatedConfig = new FrameConfig(call.getData());
- previewFrameConfigs.put(layerId, updatedConfig);
-
- if (currentFrameConfig.id.equals(layerId)) {
- currentFrameConfig = updatedConfig;
- updateCameraView(currentFrameConfig);
- }
-
- call.success();
- }
- }
-
-
- @PluginMethod()
- public void switchToPreviewFrame(PluginCall call) {
- if (fancyCamera != null && fancyCamera.cameraStarted()) {
- String layerId = call.getString("id");
- if (layerId.isEmpty()) {
- call.error("Must provide layer id");
- return;
- }
- FrameConfig existingConfig = previewFrameConfigs.get(layerId);
- if (existingConfig != null) {
- if (!existingConfig.id.equals(currentFrameConfig.id)) {
- currentFrameConfig = existingConfig;
- updateCameraView(currentFrameConfig);
- }
-
- } else {
- call.error("Frame config does not exist");
- return;
- }
- call.success();
- }
- }
-
- private int getPixels(int value) {
- return (int) (value * getContext().getResources().getDisplayMetrics().density + 0.5f);
- }
-
- private void updateCameraView(final FrameConfig frameConfig) {
-
- DisplayMetrics displayMetrics = new DisplayMetrics();
- getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
- int deviceHeight = displayMetrics.heightPixels;
- int deviceWidth = displayMetrics.widthPixels;
- int width;
- int height;
- if (fancyCamera.getLayoutParams() == null) {
- fancyCamera.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
- }
-
- ViewGroup.LayoutParams oldParams = fancyCamera.getLayoutParams();
-
- if (frameConfig.width == -1) {
- width = deviceWidth;
- } else {
- width = getPixels(frameConfig.width);
- }
-
- if (frameConfig.height == -1) {
- height = deviceHeight;
- } else {
- height = getPixels(frameConfig.height);
- }
-
- oldParams.width = width;
- oldParams.height = height;
- //fancyCamera.setY(frameConfig.y);
- //fancyCamera.setX(frameConfig.x);
- fancyCamera.setY(getPixels((int) frameConfig.y));
- fancyCamera.setX(getPixels((int) frameConfig.x));
- fancyCamera.setElevation(9);
- bridge.getWebView().setElevation(9);
- bridge.getWebView().setBackgroundColor(Color.argb(0, 0, 0, 0));
- if (frameConfig.stackPosition.equals("front")) {
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- fancyCamera.bringToFront();
- bridge.getWebView().getParent().requestLayout();
- ((CoordinatorLayout) bridge.getWebView().getParent()).invalidate();
- }
- });
-
- } else if (frameConfig.stackPosition.equals("back")) {
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (frameConfig.stackPosition.equals("back")) {
- getBridge().getWebView().bringToFront();
- }
- bridge.getWebView().getParent().requestLayout();
- ((CoordinatorLayout) bridge.getWebView().getParent()).invalidate();
- }
- });
- }
-
- }
-
-
- class FrameConfig {
- String id;
- String stackPosition;
- float x;
- float y;
- int width;
- int height;
- float borderRadius;
- DropShadow dropShadow;
-
- FrameConfig(JSObject object) {
- id = object.getString("id");
- stackPosition = object.getString("stackPosition", "back");
- x = object.getInteger("x", 0).floatValue();
- y = object.getInteger("y", 0).floatValue();
- width = object.getInteger("width", -1);
- height = object.getInteger("height", -1);
- borderRadius = object.getInteger("borderRadius", 0);
- JSObject ds = object.getJSObject("dropShadow");
- dropShadow = new DropShadow(ds != null ? ds : new JSObject());
- }
-
- class DropShadow {
- float opacity;
- float radius;
- Color color;
-
- DropShadow(JSObject object) {
- opacity = object.getInteger("opacity", 0).floatValue();
- radius = object.getInteger("radius", 0).floatValue();
- }
- }
- }
-}
diff --git a/android/src/main/java/com/capacitorcommunity/videorecorder/VideoRecorderPlugin.java b/android/src/main/java/com/capacitorcommunity/videorecorder/VideoRecorderPlugin.java
index 4151705..a11a319 100644
--- a/android/src/main/java/com/capacitorcommunity/videorecorder/VideoRecorderPlugin.java
+++ b/android/src/main/java/com/capacitorcommunity/videorecorder/VideoRecorderPlugin.java
@@ -32,11 +32,10 @@
@CapacitorPlugin(
name = "VideoRecorder",
requestCodes = {
- VideoRecorder.REQUEST_CODE
+ 868
}
)
public class VideoRecorderPlugin extends Plugin {
- static final int REQUEST_CODE = 868;
private FancyCamera fancyCamera;
private PluginCall call;
private HashMap previewFrameConfigs;
@@ -44,6 +43,7 @@ public class VideoRecorderPlugin extends Plugin {
private FancyCamera.CameraPosition cameraPosition = FancyCamera.CameraPosition.FRONT;
private Timer audioFeedbackTimer;
private boolean timerStarted;
+ private Integer videoBitrate = 4500000;
PluginCall getCall() {
return call;
@@ -122,7 +122,12 @@ public void initialize(final PluginCall call) {
currentFrameConfig = new FrameConfig(defaultFrame);
previewFrameConfigs = new HashMap<>();
+ if (call.getInt("videoBitrate") != null) {
+ videoBitrate = call.getInt("videoBitrate");
+ }
+
fancyCamera = new FancyCamera(this.getContext());
+ fancyCamera.setMaxVideoBitrate(videoBitrate);
fancyCamera.setDisableHEVC(true);
fancyCamera.setListener(new CameraEventListenerUI() {
public void onCameraOpenUI() {
@@ -174,7 +179,8 @@ public void onVideoEventUI(VideoEvent event) {
}
}
});
- final FrameLayout.LayoutParams cameraPreviewParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
+ final FrameLayout.LayoutParams cameraPreviewParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
+ fancyCamera.setLayoutParams(cameraPreviewParams);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -269,9 +275,9 @@ public void togglePip(PluginCall call) {
@PluginMethod()
public void startRecording(PluginCall call) {
- this.call = call;
+ fancyCamera.setAutoFocus(true);
fancyCamera.startRecording();
- // call.success();
+ call.success();
}
@PluginMethod()
@@ -381,32 +387,59 @@ private void updateCameraView(final FrameConfig frameConfig) {
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int deviceHeight = displayMetrics.heightPixels;
int deviceWidth = displayMetrics.widthPixels;
- int width;
- int height;
+ boolean isLandscape = deviceWidth > deviceHeight;
+
if (fancyCamera.getLayoutParams() == null) {
fancyCamera.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
- ViewGroup.LayoutParams oldParams = fancyCamera.getLayoutParams();
-
- if (frameConfig.width == -1) {
+ // Calculate the aspect ratio dimensions
+ int width, height;
+ if (isLandscape) {
width = deviceWidth;
+ height = (int) (deviceWidth * 9.0 / 16.0);
} else {
- width = getPixels(frameConfig.width);
+ width = deviceWidth;
+ height = (int) (deviceWidth * 4.0 / 3.0);
}
- if (frameConfig.height == -1) {
+ // If the calculated height is greater than the device height, adjust the width and height
+ if (height > deviceHeight) {
height = deviceHeight;
- } else {
+ width = isLandscape ? (int) (deviceHeight * 16.0 / 9.0) : (int) (deviceHeight * 3.0 / 4.0);
+ }
+
+ ViewGroup.LayoutParams oldParams = fancyCamera.getLayoutParams();
+
+ if (frameConfig.width != -1) {
+ width = getPixels(frameConfig.width);
+ }
+
+ if (frameConfig.height != -1) {
height = getPixels(frameConfig.height);
}
oldParams.width = width;
oldParams.height = height;
- //fancyCamera.setY(frameConfig.y);
- //fancyCamera.setX(frameConfig.x);
- fancyCamera.setY(getPixels((int) frameConfig.y));
- fancyCamera.setX(getPixels((int) frameConfig.x));
+ fancyCamera.setLayoutParams(oldParams);
+
+ // Center the preview frame vertically if y is 0 and height and width are -1
+ if (frameConfig.y == 0 && frameConfig.height == -1 && frameConfig.width == -1) {
+ fancyCamera.setY((deviceHeight - height) / 2);
+ } else {
+ fancyCamera.setY(getPixels((int) frameConfig.y));
+ }
+
+ // Center the preview frame horizontally if x is 0 and height and width are -1
+ if (isLandscape && frameConfig.x == 0 && frameConfig.height == -1 && frameConfig.width == -1) {
+ fancyCamera.setX((deviceWidth - width) / 2);
+ } else {
+ fancyCamera.setX(getPixels((int) frameConfig.x));
+ }
+
+ // Set the background color to black
+ ((ViewGroup) fancyCamera.getParent()).setBackgroundColor(Color.BLACK);
+
fancyCamera.setElevation(9);
bridge.getWebView().setElevation(9);
bridge.getWebView().setBackgroundColor(Color.argb(0, 0, 0, 0));
diff --git a/example/package-lock.json b/example/package-lock.json
index 35e7951..05a6199 100644
--- a/example/package-lock.json
+++ b/example/package-lock.json
@@ -60,7 +60,7 @@
}
},
"..": {
- "version": "5.0.1",
+ "version": "5.0.2",
"license": "MIT",
"devDependencies": {
"@capacitor/android": "^5.0.0",
diff --git a/example/src/app/home/home.page.ts b/example/src/app/home/home.page.ts
index bfb11b2..9876a51 100644
--- a/example/src/app/home/home.page.ts
+++ b/example/src/app/home/home.page.ts
@@ -40,7 +40,7 @@ export class HomePage implements OnInit, OnDestroy {
showVideos = false;
durationIntervalId!: any;
duration = "00:00";
- quality = VideoRecorderQuality.HIGHEST;
+ quality = VideoRecorderQuality.MAX_720P;
videoQualityMap = [
{ command: VideoRecorderQuality.HIGHEST, label: 'Highest' },
@@ -112,7 +112,8 @@ export class HomePage implements OnInit, OnDestroy {
await VideoRecorder.initialize({
camera: VideoRecorderCamera.BACK,
previewFrames: [config],
- quality: this.quality
+ quality: this.quality,
+ videoBitrate: 4500000,
});
if (this.platform.is('android')) {
@@ -127,30 +128,34 @@ export class HomePage implements OnInit, OnDestroy {
}
async startRecording() {
- await this.initialise();
- await VideoRecorder.startRecording();
- this.isRecording = true;
- this.showVideos = false;
-
- // lock screen orientation when recording
- const orientation = await ScreenOrientation.orientation();
-
- if (this.platform.is('ios')) {
- // On iOS the landscape-primary and landscape-secondary are flipped for some reason
- if (orientation.type === 'landscape-primary') {
- orientation.type = 'landscape-secondary'
- } else if (orientation.type === 'landscape-secondary') {
- orientation.type = 'landscape-primary'
+ try {
+ await this.initialise();
+ await VideoRecorder.startRecording();
+ this.isRecording = true;
+ this.showVideos = false;
+
+ // lock screen orientation when recording
+ const orientation = await ScreenOrientation.orientation();
+
+ if (this.platform.is('ios')) {
+ // On iOS the landscape-primary and landscape-secondary are flipped for some reason
+ if (orientation.type === 'landscape-primary') {
+ orientation.type = 'landscape-secondary'
+ } else if (orientation.type === 'landscape-secondary') {
+ orientation.type = 'landscape-primary'
+ }
}
- }
- await ScreenOrientation.lock({ orientation: orientation.type });
+ await ScreenOrientation.lock({ orientation: orientation.type });
- this.durationIntervalId = setInterval(() => {
- VideoRecorder.getDuration().then((res) => {
- this.duration = this.numberToTimeString(res.value);
- });
- }, 1000);
+ this.durationIntervalId = setInterval(() => {
+ VideoRecorder.getDuration().then((res) => {
+ this.duration = this.numberToTimeString(res.value);
+ });
+ }, 1000);
+ } catch (error) {
+ console.error(error);
+ }
}
flipCamera() {
diff --git a/ios/Plugin/Plugin.swift b/ios/Plugin/Plugin.swift
index 3829354..0e6566e 100644
--- a/ios/Plugin/Plugin.swift
+++ b/ios/Plugin/Plugin.swift
@@ -8,8 +8,8 @@ extension UIColor {
if (cString.hasPrefix("#")) {
cString.remove(at: cString.startIndex)
}
- var rgbValue:UInt32 = 0
- Scanner(string: cString).scanHexInt32(&rgbValue)
+ var rgbValue:UInt64 = 0
+ Scanner(string: cString).scanHexInt64(&rgbValue)
self.init(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
@@ -77,7 +77,9 @@ class CameraView: UIView {
layer.frame = self.bounds
}
}
- self.videoPreviewLayer?.connection?.videoOrientation = interfaceOrientationToVideoOrientation(UIApplication.shared.statusBarOrientation);
+ if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
+ self.videoPreviewLayer?.connection?.videoOrientation = interfaceOrientationToVideoOrientation(windowScene.interfaceOrientation)
+ }
}
func addPreviewLayer(_ previewLayer:AVCaptureVideoPreviewLayer?) {
@@ -152,7 +154,7 @@ public func joinPath(left: String, right: String) -> String {
}
public func randomFileName() -> String {
- return NSUUID().uuidString
+ return UUID().uuidString
}
@objc(VideoRecorder)
@@ -175,6 +177,7 @@ public class VideoRecorder: CAPPlugin, AVCaptureFileOutputRecordingDelegate {
var frontCamera: AVCaptureDevice?
var backCamera: AVCaptureDevice?
var quality: Int = 0
+ var videoBitrate: Int = 4500000
var stopRecordingCall: CAPPluginCall?
@@ -217,6 +220,7 @@ public class VideoRecorder: CAPPlugin, AVCaptureFileOutputRecordingDelegate {
if (self.captureSession?.isRunning != true) {
self.currentCamera = call.getInt("camera", 0)
self.quality = call.getInt("quality", 0)
+ self.videoBitrate = call.getInt("videoBitrate", 4500000)
let autoShow = call.getBool("autoShow", true)
for frameConfig in call.getArray("previewFrames", [ ["id": "default"] ]) {
@@ -228,7 +232,9 @@ public class VideoRecorder: CAPPlugin, AVCaptureFileOutputRecordingDelegate {
DispatchQueue.main.async {
do {
// Set webview to transparent and set the app window background to white
- UIApplication.shared.delegate?.window?!.backgroundColor = UIColor.white
+ if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
+ windowScene.windows.first?.backgroundColor = UIColor.white
+ }
self.capWebView?.isOpaque = false
self.capWebView?.backgroundColor = UIColor.clear
@@ -580,13 +586,27 @@ public class VideoRecorder: CAPPlugin, AVCaptureFileOutputRecordingDelegate {
@objc func startRecording(_ call: CAPPluginCall) {
if (self.captureSession != nil) {
if (!(videoOutput?.isRecording)!) {
- let tempDir = NSURL.fileURL(withPath:NSTemporaryDirectory(),isDirectory:true)
+ let tempDir = NSURL.fileURL(withPath:NSTemporaryDirectory(), isDirectory: true)
var fileName = randomFileName()
fileName.append(".mp4")
- let fileUrl = NSURL.fileURL(withPath: joinPath(left:tempDir.path,right: fileName));
+ let fileUrl = NSURL.fileURL(withPath: joinPath(left: tempDir.path, right: fileName))
+
+ // Configure video output settings
+ let videoSettings: [String: Any] = [
+ AVVideoCodecKey: AVVideoCodecType.h264,
+ AVVideoCompressionPropertiesKey: [
+ AVVideoAverageBitRateKey: self.videoBitrate
+ ]
+ ]
+
+ if let connection = self.videoOutput?.connection(with: .video) {
+ self.videoOutput?.setOutputSettings(videoSettings, for: connection)
+ }
DispatchQueue.main.async {
- self.videoOutput?.connection(with: .video)?.videoOrientation = self.cameraView.interfaceOrientationToVideoOrientation(UIApplication.shared.statusBarOrientation)
+ if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
+ self.videoOutput?.connection(with: .video)?.videoOrientation = self.cameraView.interfaceOrientationToVideoOrientation(windowScene.interfaceOrientation)
+ }
self.videoOutput?.startRecording(to: fileUrl, recordingDelegate: self)
call.resolve()
}
diff --git a/package-lock.json b/package-lock.json
index 63300b8..6c2869b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@capacitor-community/video-recorder",
- "version": "6.0.0",
+ "version": "6.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@capacitor-community/video-recorder",
- "version": "6.0.0",
+ "version": "6.1.0",
"license": "MIT",
"devDependencies": {
"@capacitor/android": "^6.0.0",
diff --git a/package.json b/package.json
index 454df76..e55f319 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@capacitor-community/video-recorder",
- "version": "6.0.0",
+ "version": "6.1.0",
"private": false,
"description": "capacitor plugin to record video",
"main": "dist/plugin.cjs.js",
diff --git a/src/definitions.ts b/src/definitions.ts
index f714d55..bfe0cad 100644
--- a/src/definitions.ts
+++ b/src/definitions.ts
@@ -47,6 +47,13 @@ export interface VideoRecorderOptions {
quality?: VideoRecorderQuality;
autoShow?: boolean;
previewFrames?: VideoRecorderPreviewFrame[];
+ /**
+ * The default bitrate is 4.5Mbps
+ * @default 4500000
+ * @type {number}
+ * @memberof VideoRecorderOptions
+ */
+ videoBitrate?: number;
}
export enum VideoRecorderCamera {