我发现了这样的问题。有人说这是可能的,但解决方案对我没有用,有些人说这是不可能的。
我有这个代码用于记录mp4:
import java.io.IOException;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity implements OnClickListener, SurfaceHolder.Callback {
MediaRecorder recorder;
SurfaceHolder holder;
boolean recording = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
recorder = new MediaRecorder();
initRecorder();
setContentView(R.layout.activity_main);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.surfaceView1);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
private void initRecorder() {
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
recorder.setOutputFile(Environment.getExternalStorageDirectory().getPath() + "/video.mp4");
recorder.setMaxDuration(5 * 1000); // 50 seconds
recorder.setMaxFileSize(5 * 1000000); // Approximately 5 megabytes
}
private void prepareRecorder() {
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
public void onClick(View v) {
if (recording) {
recorder.stop();
recording = false;
// Let's initRecorder so we can record again
initRecorder();
prepareRecorder();
} else {
recording = true;
recorder.start();
}
}
public void surfaceCreated(SurfaceHolder holder) {
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
finish();
}
}
另一个用于实时获取帧:
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.ErrorCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class MainActivity extends Activity {
SurfaceView mVideoCaptureView;
Camera mCamera;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mVideoCaptureView = (SurfaceView) findViewById(R.id.surfaceView1);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
SurfaceHolder videoCaptureViewHolder = mVideoCaptureView.getHolder();
videoCaptureViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
videoCaptureViewHolder.addCallback(new Callback() {
public void surfaceDestroyed(SurfaceHolder holder) {
stopVideo();
}
public void surfaceCreated(SurfaceHolder holder) {
startVideo();
}
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
}
private void startVideo() {
//Open camera
SurfaceHolder videoCaptureViewHolder = null;
try {
mCamera = Camera.open();
} catch (RuntimeException e) {
Log.e("CameraTest", "Camera Open failed");
return;
}
mCamera.setErrorCallback(new ErrorCallback() {
public void onError(int error, Camera camera) {
}
});
//Get params
Camera.Parameters parameters = mCamera.getParameters();
//Get Frame rate
int[] minFrameRate = {90000,90000};
List<int[]> supportedPreviewFps=parameters.getSupportedPreviewFpsRange();
Iterator<int[]> supportedPreviewFpsIterator=supportedPreviewFps.iterator();
while(supportedPreviewFpsIterator.hasNext()){
int[] tmpRate=supportedPreviewFpsIterator.next();
if(tmpRate[0]<minFrameRate[0])
{
minFrameRate[0] = tmpRate[0];
minFrameRate[1] = tmpRate[1];
}
}
//Set frame rate
parameters.setPreviewFpsRange(minFrameRate[0],minFrameRate[1]);
Log.i("Info", "Frame rate set to: " + minFrameRate[0] + ','+ minFrameRate[1]);
//Get image size
List<Size> supportedPreviewSizes=parameters.getSupportedPreviewSizes();
Iterator<Size> supportedPreviewSizesIterator=supportedPreviewSizes.iterator();
while(supportedPreviewSizesIterator.hasNext()){
Size tmpSize=supportedPreviewSizesIterator.next();
Log.v("CameraTest","supportedPreviewSize.width = "+tmpSize.width+"supportedPreviewSize.height = "+tmpSize.height);
}
//Set params
mCamera.setParameters(parameters);
if ( mVideoCaptureView!=null)
videoCaptureViewHolder = mVideoCaptureView.getHolder();
try
{
mCamera.setPreviewDisplay(videoCaptureViewHolder);
} catch (Throwable t)
{
Log.e("Error","mCamera.setPreviewDisplay(videoCaptureViewHolder) fail");
}
//Start camera
Size previewSize=mCamera.getParameters().getPreviewSize();
int dataBufferSize=(int)(previewSize.height*previewSize.width*
(ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat())/8.0));
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
public synchronized void onPreviewFrame(byte[] data, Camera camera) {
try
{
camera.addCallbackBuffer(data);
}catch (Exception e) {
Log.e("CameraTest", "addCallbackBuffer error");
}
}
});
try {
mCamera.startPreview();
} catch (Throwable e) {
mCamera.release();
mCamera = null;
return;
}
}
private void stopVideo() {
Log.i("StopVideo","OK");
if(null==mCamera)
return;
try {
mCamera.stopPreview();
mCamera.setPreviewDisplay(null);
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.release();
} catch (IOException e) {
e.printStackTrace();
return;
}
mCamera = null;
}
public void finish(){
stopVideo();
super.finish();
}
@Override
public void onBackPressed() {
stopVideo();
super.onBackPressed();
};
}
这最后一段代码有一个功能“onPreviewFrame”,可以实时获取帧。
如何将此功能包含在第一段代码中?
我试图使用Camera对象,但如果Camara打开并开始录制mp4失败,因为它不能同时执行这两项操作