Android video recorder: failed to get surface
Asked Answered
M

1

8

Hi I am trying to use the camera v2 API to record video using a Raspberry Pi 3 device that uses the Raspberry Pi camera module attached to it.

I am developing this using Android Things with Kotlin.

Here is how my video recording code looks like.

  override fun startRecording(videoCameraCallback: VideoCameraCallback) {
    val cameraIdList = cameraManager.cameraIdList
    cameraManager.openCamera(cameraIdList[0], cameraStateCalback, null)

    Log.d("JJJ", "start recording called")
}

    var cameraStateCalback = object : CameraDevice.StateCallback() {
    override fun onOpened(camera: CameraDevice?) {
        if (camera != null) {
            Log.d("JJJ", "onOpened and will now create handler and capture session")
            //create handler thread
            val thread = HandlerThread("MyHandlerThread")
            thread.start()
            val handler = Handler(thread.looper)

            //create capture session
            val mediaRecorderSurface = setMediaOutputSurface()
            val surfaces = ArrayList<Surface>()
            surfaces.add(mediaRecorderSurface)
            captureRequest =  camera.createCaptureRequest(TEMPLATE_RECORD).build()
            camera.createCaptureSession(surfaces, cameraCaptureSessionCallBack,handler)
            Log.d("JJJ", "Created thread handler and capture session")
        }
    }

    override fun onDisconnected(camera: CameraDevice?) {
        Log.d("JJJ", "on disconnected")
    }

    override fun onError(camera: CameraDevice?, error: Int) {
        Log.d("JJJ", "on error")
    }
}



 var  cameraCaptureSessionCallBack = object :  CameraCaptureSession.StateCallback(){

    override fun onConfigureFailed(session: CameraCaptureSession?) {
        Log.d("JJJ", "on configured failed")
    }

    override fun onConfigured(session: CameraCaptureSession?) {
        Log.d("JJJ", "start recording")
        mediaRecorder.start()

    }
}


    private fun setMediaOutputSurface(): Surface {
          var file = File(context.filesDir.absolutePath)
        if(file.canWrite() && file.canRead()){
            Log.d("JJJ", "File location is fine")
        }

        mediaRecorder = MediaRecorder()
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE) //changed this to surface from camera and it fixed the cant get surface error

        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
        mediaRecorder.setVideoSize(600,600)


//        mediaRecorder.setVideoEncodingBitRate(10000000)
//        mediaRecorder.setVideoEncodingBitRate(512 * 1000)
        mediaRecorder.setOutputFile(context.filesDir.absolutePath + "/"+System.currentTimeMillis() + ".mp4")
        mediaRecorder.setVideoFrameRate(30)

        mediaRecorder.prepare()
//        mediaRecorder.start()
        return mediaRecorder.surface

}

This is my strategy

  1. Get list of Camera ID's using the camera manager.
  2. Open the first camera from the list(there is only one camera attached
  3. when opened successfully, create handler thread
  4. Create mediaRecorder with all the necessary parameters(video source, framerate etc
  5. Get the surface object from the mediaRecorder(where it fails)
  6. Create capture request with the surface from the media player and the hanlder created previously
  7. on configured successfully, call mediaRecorder.start to start recording video.

The full stacktrace error i get is below:

  12-01 09:58:23.981 8776-8776/com.jr.survailancedropboxcam W/CameraDevice-JV-0: Stream configuration failed due to: endConfigure:372: Camera 0: Unsupported set of inputs/outputs provided
12-01 09:58:23.985 8776-8958/com.jr.survailancedropboxcam D/JJJ: on configured failed
12-01 09:58:23.985 8776-8776/com.jr.survailancedropboxcam E/CameraCaptureSession: Session 0: Failed to create capture session; configuration failed

Thanks in advance

Mastigophoran answered 30/11, 2017 at 21:34 Comment(3)
Any update on this? I'm struggling tooQuadruped
Not working stil. anyone have any suggestions?Mastigophoran
I realized its an issue specific to raspberry pi. If you look at the release notes for android things developer.android.com/things/preview/releases.html, under known issues for raspberry pi there is: "Camera: A new CameraCaptureSession cannot be created with more than one target output surface.". Which I believe is preventing us from accomplishing us from what we need to do. I think the solution is to buy a different boardQuadruped
R
3

With the latest release (AndroidThings DP 6) you can use the Camera v2 APIs

https://android-developers.googleblog.com/2017/11/android-things-developer-preview-6.html

This should work: https://github.com/googlesamples/android-Camera2Basic

You need to make sure you have the flag set to true in the manifest

<activity

    ...
    android:hardwareAccelerated="true">

the Camera2Basic sample using the Camera2 API and TextureView now works on both NXP and Raspberry Pi based devices (with the hardwareAccelerated flag set to true)

Rothko answered 1/12, 2017 at 8:44 Comment(5)
Wow that's great. That only got released yesterday as well. I'll give it a goMastigophoran
I updated my code and android things build and get a different error now. i will amend my Original post. It now fails when i try to createCaptureSession by calling onConfiguredFailed on the callbackMastigophoran
Nope. Does not work. Do you get the same error as me?Mastigophoran
@jonney, is it working for you? Is there any other solution?Autocorrelation
Nope doesnt work. fustrating! Are you having the same issue?Mastigophoran

© 2022 - 2024 — McMap. All rights reserved.