quien que programacion peso nariz madre los hijos hereda gen estatura dominante determina depende define bebe altura android videoview dimensions aspect-ratio

android - que - VideoView para coincidir con la altura del padre y mantener la relación de aspecto



quien determina el peso del bebe (8)

Con respecto a la pregunta 1, me sorprende que nadie haya mencionado el posible uso del modo de escalamiento de MediaPlayer. https://developer.android.com/reference/android/media/MediaPlayer.html#setVideoScalingMode(int)

Tiene 2 modos. Ambos siempre llenan el área de visualización. Para que llene el espacio a la vez que conserva la relación de aspecto, recortando así el lado largo, necesita cambiar al segundo modo, VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING . Eso resuelve una parte del problema. La otra parte es cambiar el comportamiento de medición de VideoView, tal como lo demuestran algunas de las otras respuestas. Esta es la forma en que lo hice, principalmente por pereza y no familiarizado con las API de metadatos que usan los demás, puede usar este método o uno de los otros métodos para corregir el tamaño de la vista. La captura general garantiza la seguridad cuando se llama a esto antes de que exista mMediaPlayer, ya que puede llamarse muchas veces, y también vuelve al comportamiento anterior si el nombre del campo cambia.

class FixedSizeVideoView : VideoView { constructor(ctx: Context) : super(ctx) constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) // rather than shrink down to fit, stay at the size requested by layout params. Let the scaling mode // of the media player shine through. If the scaling mode on the media player is set to the one // with cropping, you can make a player similar to AVLayerVideoGravityResizeAspectFill on iOS override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { try { val mpField = VideoView::class.java.getDeclaredField("mMediaPlayer") mpField.isAccessible = true val mediaPlayer: MediaPlayer = mpField.get(this) as MediaPlayer val width = View.getDefaultSize(mediaPlayer.videoWidth, widthMeasureSpec) val height = View.getDefaultSize(mediaPlayer.videoHeight, heightMeasureSpec) setMeasuredDimension(width, height) } catch (ex: Exception) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) } } }

Por lo tanto, al usar esta clase en el diseño, solo cambia el modo de escala en el reproductor multimedia donde sea que tenga oportunidad. Como:

video.setOnPreparedListener { mp: MediaPlayer -> mp.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING) mp.isLooping = true mp.setScreenOnWhilePlaying(false) } video.start()

Tengo un VideoView que está configurado de esta manera:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/player" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <VideoView android:id="@+id/video" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_centerInParent="true" android:layout_centerVertical="true" /> <ProgressBar android:id="@+id/loader" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" /> </RelativeLayout>

Pero VideoView coincide con el ancho del contenedor principal, y luego la altura se establece de acuerdo con la relación de aspecto de la película cargada.
Me gustaría hacer todo lo contrario, quiero que la VideoView coincida con la altura del padre manteniendo la relación de aspecto intacta, el video se recortará en los lados.

Logré estirar el VideoView para llenar el padre pero luego no se mantiene la relación de aspecto.

Otra cosa es que estoy agregando MediaController a VideoView de esta manera:

MediaController controllers = new MediaController(this) { @Override public void hide() { if (state != State.Hidden) { this.show(); } else { super.hide(); } } }; controllers.setAnchorView(videoView); videoView.setMediaController(controllers); videoView.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { controllers.show(); } });

Esto funciona muy bien, y los controladores siempre permanecen encendidos, pero la altura de los controladores no se tiene en cuenta al calcular dónde colocar el video (ya que está centrado verticalmente).

Mis dos preguntas entonces son:

  1. ¿Cómo puedo hacer que VideoView coincida con la altura del padre pero a la vez mantenga la relación de aspecto?
  2. ¿Cómo hago para que VideoView tenga en cuenta la altura de sus controladores?

Gracias.


Deberías ampliarlo desde la vista de video incorporada.

Llame a setVideoSize antes de que se muestre la vista de video, puede obtener el tamaño del video de la miniatura extraída del video.

De modo que, cuando se llama onMeasure video view, tanto mVideoWidth mVideoHeight son> 0.

Si desea tener en cuenta la altura de los controladores, puede hacerlo usted mismo en el método onMeasure .

La esperanza ayudará.

