曲面视图显示黑屏以进行视频预览

时间:2013-11-25 05:13:23

标签: android android-camera surfaceview android-mediarecorder

您好我正在开发类似于此链接的Android视频应用程序  http://android-er.blogspot.in/2011/10/video-capture-using-mediarecorder-with.html 视频应用中的哪个位置以框架布局显示。

我在表面视图上尝试上面的一个,我的xml如下所示。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="20sp" >

<SurfaceView
    android:id="@+id/CameraView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:focusable="true" />

<ImageView
    android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:paddingLeft="2dp"
    android:paddingRight="2dp"
    android:src="@drawable/record_video" />

</RelativeLayout>

我不确定为什么它显示黑屏而不是相机视图。我的ViewActivity.java如下所示。

public class ViewActivity extends Activity implements OnClickListener, SurfaceHolder.Callback
{
MediaRecorder recorder;
SurfaceHolder holder;
boolean recording=false;
private MediaRecorder mediaRecorder;
private File file;
private ImageView recVideo;
private SurfaceView cameraView;
private Camera camera;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE); 

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    recorder = new MediaRecorder();
    initRecorder();

    setContentView(R.layout.view);

    recVideo = (ImageView)findViewById(R.id.mybutton);
    cameraView = (SurfaceView) findViewById(R.id.CameraView);

    holder = cameraView.getHolder();
    holder.addCallback(ViewActivity.this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    recVideo.setClickable(true);
    recVideo.setOnClickListener(this);
}

private void initRecorder() 
{
    recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
    recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
    recorder.setOutputFile(this.initFile().getAbsolutePath());
    recorder.setMaxDuration(60000); // Set max duration 60 sec.
    recorder.setMaxFileSize(5000000); // Set max file size 5M

}

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;

        initRecorder();
        prepareRecorder();
        Toast.makeText(ViewActivity.this,"Video Saved!",Toast.LENGTH_SHORT).show();
        startActivity(new Intent(ViewActivity.this,ViewActivity.class));
        finish();

    }
    else 
    {
        recorder.start();
        recording = true;
        recVideo.setImageDrawable(getResources().getDrawable(R.drawable.stop_recording));
    }
}

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();
}

我不确定我哪里出错了。如何使表面视图显示摄像机视图而不是黑屏。

请帮助。

谢谢!

3 个答案:

答案 0 :(得分:2)

这样做:

public class AndroidVideoCapture extends Activity {

    private Camera myCamera;
    private MyCameraSurfaceView myCameraSurfaceView;
    private MediaRecorder mediaRecorder;

    Button myButton;
    RadioButton flashOff, flashTorch;
    SurfaceHolder surfaceHolder;
    boolean recording;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        recording = false;

        setContentView(R.layout.main);

        // Get Camera for preview
        myCamera = getCameraInstance();
        if (myCamera == null) {
            Toast.makeText(AndroidVideoCapture.this, "Fail to get Camera",Toast.LENGTH_LONG).show();
        }

        myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
        FrameLayout myCameraPreview = (FrameLayout) findViewById(R.id.videoview);
        myCameraPreview.addView(myCameraSurfaceView);

        myButton = (Button) findViewById(R.id.mybutton);
        myButton.setOnClickListener(myButtonOnClickListener);

