2012-10-02 11 views
5

Sto scrivendo un'app per fotocamere e sto avendo un problema con l'S3. Ogni volta che inizio a registrare, il display va in spazzatura (vedi screenshot sotto). Poi, quando mi fermo registrazione ottengo un'eccezione:La visualizzazione video è confusa durante la registrazione su 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) 

ho testato la mia app sul Galaxy Nexus (4.1), Galaxy S2, Nexus S e Galaxy Tab 10.1. Tutti funzionano bene. Ho seguito development guidelines for video recording. Non capisco perché questo dispositivo sia così diverso dagli altri. Ecco cosa vedo sul dispositivo. La prima immagine è prima che inizi la registrazione. La seconda immagine è ciò che accade una volta che inizio la registrazione.

Before I've started recording

After I start recording

Ecco il mio codice per la preparazione e l'avvio l'oggetto 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(); 
    } 
} 

Edit: Quindi questo ha qualcosa a che fare con la CamcorderProfile fase di impostazione. Lo cambio in CamcorderProfile.QUALITY_LOW e ha funzionato bene. Quindi, come posso avere un video ad alta risoluzione senza output confuso?

Edit2: Così con CamcorderProfile.QUALITY_LOW impostato, non ottengo errori utilizzando il videoregistratore. Tuttavia, il video di output sembra molto simile allo screenshot confuso pubblicato sopra. Quindi cosa dà?

+3

venderlo come iOS6-map-come fotocamera app – axis

+1

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

+0

@JasonRobinson Perché hanno chiuso il bug report? Avrei potuto almeno indicarti un'altra direzione o qualcosa del genere. È solo pigro. – ShadowScripter

risposta

10

Ho avuto un problema simile, e alla fine ho capito che era dovuto alla condivisione della superficie di anteprima tra la fotocamera e il registratore multimediale (non sono sicuro che questa sia la causa sottostante, ma dalle chiamate API sembra che modo).

sto supponendo che avete già aperto la macchina fotografica e allegato un display di anteprima ad esso, se quindi cercate di inserire le seguenti righe nella parte superiore del tuo metodo prepareRecorder:

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

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

Potrebbe anche essere necessario riassegnare la telecamera locale al campo nascosto dietro getCamera(), sfortunatamente non posso dire come l'hai implementata con lo snippet di codice specificato.

Spero che questo aiuti.

+0

Fantastico! Funziona alla grande su Huawei U8800 con ICS personalizzato. –

+0

Ha funzionato per me su Galaxy S3. Grazie! –

+0

Risparmio di vita. Grazie! –

1

Ho avuto un problema simile con una nota Samsung. Il mio problema era che l'anteprima era impostata in una risoluzione, e la registrazione era impostata su un'altra risoluzione più grande (risoluzione che non era supportata dal mio telefono), ed è per questo che sembrava così. Si dovrebbe provare:

recorder.setVideoSize(320, 240);

Se funziona, allora significa la risoluzione iniziale non è stata sostenuta/

0

Questo perché risoluzioni risoluzione di anteprima e Mediarecorder sono diversi (e possono essere diversi a seconda della dispositivo, ma su alcuni dispositivi sembra causare un problema).

Controllare l'app per fotocamera Android, non interrompe l'anteprima e quindi avvia la registrazione (è possibile controllare tenendo il flash acceso, se si interrompe l'anteprima e quindi si avvia la registrazione, il flash si spegne e quindi si riaccende, mentre nell'app Fotocamera Android ciò non accade).

La risposta "accettata" qui funziona solo perché la fotocamera rilascia la superficie di anteprima e il mediarecorder può quindi regolare la risoluzione su una delle risoluzioni del mediarecorder, ma non è tecnicamente corretto.

+0

Ulteriori approfondimenti su questo argomento rendono l'intera questione più complessa. Non è solo una corrispondenza di risoluzione, ma a livello di driver alcune risoluzioni di anteprima non sembrano onorare correttamente quello che sembra essere lo stesso aspetto o il livello di zoom della stessa risoluzione di registrazione. Ciò può comportare una regolazione della distorsione o il cambiamento apparente del "livello di zoom" quando si preme la registrazione. Fermare l'anteprima come suggerito da Stuart Ervine funziona, ma io continuo a pensare che sia un lavoro piuttosto che una soluzione adeguata. – modernPrimitive

+0

È bello vedere il vero motivo per cui questo è scoperto ... hai un esempio di codice di una soluzione adeguata? Sarebbe bello non dover fermare e avviare la fotocamera! –