2012-10-02 21 views
5

Estoy escribiendo una aplicación de cámara y estoy teniendo un problema con el S3. Cada vez que comienzo a grabar, la pantalla se va a la basura (ver capturas de pantalla a continuación). Entonces, cuando deje de grabar me sale una excepción:La visualización de video está distorsionada al grabar en Galaxy S3

10-02 13:36:31.647: E/MediaRecorder(24283): stop failed: -1007 
10-02 13:36:31.647: D/AndroidRuntime(24283): Shutting down VM 
10-02 13:36:31.647: W/dalvikvm(24283): threadid=1: thread exiting with uncaught exception (group=0x40c49a68) 
10-02 13:36:31.647: E/AndroidRuntime(24283): FATAL EXCEPTION: main 
10-02 13:36:31.647: E/AndroidRuntime(24283): java.lang.RuntimeException: stop failed. 
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.media.MediaRecorder.native_stop(Native Method) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.media.MediaRecorder.stop(MediaRecorder.java:742) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.myapp.android.ui.camera.NewCameraActivity.stopRecording(NewCameraActivity.java:178) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.myapp.android.ui.camera.NewCameraActivity.toggleRecording(NewCameraActivity.java:189) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.myapp.android.ui.camera.NewCameraActivity.onClick(NewCameraActivity.java:97) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.view.View.performClick(View.java:3565) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.view.View$PerformClick.run(View.java:14165) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.os.Handler.handleCallback(Handler.java:605) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.os.Handler.dispatchMessage(Handler.java:92) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.os.Looper.loop(Looper.java:137) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at android.app.ActivityThread.main(ActivityThread.java:4514) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at java.lang.reflect.Method.invokeNative(Native Method) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at java.lang.reflect.Method.invoke(Method.java:511) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747) 
10-02 13:36:31.647: E/AndroidRuntime(24283): at dalvik.system.NativeStart.main(Native Method) 

He probado mi aplicación en el Galaxy Nexus (4.1), Galaxy S2, Nexus S y Galaxy Tab 10.1. Todos ellos funcionan bien. Seguí development guidelines for video recording. No entiendo por qué este dispositivo es tan diferente de los demás. Esto es lo que estoy viendo en el dispositivo. La primera imagen es antes de comenzar a grabar. La segunda imagen es lo que sucede una vez que comienzo a grabar.

Before I've started recording

After I start recording

Aquí está mi código para preparar y poner en marcha el objeto MediaRecorder:

@Override 
public void onClick(View v) { 

    switch (v.getId()) { 
     case R.id.camera_action_ImageView: 
      int mode = getMode(); 
      if (mode == MODE_PHOTO) { 
       focusThenTakePicture(); 
      } 
      else if (mode == MODE_VIDEO) { 
       toggleRecording(); 
      } 
      break; 
    } 
} 

private void startRecording() { 

    if (prepareRecorder()) { 
     getRecorder().start(); 
     setRecording(true); 
    } 
} 

@TargetApi(9) 
private boolean prepareRecorder() { 

    Camera camera = getCamera(); 
    camera.unlock(); 

    MediaRecorder recorder = new MediaRecorder(); 
    setRecorder(recorder); 
    recorder.setCamera(camera); 
    recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 

    CamcorderProfile profile; 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) { 
     profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH); 
    } 
    else { 
     profile = CamcorderProfile.get(getCameraId(), CamcorderProfile.QUALITY_HIGH); 
    } 
    recorder.setProfile(profile); 

    File outputFile = LocalMediaUtil.getOutputMediaFile(LocalMediaUtil.MEDIA_TYPE_VIDEO); 
    setRecorderOutputFile(outputFile); 
    recorder.setOutputFile(outputFile.toString()); 
    recorder.setPreviewDisplay(getPreview().getHolder().getSurface()); 

    try { 
     recorder.prepare(); 
    } 
    catch (Exception e) { 
     camera.lock(); 
     setRecorder(null); 
     return false; 
    } 

    return true; 
} 

private void stopRecording() { 

    MediaRecorder recorder = getRecorder(); 
    recorder.stop(); 
    releaseRecorder(); 
    setRecording(false); 

    LocalMediaUtil.scanMedia(this, getRecorderOutputFile().toString(), 90); 
    setRecorderOutputFile(null); 
} 