        flashOff = (RadioButton) findViewById(R.id.flashoff);
        flashTorch = (RadioButton) findViewById(R.id.flashtorch);
    }

    Button.OnTouchListener flashButtonOnTouchListener = new Button.OnTouchListener() {

        @Override
        public boolean onTouch(View arg0, MotionEvent arg1) {
            // TODO Auto-generated method stub

            if (myCamera != null) {
                Parameters parameters = myCamera.getParameters();

                switch (arg1.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
                    myCamera.setParameters(parameters);
                    break;
                case MotionEvent.ACTION_UP:
                    parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
                    myCamera.setParameters(parameters);
                    break;
                }
                ;
            }

            return true;
        }
    };

    Button.OnClickListener flashModeButtonOnClickListener = new Button.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

        }
    };

    Button.OnClickListener myButtonOnClickListener = new Button.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (recording) {
                // stop recording and release camera
                mediaRecorder.stop(); // stop the recording
                releaseMediaRecorder(); // release the MediaRecorder object

                myCamera.lock(); 
                // take camera access back from
                recording = false;
                // MediaRecorder
                // inform the user that recording has stopped
                // Exit after saved
                //finish();
            } else {

                // Release Camera before MediaRecorder start
                releaseCamera();

                if (!prepareMediaRecorder()) {
                    Toast.makeText(AndroidVideoCapture.this,
                            "Fail in prepareMediaRecorder()!\n - Ended -",
                            Toast.LENGTH_LONG).show();
                    finish();
                }

                mediaRecorder.start();
                recording = true;
                myButton.setText("STOP");
            }
        }
    };

    private Camera getCameraInstance() {
        // TODO Auto-generated method stub
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
            c.setDisplayOrientation(90);
        } catch (Exception e) {
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }

    private String getFlashModeSetting() {
        if (flashTorch.isChecked()) {
            return Parameters.FLASH_MODE_TORCH;
        } else {
            return Parameters.FLASH_MODE_OFF;
        }
    }

    private boolean prepareMediaRecorder() {
        myCamera = getCameraInstance();

        Parameters parameters = myCamera.getParameters();
        parameters.setFlashMode(getFlashModeSetting());
        myCamera.setParameters(parameters);

        mediaRecorder = new MediaRecorder();

        myCamera.unlock();
        mediaRecorder.setCamera(myCamera);

        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

        mediaRecorder.setOutputFile(getOutputMediaFile("movie"));
        mediaRecorder.setMaxDuration(6000000); // Set max duration 60 sec.
        mediaRecorder.setMaxFileSize(50000000); // Set max file size 5M

        mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());

        mediaRecorder.setOrientationHint(90);

        try {
            mediaRecorder.prepare();
        } catch (IllegalStateException e) {
            releaseMediaRecorder();
            return false;
        } catch (IOException e) {
            releaseMediaRecorder();
            return false;
        }
        return true;

    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaRecorder(); // if you are using MediaRecorder, release it
                                // first
        releaseCamera(); // release the camera immediately on pause event
    }

    private void releaseMediaRecorder() {
        if (mediaRecorder != null) {
            mediaRecorder.reset(); // clear recorder configuration
            mediaRecorder.release(); // release the recorder object
            mediaRecorder = null;
            myCamera.lock(); // lock camera for later use
        }
    }

    private void releaseCamera() {
        if (myCamera != null) {
            myCamera.release();
            // release the camera for other applications
            myCamera = null;
        }
    }

    public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

        private SurfaceHolder mHolder;
        private Camera mCamera;

        public MyCameraSurfaceView(Context context, Camera camera) {
            super(context);
            mCamera = camera;

            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            // deprecated setting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format,int weight, int height) {
            // If your preview can change or rotate, take care of those events
            // here.
            // Make sure to stop the preview before resizing or reformatting it.

            if (mHolder.getSurface() == null) {
                // preview surface does not exist
                return;
            }

            // stop preview before making changes
            try {
                mCamera.stopPreview();
            } catch (Exception e) {
                // ignore: tried to stop a non-existent preview
            }

            // make any resize, rotate or reformatting changes here

            // start preview with new settings
            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (Exception e) {
            }
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            // The Surface has been created, now tell the camera where to draw
            // the preview.
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub

        }
    }

    private static String getOutputMediaFile(String sufix) {

        String mediaFile;
        File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "/YappBack");
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d("VideoLogger", "failed to create directory");
                return null;
            }
        }
        String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date());
        if (!sufix.equals("movie")) {
            mediaFile = mediaStorageDir.getPath() + File.separator + "output_"+ timeStamp + "_" + sufix + ".txt";
        } else {
            mediaFile = mediaStorageDir.getPath() + File.separator + "output_"+ timeStamp + ".mp4";

        }
        //mediaFile = Environment.getExternalStorageDirectory().getPath()+ "/default.mp4";
        return mediaFile;
    }
}

XML文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <FrameLayout
            android:id="@+id/videoview"
            android:layout_width="match_parent"
            android:layout_height="600px" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <Button
                android:id="@+id/mybutton"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="REC"
                android:textSize="12dp" />

            <RadioGroup
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >

                <RadioButton
                    android:id="@+id/flashoff"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:checked="true"
                    android:text="OFF"
                    android:textSize="8dp" />

                <RadioButton
                    android:id="@+id/flashtorch"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Torch"
                    android:textSize="8dp" />
            </RadioGroup>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

答案 1 :(得分:0)

确保您已在清单文件中声明了CAMERA权限。

同时检查您是否已从设置中授予了相机权限。

答案 2 :(得分:0)

确保您在mediaRecorder.setPreviewDisplay(new Surface(surfaceTexture));之后致电camera.setPreviewTexture(surfaceTexture);,然后诀窍就是camera.stopPreview()之前调用mediaRecorder.start();