24

when using the Camera.PreviewCallback implementation the onPreviewFrame is called without problem after initializing camera and starting preview (Camera.startPrevew()). The problem is if I make a video recording using MediaRecorder onPreviewFrame does not get called any more.

I understand that when using MediaRecorder to record video stops the Camera.PreviewCallback, but why can't it be restarted?

I have tried resetting the camera preview callback (setPreviewCallback(callback)) and restarting startPreview, but while I have a preview there is no call to onPreviewFrame.

esse
  • 394
  • 1
  • 2
  • 9

4 Answers4

17

You must call setPreviewCallback in the surfaceChanged method, not only in the surfaceCreated.

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null){
  return;
}

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

try {
    mCamera.setPreviewCallback(this);
    mCamera.setPreviewDisplay(mHolder);
    mCamera.startPreview();

} catch (Exception e){
    Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
Gilad Levinson
  • 234
  • 2
  • 12
Neonigma
  • 1,825
  • 17
  • 20
  • you can't call `mCamera.stopPreview();`, `mCamera.startPreview();` after `MediaRecorder.start` otherwise app won't respond when you try to stop recording `MediaRecorder.stop`. – user924 Sep 13 '18 at 06:24
  • anyway your answer is weird because it's not about SurfaceView or TextureView at all: https://stackoverflow.com/questions/52314822/video-recording-and-onpreviewframe-callback-at-the-same-time – user924 Sep 14 '18 at 06:59
  • we're talking about `onPreviewFrame` callback and not about video visualization on some view (SurfaceView or TextureView). – user924 Sep 14 '18 at 07:01
10

I had a similar problem; see

setOneShotPreviewCallback not hitting onPreviewFrame() in callback

What I discovered was that after calling Camera#unlock() to prepare the MediaRecorder, it was necessary to call Camera#reconnect() before setting the preview callback. This is because Camera.unlock() detaches the camera from the process to let the MediaRecorder connect to it.

http://developer.android.com/reference/android/hardware/Camera.html#unlock()

In my investigations I also discovered that if you set any preview callbacks using other methods than the one shot method, you have to reset all of these after calling Camera#reconnect() as well. So, briefly:

mCamera.unlock();
//set up MediaRecorder
mCamera.reconnect();
mCamera.setPreviewCallback(mCallback);
//or whatever callback method you want to use
//and even if you've set this callback already

I hope that helps!

Community
  • 1
  • 1
Andrew Wyld
  • 7,133
  • 7
  • 54
  • 96
3

You should call it within new instantiation of previewCallBacks() interface, like below

public void surfaceCreated(SurfaceHolder holder) {
        // if (mediaRecorder == null) {
        try {
            camera = Camera.open();
            camera.setPreviewCallback(new PreviewCallback() {
                public void onPreviewFrame(byte[] _data, Camera _camera) {
                }
            }
        }
}
M Rijalul Kahfi
  • 1,460
  • 3
  • 22
  • 42
  • it doesn't make sense, you didn't understand the question, frames won't be send after MediaRecorder.start – user924 Sep 13 '18 at 06:28
0

You need to call startPreview() again after a video or photo was taken.

botweb
  • 137
  • 3
  • 9
  • **after** - do you hear yourself? question is how to record and get frames at the same time, not **after**! – user924 Sep 13 '18 at 06:27