Android中提供了对网络上流媒体的支持,我们可以使用MediaPlayer类来播放一个网络上的音频文件。
但是网络上的站点并不建议我们直接访问流,我们需要获取他提供的M3U文件,根据M3U文件来实现流的获取。
M3U是音频流地址索引文件,相当于播放列表。
本文通过实例演示,Android中如何访问网络上的M3U文件,实现网络音频文件的播放。
本文包含三个部分:
1、根据用户输入的M3U文件的Url,访问网络,获取该M3U文件
2、对获取到的M3U文件进行解析,Android中并没有提供现成的方法来解析M3U文件
3、显示解析结果,并利用MediaPlayer来播放列表
代码如下:
1、HttpConnect类:封装网络访问
[java]view plaincopy packagedemo.camera;importjava.io.BufferedReader;importjava.io.InputStream;importjava.io.InputStreamReader;importorg.apache.http.HttpResponse;importorg.apache.http.HttpStatus;importorg.apache.http.client.HttpClient;importorg.apache.http.client.methods.HttpGet;importorg.apache.http.impl.client.DefaultHttpClient;importandroid.util.Log;/***给类提供访问网络的方法*@authorAdministrator**/publicfinalclassHttpConnect{/***利用HttpClient获取指定的Url对应的HttpResponse对象*@paramurl*@return*/publicstaticHttpResponsegetResponseFromUrl(Stringurl){try{HttpClientclient=newDefaultHttpClient();HttpGetget=newHttpGet(url);Log.v("URI:",get.getURI().toString());HttpResponseresponse=client.execute(get);if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){returnresponse;}}catch(Exceptione){//TODO:handleexceptione.printStackTrace();}returnnull;}/***利用HttpClient获取指定Url对应的字符串对象*@paramurl*@return*/publicstaticStringgetStringFromUrl(Stringurl){try{StringBuilderresult=newStringBuilder();HttpResponseres=HttpConnect.getResponseFromUrl(url);if(res!=null){InputStreamis=res.getEntity().getContent();BufferedReaderreader=newBufferedReader(newInputStreamReader(is));Stringline="";while((line=reader.readLine())!=null){result.append(line);}is.close();returnresult.toString();}}catch(Exceptione){//TODO:handleexception}returnnull;}}
2、M3UParser类:解析M3U文件
[java]view plaincopy packagedemo.camera;importjava.io.BufferedReader;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.util.ArrayList;importjava.util.List;importorg.apache.http.HttpResponse;/***该类提供对M3U文件的解析*@authorAdministrator**/publicfinalclassM3UParser{/***从指定的Url进行解析,返回一个包含FilePath对象的列表*FilePath封装每一个Audio路径。*@paramurl*@return*/publicstaticList<FilePath>parseFromUrl(Stringurl){List<FilePath>resultList=null;HttpResponseres=HttpConnect.getResponseFromUrl(url);try{if(res!=null){resultList=newArrayList<M3UParser.FilePath>();InputStreamin=res.getEntity().getContent();BufferedReaderreader=newBufferedReader(newInputStreamReader(in));Stringline="";while((line=reader.readLine())!=null){if(line.startsWith("#")){//这里是Metadata信息}elseif(line.length()>0&&line.startsWith("http://")){//这里是一个指向的音频流路径FilePathfilePath=newFilePath(line);resultList.add(filePath);}}in.close();}}catch(Exceptione){e.printStackTrace();}returnresultList;}/***返回List<String>类型*@paramurl*@return*/publicstaticList<String>parseStringFromUrl(Stringurl){List<String>resultList=null;HttpResponseres=HttpConnect.getResponseFromUrl(url);try{if(res!=null){resultList=newArrayList<String>();InputStreamin=res.getEntity().getContent();BufferedReaderreader=newBufferedReader(newInputStreamReader(in));Stringline="";while((line=reader.readLine())!=null){if(line.startsWith("#")){//这里是Metadata信息}elseif(line.length()>0&&line.startsWith("http://")){//这里是一个指向的音频流路径resultList.add(line);}}in.close();}}catch(Exceptione){e.printStackTrace();}returnresultList;}//解析后的实体对象staticclassFilePath{privateStringfilePath;publicFilePath(StringfilePath){this.filePath=filePath;}publicStringgetFilePath(){returnfilePath;}publicvoidsetFilePath(StringfilePath){this.filePath=filePath;}}}
3、InternetAudioDemo类:显示解析列表吗,并实现播放
[java]view plaincopy packagedemo.camera;importjava.io.IOException;importjava.util.List;importdemo.camera.M3UParser.FilePath;importandroid.app.Activity;importandroid.app.ListActivity;importandroid.app.ProgressDialog;importandroid.media.MediaPlayer;importandroid.os.Bundle;importandroid.view.View;importandroid.view.inputmethod.InputMethodManager;importandroid.widget.ArrayAdapter;importandroid.widget.Button;importandroid.widget.EditText;importandroid.widget.ListAdapter;importandroid.widget.Toast;/***Android支持播放网络上的Audio*访问网络上的Audio,我们通过Http需要获取音频流*这可能要涉及到ICY协议。ICY对Http协议进行了扩展*然而,网络上的站点,往往并不允许我们直接访问其音频流*我们需要一种中间文件来指向我们需要的音频流的地址,以使第三方的软件可以播放。*对于ICY流来说,其就是一个PLS文件或者一个M3U文件*PLS对应的MIME类型为:audio/x-scpls*M3U对应的MIME类型为:audio/x-mpegurl**虽然Android提供了对ICy流的支持,但是其并没有提供现成的方法来解析M3U或PLS文件*所以,为了播放网络上的音频流,我们需要自己实现这些文件的解析*M3U文件其实就是一个音频流的索引文件,他指向要播放的音频流的路径。*@authorAdministrator**/publicclassInternetAudioDemoextendsListActivity{privateButtonbtnParse,btnPlay,btnStop;privateEditTexteditUrl;privateMediaPlayerplayer;privateList<String>pathList;privateintcurrPosition=0;//记录当前播放的媒体文件的index//privateProgressDialogprogress;publicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.internet_audio);btnParse=(Button)this.findViewById(R.id.btn_parse);btnPlay=(Button)this.findViewById(R.id.btn_start);btnStop=(Button)this.findViewById(R.id.btn_end);editUrl=(EditText)this.findViewById(R.id.edit_url);editUrl.setText("http://pubint./stream/pubint_kmfa.m3u");//InputMethodManagerimm=(InputMethodManager)this.getSystemService(INPUT_METHOD_SERVICE);//imm.showSoftInput(editUrl,InputMethodManager.SHOW_IMPLICIT);btnPlay.setEnabled(false);btnStop.setEnabled(false);player=newMediaPlayer();player.setOnCompletionListener(newMediaPlayer.OnCompletionListener(){@OverridepublicvoidonCompletion(MediaPlayerplayer){//这个方法当MediaPlayer的play()执行完后触发player.stop();player.reset();if(pathList.size()>currPosition+1){currPosition++;//转到下一首prepareToPlay();}}});player.setOnPreparedListener(newMediaPlayer.OnPreparedListener(){@OverridepublicvoidonPrepared(MediaPlayerarg0){//这个方法当MediaPlayer的prepare()执行完后触发btnStop.setEnabled(true);player.start();//当一曲播放完后,执行onCompletionListener的onCompletion方法}});}privatevoidprepareToPlay(){try{//获取当前音频流的路径后我们需要通过MediaPlayer的setDataSource来设置,然后调用prepareAsync()来完成缓存加载Stringpath=pathList.get(currPosition);player.setDataSource(path);//之所以使用prepareAsync是因为该方法是异步的,因为访问音频流是网络操作,在缓冲和准备播放时需要花费//较长的时间,这样用户界面就可能出现卡死的现象//该方法执行完成后,会执行onPreparedListener的onPrepared()方法。player.prepareAsync();}catch(IllegalArgumentExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}catch(IllegalStateExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}publicvoidonClick(Viewv){intid=v.getId();switch(id){caseR.id.btn_parse://完成解析//progress=ProgressDialog.show(this,"提示","正在解析,请稍后...");//progress.show();Stringurl=null;if(editUrl.getText()!=null){url=editUrl.getText().toString();}if(url!=null&&!url.trim().equals("")){pathList=M3UParser.parseStringFromUrl(url);ListAdapteradapter=newArrayAdapter<String>(this,android.R.layout.simple_list_item_1,pathList);this.setListAdapter(adapter);btnPlay.setEnabled(true);}else{Toast.makeText(this,"请输入正确的M3U文件访问地址",Toast.LENGTH_LONG).show();}break;caseR.id.btn_start://这里播放是从第一个开始btnPlay.setEnabled(false);btnParse.setEnabled(false);this.currPosition=0;if(pathList!=null&&pathList.size()>0){prepareToPlay();}break;caseR.id.btn_end:player.pause();btnPlay.setEnabled(true);btnStop.setEnabled(false);break;default:break;}}}
转载自:/chenjie19891104/article/details/6331442
如果觉得《Android多媒体学习六:访问网络上的Audio对应的M3U文件 实现网络音频流的播放》对你有帮助,请点赞、收藏,并留下你的观点哦!