使用SurfaceView播放視頻,其實(shí)很簡(jiǎn)單,但是經(jīng)常會(huì)碰見有聲音沒圖像的問題.
其實(shí)使用SurfaceView播放視頻只需要主要下面幾個(gè)地方就可以了
1. surfaceChanged也就是Suface是否創(chuàng)建成功
2. onPrepared 也就是MideoPlayer是否加載并準(zhǔn)備完成
3. surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
類型必須是SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS
package VideoTest.Test;import java.io.FileDescriptor;import android.app.Activity;import android.content.res.AssetFileDescriptor;import android.media.AudioManager;import android.media.MediaPlayer;import android.media.MediaPlayer.OnBufferingUpdateListener;import android.media.MediaPlayer.OnCompletionListener;import android.media.MediaPlayer.OnPreparedListener;import android.os.Bundle;import android.view.SurfaceHolder;import android.view.SurfaceView;public class VideoTest extends Activity implements SurfaceHolder.Callback,OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener{private SurfaceView surfaceView;private SurfaceHolder surfaceHolder;private MediaPlayer mediaPlayer;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.surfaceView = new SurfaceView(this);this.surfaceHolder = this.surfaceView.getHolder();this.surfaceHolder.addCallback(this);//類型必須設(shè)置成SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERSthis.surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);setContentView(this.surfaceView);}@Overridepublic void onDestroy() {super.onDestroy();if (this.mediaPlayer != null) {this.mediaPlayer.release();this.mediaPlayer = null;}}public void PlayVideo(){try {//視頻文件放在 assert中AssetFileDescriptor aFD = this.getAssets().openFd("welcome.3gp");FileDescriptor fileDescriptor = aFD.getFileDescriptor();this.mediaPlayer = new MediaPlayer();this.mediaPlayer.setDataSource(fileDescriptor, aFD.getStartOffset(), aFD.getLength());aFD.close();//視頻放在SDCard中//File sdFile = Environment.getExternalStorageDirectory();//this.mediaPlayer = new MediaPlayer();//this.mediaPlayer.setDataSource(sdFile.getAbsoluteFile() + File.separator + "welcome.3gp");//視頻放在res中//this.mediaPlayer = MediaPlayer.create(this, R.raw.welcome);//網(wǎng)上的視頻,沒有測(cè)試//this.mediaPlayer// .setDataSource("http://xy2.163.com/download/down/wukong.mp3");this.mediaPlayer.setDisplay(this.surfaceHolder);this.mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//準(zhǔn)備完成后才可以播放,另外如果文件特別大或者從網(wǎng)上獲得的資源//會(huì)在這里等待時(shí)間過長(zhǎng),造成堵塞,這樣的話就得用//this.mediaPlayer.prepareAsync(),然后監(jiān)聽是否準(zhǔn)備完畢在開始this.mediaPlayer.prepare();this.mediaPlayer.start();} catch (Exception e) {// TODO: handle exception}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) {//SurfaceCreated 創(chuàng)建成功才可以播放視頻PlayVideo();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {}//@Overridepublic void onBufferingUpdate(MediaPlayer mp, int percent) {// TODO Auto-generated method stub}//@Overridepublic void onCompletion(MediaPlayer mp) {// TODO Auto-generated method stub}//@Overridepublic void onPrepared(MediaPlayer mp) {//MediaPlayer加載準(zhǔn)備完畢才能開始播放//mp.start();}}
但是,對(duì)于一些人可能會(huì)產(chǎn)生另一個(gè)問題就是
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
在設(shè)置成SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS類型后,無法畫圖了
SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS的意思是創(chuàng)建一個(gè)"PUSH"surface,這個(gè)surface沒有自己的緩沖區(qū),沒有自己的緩沖Buffer.