【问题标题】:preview display in android media recorderandroid媒体记录器中的预览显示
【发布时间】:2013-10-04 08:28:40
【问题描述】:

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

所以我可以使用上面的代码重新编码视频,但无法在录制开始之前显示预览。 请帮助我在哪里丢失。因为在重新编码视频之前会显示黑屏。

提前致谢。

【问题讨论】:

  • 我遇到了同样的问题 - 你如何在不实际录制的情况下显示相机预览?!在用户有机会将相机正确居中之前开始录制是一种糟糕的用户体验。令人印象深刻的是,还没有人回答这个问题。
  • @Cat 你得到答案了吗?

标签: android surfaceview android-mediarecorder


【解决方案1】:
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 方法。这对我有用。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。我查了一下,这是我的活动。我花了一些力气让它不崩溃,所以这是最终的结果。它在用户单击 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);
            }
        }
    }
    

    【讨论】:

    • 不幸的是,在设置音频源格式时,我在尝试您的代码时遇到了非法状态异常。如果我评论这一行,我会在凸轮轮廓的设置上遇到同样的异常。还是谢谢你
    猜你喜欢
    • 2017-04-19
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    相关资源
    最近更新 更多