Fix conflicts

pull/37/head
Mattia Iavarone 8 years ago
commit 72cd9f8d6d
  1. 19
      README.md
  2. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  3. 5
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java
  4. 25
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java
  5. 5
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java
  6. 7
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java
  7. 83
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  8. 42
      cameraview/src/main/options/com/otaliastudios/cameraview/Audio.java
  9. 5
      cameraview/src/main/res/values/attrs.xml
  10. 1
      demo/src/main/res/layout/activity_main.xml

@ -295,7 +295,8 @@ Most camera parameters can be controlled through XML attributes or linked method
app:cameraJpegQuality="100" app:cameraJpegQuality="100"
app:cameraVideoQuality="480p" app:cameraVideoQuality="480p"
app:cameraWhiteBalance="auto" app:cameraWhiteBalance="auto"
app:cameraHdr="off" /> app:cameraHdr="off"
app:cameraAudio="on"/>
``` ```
|XML Attribute|Method|Values|Default Value| |XML Attribute|Method|Values|Default Value|
@ -309,6 +310,7 @@ Most camera parameters can be controlled through XML attributes or linked method
|[`cameraVideoQuality`](#cameravideoquality)|`setVideoQuality()`|`lowest` `highest` `maxQvga` `max480p` `max720p` `max1080p` `max2160p`|`max480p`| |[`cameraVideoQuality`](#cameravideoquality)|`setVideoQuality()`|`lowest` `highest` `maxQvga` `max480p` `max720p` `max1080p` `max2160p`|`max480p`|
|[`cameraWhiteBalance`](#camerawhitebalance)|`setWhiteBalance()`|`auto` `incandescent` `fluorescent` `daylight` `cloudy`|`auto`| |[`cameraWhiteBalance`](#camerawhitebalance)|`setWhiteBalance()`|`auto` `incandescent` `fluorescent` `daylight` `cloudy`|`auto`|
|[`cameraHdr`](#camerahdr)|`setHdr()`|`off` `on`|`off`| |[`cameraHdr`](#camerahdr)|`setHdr()`|`off` `on`|`off`|
|[`cameraAudio`](#cameraaudio)|`setAudio()`|`off` `on`|`on`|
#### cameraSessionType #### cameraSessionType
@ -404,6 +406,15 @@ cameraView.setHdr(Hdr.OFF);
cameraView.setHdr(Hdr.ON); cameraView.setHdr(Hdr.ON);
``` ```
#### cameraAudio
Turns on or off audio stream.
```java
cameraView.setAudio(Audio.OFF);
cameraView.setAudio(Audio.ON);
```
## Other APIs ## Other APIs
Other APIs not mentioned above are provided, and are well documented and commented in code. Other APIs not mentioned above are provided, and are well documented and commented in code.
@ -435,15 +446,15 @@ Take also a look at public methods in `CameraUtils`, `CameraOptions`, `ExtraProp
`CameraView` needs two permissions: `CameraView` needs two permissions:
- `android.permission.CAMERA` : required for capturing pictures and videos - `android.permission.CAMERA` : required for capturing pictures and videos
- `android.permission.RECORD_AUDIO` : required for capturing videos - `android.permission.RECORD_AUDIO` : required for capturing videos with `Audio.ON` (the default)
You can handle permissions yourself and then call `CameraView.start()` once they are acquired. If they are not, `CameraView` will request permissions to the user based on the `sessionType` that was set. In that case, you can restart the camera if you have a successful response from `onRequestPermissionResults()`. You can handle permissions yourself and then call `CameraView.start()` once they are acquired. If they are not, `CameraView` will request permissions to the user based on whether they are needed. In that case, you can restart the camera if you have a successful response from `onRequestPermissionResults()`.
## Manifest file ## Manifest file
The library manifest file is not strict and only asks for camera permissions. This means that: The library manifest file is not strict and only asks for camera permissions. This means that:
- If you wish to record videos, you should also add `android.permission.RECORD_AUDIO` to required permissions - If you wish to record videos with `Audio.ON` (the default), you should also add `android.permission.RECORD_AUDIO` to required permissions
```xml ```xml
<uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/>

@ -49,7 +49,7 @@ public class CameraViewTest extends BaseTest {
} }
@Override @Override
protected boolean checkPermissions(SessionType sessionType) { protected boolean checkPermissions(SessionType sessionType, Audio audio) {
return hasPermissions; return hasPermissions;
} }
}; };

@ -81,6 +81,11 @@ public class MockCameraController extends CameraController {
mHdr = hdr; mHdr = hdr;
} }
@Override
void setAudio(Audio audio) {
mAudio = audio;
}
@Override @Override
void setLocation(Location location) { void setLocation(Location location) {
mLocation = location; mLocation = location;

@ -308,6 +308,17 @@ class Camera1 extends CameraController {
return false; return false;
} }
@Override
void setAudio(Audio audio) {
if (mAudio != audio) {
if (mIsCapturingVideo) {
LOG.w("Changing audio mode while recording. Changes will take place starting from next video");
}
mAudio = audio;
}
}
@Override @Override
void setFlash(Flash flash) { void setFlash(Flash flash) {
Flash old = mFlash; Flash old = mFlash;
@ -617,13 +628,25 @@ class Camera1 extends CameraController {
mMediaRecorder.setCamera(mCamera); mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
CamcorderProfile profile = getCamcorderProfile(mVideoQuality);
if (mAudio == Audio.ON) {
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setProfile(profile);
} else {
// Set all values contained in profile except audio settings
mMediaRecorder.setOutputFormat(profile.fileFormat);
mMediaRecorder.setVideoEncoder(profile.videoCodec);
mMediaRecorder.setVideoEncodingBitRate(profile.videoBitRate);
mMediaRecorder.setVideoFrameRate(profile.videoFrameRate);
mMediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
}
if (mLocation != null) { if (mLocation != null) {
mMediaRecorder.setLocation((float) mLocation.getLatitude(), mMediaRecorder.setLocation((float) mLocation.getLatitude(),
(float) mLocation.getLongitude()); (float) mLocation.getLongitude());
} }
mMediaRecorder.setProfile(getCamcorderProfile(mVideoQuality));
mMediaRecorder.setOutputFile(mVideoFile.getAbsolutePath()); mMediaRecorder.setOutputFile(mVideoFile.getAbsolutePath());
mMediaRecorder.setOrientationHint(computeExifRotation()); mMediaRecorder.setOrientationHint(computeExifRotation());
// Not needed. mMediaRecorder.setPreviewDisplay(mPreview.getSurface()); // Not needed. mMediaRecorder.setPreviewDisplay(mPreview.getSurface());

@ -81,6 +81,11 @@ class Camera2 extends CameraController {
} }
@Override
void setAudio(Audio audio) {
}
@Override @Override
void setLocation(Location location) { void setLocation(Location location) {

@ -29,6 +29,7 @@ abstract class CameraController implements Preview.SurfaceCallback {
protected SessionType mSessionType; protected SessionType mSessionType;
protected Hdr mHdr; protected Hdr mHdr;
protected Location mLocation; protected Location mLocation;
protected Audio mAudio;
protected Size mCaptureSize; protected Size mCaptureSize;
protected Size mPreviewSize; protected Size mPreviewSize;
@ -204,6 +205,8 @@ abstract class CameraController implements Preview.SurfaceCallback {
// If closed, keep. If opened, check supported and apply. // If closed, keep. If opened, check supported and apply.
abstract void setLocation(Location location); abstract void setLocation(Location location);
abstract void setAudio(Audio audio);
// Throw if capturing. If in video session, recompute capture size, and, if needed, preview size. // Throw if capturing. If in video session, recompute capture size, and, if needed, preview size.
abstract void setVideoQuality(VideoQuality videoQuality); abstract void setVideoQuality(VideoQuality videoQuality);
@ -266,6 +269,10 @@ abstract class CameraController implements Preview.SurfaceCallback {
return mLocation; return mLocation;
} }
final Audio getAudio() {
return mAudio;
}
final Size getCaptureSize() { final Size getCaptureSize() {
return mCaptureSize; return mCaptureSize;
} }

@ -100,6 +100,7 @@ public class CameraView extends FrameLayout {
VideoQuality videoQuality = VideoQuality.fromValue(a.getInteger(R.styleable.CameraView_cameraVideoQuality, VideoQuality.DEFAULT.value())); VideoQuality videoQuality = VideoQuality.fromValue(a.getInteger(R.styleable.CameraView_cameraVideoQuality, VideoQuality.DEFAULT.value()));
SessionType sessionType = SessionType.fromValue(a.getInteger(R.styleable.CameraView_cameraSessionType, SessionType.DEFAULT.value())); SessionType sessionType = SessionType.fromValue(a.getInteger(R.styleable.CameraView_cameraSessionType, SessionType.DEFAULT.value()));
Hdr hdr = Hdr.fromValue(a.getInteger(R.styleable.CameraView_cameraHdr, Hdr.DEFAULT.value())); Hdr hdr = Hdr.fromValue(a.getInteger(R.styleable.CameraView_cameraHdr, Hdr.DEFAULT.value()));
Audio audio = Audio.fromValue(a.getInteger(R.styleable.CameraView_cameraAudio, Audio.DEFAULT.value()));
// Gestures // Gestures
GestureAction tapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureTap, GestureAction.DEFAULT_TAP.value())); GestureAction tapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureTap, GestureAction.DEFAULT_TAP.value()));
@ -138,6 +139,7 @@ public class CameraView extends FrameLayout {
setWhiteBalance(whiteBalance); setWhiteBalance(whiteBalance);
setGrid(grid); setGrid(grid);
setHdr(hdr); setHdr(hdr);
setAudio(audio);
// Apply gestures // Apply gestures
mapGesture(Gesture.TAP, tapGesture); mapGesture(Gesture.TAP, tapGesture);
@ -488,7 +490,7 @@ public class CameraView extends FrameLayout {
public void start() { public void start() {
if (!isEnabled()) return; if (!isEnabled()) return;
if (checkPermissions(getSessionType())) { if (checkPermissions(getSessionType(), getAudio())) {
// Update display orientation for current CameraController // Update display orientation for current CameraController
mOrientationHelper.enable(getContext()); mOrientationHelper.enable(getContext());
mCameraController.start(); mCameraController.start();
@ -502,32 +504,22 @@ public class CameraView extends FrameLayout {
* @return true if we can go on, false otherwise. * @return true if we can go on, false otherwise.
*/ */
@SuppressLint("NewApi") @SuppressLint("NewApi")
protected boolean checkPermissions(SessionType sessionType) { protected boolean checkPermissions(SessionType sessionType, Audio audio) {
checkPermissionsManifestOrThrow(sessionType); checkPermissionsManifestOrThrow(sessionType, audio);
boolean api23 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; // Manifest is OK at this point. Let's check runtime permissions.
int cameraCheck, audioCheck; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return true;
if (!api23) {
cameraCheck = PackageManager.PERMISSION_GRANTED; Context c = getContext();
audioCheck = PackageManager.PERMISSION_GRANTED; boolean needsCamera = true;
} else { boolean needsAudio = sessionType == SessionType.VIDEO && audio == Audio.ON;
cameraCheck = getContext().checkSelfPermission(Manifest.permission.CAMERA);
audioCheck = getContext().checkSelfPermission(Manifest.permission.RECORD_AUDIO);
}
switch (sessionType) {
case VIDEO:
if (cameraCheck != PackageManager.PERMISSION_GRANTED || audioCheck != PackageManager.PERMISSION_GRANTED) {
requestPermissions(true, true);
return false;
}
break;
case PICTURE: needsCamera = needsCamera && c.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED;
if (cameraCheck != PackageManager.PERMISSION_GRANTED) { needsAudio = needsAudio && c.checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED;
requestPermissions(true, false);
if (needsCamera || needsAudio) {
requestPermissions(needsCamera, needsAudio);
return false; return false;
} }
break;
}
return true; return true;
} }
@ -537,8 +529,8 @@ public class CameraView extends FrameLayout {
* If the developer did not add this to its manifest, throw and fire warnings. * If the developer did not add this to its manifest, throw and fire warnings.
* (Hoping this is not caught elsewhere... we should test). * (Hoping this is not caught elsewhere... we should test).
*/ */
private void checkPermissionsManifestOrThrow(SessionType sessionType) { private void checkPermissionsManifestOrThrow(SessionType sessionType, Audio audio) {
if (sessionType == SessionType.VIDEO) { if (sessionType == SessionType.VIDEO && audio == Audio.ON) {
try { try {
PackageManager manager = getContext().getPackageManager(); PackageManager manager = getContext().getPackageManager();
PackageInfo info = manager.getPackageInfo(getContext().getPackageName(), PackageManager.GET_PERMISSIONS); PackageInfo info = manager.getPackageInfo(getContext().getPackageName(), PackageManager.GET_PERMISSIONS);
@ -866,6 +858,43 @@ public class CameraView extends FrameLayout {
} }
/**
* Controls the audio mode.
*
* @see Audio#OFF
* @see Audio#ON
*
* @param audio desired audio value
*/
public void setAudio(Audio audio) {
if (audio == getAudio() || isStopped()) {
// Check did took place, or will happen on start().
mCameraController.setAudio(audio);
} else if (checkPermissions(getSessionType(), audio)) {
// Camera is running. Pass.
mCameraController.setAudio(audio);
} else {
// This means that the audio permission is being asked.
// Stop the camera so it can be restarted by the developer onPermissionResult.
// Developer must also set the audio value again...
// Not ideal but good for now.
stop();
}
}
/**
* Gets the current audio value.
* @return the current audio value
*/
public Audio getAudio() {
return mCameraController.getAudio();
}
/** /**
* Starts an autofocus process at the given coordinates, with respect * Starts an autofocus process at the given coordinates, with respect
* to the view width and height. * to the view width and height.
@ -897,7 +926,7 @@ public class CameraView extends FrameLayout {
// Check did took place, or will happen on start(). // Check did took place, or will happen on start().
mCameraController.setSessionType(sessionType); mCameraController.setSessionType(sessionType);
} else if (checkPermissions(sessionType)) { } else if (checkPermissions(sessionType, getAudio())) {
// Camera is running. CameraImpl setSessionType will do the trick. // Camera is running. CameraImpl setSessionType will do the trick.
mCameraController.setSessionType(sessionType); mCameraController.setSessionType(sessionType);

@ -0,0 +1,42 @@
package com.otaliastudios.cameraview;
/**
* Audio values indicate whether to record audio stream when record video.
*
* @see CameraView#setAudio(Audio)
*/
public enum Audio {
/**
* No Audio.
*/
OFF(0),
/**
* With Audio.
*/
ON(1);
final static Audio DEFAULT = ON;
private int value;
Audio(int value) {
this.value = value;
}
int value() {
return value;
}
static Audio fromValue(int value) {
Audio[] list = Audio.values();
for (Audio action : list) {
if (action.value() == value) {
return action;
}
}
return null;
}
}

@ -91,6 +91,11 @@
<attr name="cameraCropOutput" format="boolean" /> <attr name="cameraCropOutput" format="boolean" />
<attr name="cameraAudio" format="enum">
<enum name="off" value="0" />
<enum name="on" value="1" />
</attr>
<!-- deprecated attr name="cameraZoomMode" format="enum"> <!-- deprecated attr name="cameraZoomMode" format="enum">
<enum name="off" value="0" /> <enum name="off" value="0" />
<enum name="pinch" value="1" /> <enum name="pinch" value="1" />

@ -30,6 +30,7 @@
app:cameraCropOutput="false" app:cameraCropOutput="false"
app:cameraFacing="back" app:cameraFacing="back"
app:cameraFlash="off" app:cameraFlash="off"
app:cameraAudio="on"
app:cameraGestureTap="focusWithMarker" app:cameraGestureTap="focusWithMarker"
app:cameraGestureLongTap="none" app:cameraGestureLongTap="none"
app:cameraGesturePinch="zoom" app:cameraGesturePinch="zoom"

Loading…
Cancel
Save