android媒体录制器中的预览显示

android媒体录制器中的预览显示,android,surfaceview,android-mediarecorder,Android,Surfaceview,Android Mediarecorder,在android中,如何在媒体录制器启动前显示预览表面。 我的应用程序具有视频录制功能,当我导航到视频录制片段时,它会显示黑屏,当我使用开始按钮开始录制时,相机预览是显示和录制开始 如何在录制前开始预览。 我添加了在片段的onCreateView()中使用的代码- surfaceHolder = mySurfaceView.getHolder(); camera = Camera.open(); if(camera!=null){ camera.setDisplayOrientation

在android中,如何在媒体录制器启动前显示预览表面。 我的应用程序具有视频录制功能,当我导航到视频录制片段时,它会显示黑屏,当我使用开始按钮开始录制时,相机预览是显示和录制开始

如何在录制前开始预览。 我添加了在片段的onCreateView()中使用的代码-

surfaceHolder = mySurfaceView.getHolder();
camera = Camera.open();
if(camera!=null){
    camera.setDisplayOrientation(90);
    Camera.Parameters param;
    param = camera.getParameters();
    param.setPreviewFrameRate(20);
    param.setPreviewSize(176, 144);
    camera.setParameters(param);
    camera.setPreviewDisplay(surfaceHolder);
}

mediaRecorder = new MediaRecorder();
camera.unlock();
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile camcorderProfile_HQ = CamcorderProfile
            .get(CamcorderProfile.QUALITY_HIGH);
mediaRecorder.setProfile(camcorderProfile_HQ);
String filePath = getOutputMediaFile(MEDIA_TYPE_VIDEO).getPath();
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
mediaRecorder.setOutputFile(filePath);
我在“开始”按钮上使用的代码-

mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.prepare();
mediaRecorder.start();
所以我可以用上面的代码重新编码视频,但不能在录制开始前显示预览。 请帮我找到我丢失的地方。因为在录制视频之前会显示黑色屏幕

提前谢谢

public void surfaceCreated(SurfaceHolder holder) {
        if (mCamera != null) {
            Parameters params = mCamera.getParameters();
            mCamera.setParameters(params);
            try {
                //mCamera.setDisplayOrientation(90);
                mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mCamera.startPreview();
        }
    }

如果实现SurfaceHolder.Callback,请像这样重写surfaceCreated方法。这对我很有效。

我遇到了同样的问题。我查了一下,这是我的活动。我花了点力气才使它不崩溃,所以这里是最后的结果。它在用户单击REC按钮之前显示预览。(我也在显示倒计时,但不介意)。还要注意,在本例中(单击时),在主线程上完成了太多的工作。这里有一些不是最佳实践,但作为一个工作示例,我认为它已经足够好了

import android.app.Activity;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.File;
import java.io.IOException;

public class MainActivity extends Activity implements SurfaceHolder.Callback {

    private static final String LOG_TAG = MainActivity.class.getCanonicalName();
    Button myButton;
    MediaRecorder mediaRecorder;
    SurfaceHolder surfaceHolder;
    boolean recording;
    private TextView mTimer;
    private Camera mCamera;

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

        setContentView(R.layout.activity_main);

        recording = false;
        mediaRecorder = new MediaRecorder();
        mCamera = Camera.open();
        initMediaRecorder();

        SurfaceView myVideoView = (SurfaceView) findViewById(R.id.videoview);
        surfaceHolder = myVideoView.getHolder();
        surfaceHolder.addCallback(this);

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

        mTimer = (TextView) findViewById(R.id.timer);
    }

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

        @Override
        public void onClick(final View arg0) {
            CountDownTimer countDownTimer = new CountDownTimer(90 * 1000, 1000) {
                @Override
                public void onTick(long millisUntilFinished) {
                    mTimer.setText(String.valueOf(millisUntilFinished / 1000));
                }

                @Override
                public void onFinish() {
                    onClick(arg0);
                }
            };

            if (recording) {
                // Stop recording and finish
                try {
                    mediaRecorder.stop();
                    mediaRecorder.reset();
                    mediaRecorder.release();
                    finish();
                } catch (Exception e) {
                    Log.e(LOG_TAG, "Failed to stop recorder", e);
                }

            } else {
                // Release the camera and start recording
                mCamera.release();
                countDownTimer.start();
                mediaRecorder.start();
                recording = true;
                myButton.setText("STOP");
            }
        }
    };


    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (mCamera != null) {
            Camera.Parameters params = mCamera.getParameters();
            mCamera.setParameters(params);
            try {
                mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mCamera.startPreview();
        }
        prepareMediaRecorder();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {

    }

    private void initMediaRecorder() {
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
        CamcorderProfile camcorderProfile_HQ = CamcorderProfile.get(CamcorderProfile.QUALITY_CIF);
        mediaRecorder.setProfile(camcorderProfile_HQ);
        File file = new File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "myvideo.mp4");
        if (file.exists()) {
            file.delete();
        }
        mediaRecorder.setOutputFile(file.getAbsolutePath());
        mediaRecorder.setMaxDuration(90000); // Set max duration 90 sec.
        mediaRecorder.setMaxFileSize(15000000); // Set max file size 15M
    }

    private void prepareMediaRecorder() {
        mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());

        try {
            mediaRecorder.prepare();
        } catch (IllegalStateException | IOException e) {
            Log.e(LOG_TAG, "Failed to prepare recorder", e);
        }
    }
}

我也有同样的问题-如何在没有实际录制的情况下显示相机预览?!在用户有机会将相机正确居中之前就开始录制是一种糟糕的用户体验。令人印象深刻的是,还没有人回答这个问题。@Cat你得到答案了吗?不幸的是,我在尝试你的代码时,在设置音频源格式时,遇到了一个非法的状态异常。如果我对这一行进行注释,我会在凸轮轮廓的设置上得到相同的异常。无论如何谢谢你