blob: 7ac7871bdd55c9260390bba13f2a81de046964e2 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.messaging.ui.mediapicker;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import com.android.messaging.Factory;
import com.android.messaging.datamodel.MediaScratchFileProvider;
import com.android.messaging.util.ContentType;
import com.android.messaging.util.SafeAsyncTask;
import java.io.FileNotFoundException;
class MmsVideoRecorder extends MediaRecorder {
private static final float VIDEO_OVERSHOOT_SLOP = .85F;
private static final int BITS_PER_BYTE = 8;
// We think user will expect to be able to record videos at least this long
private static final long MIN_DURATION_LIMIT_SECONDS = 25;
/** The uri where video is being recorded to */
private Uri mTempVideoUri;
/** The settings used for video recording */
private final CamcorderProfile mCamcorderProfile;
public MmsVideoRecorder(final Camera camera, final int cameraIndex, final int orientation,
final int maxMessageSize)
throws FileNotFoundException {
mCamcorderProfile =
CamcorderProfile.get(cameraIndex, CamcorderProfile.QUALITY_LOW);
mTempVideoUri = MediaScratchFileProvider.buildMediaScratchSpaceUri(
ContentType.getExtension(getContentType()));
// The video recorder can sometimes return a file that's larger than the max we
// say we can handle. Try to handle that overshoot by specifying an 85% limit.
final long sizeLimit = (long) (maxMessageSize * VIDEO_OVERSHOOT_SLOP);
// The QUALITY_LOW profile might not be low enough to allow for video of a reasonable
// minimum duration. Adjust a/v bitrates to allow at least MIN_DURATION_LIMIT video
// to be recorded.
int audioBitRate = mCamcorderProfile.audioBitRate;
int videoBitRate = mCamcorderProfile.videoBitRate;
final double initialDurationLimit = sizeLimit * BITS_PER_BYTE
/ (double) (audioBitRate + videoBitRate);
if (initialDurationLimit < MIN_DURATION_LIMIT_SECONDS) {
// Reduce the suggested bitrates. These bitrates are only requests, if implementation
// can't actually hit these goals it will still record video at higher rate and stop when
// it hits the size limit.
final double bitRateAdjustmentFactor = initialDurationLimit / MIN_DURATION_LIMIT_SECONDS;
audioBitRate *= bitRateAdjustmentFactor;
videoBitRate *= bitRateAdjustmentFactor;
}
setCamera(camera);
setOrientationHint(orientation);
setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
setVideoSource(MediaRecorder.VideoSource.CAMERA);
setOutputFormat(mCamcorderProfile.fileFormat);
setOutputFile(
Factory.get().getApplicationContext().getContentResolver().openFileDescriptor(
mTempVideoUri, "w").getFileDescriptor());
// Copy settings from CamcorderProfile to MediaRecorder
setAudioEncodingBitRate(audioBitRate);
setAudioChannels(mCamcorderProfile.audioChannels);
setAudioEncoder(mCamcorderProfile.audioCodec);
setAudioSamplingRate(mCamcorderProfile.audioSampleRate);
setVideoEncodingBitRate(videoBitRate);
setVideoEncoder(mCamcorderProfile.videoCodec);
setVideoFrameRate(mCamcorderProfile.videoFrameRate);
setVideoSize(
mCamcorderProfile.videoFrameWidth, mCamcorderProfile.videoFrameHeight);
setMaxFileSize(sizeLimit);
}
Uri getVideoUri() {
return mTempVideoUri;
}
int getVideoWidth() {
return mCamcorderProfile.videoFrameWidth;
}
int getVideoHeight() {
return mCamcorderProfile.videoFrameHeight;
}
void cleanupTempFile() {
final Uri tempUri = mTempVideoUri;
SafeAsyncTask.executeOnThreadPool(new Runnable() {
@Override
public void run() {
Factory.get().getApplicationContext().getContentResolver().delete(
tempUri, null, null);
}
});
mTempVideoUri = null;
}
String getContentType() {
if (mCamcorderProfile.fileFormat == OutputFormat.MPEG_4) {
return ContentType.VIDEO_MP4;
} else {
// 3GPP is the only other video format with a constant in OutputFormat
return ContentType.VIDEO_3GPP;
}
}
}