MediaPlayer使用

来源:互联网 发布:nba雄鹿队数据 编辑:程序博客网 时间:2024/05/21 13:57

   OpenCore为Android用户提供了强大的多媒体开发运用功能,为了简化音频、视频系统的开发和播放,Android提供了一个综合的的MediaPlayer以简化对多媒体的操作。

        Android提供了MediaPlayer类来完成对多媒体的播放。通过MediaPlayer类我们可以播放应用程序实现对应用程序资源文件、本地文件、内容提供器或者通过URL获得的流媒体。

        MediaPlayer对音频视频播放的流程是用一个状态机来处理的:


adfgasdg.png


图13-2  MediaPlayer状态机图


        其状态基本转换可以归纳如下:

        1、初始化分配播放时所需资源
        2、准备播放
        3、开始播放
        4、暂停播放
        5、停止播放
        6、播放结束,释放资源

        以上状态机图出自android官方的文档,网址如下:http://developer.android.com/reference/android/media/MediaPlayer.html

一、初始化和准备播放

        初始化时调用MediaPlayer的Create静态方法,可以有四种方法设置音频的数据源。

        1)资源描述符

        通过将音频文件添加到资源结构中的res/raw文件夹中。

1MediaPlayer player = MediaPlayer.create(getApplicationContext(), R.raw.music);

        2)以file://开头的本地文件URI

1MediaPlayer player = MediaPlayer.create(getApplicationContext(), Uri.parse(“file:///sdcard/music/1.mp3”));

        3)以URL为地址的网络文件URI

1MediaPlayer player = MediaPlayer.create(getApplicationContext(), Uri.parse(“<a href="\"http://music.net/1.mp3\"" target="\"_blank\"">http://music.net/1.mp3</a>”));
2        4)以内容提供器提供的URI
3<p></p><p align="\"left\""></p>
1MediaPlayer player = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI);

        也有另一种初始化方式,使用MediaPlayer的setDataSource成员方法。注意,当调用此方法作为初化方式时,在调用setDataSource之后,应当调用prepare()成员方法。代码如下:

1MediaPlayer player = new MediaPlayer();
2player.setDataSource(“/sdcard/test.3gp”);
3player.prepare();

        注意:

        1、在不合适的状态下调用prepare()和prepareAsync()方法会抛出IllegalStateException异常。
        2、当MediaPlayer对象处于Prepared状态的时候,可以调整音频/视频的属性,如音量,播放时是否一直亮屏,循环播放等。

二、播放控制

        准备好MediaPlayer后,想要开始播放,必须调用start()方法。当此方法成功返回时,MediaPlayer的对象处于Started状态。

        isPlaying()方法可以被调用来测试某个MediaPlayer对象是否在Started状态。而对一个已经处于Started 状态的MediaPlayer对象调用start()方法没有影响。

        调用pause()方法并返回时, 播放可以被暂停会使MediaPlayer对象进入Paused状态。调用start()方法会让一个处于Paused状态的MediaPlayer对象从之前暂停的地方恢复播放。当调用start()方法返回的时候,MediaPlayer对象的状态会又变成Started状态。

        注意:Started与Paused状态的相互转换在内部的播放引擎中是异步的。所以可能需要一点时间在isPlaying()方法中更新状态,若在播放流内容,这段时间可能会有几秒钟。

        调用stop()方法会停止播放,并且还会让一个处于Started,Paused,Prepared或PlaybackCompleted状态的MediaPlayer进入Stopped状态。

        调用seekTo()方法可以调整播放的位置。seekTo(int)方法是异步执行的,所以它可以马上返回,但是实际的定位播放操作可能需要一段时间才能完成,尤其是播放流形式的音频/视频。

        当实际的定位播放操作完成之后,内部的播放引擎会调用客户端程序员提供的OnSeekComplete.onSeekComplete()回调方法。可以通过setOnSeekCompleteListener(OnSeekCompleteListener)方法注册。

        注意:seekTo(int)方法也可以在其它状态下调用,比如Prepared,Paused和PlaybackCompleted状态。此外,目前的播放位置,实际可以调用getCurrentPosition()方法得到,它可以帮助如音乐播放器的应用程序不断更新播放进度。

01private void startPlay() {
02player.start();
03}
04private void stopPlay() {
05payer.stop();
06}
07private void pausePlay() {
08player.pause();
09}
10private void goTo(int pos) {
11player.seekTo(pos);
12}

三、释放播放资源

        当播放到流的末尾,播放就完成了。如果调用了setLooping(boolean)方法开启了循环模式,那么这个MediaPlayer对象会重新进入Started状态。 

        在播放结束时,应调用MediaPlayer的release()方法,释放播放程序所占用的资源。代码如下:

1private void release() {
2if(player != null) {
3player.stop();
4player.release();
5player = null;
6}
7}

四、视频播放

        视频播放与音频播放在MediaPlayer中基本相同,但与音频不同的是,视频播放必须考虑到MediaPlayer的视频的显示方法。下面简要描述了两种可以用于视频播放显示的方法。

        1) 使用VideoView播放显示视频

        由于VideoView继承了SurfaceView,并且实现了MediaController.MediaPlayerControl。使得VideoView控件包含了一个视频显示的界面,该界面可以管理MediaPlayer以控制视频的播放,同样的,VideoView也支持对MediaPlayer组件所支持的本地文件或者流式文件播放。

        下面以一个简单的VideoView的Demo简单介绍一下VideoView的使用。

        布局文件activity_main.xml的内容如下:

