SurfaceView+MediaPlayer 实现简单的视频播放

一、实现原理

由于MediaPlayer没有播放视频的界面,所以需要通过SurfaceView显示视频。SurfaceView相当于一个容器,可以把内嵌的MediaPlayer的视频数据显示出来。

二、实现步骤

1、布局文件中添加SurfaceView控件

2、通过SurfaceView.getHolder()获得SurfaceHolder

3、为SurfaceHolder添加一个Callback对象

4、重写SurfaceView的Callback类,并在该类中的surfaceCreate()方法中,为MediaPlayer设置显示控件(mediaPlayer.setDisplay(SurfaceHolder))

三、实例参考

该例实现了利用SurfaceView+MediaPlayer播放SD卡上存储的视频。

package com.example.pc.externalstoragetest;
import android.media.MediaPlayer;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.io.File;
import java.io.IOException;
import java.net.URL;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
     private URL url;
     private ImageView showPic;
     private SurfaceView sv ;
     private SurfaceHolder holder;
     private MediaPlayer mp;
     private int vWidth,vHeight;
     private Display currDisplay;
     private DownloadAsyncTask task;
     private ProgressBar pb;
     private Button startDownload,startPlay;
     private TextView showProgressNub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        holder=sv.getHolder();
        mp=new MediaPlayer();
        holder.addCallback(new SurfaceHolder.Callback(){

            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {

                mp.setDisplay(sv.getHolder());

            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

            }
        });

    }

    private void StartPlay() {
        //url=new URL("http ://vt1.doubanio.com/201806051925/5a95ce9e62a5473be84dfbaa1b69302b/view/movie/M/402300072.mp4");
        currDisplay = this.getWindowManager().getDefaultDisplay();
        //获取存储在SD卡上的视频文件
        final String  path= Environment.getExternalStorageDirectory().getPath()+ File.separator+"dahuangfeng.mp4";

        try {
            //设置MediaPlayer的数据
            mp.setDataSource(path);
            mp.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }


        mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {
                adjustVideoSize();
                mp.start();
            }
        });
        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {
                mp.stop();
            }
        });
        System.out.println("........已设置资源.........");


    }

    private void adjustVideoSize() {
        vWidth = mp.getVideoWidth();
        vHeight = mp.getVideoHeight();
        System.out.println("mp.getvideowith():"+mp.getVideoWidth());
        System.out.println("mp.getvideoheight():"+mp.getVideoHeight());
        System.out.println("currDisplay.getWidth():"+currDisplay.getWidth());
        System.out.println("currDisplay.getHeight():"+currDisplay.getHeight());

        if(vWidth > currDisplay.getWidth() || vHeight > currDisplay.getHeight()){
            //如果video的宽或者高超出了当前屏幕的大小,则要进行缩放
            float wRatio = (float)vWidth/(float)currDisplay.getWidth();
            float hRatio = (float)vHeight/(float)currDisplay.getHeight();

            //选择大的一个进行缩放
            float ratio = Math.max(wRatio, hRatio);

            vWidth = (int)Math.ceil((float)vWidth/ratio);
            vHeight = (int)Math.ceil((float)vHeight/ratio);

            //设置surfaceView的布局参数
            sv.setLayoutParams(new RelativeLayout.LayoutParams(vWidth, vHeight));

            //然后开始播放视频
            //如果视频宽度或高度小于SurfaceViewd的宽高,则调整将SurfaceView的宽高适应视频。
        }else if(vWidth<currDisplay.getWidth()||vHeight<currDisplay.getHeight()){

            RelativeLayout.LayoutParams layoutParams= new RelativeLayout.LayoutParams(vWidth,vHeight);
            layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
            layoutParams.topMargin=20;
            sv.setLayoutParams(layoutParams);
        }
    }

    private void initView() {
        sv=findViewById(R.id.suView);
        pb=findViewById(R.id.progressBar0);
        showProgressNub=findViewById(R.id.showProgressNub);
        startDownload=findViewById(R.id.startDownload);
        startPlay=findViewById(R.id.startPlay);
        startDownload.setOnClickListener(this);
        startPlay.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {

        switch (view.getId()){
            case R.id.startDownload:
                task=new DownloadAsyncTask(pb,showProgressNub);
                task.execute();
                break;
            case R.id.startPlay:
                StartPlay();

                break;
        }

    }
}

效果图


猜你喜欢

转载自blog.csdn.net/mahuicool/article/details/80658025