从已经运行的预览中录制视频

时间:2014-02-26 23:04:15

标签: android camera mediarecorder

问候同伴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);
}

1 个答案:

答案 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");  
}