我的應用程序只提供肖像模式。在肖像活動中,我有一個全屏VideoView。我想要做的是在風景模式下將VideoView(實際視頻,視頻緩衝器)旋轉90度。啓用活動在Lanscape模式不是一種選擇。 擴展VideoView和畫布旋轉不起作用,因爲它是一個SurfaceView而不是實際的視圖。 有沒有什麼辦法可以通過videoView來實現呢?旋轉android VideoView
12
A
回答
0
您可以在清單中單獨設置一個活動的排列方式,因此您的視頻可以橫向(和縱向)顯示,而其他應用程序都是縱向顯示。請參閱我的回答here以獲取解決方案。
+0
這是一個好主意,但如果您想在片段中顯示視頻而不是全屏,則無法工作。 – 2013-11-28 19:07:02
21
即使正確設置了合成矩陣並使用了旋轉屬性,VideoView也不支持旋轉視頻。
你可以做的是使用TextureView並設置其屬性rotation =「90」(例如)。然後它會旋轉框架,但縱橫比是你需要處理你自己的東西。爲了做到這一點,你可以使用textureView.setScaleX((screenHeight * 1.0F)/屏幕寬度)
<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>
應該處理流式視頻了。但請把它看作一個例子而不是發佈現成的代碼。我重命名了一些東西並刪除了其他東西,它們與問題沒有關係,這可能會破壞某些東西,但通常這是可行的示例。
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);
}
}
}
希望這會有所幫助。我一直在尋找這個解決方案很長一段時間。嘗試幾乎所有東西,這似乎是唯一的方法。
相關問題
- 1. 是否可以旋轉Android VideoView?
- 2. 如何在VideoView中旋轉視頻
- 3. 旋轉回肖像時避免Android VideoView損壞?
- 4. 避免Android VideoView腐敗時旋轉回肖像
- 5. 在android中旋轉視頻
- 6. 視頻視圖旋轉90度在Android
- 7. Android Image旋轉
- 8. Android Animate旋轉
- 9. Android旋轉Webview
- 10. Android旋轉MapView
- 11. 的Android旋轉器旋轉屏幕
- 12. Android啓動畫面旋轉或旋轉
- 13. android動畫旋轉不會旋轉ccw
- 14. 使Android旋轉木馬自動旋轉
- 15. Videoview android崩潰
- 16. 的Android VideoView crop_center
- 17. Android VideoView崩潰
- 18. Android - Videoview URL HttpURLConnection
- 19. Android VideoView與ImageView
- 20. NookTablet Android - VideoView NullPointerException
- 21. Android VideoView重疊
- 22. Android中的VideoView
- 23. Android VideoView問題
- 24. Android VideoView SplashScreen
- 25. 的Android VideoView流
- 26. Android VideoView緩存
- 27. Android旋轉動畫
- 28. Android旋轉控制
- 29. Android角度旋轉
- 30. Android ViewGroup 3D旋轉
爲什麼風景模式不是一個選項,當這是你想要的? – TouchBoarder 2012-10-14 19:50:56