Change videoQuality dynamically, adapt capture size to video AspectRatio, full docs

pull/1/head
Mattia Iavarone 7 years ago
parent 61c7b68e1e
commit 67812ac1dc
  1. 61
      camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java
  2. 36
      camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java
  3. 144
      camerakit/src/main/java/com/flurgle/camerakit/CameraView.java
  4. 29
      demo/src/main/java/com/flurgle/camerakit/demo/MainActivity.java
  5. 2
      demo/src/main/java/com/flurgle/camerakit/demo/VideoPreviewActivity.java
  6. 79
      demo/src/main/res/layout/activity_main.xml

@ -48,13 +48,7 @@ class Camera1 extends CameraImpl {
private int mDeviceOrientation; private int mDeviceOrientation;
private int mSensorOffset; private int mSensorOffset;
@Facing private int mFacing;
@Flash private int mFlash;
@Focus private int mFocus;
@ZoomMode private int mZoom; @ZoomMode private int mZoom;
@VideoQuality private int mVideoQuality;
@WhiteBalance private int mWhiteBalance;
@SessionType private int mSessionType;
private double mLatitude; private double mLatitude;
private double mLongitude; private double mLongitude;
private boolean mFocusOnTap; private boolean mFocusOnTap;
@ -136,8 +130,8 @@ class Camera1 extends CameraImpl {
); );
synchronized (mLock) { synchronized (mLock) {
Camera.Parameters params = mCamera.getParameters(); Camera.Parameters params = mCamera.getParameters();
params.setPreviewSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); params.setPreviewSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); // <- not allowed during preview
params.setPictureSize(mCaptureSize.getWidth(), mCaptureSize.getHeight()); // <- not allowed during preview params.setPictureSize(mCaptureSize.getWidth(), mCaptureSize.getHeight()); // <- allowed
mCamera.setParameters(params); mCamera.setParameters(params);
} }
mCamera.startPreview(); mCamera.startPreview();
@ -358,8 +352,27 @@ class Camera1 extends CameraImpl {
@Override @Override
void setVideoQuality(int videoQuality) { void setVideoQuality(int videoQuality) {
this.mVideoQuality = videoQuality; if (mIsCapturingVideo) {
// TODO: restore preview size if needed. throw new IllegalStateException("Can't change video quality while recording a video.");
}
mVideoQuality = videoQuality;
if (isCameraOpened() && mSessionType == CameraKit.Constants.SESSION_TYPE_VIDEO) {
// Change capture size to a size that fits the video aspect ratio.
Size oldSize = mCaptureSize;
mCaptureSize = computeCaptureSize();
if (!mCaptureSize.equals(oldSize)) {
// New video quality triggers a new aspect ratio.
// Go on and see if preview size should change also.
synchronized (mLock) {
Camera.Parameters params = mCamera.getParameters();
params.setPictureSize(mCaptureSize.getWidth(), mCaptureSize.getHeight());
mCamera.setParameters(params);
}
onSurfaceChanged();
}
Log.e(TAG, "captureSize: "+mCaptureSize);
Log.e(TAG, "previewSize: "+mPreviewSize);
}
} }
@Override @Override
@ -520,16 +533,19 @@ class Camera1 extends CameraImpl {
} else { } else {
// Choose according to developer choice in setVideoQuality. // Choose according to developer choice in setVideoQuality.
// The Camcorder internally checks for cameraParameters.getSupportedVideoSizes() etc. // The Camcorder internally checks for cameraParameters.getSupportedVideoSizes() etc.
// So its output is our output. // We want the picture size to be the max picture consistent with the video aspect ratio.
CamcorderProfile camcorderProfile = getCamcorderProfile(mVideoQuality); List<Size> captureSizes = sizesFromList(params.getSupportedPictureSizes());
return new Size(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight); CamcorderProfile profile = getCamcorderProfile(mVideoQuality);
AspectRatio targetRatio = AspectRatio.of(profile.videoFrameWidth, profile.videoFrameHeight);
return matchSize(captureSizes, targetRatio, new Size(0, 0), true);
} }
} }
private Size computePreviewSize() { private Size computePreviewSize() {
Camera.Parameters params = mCamera.getParameters(); Camera.Parameters params = mCamera.getParameters();
List<Size> previewSizes = sizesFromList(params.getSupportedPreviewSizes()); List<Size> previewSizes = sizesFromList(params.getSupportedPreviewSizes());
return computePreviewSize(previewSizes, mCaptureSize, mPreview.getSurfaceSize()); AspectRatio targetRatio = AspectRatio.of(mCaptureSize.getWidth(), mCaptureSize.getHeight());
return matchSize(previewSizes, targetRatio, mPreview.getSurfaceSize(), false);
} }
@ -761,20 +777,19 @@ class Camera1 extends CameraImpl {
/** /**
* Policy here is to return a size that is big enough to fit the surface size, * Policy here is to return a size that is big enough to fit the surface size,
* and possibly consistent with the capture size. * and possibly consistent with the target aspect ratio.
* @param sizes list of possible sizes * @param sizes list of possible sizes
* @param captureSize size representing desired aspect ratio * @param targetRatio aspect ratio
* @param surfaceSize size representing the current surface size. We'd like the returned value to be bigger. * @param biggerThan size representing the current surface size
* @return chosen size * @return chosen size
*/ */
private static Size computePreviewSize(List<Size> sizes, Size captureSize, Size surfaceSize) { private static Size matchSize(List<Size> sizes, AspectRatio targetRatio, Size biggerThan, boolean biggestPossible) {
if (sizes == null) return null; if (sizes == null) return null;
List<Size> consistent = new ArrayList<>(5); List<Size> consistent = new ArrayList<>(5);
List<Size> bigEnoughAndConsistent = new ArrayList<>(5); List<Size> bigEnoughAndConsistent = new ArrayList<>(5);
final AspectRatio targetRatio = AspectRatio.of(captureSize.getWidth(), captureSize.getHeight()); final Size targetSize = biggerThan;
final Size targetSize = surfaceSize;
for (Size size : sizes) { for (Size size : sizes) {
AspectRatio ratio = AspectRatio.of(size.getWidth(), size.getHeight()); AspectRatio ratio = AspectRatio.of(size.getWidth(), size.getHeight());
if (ratio.equals(targetRatio)) { if (ratio.equals(targetRatio)) {
@ -785,10 +800,16 @@ class Camera1 extends CameraImpl {
} }
} }
if (biggestPossible) {
if (bigEnoughAndConsistent.size() > 0) return Collections.max(bigEnoughAndConsistent);
if (consistent.size() > 0) return Collections.max(consistent);
return Collections.max(sizes);
} else {
if (bigEnoughAndConsistent.size() > 0) return Collections.min(bigEnoughAndConsistent); if (bigEnoughAndConsistent.size() > 0) return Collections.min(bigEnoughAndConsistent);
if (consistent.size() > 0) return Collections.max(consistent); if (consistent.size() > 0) return Collections.max(consistent);
return Collections.max(sizes); return Collections.max(sizes);
} }
}
} }

