Skip to content

Commit a950e79

Browse files
committed
Better algorithm
1 parent d0bb7a4 commit a950e79

File tree

13 files changed

+377
-333
lines changed

13 files changed

+377
-333
lines changed

AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
package="com.videoplayer"
3+
package="com.immortalplayer"
44
android:versionCode="1"
55
android:versionName="1.0" >
66

@@ -18,7 +18,7 @@
1818
android:label="@string/app_name"
1919
android:theme="@style/AppTheme" >
2020
<activity
21-
android:name="com.videoplayer.MainActivity"
21+
android:name="com.immortalplayer.MainActivity"
2222
android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
2323
android:label="@string/app_name" >
2424
<intent-filter>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** Automatically generated file. DO NOT MODIFY */
2-
package com.videoplayer;
2+
package com.immortalplayer;
33

44
public final class BuildConfig {
55
public final static boolean DEBUG = true;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* should not be modified by hand.
66
*/
77

8-
package com.videoplayer;
8+
package com.immortalplayer;
99

1010
public final class R {
1111
public static final class attr {

res/layout/activity_main.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
android:id="@+id/container"
44
android:layout_width="match_parent"
55
android:layout_height="match_parent"
6-
tools:context="com.videoplayer.MainActivity"
6+
tools:context="com.immortalplayer.MainActivity"
77
tools:ignore="MergeRootFrame" />
88

res/layout/fragment_main.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
android:layout_width="match_parent"
44
android:layout_height="match_parent"
55
android:id="@+id/frame1"
6-
tools:context="com.videoplayer.MainActivity$PlaceholderFragment" >
6+
tools:context="com.immortalplayer.MainActivity$PlaceholderFragment" >
77

8-
<com.videoplayer.player
8+
<com.immortalplayer.player
99
android:id="@+id/textureView1"
1010
android:layout_width="wrap_content"
1111
android:layout_height="200dp"

res/values/strings.xml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33

4-
<string name="app_name">videoplayer</string>
5-
<string name="hello_world">Hello world!</string>
6-
<string name="action_settings">Settings</string>
4+
<string name="app_name">Immortal Player</string>
5+
<string name="action_settings">exit</string>
76
<string name="VideoView_error_text_invalid_progressive_playback">error</string>
87
<string name="VideoView_error_text_unknown">error1</string>
98
<string name="VideoView_error_button">error2</string>
Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
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\nAccept-Ranges: bytes\r\nContent-Length: "+Integer.toString((int)(file1.length()-request._rangePosition))+"\r\nContent-Range: bytes "+Integer.toString((int)request._rangePosition)+"-"+Integer.toString((int)(file1.length()-1))+"/"+file1.length()+"\r\nContent-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\nAccept-Ranges: bytes\r\nContent-Length: "+Integer.toString((int)(file.length()-request._rangePosition))+"\r\nContent-Range: bytes "+Integer.toString((int)request._rangePosition)+"-"+Integer.toString((int)(file.length()-1))+"/"+file.length()+"\r\nContent-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\nAccept-Ranges: bytes\r\nContent-Length: "+Integer.toString((int)(file1.length()-request._rangePosition))+"\r\nContent-Range: bytes "+Integer.toString((int)request._rangePosition)+"-"+Integer.toString((int)(file1.length()-1))+"/"+file1.length()+"\r\nContent-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

Comments
 (0)