MediaPlayer使用

   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文件夹中。

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

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

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

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

1 MediaPlayer 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>
1 MediaPlayer player = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI);

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

1 MediaPlayer player = new MediaPlayer();
2 player.setDataSource(“/sdcard/test.3gp”);
3 player.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()方法得到,它可以帮助如音乐播放器的应用程序不断更新播放进度。

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

三、释放播放资源

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

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

1 private void release() {
2 if(player != null) {
3 player.stop();
4 player.release();
5 player = 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"
03 android:layout_width="fill_parent"
04 android:layout_height="fill_parent" >
05 <VideoView android:id="@+id/mvideoview"
06 android:layout_width="fill_parent"
07 android:layout_height="wrap_content"
08 />
09  
10 </LinearLayout>

        MainActivity.java文件的内容如下:

01 package com.example.videoviewdemo;
02  
03 import android.os.Bundle;
04 import android.app.Activity;
05 import android.view.Menu;
06 import android.view.MenuItem;
07 import android.widget.MediaController;
08 import android.widget.Toast;
09 import android.widget.VideoView;
10 import android.support.v4.app.NavUtils;
11  
12 public class MainActivity extends Activity {
13  
14 private String path = "";
15 private VideoView mVideoView;
16  
17 @Override
18 public void onCreate(Bundle savedInstanceState) {
19 super.onCreate(savedInstanceState);
20 setContentView(R.layout.activity_main);
21  
22 path = "/sdcard/abc.3gp";
23 // path = "/sdcard/one.mp3";
24 mVideoView = (VideoView) findViewById(R.id.mvideoview);
25  
26 if (path == "") {
27 Toast.makeText(this"Please set the path of your video", Toast.LENGTH_SHORT).show();
28 else {
29 mVideoView.setVideoPath(path);
30 mVideoView.setMediaController(new MediaController(this));
31 mVideoView.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"
02 android:orientation="vertical"
03 android:layout_width="fill_parent"
04 android:layout_height="fill_parent">
05 <TextView
06 android:layout_width="fill_parent"
07 android:layout_height="wrap_content"
08 android:text="@string/app_name"
09 android:padding="8sp"
10 android:gravity="center_horizontal"/>
11 <com.example.surfaceviewdemo.VideoSurfaceView
12 android:layout_width="320px"
13 android:layout_height="240px"
14 android:layout_gravity="center"/>
15 </LinearLayout>

        VideoSurfaceView.java文件的内容如下:

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

        初始化的代码如下:

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

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

        Demo2运行效果如下图所示:


豌豆荚截图20120718142319.png


图13-7  Demo运行效果图


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值