1+ package com .immortalplayer ;
2+ import java .io .File ;
3+ import java .io .IOException ;
4+ import java .io .RandomAccessFile ;
5+ import java .net .InetAddress ;
6+ import java .net .InetSocketAddress ;
7+ import java .net .ServerSocket ;
8+ import java .net .Socket ;
9+ import java .net .SocketAddress ;
10+ import java .net .SocketException ;
11+ import java .util .ArrayList ;
12+
13+ import com .immortalplayer .HttpGetProxyUtils .ProxyRequest ;
14+ import com .immortalplayer .HttpGetProxyUtils .ProxyResponse ;
15+
16+ import android .net .Uri ;
17+ import android .util .Log ;
18+
19+ public class HttpGetProxy {
20+
21+ final static public String TAG = "HttpGetProxy" ;
22+ final static public String LOCAL_IP_ADDRESS = "127.0.0.1" ;
23+ final static public int HTTP_PORT = 80 ;
24+ private int remotePort =-1 ;
25+ private long urlsize =0 ;
26+ private String remoteHost ;
27+ private int localPort ;
28+ public ServerSocket localServer = null ;
29+ private SocketAddress serverAddress ;
30+ private ProxyResponse proxyResponse =null ;
31+ private String mUrl ;
32+ private String mMediaFilePath , newPath ;
33+ private File file , file1 ;
34+ private Proxy proxy =null ;
35+ ArrayList <range > ranges = new ArrayList <range >();
36+ private boolean startProxy , error =false ;
37+ private Thread prox ;
38+ /**
39+ * Initialize the proxy server, and start the proxy server
40+ */
41+ public HttpGetProxy () {
42+ try {
43+ //Initialize proxy server
44+ localServer = new ServerSocket (0 , 1 ,InetAddress .getByName (LOCAL_IP_ADDRESS ));
45+ localPort =localServer .getLocalPort ();//There ServerSocket automatically assigned port
46+ startProxy ();
47+ } catch (Exception e ) {
48+ }
49+ }
50+
51+ public class range
52+ {
53+ long start =0 ;
54+ long end =0 ;
55+ public void setstart (long star )
56+ {start =star ;}
57+ public void setend (long en )
58+ {end =en ;}
59+ }
60+ /**
61+ * Get playing link
62+ */
63+ public String getLocalURL () {
64+ Uri originalURI = Uri .parse (mUrl );
65+ remoteHost = originalURI .getHost ();
66+ String localUrl = mUrl .replace (remoteHost , LOCAL_IP_ADDRESS + ":" + localPort );
67+ return localUrl ;
68+ }
69+
70+ public void stopProxy ()
71+ {
72+ try {
73+ startProxy =false ;
74+ localServer .setSoTimeout (1 );
75+ while (prox .isAlive ())
76+ {}
77+ localServer .setSoTimeout (0 );
78+ } catch (SocketException e1 ) {
79+ e1 .printStackTrace ();
80+ }
81+ }
82+
83+ public void setPaths (String dirPath , String file5 , String url , long MaxSize ,int maxnum )
84+ {
85+ new File (dirPath ).mkdirs ();
86+ Utils .asynRemoveBufferFile (dirPath , maxnum , MaxSize );
87+ mUrl =url ;
88+ mMediaFilePath = dirPath + "/" + file5 ;
89+ file = new File (dirPath + "/" + file5 );
90+ file1 = new File (dirPath + "/-" + file5 );
91+ error =false ;
92+ }
93+
94+ public void startProxy ()
95+ {
96+ startProxy =true ;
97+ Log .i (TAG , "1 start proxy" );
98+ prox =new Thread () {
99+ public void run () {
100+ while (startProxy ) {
101+ // --------------------------------------
102+ // MediaPlayer's request listening, MediaPlayer-> proxy server
103+ // --------------------------------------
104+ try {
105+ if (proxy !=null ){
106+ proxy .closeSockets ();
107+ }
108+ Socket s = localServer .accept ();
109+ if (startProxy ==false ) break ;
110+ proxy = new Proxy (s );
111+ proxy .run ();
112+ } catch (IOException e ) {
113+ Log .e (TAG , e .toString ());
114+ Log .e (TAG , Utils .getExceptionMessage (e ));
115+ }
116+ }
117+ }
118+ };
119+ prox .start ();
120+ }
121+
122+ private class Proxy {
123+ /** Socket receive requests Media Player */
124+ private Socket sckPlayer = null ;
125+ /** Socket transceiver Media Server requests */
126+ private Socket sckServer = null ;
127+
128+ public Proxy (Socket sckPlayer ){
129+ this .sckPlayer =sckPlayer ;
130+ }
131+
132+ /**
133+ * Shut down the existing links
134+ */
135+ public void closeSockets (){
136+ try {// Before starting a new request to close the past Sockets
137+ if (sckPlayer != null ){
138+ sckPlayer .close ();
139+ sckPlayer =null ;
140+ }
141+
142+ if (sckServer != null ){
143+ sckServer .close ();
144+ sckServer =null ;
145+ }
146+ } catch (IOException e1 ) {}
147+ }
148+
149+
150+
151+ public void run () {
152+ HttpParser httpParser = null ;
153+ HttpGetProxyUtils utils = null ;
154+ int bytes_read ;
155+ byte [] file_buffer = new byte [1024 ];
156+
157+ byte [] local_request = new byte [1024 ];
158+ byte [] remote_reply = new byte [1024 * 50 ];
159+ ProxyRequest request = null ;
160+ boolean sentResponseHeader = false ;
161+ boolean isExists =false ;
162+ String header ="" ;
163+ RandomAccessFile os = null , fInputStream = null ;
164+ try {
165+ httpParser = new HttpParser (remoteHost , remotePort , LOCAL_IP_ADDRESS , localPort );
166+ while ((bytes_read = sckPlayer .getInputStream ().read (
167+ local_request )) != -1 ) {
168+ byte [] buffer = httpParser .getRequestBody (local_request ,
169+ bytes_read );
170+ if (buffer != null ) {
171+ request = httpParser .getProxyRequest (buffer );
172+ break ;
173+ }
174+ }
175+ serverAddress = new InetSocketAddress (remoteHost , HTTP_PORT );
176+ utils = new HttpGetProxyUtils (sckPlayer , serverAddress );
177+ isExists = file .exists ();
178+ if (mMediaFilePath !=newPath ) {error =false ; urlsize =0 ; ranges .clear (); ranges .trimToSize (); newPath =mMediaFilePath ;}
179+
180+ //Read from file
181+ if ((isExists ) || ((file1 .exists ()) && (error ==true )))
182+ {//Send pre-loaded file to MediaPlayer
183+ Log .i (TAG , "Send cache to the MediaPlayer" );
184+ try {
185+ if ((file1 .exists ()) && (error ==true ) && (isExists ==false ))
186+ {
187+ fInputStream = new RandomAccessFile (file1 , "r" );
188+ header = "HTTP/1.1 206 Partial Content\r \n Accept-Ranges: bytes\r \n Content-Length: " +Integer .toString ((int )(file1 .length ()-request ._rangePosition ))+"\r \n Content-Range: bytes " +Integer .toString ((int )request ._rangePosition )+"-" +Integer .toString ((int )(file1 .length ()-1 ))+"/" +file1 .length ()+"\r \n Content-Type: application/octet-stream\r \n \r \n " ;
189+ } else {
190+ fInputStream = new RandomAccessFile (file , "r" );
191+ header = "HTTP/1.1 206 Partial Content\r \n Accept-Ranges: bytes\r \n Content-Length: " +Integer .toString ((int )(file .length ()-request ._rangePosition ))+"\r \n Content-Range: bytes " +Integer .toString ((int )request ._rangePosition )+"-" +Integer .toString ((int )(file .length ()-1 ))+"/" +file .length ()+"\r \n Content-Type: application/octet-stream\r \n \r \n " ;
192+ }
193+ if (request ._rangePosition > 0 ) {
194+ fInputStream .seek (request ._rangePosition );
195+ }
196+
197+ sckPlayer .getOutputStream ().write (header .getBytes (), 0 , header .length ());
198+ while (((bytes_read = fInputStream .read (file_buffer )) != -1 ) &&
199+ (sckPlayer .isClosed ()==false )) {
200+ sckPlayer .getOutputStream ().write (file_buffer , 0 , bytes_read );
201+ }
202+ sckPlayer .getOutputStream ().flush ();
203+ } catch (Exception ex ) {
204+ Log .e (TAG , Utils .getExceptionMessage (ex ));
205+ } finally {
206+ if (fInputStream != null )
207+ fInputStream .close ();
208+
209+ }
210+ return ;
211+ }
212+ } catch (IOException e1 ) {
213+ e1 .printStackTrace ();
214+ }
215+
216+ //Read from Internet
217+ try {
218+ if ((request != null ) && (isExists ==false ))
219+ {
220+ try {
221+ sckServer = utils .sentToServer (request ._body );// Send MediaPlayer's request to server
222+ } catch (Exception e ) {
223+ error =true ;
224+ if ((file1 .exists ()) && (error ==true ))
225+ {//Send pre-loaded file to MediaPlayer
226+ Log .i (TAG , "Send cache to the MediaPlayer" );
227+ try {
228+ fInputStream = new RandomAccessFile (file1 , "r" );
229+ if (request ._rangePosition > 0 ) {
230+ fInputStream .seek (request ._rangePosition );
231+ }
232+ header = "HTTP/1.1 206 Partial Content\r \n Accept-Ranges: bytes\r \n Content-Length: " +Integer .toString ((int )(file1 .length ()-request ._rangePosition ))+"\r \n Content-Range: bytes " +Integer .toString ((int )request ._rangePosition )+"-" +Integer .toString ((int )(file1 .length ()-1 ))+"/" +file1 .length ()+"\r \n Content-Type: application/octet-stream\r \n \r \n " ;
233+ sckPlayer .getOutputStream ().write (header .getBytes (), 0 , header .length ());
234+ while (((bytes_read = fInputStream .read (file_buffer )) != -1 ) &&
235+ (sckPlayer .isClosed ()==false )) {
236+ sckPlayer .getOutputStream ().write (file_buffer , 0 , bytes_read );
237+ }
238+ sckPlayer .getOutputStream ().flush ();
239+ } catch (Exception ex ) {
240+ Log .e (TAG , Utils .getExceptionMessage (ex ));
241+ } finally {
242+ if (fInputStream != null )
243+ fInputStream .close ();
244+ }
245+ }
246+ return ;
247+ }
248+ error =false ;
249+
250+ os = new RandomAccessFile (file1 , "rwd" );
251+ } else {// MediaPlayer's request is invalid
252+ closeSockets ();
253+ return ;
254+ }
255+
256+ // ------------------------------------------------------
257+ // The feedback network server sent to the MediaPlayer, network server -> Proxy -> MediaPlayer
258+ // ------------------------------------------------------
259+ while ((sckServer != null ) &&
260+ ((bytes_read = sckServer .getInputStream ().read (remote_reply )) != -1 ) &&
261+ (sckPlayer .isClosed ()==false ))
262+ {
263+ if (sentResponseHeader ) {
264+ try {// When you drag the progress bar, easy this exception, to disconnect and reconnect
265+ utils .sendToMP (remote_reply , bytes_read );
266+ os .write (remote_reply , 0 , bytes_read );
267+ proxyResponse ._currentPosition += bytes_read ;
268+ } catch (Exception e ) {
269+ Log .e (TAG , e .toString ());
270+ Log .e (TAG , Utils .getExceptionMessage (e ));
271+ break ;// Send abnormal (normal) exit while
272+ }
273+ continue ;// Exit this while
274+ }
275+ proxyResponse = httpParser .getProxyResponse (remote_reply ,
276+ bytes_read );
277+ if (proxyResponse ._duration >0 ) {urlsize =proxyResponse ._duration ;}
278+ sentResponseHeader = true ;
279+ // send http header to mediaplayer
280+ utils .sendToMP (proxyResponse ._body );
281+
282+
283+ // Send the binary data
284+ if (proxyResponse ._other != null ) {
285+ utils .sendToMP (proxyResponse ._other );
286+ os .seek (proxyResponse ._currentPosition );
287+ os .write (proxyResponse ._other , 0 , proxyResponse ._other .length );
288+ proxyResponse ._currentPosition += proxyResponse ._other .length ;
289+ }
290+ }
291+ Log .i (TAG , "END WHILE AND CLOSE SOCKETS" );
292+ // Close 2 SOCKETS
293+ closeSockets ();
294+ } catch (Exception e ) {
295+ Log .e (TAG , e .toString ());
296+ Log .e (TAG , Utils .getExceptionMessage (e ));
297+ }
298+ finally {
299+ try {
300+ if (os != null )
301+ {
302+ os .close ();
303+
304+ if (isExists ==false ) {
305+ range r =new range ();
306+ r .setstart (request ._rangePosition );
307+ r .setend (proxyResponse ._currentPosition );
308+ ranges .add (r );
309+ if (urlsize >0 ) {
310+ long h =0 ;
311+ for (int i =0 ; i <ranges .size (); i ++)
312+ {
313+ for (int i1 =0 ; i1 <ranges .size (); i1 ++)
314+ {
315+ if (ranges .get (i1 ).start <=h ) {
316+ if (ranges .get (i1 ).end >h ) h =ranges .get (i1 ).end ;
317+ }
318+
319+ }
320+ }
321+ if (urlsize ==(h -1 )) {
322+ file1 .renameTo (file );
323+ }
324+ }
325+ }
326+ }
327+ } catch (IOException e ) {
328+ e .printStackTrace ();
329+ }
330+ }
331+ }
332+ }
333+ }
0 commit comments