Android用SurfaceView播放本地視屏(音頻)文件
我們知道Android中可以使 用VideoView播放視頻,而且操作簡單、方便。除此之外,我們還可以利用MediaPlayer用來播放視頻,不過MediaPlayer主要用于 播放音頻,沒有提供輸出圖像的輸出界面,就是只能聽到聲音,看不到畫面,這時就想到到了SurfaceView控件,將它與MediaPlayer結合起 來,就能達到了視屏播放效果了,今天就做一個簡單的視屏播放功能,把準備好的視屏文件test.3gp放在手機SD卡中,然后用SurfaceView來播放:
先看布局activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:weightSum="1" android:orientation="vertical" > <SurfaceView android:id="@+id/surfaceVIew" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="0.15" tools:context=".MainActivity" /> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="0.85"> <Button android:id="@+id/btn_play" android:text="開始" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/btn_pause" android:text="暫停" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/btn_stop" android:text="停止" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/btn_low" android:text="調低音量" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/btn_hight" android:text="調高音量" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>
接著就是Activity:
public class MainActivity extends Activity implements OnClickListener {/* 功能按鈕 */
private Button btn_play, btn_pause, btn_stop, btn_low, btn_height;
/* SurfaceView */
private SurfaceView mSurfaceView; / 播放視頻對象 / private MediaPlayer mediaPlayer; / 系統聲音 / private AudioManager audioManager; / 記錄播放位置 / private int position; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
/*設置窗口無title*/
requestWindowFeature(Window.FEATURE_NO_TITLE); /全屏顯示/ this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); findViews(); setListeners(); mediaPlayer = new MediaPlayer(); setSurfaceView(); }
// 橫豎屏切換時的處理 @Override protected void onSaveInstanceState(Bundle outState) { if (mediaPlayer != null && mediaPlayer.isPlaying()) {// 如果在播放的時候切換屏幕則保存當前觀看的位置 outState.putInt("position", mediaPlayer.getCurrentPosition()); } super.onSaveInstanceState(outState); }
// 橫豎屏切換后的處理 @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { if (savedInstanceState.containsKey("position")) { position = savedInstanceState.getInt("position");// 取得切換屏幕時保存的位置 } super.onRestoreInstanceState(savedInstanceState); }
/ 實例化UI / private void findViews() { btn_play = (Button) findViewById(R.id.btn_play); btn_pause = (Button) findViewById(R.id.btn_pause); btn_stop = (Button) findViewById(R.id.btn_stop); btn_low = (Button) findViewById(R.id.btn_low); btn_height = (Button) findViewById(R.id.btn_hight); mSurfaceView = (SurfaceView) findViewById(R.id.surfaceVIew); audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); }
/ 為5個按鈕設置監聽 / private void setListeners() { btn_play.setOnClickListener(this); btn_pause.setOnClickListener(this); btn_stop.setOnClickListener(this); btn_low.setOnClickListener(this); btn_height.setOnClickListener(this); }
/ 播放視頻 / private void playMedia() { / 初始化狀態 / mediaPlayer.reset(); / 設置聲音流類型 / mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); / 設置mp3\mp4加載路徑 / File file = new File(Environment.getExternalStorageDirectory(), "test.3gp"); try { mediaPlayer.setDataSource(file.getAbsolutePath()); // 緩沖 mediaPlayer.prepare(); // 開始播放 mediaPlayer.start(); // 具體位置 Log.i("position", position + "------"); mediaPlayer.seekTo(position); // 視頻輸出到View mediaPlayer.setDisplay(mSurfaceView.getHolder()); // 重置位置為0 position = 0; } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } / 設置surfaceView視圖 / private void setSurfaceView() { // creates a "push" surface mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 設置事件,回調函數 mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { / SurfaceView創建時 / @Override public void surfaceCreated(SurfaceHolder holder) { if (position > 0) { playMedia(); position = 0; } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } / SurfaceView銷毀視圖 / @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mediaPlayer.isPlaying()) { mediaPlayer.stop(); } / Activity銷毀時停止播放,釋放資源。不做這個操作,即使退出,還是能聽到視頻的聲音 / mediaPlayer.release(); } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_play:// 播放 if (mediaPlayer != null && mediaPlayer.isPlaying()) { return; } else { playMedia(); } break; case R.id.btn_pause:// 暫停 if (mediaPlayer != null && mediaPlayer.isPlaying()) { position = mediaPlayer.getCurrentPosition(); mediaPlayer.pause(); } else { return; } break; case R.id.btn_stop:// 停止 if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.stop(); position = 0; } else { return; } break; case R.id.btn_low:// 調小音量 // 獲取當前的音樂音量 int volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); Log.v("Volume", "volume" + volume); // 音量>0 if (volume > 0) { audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, 0); } else { return; } break; case R.id.btn_hight:// 調大音量 volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); // 音量<100 if (volume < audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)) { audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0); } else { return; } break; } } }</pre>