Files
react-native-camera/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java
T
Marc Johnson e326d51a53 Android support for recording video (#262)
* Initial commit with Android video support

* stopCapture now works

* Bug fixes and parameter enhancements.  README updated.

* Modified stopCapture parameter count to match iOS

* fixed promise bug on stopCapture

* Update RCTCameraModule.java

In Android preview and recording sizes are different, which can cause an error.  This fix detects the difference and chooses a recording resolution that matches.

* Update RCTCameraModule.java

* Update RCTCamera.java

Creating video functions in style/convention of existing

* Update RCTCameraModule.java

Use new functions for adjusting video capture size and quality

* Update RCTCameraModule.java

Fixes issue where file not video playable (readable) on older devices

* Update AndroidManifest.xml

Since we're reading and writing video and pictures, need permissions for it.

* Fixed upside down camera (on some platforms), and misc bugs and crashes

* Added camera-roll and capture to memory support, new options, and support for duration, filesize, and metadata

* To make merge nicer, temporarily reverting "Added camera-roll and capture to memory support, new options, and support for duration, filesize, and metadata"

This reverts commit 9ea1ad409c7e6121cf0197172e752b7523d4b092.

* Fixed merge & brought back all improvements from 9ea1ad4

* Fixed logic for video -> camera roll

* Updates

* Uncommenting setProfile

* Fix support for React Native 0.25

* Renamed Camera to index

* * Fix after merge android recording

* * Fixed android camera roll file saving
* Added recording to example

* * Android promise rejections with exceptions
* Fixed preview, video and photo sizes
* Android recording result in new, javascript object, format

* * Removed example.index.android.js as there is Example project

* * Readme for example

* don't force a specific codec

* always use cache dir

* * Using MediaScannerConnection instead of ACTION_MEDIA_SCANNER_SCAN_FILE intent

* * As described in https://github.com/lwansbrough/react-native-camera/pull/262#issuecomment-239622268:
- fixed video the wrong direction and recoder start fail at "low,medium" on the nexus 5 x
2016-08-27 21:49:46 -04:00

165 lines
5.7 KiB
Java

/**
* Created by Fabrice Armisen (farmisen@gmail.com) on 1/3/16.
*/
package com.lwansbrough.RCTCamera;
import android.content.Context;
import android.hardware.SensorManager;
import android.view.OrientationEventListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.View;
public class RCTCameraView extends ViewGroup {
private final OrientationEventListener _orientationListener;
private final Context _context;
private RCTCameraViewFinder _viewFinder = null;
private int _actualDeviceOrientation = -1;
private int _aspect = RCTCameraModule.RCT_CAMERA_ASPECT_FIT;
private String _captureQuality = "high";
private int _torchMode = -1;
private int _flashMode = -1;
public RCTCameraView(Context context) {
super(context);
this._context = context;
setActualDeviceOrientation(context);
_orientationListener = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_NORMAL) {
@Override
public void onOrientationChanged(int orientation) {
if (setActualDeviceOrientation(_context)) {
layoutViewFinder();
}
}
};
if (_orientationListener.canDetectOrientation()) {
_orientationListener.enable();
} else {
_orientationListener.disable();
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
layoutViewFinder(left, top, right, bottom);
}
@Override
public void onViewAdded(View child) {
if (this._viewFinder == child) return;
// remove and readd view to make sure it is in the back.
// @TODO figure out why there was a z order issue in the first place and fix accordingly.
this.removeView(this._viewFinder);
this.addView(this._viewFinder, 0);
}
public void setAspect(int aspect) {
this._aspect = aspect;
layoutViewFinder();
}
public void setCameraType(final int type) {
if (null != this._viewFinder) {
this._viewFinder.setCameraType(type);
RCTCamera.getInstance().adjustPreviewLayout(type);
} else {
_viewFinder = new RCTCameraViewFinder(_context, type);
if (-1 != this._flashMode) {
_viewFinder.setFlashMode(this._flashMode);
}
if (-1 != this._torchMode) {
_viewFinder.setFlashMode(this._torchMode);
}
addView(_viewFinder);
}
}
public void setCaptureQuality(String captureQuality) {
this._captureQuality = captureQuality;
if (this._viewFinder != null) {
this._viewFinder.setCaptureQuality(captureQuality);
}
}
public void setTorchMode(int torchMode) {
this._torchMode = torchMode;
if (this._viewFinder != null) {
this._viewFinder.setTorchMode(torchMode);
}
}
public void setFlashMode(int flashMode) {
this._flashMode = flashMode;
if (this._viewFinder != null) {
this._viewFinder.setFlashMode(flashMode);
}
}
public void setOrientation(int orientation) {
RCTCamera.getInstance().setOrientation(orientation);
if (this._viewFinder != null) {
layoutViewFinder();
}
}
private boolean setActualDeviceOrientation(Context context) {
int actualDeviceOrientation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();
if (_actualDeviceOrientation != actualDeviceOrientation) {
_actualDeviceOrientation = actualDeviceOrientation;
RCTCamera.getInstance().setActualDeviceOrientation(_actualDeviceOrientation);
return true;
} else {
return false;
}
}
private void layoutViewFinder() {
layoutViewFinder(this.getLeft(), this.getTop(), this.getRight(), this.getBottom());
}
private void layoutViewFinder(int left, int top, int right, int bottom) {
if (null == _viewFinder) {
return;
}
float width = right - left;
float height = bottom - top;
int viewfinderWidth;
int viewfinderHeight;
double ratio;
switch (this._aspect) {
case RCTCameraModule.RCT_CAMERA_ASPECT_FIT:
ratio = this._viewFinder.getRatio();
if (ratio * height > width) {
viewfinderHeight = (int) (width / ratio);
viewfinderWidth = (int) width;
} else {
viewfinderWidth = (int) (ratio * height);
viewfinderHeight = (int) height;
}
break;
case RCTCameraModule.RCT_CAMERA_ASPECT_FILL:
ratio = this._viewFinder.getRatio();
if (ratio * height < width) {
viewfinderHeight = (int) (width / ratio);
viewfinderWidth = (int) width;
} else {
viewfinderWidth = (int) (ratio * height);
viewfinderHeight = (int) height;
}
break;
default:
viewfinderWidth = (int) width;
viewfinderHeight = (int) height;
}
int viewFinderPaddingX = (int) ((width - viewfinderWidth) / 2);
int viewFinderPaddingY = (int) ((height - viewfinderHeight) / 2);
this._viewFinder.layout(viewFinderPaddingX, viewFinderPaddingY, viewFinderPaddingX + viewfinderWidth, viewFinderPaddingY + viewfinderHeight);
this.postInvalidate(this.getLeft(), this.getTop(), this.getRight(), this.getBottom());
}
}