Android提高之MediaPlayer播放网络音频的实现方法
程序员文章站
2022-05-16 12:27:43
前面有文章曾经地介绍过mediaplayer的基本用法,这里就更加深入地讲解mediaplayer的在线播放功能。本文主要实现mediaplayer在线播放音频的功能,由于...
前面有文章曾经地介绍过mediaplayer的基本用法,这里就更加深入地讲解mediaplayer的在线播放功能。本文主要实现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.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程序设计起到一定的促进作用。