我遇到了一个我无法解决的问题.我正在使用MediaPlayer类来播放视频;但是,我总是失去原有的宽高比.这里提到了媒体播放器代码和xml代码.我尝试了很多东西,但仍然无法解决问题.我需要保持原始的宽高比.我已经在
Android Manifest文件中将此活动声明为全屏.我还在媒体播放器代码之后附加了xml代码.请建议我.
private class ErrorListener implements OnErrorListener { // FIXME: @Override public boolean onError(MediaPlayer mp,int what,int extra) { String message = "Unknown error"; switch (what) { case MediaPlayer.MEDIA_ERROR_UNKNOWN: message = "Unable to play media"; showError(message); break; case MediaPlayer.MEDIA_ERROR_SERVER_DIED: message = "Server Failed"; showError(message); break; case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: message = "Invalid media"; showError(message); break; } return false; } } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.videoview); Intent intent = getIntent(); uri = intent.getData(); new loadMovie().execute(); mPreview = (SurfaceView) findViewById(R.id.videoview); mPreview.bringToFront(); holder = mPreview.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mediaPlayer = new MediaPlayer(); }// onCreate Method Ends private void playVideo() { doCleanUp(); try { mediaPlayer.setDataSource(this,uri); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } mediaPlayer.setDisplay(holder); try { mediaPlayer.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } mediaPlayer.setOnErrorListener(new ErrorListener()); mediaPlayer.setOnBufferingUpdateListener(this); mediaPlayer.setOnCompletionListener(this); mediaPlayer.setOnPreparedListener(this); mediaPlayer.setOnVideoSizeChangedListener(this); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaController = new MediaController(this); } @Override public boolean onTouchEvent(MotionEvent event) { mediaController.show(); return false; } // --MediaPlayerControl // methods---------------------------------------------------- public void start() { mediaPlayer.start(); } public void pause() { mediaPlayer.pause(); } public int getDuration() { return mediaPlayer.getDuration(); } public int getCurrentPosition() { return mediaPlayer.getCurrentPosition(); } public void seekTo(int i) { mediaPlayer.seekTo(i); } public boolean isPlaying() { return mediaPlayer.isPlaying(); } public int getBufferPercentage() { return 0; } public boolean canPause() { return true; } public boolean canSeekBackward() { return true; } public boolean canSeekForward() { return true; } // End of MediaPlayer // Controls-------------------------------------------------------- // ------------------------ public void onPrepared(MediaPlayer mediaPlayer) { mediaController.setMediaPlayer(this); mediaController.setAnchorView(findViewById(R.id.videoview)); mIsVideoReadyToBePlayed = true; if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) { startVideoPlayback(); } handler.post(new Runnable() { public void run() { mediaController.setEnabled(true); mediaController.show(); } }); } public void surfaceChanged(SurfaceHolder arg0,int arg1,int arg2,int arg3) { // TODO Auto-generated method stub } public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub playVideo(); } public void surfaceDestroyed(SurfaceHolder arg0) { } private void startVideoPlayback() { holder.setFixedSize(mVideoWidth,mVideoHeight); mediaPlayer.start(); } public void onVideoSizeChanged(MediaPlayer mp,int width,int height) { if (width == 0 || height == 0) { return; } mIsVideoSizeKnown = true; mVideoWidth = width; mVideoHeight = height; if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) { startVideoPlayback(); } } public void onCompletion(MediaPlayer arg0) { } public void onBufferingUpdate(MediaPlayer mp,int percent) { } private void releaseMediaPlayer() { mediaPlayer.release(); mediaPlayer = null; } private void doCleanUp() { mVideoWidth = 0; mVideoHeight = 0; mIsVideoReadyToBePlayed = false; mIsVideoSizeKnown = false; }
这是XML:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" > <SurfaceView android:id="@+id/videoview" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
任何人都可以告诉我如何保持视频的宽高比?
解决方法
首先使用Gravity.CENTER创建相对布局,然后将Surface视图附加到其中.这将确保视频在屏幕内居中.
此外,如果您正在使用活动,请使用“黑色”主题来避免渐变
在SurfaceView中,创建一个监听器:
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
…
MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(MediaPlayer mp,int height) { setFitToFillAspectRatio(mp,width,height); } };
…
最后适合SurfaceView中的填充方法.这将适用于风景和肖像
private void setFitToFillAspectRatio(MediaPlayer mp,int videoWidth,int videoHeight) { if(mp != null) { Integer screenWidth = ((Activity) mContext).getWindowManager().getDefaultDisplay().getWidth(); Integer screenHeight = ((Activity) mContext).getWindowManager().getDefaultDisplay().getHeight(); android.view.ViewGroup.LayoutParams videoParams = getLayoutParams(); if (videoWidth > videoHeight) { videoParams.width = screenWidth; videoParams.height = screenWidth * videoHeight / videoWidth; } else { videoParams.width = screenHeight * videoWidth / videoHeight; videoParams.height = screenHeight; } setLayoutParams(videoParams); } }