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.
- ¿Cómo podemos reproducir código incrustado de YouTube en una aplicación de Android mediante webview?
- Reproducción de vídeo en TextureView
- Forzar el no-flash Vimeo incrustar o deshabilitar Flash en un WebView?
- Android Crear miniatura de video en un momento específico
- No se pueden reproducir ciertos videos
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:
- Muestra una fuente de video de gstreamer en Google Cartón SurfaceTexture
- Subir vídeo en twitter
- VideoView: IllegalStateException en MediaPlayer.getVideoWidth
- Android: cómo obtener una miniatura de vídeo de un archivo privado para su aplicación?
- Botón de pantalla completa de Video dentro de WebView no funciona
- InAppBrowser reproduce video de vimeo en el reproductor de video nativo automáticamente?
- ¿Cómo puedo reproducir video html5 en línea en un WebView?
- MediaMuxer no puede hacer MP4 que son streamable
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:
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?
- No se puede encontrar la clase de símbolo onClickListener
- RecyclerView, swiping de artículos, java.lang.IllegalStateException