Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Cómo girar un VideoView de Android

Mi aplicación sólo ofrece el modo Retrato. En una actividad de retrato tengo un VideoView de pantalla completa. Lo que quiero hacer es girar el VideoView (el vídeo real, videobuffer) 90 grados en el modo de paisaje. Habilitar la actividad para estar en modo Lanscape no es una opción. La ampliación de VideoView y de rotación de lienzo no funcionará, ya que es una SurfaceView no una vista real. ¿Hay alguna manera de lograr eso con un videoView?

2 Solutions collect form web for “Cómo girar un VideoView de Android”

VideoView no admite la rotación del vídeo incluso si la matriz de composición se establece correctamente y se utiliza el atributo de rotación.

Lo que puedes hacer es usar TextureView y establecer su atributo rotation = "90" (por ejemplo). Entonces girará los marcos pero la proporción de aspecto es algo que usted necesita manejar su uno mismo. Para hacerlo, puede utilizar textureView.setScaleX ((screenHeight * 1.0f) / screenWidth)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextureView android:id="@+id/playback_video" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:rotation="90" /> </RelativeLayout> 

Debe manejar el vídeo fluido también. Pero por favor piensa en ello como un ejemplo en lugar de liberar código listo. Renombrado algunas cosas y eliminado otros, no tienen relación con la pregunta y esto podría romper algo, pero en general este es un ejemplo viable.

 public class PlaybackActivity extends Activity implements MediaPlayer.OnErrorListener, OnPreparedListener, OnCompletionListener, OnVideoSizeChangedListener, OnBufferingUpdateListener, OnInfoListener, SurfaceTextureListener { private MediaPlayer mediaPlayer; private TextureView videoView; private boolean startedPlayback = false; private boolean playerReady = false; public static final int MEDIA_INFO_NETWORK_BANDWIDTH = 703; private void createMediaPlayer() { mediaPlayer = new MediaPlayer(); } private void releaseMediaPlayer() { if (mediaPlayer != null) { mediaPlayer.setSurface(null); mediaPlayer.release(); mediaPlayer = null; } } public void onCompletion(MediaPlayer mp) { Log.w(TAG, "Video playback finished"); } @Override public boolean onError(MediaPlayer player, int what, int extra) { if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN) { /* * Restart play back in case we did not start anything yet. This may * be the case when we tried to tune in in very first secs of the * broadcast when there is no data yet. */ if (liveBroadcast && mediaPlayer != null && !mediaPlayer.isPlaying() && !startedPlayback) { if (checkCount-- > 0) { mediaPlayer.reset(); checkBroadcast(); } else { Log.w(TAG, "Broadcast finished"); } } else { Log.w(TAG, "No media in stream"); } } else if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) { Log.w(TAG, "Media service died unexpectedly"); } else { Log.w(TAG, "Unknown media error"); } return true; } @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { switch (what) { case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING: Log.w(TAG, "Media is too complex to decode it fast enough."); startedPlayback = true; break; case MEDIA_INFO_NETWORK_BANDWIDTH: Log.w(TAG, "Bandwith in recent past."); break; case MediaPlayer.MEDIA_INFO_BUFFERING_START: Log.w(TAG, "Start of media bufferring."); startedPlayback = true; break; case MediaPlayer.MEDIA_INFO_BUFFERING_END: Log.w(TAG, "End of media bufferring."); startedPlayback = true; break; case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING: Log.w(TAG, "Media is not properly interleaved."); break; case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE: Log.w(TAG, "Stream is not seekable."); break; case MediaPlayer.MEDIA_INFO_METADATA_UPDATE: Log.w(TAG, "New set of metadata is available."); break; case MediaPlayer.MEDIA_INFO_UNKNOWN: default: Log.w(TAG, "Unknown playback info (" + what + ":" + extra + ")."); break; } return true; } private void startPlayback() { if (mediaPlayer != null) { onLoaded(mediaPlayer); mediaPlayer.start(); } } private void pausePlayback() { if (mediaPlayer != null && mediaPlayer.isPlaying()) mediaPlayer.pause(); } private void resumePlayback() { if (mediaPlayer != null && mediaPlayer.isPlaying()) mediaPlayer.start(); } private void onLoaded(MediaPlayer mp) { } public void onPrepared(MediaPlayer mp) { playerReady = true; startPlayback(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.playback); videoView = (TextureView) findViewById(R.id.playback_video); videoView.setOnClickListener(videoViewClickHandler); videoView.setSurfaceTextureListener(this); createMediaPlayer(); } @Override protected void onDestroy() { releaseMediaPlayer(); if (surface != null) { surface.release(); surface = null; } super.onDestroy(); } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { this.surface = new Surface(surface); loadMedia(someurl); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { if (this.surface != null) { releaseMediaPlayer(); this.surface.release(); this.surface = null; } return true; } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } @Override public void onVideoSizeChanged(MediaPlayer mp, int w, int h) { if (w > 0 && h > 0 && !videoSizeSetupDone) { Log.w(TAG, "Video size changed: " + w + "x" + h); changeVideoSize(w, h); } } private boolean videoSizeSetupDone = false; private void changeVideoSize(int width, int height) { DisplayMetrics metrics = new DisplayMetrics(); RelativeLayout.LayoutParams params; Utils.getScreenMetrics(this, metrics); VideoOrientation orientation = someVideoSource.getVideoOrientation(); if (orientation == LANDSCAPE) { params = new RelativeLayout.LayoutParams(metrics.widthPixels, metrics.heightPixels); } else { float rotation = orientation == BroadcastVideoOrientation.BroadcastVideoFrontCamera ? -90.0f : 90.0f; params = new RelativeLayout.LayoutParams(metrics.heightPixels, metrics.widthPixels); float scale = (width * 1.0f) / (height * 1.0f); videoView.setRotation(rotation); videoView.setScaleX(scale); } params.addRule(RelativeLayout.CENTER_IN_PARENT, -1); videoView.setLayoutParams(params); videoSizeSetupDone = true; } private void loadMedia(String url) { if (surface == null) return; Log.d(App.TAG, "Loading url: " + url); startedPlayback = false; try { mediaPlayer.reset(); mediaPlayer.setSurface(surface); mediaPlayer.setDataSource(url); mediaPlayer.setOnPreparedListener(this); mediaPlayer.setOnCompletionListener(this); mediaPlayer.setOnErrorListener(this); mediaPlayer.setOnVideoSizeChangedListener(this); mediaPlayer.setScreenOnWhilePlaying(true); mediaPlayer.setOnBufferingUpdateListener(this); mediaPlayer.setOnInfoListener(this); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepareAsync(); } catch (Exception e) { Log.w(TAG, "Media load failed"); Utils.alert(this, "Playback Error", e.getMessage(), finishHandler); } } } 

Espero que esto ayude. Estaba buscando esta solución por bastante tiempo. Probado casi todo y esto parece ser la única manera.

Puede configurar el oriantation individualmente de una actividad en el manifiesto, por lo que el vídeo se puede mostrar en horizontal (y vertical) mientras que el resto de la aplicación está en formato vertical. Ver mi respuesta aquí para una solución en esto.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.