问候同伴Androiders。我正在开发一个使用相机显示连续预览的应用程序,当用户想要时,记录来自该Feed的视频并保存。
我已经设置了第一部分,但是我遇到了让录音工作的问题。我已经按照各种指南和我正在遇到的问题的答案,但我似乎总是遇到“无效状态”问题(目前setCamera调用无效状态(4))。
这是我的完整代码。谢谢你看看!
Camera camera;
SurfaceView preview;
SurfaceHolder previewHolder;
MediaRecorder recorder;
boolean recording = false;
boolean cameraConfigured = false;
private Button camera_button;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Remove title bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
//Remove notification bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//Keep screen awake
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_fullscreen);
preview = (SurfaceView)findViewById(R.id.camerapreview);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
camera_button = (Button) findViewById(R.id.camera_button);
camera_button.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View view)
{
if (recording)
{
recorder.stop();
recording = false;
initRecorder();
prepareRecorder();
camera_button.setText("Record");
}
else
{
recording = true;
recorder.start();
camera_button.setText("Stop");
}
}
});
// Wake screen
WakeLock screenLock = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
screenLock.acquire();
screenLock.release();
}
@Override
public void onResume()
{
super.onResume();
if (camera == null)
{
camera = Camera.open();
}
preview.setVisibility(View.VISIBLE);
startPreview();
}
@Override
public void onPause()
{
if(camera != null)
{
camera.stopPreview();
camera.release();
camera = null;
cameraConfigured = false;
}
preview.setVisibility(View.INVISIBLE);
super.onPause();
}
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback()
{
public void surfaceCreated(SurfaceHolder holder)
{
initRecorder();
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height)
{
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder)
{
if (recording)
{
recorder.stop();
recording = false;
}
recorder.release();
}
};
private void initRecorder()
{
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
recorder.setOutputFile("/sdcard" + File.separator + "testVideo_" + timeStamp + ".mp4");
camera.unlock();
recorder.setCamera(camera);
}
private void prepareRecorder()
{
recorder.setPreviewDisplay(previewHolder.getSurface());
try
{
recorder.prepare();
}
catch (IllegalStateException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void initPreview(int width, int height)
{
if (camera != null && previewHolder.getSurface() != null)
{
try
{
camera.setPreviewDisplay(previewHolder);
}
catch (Throwable t)
{
Log.e("CameraTest","");
}
if (!cameraConfigured)
{
Camera.Parameters parameters=camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);
Camera.Size pictureSize = getSmallestPictureSize(parameters);
if (size != null && pictureSize != null)
{
parameters.setPreviewSize(size.width, size.height);
parameters.setPictureSize(pictureSize.width,
pictureSize.height);
parameters.set("cam_mode", 1 );
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
parameters.setPictureFormat(ImageFormat.JPEG);
camera.setParameters(parameters);
cameraConfigured=true;
}
}
}
}
private void startPreview()
{
if (cameraConfigured && camera != null)
{
camera.startPreview();
}
}
public Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters)
{
Camera.Size result=null;
for (Camera.Size size : parameters.getSupportedPreviewSizes())
{
if ((size.width <= width && size.height <= height) || (size.height <= width && size.width <= height))
{
if (result == null)
{
result=size;
}
else
{
int resultArea=result.width * result.height;
int newArea=size.width * size.height;
if (newArea > resultArea)
{
result=size;
}
}
}
}
return(result);
}
public Camera.Size getSmallestPictureSize(Camera.Parameters parameters)
{
Camera.Size result=null;
for (Camera.Size size : parameters.getSupportedPictureSizes())
{
if (result == null)
{
result=size;
}
else
{
int resultArea=result.width * result.height;
int newArea=size.width * size.height;
if (newArea < resultArea)
{
result=size;
}
}
}
return(result);
}
答案 0 :(得分:2)
查看android video recording sample code,android需要一个非常特定的顺序来配置mediaRecorder。在我看来,您应该安排initRecorder()
如下:
private void initRecorder()
{
recorder = new MediaRecorder();
// The following two lines should precede setAudioSource line
camera.unlock();
recorder.setCamera(camera);
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
recorder.setOutputFile("/sdcard" + File.separator + "testVideo_" + timeStamp + ".mp4");
}