Vídeo de escala de matriz en TextureView Android

Estoy intentando reproducir video con ExoPlaye en TextureView . Con el fin de escalar y recortar vídeo para ajustar la vista que uso la matriz. Mi vista personalizada se extiende `TextureView 'Aquí está mi código:

 @Override public void onVideoSizeChanged(int width, int height, float pixelWidthHeightRatio) { updateTextureViewSize(width, height); Log.v("EXO", "onVideoSizeChanged() " + width + "x" + height); } private void updateTextureViewSize(float videoWidth, float videoHeight) { float viewWidth = getWidth(); float viewHeight = getHeight(); float scaleX = 1.0f; float scaleY = 1.0f; float viewRatio = viewWidth / viewHeight; float videoRatio = videoWidth / videoHeight; if (viewRatio > videoRatio) { // video is higher than view scaleY = videoHeight / videoWidth; } else { //video is wider than view scaleX = videoWidth / videoHeight; } Matrix matrix = new Matrix(); matrix.setScale(scaleX, scaleY, viewWidth / 2, viewHeight / 2); setTransform(matrix); } 

Yo tenía una vista rectangular y funcionaba perfectamente. Pero ahora las vistas tienen 2 estados: ampliado (los viejos que todavía son rectangulares) y colapsados ​​(tienen una altura más pequeña.

Así que ahora el video se estira verticalmente en las vistas colapsadas.

Por ejemplo, tengo vista 1080x480 y video 360x640 pero parece que el video se escala y se recorta a 1080x1080 y que se extiende a 1080x480 .

Qué estoy haciendo mal aquí ?

UPD: Aquí hay capturas de pantalla: introduzca la descripción de la imagen aquí

comprobar updateTextureViewSize :

 /** * Set the display options * * @param layout <ul> * <li>{@link #VIDEO_LAYOUT_ORIGIN} * <li>{@link #VIDEO_LAYOUT_SCALE} * <li>{@link #VIDEO_LAYOUT_STRETCH} * <li>{@link #VIDEO_LAYOUT_ZOOM} * </ul> */ public void updateTextureViewSize(int layout,float videoWidth, float videoHeight) { RelativeLayout.LayoutParams lp = (android.widget.RelativeLayout.LayoutParams) getLayoutParams(); DisplayMetrics disp = m_Context.getResources().getDisplayMetrics(); int windowWidth = disp.widthPixels, windowHeight = disp.heightPixels; float windowRatio = windowWidth / (float) windowHeight; float videoRatio = (float) videoWidth / (float) videoHeight; m_iSurfaceHeight = videoHeight; m_iSurfaceWidth = videoWidth; if (VIDEO_LAYOUT_ORIGIN == layout && m_iSurfaceWidth < windowWidth && m_iSurfaceHeight < windowHeight) { lp.width = (int) (m_iSurfaceHeight * videoRatio); lp.height = m_iSurfaceHeight; } else if (layout == VIDEO_LAYOUT_ZOOM) { lp.width = windowRatio > videoRatio ? windowWidth : (int) (videoRatio * windowHeight); lp.height = windowRatio < videoRatio ? windowHeight : (int) (windowWidth / videoRatio); } else { boolean full = layout == VIDEO_LAYOUT_STRETCH; lp.width = (full || windowRatio < videoRatio) ? windowWidth : (int) (videoRatio * windowHeight); lp.height = (full || windowRatio > videoRatio) ? windowHeight : (int) (windowWidth / videoRatio); lp.leftMargin = (disp.widthPixels - lp.width) / 2; lp.topMargin = (disp.heightPixels - lp.height) / 2; } lp.leftMargin = (disp.widthPixels - lp.width) / 2; lp.topMargin = (disp.heightPixels - lp.height) / 2; getHolder().setFixedSize(m_iSurfaceWidth, m_iSurfaceHeight); setLayoutParams(lp); m_iVideoLayout = layout; } 

He arreglado este problema al multiplicar o dividir los factores de escala por viewRatio ( width / height ):

  if (viewRatio > videoRatio) { // video is higher than view scaleY = videoHeight / videoWidth * viewRatio; } else { //video is wider than view scaleX = videoWidth / videoHeight / viewRatio; } 

Pero no entendí por qué funciona así. De acuerdo con mis cálculos, si tengo, por ejemplo, ver 1080x480 y vídeo 360x640 video debe ser escalado para tener ancho x' = 1080 y la altura proporcional. Así que la altura debe ser y' = 640*1080/360 videoHeight * viewHeight / videoWidth ( videoHeight * viewHeight / videoWidth ) y x' = 1080

Según esta imagen: introduzca la descripción de la imagen aquí

sx * 360 = 1080 => sx = 1080 / 360

sy * 640 = 640*1080/360 => sy = 1080 / 360

Parece que tiene sentido. Si necesitamos ahorrar proporciones, el ancho y la altura deben multiplicarse por el mismo factor. Pero no funciona de esta manera. ¿Dónde está un error? ¿Hay algún buen doc en esto?

  • Decodificación h264 ByteStream en Android
  • Android en vivo de vídeo - El audio no funciona
  • Realice un ajuste de vídeo en un TextureView (Partes de él están fuera (no visibles)) con MediaPlayer
  • Reproducción de vídeo de Android Things en Raspberry Pi
  • No se puede eliminar la caché en xperia mini
  • Establecer brillo / contraste en la captura de vídeo con Android Camera2
  • Reproducir un archivo m3u8 local en android mostrando setDataSourceFD failed .: status = 0x80000000
  • Resample / upsample sonidos de 8Khz a 48Khz (Java / Android)
  • Android SDK: Reproducción de vídeo mediante el protocolo mms
  • Cómo reproducir vídeos de YouTube en WebView en Amazon Fire TV?
  • Cómo implementar el chat de voz y video
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.