Android多媒体之处理视频

  • 工作以来,一直偷懒,没有好好整理过自己的知识,从今天打算下定决心,开始整理笔记,记录自己的技术点滴,写给自己。不扯淡,直接进入正题。
    Android多媒体包括音频,视频,图片,流媒体等,这里我只说视频的处理,视频分为本地视频与网络视频,这里先说本地视频,这个比较简单。一般有两种方式:
    1、使用MediaPlayer来播放视频,当然它也可以播放音频;其底层是基于OpenCore(PacketVideo)的库实现的,为了构建一个MediaPlayer程序,上层还包含了进程间通讯等内容,
    这种进程间通讯的基础是Android基本库中的Binder机制(这里不做过多叙述);MediaPlayer的生命周期

    初始化操作reset(),调用release()方法,让音频或者视频结束,设置数据源setDataSource(),同时设置error监听器,如果资源有问题,会回调onError()方法结束;然后准备资源,如果是小资源是本地且占用空间比较小,就用prepare()方法,如果是网络上的资源或者大的资源,就用prepareAsync()方法,异步准备完成之后,然后去回调OnPrepareListener接口的onPrepared()方法,音频或者视频资源准备完成Prepared;这时,可以直接调用start()方法,开始播放,started与paused暂停可以相互转换,同时可以调用seekTo方法;当调用stop方法后,再起启动的时候,需要先prepare在start这里要注意,当播放完成之后,会调用playbackComplete()。
    播放视频的步骤: ①创建MediaPlayer对象,并让他加载制定的数据源(视频文件)
    ②在界面布局文件中定义SurfaceView组件,或者代码创建,并为SurfaceView的SurfaceHodler添加Callback监听器。
    ③调用MediaPlayer对象的setDisplay(holder)方法,设置视频显示的位置
    ④设置音频流对象、数据源、异步准备,各种监听,错误完成接口,走上述声明周期方法

具体代码如下:

mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);
        mSurHolder = mSurfaceView.getHolder();
        mSurfaceView.getHolder().addCallback(new Callback() {
            // 当前的surfaceView销毁的时候调用
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.i("TAG", "surfaceDestroyed");
                // 在SurfaceView被销毁之前保存当前的视频播放位置
                if (mMediaPlayer != null) {
                    mCurrentPosition = mMediaPlayer.getCurrentPosition();
                    mMediaPlayer.stop();
                    mMediaPlayer.release();
                }
            }
            // 当前surfaceView创建的时候调用
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                try {
                    if (mCurrentPosition > 0) {
                        mMediaPlayer = new MediaPlayer();
                        // 设置音频流类型
                        mMediaPlayer
                                .setAudioStreamType(AudioManager.STREAM_MUSIC);
                        // 设置视频显示位置
                        mMediaPlayer.setDisplay(mSurHolder);
                        // 设置播放的资源路径
                        mMediaPlayer.setDataSource(mp4Path);
                        // 准备播放
                        // mMediaPlayer.prepare();
                        mMediaPlayer.prepareAsync();
                        // 准备播放的监听器
                        mMediaPlayer
                                .setOnPreparedListener(new OnPreparedListener() {

                                    @Override
                                    public void onPrepared(MediaPlayer mp) {
                                        // 开始播放
                                        mMediaPlayer.start();
                                        mMediaPlayer.seekTo(mCurrentPosition);
                                    }
                                });
                        // 设置播放按钮不能点击
                        mStart.setEnabled(false);
                        // 播放完成的状态
                        mMediaPlayer
                                .setOnCompletionListener(new OnCompletionListener() {

                                    @Override
                                    public void onCompletion(MediaPlayer mp) {
                                        mStart.setEnabled(true);
                                    }
                                });
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            // 当前SurfaceView被改变的时候调用
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format,
                    int width, int height) {
                Log.i("TAG", "surfaceChanged");

            }
        });

播放的代码

private void play() {
        try {
            mMediaPlayer = new MediaPlayer();
            // 设置音频流类型
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            // 设置视频显示位置
            mMediaPlayer.setDisplay(mSurHolder);
            // 设置播放的资源路径
            mMediaPlayer.setDataSource(mp4Path);
            // 准备播放
            // mMediaPlayer.prepare();
            mMediaPlayer.prepareAsync();

            // 准备播放的监听器
            mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {

                @Override
                public void onPrepared(MediaPlayer mp) {
                    // 开始播放
                    mMediaPlayer.start();
                }
            });
            // 设置播放按钮不能点击
            mStart.setEnabled(false);
            // 播放完成的状态
            mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {

                @Override
                public void onCompletion(MediaPlayer mp) {
                    mStart.setEnabled(true);
                }
            });

            // 播放的过程中出现问题 设置播放按钮能点击
            mMediaPlayer.setOnErrorListener(new OnErrorListener() {

                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    int mediaErrorServerDied = MediaPlayer.MEDIA_ERROR_SERVER_DIED;
                    mStart.setEnabled(true);
                    return false;
                }
            });

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

2、使用VideoView来播放视频,首先它继承自SurfaceView,整合了MediaPlayer,将二者进行了封装,可以使用setVideoPath(String path)制定本地资源,setVideoURI(Uri uri):加载uri对应的视频;对视频控制的时候可以使用setMediaController(new MediaController(this)),使用起来更加方便,不用自己控制播放与暂停,并且实现了接口setOnPreparedListener(),当准备好后可以播放视频

具体的使用代码如下:

 Uri uri = Uri.parse("http://211.149.213.143/video_temp/fb586b2f216244f0bf4597242e8ca350.mp4");  
        VideoView videoView = (VideoView)this.findViewById(R.id.video_view);  
        videoView.setMediaController(new MediaController(this));  
        videoView.setVideoURI(uri);  
        videoView.start();  
        videoView.requestFocus();

接下来的文章会介绍一下http渐进下载协议与rtsp/rtp实时流媒体协议,同时在收一下SurfaceView与普通View的不同

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值