@ -11,6 +11,13 @@ abstract class CameraImpl implements PreviewImpl.SurfaceCallback {
protected final CameraView.CameraCallbacks mCameraListener; protected final CameraView.CameraCallbacks mCameraListener;
protected final PreviewImpl mPreview; protected final PreviewImpl mPreview;
@Facing protected int mFacing;
@Flash protected int mFlash;
@Focus protected int mFocus;
@VideoQuality protected int mVideoQuality;
@WhiteBalance protected int mWhiteBalance;
@SessionType protected int mSessionType;
CameraImpl(CameraView.CameraCallbacks callback, PreviewImpl preview) { CameraImpl(CameraView.CameraCallbacks callback, PreviewImpl preview) {
mCameraListener = callback; mCameraListener = callback;
mPreview = preview; mPreview = preview;
@ -47,4 +54,33 @@ abstract class CameraImpl implements PreviewImpl.SurfaceCallback {
@Nullable @Nullable
abstract ExtraProperties getExtraProperties(); abstract ExtraProperties getExtraProperties();
@Facing
final int getFacing() {
return mFacing;
}
@Flash
final int getFlash() {
return mFlash;
}
@Focus
final int getFocus() {
return mFocus;
}
@WhiteBalance
final int getWhiteBalance() {
return mWhiteBalance;
}
@VideoQuality
final int getVideoQuality() {
return mVideoQuality;
}
@SessionType
final int getSessionType() {
return mSessionType;
}
} }

@ -83,15 +83,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
getWorkerHandler().post(runnable); getWorkerHandler().post(runnable);
} }
@Facing private int mFacing;
@Flash private int mFlash;
@Focus private int mFocus;
// @Method private int mMethod;
@ZoomMode private int mZoom; @ZoomMode private int mZoom;
// @Permissions private int mPermissions;
@SessionType private int mSessionType;
@VideoQuality private int mVideoQuality;
@WhiteBalance private int mWhiteBalance;
private int mJpegQuality; private int mJpegQuality;
private boolean mCropOutput; private boolean mCropOutput;
private int mDisplayOffset; private int mDisplayOffset;
@ -118,13 +110,13 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
@SuppressWarnings("WrongConstant") @SuppressWarnings("WrongConstant")
private void init(@NonNull Context context, @Nullable AttributeSet attrs) { private void init(@NonNull Context context, @Nullable AttributeSet attrs) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CameraView, 0, 0); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CameraView, 0, 0);
mFacing = a.getInteger(R.styleable.CameraView_cameraFacing, CameraKit.Defaults.DEFAULT_FACING); int facing = a.getInteger(R.styleable.CameraView_cameraFacing, CameraKit.Defaults.DEFAULT_FACING);
mFlash = a.getInteger(R.styleable.CameraView_cameraFlash, CameraKit.Defaults.DEFAULT_FLASH); int flash = a.getInteger(R.styleable.CameraView_cameraFlash, CameraKit.Defaults.DEFAULT_FLASH);
mFocus = a.getInteger(R.styleable.CameraView_cameraFocus, CameraKit.Defaults.DEFAULT_FOCUS); int focus = a.getInteger(R.styleable.CameraView_cameraFocus, CameraKit.Defaults.DEFAULT_FOCUS);
mSessionType = a.getInteger(R.styleable.CameraView_cameraSessionType, CameraKit.Defaults.DEFAULT_SESSION_TYPE); int sessionType = a.getInteger(R.styleable.CameraView_cameraSessionType, CameraKit.Defaults.DEFAULT_SESSION_TYPE);
int whiteBalance = a.getInteger(R.styleable.CameraView_cameraWhiteBalance, CameraKit.Defaults.DEFAULT_WHITE_BALANCE);
int videoQuality = a.getInteger(R.styleable.CameraView_cameraVideoQuality, CameraKit.Defaults.DEFAULT_VIDEO_QUALITY);
mZoom = a.getInteger(R.styleable.CameraView_cameraZoomMode, CameraKit.Defaults.DEFAULT_ZOOM); mZoom = a.getInteger(R.styleable.CameraView_cameraZoomMode, CameraKit.Defaults.DEFAULT_ZOOM);
mWhiteBalance = a.getInteger(R.styleable.CameraView_cameraWhiteBalance, CameraKit.Defaults.DEFAULT_WHITE_BALANCE);
mVideoQuality = a.getInteger(R.styleable.CameraView_cameraVideoQuality, CameraKit.Defaults.DEFAULT_VIDEO_QUALITY);
mJpegQuality = a.getInteger(R.styleable.CameraView_cameraJpegQuality, CameraKit.Defaults.DEFAULT_JPEG_QUALITY); mJpegQuality = a.getInteger(R.styleable.CameraView_cameraJpegQuality, CameraKit.Defaults.DEFAULT_JPEG_QUALITY);
mCropOutput = a.getBoolean(R.styleable.CameraView_cameraCropOutput, CameraKit.Defaults.DEFAULT_CROP_OUTPUT); mCropOutput = a.getBoolean(R.styleable.CameraView_cameraCropOutput, CameraKit.Defaults.DEFAULT_CROP_OUTPUT);
a.recycle(); a.recycle();
@ -136,13 +128,13 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
addView(mFocusMarkerLayout); addView(mFocusMarkerLayout);
mIsStarted = false; mIsStarted = false;
setFacing(mFacing); setFacing(facing);
setFlash(mFlash); setFlash(flash);
setFocus(mFocus); setFocus(focus);
setSessionType(mSessionType); setSessionType(sessionType);
setZoomMode(mZoom); setZoomMode(mZoom);
setVideoQuality(mVideoQuality); setVideoQuality(videoQuality);
setWhiteBalance(mWhiteBalance); setWhiteBalance(whiteBalance);
if (!isInEditMode()) { if (!isInEditMode()) {
mOrientationHelper = new OrientationHelper(context) { mOrientationHelper = new OrientationHelper(context) {
@ -159,19 +151,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mPreviewImpl.onDeviceOrientation(deviceOrientation); mPreviewImpl.onDeviceOrientation(deviceOrientation);
} }
}; };
/* focusMarkerLayout.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent motionEvent) {
int action = motionEvent.getAction();
if (action == MotionEvent.ACTION_UP && mFocus == CameraKit.Constants.FOCUS_TAP_WITH_MARKER) {
focusMarkerLayout.focus(motionEvent.getX(), motionEvent.getY());
}
mPreviewImpl.getView().dispatchTouchEvent(motionEvent);
return true;
}
}); */
} }
mLifecycle = null; mLifecycle = null;
} }
@ -384,13 +363,18 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
destroy(); destroy();
} }
/**
* Starts the camera preview, if not started already.
* This should be called onResume(), or when you are ready with permissions.
*/
public void start() { public void start() {
if (mIsStarted || !isEnabled()) { if (mIsStarted || !isEnabled()) {
// Already started, do nothing. // Already started, do nothing.
return; return;
} }
if (checkPermissions(mSessionType)) { if (checkPermissions(getSessionType())) {
mIsStarted = true; mIsStarted = true;
run(new Runnable() { run(new Runnable() {
@Override @Override
@ -455,6 +439,11 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
} }
} }
/**
* Stops the current preview, if any was started.
* This should be called onPause().
*/
public void stop() { public void stop() {
if (!mIsStarted) { if (!mIsStarted) {
// Already stopped, do nothing. // Already stopped, do nothing.
@ -484,6 +473,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
/** /**
* Set location coordinates to be found later in the jpeg EXIF header * Set location coordinates to be found later in the jpeg EXIF header
*
* @param latitude current latitude * @param latitude current latitude
* @param longitude current longitude * @param longitude current longitude
*/ */
@ -491,22 +481,30 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraImpl.setLocation(latitude, longitude); mCameraImpl.setLocation(latitude, longitude);
} }
/** /**
* Sets desired white balance to current camera session. * Sets desired white balance to current camera session.
*
* @see CameraKit.Constants#WHITE_BALANCE_AUTO
* @see CameraKit.Constants#WHITE_BALANCE_CLOUDY
* @see CameraKit.Constants#WHITE_BALANCE_DAYLIGHT
* @see CameraKit.Constants#WHITE_BALANCE_FLUORESCENT
* @see CameraKit.Constants#WHITE_BALANCE_INCANDESCENT
*
* @param whiteBalance desired white balance behavior. * @param whiteBalance desired white balance behavior.
*/ */
public void setWhiteBalance(@WhiteBalance int whiteBalance) { public void setWhiteBalance(@WhiteBalance int whiteBalance) {
mWhiteBalance = whiteBalance;
mCameraImpl.setWhiteBalance(whiteBalance); mCameraImpl.setWhiteBalance(whiteBalance);
} }
/** /**
* Returns the current white balance behavior. * Returns the current white balance behavior.
* @return white balance value. * @return white balance value.
*/ */
@WhiteBalance @WhiteBalance
public int getWhiteBalance() { public int getWhiteBalance() {
return mWhiteBalance; return mCameraImpl.getWhiteBalance();
} }
@ -519,7 +517,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
* @param facing a facing value. * @param facing a facing value.
*/ */
public void setFacing(@Facing final int facing) { public void setFacing(@Facing final int facing) {
this.mFacing = facing;
run(new Runnable() { run(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -535,7 +532,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
*/ */
@Facing @Facing
public int getFacing() { public int getFacing() {
return mFacing; return mCameraImpl.getFacing();
} }
@ -547,7 +544,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
*/ */
@Facing @Facing
public int toggleFacing() { public int toggleFacing() {
switch (mFacing) { int facing = mCameraImpl.getFacing();
switch (facing) {
case FACING_BACK: case FACING_BACK:
setFacing(FACING_FRONT); setFacing(FACING_FRONT);
break; break;
@ -557,7 +555,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
break; break;
} }
return mFacing; return mCameraImpl.getFacing();
} }
@ -572,7 +570,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
* @param flash desired flash mode. * @param flash desired flash mode.
*/ */
public void setFlash(@Flash int flash) { public void setFlash(@Flash int flash) {
this.mFlash = flash;
mCameraImpl.setFlash(flash); mCameraImpl.setFlash(flash);
} }
@ -583,7 +580,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
*/ */
@Flash @Flash
public int getFlash() { public int getFlash() {
return mFlash; return mCameraImpl.getFlash();
} }
@ -596,7 +593,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
*/ */
@Flash @Flash
public int toggleFlash() { public int toggleFlash() {
switch (mFlash) { int flash = mCameraImpl.getFlash();
switch (flash) {
case FLASH_OFF: case FLASH_OFF:
setFlash(FLASH_ON); setFlash(FLASH_ON);
break; break;
@ -611,7 +609,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
break; break;
} }
return mFlash; return mCameraImpl.getFlash();
} }
@ -626,7 +624,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
* @param focus a Focus value. * @param focus a Focus value.
*/ */
public void setFocus(@Focus int focus) { public void setFocus(@Focus int focus) {
mFocus = focus;
mFocusMarkerLayout.setEnabled(focus == CameraKit.Constants.FOCUS_TAP_WITH_MARKER); mFocusMarkerLayout.setEnabled(focus == CameraKit.Constants.FOCUS_TAP_WITH_MARKER);
if (focus == CameraKit.Constants.FOCUS_TAP_WITH_MARKER) { if (focus == CameraKit.Constants.FOCUS_TAP_WITH_MARKER) {
focus = CameraKit.Constants.FOCUS_TAP; focus = CameraKit.Constants.FOCUS_TAP;
@ -641,7 +638,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
*/ */
@Focus @Focus
public int getFocus() { public int getFocus() {
return mFocus; return mCameraImpl.getFocus();
} }
@ -674,14 +671,12 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
*/ */
public void setSessionType(@SessionType int sessionType) { public void setSessionType(@SessionType int sessionType) {
if (sessionType == mSessionType || !mIsStarted) { if (sessionType == getSessionType() || !mIsStarted) {
// Check did took place, or will happen on start(). // Check did took place, or will happen on start().
mSessionType = sessionType;
mCameraImpl.setSessionType(sessionType); mCameraImpl.setSessionType(sessionType);
} else if (checkPermissions(sessionType)) { } else if (checkPermissions(sessionType)) {
// Camera is running. CameraImpl setSessionType will do the trick. // Camera is running. CameraImpl setSessionType will do the trick.
mSessionType = sessionType;
mCameraImpl.setSessionType(sessionType); mCameraImpl.setSessionType(sessionType);
} else { } else {
@ -700,7 +695,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
*/ */
@SessionType @SessionType
public int getSessionType() { public int getSessionType() {
return mSessionType; return mCameraImpl.getSessionType();
} }
@ -728,27 +723,62 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
} }
/**
* Sets video recording quality. This is not guaranteed to be supported by current device.
* If it's not, a lower quality will be chosen, until a supported one is found.
* If sessionType is video, this might trigger a camera restart and a change in preview size.
*
* @see CameraKit.Constants#VIDEO_QUALITY_LOWEST
* @see CameraKit.Constants#VIDEO_QUALITY_QVGA
* @see CameraKit.Constants#VIDEO_QUALITY_480P
* @see CameraKit.Constants#VIDEO_QUALITY_720P
* @see CameraKit.Constants#VIDEO_QUALITY_1080P
* @see CameraKit.Constants#VIDEO_QUALITY_2160P
* @see CameraKit.Constants#VIDEO_QUALITY_HIGHEST
*
* @param videoQuality requested video quality
*/
public void setVideoQuality(@VideoQuality int videoQuality) { public void setVideoQuality(@VideoQuality int videoQuality) {
this.mVideoQuality = videoQuality; mCameraImpl.setVideoQuality(videoQuality);
mCameraImpl.setVideoQuality(mVideoQuality);
} }
/**
* Gets the current video quality.
* @return the current video quality
*/
@VideoQuality
public int getVideoQuality() {
return mCameraImpl.getVideoQuality();
}
/**
* Sets the JPEG compression quality for image outputs.
* @param jpegQuality a 0-100 integer.
*/
public void setJpegQuality(int jpegQuality) { public void setJpegQuality(int jpegQuality) {
this.mJpegQuality = jpegQuality; if (jpegQuality <= 0 || jpegQuality > 100) {
throw new IllegalArgumentException("JPEG quality should be > 0 and <= 0");
} }
mJpegQuality = jpegQuality;
}
/**
* Whether we should crop the picture output to match CameraView aspect ratio.
* This is only relevant if CameraView dimensions were somehow constrained
* (e.g. by fixed value or MATCH_PARENT) and do not match internal aspect ratio.
*
* Please note that this requires additional computations after the picture is taken.
*
* @param cropOutput whether to crop
*/
public void setCropOutput(boolean cropOutput) { public void setCropOutput(boolean cropOutput) {
this.mCropOutput = cropOutput; this.mCropOutput = cropOutput;
} }
/** /**
* Sets a {@link CameraListener} instance to be notified of all * Sets a {@link CameraListener} instance to be notified of all
* interesting events that will happen during the camera lifecycle. * interesting events that will happen during the camera lifecycle.

@ -40,6 +40,10 @@ public class MainActivity extends AppCompatActivity implements View.OnLayoutChan
@BindView(R.id.cropModeRadioGroup) @BindView(R.id.cropModeRadioGroup)
RadioGroup cropModeRadioGroup; RadioGroup cropModeRadioGroup;
// Video Quality:
@BindView(R.id.videoQualityRadioGroup)
RadioGroup videoQualityRadioGroup;
// Width: // Width:
@BindView(R.id.screenWidth) @BindView(R.id.screenWidth)
TextView screenWidth; TextView screenWidth;
@ -86,6 +90,7 @@ public class MainActivity extends AppCompatActivity implements View.OnLayoutChan
cropModeRadioGroup.setOnCheckedChangeListener(cropModeChangedListener); cropModeRadioGroup.setOnCheckedChangeListener(cropModeChangedListener);
widthModeRadioGroup.setOnCheckedChangeListener(widthModeChangedListener); widthModeRadioGroup.setOnCheckedChangeListener(widthModeChangedListener);
heightModeRadioGroup.setOnCheckedChangeListener(heightModeChangedListener); heightModeRadioGroup.setOnCheckedChangeListener(heightModeChangedListener);
videoQualityRadioGroup.setOnCheckedChangeListener(videoQualityChangedListener);
} }
private void message(String content, boolean important) { private void message(String content, boolean important) {
@ -116,9 +121,8 @@ public class MainActivity extends AppCompatActivity implements View.OnLayoutChan
if (mCapturingPicture) return; if (mCapturingPicture) return;
mCapturingPicture = true; mCapturingPicture = true;
final long startTime = System.currentTimeMillis(); final long startTime = System.currentTimeMillis();
final boolean snapshot = camera.getSessionType() != CameraKit.Constants.SESSION_TYPE_PICTURE; final Size nativeSize = camera.getCaptureSize();
final Size nativeSize = snapshot ? camera.getSnapshotSize() : camera.getCaptureSize(); message("Capturing picture...", false);
message(snapshot ? "Capturing snapshot..." : "Capturing picture...", false);
camera.removeCameraListener(mPictureListener); camera.removeCameraListener(mPictureListener);
mPictureListener = new CameraListener() { mPictureListener = new CameraListener() {
@Override @Override
@ -226,6 +230,25 @@ public class MainActivity extends AppCompatActivity implements View.OnLayoutChan
} }
}; };
RadioGroup.OnCheckedChangeListener videoQualityChangedListener = new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (mCapturingVideo) return;
int videoQuality = CameraKit.Constants.VIDEO_QUALITY_HIGHEST;
switch (checkedId) {
case R.id.videoQualityLowest: videoQuality = CameraKit.Constants.VIDEO_QUALITY_LOWEST; break;
case R.id.videoQualityQvga: videoQuality = CameraKit.Constants.VIDEO_QUALITY_QVGA; break;
case R.id.videoQuality480p: videoQuality = CameraKit.Constants.VIDEO_QUALITY_480P; break;
case R.id.videoQuality720p: videoQuality = CameraKit.Constants.VIDEO_QUALITY_720P; break;
case R.id.videoQuality1080p: videoQuality = CameraKit.Constants.VIDEO_QUALITY_1080P; break;
case R.id.videoQuality2160p: videoQuality = CameraKit.Constants.VIDEO_QUALITY_2160P; break;
case R.id.videoQualityHighest: videoQuality = CameraKit.Constants.VIDEO_QUALITY_HIGHEST; break;
}
camera.setVideoQuality(videoQuality);
message("Video quality changed!", false);
}
};
@OnClick(R.id.widthUpdate) @OnClick(R.id.widthUpdate)
void widthUpdateClicked() { void widthUpdateClicked() {
if (mCapturingPicture) return; if (mCapturingPicture) return;

@ -51,9 +51,9 @@ public class VideoPreviewActivity extends Activity {
float viewWidth = videoView.getWidth(); float viewWidth = videoView.getWidth();
lp.height = (int) (viewWidth * (videoHeight / videoWidth)); lp.height = (int) (viewWidth * (videoHeight / videoWidth));
videoView.setLayoutParams(lp); videoView.setLayoutParams(lp);
playVideo();
} }
}); });
playVideo();
} }

@ -389,6 +389,85 @@
</FrameLayout> </FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<View
android:layout_width="2.5dp"
android:layout_height="match_parent"
android:background="@color/colorPrimary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:text="VIDEO QUALITY"
android:textColor="@android:color/black"
android:textSize="14sp"
android:textStyle="bold" />
<HorizontalScrollView
android:layout_marginTop="4dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioGroup
android:id="@+id/videoQualityRadioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkedButton="@+id/videoQuality480p"
android:orientation="horizontal">
<RadioButton
android:id="@+id/videoQualityLowest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="low" />
<RadioButton
android:id="@+id/videoQualityQvga"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="QVGA" />
<RadioButton
android:id="@+id/videoQuality480p"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="480p" />
<RadioButton
android:id="@+id/videoQuality720p"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="720p" />
<RadioButton
android:id="@+id/videoQuality1080p"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1080p" />
<RadioButton
android:id="@+id/videoQuality2160p"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2160p" />
<RadioButton
android:id="@+id/videoQualityHighest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="high" />
</RadioGroup>
</HorizontalScrollView>
</LinearLayout>
</FrameLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

Loading…
Cancel
Save