2013-01-03 28 views
26

Sto tentando di consentire agli utenti di registrare video di dimensioni diverse rispetto all'anteprima sullo schermo che possono vedere durante la registrazione. Questo sembra essere possibile dal this documentation concerning the getSupportedVideoSizes function in cui si afferma:Registrare video con dimensioni di anteprima diverse rispetto al file video risultante

Se l'elenco restituito non è nullo, l'elenco restituito conterrà al almeno una dimensione e una delle dimensioni della lista deve essere restituito passato al MediaRecorder. setVideoSize() per l'applicazione videocamera se la videocamera viene utilizzata come sorgente video. In questo caso, la dimensione dell'anteprima può essere diversa dalla risoluzione del video registrato durante la registrazione video.

Questo suggerisce che alcuni telefoni torneranno nulla da questa fn (nella mia esperienza il Galaxy SIII fa), ma per coloro che non lo fanno, è possibile fornire un'anteprima con una risoluzione diversa rispetto al video vero e proprio. Questa comprensione è corretta? Alcuni telefoni consentono il comportamento e altri no?

Un tentativo di soluzione:

Nella funzione official description of the setPreviewDisplay, che viene utilizzato nella lengthy process of setting up for video recording, si afferma che:

Se questo metodo viene chiamato con superficie null o non chiamato affatto , media , il registratore non cambia la superficie di anteprima della telecamera.

Questo sembra essere quello che voglio, ma sfortunatamente se lo faccio, l'intero processo di registrazione video è completamente incasinato. Suppongo che questa funzione non possa essere superata o non richiamata affatto durante il processo di registrazione del video. Forse in altri contesti questo va bene. Sfortunatamente, questo non sembra aiutarmi.

I miei passaggi successivi sono di esaminare TextureView s e utilizzare un'anteprima Texture in contrasto con un'implementazione tipica di SurfaceView per utilizzare openGL per estendere la trama alla dimensione desiderata diversa dalla risoluzione effettiva (e ritagliare qualsiasi eccesso sullo schermo), quindi su Costruisci una superficie per la funzione setPreviewDisplay con il costruttore Surface(SurfaceTexture surfaceTexture) per una superficie. Vorrei evitare l'uso di un TextureView a causa di incompatibilità sotto ICS, e anche perché questo aggiunge una notevole complessità.

Questo sembra un processo delicato, ma spero che qualcuno possa offrire qualche consiglio in questo settore.

Grazie.

+0

Potete chiarire cosa significa "completamente incasinato"? –

+0

Se ricordo correttamente, significava che la superficie di anteprima diventava nera e nulla è stato registrato. –

risposta

1

a.Assume l'utente imposta la dimensione di x, y il video formato

b.Now con funzione getSupportedVideoSizes ottenere l'intero elenco e vedere se x, y cade in uno di essi e impostare la MediaRecorder.setVideoSize(). Se x, y non rientra nell'elenco getSupportedVideoSizes, quindi imposta il profilo predefinito per il record video.

Questo è circa la dimensione del video

Ora venendo al formato anteprima, non le opzioni di soluzione molto. Prendere un RelativeLayout che contiene SurfaceView.

<android.view.SurfaceView xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/preview" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
/> 

anteprima è il nome di SurfaceView. Qui ho dato un campione di ridimensionamento a metà della larghezza e dell'altezza.

resetCamera(); //reset the camera 

ViewGroup.LayoutParams params = preview.getLayoutParams(); 
RelativeLayout myRelLayout = (RelativeLayout) findViewById(R.id.myRelLayout); 
params.width = (int) (myRelLayout.getWidth()/2); 
params.height = (int)(myRelLayout.getHeight()/2); 
preview.setLayoutParams(params); 

initCamera(); //initiate the camera(open camera, set parameter, setPreviewDisplay,startPreview) 

Si prega di guardare la risoluzione dell'anteprima e quindi ridimensionare l'altezza o la larghezza di conseguenza in base alla dimensione del video.

Spero che aiuti.

1

Come accennato, questo è possibile solo quando getSupportedVideoSizes() restituisce un elenco non nullo.

