Android MediaPlayer与Http Proxy结合之提高篇

Debian Unstable(Sid)实战指南:从原理到日常维护 Debian Unstable(代号Sid)并非传统意义上的‘不稳定发行版’,而是一个面向开发者与前沿技术实践者的持续集成软件流。其核心原理是基于严格的包上传验证、依赖锁死机制与testing/sid协同演进模型,确保‘最新’不等于‘不可控’。技术价值在于无缝对接上游内核、Mesa图形栈、Rust工具链等快速迭代生态,支撑硬件驱动调试、容器构建、Wayland开发等高时效性场景。本文深入解析Sid的真实可用性光谱、升级九道坎、典型故障修复范式及长期维护策略,帮助用户将Sid从高风险实验环境转化为可持续的生产 阅读详情

本文来自http://blog.youkuaiyun.com/hellogv/ ,引用必须注明出处!

       基础篇实现一个简单的代理服务器与Android的MediaPlayer结合(仅支持Http Get),可以通过代理服务器来转发MediaPlayer的Request以及传输服务器的Response,但基础篇还不能支持Seek,这次提高篇支持了Seek。代理服务器可以增强MediaPlayer对复杂的Http情况的适应,可以播放带防盗链的媒体文件,边播边存,还可以对大体积的媒体文件(如视频)进行多线程预加载,达到快速播放的效果。

       本文代码运行在模拟器上,使用Microsoft Network Monitor 3.4来抓包,通过抓包可以发现seek的操作会重新连接服务器,并在Http Get请求中加入Range 字段,所以代理服务器每次监听到MediaPlayer的request都需要新建socket与远程服务器连接。

本文的代码可以到http://download.youkuaiyun.com/detail/hellogv/4332362下载,本文程序运行效果如图:

 

 

接下来贴出核心代码HttpGetProxy.java:

public class HttpGetProxy {
	final static private String TAG = "HttpGetProxy";
	final static private String LOCAL_IP_ADDRESS = "127.0.0.1";
	final static private int HTTP_PORT = 80;
	
	private int local_ip_port;
	private ServerSocket localServer = null;
	private Socket localSocket = null;
	private Socket remoteSocket = null;
	private String remoteHost;

	private InputStream in_remoteSocket;
	private OutputStream out_remoteSocket;
	private InputStream in_localSocket;
	private OutputStream out_localSocket;

	private SocketAddress address;
	private interface OnFinishListener {
		void onFinishListener();
	}

