android - 录像同时回调onPreviewFrame

标签 android android-camera mediarecorder android-mediarecorder android-video-record

我正在尝试使用 MediaRecorder 录制视频并从 onPreviewFrame 回调方法获取原始帧(字节数组)

似乎没那么容易,mb这甚至不可能,我不知道...

但我找到了一些答案(对于类似的问题),人们说你应该在调用 MediaRecorder.start() 后重新连接相机实例(Camera.reconnect())并再次设置预览回调

我尝试过类似的方法,但它不起作用(记录有效但从未调用 onPreviewFrame)

我还尝试在 MediaRecorder.start() 之后调用相机的 stopPreviewstartPreview 方法,但似乎我们不应该这样做,否则当我在此类操作应用停止响应(它变得卡住)之后尝试停止录制(MediaRecorder.stop())

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sample_main);
    mPreview = findViewById(R.id.surface_view);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            testVideoRecording();
        }
    }, 1000);
}

@Override
public void onPreviewFrame(byte[] bytes, Camera camera) {
    Log.i(TAG, "onPreviewFrame");
}

private void testVideoRecording() {
    mCamera = Camera.open();

    Camera.Parameters parameters = mCamera.getParameters();
    List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
    List<Camera.Size> mSupportedVideoSizes = parameters.getSupportedVideoSizes();
    Camera.Size optimalSize = CameraHelper.getOptimalVideoSize(mSupportedVideoSizes,
            mSupportedPreviewSizes, mPreview.getWidth(), mPreview.getHeight());

    CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
    profile.videoFrameWidth = optimalSize.width;
    profile.videoFrameHeight = optimalSize.height;

    parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
    mCamera.setParameters(parameters);
    try {
        mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
    } catch (IOException e) {
        e.printStackTrace();
    }

    mCamera.setPreviewCallback(this);

    mMediaRecorder = new MediaRecorder();

    // Step 1: Unlock and set camera to MediaRecorder
    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    // Step 2: Set sources
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    mMediaRecorder.setProfile(profile);

    // Step 4: Set output file
    mOutputFile = new File(Environment.getExternalStorageDirectory()
            + File.separator + "test.mp4");
    if (mOutputFile.exists()) mOutputFile.delete();

    mMediaRecorder.setOutputFile(mOutputFile.getPath());

    // Step 5: Prepare configured MediaRecorder
    try {
        mMediaRecorder.prepare();
    } catch (IOException e) {
        e.printStackTrace();
    }
    mMediaRecorder.start();

    // Step 6: try to set preview frame callback

    //mCamera.stopPreview();

    try {
        mCamera.reconnect();
    } catch (IOException e) {
        e.printStackTrace();
    }

    /*try {
        mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
    } catch (IOException e) {
        e.printStackTrace();
    }*/

    mCamera.setPreviewCallback(this);

    //mCamera.startPreview();
}

所以我想知道是否可以同时使用 MediaRecorder 和预览帧回调。如果是,那么如何正确地做到这一点?

最佳答案

(根据以下亚历克斯的评论编辑)

是的,一般来说是可以的。相机 API 可能很棘手,需要精确度和持久性。

首先,从您知道有效的示例代码开始。比如官方的原始API抓视频教程是:https://developer.android.com/guide/topics/media/camera#capture-video .太好了,现在您的设备上已经有了示例代码,您已经完成了大部分工作。如果您无法在您的设备上使用它,请至少尝试使用其他品牌的设备。

接下来,让您自己的应用程序代码与示例的线程和 API 调用相匹配。当您遇到错误或卡住时,请查看日志以了解发生了什么。这通常是一些微不足道的事情,比如 list 中缺少权限。

最后,日志,日志,日志。在这个问题中,如果您将日志中的错误与您的代码一起发布,您可能会找到具有特定答案的特定问题。

祝你好运!

关于android - 录像同时回调onPreviewFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52314822/

相关文章:

java - 如何从内部方法向 ArrayList 添加值?

android - Xamarin Android 状态栏字体颜色

android - 将相机预览安装到比显示器大的 SurfaceView

android - 相机请求代码在Android中意味着什么

android - 拆分和合并/连接录制的音频

android - 通知状态栏文字

android - 对于某些帐户,Google Drive API Android 帐户选择器始终返回 RESULT_CANCELED

android - Droid 设备 - 不会旋转从相机捕获的图像? (相机.参数)

Android 无法使用前置摄像头录制视频,MediaRecorder 启动失败 : -19

java - 如何使用 LocalSocket 修复 'java.lang.IllegalStateException' 上的 'MediaRecorder.start()'