本文来自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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/** * 结束时,清除所有资源 */private OnFinishListener finishListener = new OnFinishListener() {@Overridepublic 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 blocke.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带Portaddress = new InetSocketAddress(remoteHost,originalURI.getPort());//使用默认端口result=url.replace(remoteHost+":"+originalURI.getPort(),LOCAL_IP_ADDRESS+":"+local_ip_port);}else{//URL不带Portaddress = 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 blocke.printStackTrace();}}}}.start();}}

更多相关文章

  1. 浅论Android网络请求库——android-async-http
  2. Android富文本编辑器附源码
  3. Android(安卓)网络编程 API笔记 - java.net 包相关 接口 api
  4. android中如何通过代码来开启和关闭移动网络
  5. Android拍照上传至PHP服务器并写入MySql数据库(上)
  6. Android中 网络框架Volley的用法
  7. Android(安卓)Volley 库通过网络获取 JSON 数据
  8. Android(安卓)sdk安装目录中没有platform-tools目录问题详解
  9. 简单的android ios抓包技巧

随机推荐

  1. 可以看到android源码的网站
  2. 安卓布局详细
  3. https://developers.google.com/chrome/m
  4. android中使用wakelock
  5. 一个很有深度的Android Blog
  6. Android 新手入门指导
  7. android 签名
  8. Android studio生成APK打包,修改生成APK的
  9. Android 支持的文件类型
  10. Android控件属性大全