我使用表面视图在android中创建了一个自定义视频录制。我做了代码和它在设备(Sony xperia s,xperia z和Samsung grand)的工作。在三星galaxy s3,s4和s5设备中,我没有停止我的视频录制,它会导致此行mediarecorder.stop()行出错。它只会出现在后置摄像头上。对于前置摄像头,它工作正常,如果我从前置摄像头回到后置摄像头,它正在工作。请澄清这个问题。我在下面粘贴我的代码。
CameraPreview class that extends SurfaceView:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
public static SurfaceHolder mHolder;
private Camera mCamera;
private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;
private static final String TAG = "CameraPreview";
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
} catch (NullPointerException e) {
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
try {
this.getHolder().removeCallback(this);
mCamera.stopPreview();
mCamera.release();
}catch (Exception e){
Log.e("Inside Main Exc",""+e);
}
}
private void stopPreviewAndFreeCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
mCamera.setDisplayOrientation(90);
} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
try {
Camera.Parameters params = mCamera.getParameters();
if (params.getSupportedFocusModes().contains(
Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
List<Camera.Size> sizes = params.getSupportedPictureSizes();
Camera.Size size = sizes.get(0);
for (int i = 0; i < sizes.size(); i++) {
if (sizes.get(i).width > size.width)
size = sizes.get(i);
}
params.setPictureSize(size.width, size.height);
mCamera.setParameters(params);
}catch (Exception e){
Log.e("Exception value",""+e);
}
}
}
Inside Main Class, I did the following:
In onCreate(), I initialized the startcamera task:
startCamera(currentCameraId);
If I select Start button, then recordVideo() is called and Select Stop button, then recordCompleted() is called.
private void startCamera(int cameraId) {
try {
mCamera = CameraAPI.getCameraInstance(this, cameraId);
mCameraPreview = new CameraPreview(this, mCamera);
captureScreenFrame.addView(mCameraPreview);
} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
private void recordVideo() {
if (isVideoRecording) {
recordCompleted();
} else {
T = new Timer();
T.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (tempCount == 31) {
recordCompleted();
} else {
recordValue.setText("00:" + tempCount);
tempCount++;
}
}
});
}
}, 1000, 1000);
cameraFlip.setVisibility(View.GONE);
cameraFlash.setVisibility(View.GONE);
if (!prepareMediaRecorder()) {
Toast.makeText(TrunqCameraActivity.this,
"Fail in prepareMediaRecorder()!\n - Ended -", Toast.LENGTH_LONG).show();
finish();
}
runOnUiThread(new Runnable() {
public void run() {
try {
mediaRecorder.start();
} catch (Exception e) {
}
}
});
isVideoRecording = true;
}
}
public void recordCompleted(){
mediaRecorder.stop();
T.cancel();
MediaController mc = new MediaController(TrunqCameraActivity.this);
mc.setMediaPlayer(capturedVideoPreview);
mc.setAnchorView(capturedVideoPreview);
capturedVideoPreview.requestFocus();
capturedVideoPreview.setMediaController(mc);
capturedVideoPreview.setVideoPath(capturedFile.getPath());
isVideoRecording = false;
}
private boolean prepareMediaRecorder() {
String capturedFilePath = VIDEO_DIRECTORY.concat("TrunqVideo_" +
new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()) + ".mp4");
capturedFile = new File(capturedFilePath);
mediaRecorder = new MediaRecorder();
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setVideoEncodingBitRate(512 * 1000);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mediaRecorder.setVideoFrameRate(30);
mediaRecorder.setVideoSize(640, 480);
}
mediaRecorder.setOutputFile(capturedFilePath);
mediaRecorder.setMaxDuration(30000);
mediaRecorder.setMaxFileSize(50000000);
if (currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
mediaRecorder.setOrientationHint(90);
} else {
mediaRecorder.setOrientationHint(270);
}
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}catch (Exception e){}
return true;
}