01<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
02xmlns:tools="http://schemas.android.com/tools"
03android:layout_width="fill_parent"
04android:layout_height="fill_parent" >
05<VideoView android:id="@+id/mvideoview"
06android:layout_width="fill_parent"
07android:layout_height="wrap_content"
08/>
09 
10</LinearLayout>

        MainActivity.java文件的内容如下:

01package com.example.videoviewdemo;
02 
03import android.os.Bundle;
04import android.app.Activity;
05import android.view.Menu;
06import android.view.MenuItem;
07import android.widget.MediaController;
08import android.widget.Toast;
09import android.widget.VideoView;
10import android.support.v4.app.NavUtils;
11 
12public class MainActivity extends Activity {
13 
14private String path = "";
15private VideoView mVideoView;
16 
17@Override
18public void onCreate(Bundle savedInstanceState) {
19super.onCreate(savedInstanceState);
20setContentView(R.layout.activity_main);
21 
22path = "/sdcard/abc.3gp";
23// path = "/sdcard/one.mp3";
24mVideoView = (VideoView) findViewById(R.id.mvideoview);
25 
26if (path == "") {
27Toast.makeText(this"Please set the path of your video", Toast.LENGTH_SHORT).show();
28else {
29mVideoView.setVideoPath(path);
30mVideoView.setMediaController(new MediaController(this));
31mVideoView.requestFocus();
32}
33}
34 
35// @Override
36// public boolean onCreateOptionsMenu(Menu menu) {
37// getMenuInflater().inflate(R.menu.activity_main, menu);
38// return true;
39// }
40 
41 
42}

        这个Demo内容非常简单,不再做具体分析了。在调试时,本人采用的是真机调试,需要把abc.3gp文件放在SD卡的根目录下。

        运行效果如下图所示:


豌豆荚截图20120718122120.png


图13-3  Demo运行效果图


        2) 使用SurfaceHolder播放显示视频

        虽然VideoView可以很容易地播放视频,但播放位置和播放大小并不受控制,因此,需要用SurfaceView来播放视频。

想要使用MediaPlayer播放视频,需要使用SurfaceView控件。对于显示视频内容则需要调用MediaPlayer的setDisplay()方法分配一个SurfaceHolder对象,否则,视频将不会显示。

        下面以一个Demo简单演示一下通过SurfaceView播放视频文件。

        activity_main.xml布局文件内容如下:

01<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
02android:orientation="vertical"
03android:layout_width="fill_parent"
04android:layout_height="fill_parent">
05<TextView
06android:layout_width="fill_parent"
07android:layout_height="wrap_content"
08android:text="@string/app_name"
09android:padding="8sp"
10android:gravity="center_horizontal"/>
11<com.example.surfaceviewdemo.VideoSurfaceView
12android:layout_width="320px"
13android:layout_height="240px"
14android:layout_gravity="center"/>
15</LinearLayout>

        VideoSurfaceView.java文件的内容如下:

001package com.example.surfaceviewdemo;
002 
003import java.io.IOException;
004 
005import android.content.Context;
006import android.media.AudioManager;
007import android.media.MediaPlayer;
008import android.media.MediaPlayer.OnCompletionListener;
009import android.media.MediaPlayer.OnPreparedListener;
010import android.util.AttributeSet;
011import android.util.Log;
012import android.view.SurfaceHolder;
013import android.view.SurfaceHolder.Callback;
014import android.view.SurfaceView;
015 
016public class VideoSurfaceView extends SurfaceView implements Callback,
017OnPreparedListener, OnCompletionListener {
018 
019//定义视频播放器
020private MediaPlayer videoPlayer = null;
021 
022public VideoSurfaceView(Context context, AttributeSet attrs) {
023super(context, attrs);
024// TODO Auto-generated constructor stub
025this.getHolder().addCallback(this);
026this.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
027}
028 
029 
030//初始化视频播放器
031private void initVideoPlayer() throws IllegalArgumentException, IllegalStateException, IOException {
032 
033videoPlayer = new MediaPlayer();
034videoPlayer.reset();
035videoPlayer.setDataSource("/sdcard/def.3gp");
036videoPlayer.setDisplay(this.getHolder() );
037videoPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
038 
039//设置音量
040videoPlayer.setVolume(80100);
041//设置播放预备侦听器
042videoPlayer.setOnPreparedListener(this);
043//设置播放完成侦听器
044videoPlayer.setOnCompletionListener(this);
045videoPlayer.prepare();
046 
047Log.d(this.getClass().getSimpleName(),
048"Width="+videoPlayer.getVideoWidth()+
049", height=" +videoPlayer.getVideoHeight() );
050}
051 
052//播放完毕
053@Override
054public void onCompletion(MediaPlayer mp) {
055// TODO Auto-generated method stub
056if(videoPlayer != null) {
057videoPlayer.stop();
058videoPlayer.release();
059videoPlayer = null;
060}
061}
062 
063//播放已准备就绪
064@Override
065public void onPrepared(MediaPlayer mp) {
066// TODO Auto-generated method stub
067if(videoPlayer != null) {
068videoPlayer.start();
069}
070}
071 
072@Override
073public void surfaceChanged(SurfaceHolder holder, int format, int width,
074int height) {
075// TODO Auto-generated method stub
076 
077}
078 
079 
080@Override
081public void surfaceCreated(SurfaceHolder holder) {
082// TODO Auto-generated method stub
083try {
084initVideoPlayer();
085catch (IllegalArgumentException e) {
086// TODO Auto-generated catch block
087e.printStackTrace();
088catch (IllegalStateException e) {
089// TODO Auto-generated catch block
090e.printStackTrace();
091catch (IOException e) {
092// TODO Auto-generated catch block
093e.printStackTrace();
094}
095}
096 
097@Override
098public void surfaceDestroyed(SurfaceHolder holder) {
099// TODO Auto-generated method stub
100if (videoPlayer != null) {
101videoPlayer.release();
102videoPlayer = null;
103}
104}
105 
106}

        Demo的运行效果如下图所示:


豌豆荚截图20120718141525.png


图13-4  Demo运行效果图1

豌豆荚截图20120718141515.png


图13-5  Demo运行效果图2


五、音频播放

        音频播放的操作相对视频播放要简单一些,关于MediaPlayer的使用方法,前文已经做了详细的说明。下面给出两个例子作为参考。

        Demo1

        该Demo用来播放SD卡上对应路径的音频文件,需要把one.mp3、two.mp3和three.mp3放到SD卡的根目录下。

        Demo1的运行效果如下图所示:


豌豆荚截图20120718142309.png


图13-6  Demo运行效果图


        分别点击音乐列表中的对应项,会播放不同的歌曲,退出程序,歌曲停止播放。

        Demo2

        该Demo用来播放res目录下raw文件夹里面的音乐资源,需要把one.mp3放到raw文件夹里面。

        初始化的代码如下:

1musicMediaPlayer = MediaPlayer.create(this, R.raw.one);

        不需要执行prepare()方法,直接通过start()方法进行播放。如果执行prepare()方法程序会报错。

        Demo2运行效果如下图所示:


豌豆荚截图20120718142319.png


图13-7  Demo运行效果图


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 a2驾驶员扣33分怎么办 驾驶证被扣48分怎么办 驾照扣了33分怎么办 车辆被扣36分怎么办 车被朋友借走了怎么办 在中国终身禁驾怎么办 c驾驶证忘年审了怎么办 驾驶证脱审1年多怎么办 驾驶证脱审四个月怎么办 驾照b2过期没审怎么办 a照驾照过期没审怎么办 驾照扣60多分怎么办 无证违章被扣分怎么办 变味的牛奶喝了怎么办 孩子喝了坏牛奶怎么办 孕妇喝了坏牛奶怎么办 驾照过期五年了怎么办 科目一没过之后怎么办? 重庆科目一没过怎么办 科三过了没签字怎么办 驾照过期几天撞死人怎么办 办理过期身份时出错了怎么办 新加坡半年临时驾照过期后怎么办 北京怎么办残摩行驶证 报考驾照三年到期了怎么办 车辆违章扣3分怎么办 驾照过期忘审了怎么办 外省港澳证办了居住证怎么办 电动车交警罚单丢了怎么办 在外地开车违章扣分怎么办 郑州车在外地扣分违章怎么办 电工证掉了应该怎么办 毕业回国美国驾照过期了怎么办 a2驾驶证4年没交体检报告怎么办 中国驾照在美国丢了怎么办 拿了驾照不敢开车怎么办 刚拿驾照不敢上路怎么办 雅思考试作文格式写错了怎么办 英国银行卡注销后钱怎么办 本科毕业有毕业证没有学位证怎么办 莫名收到平安一账通验证码怎么办