Android MediaPlayer播放視頻

MediaPlayer主要是用來播放音頻的,因此它沒有提供圖像輸出界面,此時就需要藉助於SurfaceView來顯示MediaPlayer播放時候的圖像輸出。

有幾點要注意的:

1、MediaPlayer管理播放的,所以狀態問題一定不能忽略的。

2、SurfaceHolder.setType(int)方法雖然被標記爲deprecate的,但是最好還是對SurfaceView進行這樣設置this.surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

3、最好保證mediaPlayer.start()之後,在進行mediaPlayer.setDisplay()的設置,不過一般問題不大。

4、有時候會遇到只有聲音沒有圖像的情況,那是因爲surfaceview的創建優先級並不高,因此在mediaPlayer開始之後,surfaceView還沒有創建出來,因此會出現有聲音沒圖像的問題

一般有兩種實現方法:

一是在通過holder增加callback,監聽surfaceCreate事件,在監聽到之後再開始mediaPlayer的相關操作,具體可以看videoView的實現方法

二是通過按鈕來實現mediaPlayer,這樣也可以保證再用戶按到按鈕之前,surfaceView已經被創建出來了。

下面是封裝的操作播放視頻的代碼,因爲需要,加了一些判斷,不過基本的封裝都有。

[java] view plaincopy

public class OperateMedia implements OnBufferingUpdateListener,  
        OnCompletionListener, OnErrorListener {  
    private int position = 0;// 保存播放的的位置  
    private SurfaceView surfaceView;// surfaceVie對象  
    private Context context;// 上下文對象  
    private MediaPlayer mediaPlayer;// mediaplayer對象  
    private int currentPlay = 0;// 保存當前正在播放的視頻 0表示還沒有記錄  
    private boolean justBack = false;// 是否剛纔另外一個界面跳回,fasle 表示不是  

    public OperateMedia(Context context, MediaPlayer mediaPlayer,  
            SurfaceView surfaceView) {  
        // TODO Auto-generated constructor stub  
        this.context = context;  
        this.mediaPlayer = mediaPlayer;  
        this.surfaceView = surfaceView;  
        // mediaPlayer的設置  
        this.mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);  
        this.mediaPlayer.setOnBufferingUpdateListener(this);  
        this.mediaPlayer.setOnCompletionListener(this);  
        // surfaceView的設置  
        this.surfaceView.getHolder().setKeepScreenOn(true);  
        this.surfaceView.getHolder().setType(  
                SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
        this.surfaceView.getHolder().addCallback(new SurfaceCallback()); // surfaceView的回調  

    }  

    // 設置播放不同的視頻  
    public void loadSrc(int num) {  
        // 如果在次播放的是不同的視頻,那麼就將position初始化,並且reset,重新設置視頻源  
        if (num != currentPlay) {  
            position = 0;  
            try {  
                currentPlay = num;  
                mediaPlayer.reset();  
                AssetFileDescriptor fd = null;  
                switch (num) {  
                case 0:  
                    fd = context.getAssets().openFd("a.mp4");  
                    break;  
                case 1:  
                    fd = context.getAssets().openFd("b.mp4");  
                    break;  
                case 2:  
                    fd = context.getAssets().openFd("c.mp4");  
                    break;  
                case 3:  
                    fd = context.getAssets().openFd("d.mp4");  
                    break;  
                }  
                mediaPlayer.setDataSource(fd.getFileDescriptor(),  
                        fd.getStartOffset(), fd.getLength());  
                play();  
            } 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();  
            }  
            return;// 中斷當前程序  
        }  
        // 如果點擊的是同一個視頻。那麼就不用reset了  
        if (num == currentPlay) {  
            if (justBack) {  
                play();  
                return;  
            } else {//如果不是從另一個activity切換回來,那麼,就直接設置到0,開始播放  
                mediaPlayer.seekTo(0);  
                mediaPlayer.start();  
                mediaPlayer.setDisplay(surfaceView.getHolder());// 設置屏幕  
            }  
        }  

    }  

    // 播放視頻  
    public void play() {  
        mediaPlayer.prepareAsync();  
        mediaPlayer.setOnPreparedListener(new OnPreparedListener() {  
            public void onPrepared(MediaPlayer mp) {  
                if (position > 0) {  
                    mediaPlayer.seekTo(position);  
                    if (justBack) {  
                        justBack = false;  
                        position = 0;  
                    }  
                }  
                mediaPlayer.start();  
            }  
        });  
        mediaPlayer.setDisplay(surfaceView.getHolder());// 設置屏幕  
    }  

    // 視頻播放完成的回調方法  
    public void onCompletion(MediaPlayer mp) throws IllegalStateException {  
        if (currentPlay == 0) {  
            MediaVideo.justPlay = false;  
        }  
    }  

    //  
    public void onBufferingUpdate(MediaPlayer mp, int percent)  
            throws IllegalStateException {  
    }  

    // SurfaceView的callBack  
    private class SurfaceCallback implements SurfaceHolder.Callback {  
        public void surfaceChanged(SurfaceHolder holder, int format, int width,  
                int height) {  
        }  

        public void surfaceCreated(SurfaceHolder holder) {  
            if (position > 0) {  
                loadSrc(currentPlay);  
            }  
        }  

        public void surfaceDestroyed(SurfaceHolder holder) {  
            // 界面銷燬,即將跳轉到另外一個界面  
            if (mediaPlayer.isPlaying()) {  
                justBack = true;  
                position = mediaPlayer.getCurrentPosition();  
                mediaPlayer.stop();  
            }  
        }  

    }  

    public boolean onError(MediaPlayer mp, int what, int extra) {  

        return false;  
    }  

}  

推薦一個寫的不錯的MediaPlayer的文章:點擊打開鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章