Add VideoCodec option (#174)

* Add VideoCodec options

* Fix tests
pull/175/head
Mattia Iavarone 7 years ago committed by GitHub
parent 0494477c3b
commit e9cba8c6ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      README.md
  2. 9
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  3. 36
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MapperTest.java
  4. 2
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java
  5. 9
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java
  6. 28
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  7. 11
      cameraview/src/main/java/com/otaliastudios/cameraview/Mapper.java
  8. 49
      cameraview/src/main/options/com/otaliastudios/cameraview/VideoCodec.java
  9. 6
      cameraview/src/main/res/values/attrs.xml

@ -399,6 +399,7 @@ Most camera parameters can be controlled through XML attributes or linked method
app:cameraCropOutput="false" app:cameraCropOutput="false"
app:cameraJpegQuality="100" app:cameraJpegQuality="100"
app:cameraVideoQuality="480p" app:cameraVideoQuality="480p"
app:cameraVideoCodec="deviceDefault"
app:cameraWhiteBalance="auto" app:cameraWhiteBalance="auto"
app:cameraHdr="off" app:cameraHdr="off"
app:cameraAudio="on" app:cameraAudio="on"
@ -416,6 +417,7 @@ Most camera parameters can be controlled through XML attributes or linked method
|[`cameraCropOutput`](#cameracropoutput)|`setCropOutput()`|`true` `false`|`false`| |[`cameraCropOutput`](#cameracropoutput)|`setCropOutput()`|`true` `false`|`false`|
|[`cameraJpegQuality`](#camerajpegquality)|`setJpegQuality()`|`0 < n <= 100`|`100`| |[`cameraJpegQuality`](#camerajpegquality)|`setJpegQuality()`|`0 < n <= 100`|`100`|
|[`cameraVideoQuality`](#cameravideoquality)|`setVideoQuality()`|`lowest` `highest` `maxQvga` `max480p` `max720p` `max1080p` `max2160p`|`max480p`| |[`cameraVideoQuality`](#cameravideoquality)|`setVideoQuality()`|`lowest` `highest` `maxQvga` `max480p` `max720p` `max1080p` `max2160p`|`max480p`|
|[`cameraVideoCodec`](#cameravideocodec)|`setVideoCodec()`|`deviceDefault` `h263` `h264`|`deviceDefault`|
|[`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`| |[`cameraAudio`](#cameraaudio)|`setAudio()`|`off` `on`|`on`|
@ -504,6 +506,16 @@ cameraView.setVideoQuality(VideoQuality.MAX_1080P);
cameraView.setVideoQuality(VideoQuality.MAX_2160P); cameraView.setVideoQuality(VideoQuality.MAX_2160P);
``` ```
#### cameraVideoCodec
Sets the encoder for video recordings.
```java
cameraView.setVideoCodec(VideoCodec.DEVICE_DEFAULT);
cameraView.setVideoCodec(VideoCodec.H_263);
cameraView.setVideoCodec(VideoCodec.H_264);
```
#### cameraWhiteBalance #### cameraWhiteBalance
Sets the desired white balance for the current session. Sets the desired white balance for the current session.

@ -93,6 +93,7 @@ public class CameraViewTest extends BaseTest {
assertEquals(cameraView.getHdr(), Hdr.DEFAULT); assertEquals(cameraView.getHdr(), Hdr.DEFAULT);
assertEquals(cameraView.getAudio(), Audio.DEFAULT); assertEquals(cameraView.getAudio(), Audio.DEFAULT);
assertEquals(cameraView.getVideoQuality(), VideoQuality.DEFAULT); assertEquals(cameraView.getVideoQuality(), VideoQuality.DEFAULT);
assertEquals(cameraView.getVideoCodec(), VideoCodec.DEFAULT);
assertEquals(cameraView.getLocation(), null); assertEquals(cameraView.getLocation(), null);
assertEquals(cameraView.getExposureCorrection(), 0f, 0f); assertEquals(cameraView.getExposureCorrection(), 0f, 0f);
assertEquals(cameraView.getZoom(), 0f, 0f); assertEquals(cameraView.getZoom(), 0f, 0f);
@ -560,6 +561,14 @@ public class CameraViewTest extends BaseTest {
assertEquals(cameraView.getVideoQuality(), VideoQuality.LOWEST); assertEquals(cameraView.getVideoQuality(), VideoQuality.LOWEST);
} }
@Test
public void testVideoCodec() {
cameraView.set(VideoCodec.H_263);
assertEquals(cameraView.getVideoCodec(), VideoCodec.H_263);
cameraView.set(VideoCodec.H_264);
assertEquals(cameraView.getVideoCodec(), VideoCodec.H_264);
}
@Test @Test
public void testPictureSizeSelector() { public void testPictureSizeSelector() {
SizeSelector source = SizeSelectors.minHeight(50); SizeSelector source = SizeSelectors.minHeight(50);

@ -0,0 +1,36 @@
package com.otaliastudios.cameraview;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class MapperTest extends BaseTest {
private Mapper mapper = new Mapper() {
<T> T map(Flash flash) { return null; }
<T> T map(Facing facing) { return null; }
<T> T map(WhiteBalance whiteBalance) { return null; }
<T> T map(Hdr hdr) { return null; }
<T> Flash unmapFlash(T cameraConstant) { return null; }
<T> Facing unmapFacing(T cameraConstant) { return null; }
<T> WhiteBalance unmapWhiteBalance(T cameraConstant) { return null; }
<T> Hdr unmapHdr(T cameraConstant) { return null; }
};
@Test
public void testMap() {
assertEquals(mapper.map(VideoCodec.DEVICE_DEFAULT), MediaRecorder.VideoEncoder.DEFAULT);
assertEquals(mapper.map(VideoCodec.H_263), MediaRecorder.VideoEncoder.H263);
assertEquals(mapper.map(VideoCodec.H_264), MediaRecorder.VideoEncoder.H264);
}
}

@ -688,7 +688,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
mMediaRecorder.setOutputFormat(profile.fileFormat); mMediaRecorder.setOutputFormat(profile.fileFormat);
mMediaRecorder.setVideoFrameRate(profile.videoFrameRate); mMediaRecorder.setVideoFrameRate(profile.videoFrameRate);
mMediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight); mMediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
mMediaRecorder.setVideoEncoder(profile.videoCodec); mMediaRecorder.setVideoEncoder(mMapper.map(mVideoCodec));
mMediaRecorder.setVideoEncodingBitRate(profile.videoBitRate); mMediaRecorder.setVideoEncodingBitRate(profile.videoBitRate);
if (mAudio == Audio.ON) { if (mAudio == Audio.ON) {
mMediaRecorder.setAudioChannels(profile.audioChannels); mMediaRecorder.setAudioChannels(profile.audioChannels);

@ -39,6 +39,7 @@ abstract class CameraController implements
protected Flash mFlash; protected Flash mFlash;
protected WhiteBalance mWhiteBalance; protected WhiteBalance mWhiteBalance;
protected VideoQuality mVideoQuality; protected VideoQuality mVideoQuality;
protected VideoCodec mVideoCodec;
protected SessionType mSessionType; protected SessionType mSessionType;
protected Hdr mHdr; protected Hdr mHdr;
protected Location mLocation; protected Location mLocation;
@ -285,6 +286,10 @@ abstract class CameraController implements
mVideoMaxDuration = videoMaxDurationMillis; mVideoMaxDuration = videoMaxDurationMillis;
} }
final void setVideoCodec(VideoCodec codec) {
mVideoCodec = codec;
}
//endregion //endregion
@ -362,6 +367,10 @@ abstract class CameraController implements
return mVideoQuality; return mVideoQuality;
} }
final VideoCodec getVideoCodec() {
return mVideoCodec;
}
final long getVideoMaxSize() { final long getVideoMaxSize() {
return mVideoMaxSize; return mVideoMaxSize;
} }

@ -107,6 +107,7 @@ public class CameraView extends FrameLayout {
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())); Audio audio = Audio.fromValue(a.getInteger(R.styleable.CameraView_cameraAudio, Audio.DEFAULT.value()));
VideoCodec codec = VideoCodec.fromValue(a.getInteger(R.styleable.CameraView_cameraVideoCodec, VideoCodec.DEFAULT.value()));
long videoMaxSize = (long) a.getFloat(R.styleable.CameraView_cameraVideoMaxSize, 0); long videoMaxSize = (long) a.getFloat(R.styleable.CameraView_cameraVideoMaxSize, 0);
int videoMaxDuration = a.getInteger(R.styleable.CameraView_cameraVideoMaxDuration, 0); int videoMaxDuration = a.getInteger(R.styleable.CameraView_cameraVideoMaxDuration, 0);
@ -181,6 +182,7 @@ public class CameraView extends FrameLayout {
setHdr(hdr); setHdr(hdr);
setAudio(audio); setAudio(audio);
setPictureSize(selector); setPictureSize(selector);
setVideoCodec(codec);
setVideoMaxSize(videoMaxSize); setVideoMaxSize(videoMaxSize);
setVideoMaxDuration(videoMaxDuration); setVideoMaxDuration(videoMaxDuration);
@ -652,6 +654,8 @@ public class CameraView extends FrameLayout {
setVideoQuality((VideoQuality) control); setVideoQuality((VideoQuality) control);
} else if (control instanceof WhiteBalance) { } else if (control instanceof WhiteBalance) {
setWhiteBalance((WhiteBalance) control); setWhiteBalance((WhiteBalance) control);
} else if (control instanceof VideoCodec) {
setVideoCodec((VideoCodec) control);
} }
} }
@ -1375,6 +1379,30 @@ public class CameraView extends FrameLayout {
} }
/**
* Sets the encoder for video recordings.
* Defaults to {@link VideoCodec#DEVICE_DEFAULT}.
*
* @see VideoCodec#DEVICE_DEFAULT
* @see VideoCodec#H_263
* @see VideoCodec#H_264
*
* @param codec requested video codec
*/
public void setVideoCodec(VideoCodec codec) {
mCameraController.setVideoCodec(codec);
}
/**
* Gets the current encoder for video recordings.
* @return the current video codec
*/
public VideoCodec getVideoCodec() {
return mCameraController.getVideoCodec();
}
/** /**
* Sets the maximum size in bytes for recorded video files. * Sets the maximum size in bytes for recorded video files.
* Once this size is reached, the recording will automatically stop. * Once this size is reached, the recording will automatically stop.

@ -1,6 +1,7 @@
package com.otaliastudios.cameraview; package com.otaliastudios.cameraview;
import android.hardware.Camera; import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Build; import android.os.Build;
import java.util.HashMap; import java.util.HashMap;
@ -16,6 +17,16 @@ abstract class Mapper {
abstract <T> WhiteBalance unmapWhiteBalance(T cameraConstant); abstract <T> WhiteBalance unmapWhiteBalance(T cameraConstant);
abstract <T> Hdr unmapHdr(T cameraConstant); abstract <T> Hdr unmapHdr(T cameraConstant);
int map(VideoCodec codec) {
switch (codec) {
case DEVICE_DEFAULT: return MediaRecorder.VideoEncoder.DEFAULT;
case H_263: return MediaRecorder.VideoEncoder.H263;
case H_264: return MediaRecorder.VideoEncoder.H264;
default: return MediaRecorder.VideoEncoder.DEFAULT;
}
}
static class Mapper1 extends Mapper { static class Mapper1 extends Mapper {
private static final HashMap<Flash, String> FLASH = new HashMap<>(); private static final HashMap<Flash, String> FLASH = new HashMap<>();

@ -0,0 +1,49 @@
package com.otaliastudios.cameraview;
/**
* Constants for selecting the encoder of video recordings.
* https://developer.android.com/guide/topics/media/media-formats.html#video-formats
*
* @see CameraView#setVideoCodec(VideoCodec)
*/
public enum VideoCodec implements Control {
/**
* Let the device choose its codec.
*/
DEVICE_DEFAULT(0),
/**
* The H.263 codec.
*/
H_263(1),
/**
* The H.264 codec.
*/
H_264(2);
static final VideoCodec DEFAULT = DEVICE_DEFAULT;
private int value;
VideoCodec(int value) {
this.value = value;
}
int value() {
return value;
}
static VideoCodec fromValue(int value) {
VideoCodec[] list = VideoCodec.values();
for (VideoCodec action : list) {
if (action.value() == value) {
return action;
}
}
return null;
}
}

@ -114,6 +114,12 @@
<attr name="cameraVideoMaxDuration" format="integer" /> <attr name="cameraVideoMaxDuration" format="integer" />
<attr name="cameraVideoCodec" format="enum">
<enum name="deviceDefault" value="0" />
<enum name="h263" value="1" />
<enum name="h264" value="2" />
</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" />

Loading…
Cancel
Save