Android中提供了对网络上流媒体的支持,我们可以使用MediaPlayer类来播放一个网络上的音频文件。

但是网络上的站点并不建议我们直接访问流,我们需要获取他提供的M3U文件,根据M3U文件来实现流的获取。

M3U是音频流地址索引文件,相当于播放列表。

本文通过实例演示,Android中如何访问网络上的M3U文件,实现网络音频文件的播放。

本文包含三个部分:

1、根据用户输入的M3U文件的Url,访问网络,获取该M3U文件

2、对获取到的M3U文件进行解析,Android中并没有提供现成的方法来解析M3U文件

3、显示解析结果,并利用MediaPlayer来播放列表

代码如下:

1、HttpConnect类:封装网络访问

[java] view plaincopy
  1. package demo.camera;
  2. import java.io.BufferedReader;
  3. import java.io.InputStream;
  4. import java.io.InputStreamReader;
  5. import org.apache.http.HttpResponse;
  6. import org.apache.http.HttpStatus;
  7. import org.apache.http.client.HttpClient;
  8. import org.apache.http.client.methods.HttpGet;
  9. import org.apache.http.impl.client.DefaultHttpClient;
  10. import android.util.Log;
  11. /**
  12. * 给类提供访问网络的方法
  13. * @author Administrator
  14. *
  15. */
  16. public final class HttpConnect {
  17. /**
  18. * 利用HttpClient获取指定的Url对应的HttpResponse对象
  19. * @param url
  20. * @return
  21. */
  22. public static HttpResponse getResponseFromUrl(String url){
  23. try {
  24. HttpClient client = new DefaultHttpClient();
  25. HttpGet get = new HttpGet(url);
  26. Log.v("URI : ", get.getURI().toString());
  27. HttpResponse response = client.execute(get);
  28. if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
  29. return response;
  30. }
  31. } catch (Exception e) {
  32. // TODO: handle exception
  33. e.printStackTrace();
  34. }
  35. return null;
  36. }
  37. /**
  38. * 利用HttpClient获取指定Url对应的字符串对象
  39. * @param url
  40. * @return
  41. */
  42. public static String getStringFromUrl(String url){
  43. try {
  44. StringBuilder result = new StringBuilder();
  45. HttpResponse res = HttpConnect.getResponseFromUrl(url);
  46. if(res != null){
  47. InputStream is = res.getEntity().getContent();
  48. BufferedReader reader = new BufferedReader(new InputStreamReader(is));
  49. String line = "";
  50. while((line = reader.readLine()) != null){
  51. result.append(line);
  52. }
  53. is.close();
  54. return result.toString();
  55. }
  56. } catch (Exception e) {
  57. // TODO: handle exception
  58. }
  59. return null;
  60. }
  61. }

2、M3UParser类:解析M3U文件

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

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

