android videos Grabe video con un tamaño de vista previa diferente al archivo de video resultante



youtube google videos (3)

Estoy intentando permitir que los usuarios graben videos de un tamaño diferente al de la vista previa en pantalla real que pueden ver mientras graban. Esto parece ser posible a partir de esta documentación relativa a la función getSupportedVideoSizes que establece:

Si la lista devuelta no es nula, la lista devuelta contendrá al menos un tamaño y uno de los tamaños en la lista devuelta debe pasarse a MediaRecorder.setVideoSize () para la aplicación de la videocámara si la cámara se utiliza como fuente de video. En este caso, el tamaño de la vista previa puede ser diferente de la resolución del video grabado durante la grabación de video.

Esto sugiere que algunos teléfonos regresarán nulos de este fn (en mi experiencia, el Galaxy SIII lo hace), pero para aquellos que no lo hacen, es posible proporcionar una vista previa con una resolución diferente a la del video real. ¿Es correcto este entendimiento? ¿Algunos teléfonos permiten el comportamiento y otros no?

Intentando una solución:

En la descripción oficial de la función setPreviewDisplay , que se usa en el largo proceso de configuración para la grabación de video , se menciona que:

Si se llama a este método con una superficie nula o no se llama en absoluto, la grabadora de medios no cambiará la superficie de vista previa de la cámara.

Esto parece ser lo que quiero, pero desafortunadamente si hago esto, todo el proceso de grabación de video está completamente desordenado. Estoy asumiendo que esta función no se puede pasar nula o no se puede llamar en absoluto en el proceso de grabación de video. Quizás en otros contextos esto está bien. Lamentablemente, sin embargo, esto no parece ayudarme.

Mis únicos pasos siguientes son mirar TextureView y usar una textura de vista previa en lugar de una implementación típica de SurfaceView para usar openGL para extender la textura a mi tamaño deseado que difiere de la resolución real (y recortar cualquier exceso de la pantalla) ), y luego a Construir una superficie para la función setPreviewDisplay con el constructor Surface(SurfaceTexture surfaceTexture) para una Surface. Me gustaría evitar el uso de un TextureView debido a la incompatibilidad por debajo de ICS, y también porque esto agrega una complejidad significativa.

Esto parece un proceso delicado, pero espero que alguien pueda ofrecer algún consejo en esta área.

Gracias.


a. Supongamos que el usuario establece el tamaño de x, y como tamaño de video

b. Ahora, con la función getSupportedVideoSizes, obtenga la lista completa y vea si x, y cae en uno de ellos y configure MediaRecorder.setVideoSize (). Si x, y no se encuentra en la lista getSupportedVideoSizes, configure el perfil predeterminado para el video grabar.

Esto es sobre el tamaño del video

Ahora llegando al tamaño de vista previa, no hay muchas opciones de solución. Toma un RelativeLayout que contiene el 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"
 />

Vista previa es el nombre de SurfaceView. Aquí he dado una muestra de redimensionarlo a la mitad del ancho y la altura.

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)

Mire la resolución de la vista previa y luego reduzca la altura o el ancho según el tamaño del video.

Espero eso ayude.


Como mencionó, esto solo es posible cuando getSupportedVideoSizes () devuelve una lista no nula.

Pero si ve una lista que no sea nula, entonces este enfoque simple debería funcionar:

  1. Establezca la resolución de vista previa deseada con setPreviewSize ; el tamaño que seleccione debe ser uno de los tamaños dados desde getSupportedPreviewSizes .

  2. Establezca la vista previa en su SurfaceView o SurfaceTexture con setPreviewDisplay o setPreviewTexture , respectivamente.

  3. Iniciar vista previa.

  4. Cree la grabadora de medios y configure su tamaño de video directamente con setVideoSize usando uno de los tamaños de getSupportedVideoSizes , o use uno de los perfiles de Camcorder predefinidos para configurar todos los ajustes de la grabadora de medios para una calidad / tamaño dados.

  5. Pase el objeto de la cámara a la llamada setCamera de setCamera , configure el resto de la grabadora de medios y comience a grabar.

En los dispositivos con una lista no nula de getSupportedVideoSizes, esto debería dar como resultado que la vista previa permanezca en la resolución establecida por su llamada setPreviewSize, con la grabación operando a la resolución de perfil de video / tamaño de video establecida. En dispositivos sin tamaños de video compatibles, el tamaño de la vista previa será restablecido por el MediaRecorder para que coincida con el tamaño de grabación. Debería poder probar esto configurando una resolución de vista previa muy baja y una resolución de grabación alta (por ejemplo, 160x120 para vista previa, 720p para grabación). Debería ser obvio si el MediaRecorder cambia la resolución de la vista previa a 720p cuando comienza la grabación, ya que la calidad de la vista previa saltará sustancialmente.

Tenga en cuenta que el tamaño de la vista previa no está directamente vinculado a las dimensiones de la pantalla SurfaceView; la salida de la vista previa de la cámara se escalará para que se ajuste a SurfaceView, de modo que si las dimensiones de su SurfaceView son, digamos 100x100 píxeles debido a su diseño y dispositivo, cualquiera que sea la resolución de vista previa que utilice, se escalará a 100x100 para su visualización. Por lo tanto, aún debe asegurarse de mantener la relación de aspecto de SurfaceView correcta para que la vista previa no se distorsione.

Y para una mayor eficiencia energética, no debe usar una resolución de vista previa mucho mayor que la cantidad real de píxeles en su SurfaceView, ya que la resolución adicional se perderá al ajustar la vista previa en la vista de superficie. Por supuesto, esto solo es posible para la grabación cuando getSupportedVideoSizes () devuelve un valor no nulo.


Primero, trataré de responder a sus preguntas específicas.

  1. es posible proporcionar una vista previa con una resolución diferente a la del video real. ¿Es correcto este entendimiento?

Sí, el tamaño de la vista previa es a menudo diferente del tamaño de grabación. El tamaño de la vista previa suele estar vinculado a su tamaño de visualización. Entonces, si un teléfono tiene una pantalla de CIF (352 x 288), pero es capaz de grabar D1 (720 x 480), entonces el tamaño de la vista previa y el tamaño de la grabación serán diferentes. Siento que otros expertos han respondido suficientemente sobre este punto.

  1. ¿Algunos teléfonos permiten el comportamiento y otros no?

La mayoría de los teléfonos más recientes son compatibles con esta función, excepto quizás algunos de gama baja.

Junto con setPreviewDisplay , tenemos que considerar este punto también:

La única excepción es que si la superficie de vista previa no se establece (o se establece en nulo) antes de llamar a startPreview (), entonces se puede llamar a este método una vez con un parámetro no nulo para establecer la superficie de vista previa. (Esto permite que la configuración de la cámara y la creación de la superficie se realicen en paralelo, ahorrando tiempo). La superficie de la vista previa no puede cambiar mientras se ejecuta la vista previa.

¿Podría compartir el problema al que se enfrenta cuando se invoca setPreviewDisplay con una superficie setPreviewDisplay ?





mediarecorder