Android实现使用流媒体播放远程mp3文件的方法
本文实例讲述了Android实现使用流媒体播放远程mp3文件的方法。分享给大家供大家参考,具体如下:
packagecom.shadow.util; importjava.io.BufferedInputStream; importjava.io.BufferedOutputStream; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.InputStream; importjava.net.URL; importjava.net.URLConnection; importjava.util.ArrayList; importjava.util.List; importcom.shadow.service.AudioPlayService.LocalBinder; importandroid.app.Service; importandroid.content.Context; importandroid.content.Intent; importandroid.media.MediaPlayer; importandroid.os.Binder; importandroid.os.Handler; importandroid.os.IBinder; importandroid.util.Log; importandroid.widget.Button; importandroid.widget.ImageButton; importandroid.widget.ProgressBar; importandroid.widget.TextView; importandroid.widget.Toast; /** *MediaPlayerdoesnotyetsupportstreamingfromexternalURLssothisclassprovidesapseudo-streamingfunction *bydownloadingthecontentincrementally&playingassoonaswegetenoughaudioinourtemporarystorage. */ publicclassStreamingMediaPlayerextendsService{ privatestaticfinalintINTIAL_KB_BUFFER=96*10/8;//assume96kbps*10secs/8bitsperbyte privateTextViewtextStreamed; privateImageButtonplayButton; privateProgressBarprogressBar; //TrackfordisplaybyprogressBar privatelongmediaLengthInKb,mediaLengthInSeconds; privateinttotalKbRead=0; //CreateHandlertocallViewupdatesonthemainUIthread. privatefinalHandlerhandler=newHandler(); privateMediaPlayermediaPlayer; privateFiledownloadingMediaFile; privatebooleanisInterrupted; privateContextcontext; privateintcounter=0; privatestaticRunnabler; privatestaticThreadplayerThread; privateLocalBinderlocalBinder=newLocalBinder(); privateMediaPlayerplayer; privatebooleanisPause=false;//播放器是否处于暂停状态 privatebooleanisSame=false;//所点播歌曲是否是当前播放歌曲 privateIntegerposition=-1;//设置播放标记 privateList<String>music_name;//歌曲列表 privateList<String>music_path; publicStreamingMediaPlayer(Contextcontext,TextViewtextStreamed,ImageButtonplayButton,ButtonstreamButton,ProgressBarprogressBar) { this.context=context; this.textStreamed=textStreamed; this.playButton=playButton; this.progressBar=progressBar; } /** *ProgressivlydownloadthemediatoatemporarylocationandupdatetheMediaPlayerasnewcontentbecomesavailable. */ publicvoidstartStreaming(finalStringmediaUrl,longmediaLengthInKb,longmediaLengthInSeconds)throwsIOException{ this.mediaLengthInKb=mediaLengthInKb; this.mediaLengthInSeconds=mediaLengthInSeconds; r=newRunnable(){ publicvoidrun(){ try{ Log.i("downloadAudioIncrement","downloadAudioIncrement"); downloadAudioIncrement(mediaUrl); }catch(IOExceptione){ Log.e(getClass().getName(),"UnabletoinitializetheMediaPlayerforfileUrl="+mediaUrl,e); return; } } }; playerThread=newThread(r); playerThread.start(); //newThread(r).start(); } /** *DownloadtheurlstreamtoatemporarylocationandthencallthesetDataSource *forthatlocalfile */ publicvoiddownloadAudioIncrement(StringmediaUrl)throwsIOException{ URLConnectioncn=newURL(mediaUrl).openConnection(); cn.addRequestProperty("User-Agent","NSPlayer/10.0.0.4072WMFSDK/10.0"); cn.connect(); InputStreamstream=cn.getInputStream(); if(stream==null){ Log.e(getClass().getName(),"UnabletocreateInputStreamformediaUrl:"+mediaUrl); } downloadingMediaFile=newFile(context.getCacheDir(),"downloadingMedia.dat"); //Justincaseapriordeletionfailedbecauseourcodecrashedorsomething,wealsodeleteanypreviously //downloadedfiletoensurewestartfresh.Ifyouusethiscode,alwaysdelete //nolongeruseddownloadselseyou'llquicklyfillupyourharddiskmemory.Ofcourse,youcanalso //storeanypreviouslydownloadedfileinaseparatedatacacheforinstantreplayifyouwantedaswell. if(downloadingMediaFile.exists()){ downloadingMediaFile.delete(); } FileOutputStreamout=newFileOutputStream(downloadingMediaFile); bytebuf[]=newbyte[16384]; inttotalBytesRead=0,incrementalBytesRead=0; do{ intnumread=stream.read(buf); if(numread<=0) break; out.write(buf,0,numread); totalBytesRead+=numread; incrementalBytesRead+=numread; totalKbRead=totalBytesRead/1000; testMediaBuffer(); fireDataLoadUpdate(); }while(validateNotInterrupted()); stream.close(); if(validateNotInterrupted()){ fireDataFullyLoaded(); } } privatebooleanvalidateNotInterrupted(){ if(isInterrupted){ if(mediaPlayer!=null){ mediaPlayer.pause(); //mediaPlayer.release(); } returnfalse; }else{ returntrue; } } /** *TestwhetherweneedtotransferbuffereddatatotheMediaPlayer. *InteractingwithMediaPlayeronnon-mainUIthreadcancausescrashestosoperformthisusingaHandler. */ privatevoidtestMediaBuffer(){ Runnableupdater=newRunnable(){ publicvoidrun(){ if(mediaPlayer==null){ //OnlycreatetheMediaPlayeroncewehavetheminimumbuffereddata if(totalKbRead>=INTIAL_KB_BUFFER){ try{ startMediaPlayer(); }catch(Exceptione){ Log.e(getClass().getName(),"Errorcopyingbufferedconent.",e); } } }elseif(mediaPlayer.getDuration()-mediaPlayer.getCurrentPosition()<=1000){ //NOTE:Themediaplayerhasstoppedattheendsotransferanyexistingbuffereddata //Wetestfor<1secondofdatabecausethemediaplayercanstopwhenthereisstill //afewmillisecondsofdatalefttoplay transferBufferToMediaPlayer(); } } }; handler.post(updater); } privatevoidstartMediaPlayer(){ try{ FilebufferedFile=newFile(context.getCacheDir(),"playingMedia"+(counter++)+".dat"); //Wedoublebufferthedatatoavoidpotentialread/writeerrorsthatcouldhappenifthe //downloadthreadattemptedtowriteatthesametimetheMediaPlayerwastryingtoread. //Forexample,wecan'tguaranteethattheMediaPlayerwon'topenafileforplayingandleaveitlockedwhile //themediaisplaying.Thiswouldpermanentlydeadlockthefiledownload.Toavoidsuchadeadloack, //wemovethecurrentlyloadeddatatoatemporarybufferfilethatwestartplayingwhiletheremaining //datadownloads. moveFile(downloadingMediaFile,bufferedFile); Log.e(getClass().getName(),"BufferedFilepath:"+bufferedFile.getAbsolutePath()); Log.e(getClass().getName(),"BufferedFilelength:"+bufferedFile.length()+""); mediaPlayer=createMediaPlayer(bufferedFile); //Wehavepre-loadedenoughcontentandstartedtheMediaPlayersoupdatethebuttons&progressmeters. mediaPlayer.start(); startPlayProgressUpdater(); playButton.setEnabled(true); }catch(IOExceptione){ Log.e(getClass().getName(),"ErrorinitializingtheMediaPlayer.",e); return; } } publicvoidpausePlayer(){ try{ getMediaPlayer().pause(); }catch(Exceptione){ e.printStackTrace(); } } publicvoidstartPlayer(){ getMediaPlayer().start(); } publicvoidstopPlayer(){ getMediaPlayer().stop(); } /** *根据文件创建一个mediaplayer对象 */ privateMediaPlayercreateMediaPlayer(FilemediaFile) throwsIOException{ MediaPlayermPlayer=newMediaPlayer(); mPlayer.setOnErrorListener( newMediaPlayer.OnErrorListener(){ publicbooleanonError(MediaPlayermp,intwhat,intextra){ Log.e(getClass().getName(),"ErrorinMediaPlayer:("+what+")withextra("+extra+")"); returnfalse; } }); //Itappearsthatforsecurity/permissionreasons,itisbettertopassaFileDescriptorratherthanadirectpathtotheFile. //AlsoIhaveseenerrorssuchas"PVMFErrNotSupported"and"Preparefailed.:status=0x1"ifafilepathStringispassedto //setDataSource().Sounlessotherwisenoted,weuseaFileDescriptorhere. FileInputStreamfis=newFileInputStream(mediaFile); mPlayer.setDataSource(fis.getFD()); mPlayer.prepare(); returnmPlayer; }
packagecom.shadow.util; importjava.io.BufferedInputStream; importjava.io.BufferedOutputStream; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.InputStream; importjava.net.URL; importjava.net.URLConnection; importjava.util.ArrayList; importjava.util.List; importcom.shadow.service.AudioPlayService.LocalBinder; importandroid.app.Service; importandroid.content.Context; importandroid.content.Intent; importandroid.media.MediaPlayer; importandroid.os.Binder; importandroid.os.Handler; importandroid.os.IBinder; importandroid.util.Log; importandroid.widget.Button; importandroid.widget.ImageButton; importandroid.widget.ProgressBar; importandroid.widget.TextView; importandroid.widget.Toast; /** *MediaPlayerdoesnotyetsupportstreamingfromexternalURLssothisclassprovidesapseudo-streamingfunction *bydownloadingthecontentincrementally&playingassoonaswegetenoughaudioinourtemporarystorage. */ publicclassStreamingMediaPlayerextendsService{ privatestaticfinalintINTIAL_KB_BUFFER=96*10/8;//assume96kbps*10secs/8bitsperbyte privateTextViewtextStreamed; privateImageButtonplayButton; privateProgressBarprogressBar; //TrackfordisplaybyprogressBar privatelongmediaLengthInKb,mediaLengthInSeconds; privateinttotalKbRead=0; //CreateHandlertocallViewupdatesonthemainUIthread. privatefinalHandlerhandler=newHandler(); privateMediaPlayermediaPlayer; privateFiledownloadingMediaFile; privatebooleanisInterrupted; privateContextcontext; privateintcounter=0; privatestaticRunnabler; privatestaticThreadplayerThread; privateLocalBinderlocalBinder=newLocalBinder(); privateMediaPlayerplayer; privatebooleanisPause=false;//播放器是否处于暂停状态 privatebooleanisSame=false;//所点播歌曲是否是当前播放歌曲 privateIntegerposition=-1;//设置播放标记 privateList<String>music_name;//歌曲列表 privateList<String>music_path; publicStreamingMediaPlayer(Contextcontext,TextViewtextStreamed,ImageButtonplayButton,ButtonstreamButton,ProgressBarprogressBar) { this.context=context; this.textStreamed=textStreamed; this.playButton=playButton; this.progressBar=progressBar; } /** *ProgressivlydownloadthemediatoatemporarylocationandupdatetheMediaPlayerasnewcontentbecomesavailable. */ publicvoidstartStreaming(finalStringmediaUrl,longmediaLengthInKb,longmediaLengthInSeconds)throwsIOException{ this.mediaLengthInKb=mediaLengthInKb; this.mediaLengthInSeconds=mediaLengthInSeconds; r=newRunnable(){ publicvoidrun(){ try{ Log.i("downloadAudioIncrement","downloadAudioIncrement"); downloadAudioIncrement(mediaUrl); }catch(IOExceptione){ Log.e(getClass().getName(),"UnabletoinitializetheMediaPlayerforfileUrl="+mediaUrl,e); return; } } }; playerThread=newThread(r); playerThread.start(); //newThread(r).start(); } /** *DownloadtheurlstreamtoatemporarylocationandthencallthesetDataSource *forthatlocalfile */ publicvoiddownloadAudioIncrement(StringmediaUrl)throwsIOException{ URLConnectioncn=newURL(mediaUrl).openConnection(); cn.addRequestProperty("User-Agent","NSPlayer/10.0.0.4072WMFSDK/10.0"); cn.connect(); InputStreamstream=cn.getInputStream(); if(stream==null){ Log.e(getClass().getName(),"UnabletocreateInputStreamformediaUrl:"+mediaUrl); } downloadingMediaFile=newFile(context.getCacheDir(),"downloadingMedia.dat"); //Justincaseapriordeletionfailedbecauseourcodecrashedorsomething,wealsodeleteanypreviously //downloadedfiletoensurewestartfresh.Ifyouusethiscode,alwaysdelete //nolongeruseddownloadselseyou'llquicklyfillupyourharddiskmemory.Ofcourse,youcanalso //storeanypreviouslydownloadedfileinaseparatedatacacheforinstantreplayifyouwantedaswell. if(downloadingMediaFile.exists()){ downloadingMediaFile.delete(); } FileOutputStreamout=newFileOutputStream(downloadingMediaFile); bytebuf[]=newbyte[16384]; inttotalBytesRead=0,incrementalBytesRead=0; do{ intnumread=stream.read(buf); if(numread<=0) break; out.write(buf,0,numread); totalBytesRead+=numread; incrementalBytesRead+=numread; totalKbRead=totalBytesRead/1000; testMediaBuffer(); fireDataLoadUpdate(); }while(validateNotInterrupted()); stream.close(); if(validateNotInterrupted()){ fireDataFullyLoaded(); } } privatebooleanvalidateNotInterrupted(){ if(isInterrupted){ if(mediaPlayer!=null){ mediaPlayer.pause(); //mediaPlayer.release(); } returnfalse; }else{ returntrue; } } /** *TestwhetherweneedtotransferbuffereddatatotheMediaPlayer. *InteractingwithMediaPlayeronnon-mainUIthreadcancausescrashestosoperformthisusingaHandler. */ privatevoidtestMediaBuffer(){ Runnableupdater=newRunnable(){ publicvoidrun(){ if(mediaPlayer==null){ //OnlycreatetheMediaPlayeroncewehavetheminimumbuffereddata if(totalKbRead>=INTIAL_KB_BUFFER){ try{ startMediaPlayer(); }catch(Exceptione){ Log.e(getClass().getName(),"Errorcopyingbufferedconent.",e); } } }elseif(mediaPlayer.getDuration()-mediaPlayer.getCurrentPosition()<=1000){ //NOTE:Themediaplayerhasstoppedattheendsotransferanyexistingbuffereddata //Wetestfor<1secondofdatabecausethemediaplayercanstopwhenthereisstill //afewmillisecondsofdatalefttoplay transferBufferToMediaPlayer(); } } }; handler.post(updater); } privatevoidstartMediaPlayer(){ try{ FilebufferedFile=newFile(context.getCacheDir(),"playingMedia"+(counter++)+".dat"); //Wedoublebufferthedatatoavoidpotentialread/writeerrorsthatcouldhappenifthe //downloadthreadattemptedtowriteatthesametimetheMediaPlayerwastryingtoread. //Forexample,wecan'tguaranteethattheMediaPlayerwon'topenafileforplayingandleaveitlockedwhile //themediaisplaying.Thiswouldpermanentlydeadlockthefiledownload.Toavoidsuchadeadloack, //wemovethecurrentlyloadeddatatoatemporarybufferfilethatwestartplayingwhiletheremaining //datadownloads. moveFile(downloadingMediaFile,bufferedFile); Log.e(getClass().getName(),"BufferedFilepath:"+bufferedFile.getAbsolutePath()); Log.e(getClass().getName(),"BufferedFilelength:"+bufferedFile.length()+""); mediaPlayer=createMediaPlayer(bufferedFile); //Wehavepre-loadedenoughcontentandstartedtheMediaPlayersoupdatethebuttons&progressmeters. mediaPlayer.start(); startPlayProgressUpdater(); playButton.setEnabled(true); }catch(IOExceptione){ Log.e(getClass().getName(),"ErrorinitializingtheMediaPlayer.",e); return; } } publicvoidpausePlayer(){ try{ getMediaPlayer().pause(); }catch(Exceptione){ e.printStackTrace(); } } publicvoidstartPlayer(){ getMediaPlayer().start(); } publicvoidstopPlayer(){ getMediaPlayer().stop(); } /** *根据文件创建一个mediaplayer对象 */ privateMediaPlayercreateMediaPlayer(FilemediaFile) throwsIOException{ MediaPlayermPlayer=newMediaPlayer(); mPlayer.setOnErrorListener( newMediaPlayer.OnErrorListener(){ publicbooleanonError(MediaPlayermp,intwhat,intextra){ Log.e(getClass().getName(),"ErrorinMediaPlayer:("+what+")withextra("+extra+")"); returnfalse; } }); //Itappearsthatforsecurity/permissionreasons,itisbettertopassaFileDescriptorratherthanadirectpathtotheFile. //AlsoIhaveseenerrorssuchas"PVMFErrNotSupported"and"Preparefailed.:status=0x1"ifafilepathStringispassedto //setDataSource().Sounlessotherwisenoted,weuseaFileDescriptorhere. FileInputStreamfis=newFileInputStream(mediaFile); mPlayer.setDataSource(fis.getFD()); mPlayer.prepare(); returnmPlayer; } /** *把缓存转化成mediaplay对象 *TransferbuffereddatatotheMediaPlayer. *NOTE:InteractingwithaMediaPlayeronanon-mainUIthreadcancausethread-lockandcrashesso *thismethodshouldalwaysbecalledusingaHandler. */ privatevoidtransferBufferToMediaPlayer(){ try{ //Firstdetermineifweneedtorestarttheplayeraftertransferringdata...e.g.perhapstheuserpressedpause booleanwasPlaying=mediaPlayer.isPlaying(); intcurPosition=mediaPlayer.getCurrentPosition(); //CopythecurrentlydownloadedcontenttoanewbufferedFile.StoretheoldFilefordeletinglater. FileoldBufferedFile=newFile(context.getCacheDir(),"playingMedia"+counter+".dat"); FilebufferedFile=newFile(context.getCacheDir(),"playingMedia"+(counter++)+".dat"); //ThismaybethelastbufferedFilesoaskthatitbedeleteonexit.Ifit'salreadydeleted,thenthiswon'tmeananything.Ifyouwantto //keepandtrackfullydownloadedfilesforlateruse,writecachingcodeandpleasesendmeacopy. bufferedFile.deleteOnExit(); moveFile(downloadingMediaFile,bufferedFile); //Pausethecurrentplayernowasweareabouttocreateandstartanewone.Sofar(Androidv1.5), //thisalwayshappenssoquicklythattheuserneverrealizedwe'vestoppedtheplayerandstartedanewone mediaPlayer.pause(); //CreateanewMediaPlayerratherthantrytore-preparethepriorone. mediaPlayer=createMediaPlayer(bufferedFile); mediaPlayer.seekTo(curPosition); //RestartifatendofpriorbufferedcontentormediaPlayerwaspreviouslyplaying. //NOTE:Wetestfor<1secondofdatabecausethemediaplayercanstopwhenthereisstill //afewmillisecondsofdatalefttoplay booleanatEndOfFile=mediaPlayer.getDuration()-mediaPlayer.getCurrentPosition()<=1000; if(wasPlaying||atEndOfFile){ mediaPlayer.start(); } //LastlydeletethepreviouslyplayingbufferedFileasit'snolongerneeded. oldBufferedFile.delete(); }catch(Exceptione){ Log.e(getClass().getName(),"Errorupdatingtonewlyloadedcontent.",e); } } privatevoidfireDataLoadUpdate(){ Runnableupdater=newRunnable(){ publicvoidrun(){ //textStreamed.setText((totalKbRead+"Kbread")); floatloadProgress=((float)totalKbRead/(float)mediaLengthInKb); //progressBar.setSecondaryProgress((int)(loadProgress*100)); } }; handler.post(updater); } privatevoidfireDataFullyLoaded(){ Runnableupdater=newRunnable(){ publicvoidrun(){ transferBufferToMediaPlayer(); //DeletethedownloadedFileasit'snowbeentransferredtothecurrentlyplayingbufferfile. downloadingMediaFile.delete(); //textStreamed.setText(("Audiofullloaded:"+totalKbRead+"Kbread")); } }; handler.post(updater); } //TODO这个方法应该可以控制歌曲的播放 publicMediaPlayergetMediaPlayer(){ returnmediaPlayer; } publicvoidstartPlayProgressUpdater(){ floatprogress=(((float)mediaPlayer.getCurrentPosition()/1000)/mediaLengthInSeconds); progressBar.setProgress((int)(progress*100)); if(mediaPlayer.isPlaying()){ Runnablenotification=newRunnable(){ publicvoidrun(){ startPlayProgressUpdater(); } }; handler.postDelayed(notification,1000); } } publicvoidinterrupt(){ playButton.setEnabled(false); isInterrupted=true; validateNotInterrupted(); } /** *MovethefileinoldLocationtonewLocation. */ publicvoidmoveFile(FileoldLocation,FilenewLocation) throwsIOException{ if(oldLocation.exists()){ BufferedInputStreamreader=newBufferedInputStream(newFileInputStream(oldLocation)); BufferedOutputStreamwriter=newBufferedOutputStream(newFileOutputStream(newLocation,false)); try{ byte[]buff=newbyte[8192]; intnumChars; while((numChars=reader.read(buff,0,buff.length))!=-1){ writer.write(buff,0,numChars); } }catch(IOExceptionex){ thrownewIOException("IOExceptionwhentransferring"+oldLocation.getPath()+"to"+newLocation.getPath()); }finally{ try{ if(reader!=null){ writer.close(); reader.close(); } }catch(IOExceptionex){ Log.e(getClass().getName(),"Errorclosingfileswhentransferring"+oldLocation.getPath()+"to"+newLocation.getPath()); } } }else{ thrownewIOException("Oldlocationdoesnotexistwhentransferring"+oldLocation.getPath()+"to"+newLocation.getPath()); } } /** *獲取service中的播放器对象 *@return播放器对象 */ publicMediaPlayergetPlayer(){ returnthis.player; } @Override publicvoidonStart(Intentintent,intstartId){ super.onStart(intent,startId); /** *1.现在需要的就是做从PlayActivity里获取歌曲列表,和歌曲路径,歌曲手名 *并存放到各个集合里 *2.之后就是对对这些数组进行处理 */ music_name=newArrayList<String>(); music_path=newArrayList<String>(); Stringinfo=intent.getStringExtra("info"); //songPath=intent.getStringExtra("songPath"); Toast.makeText(getApplicationContext(),"歌曲播放异常",Toast.LENGTH_SHORT).show(); player=newMediaPlayer(); try{ playMusic(info); }catch(Exceptione){ Toast.makeText(getApplicationContext(),"歌曲播放异常",Toast.LENGTH_SHORT).show(); e.printStackTrace(); } } //播放音乐 privatevoidplayMusic(Stringinfo)throwsException{ if("play".equals(info)){ if(isPause){//暂停后,继续播放 player.start(); isPause=false; }elseif(isSame){//如果现在播放和与所点播歌曲时同一首,继续播放所选歌曲 player.start(); }else{//点播某一首歌曲 play(); } }elseif("pause".equals(info)){ player.pause();//暂停 isPause=true; }elseif("before".equals(info)){ playBefore();//播放上一首 }elseif("after".equals(info)){ playAfter();//播放下一首 } } privatevoidplay()throwsException{ //TODO获取歌曲路径 try{ Log.i("playtest","playtest"); //myApp.setPlaying_position(position);//设置歌曲当前的播放标记 player.reset(); //player.setDataSource(songPath); player.start(); //musicName=music_name.get(position); }catch(Exceptione){ e.printStackTrace(); } } privatevoidplayBefore()throwsException{ if(position==0){ position=music_name.size()-1; }else{ position--; } play(); } privatevoidplayAfter()throwsException{ if(position==0){ position=music_name.size()+1; }else{ position++; } play(); } publicclassLocalBinderextendsBinder{ publicStreamingMediaPlayergetService(){ returnStreamingMediaPlayer.this; } } @Override publicvoidonDestroy(){ super.onDestroy(); } @Override publicbooleanonUnbind(Intentintent){ returnsuper.onUnbind(intent); } @Override publicIBinderonBind(Intentintent){ returnlocalBinder; } }
更多关于Android相关内容感兴趣的读者可查看本站专题:《Android多媒体操作技巧汇总(音频,视频,录音等)》、《Android开发入门与进阶教程》、《Android视图View技巧总结》、《Android编程之activity操作技巧总结》、《Android操作SQLite数据库技巧总结》、《Android操作json格式数据技巧总结》、《Android数据库操作技巧总结》、《Android文件操作技巧汇总》、《Android编程开发之SD卡操作方法汇总》、《Android资源操作技巧汇总》及《Android控件用法总结》
希望本文所述对大家Android程序设计有所帮助。