本文标签: Android 学习笔记
Android中提供了对网络上流媒体的支持,我们可以使用MediaPlayer类来播放一个网络上的音频文件。
但是网络上的站点并不建议我们直接访问流,我们需要获取他提供的M3U文件,根据M3U文件来实现流的获取。
M3U是音频流地址索引文件,相当于播放列表。
本文通过实例演示,Android中如何访问网络上的M3U文件,实现网络音频文件的播放。
本文包含三个部分:
1、根据用户输入的M3U文件的Url,访问网络,获取该M3U文件
2、对获取到的M3U文件进行解析,Android中并没有提供现成的方法来解析M3U文件
3、显示解析结果,并利用MediaPlayer来播放列表
代码如下:
1、HttpConnect类:封装网络访问
/**
* 利用HttpClient获取指定的Url对应的HttpResponse对象
* @param url
* @return
*/
public static HttpResponse getResponseFromUrl(String url){
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
Log.v("URI : ", get.getURI().toString());
HttpResponse response = client.execute(get);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
return response;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
/**
* 利用HttpClient获取指定Url对应的字符串对象
* @param url
* @return
*/
public static String getStringFromUrl(String url){
try {
StringBuilder result = new StringBuilder();
HttpResponse res = HttpConnect.getResponseFromUrl(url);
if(res != null){
InputStream is = res.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = "";
while((line = reader.readLine()) != null){
result.append(line);
}
is.close();
return result.toString();
}
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
}
2、M3UParser类:解析M3U文件
/**
* 从指定的Url进行解析,返回一个包含FilePath对象的列表
* FilePath封装每一个Audio路径。
* @param url
* @return
*/
public static List<FilePath> parseFromUrl(String url){
List<FilePath> resultList = null;
HttpResponse res = HttpConnect.getResponseFromUrl(url);
try {
if(res != null){
resultList = new ArrayList<M3UParser.FilePath>();
InputStream in = res.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while((line = reader.readLine()) != null){
if(line.startsWith("#")){
//这里是Metadata信息
}else if(line.length() > 0 && line.startsWith("http://")){
//这里是一个指向的音频流路径
FilePath filePath = new FilePath(line);
resultList.add(filePath);
}
}
in.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return resultList;
}
/**
* 返回List<String>类型
* @param url
* @return
*/
public static List<String> parseStringFromUrl(String url){
List<String> resultList = null;
HttpResponse res = HttpConnect.getResponseFromUrl(url);
try {
if(res != null){
resultList = new ArrayList<String>();
InputStream in = res.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while((line = reader.readLine()) != null){
if(line.startsWith("#")){
//这里是Metadata信息
}else if(line.length() > 0 && line.startsWith("http://")){
//这里是一个指向的音频流路径
resultList.add(line);
}
}
in.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return resultList;
}
//解析后的实体对象
static class FilePath{
private String filePath;
public FilePath(String filePath){
this.filePath = filePath;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
}
}
3、InternetAudioDemo类:显示解析列表吗,并实现播放
private Button btnParse, btnPlay, btnStop;
private EditText editUrl;
private MediaPlayer player;
private List<String> pathList;
private int currPosition = 0; //记录当前播放的媒体文件的index
//private ProgressDialog progress;
public void onCreate(Bundle savedInstanceState){
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");
// InputMethodManager imm = (InputMethodManager)this.getSystemService(INPUT_METHOD_SERVICE);
// imm.showSoftInput(editUrl, InputMethodManager.SHOW_IMPLICIT);
btnPlay.setEnabled(false);
btnStop.setEnabled(false);
player = new MediaPlayer();
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer player) {
// 这个方法当MediaPlayer的play()执行完后触发
player.stop();
player.reset();
if(pathList.size() > currPosition+1){
currPosition++; //转到下一首
prepareToPlay();
}
}
});
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer arg0) {
// 这个方法当MediaPlayer的prepare()执行完后触发
btnStop.setEnabled(true);
player.start();
//当一曲播放完后,执行onCompletionListener的onCompletion方法
}
});
}
private void prepareToPlay(){
try {
//获取当前音频流的路径后我们需要通过MediaPlayer的setDataSource来设置,然后调用prepareAsync()来完成缓存加载
String path = pathList.get(currPosition);
player.setDataSource(path);
//之所以使用prepareAsync是因为该方法是异步的,因为访问音频流是网络操作,在缓冲和准备播放时需要花费
//较长的时间,这样用户界面就可能出现卡死的现象
//该方法执行完成后,会执行onPreparedListener的onPrepared()方法。
player.prepareAsync();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void onClick(View v){
int id = v.getId();
switch(id){
case R.id.btn_parse:
//完成解析
// progress = ProgressDialog.show(this, "提示", "正在解析,请稍后...");
// progress.show();
String url = null;
if(editUrl.getText() != null){
url = editUrl.getText().toString();
}
if(url != null && !url.trim().equals("")){
pathList = M3UParser.parseStringFromUrl(url);
ListAdapter adapter = new ArrayAdapter<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;
case R.id.btn_start:
//这里播放是从第一个开始
btnPlay.setEnabled(false);
btnParse.setEnabled(false);
this.currPosition = 0;
if(pathList != null && pathList.size() > 0){
prepareToPlay();
}
break;
case R.id.btn_end:
player.pause();
btnPlay.setEnabled(true);
btnStop.setEnabled(false);
break;
default:
break;
}
}
}
4、需要在清单文件中加入INTERNET权限。
声明: 本文由( 张飞不张,文采横飞 )原创编译,转载请保留链接: Android多媒体学习七:访问网络上的Audio对应的M3U文件,实现网络音频流的播放
Linux系统与内核学习群:194051772
WP建站技术学习交流群:194062106
哥们,能给我这个程序的源码吗。现在正在研究Android流媒体播放的问题。谢谢.basketball520@gmail.com
2011-06-08 17:01哈,m3u可以直接拿来用了,3Q
2011-08-15 02:00不錯,受教了。其實有沒有源碼都一樣,我們最好還是自己敲敲鍵盤~
2011-08-26 15:20能不能把源码发过来,受教了。137190143@qq.com
2011-08-29 08:22