某些设备上MediaRecorder启动失败(启动失败:-2147483648和-19)

4
我已经阅读了有关MediaRecorder并按照Android上的指南操作的所有内容。
至少在API 8及更高版本中,它应该能够正常工作,但我的最低SDK是14,所以它应该会更好。
在我的设备Samsung Galaxy S3 Mini上,它可以正常工作。一些其他使用Ice Cream Sandwitch的设备也可以,但是有些设备不行。它们会崩溃:
mediaRecorder.start()

我创建了一个用于记录视频的服务,这是我的代码(每个阶段的操作指南):
    @Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {

    //OPEN CAMERA
    int ncamara=0;
    qcamara=0;
    if(android.os.Build.VERSION.SDK_INT<9)
        camera = Camera.open();                                       
    else{
    try {
        ncamara = Camera.getNumberOfCameras();
        if (f.leer("camara", context).equals("frontal"))
            qcamara=10;
        else qcamara=20;
    } catch (Exception e) {}
    if (ncamara>=2 && qcamara == 10)
        camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
    else if (ncamara>=2 && qcamara == 20)
        camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
    else
        camera = Camera.open();
    }
                                                                        //
    try {
        camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    //UNLOCK CAMERA
    camera.unlock();    
    mediaRecorder = new MediaRecorder();

    mediaRecorder.setCamera(camera);                                    //setCamera
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

                                                                        //setProfile
    if (f.leer("calidad", context).equals("alta") && qcamara !=10)
        mediaRecorder.setProfile(CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH));
    else if (f.leer("calidad", context).equals("alta") && qcamara == 10)
        mediaRecorder.setProfile(CamcorderProfile.get(1, CamcorderProfile.QUALITY_LOW));
    else if (f.leer("calidad", context).equals("baja") && qcamara != 10)
    mediaRecorder.setProfile(CamcorderProfile.get(0, CamcorderProfile.QUALITY_LOW));
    else
        mediaRecorder.setProfile(CamcorderProfile.get(1, CamcorderProfile.QUALITY_LOW));

    mediaRecorder.setVideoSize(320, 240);   

    if (CameraRecorder.duracion>0)                                      // -- duration
    mediaRecorder.setMaxDuration(CameraRecorder.duracion * 1000);


    File dataDirectory = Environment.getExternalStorageDirectory();
    File fileDir = new File(dataDirectory, "/weddingR/");
    fileDir.mkdirs();
    mediaRecorder.setOutputFile(                                        //setOutputFile
            Environment.getExternalStorageDirectory()+"/weddingR/"+
            DateFormat.format("yyyy-MM-dd---kk-mm-ss", new Date().getTime())+
            ".mp4"
    );
    mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());  
    if (qcamara==10){ // FRONT CAMERA
        try { mediaRecorder.setOrientationHint(270); } catch (Exception e) {}
    } else { // BACK CAMERA
        try { mediaRecorder.setOrientationHint(90); } catch (Exception e) {}
    }
    try { 
        mediaRecorder.prepare();
        } catch (Exception e) {}
    mediaRecorder.setOnInfoListener(new OnInfoListener(){

        @Override
        public void onInfo(MediaRecorder mr, int what, int extra) {
            Log.d("INFO_ON", what + " " + extra + " ");
            nascosto=true;
            stopSelf();
        }
    });

    mediaRecorder.start();
}

如果我设置mediaRecorder.setVideoFrameRate(20),例如,在每个设备上都会崩溃。
我最想知道的是,在某些设备上之前工作正常,但在其他设备上不行(例如,API 17或18的模拟器可以工作...带有API 15的设备可以工作,但API 15的模拟器无法工作...)
我做错了什么??
提前致谢。

ANDROID清单权限

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

编辑

在@Melquiades的回答之后,我修改了我的代码,现在捕获异常并且没有任何异常被捕获。

另外,我想指出一些有趣的事情:我正在尝试使用API15模拟器,结果如下:

  1. 当我设置mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());(在mediaRecorder.setOutputFile()之后),我得到START FAILED -19
  2. 当我不设置它时,我得到START FAILED -2147483648

但是在我的三星手机上仍然可以正常工作...


新编辑(2014年1月1日)新年快乐!

我在三星 Galaxy S2 Plus(Android 4.1.2)上尝试了一下,但它不起作用,但在我的三星 Galaxy S3 Mini上它可以工作(也是 Android 4.1.2)......我正在变得疯狂。


在执行 camera.setPreviewDisplay(surfaceHolder) 前,您应该先解锁相机。 然后再执行 camera.startPreview()。 - Auto-Droid ツ
在你的回答之后,我在StackOverflow上阅读了一些内容,建议在调用surfaceChanged()时设置camera.setPreviewDisplay(surfaceHolder);camera.startPreview();。我已经这样做了,但仍然出现错误。 - Rafael Ruiz Muñoz
1个回答

0

当调用mediaRecorder.prepare()时,您没有处理捕获的异常:

try { 
    mediaRecorder.prepare();
} catch (Exception e) { //empty??? }

不要这样做,这是一种不好的做法。如果有任何异常,您都将不知道它。

在 prepare() 中的 {} 内放置 Log.d() 并查看正在发生的情况。对于所有捕获到的异常都要这样做。

根据该指南:

// Step 6: Prepare configured MediaRecorder
try {
    mMediaRecorder.prepare();
} catch (IllegalStateException e) {
    Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
    releaseMediaRecorder();
    return false;
} catch (IOException e) {
    Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
    releaseMediaRecorder();
    return false;
}

嗨,感谢您的回答。我不习惯做那种不好的实践,但还是感谢您提醒我。我正在捕获异常,而且没有异常。它只是崩溃了。我正在编辑我的编辑器,这样您就可以知道如果我修改一些参数会发生什么。 - Rafael Ruiz Muñoz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接