獲得網路視訊縮圖並且播放
阿新 • • 發佈:2019-01-28
</pre><pre name="code" class="java">
</pre><pre name="code" class="java">利用surfacehlder 和mediaplayer 播放網路視訊
import java.io.IOException; import android.app.Activity; import android.content.Intent; import android.graphics.PixelFormat; import android.media.MediaPlayer; import android.media.MediaPlayer.OnBufferingUpdateListener; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.media.MediaPlayer.OnPreparedListener; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.TextView; /** * * * SurfaceHolder * 1. 簡介 : 是 Surface 的控制器, 用於控制 SurfaceView 繪圖, 處理畫布上的動畫, 渲染效果, 大小等; * 2. 常用方法 : * -- abstract void addCallback(SurfaceHolder.Callback callback) : 新增一個 SurfaceHolder.Callback 介面物件, 監聽 Surface 的開始結束繪製大小改變事件; * -- abstract Canvas lockCanvas() : 鎖定畫布, 可以獲得 Canvas 物件, 之後就可以在 Canvas 上繪圖了; * * SurfaceHolder.Callback介面 : * 1. Surface 繪圖邊界 : 所有的繪圖工作都在 Surface 建立之後才能進行, 在 Surface 銷燬之前結束; * 2. Callback 介面對應的 Surface 邊界 : surfaceCreated() 方法在開始繪製時回撥, surfaceDestroyed() 在 Surface 銷燬前回調; * 3. 該介面中的方法 : * -- surfaceChanged() : 在 Surface 大小改變時回撥; * -- surfaceCreated() : 在 Surface 建立時回撥; * -- () : 在 Surface 銷燬時回撥; * * @author octopus * */ public class MPlayer extends Activity implements SurfaceHolder.Callback { // private AutoCompleteTextView url; /* 地址輸入框, 帶自動提示功能 */ private SurfaceView surface_view; /* 播放視訊載體 */ private TextView status; /* 顯示播放狀態 */ private Button play; /* 播放按鈕 */ private Button pause; /* 暫停按鈕 */ private Button reset; /* 重放按鈕 */ private Button stop; /* 停止按鈕 */ private MediaPlayer mediaPlayer; /* 播放器 */ private SurfaceHolder surface_holder; /* Surface 控制器 */ private boolean isStartPlaying; /* 是否開始了播放 */ private int vedioPosition; /* 接收intent從MainActivity傳過來的需要播放的視訊URL*/ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mplayer); Intent intent1=getIntent();//getIntent將該專案中包含的原始intent檢索出來,將檢索出來的intent賦值給一個Intent型別的變數intent vedioPosition=intent1.getExtras().getInt("vedioUrl"); initViews(); initData(); } /** * 初始化成員變數中的元件變數 */ private void initViews() { /* 通過 findViewById 獲取相關方法 */ // url = (AutoCompleteTextView) findViewById(R.id.url); surface_view = (SurfaceView) findViewById(R.id.surface_view); status = (TextView) findViewById(R.id.status); play = (Button) findViewById(R.id.play); pause = (Button) findViewById(R.id.pause); reset = (Button) findViewById(R.id.reset); stop = (Button) findViewById(R.id.stop); /* 使視窗支援透明度, 把當前 Activity 視窗設定成透明, 設定了該選項就可以使用 setAlpha 等函式設定視窗透明度 */ getWindow().setFormat(PixelFormat.TRANSPARENT); } /** * 初始化相關資料變數 */ private void initData() { /* 獲取並設定 SurfaceHolder 物件 */ surface_holder = surface_view.getHolder(); /* 根據 SurfaceView 元件, 獲取 SurfaceHolder 物件 */ surface_holder.addCallback(this); /* 為 SurfaceHolder 設定回撥函式, 即 SurfaceHolder.Callback 子類物件 */ surface_holder.setFixedSize(160, 128); /* 設定視訊大小比例 */ surface_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);/* 設定視訊型別 */ } /** * 設定點選事件 * @param view */ public void onClick(View view) { int id = view.getId(); switch (id) { case R.id.play: playVideo(VedioImages.imageThumbUrls[vedioPosition].toString()); break; case R.id.pause: if(mediaPlayer != null){ mediaPlayer.pause(); status.setText("暫停"); } break; case R.id.reset: if(mediaPlayer != null){ mediaPlayer.seekTo(0); mediaPlayer.start(); status.setText("播放中"); } break; case R.id.stop: if(mediaPlayer != null){ mediaPlayer.stop(); mediaPlayer.release(); isStartPlaying = false; status.setText("停止"); } break; default: break; } } /** * 播放網路視訊 * a. 建立並配置 MediaPlayer 物件 (音量, SurfaceHolder) * b. 為 MediaPlayer 設定錯誤監聽器, 緩衝進度監聽器, 播放完畢監聽器, 準備完畢監聽器 * c. 未 MediaPlayer 設定資料來源 * d. 呼叫 prepare() 進入 Prapared 狀態 * e. 呼叫 start() 進入 Started 狀態 * * @param dataSource 播放視訊的網路地址 */ private void playVideo(final String dataSource) { /* 點選播放有兩種情況 * a. 第一次點選 : 需要初始化 MediaPlayer 物件, 設定監聽器 * b. 第二次點選 : 只需要 呼叫 mediaPlayer 的 start() 方法 * 兩種情況通過 isStartPlaying 點選時間判斷 */ if(isStartPlaying){ /* 如果已經開始了播放, 就直接開始播放 */ mediaPlayer.start(); }else{ /* 如果是第一次開始播放, 需要初始化 MediaPlayer 設定監聽器等操作 */ mediaPlayer = new MediaPlayer(); /* 建立 MediaPlayer 物件 */ mediaPlayer.setAudioStreamType(2); /* 設定播放音量 */ mediaPlayer.setDisplay(surface_holder); /* 設定播放載體 */ /* 設定 MediaPlayer 錯誤監聽器, 如果出現錯誤就會回撥該方法列印錯誤程式碼 */ mediaPlayer.setOnErrorListener(new OnErrorListener() { @Override public boolean onError(MediaPlayer arg0, int what, int extra) { System.out.println("MediaPlayer 出現錯誤 what : " + what + " , extra : " + extra); return false; } }); /* 設定緩衝進度更新監聽器 */ mediaPlayer.setOnBufferingUpdateListener(new OnBufferingUpdateListener() { @Override public void onBufferingUpdate(MediaPlayer arg0, int percent) { /* 列印緩衝的百分比, 如果緩衝 */ System.out.println("緩衝了的百分比 : " + percent + " %"); } }); /* 設定播放完畢監聽器 */ mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer arg0) { Log.i("tag","播放完畢了"); System.out.println("播放完畢了"); status.setText("播放完畢"); } }); /* 設定準備完畢監聽器 */ mediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer arg0) { Log.i("tag","準備完畢"); System.out.println("準備完畢"); /* 設定播放狀態 */ status.setText("播放中"); } }); new Thread(){ public void run() { try { System.out.println("設定資料來源"); mediaPlayer.setDataSource(dataSource); mediaPlayer.prepare(); /* 列印播放視訊的時長 */ Log.i("tag","視訊播放長度 : " + mediaPlayer.getDuration()); System.out.println("視訊播放長度 : " + mediaPlayer.getDuration()); mediaPlayer.start(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }; }.start(); /* 設定 MediaPlayer 開始播放標識為 true */ isStartPlaying = true; /* 設定播放狀態 */ status.setText("正在緩衝"); } } /** * 在 Surface 大小發生改變的時候回撥 * 實現的 SurfaceHolder.Callback 介面方法 */ @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { Log.i("tag","SurfaceHolder.Callback.surfaceChanged : Surface 大小發生改變"); System.out.println("SurfaceHolder.Callback.surfaceChanged : Surface 大小發生改變"); } /** * 在 Surface 建立的時候回撥, 一般在該方法中開始繪圖 * 實現的 SurfaceHolder.Callback 介面方法 */ @Override public void surfaceCreated(SurfaceHolder arg0) { Log.i("tag","SurfaceHolder.Callback.surfaceCreated : Surface 開始建立"); System.out.println("SurfaceHolder.Callback.surfaceCreated : Surface 開始建立"); } /** * 在 Surface 銷燬之前回調, 在該方法中停止渲染執行緒, 釋放相關資源 * 實現的 SurfaceHolder.Callback 介面方法 */ @Override public void surfaceDestroyed(SurfaceHolder arg0) { Log.i("tag","SurfaceHolder.Callback.surfaceDestroyed : Surface 銷燬"); System.out.println("SurfaceHolder.Callback.surfaceDestroyed : Surface 銷燬"); } @Override protected void onDestroy() { if(mediaPlayer != null) mediaPlayer.release(); super.onDestroy(); } }