Android多媒体--访问网络上的Audio对应的M3U文件,实现网络音频流的播放
16lz
2021-01-23
From:http://blog.csdn.net/swdrt/article/details/8902596
Android中提供了对网络上流媒体的支持,我们可以使用MediaPlayer类来播放一个网络上的音频文件。
但是网络上的站点并不建议我们直接访问流,我们需要获取他提供的M3U文件,根据M3U文件来实现流的获取。
M3U是音频流地址索引文件,相当于播放列表。
本文通过实例演示,Android中如何访问网络上的M3U文件,实现网络音频文件的播放。
本文包含三个部分:
1、根据用户输入的M3U文件的Url,访问网络,获取该M3U文件
2、对获取到的M3U文件进行解析,Android中并没有提供现成的方法来解析M3U文件
3、显示解析结果,并利用MediaPlayer来播放列表
代码如下:
1、HttpConnect类:封装网络访问
[java] view plain copy- 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:handleexception
- e.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 plain copy- 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 plain copy- 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.ic.llnwd.net/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(){
- @Override
- publicvoidonCompletion(MediaPlayerplayer){
- //这个方法当MediaPlayer的play()执行完后触发
- player.stop();
- player.reset();
- if(pathList.size()>currPosition+1){
- currPosition++;//转到下一首
- prepareToPlay();
- }
- }
- });
- player.setOnPreparedListener(newMediaPlayer.OnPreparedListener(){
- @Override
- publicvoidonPrepared(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-generatedcatchblock
- e.printStackTrace();
- }catch(IllegalStateExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }catch(IOExceptione){
- //TODOAuto-generatedcatchblock
- e.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;
- }
- }
- }
转载自:http://blog.csdn.net/chenjie19891104/article/details/6331442
更多相关文章
- 文件操作二
- Android使用Itext生成pdf文件
- Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行
- android下创建文件夹和修改其权限的方法
- Android 将少量的数据文件保存在 data/data 目录下
- Android编译系统中头文件搜索路径的顺序问题
- Android 如何利用proc有上层想kernel写文件
- 仿微信、短信、QQ等消息数目右上角红色小圆球气泡显示(基于Androi
- Android运行时ART加载OAT文件的过程分析