当前位置: > 华清远见教育科技集团 > 嵌入式学习 > 讲师博文 > 使用MediaPlayer来播放视频
使用MediaPlayer来播放视频
时间:2016-12-09作者:华清远见

在上一篇文章中,我们讨论了如何在android中播放视频,并且讲解了VideoView的使用。本篇文章将继续上篇文章的主题,来学习如何使用MediaPlayer来播放视频。

对于MediaPlayer,要熟练掌握它的用法,一定要熟悉下面这张MediaPlayer的方法调用和状态转换图。

这张MediaPLayer状态图看起来很复杂,但实际上,只要理解了它的基本过程,就不会那么难了。我们可以结合我们播放视频的过程来了解,我们如果需要播放一个视频,大致的流程是:创建播放器对象?设置需要播放的视频的来源?对视频进行解码等准备工作?开始播放?(暂停?重启)?停止播放。对应这些流程,在MediaPlayer中都定义了相关的方法,而且,在调用这些方法后,MediaPlayer可以进入不同的状态。这些方法和状态都很好理解,读者可以参照上图来了解。另外,因为在设置播放的视频的视频数据源之后,它需要对其进行解码(调用prepare()方法),这是一个比较耗时的操作,所以为了避免应用程序阻止在这里,可以使用它的prepareAsync()方法配合OnPreparedListener监听器来让其异步操作。注意,只有MediaPlayer的准备工作做完后,才能开始播放。

MediaPlayer本身不能显示视频内容,它只能控制视频的播放。如果要使用MediaPlayer来播放视频,还需要配合SurfaceView来显示视频。关于SurfaceView的用法,限于篇幅在这里不再赘述。而要将MediaPlayer中解码的视频数据在SurfaceView中播放,需要调用MediaPlayer中的setDisplay()方法,它接受一个SurfaceHolder对象,可以将我们用于播放视频的SurfaceView对应的SurfaceHolder对象作为参数,这样,MediaPlayer和SurfaceView就建立起了关联。还有一个需要注意的是,要正确设置SurfaceView的大小(Size)和视频的大小相匹配。

以下为MediaPlayer中的主要方法和说明:

●setDataSource():设置播放的数据源。参数可以是字符串、FileDescriptor或者Uri等。

●setDisplay():接受一个SurfaceHolder参数,用于设置播放视频的SurfaceView。

●prepare()/prepareAsync():准备MediaPlayer准备播放。它们的区别在于前者是同步方法,后者是异步方法,且后者一般需要配合OnPreparedListener监听器。

●start():开始播放多媒体。

● pause():暂停播放多媒体。

●seekTo():改变播放进度。

●stop():停止播放多媒体。

下面我们来看一个例子:

package com.stylingandroid.viewpager;

import android.app.Activity;
        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.media.MediaPlayer.OnVideoSizeChangedListener;
        import android.os.Bundle;
        import android.util.Log;
        import android.view.SurfaceHolder;
        import android.view.SurfaceView;
        import android.widget.Toast;

public class MediaPlayerVideo extends Activity implements
                 OnCompletionListener,
                OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {

private static final String TAG = "MediaPlayerDemo";
        private int mVideoWidth;
        private int mVideoHeight;
        private MediaPlayer mMediaPlayer;
        private SurfaceView mPreview;
         private SurfaceHolder holder;
         private String path;
        private Bundle extras;

private boolean mIsVideoSizeKnown = false;
     &nbnbsp;  private boolean mIsVideoReadyToBePlayed = false;
        /**
        *
        * when the activity is first created.
        */
        @Override
        public void onCreate(Bundle icicle) {
                super.onCreate(icicle);
                setContentView(R.layout.main);
                mPreview = (SurfaceView) findViewById(R.id.surfaceview);
                holder = mPreview.getHolder();
                holder.addCallback(this);
                holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
                extras = getIntent().getExtras();
        }

private void playVideo() {
                clean();
                try{

        // 创建一个MediaPlayer对象
                mMediaPlayer = new MediaPlayer();
                // 设置播放的视频数据源
                 mMediaPlayer.setDataSource(path);
                // 将视频输出到SurfaceView
                mMediaPlayer.setDisplay(holder);
                // 播放准备,使用异步方式,配合OnPreparedListener
                mMediaPlayer.prepareAsync();
                 // 设置相关的监听器
                mMediaPlayer.setOnCompletionListener(this);
                mMediaPlayer.setOnPreparedListener(this);
                mMediaPlayer.setOnVideoSizeChangedListener(this);
                // 设置音频流类型
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                } catch (Exception e) {
                e.printStackTrace();
                 }
        }

public void onCompletion(MediaPlayer arg0) {
                 Log.d(TAG, "onCompletion");
         }
        //获得视频的宽和高
         public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                 Log.v(TAG, "onVideoSizeChanged");
                 if (width == 0 || height == 0) {
                 Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
                 return;
         }
                mIsVideoSizeKnown = true;
                mVideoWidth = width;
                mVideoHeight = height;
                if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
                 startVideoPlayback();
                }
        }
        //实现OnPreparedListener中的方法,当视频准备完毕会调用这个回调方法,开始播放
        public void onPrepared(MediaPlayer mediaplayer) {
                 Log.d(TAG, "onPrepared");
                mIsVideoReadyToBePlayed = true;
                if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
                 startVideoPlayback();
                 }
        }

public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
                 Log.d(TAG, "surfaceChanged");
        }

public void surfaceDestroyed(SurfaceHolder surfaceholder) {
                 Log.d(TAG, "surfaceDestroyed");
         }

public void surfaceCreated(SurfaceHolder holder) {
                  Log.d(TAG, "surfaceCreated");
                 playVideo();
        }

@Override
         protected void onPause() {
                 releaseMediaPlayer();
                clean();
                super.onPause();
        }

@Override
        protected void onDestroy() {
                super.onDestroy();
                releaseMediaPlayer();
                clean();
         }
        // 释放MediaPlayer
        private void releaseMediaPlayer() {
                if (mMediaPlayer != null) {
                 mMediaPlayer.release();
                mMediaPlayer = null;
                }
        }
        // 资源清理工作
        private void clean() {
                mVideoWidth = 0;
                mVideoHeight = 0;
                mIsVideoReadyToBePlayed = false;
                mIsVideoSizeKnown = false;
        }
        // 播放视频的方法
        private void startVideoPlayback() {
                Log.v(TAG, "startVideoPlayback");
                holder.setFixedSize(mVideoWidth, mVideoHeight);
                mMediaPlayer.start();
                }
        }

其中的main.xml这个layout很简单,就是一个SurfaceView,如下:

<?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="//schemas.

android.com/apk/res/android"
                android:orientation="vertical" android:layout_width="fill_parent"
        android:gravity="center" android:layout_height="fill_parent">
        <SurfaceView android:id="@+id/surfaceView1"
                android:layout_width="800px"
        android:layout_height="600px"></SurfaceView>
        </LinearLayout>

发表评论
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)