Android MediaPlayer与Http Proxy结合之提高篇

简介: 本文来自http://blog.csdn.net/hellogv/ ,引用.        基础篇实现一个简单的代理服务器与Android的MediaPlayer结合(仅支持Http Get),可以通过代理服务器来转发MediaPlayer的Request以及传输服务器的Response,但基础篇还不能支持Seek,这次提高篇支持了Seek。

本文来自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:

[java]  view plain copy print ?
  1. public class HttpGetProxy {  
  2.     final static private String TAG = "HttpGetProxy";  
  3.     final static private String LOCAL_IP_ADDRESS = "127.0.0.1";  
  4.     final static private int HTTP_PORT = 80;  
  5.       
  6.     private int local_ip_port;  
  7.     private ServerSocket localServer = null;  
  8.     private Socket localSocket = null;  
  9.     private Socket remoteSocket = null;  
  10.     private String remoteHost;  
  11.   
  12.     private InputStream in_remoteSocket;  
  13.     private OutputStream out_remoteSocket;  
  14.     private InputStream in_localSocket;  
  15.     private OutputStream out_localSocket;  
  16.   
  17.     private SocketAddress address;  
  18.     private interface OnFinishListener {  
  19.         void onFinishListener();  
  20.     }  
  21.   
  22.     /** 
  23.      * 初始化代理服务器 
  24.      * @param localport 代理服务器监听的端口 
  25.      */  
  26.     public HttpGetProxy(int localport) {  
  27.         local_ip_port=localport;  
  28.         try {  
  29.             localServer = new ServerSocket(localport, 1,  
  30.                     InetAddress.getByName(LOCAL_IP_ADDRESS));  
  31.         } catch (UnknownHostException e) {  
  32.             // TODO Auto-generated catch block  
  33.             e.printStackTrace();  
  34.         } catch (IOException e) {  
  35.             // TODO Auto-generated catch block  
  36.             e.printStackTrace();  
  37.         }  
  38.     }  
  39.   
  40.     /** 
  41.      * 结束时,清除所有资源 
  42.      */  
  43.     private OnFinishListener finishListener = new OnFinishListener() {  
  44.   
  45.         @Override  
  46.         public void onFinishListener() {  
  47.             System.out.println("..........release all..........");  
  48.             Log.e(TAG, "..........release all..........");  
  49.             try {  
  50.                 in_localSocket.close();  
  51.                 out_remoteSocket.close();  
  52.   
  53.                 in_remoteSocket.close();  
  54.                 out_localSocket.close();  
  55.   
  56.                 localSocket.close();  
  57.                 remoteSocket.close();  
  58.             } catch (IOException e) {  
  59.                 // TODO Auto-generated catch block  
  60.                 e.printStackTrace();  
  61.             }  
  62.         }  
  63.     };  
  64.   
  65.   
  66.     /** 
  67.      * 把网络URL转为本地URL,127.0.0.1替换网络域名 
  68.      * @param url 网络URL 
  69.      * @return 本地URL 
  70.      */  
  71.     public String getLocalURL(String url){  
  72.         String result = null;  
  73.         URI originalURI=URI.create(url);  
  74.         remoteHost=originalURI.getHost();  
  75.         if(originalURI.getPort()!=-1){//URL带Port  
  76.             address = new InetSocketAddress(remoteHost,  
  77.                     originalURI.getPort());//使用默认端口  
  78.             result=url.replace(remoteHost+":"+originalURI.getPort(),  
  79.                     LOCAL_IP_ADDRESS+":"+local_ip_port);  
  80.         }  
  81.         else{//URL不带Port  
  82.             address = new InetSocketAddress(remoteHost,  
  83.                     HTTP_PORT);//使用80端口  
  84.             result=url.replace(remoteHost,LOCAL_IP_ADDRESS+":"+local_ip_port);  
  85.         }  
  86.         return result;  
  87.           
  88.     }  
  89.       
  90.     /** 
  91.      * 启动代理服务器 
  92.      * @throws IOException 
  93.      */  
  94.     public void startProxy() throws IOException {  
  95.           
  96.         new Thread() {  
  97.             public void run() {  
  98.                 int bytes_read;  
  99.                 byte[] local_request = new byte[1024];  
  100.                 byte[] remote_reply = new byte[1024];  
  101.                 while (true) {  
  102.                     try {  
  103.                         //--------------------------------------  
  104.                         //监听MediaPlayer的请求,MediaPlayer->代理服务器  
  105.                         //--------------------------------------  
  106.                         localSocket = localServer.accept();  
  107.   
  108.                         Log.e(TAG, "..........localSocket connected..........");  
  109.                         in_localSocket = localSocket.getInputStream();  
  110.                         out_localSocket = localSocket.getOutputStream();  
  111.                         Log.e(TAG, "..........init local Socket I/O..........");  
  112.   
  113.                         String buffer = "";//保存MediaPlayer的HTTP请求  
  114.                         while ((bytes_read = in_localSocket.read(local_request)) != -1) {  
  115.                             String str = new String(local_request);  
  116.                             Log.e("localSocket---->", str);  
  117.                             buffer = buffer + str;  
  118.                             if (buffer.contains("GET")  
  119.                                     && buffer.contains("\r\n\r\n")) {  
  120.                                 // ---把request中的本地ip改为远程ip---//  
  121.                                 buffer = buffer.replace(LOCAL_IP_ADDRESS,remoteHost);  
  122.                                 break;  
  123.                             }  
  124.                         }  
  125.                         Log.e(TAG, "..........local finish receive..........");  
  126.   
  127.                         //--------------------------------------  
  128.                         //把MediaPlayer的请求发到网络服务器,代理服务器->网络服务器  
  129.                         //--------------------------------------  
  130.                         remoteSocket = new Socket();  
  131.                         remoteSocket.connect(address);  
  132.                         Log.e(TAG,"..........remote Server connected..........");  
  133.                         in_remoteSocket = remoteSocket.getInputStream();  
  134.                         out_remoteSocket = remoteSocket.getOutputStream();  
  135.                         out_remoteSocket.write(buffer.getBytes());//发送MediaPlayer的请求  
  136.                         out_remoteSocket.flush();  
  137.   
  138.                         //------------------------------------------------------  
  139.                         //把网络服务器的反馈发到MediaPlayer,网络服务器->代理服务器->MediaPlayer  
  140.                         //------------------------------------------------------  
  141.                         Log.e(TAG,"..........remote start to receive..........");  
  142.                         while ((bytes_read = in_remoteSocket.read(remote_reply)) != -1) {  
  143.                             out_localSocket.write(remote_reply, 0, bytes_read);  
  144.                             out_localSocket.flush();  
  145.                         }  
  146.                         Log.e(TAG, "..........over..........");  
  147.                         finishListener.onFinishListener();//释放资源  
  148.                     } catch (IOException e) {  
  149.                         // TODO Auto-generated catch block  
  150.                         e.printStackTrace();  
  151.                     }  
  152.                 }  
  153.             }  
  154.         }.start();  
  155.     }  
  156. }  
  157.    
