Rk3288板子插2个摄像头,其中一个做监控用,需要录制视频,代码如下
public class Recorder {
private String TAG = Recorder.class.getSimpleName();
private static final int MEDIA_RECORDER_REQUEST = 0;
private Camera mCamera;
private TextureView mPreview;
private MediaRecorder mMediaRecorder;
private File mOutputFile;
private boolean isRecording = false;
int frontCamera = 1;
private int previewWidth = 320;
private int previewHeight = 240;
int defaultVideoFrameRate = -1;
private final String[] requiredPermissions = {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
};
public Recorder(TextureView mPreview) {
this.mPreview = mPreview;
}
public void startCapture(String rid) {
dLog.e(TAG, "开始录制视频rid=" + rid);
if (isRecording) {
// BEGIN_INCLUDE(stop_release_media_recorder)
// stop recording and release camera
try {
mMediaRecorder.stop(); // stop the recording
} catch (RuntimeException e) {
// RuntimeException is thrown when stop() is called immediately after start().
// In this case the output file is not properly constructed ans should be deleted.
Log.d(TAG, "RuntimeException: stop() is called immediately after start()");
//noinspection ResultOfMethodCallIgnored
mOutputFile.delete();
}
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
isRecording = false;
releaseCamera();
// END_INCLUDE(stop_release_media_recorder)
}
;
new MediaPrepareTask(rid).execute(null, null, null);
}
public void stopCapture() {
dLog.e(TAG, "结束录制视频");
if (isRecording) {
// BEGIN_INCLUDE(stop_release_media_recorder)
// stop recording and release camera
try {
mMediaRecorder.stop(); // stop the recording
} catch (RuntimeException e) {
// RuntimeException is thrown when stop() is called immediately after start().
// In this case the output file is not properly constructed ans should be deleted.
Log.e(TAG, "RuntimeException: stop() is called immediately after start()");
//noinspection ResultOfMethodCallIgnored
mOutputFile.delete();
}
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
isRecording = false;
releaseCamera();
// END_INCLUDE(stop_release_media_recorder)
new Thread(new Runnable() {
@Override
public void run() {
clearFile();
}
}).start();
}
}
private void clearFile() {
Long dirLgngth = FileUtils.getDirLength(UploadVideoUtils.FolderPath);
if (dirLgngth / 1048576 > 20) {
deleteAnyVideo(FileUtils.getFileByPath(UploadVideoUtils.FolderPath));
}
}
public static long deleteAnyVideo(final File dir) {
if (!FileUtils.isDir(dir)) return -1;
long len = 0;
File[] files = dir.listFiles();
if (files != null && files.length != 0) {
for (int i = 0; i < files.length / 3; i++) {
FileUtils.delete(files[i]);
}
}
return len;
}
protected void onPause() {
// if we are using MediaRecorder, release it first
releaseMediaRecorder();
// release the camera immediately on pause event
releaseCamera();
}
private void releaseMediaRecorder() {
if (mMediaRecorder != null) {
// clear recorder configuration
mMediaRecorder.reset();
// release the recorder object
mMediaRecorder.release();
mMediaRecorder = null;
// Lock camera for later use i.e taking it back from MediaRecorder.
// MediaRecorder doesn't need it anymore and we will release it if the activity pauses.
mCamera.lock();
}
}
private void releaseCamera() {
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
@SuppressLint("NewApi")
private boolean initCamera() {
try {
if (frontCamera == 0) {
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
} else {
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
}
Camera.Parameters camParams = mCamera.getParameters();
mCamera.lock();
try {
mCamera.setPreviewTexture(mPreview.getSurfaceTexture());//注意处,如果没有设置preview,录像会报错.坑1
} catch (IOException e) {
e.printStackTrace();
dLog.e(TAG, e.getMessage());
}
mCamera.setDisplayOrientation(90);
} catch (RuntimeException ex) {
dLog.e(TAG, ex.getMessage());
return false;
}
return true;
}
void initCameraParameter(){
boolean hasSupportRate = false;
Camera.Parameters parameters = mCamera.getParameters();
List<Integer> supportedPreviewFrameRates = parameters.getSupportedPreviewFrameRates();
if (supportedPreviewFrameRates != null
&& supportedPreviewFrameRates.size() > 0) {
Collections.sort(supportedPreviewFrameRates);
for (int i = 0; i < supportedPreviewFrameRates.size(); i++) {
int supportRate = supportedPreviewFrameRates.get(i);
if (supportRate == 15) {
hasSupportRate = true;
}
}
if (hasSupportRate) {
defaultVideoFrameRate = 15;
} else {
defaultVideoFrameRate = supportedPreviewFrameRates.get(0);
}
}
// 获取摄像头的所有支持的分辨率
List<Camera.Size> resolutionList = parameters.getSupportedVideoSizes();
if (resolutionList != null && resolutionList.size() > 0) {
// Collections.sort(resolutionList, new Utils.ResolutionComparator());
Camera.Size previewSize = null;
boolean hasSize = false;
// 如果摄像头支持640*480,那么强制设为640*480
for (int i = 0; i < resolutionList.size(); i++) {
Camera.Size size = resolutionList.get(i);
if (size != null && size.width == 320 && size.height == 240) {
previewSize = size;
previewWidth = previewSize.width;
previewHeight = previewSize.height;
hasSize = true;
break;
}
}
// 如果不支持设为中间的那个
if (!hasSize) {
int mediumResolution = resolutionList.size() / 2;
if (mediumResolution >= resolutionList.size())
mediumResolution = resolutionList.size() - 1;
previewSize = resolutionList.get(mediumResolution);
previewWidth = previewSize.width;
previewHeight = previewSize.height;
}
}
}
private boolean prepareVideoRecorder(String rid) {
try {
initCamera();
initCameraParameter();
mMediaRecorder = new MediaRecorder();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// 设置录制视频源为Camera(相机)
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
if (frontCamera == 1) {
mMediaRecorder.setOrientationHint(270);
} else {
mMediaRecorder.setOrientationHint(90);
}
// 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// 设置录制的视频编码h263 h264
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
// 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错
mMediaRecorder.setVideoSize(previewWidth, previewHeight);
// 设置视频的比特率
mMediaRecorder.setVideoEncodingBitRate(384 * 1024);
// // 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错
if (defaultVideoFrameRate != -1) {
//mMediaRecorder.setVideoFrameRate(defaultVideoFrameRate);
}
mOutputFile = CameraHelper.getOutputMediaFile(CameraHelper.MEDIA_TYPE_VIDEO, rid);
dLog.e(TAG, "录制视频地址=" + mOutputFile.getAbsolutePath());
if (mOutputFile == null) {
return false;
}
mMediaRecorder.setOutputFile(mOutputFile.getPath());
mMediaRecorder.setMaxFileSize(1024 * 1024 * 200);
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
dLog.e(TAG, "IllegalStateException preparing MediaRecorder: ${e.message}");
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
} catch (Exception e) {
Log.e("recorderError", e.getMessage());
releaseMediaRecorder();
return false;
}
}
class MediaPrepareTask extends AsyncTask<Void, Void, Boolean> {
private String rid;
public MediaPrepareTask(String rid) {
this.rid = rid;
}
@Override
protected Boolean doInBackground(Void... Void) {
// initialize video camera
if (prepareVideoRecorder(rid)) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
try {
mMediaRecorder.start();
isRecording = true;
} catch (IllegalStateException e) {
isRecording = false;
releaseMediaRecorder();
Log.e(TAG, "mMediaRecorder start Error" + e.getMessage());
return false;
} catch (Exception e) {
isRecording = false;
releaseMediaRecorder();
Log.e(TAG, "mMediaRecorder start Error" + e.getMessage());
}
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
return false;
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) {
// Recorder.this.finish();
}
}
}
}