diff --git a/.gitignore b/.gitignore index c3c236f..333ac58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.iml .DS_Store .gradle +.publish.sh /.idea /build diff --git a/README.md b/README.md index c45930c..93abe15 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ repositories { maven { url 'https://dl.bintray.com/alexeydanilov/maven' } } dependencies { - compile 'com.danikula:videocache:2.1.3' + compile 'com.danikula:videocache:2.1.4' } ``` @@ -59,14 +59,17 @@ More preferable way is use some dependency injector like [Dagger](http://square. See `sample` app for details. ## Whats new +### 2.1.4 +- [fix](https://github.com/danikula/AndroidVideoCache/issues/18) available cache percents callback + ### 2.1.3 - ping proxy after starting to make sure it works fine ### 2.1.2 -- fix offline work +- [fix](https://github.com/danikula/AndroidVideoCache/issues/13) offline work ### 2.1.1 -- fix for too long cache file name +- [fix](https://github.com/danikula/AndroidVideoCache/issues/14) for too long cache file name - url redirects support (thanks [ongakuer](https://github.com/ongakuer) for [PR](https://github.com/danikula/AndroidVideoCache/pull/12)) ### 2.0 diff --git a/library/build.gradle b/library/build.gradle index 6dbe8a1..6390e75 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -26,7 +26,7 @@ publish { userOrg = 'alexeydanilov' groupId = 'com.danikula' artifactId = 'videocache' - publishVersion = '2.1.3' + publishVersion = '2.1.4' description = 'Cache support for android VideoView' website = 'https://github.com/danikula/AndroidVideoCache' } diff --git a/library/src/main/java/com/danikula/videocache/HttpProxyCache.java b/library/src/main/java/com/danikula/videocache/HttpProxyCache.java index bd99b85..6bde7be 100644 --- a/library/src/main/java/com/danikula/videocache/HttpProxyCache.java +++ b/library/src/main/java/com/danikula/videocache/HttpProxyCache.java @@ -43,9 +43,6 @@ class HttpProxyCache extends ProxyCache { } out.write(buffer, 0, readBytes); offset += readBytes; - if (cache.isCompleted()) { - onCacheAvailable(100); - } } out.flush(); } @@ -68,7 +65,7 @@ class HttpProxyCache extends ProxyCache { } @Override - protected void onCacheAvailable(int percents) { + protected void onCachePercentsAvailableChanged(int percents) { if (listener != null) { listener.onCacheAvailable(cache.file, source.url, percents); } diff --git a/library/src/main/java/com/danikula/videocache/ProxyCache.java b/library/src/main/java/com/danikula/videocache/ProxyCache.java index 50c355c..1ec1613 100644 --- a/library/src/main/java/com/danikula/videocache/ProxyCache.java +++ b/library/src/main/java/com/danikula/videocache/ProxyCache.java @@ -24,9 +24,10 @@ class ProxyCache { private final Cache cache; private final Object wc = new Object(); private final Object stopLock = new Object(); + private final AtomicInteger readSourceErrorsCount; private volatile Thread sourceReaderThread; private volatile boolean stopped; - private final AtomicInteger readSourceErrorsCount; + private volatile int percentsAvailable = -1; public ProxyCache(Source source, Cache cache) { this.source = checkNotNull(source); @@ -42,7 +43,12 @@ class ProxyCache { waitForSourceData(); checkReadSourceErrorsCount(); } - return cache.read(buffer, offset, length); + int read = cache.read(buffer, offset, length); + if (cache.isCompleted() && percentsAvailable != 100) { + percentsAvailable = 100; + onCachePercentsAvailableChanged(100); + } + return read; } private void checkReadSourceErrorsCount() throws ProxyCacheException { @@ -86,22 +92,34 @@ class ProxyCache { } } - private void notifyNewCacheDataAvailable(int cachePercentage) { - onCacheAvailable(cachePercentage); + private void notifyNewCacheDataAvailable(long cacheAvailable, long sourceAvailable) { + onCacheAvailable(cacheAvailable, sourceAvailable); synchronized (wc) { wc.notifyAll(); } } - protected void onCacheAvailable(int percents) { + protected void onCacheAvailable(long cacheAvailable, long sourceAvailable) { + int percents = (int) (cacheAvailable * 100 / sourceAvailable); + boolean percentsChanged = percents != percentsAvailable; + boolean sourceLengthKnown = sourceAvailable >= 0; + if (sourceLengthKnown && percentsChanged) { + onCachePercentsAvailableChanged(percents); + } + percentsAvailable = percents; + } + + protected void onCachePercentsAvailableChanged(int percentsAvailable) { } private void readSource() { - int cachePercentage = 0; + int sourceAvailable = -1; + int offset = 0; try { - int offset = cache.available(); + offset = cache.available(); source.open(offset); + sourceAvailable = source.available(); byte[] buffer = new byte[ProxyCacheUtils.DEFAULT_BUFFER_SIZE]; int readBytes; while ((readBytes = source.read(buffer)) != -1) { @@ -112,9 +130,7 @@ class ProxyCache { cache.append(buffer, readBytes); } offset += readBytes; - cachePercentage = offset * 100 / source.available(); - - notifyNewCacheDataAvailable(cachePercentage); + notifyNewCacheDataAvailable(offset, sourceAvailable); } tryComplete(); } catch (Throwable e) { @@ -122,7 +138,7 @@ class ProxyCache { onError(e); } finally { closeSource(); - notifyNewCacheDataAvailable(cachePercentage); + notifyNewCacheDataAvailable(offset, sourceAvailable); } } diff --git a/library/src/main/java/com/danikula/videocache/Source.java b/library/src/main/java/com/danikula/videocache/Source.java index 98d1648..1aa5fbc 100644 --- a/library/src/main/java/com/danikula/videocache/Source.java +++ b/library/src/main/java/com/danikula/videocache/Source.java @@ -7,11 +7,34 @@ package com.danikula.videocache; */ public interface Source { - int available() throws ProxyCacheException; - + /** + * Opens source. Source should be open before using {@link #read(byte[])} + * + * @param offset offset in bytes for source. + * @throws ProxyCacheException if error occur while opening source. + */ void open(int offset) throws ProxyCacheException; - void close() throws ProxyCacheException; + /** + * Returns available bytes or negative value if available bytes count is unknown. + * + * @return bytes available + * @throws ProxyCacheException if error occur while fetching source data. + */ + int available() throws ProxyCacheException; + /** + * Read data to byte buffer from source with current offset. + * + * @param buffer a buffer to be used for reading data. + * @throws ProxyCacheException if error occur while reading source. + */ int read(byte[] buffer) throws ProxyCacheException; + + /** + * Closes source and release resources. Every opened source should be closed. + * + * @throws ProxyCacheException if error occur while closing source. + */ + void close() throws ProxyCacheException; } diff --git a/sample/build.gradle b/sample/build.gradle index 799a3cd..5d4a212 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -39,7 +39,7 @@ dependencies { // compile project(':library') compile 'com.android.support:support-v4:23.0.1' compile 'org.androidannotations:androidannotations-api:3.3.2' - compile 'com.danikula:videocache:2.1.3' + compile 'com.danikula:videocache:2.1.4' compile 'com.viewpagerindicator:library:2.4.2-SNAPSHOT@aar' apt 'org.androidannotations:androidannotations:3.3.2' } diff --git a/sample/src/main/java/com/danikula/videocache/sample/VideoFragment.java b/sample/src/main/java/com/danikula/videocache/sample/VideoFragment.java index c605eff..b11707a 100644 --- a/sample/src/main/java/com/danikula/videocache/sample/VideoFragment.java +++ b/sample/src/main/java/com/danikula/videocache/sample/VideoFragment.java @@ -4,6 +4,7 @@ import android.content.Context; import android.os.Handler; import android.os.Message; import android.support.v4.app.Fragment; +import android.util.Log; import android.widget.ProgressBar; import android.widget.VideoView; @@ -77,6 +78,7 @@ public class VideoFragment extends Fragment implements CacheListener { @Override public void onCacheAvailable(File file, String url, int percentsAvailable) { progressBar.setSecondaryProgress(percentsAvailable); + Log.d(LOG_TAG, String.format("onCacheAvailable. percents: %d, file: %s, url: %s", percentsAvailable, file, url)); } private void updateVideoProgress() {