Android MediaPlayer与Http Proxy结合之提高篇

2020腾讯云10周年活动,优惠非常大!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1040

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

推荐:Android MediaPlayer与Http Proxy结合之基础篇

[本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!              最近半年都忙着Android TV项目,在春节假期才有时间写点东西。先在这里给大家拜个年,祝大家

本文来自http://blog.csdn.net/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.csdn.net/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://blog.csdn.net/hellogv/ ,引用必须注明出处!  本文是在《玩转 Android MediaPlayer之视频预加载(优化)》基础上修复Http代理服务器(Http Proxy)透传的b

相关推荐