Add support for videoBitRate and audioBitRate

v2
Mattia Iavarone 6 years ago
parent 264551cddc
commit 8b2c85fe0a
  1. 2
      MIGRATION.md
  2. 1
      cameraview/src/main/gles/com/otaliastudios/cameraview/MediaEncoderEngine.java
  3. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java
  4. 9
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java
  5. 24
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  6. 10
      cameraview/src/main/java/com/otaliastudios/cameraview/FullVideoRecorder.java
  7. 16
      cameraview/src/main/java/com/otaliastudios/cameraview/SnapshotVideoRecorder.java
  8. 20
      cameraview/src/main/java/com/otaliastudios/cameraview/VideoResult.java
  9. 3
      cameraview/src/main/res/values/attrs.xml

@ -49,3 +49,5 @@
- VideoSnapshots now respect maxDuration and maxSize limits
- TODO: cameraPreview documentation
- TODO: takeVideoSnapshot documentation
- New setVideoBitRate() and setAudioBitRate() (and XML too) options, accepting bits per second values.
TODO: document them

@ -56,6 +56,7 @@ class MediaEncoderEngine {
public void run() {
// Trying to convert the size constraints to duration constraints,
// because they are super easy to check.
// This is really naive & not accurate, but...
int bitRate = 0;
for (MediaEncoder encoder : mEncoders) {
bitRate += encoder.getBitRate();

@ -631,6 +631,8 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
videoResult.audio = mAudio;
videoResult.maxSize = mVideoMaxSize;
videoResult.maxDuration = mVideoMaxDuration;
videoResult.videoBitRate = mVideoBitRate;
videoResult.audioBitRate = mAudioBitRate;
// Initialize the media recorder
mCamera.unlock();
@ -660,6 +662,8 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
videoResult.isSnapshot = true;
videoResult.codec = mVideoCodec;
videoResult.location = mLocation;
videoResult.videoBitRate = mVideoBitRate;
videoResult.audioBitRate = mAudioBitRate;
// What matters as size here is the preview size, which is passed to the GlCameraPreview
// surface texture, which is then passed to the encoder. The view size has no influence.

@ -59,6 +59,8 @@ abstract class CameraController implements
protected VideoRecorder mVideoRecorder;
protected long mVideoMaxSize;
protected int mVideoMaxDuration;
protected int mVideoBitRate;
protected int mAudioBitRate;
protected Size mCaptureSize;
protected Size mPreviewSize;
protected int mPreviewFormat;
@ -291,6 +293,13 @@ abstract class CameraController implements
mVideoCodec = codec;
}
final void setVideoBitRate(int videoBitRate) {
mVideoBitRate = videoBitRate;
}
final void setAudioBitRate(int audioBitRate) {
mAudioBitRate = audioBitRate;
}
//endregion

@ -109,6 +109,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
VideoCodec codec = VideoCodec.fromValue(a.getInteger(R.styleable.CameraView_cameraVideoCodec, VideoCodec.DEFAULT.value()));
long videoMaxSize = (long) a.getFloat(R.styleable.CameraView_cameraVideoMaxSize, 0);
int videoMaxDuration = a.getInteger(R.styleable.CameraView_cameraVideoMaxDuration, 0);
int videoBitRate = a.getInteger(R.styleable.CameraView_cameraVideoBitRate, 0);
int audioBitRate = a.getInteger(R.styleable.CameraView_cameraAudioBitRate, 0);
// Picture size selector
List<SizeSelector> pictureConstraints = new ArrayList<>(3);
@ -207,11 +209,13 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
setGrid(grid);
setHdr(hdr);
setAudio(audio);
setAudioBitRate(audioBitRate);
setPictureSize(pictureSelector);
setVideoSize(videoSelector);
setVideoCodec(codec);
setVideoMaxSize(videoMaxSize);
setVideoMaxDuration(videoMaxDuration);
setVideoBitRate(videoBitRate);
// Apply gestures
mapGesture(Gesture.TAP, tapGesture);
@ -1090,6 +1094,26 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraController.setVideoSizeSelector(selector);
}
/**
* Sets the bit rate in bits per second for video capturing.
* Will be used by both {@link #takeVideo(File)} and {@link #takeVideoSnapshot(File)}.
*
* @param bitRate desired bit rate
*/
public void setVideoBitRate(int bitRate) {
mCameraController.setVideoBitRate(bitRate);
}
/**
* Sets the bit rate in bits per second for audio capturing.
* Will be used by both {@link #takeVideo(File)} and {@link #takeVideoSnapshot(File)}.
*
* @param bitRate desired bit rate
*/
public void setAudioBitRate(int bitRate) {
mCameraController.setAudioBitRate(bitRate);
}
/**
* Adds a {@link CameraListener} instance to be notified of all

@ -45,12 +45,22 @@ class FullVideoRecorder extends VideoRecorder {
case H_264: mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); break;
case DEVICE_DEFAULT: mMediaRecorder.setVideoEncoder(mProfile.videoCodec); break;
}
if (mResult.videoBitRate <= 0) {
mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate);
mResult.videoBitRate = mProfile.videoBitRate;
} else {
mMediaRecorder.setVideoEncodingBitRate(mResult.videoBitRate);
}
if (mResult.getAudio() == Audio.ON) {
mMediaRecorder.setAudioChannels(mProfile.audioChannels);
mMediaRecorder.setAudioSamplingRate(mProfile.audioSampleRate);
mMediaRecorder.setAudioEncoder(mProfile.audioCodec);
if (mResult.audioBitRate <= 0) {
mMediaRecorder.setAudioEncodingBitRate(mProfile.audioBitRate);
mResult.audioBitRate = mProfile.audioBitRate;
} else {
mMediaRecorder.setAudioEncodingBitRate(mResult.audioBitRate);
}
}
if (mResult.getLocation() != null) {
mMediaRecorder.setLocation(

@ -36,16 +36,6 @@ class SnapshotVideoRecorder extends VideoRecorder implements GlCameraPreview.Ren
@Override
void start() {
mDesiredState = STATE_RECORDING;
// TODO respect maxSize by doing inspecting frameRate, bitRate and frame size?
// TODO do this at the encoder level, not here with a handler.
/* if (mResult.maxDuration > 0) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mDesiredState = STATE_NOT_RECORDING;
}
}, (long) mResult.maxDuration);
} */
}
@Override
@ -75,9 +65,11 @@ class SnapshotVideoRecorder extends VideoRecorder implements GlCameraPreview.Ren
case H_264: type = "video/avc"; break; // MediaFormat.MIMETYPE_VIDEO_AVC:
case DEVICE_DEFAULT: type = "video/avc"; break;
}
if (mResult.videoBitRate <= 0) mResult.videoBitRate = 1000000;
if (mResult.audioBitRate <= 0) mResult.audioBitRate = 64000;
TextureMediaEncoder.Config config = new TextureMediaEncoder.Config(
width, height,
1000000,
mResult.videoBitRate,
30,
mResult.getRotation(),
type, mTextureId,
@ -87,7 +79,7 @@ class SnapshotVideoRecorder extends VideoRecorder implements GlCameraPreview.Ren
TextureMediaEncoder videoEncoder = new TextureMediaEncoder(config);
AudioMediaEncoder audioEncoder = null;
if (mResult.audio == Audio.ON) {
audioEncoder = new AudioMediaEncoder(new AudioMediaEncoder.Config(64000));
audioEncoder = new AudioMediaEncoder(new AudioMediaEncoder.Config(mResult.audioBitRate));
}
mEncoderEngine = new MediaEncoderEngine(mResult.file, videoEncoder, audioEncoder,
mResult.maxDuration, mResult.maxSize, SnapshotVideoRecorder.this);

@ -25,6 +25,8 @@ public class VideoResult {
long maxSize;
int maxDuration;
int endReason;
int videoBitRate;
int audioBitRate;
VideoResult() {}
@ -126,4 +128,22 @@ public class VideoResult {
public int getTerminationReason() {
return endReason;
}
/**
* Returns the bit rate used for video encoding.
*
* @return the video bit rate
*/
public int getVideoBitRate() {
return videoBitRate;
}
/**
* Returns the bit rate used for audio encoding.
*
* @return the audio bit rate
*/
public int getAudioBitRate() {
return audioBitRate;
}
}

@ -22,6 +22,9 @@
<attr name="cameraVideoSizeBiggest" format="boolean"/>
<attr name="cameraVideoSizeAspectRatio" format="string|reference"/>
<attr name="cameraVideoBitRate" format="integer|reference" />
<attr name="cameraAudioBitRate" format="integer|reference" />
<attr name="cameraGestureTap" format="enum">
<enum name="none" value="0" />
<enum name="focus" value="1" />

Loading…
Cancel
Save