	/**
	 * 初始化代理服务器
	 * @param localport 代理服务器监听的端口
	 */
	public HttpGetProxy(int localport) {
		local_ip_port=localport;
		try {
			localServer = new ServerSocket(localport, 1,
					InetAddress.getByName(LOCAL_IP_ADDRESS));
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 结束时,清除所有资源
	 */
	private OnFinishListener finishListener = new OnFinishListener() {

		@Override
		public void onFinishListener() {
			System.out.println("..........release all..........");
			Log.e(TAG, "..........release all..........");
			try {
				in_localSocket.close();
				out_remoteSocket.close();

				in_remoteSocket.close();
				out_localSocket.close();

				localSocket.close();
				remoteSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	};


	/**
	 * 把网络URL转为本地URL,127.0.0.1替换网络域名
	 * @param url 网络URL
	 * @return 本地URL
	 */
	public String getLocalURL(String url){
		String result = null;
		URI originalURI=URI.create(url);
		remoteHost=originalURI.getHost();
		if(originalURI.getPort()!=-1){//URL带Port
			address = new InetSocketAddress(remoteHost,
					originalURI.getPort());//使用默认端口
			result=url.replace(remoteHost+":"+originalURI.getPort(),
					LOCAL_IP_ADDRESS+":"+local_ip_port);
		}
		else{//URL不带Port
			address = new InetSocketAddress(remoteHost,
					HTTP_PORT);//使用80端口
			result=url.replace(remoteHost,LOCAL_IP_ADDRESS+":"+local_ip_port);
		}
		return result;
		
	}
	
	/**
	 * 启动代理服务器
	 * @throws IOException
	 */
	public void startProxy() throws IOException {
		
		new Thread() {
			public void run() {
				int bytes_read;
				byte[] local_request = new byte[1024];
				byte[] remote_reply = new byte[1024];
				while (true) {
					try {
						//--------------------------------------
						//监听MediaPlayer的请求,MediaPlayer->代理服务器
						//--------------------------------------
						localSocket = localServer.accept();

						Log.e(TAG, "..........localSocket connected..........");
						in_localSocket = localSocket.getInputStream();
						out_localSocket = localSocket.getOutputStream();
						Log.e(TAG, "..........init local Socket I/O..........");

						String buffer = "";//保存MediaPlayer的HTTP请求
						while ((bytes_read = in_localSocket.read(local_request)) != -1) {
							String str = new String(local_request);
							Log.e("localSocket---->", str);
							buffer = buffer + str;
							if (buffer.contains("GET")
									&& buffer.contains("\r\n\r\n")) {
								// ---把request中的本地ip改为远程ip---//
								buffer = buffer.replace(LOCAL_IP_ADDRESS,remoteHost);
								break;
							}
						}
						Log.e(TAG, "..........local finish receive..........");

						//--------------------------------------
						//把MediaPlayer的请求发到网络服务器,代理服务器->网络服务器
						//--------------------------------------
						remoteSocket = new Socket();
						remoteSocket.connect(address);
						Log.e(TAG,"..........remote Server connected..........");
						in_remoteSocket = remoteSocket.getInputStream();
						out_remoteSocket = remoteSocket.getOutputStream();
						out_remoteSocket.write(buffer.getBytes());//发送MediaPlayer的请求
						out_remoteSocket.flush();

						//------------------------------------------------------
						//把网络服务器的反馈发到MediaPlayer,网络服务器->代理服务器->MediaPlayer
						//------------------------------------------------------
						Log.e(TAG,"..........remote start to receive..........");
						while ((bytes_read = in_remoteSocket.read(remote_reply)) != -1) {
							out_localSocket.write(remote_reply, 0, bytes_read);
							out_localSocket.flush();
						}
						Log.e(TAG, "..........over..........");
						finishListener.onFinishListener();//释放资源
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}.start();
	}
}
 
Android MediaPlayer与Http Proxy结合之基础篇 如何实现一个简单的代理服务器(仅支持Http Get),与Android的MediaPlayer结合,从而可以扩展出“播放 反盗链的媒体文件”,“边播放边保存”的功能。 立即下载

相关推荐

Android MediaPlayer与Http Proxy结合之优化篇

本文是在《玩转 Android MediaPlayer之视频预加载(优化)》基础上修复Http代理服务器(Http Proxy()透传的bug。前面几篇相关文章所用的代理服务器一个时间只能监听来自Mediaplayer的一个Request请求,但在实际项目开发过程中,发现有些支持m3u8格式Mediaplayer发出新的Request请求之前不会中断旧的Request请求,所以本文代码会加入多线程监听Request请求。

Android的MediaPlayer在播放时设置Http请求头

需求       在MediaPlayer进行播放时

池塘 8948

Android 使用MediaPlayer播放视频

详情见博客:https://blog.youkuaiyun.com/qq_20785431/article/details/100543504

android 使用mediaplayer播放视频的时候设置请求头header

很简单,使用如下代码就行 Uri uri = Uri.parse("http://47.96.22.18:8002/test.pg1"); Map headers = new HashMap<>(); headers.put("sencoder", "hevc"); Map headers = new HashMap(); headers.put("U

dashen的博客 6044

Greenplum基础

CREATE DATABASE 是 SQL 命令,用于创建一个新的数据库。name 是你要创建的数据库的名称。这个名称是必须的,并且在同一个数据库服务器上必须是唯一的。可选项,OWNER 指定了新数据库的所有者,如果未指定,新数据库的所有者默认是执行该命令的用户。dbowner 是数据库所有者的用户名。可选项,TEMPLATE 指定了用于创建新数据库的模板。在 PostgreSQL 和 GreenPlum 中,通常有一个名为 template1 的默认模板。如果不指定,就会使用这个默认模板。

m0_57697768的博客 1206

【遥感数字图像处理(朱文泉)】第四章 变换域处理方法

变换域的处理方法

甜子yu的博客 4307

android mediaplay http,Android的MediaPlayer在播放时设置Http请求头

需求在MediaPlayer进行播放时需要设置特定的User-Agent。首先看StackvOerflow上的讨论,总共有2篇文章。讨论1http://stackoverflow.com/questions/8959300/how-do-i-include-http-headers-with-mediaplayer-setdatasourceThe method setDataSource(Con...

weixin_32955259的博客 720

GlobalPlatform Technology Secure Channel Protocol ‘03‘ 标准 - 安全通道协议简介

按照GlobalPlatform Technology Secure Channel Protocol '03' (SCP03)标准,描述了如何利用S-MAC,S-RMAC,S-ENC进行安全通信的过程。

mmmx777的专栏 6091

玩转 Android MediaPlayer之Media Proxy

玩转 Android MediaPlayer之Media Proxy

qq_44929301的博客 790

Python 上位机开发

首先,什么是上位机?上位机通常是指可以与下位机(如单片机、传感器等硬件设备)进行通信和交互,实现数据采集、控制指令发送以及数据处理和展示的计算机程序。 Python 作为一种高级编程语言,在开发上位机方面具有诸多优势。它拥有丰富的第三方库,使得开发过程变得相对简单和高效。

weixin_46807151的博客 4302

基于MATLAB的脑功能网络工具箱:BCT与FCLab

脑功能网络分析是神经科学领域的一个重要研究方向,它通过分析大脑中神经元之间的连接模式和信息传递方式,揭示脑网络的结构和功能。在这个领域,MATLAB是一个广泛使用的工具,提供了丰富的函数和工具箱来进行脑功能网络的分析和可视化。这些工具箱提供了丰富的函数和工具,使得脑功能网络的计算和分析变得更加简单和高效。在上述示例代码中,我们首先导入BCT工具箱,并构建一个邻接矩阵来表示脑网络的连接关系。在上述示例代码中,我们首先导入FCLab工具箱,并导入脑功能数据。函数对数据进行预处理,如去除噪声、降采样等操作。

web_bug407的博客 2608
上一篇: 适应多行长文本的Android TextView
下一篇: 玩转 Android MediaPlayer之Media Proxy
欧巴Godwin
欧巴Godwin 领域专家: 操作系统技术领域 领域专家: 操作系统技术领域
博客等级 码龄20年 9690粉丝 141原创
评论 23
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值