`

(转)Android多媒体学习七:访问网络上的Audio对应的M3U文件,实现网络音频流的播放

 
阅读更多

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

 

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

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

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

 

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

 

本文包含三个部分:

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

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

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

 

代码如下:

 

1、HttpConnect类:封装网络访问

 

package demo.camera;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.util.Log;
/**
 * 给类提供访问网络的方法
 * @author Administrator
 *
 */
public final class 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文件

 

 

package demo.camera;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
/**
 * 该类提供对M3U文件的解析
 * @author Administrator
 *
 */
public final class M3UParser {
	
	/**
	 * 从指定的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类:显示解析列表吗,并实现播放

 

package demo.camera;
import java.io.IOException;
import java.util.List;
import demo.camera.M3UParser.FilePath;
import android.app.Activity;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.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文件其实就是一个音频流的索引文件,他指向要播放的音频流的路径。
 * @author Administrator
 *
 */
public class InternetAudioDemo extends ListActivity {
	
	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权限。

 

 

转自chenjie19891104的的博客(http://blog.csdn.net/chenjie19891104/article/category/756236),以

便以后学习和查询!


 

 

分享到:
评论

相关推荐

    解析m3u播放列表对应的音乐文件

    在Android中,我们可以使用MediaPlayer类来播放网络上的音频文件,但是网络上的站点并不建议我们直接访问流,我们需要获取他提供的m3u文件,根据m3u文件来实现流的获取。 在本文中,我们将通过实例演示,Android中...

    网络电视播放列表(m3u,pls格式)

    在本文中,我们将详细探讨两种主要的播放列表格式:m3u和pls,以及它们在网络电视中的应用。 1. m3u格式 m3u是MPEG-2 Transport Stream (MPTS)或Single Program Transport Stream (SPTS)文件的播放列表格式,由...

    M3U播放列表制作工具

    4. **流媒体支持**:除了本地文件,M3U还可以包含网络流媒体地址,这意味着用户可以创建包含在线电台或其他网络音频资源的播放列表。 不过,需要注意的是,虽然M3U文件是文本格式,但某些播放器可能不支持特定的...

    android 音频播放MP3 audio

    在Android平台上,音频播放是移动应用开发中常见且重要的功能之一。本教程将重点讲解如何在Android中播放MP3格式的音频文件,包括在线音乐的获取与播放控制。以下是相关的关键知识点: 1. **Android Media ...

    C++ 播放音频流(PCM裸流)

    4. **音频播放**:C++中可以使用各种库来实现音频播放,如ALSA(Advanced Linux Sound Architecture)在Linux下,Core Audio在macOS,或Windows API在Windows上。这些库提供了API接口来发送PCM数据到音频硬件。 5. ...

    Android 音频文件播放(使用手机内置播放器播放)

    在Android平台上,开发一款应用并实现音频文件播放是一项常见的任务。本教程将深入探讨如何利用Android内置的音乐播放器来播放音频文件,这种方式无需我们自行编写复杂的音频播放逻辑,极大地简化了开发流程。 首先...

    audioplayers,同时播放多个音频文件的flutter插件(android/ios).zip

    《使用audioplayers Flutter插件实现多音频同时播放在Android和iOS平台》 在移动应用开发中,音频处理是一项常见的需求,特别是在游戏、教育、音乐类应用中。Flutter作为谷歌推出的跨平台UI工具包,提供了丰富的...

    Android多媒体应用开发实战详解:图像、音频、视频、2D和3D

    例如,MediaPlayer类用于播放音频和视频文件,Camera API用于访问和控制设备的摄像头,而SurfaceView则为显示实时视频流提供了可能。 图像处理方面,开发者需要熟悉Bitmap类,它是Android中处理图像的基本对象,...

    android下一个jni方式实现的音频播放

    本示例着重于使用JNI在Android系统中实现音频的播放功能,这是一个深入理解Android NDK(Native Development Kit)和音频处理的好教材。 首先,我们需要了解JNI的基本原理。JNI是Java平台的一部分,它提供了在Java...

    Audiotrack 播放音频流

    在Android平台上,`AudioTrack`类是用于播放音频数据的核心组件。它允许开发者将音频数据送入设备的音频硬件进行播放,支持多种音频格式。在本文中,我们将深入探讨`AudioTrack`的工作原理、使用方法以及如何处理PCM...

    android使用audioRecord和audioTrack实现语音录音播放与即时播放

    在Android平台上,开发音频应用时,我们经常需要处理声音的录制和播放功能。`AudioRecord`和`AudioTrack`是Android SDK提供的一对关键类,分别用于录音和播放音频数据。这两个类允许开发者进行低级别的音频操作,...

    C#实现播放音频流

    一个是demo,一个是库类,语音流来自百度语音合成,支持mp3类型的流播放,Pcm流,和其他的及几改,不会的问我。几组啦。是mp3流其他的流自己改!,嗯~ 然后呢调用了一下NAudio,嗯,没了,觉得好记得评论

    android多媒体学习代码

    这个“android多媒体学习代码”压缩包包含了一系列的示例项目,帮助开发者深入理解如何在Android应用中处理图像、音频、视频以及利用绘图和动画功能。下面将详细介绍这些知识点。 1. **Android绘图**: Android...

    Android P Audio系统笔记:AudioPolicy&AudioFlinger初始化

    AudioPolicy&AudioFlinger初始化总体框架初始化步骤简介初始化步骤详细流程分析1、loadConfig()2、initialize()2.1、初始音频路由引擎2.2、加载so 并且打开设备节点2.3、打开输出流 总体框架 AudioFlinger和Audio...

    Android 使用 AudioRecord 和 AudioTrack 完成音频PCM数据的采集和播放,并读写音频wav文件。

    Android 使用 AudioRecord 和 AudioTrack 完成音频PCM数据的采集和播放,并读写音频wav文件。 封装好的Java代码,可同时录制PCM和WAV文件。自己定义存储位置。 Android提供了AudioRecord和MediaRecord。MediaRecord...

    利用Audiorecorder实现录制音频文件

    Android 多媒体学习中,实现音频录制程序是一项非常重要的任务。AudioRecord 类是 Android 中的一个多媒体类,提供了录制音频文件的功能。在本文中,我们将学习如何使用 AudioRecord 类来实现音频录制程序。 首先...

    实现base64格式的amr音频文件在android微信内置浏览器的播放

    在Android平台上,微信内置浏览器对某些特定格式的音频文件支持有限,例如AMR格式。AMR(Adaptive Multi-Rate)是一种广泛用于语音编码的压缩格式,尤其在移动通信领域。由于其高效的压缩率,AMR文件在传输和存储时...

    android开发ExoPlayer播放视频和wav音频

    ExoPlayer是Android平台上一个强大的开源媒体播放器,由Google开发并维护,旨在提供更灵活、可定制的媒体播放体验,对比系统默认的MediaPlayer组件,它具有更好的性能和更多的功能。在Android应用开发中,使用...

Global site tag (gtag.js) - Google Analytics