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
  1. packagedemo.camera;
  2. importjava.io.BufferedReader;
  3. importjava.io.InputStream;
  4. importjava.io.InputStreamReader;
  5. importorg.apache.http.HttpResponse;
  6. importorg.apache.http.HttpStatus;
  7. importorg.apache.http.client.HttpClient;
  8. importorg.apache.http.client.methods.HttpGet;
  9. importorg.apache.http.impl.client.DefaultHttpClient;
  10. importandroid.util.Log;
  11. /**
  12. *给类提供访问网络的方法
  13. *@authorAdministrator
  14. *
  15. */
  16. publicfinalclassHttpConnect{
  17. /**
  18. *利用HttpClient获取指定的Url对应的HttpResponse对象
  19. *@paramurl
  20. *@return
  21. */
  22. publicstaticHttpResponsegetResponseFromUrl(Stringurl){
  23. try{
  24. HttpClientclient=newDefaultHttpClient();
  25. HttpGetget=newHttpGet(url);
  26. Log.v("URI:",get.getURI().toString());
  27. HttpResponseresponse=client.execute(get);
  28. if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
  29. returnresponse;
  30. }
  31. }catch(Exceptione){
  32. //TODO:handleexception
  33. e.printStackTrace();
  34. }
  35. returnnull;
  36. }
  37. /**
  38. *利用HttpClient获取指定Url对应的字符串对象
  39. *@paramurl
  40. *@return
  41. */
  42. publicstaticStringgetStringFromUrl(Stringurl){
  43. try{
  44. StringBuilderresult=newStringBuilder();
  45. HttpResponseres=HttpConnect.getResponseFromUrl(url);
  46. if(res!=null){
  47. InputStreamis=res.getEntity().getContent();
  48. BufferedReaderreader=newBufferedReader(newInputStreamReader(is));
  49. Stringline="";
  50. while((line=reader.readLine())!=null){
  51. result.append(line);
  52. }
  53. is.close();
  54. returnresult.toString();
  55. }
  56. }catch(Exceptione){
  57. //TODO:handleexception
  58. }
  59. returnnull;
  60. }
  61. }

2、M3UParser类:解析M3U文件

[java] view plain copy
  1. packagedemo.camera;
  2. importjava.io.BufferedReader;
  3. importjava.io.InputStream;
  4. importjava.io.InputStreamReader;
  5. importjava.util.ArrayList;
  6. importjava.util.List;
  7. importorg.apache.http.HttpResponse;
  8. /**
  9. *该类提供对M3U文件的解析
  10. *@authorAdministrator
  11. *
  12. */
  13. publicfinalclassM3UParser{
  14. /**
  15. *从指定的Url进行解析,返回一个包含FilePath对象的列表
  16. *FilePath封装每一个Audio路径。
  17. *@paramurl
  18. *@return
  19. */
  20. publicstaticList<FilePath>parseFromUrl(Stringurl){
  21. List<FilePath>resultList=null;
  22. HttpResponseres=HttpConnect.getResponseFromUrl(url);
  23. try{
  24. if(res!=null){
  25. resultList=newArrayList<M3UParser.FilePath>();
  26. InputStreamin=res.getEntity().getContent();
  27. BufferedReaderreader=newBufferedReader(newInputStreamReader(in));
  28. Stringline="";
  29. while((line=reader.readLine())!=null){
  30. if(line.startsWith("#")){
  31. //这里是Metadata信息
  32. }elseif(line.length()>0&&line.startsWith("http://")){
  33. //这里是一个指向的音频流路径
  34. FilePathfilePath=newFilePath(line);
  35. resultList.add(filePath);
  36. }
  37. }
  38. in.close();
  39. }
  40. }catch(Exceptione){
  41. e.printStackTrace();
  42. }
  43. returnresultList;
  44. }
  45. /**
  46. *返回List<String>类型
  47. *@paramurl
  48. *@return
  49. */
  50. publicstaticList<String>parseStringFromUrl(Stringurl){
  51. List<String>resultList=null;
  52. HttpResponseres=HttpConnect.getResponseFromUrl(url);
  53. try{
  54. if(res!=null){
  55. resultList=newArrayList<String>();
  56. InputStreamin=res.getEntity().getContent();
  57. BufferedReaderreader=newBufferedReader(newInputStreamReader(in));
  58. Stringline="";
  59. while((line=reader.readLine())!=null){
  60. if(line.startsWith("#")){
  61. //这里是Metadata信息
  62. }elseif(line.length()>0&&line.startsWith("http://")){
  63. //这里是一个指向的音频流路径
  64. resultList.add(line);
  65. }
  66. }
  67. in.close();
  68. }
  69. }catch(Exceptione){
  70. e.printStackTrace();
  71. }
  72. returnresultList;
  73. }
  74. //解析后的实体对象
  75. staticclassFilePath{
  76. privateStringfilePath;
  77. publicFilePath(StringfilePath){
  78. this.filePath=filePath;
  79. }
  80. publicStringgetFilePath(){
  81. returnfilePath;
  82. }
  83. publicvoidsetFilePath(StringfilePath){
  84. this.filePath=filePath;
  85. }
  86. }
  87. }

