Android提高之MediaPlayer播放网络音频的实现方法
来源:互联网 发布:淘宝客机器人有哪些 编辑:程序博客网 时间:2024/05/24 22:44
实现MediaPlayer在线播放音频的功能,由于在线视频播放比在线音频播放复杂,因此先介绍在线音频播放的实现,这样可以帮助大家逐步深入了解MediaPlayer的在线播放功能。
先来看看本文程序运行的结果如下图所示:
main.xml的源码如下:
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
FrameLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:layout_height
=
"fill_parent"
android:layout_width
=
"fill_parent"
>
<
LinearLayout
android:layout_height
=
"wrap_content"
android:layout_width
=
"fill_parent"
android:orientation
=
"vertical"
android:layout_gravity
=
"top"
>
<
LinearLayout
android:orientation
=
"horizontal"
android:layout_gravity
=
"center_horizontal"
android:layout_marginTop
=
"4.0dip"
android:layout_height
=
"wrap_content"
android:layout_width
=
"wrap_content"
>
<
Button
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:id
=
"@+id/btnPlayUrl"
android:text
=
"播放网络音频"
></
Button
>
<
Button
android:layout_height
=
"wrap_content"
android:id
=
"@+id/btnPause"
android:text
=
"暂停"
android:layout_width
=
"80dip"
></
Button
>
<
Button
android:layout_height
=
"wrap_content"
android:layout_width
=
"80dip"
android:text
=
"停止"
android:id
=
"@+id/btnStop"
></
Button
>
</
LinearLayout
>
<
LinearLayout
android:orientation
=
"horizontal"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:layout_marginBottom
=
"20dip"
>
<
SeekBar
android:paddingRight
=
"10dip"
android:layout_gravity
=
"center_vertical"
android:paddingLeft
=
"10dip"
android:layout_weight
=
"1.0"
android:layout_height
=
"wrap_content"
android:layout_width
=
"wrap_content"
android:id
=
"@+id/skbProgress"
android:max
=
"100"
></
SeekBar
>
</
LinearLayout
>
</
LinearLayout
>
</
FrameLayout
>
Player.java是本文的核心,Player.java实现了“进度条更新”、“数据缓冲”等功能,虽然不是很复杂的功能,但却是非常有用的功能。
Player.java源码如下:
package
com.musicplayer;
import
java.io.IOException;
import
java.util.Timer;
import
java.util.TimerTask;
import
android.media.AudioManager;
import
android.media.MediaPlayer;
import
android.media.MediaPlayer.OnBufferingUpdateListener;
import
android.media.MediaPlayer.OnCompletionListener;
import
android.os.Handler;
import
android.os.Message;
import
android.util.Log;
import
android.widget.SeekBar;
public
class
Player
implements
OnBufferingUpdateListener,
OnCompletionListener, MediaPlayer.OnPreparedListener{
public
MediaPlayer mediaPlayer;
private
SeekBar skbProgress;
private
Timer mTimer=
new
Timer();
public
Player(SeekBar skbProgress)
{
this
.skbProgress=skbProgress;
try
{
mediaPlayer =
new
MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnBufferingUpdateListener(
this
);
mediaPlayer.setOnPreparedListener(
this
);
}
catch
(Exception e) {
Log.e(
"mediaPlayer"
,
"error"
, e);
}
mTimer.schedule(mTimerTask,
0
,
1000
);
}
/*******************************************************
* 通过定时器和Handler来更新进度条
******************************************************/
TimerTask mTimerTask =
new
TimerTask() {
@Override
public
void
run() {
if
(mediaPlayer==
null
)
return
;
if
(mediaPlayer.isPlaying() && skbProgress.isPressed() ==
false
) {
handleProgress.sendEmptyMessage(
0
);
}
}
};
Handler handleProgress =
new
Handler() {
public
void
handleMessage(Message msg) {
int
position = mediaPlayer.getCurrentPosition();
int
duration = mediaPlayer.getDuration();
if
(duration >
0
) {
long
pos = skbProgress.getMax() * position / duration;
skbProgress.setProgress((
int
) pos);
}
};
};
//*****************************************************
public
void
play()
{
mediaPlayer.start();
}
public
void
playUrl(String videoUrl)
{
try
{
MediaPlayer的reset()方法的作用
MediaPlayer的reset()方法经常使用,但具体为什么要用却不是很明白,今天看MediaPlayer的API说明,才知道是为了重用MediaPlayer对象。
在MediaPlayer的API说明中有如下内容:
In order to reuse a MediaPlayer object that is in the Error state and recover from the error, reset()
can be called to restore the object to its Idle state.
也就是说,为了重用处于Error错误状态的MediaPlayer对象,可以通过调用reset()方法,使其恢复到idle空闲状态。
http://developer.android.com/reference/android/media/MediaPlayer.html
mediaPlayer.reset();
mediaPlayer.setDataSource(videoUrl);
mediaPlayer.prepare();
//prepare之后自动播放
//mediaPlayer.start();
}
catch
(IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public
void
pause()
{
mediaPlayer.pause();
}
public
void
stop()
{
if
(mediaPlayer !=
null
) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer =
null
;
}
}
@Override
/**
* 通过onPrepared播放
*/
public
void
onPrepared(MediaPlayer arg0) {
arg0.start();
Log.e(
"mediaPlayer"
,
"onPrepared"
);
}
@Override
public
void
onCompletion(MediaPlayer arg0) {
Log.e(
"mediaPlayer"
,
"onCompletion"
);
}
@Override
public
void
onBufferingUpdate(MediaPlayer arg0,
int
bufferingProgress) {
skbProgress.setSecondaryProgress(bufferingProgress);
int
currentProgress=skbProgress.getMax()*mediaPlayer.getCurrentPosition()/mediaPlayer.getDuration();
Log.e(currentProgress+
"% play"
, bufferingProgress +
"% buffer"
);
}
}
test_musicplayer.java是主程序,负责调用Player类,其中关键部分是SeekBarChangeEvent这个SeekBar拖动的事件:SeekBar的Progress是0~SeekBar.getMax()之内的数,而MediaPlayer.seekTo()的参数是0~MediaPlayer.getDuration()之内数,所以MediaPlayer.seekTo()的参数是(progress/seekBar.getMax())*player.mediaPlayer.getDuration()。
test_musicplayer.java源码如下:
package
com.musicplayer;
import
android.app.Activity;
import
android.os.Bundle;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
import
android.widget.SeekBar;
public
class
test_musicplayer
extends
Activity {
private
Button btnPause, btnPlayUrl, btnStop;
private
SeekBar skbProgress;
private
Player player;
/** Called when the activity is first created. */
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
this
.setTitle(
"在线音乐播放---hellogv编写"
);
btnPlayUrl = (Button)
this
.findViewById(R.id.btnPlayUrl);
btnPlayUrl.setOnClickListener(
new
ClickEvent());
btnPause = (Button)
this
.findViewById(R.id.btnPause);
btnPause.setOnClickListener(
new
ClickEvent());
btnStop = (Button)
this
.findViewById(R.id.btnStop);
btnStop.setOnClickListener(
new
ClickEvent());
skbProgress = (SeekBar)
this
.findViewById(R.id.skbProgress);
skbProgress.setOnSeekBarChangeListener(
new
SeekBarChangeEvent());
player =
new
Player(skbProgress);
}
class
ClickEvent
implements
OnClickListener {
@Override
public
void
onClick(View arg0) {
if
(arg0 == btnPause) {
player.pause();
}
else
if
(arg0 == btnPlayUrl) {
//在百度MP3里随便搜索到的,大家可以试试别的链接
String url=
"http://219.138.125.22/myweb/mp3/CMP3/JH19.MP3"
;
player.playUrl(url);
}
else
if
(arg0 == btnStop) {
player.stop();
}
}
}
class
SeekBarChangeEvent
implements
SeekBar.OnSeekBarChangeListener {
int
progress;
@Override
public
void
onProgressChanged(SeekBar seekBar,
int
progress,
boolean
fromUser) {
// 原本是(progress/seekBar.getMax())*player.mediaPlayer.getDuration()
this
.progress = progress * player.mediaPlayer.getDuration()
/ seekBar.getMax();
}
@Override
public
void
onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public
void
onStopTrackingTouch(SeekBar seekBar) {
// seekTo()的参数是相对与影片时间的数字,而不是与seekBar.getMax()相对的数字
player.mediaPlayer.seekTo(progress);
}
}
}
- Android提高之MediaPlayer播放网络音频的实现方法
- Android提高之MediaPlayer播放网络视频的实现方法
- Android提高第二十篇之MediaPlayer播放网络音频
- Android提高第二十篇之MediaPlayer播放网络音频
- Android提高篇之MediaPlayer播放网络音频
- Android提高第二十篇之MediaPlayer播放网络音频
- (转)Android提高第二十篇之MediaPlayer播放网络音频
- Android提高第二十篇之MediaPlayer播放网络音频
- Android提高第二十篇之MediaPlayer播放网络音频
- Android提高第二十篇之MediaPlayer播放网络音频
- Android提高第二十篇之MediaPlayer播放网络音频
- Android之MediaPlayer播放网络视频的实现方法
- Android提高第二十篇之MediaPlayer播放网络音频(转)
- Android 音频的播放之二MediaPlayer
- Android之MediaPlayer 音频播放
- 我的Android进阶之旅------>Android MediaPlayer播放网络音频的实例--网络mp3播放器
- Android之解决Mediaplayer播放网络音频缓冲太慢的问题
- Android提高第二十一篇之MediaPlayer播放网络视频
- 新的开始
- 3. Longest Substring Without Repeating Characters
- service本地服务
- 基于Dragonboard410c android系统实现USB camera图像预览
- plsql数据库密码过期的解决方法
- Android提高之MediaPlayer播放网络音频的实现方法
- 【指导】virtual box ubuntu 网络配置
- 基于ARM的智能灯光控制系统(2)需求分析
- 为什么学习React Native三点原因
- 启动weblogic服务时,报此时不应有“1.6(1.7)jdk”解决方法
- SpringBoot配置文件以及配置项
- at org.codehaus.plexus.archiver.AbstractArchiver$1.hasNext(AbstractArchiver.java:504)
- OJ题,后两题
- 数据结构实验之数组一:矩阵转置