public class MyVideoView extends VideoView { private int mVideoWidth; private int mVideoHeight; public MyVideoView(Context context, AttributeSet attrs) { super(context, attrs); } public MyVideoView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MyVideoView(Context context) { super(context); } public void setVideoSize(int width, int height) { mVideoWidth = width; mVideoHeight = height; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Log.i("@@@", "onMeasure"); int width = getDefaultSize(mVideoWidth, widthMeasureSpec); int height = getDefaultSize(mVideoHeight, heightMeasureSpec); if (mVideoWidth > 0 && mVideoHeight > 0) { if (mVideoWidth * height > width * mVideoHeight) { // Log.i("@@@", "image too tall, correcting"); height = width * mVideoHeight / mVideoWidth; } else if (mVideoWidth * height < width * mVideoHeight) { // Log.i("@@@", "image too wide, correcting"); width = height * mVideoWidth / mVideoHeight; } else { // Log.i("@@@", "aspect ratio is correct: " + // width+"/"+height+"="+ // mVideoWidth+"/"+mVideoHeight); } } // Log.i("@@@", "setting size: " + width + ''x'' + height); setMeasuredDimension(width, height); } }


Gasté tiempo en buscar esto en Internet. No encontré ninguna solución mejor que se pueda aplicar a la vista de video predeterminada. Así que busqué las bibliotecas que solucionarán mis requisitos. Finalmente encontré una ''Pantalla completa de video'' ( https://github.com/rtoshiro/FullscreenVideoView ). Esto resolvió mi requisito.


He probado muchas soluciones, mientras que mi video siempre estuvo en formato 1000 * 1000, así que he creado una solución fácil para las personas que conocen su relación de aspecto. Primero crea un VideoView en un RelativeLayout como este:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/video_holder" android:layout_width="wrap_content" android:layout_height="fill_parent" android:clipToPadding="false"> <VideoView android:id="@+id/videoView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" /> </RelativeLayout>

Luego, antes de cargar el video, cambie la altura y programáticamente así:

int i = videoView.getHeight() > videoView.getWidth() ? videoView.getHeight() : videoView.getWidth(); video_holder.setLayoutParams(new ConstraintLayout.LayoutParams(i, i));

Por supuesto, esto solo funciona con una relación de aspecto de 1: 1, pero puedes usar tu relación de aspecto para cambiar la altura o el ancho.


La respuesta de Jobbert en Kotlin, en caso de que alguien la necesite:

val max = if (videoView.height > videoView.width) videoView.height else videoView.width videoView.layoutParams = ConstraintLayout.LayoutParams(max, max)


Resolví este problema con el diseño. Parece que funcionó bien cuando se fijó en las esquinas, pero provocó que el video se sesgara. Para probar, cambié el fondo de mi diseño relativo a # 990000 para ver el rojo que sobresale.

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/relative_parent" android:background="#000000"> <VideoView android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:focusable="false" android:focusableInTouchMode="false" android:id="@+id/videoView" /> </RelativeLayout>


Solución rápida y eficiente:

No es necesario crear una vista personalizada que se extienda desde VideoView. Solo establece un valor lo suficientemente grande como para android:layout_width . Esto establecerá el widthSpecMode de la vista de video en View.MeasureSpec.AT_MOST y luego el método onMeasure() de VideoView ajustará automáticamente su ancho manteniendo la proporción.

<VideoView android:id="@+id/video" android:layout_width="2000dp" android:layout_height="match_parent" />


public class MyVideoView extends VideoView { private int mVideoWidth; private int mVideoHeight; public MyVideoView(Context context, AttributeSet attrs) { super(context, attrs); } public MyVideoView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MyVideoView(Context context) { super(context); } @Override public void setVideoURI(Uri uri) { MediaMetadataRetriever retriever = new MediaMetadataRetriever(); retriever.setDataSource(this.getContext(), uri); mVideoWidth = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)); mVideoHeight = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)); super.setVideoURI(uri); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Log.i("@@@", "onMeasure"); int width = getDefaultSize(mVideoWidth, widthMeasureSpec); int height = getDefaultSize(mVideoHeight, heightMeasureSpec); if (mVideoWidth > 0 && mVideoHeight > 0) { if (mVideoWidth * height > width * mVideoHeight) { // Log.i("@@@", "image too tall, correcting"); height = width * mVideoHeight / mVideoWidth; } else if (mVideoWidth * height < width * mVideoHeight) { // Log.i("@@@", "image too wide, correcting"); width = height * mVideoWidth / mVideoHeight; } else { // Log.i("@@@", "aspect ratio is correct: " + // width+"/"+height+"="+ // mVideoWidth+"/"+mVideoHeight); } } // Log.i("@@@", "setting size: " + width + ''x'' + height); setMeasuredDimension(width, height); } }