mirror of
https://github.com/zhigang1992/AndroidVideoCache.git
synced 2026-03-06 22:32:57 +08:00
📦 2.6.3: return file:// proxy uri for fully cached files
This commit is contained in:
@@ -36,7 +36,7 @@ repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
compile 'com.danikula:videocache:2.6.2'
|
||||
compile 'com.danikula:videocache:2.6.3'
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ publish {
|
||||
userOrg = 'alexeydanilov'
|
||||
groupId = 'com.danikula'
|
||||
artifactId = 'videocache'
|
||||
publishVersion = '2.6.2'
|
||||
publishVersion = '2.6.3'
|
||||
description = 'Cache support for android VideoView'
|
||||
website = 'https://github.com/danikula/AndroidVideoCache'
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.danikula.videocache;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.danikula.videocache.file.DiskUsage;
|
||||
import com.danikula.videocache.file.FileNameGenerator;
|
||||
@@ -84,7 +85,37 @@ public class HttpProxyCacheServer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns url that wrap original url and should be used for client (MediaPlayer, ExoPlayer, etc).
|
||||
* <p>
|
||||
* If file for this url is fully cached (it means method {@link #isCached(String)} returns {@code true})
|
||||
* then file:// uri to cached file will be returned.
|
||||
* <p>
|
||||
* Calling this method has same effect as calling {@link #getProxyUrl(String, boolean)} with 2nd parameter set to {@code true}.
|
||||
*
|
||||
* @param url a url to file that should be cached.
|
||||
* @return a wrapped by proxy url if file is not fully cached or url pointed to cache file otherwise.
|
||||
*/
|
||||
public String getProxyUrl(String url) {
|
||||
return getProxyUrl(url, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns url that wrap original url and should be used for client (MediaPlayer, ExoPlayer, etc).
|
||||
* <p>
|
||||
* If parameter {@code allowCachedFileUri} is {@code true} and file for this url is fully cached
|
||||
* (it means method {@link #isCached(String)} returns {@code true}) then file:// uri to cached file will be returned.
|
||||
*
|
||||
* @param url a url to file that should be cached.
|
||||
* @param allowCachedFileUri {@code true} if allow to return file:// uri if url is fully cached
|
||||
* @return a wrapped by proxy url if file is not fully cached or url pointed to cache file otherwise (if {@code allowCachedFileUri} is {@code true}).
|
||||
*/
|
||||
public String getProxyUrl(String url, boolean allowCachedFileUri) {
|
||||
if (allowCachedFileUri && isCached(url)) {
|
||||
File cacheFile = getCacheFile(url);
|
||||
touchFileSafely(cacheFile);
|
||||
return Uri.fromFile(cacheFile).toString();
|
||||
}
|
||||
return isAlive() ? appendToProxyUrl(url) : url;
|
||||
}
|
||||
|
||||
@@ -127,10 +158,7 @@ public class HttpProxyCacheServer {
|
||||
*/
|
||||
public boolean isCached(String url) {
|
||||
checkNotNull(url, "Url can't be null!");
|
||||
File cacheDir = config.cacheRoot;
|
||||
String fileName = config.fileNameGenerator.generate(url);
|
||||
File cacheFile = new File(cacheDir, fileName);
|
||||
return cacheFile.exists();
|
||||
return getCacheFile(url).exists();
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
@@ -158,6 +186,20 @@ public class HttpProxyCacheServer {
|
||||
return String.format(Locale.US, "http://%s:%d/%s", PROXY_HOST, port, ProxyCacheUtils.encode(url));
|
||||
}
|
||||
|
||||
private File getCacheFile(String url) {
|
||||
File cacheDir = config.cacheRoot;
|
||||
String fileName = config.fileNameGenerator.generate(url);
|
||||
return new File(cacheDir, fileName);
|
||||
}
|
||||
|
||||
private void touchFileSafely(File cacheFile) {
|
||||
try {
|
||||
config.diskUsage.touch(cacheFile);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error touching file " + cacheFile, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void shutdownClients() {
|
||||
synchronized (clientsLock) {
|
||||
for (HttpProxyCacheServerClients clients : clientsMap.values()) {
|
||||
|
||||
@@ -38,7 +38,7 @@ dependencies {
|
||||
// compile project(':library')
|
||||
compile 'com.android.support:support-v4:23.1.0'
|
||||
compile 'org.androidannotations:androidannotations-api:3.3.2'
|
||||
compile 'com.danikula:videocache:2.6.2'
|
||||
compile 'com.danikula:videocache:2.6.3'
|
||||
compile 'com.viewpagerindicator:library:2.4.2-SNAPSHOT@aar'
|
||||
apt 'org.androidannotations:androidannotations:3.3.2'
|
||||
}
|
||||
|
||||
@@ -55,12 +55,17 @@ public class VideoFragment extends Fragment implements CacheListener {
|
||||
HttpProxyCacheServer proxy = App.getProxy(getActivity());
|
||||
boolean fullyCached = proxy.isCached(url);
|
||||
setCachedState(fullyCached);
|
||||
if (fullyCached) {
|
||||
progressBar.setSecondaryProgress(100);
|
||||
}
|
||||
}
|
||||
|
||||
private void startVideo() {
|
||||
HttpProxyCacheServer proxy = App.getProxy(getActivity());
|
||||
proxy.registerCacheListener(this, url);
|
||||
videoView.setVideoPath(proxy.getProxyUrl(url));
|
||||
String proxyUrl = proxy.getProxyUrl(url);
|
||||
Log.d(LOG_TAG, "Use proxy url " + proxyUrl + " instead of original url " + url);
|
||||
videoView.setVideoPath(proxyUrl);
|
||||
videoView.start();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.danikula.videocache;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.danikula.android.garden.io.IoUtils;
|
||||
@@ -29,6 +30,7 @@ import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_URL_
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_URL_6_REDIRECTS;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_URL_ONE_REDIRECT;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.getFileContent;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.getPort;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.loadAssetFile;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.readProxyResponse;
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
@@ -250,6 +252,50 @@ public class HttpProxyCacheServerTest extends BaseTest {
|
||||
assertThat(proxy.isCached(HTTP_DATA_URL)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProxiedUrlForEmptyCache() throws Exception {
|
||||
HttpProxyCacheServer proxy = newProxy(cacheFolder);
|
||||
String expectedUrl = "http://127.0.0.1:" + getPort(proxy) + "/" + ProxyCacheUtils.encode(HTTP_DATA_URL);
|
||||
assertThat(proxy.getProxyUrl(HTTP_DATA_URL)).isEqualTo(expectedUrl);
|
||||
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, true)).isEqualTo(expectedUrl);
|
||||
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, false)).isEqualTo(expectedUrl);
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProxiedUrlForPartialCache() throws Exception {
|
||||
File cacheDir = RuntimeEnvironment.application.getExternalCacheDir();
|
||||
File file = new File(cacheDir, new Md5FileNameGenerator().generate(HTTP_DATA_URL));
|
||||
int partialCacheSize = 1000;
|
||||
byte[] partialData = ProxyCacheTestUtils.generate(partialCacheSize);
|
||||
File partialCacheFile = ProxyCacheTestUtils.getTempFile(file);
|
||||
IoUtils.saveToFile(partialData, partialCacheFile);
|
||||
|
||||
HttpProxyCacheServer proxy = newProxy(cacheFolder);
|
||||
String expectedUrl = "http://127.0.0.1:" + getPort(proxy) + "/" + ProxyCacheUtils.encode(HTTP_DATA_URL);
|
||||
|
||||
assertThat(proxy.getProxyUrl(HTTP_DATA_URL)).isEqualTo(expectedUrl);
|
||||
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, true)).isEqualTo(expectedUrl);
|
||||
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, false)).isEqualTo(expectedUrl);
|
||||
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProxiedUrlForExistedCache() throws Exception {
|
||||
HttpProxyCacheServer proxy = newProxy(cacheFolder);
|
||||
readProxyResponse(proxy, HTTP_DATA_URL, 0);
|
||||
String proxiedUrl = "http://127.0.0.1:" + getPort(proxy) + "/" + ProxyCacheUtils.encode(HTTP_DATA_URL);
|
||||
|
||||
File cachedFile = file(cacheFolder, HTTP_DATA_URL);
|
||||
String cachedFileUri = Uri.fromFile(cachedFile).toString();
|
||||
assertThat(proxy.getProxyUrl(HTTP_DATA_URL)).isEqualTo(cachedFileUri);
|
||||
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, true)).isEqualTo(cachedFileUri);
|
||||
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, false)).isEqualTo(proxiedUrl);
|
||||
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
private Pair<File, Response> readProxyData(String url, int offset) throws IOException {
|
||||
File file = file(cacheFolder, url);
|
||||
HttpProxyCacheServer proxy = newProxy(cacheFolder);
|
||||
|
||||
@@ -5,9 +5,8 @@ import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.getPort;
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -53,12 +52,5 @@ public class PingerTest extends BaseTest {
|
||||
assertThat(out.toString()).isEqualTo("HTTP/1.1 200 OK\n\nping ok");
|
||||
}
|
||||
|
||||
private int getPort(HttpProxyCacheServer server) {
|
||||
String proxyUrl = server.getProxyUrl("test");
|
||||
Pattern pattern = Pattern.compile("http://127.0.0.1:(\\d*)/test");
|
||||
Matcher matcher = pattern.matcher(proxyUrl);
|
||||
assertThat(matcher.find()).isTrue();
|
||||
String portAsString = matcher.group(1);
|
||||
return Integer.parseInt(portAsString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
@@ -54,9 +57,9 @@ public class ProxyCacheTestUtils {
|
||||
}
|
||||
|
||||
public static Response readProxyResponse(HttpProxyCacheServer proxy, String url, int offset) throws IOException {
|
||||
String proxyUrl = proxy.getProxyUrl(url);
|
||||
String proxyUrl = proxy.getProxyUrl(url, false);
|
||||
if (!proxyUrl.startsWith("http://127.0.0.1")) {
|
||||
throw new IllegalStateException("Url " + url + " is not proxied!");
|
||||
throw new IllegalStateException("Proxy url " + proxyUrl + " is not proxied! Original url is " + url);
|
||||
}
|
||||
URL proxiedUrl = new URL(proxyUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) proxiedUrl.openConnection();
|
||||
@@ -135,4 +138,13 @@ public class ProxyCacheTestUtils {
|
||||
}).doCallRealMethod().when(spySource).read(any(byte[].class));
|
||||
return spySource;
|
||||
}
|
||||
|
||||
public static int getPort(HttpProxyCacheServer server) {
|
||||
String proxyUrl = server.getProxyUrl("test");
|
||||
Pattern pattern = Pattern.compile("http://127.0.0.1:(\\d*)/test");
|
||||
Matcher matcher = pattern.matcher(proxyUrl);
|
||||
assertThat(matcher.find()).isTrue();
|
||||
String portAsString = matcher.group(1);
|
||||
return Integer.parseInt(portAsString);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user