Search code examples
androidandroid-intentvideo-capture

Android - taking video error -22


I've been trying to take videos with the com.android.hardware.Camerapackage.

It seems that the MediaRecorder fail to start. I want to take videos through an Intent Service (without previewing the output on the screen). Here's my Intent mains functions.

private     MediaRecorder   mMediaRecorder;
private     Camera          cam = null;
public static boolean       isRecording = false;
public static boolean       isRunning = false;

public void onCreate() {
    cam = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
    try {
        cam.unlock();
        mMediaRecorder.setCamera(cam);
        cam.lock();
    } catch (Exception e){
        e.fillInStackTrace();
    }
    isRunning = true;
    // Step 2: Set sources
    mMediaRecorder = new MediaRecorder();
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
    // Step 4: Set output file
    String fileName = "/sdcard/" + RandomNameGenerator.setSecureFilename(".video");
    mMediaRecorder.setOutputFile(fileName);
    // Step 6: Prepare configured MediaRecorder
    try {
        mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d("DEBUG", "IllegalStateException preparing MediaRecorder: " + e.getMessage());
    } catch (IOException e) {
        Log.d("DEBUG", "IOException preparing MediaRecorder: " + e.getMessage());
    }
    isRecording = true;
    Log.d("SERVICE VIDEO", "IS RECORDING");
    try {
        mMediaRecorder.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void onDestroy(){
    isRecording = false;
    if (mMediaRecorder != null) {
        mMediaRecorder.reset();   // clear recorder configuration
        mMediaRecorder.release(); // release the recorder object
        mMediaRecorder = null;
        isRunning = false;
    }
}

And here's the logs when I start the intent:

E/MediaRecorder: start failed: -22
W/System.err: java.lang.RuntimeException: start failed.
W/System.err:     at android.media.MediaRecorder.start(Native Method)
W/System.err:     at com.example.nathan.def_calc.VideoRecorder.onCreate(VideoRecorder.java:61)
W/System.err:     at android.app.ActivityThread.handleCreateService(ActivityThread.java:3192)
W/System.err:     at android.app.ActivityThread.-wrap5(ActivityThread.java)
W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1568)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err:     at android.os.Looper.loop(Looper.java:154)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6121)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)

All the necessary permissions are set in the manifest. Do I have to declare a kind of buffer somewhere ? I didn't find any documentation in the API about how we create a video buffer. Does anyone have a solution ?


Solution

  • Ok, I resolve the issue, the obvious problem was that I didn't have any buffer for the video. I found that I needed a Surfacewhich correspond to the buffer for the Camera object. adding in onCreate():

    sft = new SurfaceTexture(0);
    sf = new Surface(sft);
    mMediaRecorder.setPreviewDisplay(sf);
    

    and

    sf.release();
    sft.release();
    

    in the onDestroy() function made the trick.