MediaPlayer使用
来源:互联网 发布:nba雄鹿队数据 编辑:程序博客网 时间:2024/05/21 13:57
OpenCore为Android用户提供了强大的多媒体开发运用功能,为了简化音频、视频系统的开发和播放,Android提供了一个综合的的MediaPlayer以简化对多媒体的操作。
Android提供了MediaPlayer类来完成对多媒体的播放。通过MediaPlayer类我们可以播放应用程序实现对应用程序资源文件、本地文件、内容提供器或者通过URL获得的流媒体。
MediaPlayer对音频视频播放的流程是用一个状态机来处理的:
图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"
02
xmlns:tools
=
"http://schemas.android.com/tools"
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卡的根目录下。
运行效果如下图所示:
图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(
80
,
100
);
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的运行效果如下图所示:
图13-4 Demo运行效果图1
图13-5 Demo运行效果图2
五、音频播放
音频播放的操作相对视频播放要简单一些,关于MediaPlayer的使用方法,前文已经做了详细的说明。下面给出两个例子作为参考。
Demo1
该Demo用来播放SD卡上对应路径的音频文件,需要把one.mp3、two.mp3和three.mp3放到SD卡的根目录下。
Demo1的运行效果如下图所示:
图13-6 Demo运行效果图
分别点击音乐列表中的对应项,会播放不同的歌曲,退出程序,歌曲停止播放。
Demo2
该Demo用来播放res目录下raw文件夹里面的音乐资源,需要把one.mp3放到raw文件夹里面。
初始化的代码如下:
1
musicMediaPlayer = MediaPlayer.create(
this
, R.raw.one);
不需要执行prepare()方法,直接通过start()方法进行播放。如果执行prepare()方法程序会报错。
Demo2运行效果如下图所示:
图13-7 Demo运行效果图
- MediaPlayer使用
- MediaPlayer使用
- 在網頁中使用MediaPlayer
- 网页中使用MediaPlayer
- 使用MediaPlayer播放在线视频
- 使用MediaPlayer播放音频
- 简单的MediaPlayer使用
- MediaPlayer的基本使用
- MediaPlayer简单使用
- MediaPlayer基本使用方式
- 使用MediaPlayer时报错
- SoundPool与MediaPlayer使用
- 使用MediaPlayer播放音频
- MediaPlayer简单使用
- MediaPlayer简单使用
- MediaPlayer的基本使用
- MediaPlayer 的使用介绍
- MediaPlayer基本使用方式
- VS上开发Node.js插件NTVS
- 梯度下降法学习总结
- 图论;单源最短路径;拓扑排序+松弛(有向无回路);Bellman-Ford(回路,负权回路)Dijkstra(无负权,可回路);可以用最小堆实现算法的优化;
- POJ3126 Prime Path 打表+BFS
- android 5.0 Lollipop上INSTALL_FAILED_DUPLICATE_PERMISSION错误的解决方法
- MediaPlayer使用
- 网络攻击(包括DDOS预防)
- 安全测试工具
- 简单的鱼群算法实现
- Java核心技术基础篇 第四章 类与对象 阅读笔记
- linux动态编译和静态编译
- 深入理解java异常处理机制
- 无法使用此Apple ID 进行更新的解决方法
- 黑马程序员——Java基础 网络编程