[java] view plaincopy
  1. package demo.camera;
  2. import java.io.IOException;
  3. import java.util.List;
  4. import demo.camera.M3UParser.FilePath;
  5. import android.app.Activity;
  6. import android.app.ListActivity;
  7. import android.app.ProgressDialog;
  8. import android.media.MediaPlayer;
  9. import android.os.Bundle;
  10. import android.view.View;
  11. import android.view.inputmethod.InputMethodManager;
  12. import android.widget.ArrayAdapter;
  13. import android.widget.Button;
  14. import android.widget.EditText;
  15. import android.widget.ListAdapter;
  16. import android.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. * @author Administrator
  31. *
  32. */
  33. public class InternetAudioDemo extends ListActivity {
  34. private Button btnParse, btnPlay, btnStop;
  35. private EditText editUrl;
  36. private MediaPlayer player;
  37. private List<String> pathList;
  38. private int currPosition = 0; //记录当前播放的媒体文件的index
  39. //private ProgressDialog progress;
  40. public void onCreate(Bundle savedInstanceState){
  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. //      InputMethodManager imm = (InputMethodManager)this.getSystemService(INPUT_METHOD_SERVICE);
  49. //      imm.showSoftInput(editUrl, InputMethodManager.SHOW_IMPLICIT);
  50. btnPlay.setEnabled(false);
  51. btnStop.setEnabled(false);
  52. player = new MediaPlayer();
  53. player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
  54. @Override
  55. public void onCompletion(MediaPlayer player) {
  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(new MediaPlayer.OnPreparedListener() {
  66. @Override
  67. public void onPrepared(MediaPlayer arg0) {
  68. // 这个方法当MediaPlayer的prepare()执行完后触发
  69. btnStop.setEnabled(true);
  70. player.start();
  71. //当一曲播放完后,执行onCompletionListener的onCompletion方法
  72. }
  73. });
  74. }
  75. private void prepareToPlay(){
  76. try {
  77. //获取当前音频流的路径后我们需要通过MediaPlayer的setDataSource来设置,然后调用prepareAsync()来完成缓存加载
  78. String path = pathList.get(currPosition);
  79. player.setDataSource(path);
  80. //之所以使用prepareAsync是因为该方法是异步的,因为访问音频流是网络操作,在缓冲和准备播放时需要花费
  81. //较长的时间,这样用户界面就可能出现卡死的现象
  82. //该方法执行完成后,会执行onPreparedListener的onPrepared()方法。
  83. player.prepareAsync();
  84. } catch (IllegalArgumentException e) {
  85. // TODO Auto-generated catch block
  86. e.printStackTrace();
  87. } catch (IllegalStateException e) {
  88. // TODO Auto-generated catch block
  89. e.printStackTrace();
  90. } catch (IOException e) {
  91. // TODO Auto-generated catch block
  92. e.printStackTrace();
  93. }
  94. }
  95. public void onClick(View v){
  96. int id = v.getId();
  97. switch(id){
  98. case R.id.btn_parse:
  99. //完成解析
  100. //          progress = ProgressDialog.show(this, "提示", "正在解析,请稍后...");
  101. //          progress.show();
  102. String url = 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. ListAdapter adapter = new ArrayAdapter<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. case R.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. case R.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

Android多媒体学习六:访问网络上的Audio对应的M3U文件,实现网络音频流的播放相关推荐

  1. vb fso方式访问网络上的共享文件夹_经常遇见的网络故障详细分析及解决方法!...

     故障1:交换机刚加电时网络无法通信  [故障现象] 交换机刚刚开启的时候无法连接至其他网络,需要等待一段时间才可以.另外,需要使用一段时间之后,访问其他计算机的速度才快,如果有一段时间不使用网络,再 ...

  2. Android JNI学习(六)——Java与Native实战演习

    前言: 前几篇我主要介绍了jni先关的基础知识和常用API,相信看过的童靴对JNI已经有了一定的了解,如果不了解也没关系,下面我给出了链接,可以点进去学习.接下来我将实战一个完整案例,案例很简单,就是 ...

  3. 如何在网络上连接另一台计算机,如何通过网络共享连接到另一台电脑?

    网络共享就是以计算机等终端设备为载体,借助互联网这个面向公众的社会性组织,进行信息交流和资源共享,并允许他人去共享自己的劳动果实. 互联网最初的设计是为了能提供一个通讯网络,即使一些地点被核 武器摧毁 ...

  4. Android多媒体学习一:Android中Image的简单实例。

    在多媒体应用中,Image是最基础的功能模块,接下来我们将看看在Android中是如何获取和存储Image的.Android内嵌的Image获取和存储功能,可以让我们对于整个媒体框架有个比较全面的了解 ...

  5. Android多媒体学习五:调用Android自带的播放器播放Audio

    Android有其自带的播放器,我们可以使用隐式Intent来调用它:通过传入一个Action为ACTION_VIEW同时,指定Data为所要播放的Audio的Uri对象,并指定格式信息,则我们就可以 ...

  6. Android开发——相册的访问、上传以及服务端对接

    相册的访问与图片保存 1.访问相册并上传到服务器 2.下载网络图片到相册 3.这里顺便分享一手后端的对接方法 4.生产环境资源配置 5.后端项目打包     一般Android开发需要涉及到本地相册的 ...

  7. Android多媒体学习三:实现自己的Camera

    Android自带的Camera应用虽然可以满足大多数情景,但是其灵活性上还有不足.但是Android允许我们定制自己的Camera. 在Android的hardware包中有一个Camera类.这个 ...

  8. Android Framework学习(六)之RefBase,SP,WP

    Android中通过引用计数来实现智能指针,并且实现有强指针与弱指针.由对象本身来提供引用计数器,但是对象不会去维护引用计数器的值,而是由智能指针来管理. 要达到所有对象都可用引用计数器实现智能指针管 ...

  9. Android多媒体学习八:调用Android自带的音频录制程序,实现录制

    Android中有自带的音频录制程序,我们可以通过指定一个Action为MediaStore.Audio.Media.RECORD_SOUND_ACTION的Intent来 启动它就可以了.然后在on ...

最新文章

  1. docker rails mysql_MySQL 进行 Docker 容器化之体验与感悟
  2. 关于程序员的59条搞笑但却真实无比的编程语录_技术/软件
  3. linux Pytorch C++ 环境搭建
  4. php时间戳本周,php获取今天,昨天,本周,上周,本月,上月的起止时间戳
  5. Widows核心编程第一章:错误处理
  6. 苹果屏幕供应商JDI正寻求中国投资 因国内面板厂商正在崛起
  7. python有什么用-python都可以做什么用
  8. APK解包修改后,重新打包
  9. 华为电脑管家最新(11.1.1.95)版完美升级安装教程
  10. cx_oracle 字符编码,cx_oracle访问处理oracle中文乱码问题
  11. 基于对数变换和非线性变换的图像增强(图像亮度调节)
  12. 红蓝出屏3D图片,请使用红蓝眼镜观看
  13. 星淘惠跨境—从火爆现象中抓住商机是卖家应该具备的思维
  14. 基于Java+SpringBoot+Thymeleaf+Mysql校园运动场地预约系统设计与实现
  15. 活体检测的几种手段分析
  16. 2021阿里云供应链大赛--需求预测与单级库存优化参赛总结
  17. 新点软件怎么导入清单_表格软件excel怎样导入数据 | 新点软件怎么导入excel清单表格 表格有什么要求???...
  18. 上海交通大学出版社python教材答案_上海交通大学出版社python答案
  19. 数据处理如同流水——介绍下偶的数据流引擎Samsara
  20. 旅行家算法(贪心算法)

热门文章

  1. iOS开发--汉字转成没有声调也没有空格的拼音
  2. php网页是什么样,网页php开发是什么意思
  3. win10系统输入法失效打不了字怎么办
  4. 【ROS】科大讯飞语音SDK+Ubuntu16.04 + kinetic 实践报错记录及解决方案(1):cannot find -lmsc
  5. 日媒:淘宝网年成交额是eBay的2.3倍
  6. 苹果nfc功能怎么开启_苹果手机便签怎么开启企业微信群提醒 - 学显
  7. android与plc通过局域网,通过S7-1200与第三方设备实现自由口通信
  8. html5学习12:其他文本元素
  9. U3DSPACESHOOT个人重制版。代码分享(五)其他代码部分
  10. Linux操作系统高级管理