Ma se si fa vedere una lista non nullo, allora questo approccio semplice dovrebbe funzionare:

  1. Impostare la risoluzione di anteprima desiderata con setPreviewSize; la dimensione selezionata deve essere una delle dimensioni indicate da getSupportedPreviewSizes.

  2. Impostare la visualizzazione dell'anteprima su SurfaceView o SurfaceTexture con setPreviewDisplay o setPreviewTexture, rispettivamente.

  3. Avvia anteprima.

  4. Creare il registratore di media, e impostare la sua dimensione del video sia direttamente con setVideoSize utilizzando uno dei formati da getSupportedVideoSizes, o utilizzare uno dei predefiniti Camcorder profiles per configurare tutte le impostazioni del registratore di media per una qualità data/dimensione.

  5. Passare l'oggetto della telecamera alla chiamata setCamera di MediaRecorder, configurare il resto del registratore multimediale e avviare la registrazione.

Sui dispositivi con un elenco getSupportedVideoSizes non nullo, questo dovrebbe tradursi in anteprima presso la risoluzione impostata per la chiamata setPreviewSize, con registrazione operante alla risoluzione profilo dimensioni videoregistratore/videocamera. Sui dispositivi senza dimensioni video supportate, la dimensione dell'anteprima verrà reimpostata dal MediaRecorder in modo che corrisponda alle dimensioni della registrazione. Dovresti essere in grado di testare questo impostando una risoluzione di anteprima molto bassa e una risoluzione di registrazione elevata (ad esempio, 160x120 per l'anteprima, 720p per la registrazione). Dovrebbe essere ovvio se MediaRecorder cambia la risoluzione di anteprima a 720p all'avvio della registrazione, poiché la qualità dell'anteprima salterà in modo sostanziale.

Si noti che la dimensione dell'anteprima non è direttamente collegata alle dimensioni del display SurfaceView; l'output dell'anteprima della fotocamera verrà ridimensionato per adattarsi a SurfaceView, quindi se le dimensioni di SurfaceView sono, ad esempio, 100x100 pixel a causa del layout e del dispositivo, qualunque sia la risoluzione di anteprima utilizzata verrà ridimensionata a 100x100 per la visualizzazione. Quindi è ancora necessario assicurarsi di mantenere corrette le proporzioni di SurfaceView in modo che l'anteprima non sia distorta.

E per l'efficienza energetica, non è necessario utilizzare una risoluzione di anteprima molto più elevata rispetto al numero effettivo di pixel in SurfaceView, poiché la risoluzione aggiuntiva andrà persa nel montaggio dell'anteprima nella vista superficiale. Questo è ovviamente possibile solo per la registrazione quando getSupportedVideoSizes() restituisce un valore non nullo.

+0

Proverò a provarlo al più presto, ma sono attualmente nel bel mezzo di un sacco di revisione del codice e non voglio rovinare troppe cose. Questo sembra molto promettente (anche se frustrante se 'getSupportedVideoSizes' è nullo come spesso sembra essere. –

0

In primo luogo, proverò a rispondere alle vostre domande specifiche.

  1. è possibile fornire un'anteprima con una risoluzione diversa rispetto al video effettivo. Questa comprensione è corretta?

Sì, la dimensione dell'anteprima è più spesso diversa da quella della registrazione. Le dimensioni dell'anteprima sono più spesso collegate alle dimensioni del display. Pertanto, se un telefono è dotato di display CIF (352 x 288), ma è in grado di registrare D1 (720 x 480), le dimensioni dell'anteprima e le dimensioni della registrazione saranno diverse. Sento che altri esperti hanno risposto a sufficienza su questo punto.

  1. Alcuni telefoni consentono il comportamento e altri no?

La maggior parte degli ultimi telefoni supporta questa funzione tranne forse alcuni di fascia bassa.

Insieme setPreviewDisplay, dobbiamo considerare questo punto anche:

L'unica eccezione è che se la superficie di anteprima non è impostato (o impostato a zero) prima startPreview() viene chiamato, questo metodo può essere chiamato una volta con un parametro non nullo per impostare la superficie di anteprima. (Ciò consente che l'impostazione della fotocamera e la creazione della superficie avvengano in parallelo, risparmiando tempo.) La superficie di anteprima potrebbe non cambiare in caso di esecuzione dell'anteprima.

Potrebbe per favore condividere il problema che deve affrontare quando setPreviewDisplay viene richiamato con una superficie NULL?

Problemi correlati