一、实现原理
由于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; } } }
效果图