private void toggleRecording() { 

    if (isRecording()) { 
     stopRecording(); 
    } 
    else { 
     startRecording(); 
    } 
} 

private void releaseRecorder() { 

    MediaRecorder recorder = getRecorder(); 
    if (recorder != null) { 

     recorder.reset(); 
     recorder.release(); 
     setRecorder(null); 

     getCamera().lock(); 
    } 
} 

Editar: Así que esto tiene algo que ver con que se establezca el CamcorderProfile. Lo cambio a CamcorderProfile.QUALITY_LOW y funcionó bien. Entonces, ¿cómo puedo tener video de alta resolución sin una salida distorsionada?

Edit2: Así que con CamcorderProfile.QUALITY_LOW conjunto, no consigo ningún error al utilizar la grabadora de video. Sin embargo, el video de salida se ve muy similar a la captura de pantalla ilegible publicada anteriormente. Entonces, ¿qué da?

+3

venderlo como iOS6-mapa-como aplicación de la cámara – axis

+1

Google informe de error: http://code.google.com/p/android/issues/detail?id=38139&thanks=38139&ts=1349306102 –

+0

@JasonRobinson ¿Por qué cerraron el informe de error? Podría al menos apuntar en otra dirección o algo así. Eso es perezoso. – ShadowScripter

Respuesta

10

Tuve un problema similar, y finalmente descubrí que se debía a compartir la superficie de vista previa entre la cámara y el grabador de medios (no estoy seguro de que esta sea la causa subyacente, pero de las llamadas API parece que camino).

Estoy asumiendo que ya ha abierto la cámara y se adjunta una pantalla de vista previa para que, si a fin de tratar de insertar las siguientes líneas en la parte superior de su método de prepareRecorder:

Camera camera = getCamera(); 
camera.stopPreview(); 
camera.lock(); 
camera.release(); 

camera = Camera.open(); 
camera.unlock(); 

También podría ser necesario reasignar la cámara local en el campo oculto detrás de getCamera(), desafortunadamente no puedo decir cómo lo has implementado con el fragmento de código dado.

Espero que esto ayude.

+0

¡Impresionante! Funciona muy bien en Huawei U8800 con ICS personalizado. –

+0

Funcionó para mí en Galaxy S3. ¡Gracias! –

+0

Ahorrador de vida. ¡Gracias! –

1

Tuve un problema similar con una Samsung Note. Mi problema era que la vista previa estaba configurada en una resolución, y la grabación estaba configurada en otra resolución más grande (resolución que no era compatible con mi teléfono), y esta es la razón por la que se veía así. Usted debe tratar:

recorder.setVideoSize(320, 240);

Si funciona, entonces significa que su resolución inicial no fue apoyada/

0

Esto se debe a la resolución de vista previa y MediaRecorder resoluciones son diferentes (y que pueden ser diferentes en función de la dispositivo, pero en algunos dispositivos parece causar un problema).

Compruebe la aplicación de la cámara Android, no detiene la vista previa y luego comience a grabar (puede comprobar esto manteniendo el flash encendido, si detiene la vista previa y luego comienza a grabar, el flash se apagará y volverá a encenderse, mientras que en la aplicación de la cámara de Android eso no sucede).

La respuesta "aceptada" aquí solo funciona porque la cámara libera la superficie de vista previa y la grabadora de medios puede entonces ajustar la resolución a una de las resoluciones de la grabadora de medios, pero no es técnicamente correcta.

+0

La investigación adicional de este tema hace que todo el asunto sea más complejo. No es solo una coincidencia de resolución, pero en el nivel del controlador, ciertas resoluciones de vista previa no parecen honrar adecuadamente lo que parece ser el mismo aspecto o nivel de zoom que la misma resolución de grabación. Esto puede provocar un ajuste de la distorsión o un cambio aparente de "nivel de zoom" al presionar grabar. Detener la vista previa como lo sugirió Stuart Ervine funciona, pero todavía creo que es una solución alternativa en lugar de la adecuada. – modernPrimitive

+0

Genial para ver la verdadera razón por la que esto ocurre sin cobertura ... ¿tiene un ejemplo de código de una solución adecuada? ¡Sería genial no tener que parar y encender la cámara! –

Cuestiones relacionadas