3、InternetAudioDemo类:显示解析列表吗,并实现播放

[java] view plain copy
  1. packagedemo.camera;
  2. importjava.io.IOException;
  3. importjava.util.List;
  4. importdemo.camera.M3UParser.FilePath;
  5. importandroid.app.Activity;
  6. importandroid.app.ListActivity;
  7. importandroid.app.ProgressDialog;
  8. importandroid.media.MediaPlayer;
  9. importandroid.os.Bundle;
  10. importandroid.view.View;
  11. importandroid.view.inputmethod.InputMethodManager;
  12. importandroid.widget.ArrayAdapter;
  13. importandroid.widget.Button;
  14. importandroid.widget.EditText;
  15. importandroid.widget.ListAdapter;
  16. importandroid.widget.Toast;
  17. /**
  18. *Android支持播放网络上的Audio
  19. *访问网络上的Audio,我们通过Http需要获取音频流
  20. *这可能要涉及到ICY协议。ICY对Http协议进行了扩展
  21. *然而,网络上的站点,往往并不允许我们直接访问其音频流
  22. *我们需要一种中间文件来指向我们需要的音频流的地址,以使第三方的软件可以播放。
  23. *对于ICY流来说,其就是一个PLS文件或者一个M3U文件
  24. *PLS对应的MIME类型为:audio/x-scpls
  25. *M3U对应的MIME类型为:audio/x-mpegurl
  26. *
  27. *虽然Android提供了对ICy流的支持,但是其并没有提供现成的方法来解析M3U或PLS文件
  28. *所以,为了播放网络上的音频流,我们需要自己实现这些文件的解析
  29. *M3U文件其实就是一个音频流的索引文件,他指向要播放的音频流的路径。
  30. *@authorAdministrator
  31. *
  32. */
  33. publicclassInternetAudioDemoextendsListActivity{
  34. privateButtonbtnParse,btnPlay,btnStop;
  35. privateEditTexteditUrl;
  36. privateMediaPlayerplayer;
  37. privateList<String>pathList;
  38. privateintcurrPosition=0;//记录当前播放的媒体文件的index
  39. //privateProgressDialogprogress;
  40. publicvoidonCreate(BundlesavedInstanceState){
  41. super.onCreate(savedInstanceState);
  42. setContentView(R.layout.internet_audio);
  43. btnParse=(Button)this.findViewById(R.id.btn_parse);
  44. btnPlay=(Button)this.findViewById(R.id.btn_start);
  45. btnStop=(Button)this.findViewById(R.id.btn_end);
  46. editUrl=(EditText)this.findViewById(R.id.edit_url);
  47. editUrl.setText("http://pubint.ic.llnwd.net/stream/pubint_kmfa.m3u");
  48. //InputMethodManagerimm=(InputMethodManager)this.getSystemService(INPUT_METHOD_SERVICE);
  49. //imm.showSoftInput(editUrl,InputMethodManager.SHOW_IMPLICIT);
  50. btnPlay.setEnabled(false);
  51. btnStop.setEnabled(false);
  52. player=newMediaPlayer();
  53. player.setOnCompletionListener(newMediaPlayer.OnCompletionListener(){
  54. @Override
  55. publicvoidonCompletion(MediaPlayerplayer){
  56. //这个方法当MediaPlayer的play()执行完后触发
  57. player.stop();
  58. player.reset();
  59. if(pathList.size()>currPosition+1){
  60. currPosition++;//转到下一首
  61. prepareToPlay();
  62. }
  63. }
  64. });
  65. player.setOnPreparedListener(newMediaPlayer.OnPreparedListener(){
  66. @Override
  67. publicvoidonPrepared(MediaPlayerarg0){
  68. //这个方法当MediaPlayer的prepare()执行完后触发
  69. btnStop.setEnabled(true);
  70. player.start();
  71. //当一曲播放完后,执行onCompletionListener的onCompletion方法
  72. }
  73. });
  74. }
  75. privatevoidprepareToPlay(){
  76. try{
  77. //获取当前音频流的路径后我们需要通过MediaPlayer的setDataSource来设置,然后调用prepareAsync()来完成缓存加载
  78. Stringpath=pathList.get(currPosition);
  79. player.setDataSource(path);
  80. //之所以使用prepareAsync是因为该方法是异步的,因为访问音频流是网络操作,在缓冲和准备播放时需要花费
  81. //较长的时间,这样用户界面就可能出现卡死的现象
  82. //该方法执行完成后,会执行onPreparedListener的onPrepared()方法。
  83. player.prepareAsync();
  84. }catch(IllegalArgumentExceptione){
  85. //TODOAuto-generatedcatchblock
  86. e.printStackTrace();
  87. }catch(IllegalStateExceptione){
  88. //TODOAuto-generatedcatchblock
  89. e.printStackTrace();
  90. }catch(IOExceptione){
  91. //TODOAuto-generatedcatchblock
  92. e.printStackTrace();
  93. }
  94. }
  95. publicvoidonClick(Viewv){
  96. intid=v.getId();
  97. switch(id){
  98. caseR.id.btn_parse:
  99. //完成解析
  100. //progress=ProgressDialog.show(this,"提示","正在解析,请稍后...");
  101. //progress.show();
  102. Stringurl=null;
  103. if(editUrl.getText()!=null){
  104. url=editUrl.getText().toString();
  105. }
  106. if(url!=null&&!url.trim().equals("")){
  107. pathList=M3UParser.parseStringFromUrl(url);
  108. ListAdapteradapter=newArrayAdapter<String>(this,android.R.layout.simple_list_item_1,pathList);
  109. this.setListAdapter(adapter);
  110. btnPlay.setEnabled(true);
  111. }else{
  112. Toast.makeText(this,"请输入正确的M3U文件访问地址",Toast.LENGTH_LONG).show();
  113. }
  114. break;
  115. caseR.id.btn_start:
  116. //这里播放是从第一个开始
  117. btnPlay.setEnabled(false);
  118. btnParse.setEnabled(false);
  119. this.currPosition=0;
  120. if(pathList!=null&&pathList.size()>0){
  121. prepareToPlay();
  122. }
  123. break;
  124. caseR.id.btn_end:
  125. player.pause();
  126. btnPlay.setEnabled(true);
  127. btnStop.setEnabled(false);
  128. break;
  129. default:
  130. break;
  131. }
  132. }
  133. }

转载自:http://blog.csdn.net/chenjie19891104/article/details/6331442

更多相关文章

  1. 文件操作二
  2. Android使用Itext生成pdf文件
  3. Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行
  4. android下创建文件夹和修改其权限的方法
  5. Android 将少量的数据文件保存在 data/data 目录下
  6. Android编译系统中头文件搜索路径的顺序问题
  7. Android 如何利用proc有上层想kernel写文件
  8. 仿微信、短信、QQ等消息数目右上角红色小圆球气泡显示(基于Androi
  9. Android运行时ART加载OAT文件的过程分析

随机推荐

  1. php base64如何进行URL字符串编码和解码?
  2. PHP实现长轮询【代码示例】
  3. PHP中数组规范和自定义集合
  4. 带你一分钟了解php的四大特性八大优势(详
  5. PHP SPL 标准库之 Countable
  6. PHP之微服务协程框架Swoft
  7. 微信PC端登录和手机端登录逻辑分享
  8. CI框架简单分页类
  9. 探讨php的垃圾回收机制
  10. 全方位解读php8.0版本优化与改进