我在相机预览方面遇到了麻烦。但首先,这是我的应用程序的流程:
1. Show Camera preview for video recording (works fine)
2. When video recording stops (user presses stop), play the recorded video (works fine)
3. on Recorded video completion, start camera preview (not working)
我无法弄清楚为什么它不起作用,在Logcat中没有返回错误。
任何人都有这个预览的想法/建议吗?
编辑:当我按下硬件主页按钮然后再启动应用时,相机预览再次有效。
这是我的代码:
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...>
<VideoView android:id="@+id/videoView1"
android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight=".5"/>
<RelativeLayout android:id="@+id/surfaceViewWrapper" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight=".5">
<com.sample.video.CameraSurfaceView
android:id="@+id/cameraView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00ff00"
/>
</RelativeLayout>
</LinearLayout>
CameraSurfaceView.java
public class CameraSurfaceView extends ViewGroup implements SurfaceHolder.Callback{
...
private Camera mCamera;
private MediaRecorder mMediaRecorder;
private int frontCameraId;
public CameraSurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CameraSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
frontCameraId = 0;
}
//---Recording---
public void startRecording(){
mMediaRecorder.start();
}
public boolean prepareVideoRecorder() throws IOException{
//Some code here from google, I didn't include in this post to make this not too long
...
}
public void stopRecording() {
mMediaRecorder.stop();
}
public void releaseMediaRecorder(){
if (mMediaRecorder != null) {
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
//###---Camera---
public void releaseCamera(){
//Some code here from google, I didn't include in this post to make this not too long
...
}
public void useFrontCamera(){
int numberOfCameras = Camera.getNumberOfCameras();
CameraInfo cameraInfo = new CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
frontCameraId = i;
}
}
mCamera = Camera.open(frontCameraId);
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
}
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.stopPreview();
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
if (mCamera != null) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
public void startPreview(){
mCamera.startPreview();
}
public void setCamera(Camera camera){
this.mCamera = camera;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//Some code here from google, I didn't include in this post to make this not too long
...
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//Some code here from google, I didn't include in this post to make this not too long
...
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
//Some code here from google, I didn't include in this post to make this not too long
...
}
}
CameraPreview code: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html
MainActivity.java
public class MainActivity extends Activity{
CameraSurfaceView cameraSurfaceView;
private boolean isRecording = false;
private VideoView mVideoView;
MediaPlayer mpPlayer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cameraSurfaceView = (CameraSurfaceView)findViewById(R.id.cameraView);
mVideoView = (VideoView)findViewById(R.id.videoView1);
}
@Override
protected void onResume() {
super.onResume();
cameraSurfaceView.useFrontCamera();
}
@Override
protected void onPause() {
super.onPause();
cameraSurfaceView.releaseMediaRecorder();
cameraSurfaceView.releaseCamera();
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
menu.add(0, 0, 0, "Start Recording");
menu.add(0, 1, 0, "Stop Recording");
menu.add(0, 2, 0, "Play Recording");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId())
{
case 0:
if(isRecording){
// stop recording and release camera
cameraSurfaceView.stopRecording(); // stop the recording
cameraSurfaceView.releaseMediaRecorder(); // release the MediaRecorder object
isRecording = false;
}else{
try {
// initialize video camera
if (cameraSurfaceView.prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
cameraSurfaceView.startRecording();
// inform the user that recording has started
isRecording = true;
Toast.makeText(getBaseContext(), "Recording Start.", Toast.LENGTH_SHORT).show();
} else {
// prepare didn't work, release the camera
cameraSurfaceView.releaseMediaRecorder();
}
}catch (Exception e) {
String message = e.getMessage();
Log.i(null, "Problem Start"+message);
cameraSurfaceView.releaseMediaRecorder();
}
}
break;
case 1:
if(isRecording){
// stop recording and release camera
cameraSurfaceView.stopRecording(); // stop the recording
cameraSurfaceView.releaseMediaRecorder(); // release the MediaRecorder object
// inform the user that recording has stopped
isRecording = false;
}
break;
case 2:
//play video
cameraSurfaceView.releaseMediaRecorder();
cameraSurfaceView.releaseCamera();
if (mVideoView.getVisibility() == View.INVISIBLE) {
mVideoView.setVisibility(View.VISIBLE);
}
if(cameraSurfaceView.getVisibility() == View.VISIBLE)
cameraSurfaceView.setVisibility(View.INVISIBLE);
try {
mpPlayer = new MediaPlayer();
mpPlayer.setDisplay(mVideoView.getHolder());
mpPlayer.setDataSource(MainActivity2.this, Uri.parse(Environment.getExternalStorageDirectory() + "/Sample Video Recording/sample.mp4"));
mpPlayer.setOnCompletionListener(onVideoComplete);
mpPlayer.setOnErrorListener(onErrorMediaPlayer);
mpPlayer.prepare();
mpPlayer.start();
} catch (IllegalArgumentException e) {e.printStackTrace();
} catch (SecurityException e) {e.printStackTrace();
} catch (IllegalStateException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
public MediaPlayer.OnErrorListener onErrorMediaPlayer = new MediaPlayer.OnErrorListener(){
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return false;
}
};
public MediaPlayer.OnPreparedListener onNarrPreparedListener = new MediaPlayer.OnPreparedListener(){
@Override
public void onPrepared(MediaPlayer mp) {
}
};
private MediaPlayer.OnCompletionListener onVideoComplete = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mpPlayer.stop();
mpPlayer.release();
if (mVideoView.getVisibility() == View.VISIBLE) {
mVideoView.setVisibility(View.INVISIBLE);
}
if(cameraSurfaceView != null){
cameraSurfaceView.releaseMediaRecorder();
cameraSurfaceView.releaseCamera();
}
if(cameraSurfaceView.getVisibility() == View.INVISIBLE)
cameraSurfaceView.setVisibility(View.VISIBLE);
cameraSurfaceView.useFrontCamera();
cameraSurfaceView.startPreview();
}
};
}
清单:
...
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" android:required="false"/>
...
先谢谢你们。
答案 0 :(得分:3)
在创建MediaRecorder之前,您必须解锁相机。 并在释放之前将其锁定。
试试这段代码,它会起作用 玩得开心......
if(mCamera == null)
{
mCamera = Camera.open();
mCamera.unlock();
}
if(mMediaRecorder == null)
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setPreviewDisplay(surface);
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);