Android: Mediaplayer: How to use SurfaceView or mediaplayer to play video in correct size

前端 未结 3 923
一向
一向 2020-12-04 10:24

I am playing local video file using MediaPlayer and SurfaceView. SurfaceView is the only control in activity, while my video files are QVGA or other. Problem is that video i

相关标签:
3条回答
  • 2020-12-04 10:53

    here is the code I currently use in a project:

    private MediaPlayer mMediaPlayer;
    private SurfaceView mSurfaceView;
    private SurfaceHolder holder;
    private int mPos = 0;
    

    ...

    int width = mSurfaceView.getWidth();
    int height = mSurfaceView.getHeight();
    float boxWidth = width;
    float boxHeight = height;
    
    float videoWidth = mMediaPlayer.getVideoWidth();
    float videoHeight = mMediaPlayer.getVideoHeight();
    
    Log.i(TAG, String.format("startVideoPlayback @ %d - video %dx%d - box %dx%d", mPos, (int) videoWidth, (int) videoHeight, width, height));
    
    float wr = boxWidth / videoWidth;
    float hr = boxHeight / videoHeight;
    float ar = videoWidth / videoHeight;
    
    if (wr > hr)
        width = (int) (boxHeight * ar);
    else
        height = (int) (boxWidth / ar);
    
    Log.i(TAG, String.format("Scaled to %dx%d", width, height));
    
    holder.setFixedSize(width, height);
    mMediaPlayer.seekTo(mPos);
    mMediaPlayer.start();
    

    the layout I'm using (you can just ignore the progress bar)

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical" >
    
    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    
    <SurfaceView
        android:id="@+id/surface"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" >
    </SurfaceView>
    

    0 讨论(0)
  • 2020-12-04 11:03

    Setting your SurfaceView layout to wrap_content will not size a video to play at the proper aspect ratio.

    • A SurfaceView is an optimized drawing surface
    • A video is drawn to a SurfaceView, not contained within it

    wrap_content is synonymous with fill_parent for a SurfaceView.

    What you want to do is get the dimensions of your video from the MediaPlayer object. You can then set the aspect ratio of the SurfaceView to match the video.

    Some Basic initialization

    public class YourMovieActivity extends Activity implements SurfaceHolder.Callback {
        private MediaPlayer mp = null;
        //...
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            mp = new MediaPlayer();
            mSurfaceView = (SurfaceView) findViewById(R.id.surface);
            //...
        }
    }
    

    Then the good stuff. I have omitted error checking here to reduce code, MediaPlayer calls should be wrapped in a try{}.

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    
        mp.setDataSource("/sdcard/someVideo.mp4");
        mp.prepare();
    
        //Get the dimensions of the video
        int videoWidth = mp.getVideoWidth();
        int videoHeight = mp.getVideoHeight();
    
        //Get the width of the screen
        int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
    
        //Get the SurfaceView layout parameters
        android.view.ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
    
        //Set the width of the SurfaceView to the width of the screen
        lp.width = screenWidth;
    
        //Set the height of the SurfaceView to match the aspect ratio of the video 
        //be sure to cast these as floats otherwise the calculation will likely be 0
        lp.height = (int) (((float)videoHeight / (float)videoWidth) * (float)screenWidth);
    
        //Commit the layout parameters
        mSurfaceView.setLayoutParams(lp);        
    
        //Start video
        mp.start();
    }
    

    Note that this code makes some assumptions about the dimensions of your video. As-is, it maximizes the width and assumes that the height is not greater than the height of the screen.

    You may want to fit height instead of width, also you could check the dimension calculation and ensure that it is not greater than the screen or screen - other_layout_elements.

    0 讨论(0)
  • 2020-12-04 11:05

    On your SurfaceView in XML are you using wrap_content ? This should fix your problem if not. You may need to paste a little more code for further investigation if that doesn't fix your problem.

    Change your surface view width to wrap_content as well.

    0 讨论(0)
提交回复
热议问题