SurfaceView+MediaPlayer 實現簡單的視訊播放
阿新 • • 發佈:2018-12-30
一、實現原理
由於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; } } }
效果圖