相关文章
|
3月前
|
缓存 网络协议 安全
49. 【Android教程】HTTP 使用详解
49. 【Android教程】HTTP 使用详解
51 1
|
3月前
|
XML API 网络安全
【安卓】在安卓中使用HTTP协议的最佳实践
【安卓】在安卓中使用HTTP协议的最佳实践
64 4
|
1月前
|
Java Spring
成功解决Initialization failed for ‘https://start.spring.io‘ Please check URL, network and proxy settings
这篇文章提供了解决Spring Initializr网站初始化失败问题的方法,包括检查URL、网络和代理设置。
成功解决Initialization failed for ‘https://start.spring.io‘ Please check URL, network and proxy settings
|
18天前
|
Android开发
Android 利用MediaPlayer实现音乐播放
本文提供了一个简单的Android MediaPlayer音乐播放示例,包括创建PlayerActivity、配置AndroidManifest.xml和activity_player.xml布局,以及实现播放和暂停功能的代码。
13 0
Android 利用MediaPlayer实现音乐播放
|
1月前
|
XML 安全 Android开发
Flutter配置Android和IOS允许http访问
Flutter配置Android和IOS允许http访问
35 3
|
2月前
|
数据采集 缓存 安全
http proxy 协议的工作原理与常见用途
在这篇博客文章中,我们将深入探讨HTTP代理协议的工作原理,揭示它如何在客户端和服务器之间传递HTTP请求和响应,并讨论它在各种应用场景中的常见用途。
http proxy 协议的工作原理与常见用途
|
1月前
|
Java Android开发 UED
安卓scheme_url调端:如果手机上多个app都注册了 http或者https 的 intent。 调端的时候,调起哪个app呢?
当多个Android应用注册了相同的URL Scheme(如http或https)时,系统会在尝试打开这类链接时展示一个选择对话框,让用户挑选偏好应用。若用户选择“始终”使用某个应用,则后续相同链接将直接由该应用处理,无需再次选择。本文以App A与App B为例,展示了如何在`AndroidManifest.xml`中配置对http与https的支持,并提供了从其他应用发起调用的示例代码。此外,还讨论了如何在系统设置中管理这些默认应用选择,以及建议开发者为避免冲突应注册更独特的Scheme。
|
3月前
|
缓存 网络协议 安全
Android网络面试题之Http基础和Http1.0的特点
**HTTP基础:GET和POST关键差异在于参数传递方式(GET在URL,POST在请求体),安全性(POST更安全),数据大小限制(POST无限制,GET有限制),速度(GET较快)及用途(GET用于获取,POST用于提交)。面试中常强调POST的安全性、数据量、数据类型支持及速度。HTTP 1.0引入了POST和HEAD方法,支持多种数据格式和缓存,但每个请求需新建TCP连接。**
40 5
|
3月前
|
安全 网络协议 算法
Android网络基础面试题之HTTPS的工作流程和原理
HTTPS简述 HTTPS基于TCP 443端口,通过CA证书确保服务器身份,使用DH算法协商对称密钥进行加密通信。流程包括TCP握手、证书验证(公钥解密,哈希对比)和数据加密传输(随机数加密,预主密钥,对称加密)。特点是安全但慢,易受特定攻击,且依赖可信的CA。每次请求可能复用Session ID以减少握手。
47 2
|
3月前
|
缓存 网络协议 Android开发
Android网络面试题之Http1.1和Http2.0
HTTP/1.1 引入持久连接和管道机制提升效率,支持分块传输编码和更多请求方式如PUT、PATCH。Host字段指定服务器域名,RANGE用于断点续传。HTTP/2变为二进制协议,实现多工处理,头信息压缩和服务器推送,减少延迟并优化资源加载。HTTP不断发展,从早期的简单传输到后来的高效交互。
43 0
Android网络面试题之Http1.1和Http2.0