Android MediaPlayer播放视频

本文介绍如何使用MediaPlayer播放音频并借助SurfaceView显示播放的图像输出,详细阐述了关键注意事项,包括状态管理、SurfaceView设置、视频加载与播放等,并提供了封装的播放视频代码。同时推荐了一个关于MediaPlayer的优秀文章。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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的文章:点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值