GithubHelp home page GithubHelp logo

danikula / androidvideocache Goto Github PK

View Code? Open in Web Editor NEW
5.4K 149.0 1.1K 113.34 MB

Cache support for any video player with help of single line

License: Apache License 2.0

Java 100.00%
android video cache

androidvideocache's Introduction

Video cache support for Android

Android Arsenal Build Status Download

Table of Content

Why AndroidVideoCache?

Because there is no sense to download video a lot of times while streaming! AndroidVideoCache allows to add caching support to your VideoView/MediaPlayer, ExoPlayer or any another player with help of single line!

Features

  • caching to disk during streaming;
  • offline work with cached resources;
  • partial loading;
  • cache limits (max cache size, max files count);
  • multiple clients for same url.

Note AndroidVideoCache works only with direct urls to media file, it doesn't support any streaming technology like DASH, SmoothStreaming, HLS.

Get started

Just add dependency (AndroidVideoCache is available in jcenter):

dependencies {
    compile 'com.danikula:videocache:2.7.1'
}

and use url from proxy instead of original url for adding caching:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

    HttpProxyCacheServer proxy = getProxy();
    String proxyUrl = proxy.getProxyUrl(VIDEO_URL);
    videoView.setVideoPath(proxyUrl);
}

private HttpProxyCacheServer getProxy() {
    // should return single instance of HttpProxyCacheServer shared for whole app.
}

To guarantee normal work you should use single instance of HttpProxyCacheServer for whole app. For example you can store shared proxy in your Application:

public class App extends Application {

    private HttpProxyCacheServer proxy;

    public static HttpProxyCacheServer getProxy(Context context) {
        App app = (App) context.getApplicationContext();
        return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;
    }

    private HttpProxyCacheServer newProxy() {
        return new HttpProxyCacheServer(this);
    }
}

or use simple factory. More preferable way is use some dependency injector like Dagger.

Recipes

Disk cache limit

By default HttpProxyCacheServer uses 512Mb for caching files. You can change this value:

private HttpProxyCacheServer newProxy() {
    return new HttpProxyCacheServer.Builder(this)
            .maxCacheSize(1024 * 1024 * 1024)       // 1 Gb for cache
            .build();
}

or can limit total count of files in cache:

private HttpProxyCacheServer newProxy() {
    return new HttpProxyCacheServer.Builder(this)
            .maxCacheFilesCount(20)
            .build();
}

or even implement your own DiskUsage strategy:

private HttpProxyCacheServer newProxy() {
    return new HttpProxyCacheServer.Builder(this)
            .diskUsage(new MyCoolDiskUsageStrategy())
            .build();
}

Listen caching progress

Use HttpProxyCacheServer.registerCacheListener(CacheListener listener) method to set listener with callback onCacheAvailable(File cacheFile, String url, int percentsAvailable) to be aware of caching progress. Do not forget to to unsubscribe listener with help of HttpProxyCacheServer.unregisterCacheListener(CacheListener listener) method to avoid memory leaks.

Use HttpProxyCacheServer.isCached(String url) method to check was url's content fully cached to file or not.

See sample app for more details.

Providing names for cached files

By default AndroidVideoCache uses MD5 of video url as file name. But in some cases url is not stable and it can contain some generated parts (e.g. session token). In this case caching mechanism will be broken. To fix it you have to provide own FileNameGenerator:

public class MyFileNameGenerator implements FileNameGenerator {

    // Urls contain mutable parts (parameter 'sessionToken') and stable video's id (parameter 'videoId').
    // e. g. http://example.com?videoId=abcqaz&sessionToken=xyz987
    public String generate(String url) {
        Uri uri = Uri.parse(url);
        String videoId = uri.getQueryParameter("videoId");
        return videoId + ".mp4";
    }
}

...
HttpProxyCacheServer proxy = new HttpProxyCacheServer.Builder(context)
    .fileNameGenerator(new MyFileNameGenerator())
    .build()

Adding custom http headers

You can add custom headers to requests with help of HeadersInjector:

public class UserAgentHeadersInjector implements HeaderInjector {

    @Override
    public Map<String, String> addHeaders(String url) {
        return Maps.newHashMap("User-Agent", "Cool app v1.1");
    }
}

private HttpProxyCacheServer newProxy() {
    return new HttpProxyCacheServer.Builder(this)
            .headerInjector(new UserAgentHeadersInjector())
            .build();
}

Using exoPlayer

You can use exoPlayer with AndroidVideoCache. See sample app in exoPlayer branch. Note exoPlayer supports cache as well.

Sample

See sample app.

Known problems

  • In some cases clients can't connect to local proxy server ('Error pinging server' error). May be it is result of previous error. Note in this case video will be played, but without caching.

Whats new

See Release Notes here

Code contributions

If it's a feature that you think would need to be discussed please open an issue first, otherwise, you can follow this process:

  1. Fork the project
  2. Create a feature branch (git checkout -b my_branch)
  3. Fix a problem. Your code must contain test for reproducing problem. Your tests must be passed with help of your fix
  4. Push your changes to your new branch (git push origin my_branch)
  5. Initiate a pull request on github
  6. Rebase master branch if your local branch is not actual. Merging is not acceptable, only rebase
  7. Your pull request will be reviewed and hopefully merged :)

Where published?

Here

Questions?

[email protected]

License

Copyright 2014-2017 Alexey Danilov

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

androidvideocache's People

Contributors

arthurpalves avatar danikula avatar imalhasaranga avatar jpage4500 avatar lucas34 avatar xinydev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

androidvideocache's Issues

NPE: causing app to crash on start up

java.lang.NullPointerException: Attempt to read from field 'int com.android.okio.Segment.limit' on a null object reference
    at com.android.okio.OkBuffer.write(OkBuffer.java:574)
    at com.android.okio.OkBuffer.read(OkBuffer.java:610)
    at com.android.okio.RealBufferedSource.read(RealBufferedSource.java:53)
    at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:442)
    at com.android.okhttp.internal.Util.skipAll(Util.java:227)
    at com.android.okhttp.internal.http.HttpConnection.discard(HttpConnection.java:212)
    at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.close(HttpConnection.java:464)
    at com.android.okhttp.internal.Util.closeQuietly(Util.java:97)
    at com.android.okhttp.internal.http.HttpEngine.close(HttpEngine.java:433)
    at com.android.okhttp.internal.http.HttpURLConnectionImpl.disconnect(HttpURLConnectionImpl.java:113)
    at com.danikula.videocache.HttpUrlSource.close(HttpUrlSource.java:79)
    at com.danikula.videocache.ProxyCache.closeSource(ProxyCache.java:159)
    at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:140)
    at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19)
    at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:178)
    at java.lang.Thread.run(Thread.java:818)

So far I have only received crash reports from a single device, an HTC One (m7). According to the user, this prevents the app from opening completely. Is this device not supported? or is there any known workarounds etc?

NullPointerException on Android 5.0

hi, I encounter this exception, it seems related to new io library okio:
log detail:


01-04 15:14:41.660: E/ProxyCache(17773): ProxyCache error
01-04 15:14:41.660: E/ProxyCache(17773): java.lang.NullPointerException: Attempt to read from field 'int com.android.okio.Segment.limit' on a null object reference
01-04 15:14:41.660: E/ProxyCache(17773):    at com.android.okio.OkBuffer.write(OkBuffer.java:574)
01-04 15:14:41.660: E/ProxyCache(17773):    at com.android.okio.OkBuffer.read(OkBuffer.java:610)
01-04 15:14:41.660: E/ProxyCache(17773):    at com.android.okio.RealBufferedSource.read(RealBufferedSource.java:53)
01-04 15:14:41.660: E/ProxyCache(17773):    at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:442)
01-04 15:14:41.660: E/ProxyCache(17773):    at com.android.okio.RealBufferedSource$1.read(RealBufferedSource.java:168)
01-04 15:14:41.660: E/ProxyCache(17773):    at java.io.BufferedInputStream.read(BufferedInputStream.java:290)
01-04 15:14:41.660: E/ProxyCache(17773):    at com.danikula.videocache.HttpUrlSource.read(HttpUrlSource.java:89)
01-04 15:14:41.660: E/ProxyCache(17773):    at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:125)
01-04 15:14:41.660: E/ProxyCache(17773):    at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19)
01-04 15:14:41.660: E/ProxyCache(17773):    at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:178)
01-04 15:14:41.660: E/ProxyCache(17773):    at java.lang.Thread.run(Thread.java:831)
01-04 15:14:41.710: E/ProxyCache(17773): Error fetching info from http://xa/b/c/2Daw450.mp4
01-04 15:14:41.710: E/ProxyCache(17773): java.io.FileNotFoundException: http://xa/b/c/2Daw450.mp4
01-04 15:14:41.710: E/ProxyCache(17773):    at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:197)
01-04 15:14:41.710: E/ProxyCache(17773):    at com.danikula.videocache.HttpUrlSource.fetchContentInfo(HttpUrlSource.java:105)
01-04 15:14:41.710: E/ProxyCache(17773):    at com.danikula.videocache.HttpUrlSource.length(HttpUrlSource.java:53)
01-04 15:14:41.710: E/ProxyCache(17773):    at com.danikula.videocache.HttpProxyCache.newResponseHeaders(HttpProxyCache.java:61)
01-04 15:14:41.710: E/ProxyCache(17773):    at com.danikula.videocache.HttpProxyCache.processRequest(HttpProxyCache.java:39)
01-04 15:14:41.710: E/ProxyCache(17773):    at com.danikula.videocache.HttpProxyCacheServerClients.processRequest(HttpProxyCacheServerClients.java:42)
01-04 15:14:41.710: E/ProxyCache(17773):    at com.danikula.videocache.HttpProxyCacheServer.processSocket(HttpProxyCacheServer.java:221)
01-04 15:14:41.710: E/ProxyCache(17773):    at com.danikula.videocache.HttpProxyCacheServer.access$300(HttpProxyCacheServer.java:55)
01-04 15:14:41.710: E/ProxyCache(17773):    at com.danikula.videocache.HttpProxyCacheServer$SocketProcessorRunnable.run(HttpProxyCacheServer.java:331)
01-04 15:14:41.710: E/ProxyCache(17773):    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
01-04 15:14:41.710: E/ProxyCache(17773):    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
01-04 15:14:41.710: E/ProxyCache(17773):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
01-04 15:14:41.710: E/ProxyCache(17773):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
01-04 15:14:41.710: E/ProxyCache(17773):    at java.lang.Thread.run(Thread.java:831)

Using ProxyCache for multiple videos

hi. i play video, and in OnCompletionListener event i play other video

videoview.setOnCompletionListener(new OnCompletionListener() {

            @Override
            public void onCompletion(final MediaPlayer mp) {
                // TODO Auto-generated method stub

                    videoview.setVideoPath(proxyCache.getUrl());
                    videoview.setZOrderOnTop(false);
                    videoview.requestFocus();
                    videoview.setKeepScreenOn(true);
                    videoview.start();

            }
        });

. I see 1 exception:

05-13 06:07:12.330: E/ProxyCache(21949): ProxyCache error
05-13 06:07:12.330: E/ProxyCache(21949): com.danikula.videocache.ProxyCacheException: Error processing request
05-13 06:07:12.330: E/ProxyCache(21949): at com.danikula.videocache.HttpProxyCache.processSocket(HttpProxyCache.java:139)
05-13 06:07:12.330: E/ProxyCache(21949): at com.danikula.videocache.HttpProxyCache.access$1(HttpProxyCache.java:131)
05-13 06:07:12.330: E/ProxyCache(21949): at com.danikula.videocache.HttpProxyCache$1.run(HttpProxyCache.java:123)
05-13 06:07:12.330: E/ProxyCache(21949): at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
05-13 06:07:12.330: E/ProxyCache(21949): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
05-13 06:07:12.330: E/ProxyCache(21949): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
05-13 06:07:12.330: E/ProxyCache(21949): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
05-13 06:07:12.330: E/ProxyCache(21949): at java.lang.Thread.run(Thread.java:856)
05-13 06:07:12.330: E/ProxyCache(21949): Caused by: java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer)
05-13 06:07:12.330: E/ProxyCache(21949): at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:506)
05-13 06:07:12.330: E/ProxyCache(21949): at libcore.io.IoBridge.sendto(IoBridge.java:475)
05-13 06:07:12.330: E/ProxyCache(21949): at java.net.PlainSocketImpl.write(PlainSocketImpl.java:507)
05-13 06:07:12.330: E/ProxyCache(21949): at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
05-13 06:07:12.330: E/ProxyCache(21949): at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:269)
05-13 06:07:12.330: E/ProxyCache(21949): at java.io.BufferedOutputStream.write(BufferedOutputStream.java:131)
05-13 06:07:12.330: E/ProxyCache(21949): at com.danikula.videocache.HttpProxyCache.writeResponse(HttpProxyCache.java:157)
05-13 06:07:12.330: E/ProxyCache(21949): at com.danikula.videocache.HttpProxyCache.processSocket(HttpProxyCache.java:137)
05-13 06:07:12.330: E/ProxyCache(21949): ... 7 more
05-13 06:07:12.330: E/ProxyCache(21949): Caused by: libcore.io.ErrnoException: sendto failed: ECONNRESET (Connection reset by peer)
05-13 06:07:12.330: E/ProxyCache(21949): at libcore.io.Posix.sendtoBytes(Native Method)
05-13 06:07:12.330: E/ProxyCache(21949): at libcore.io.Posix.sendto(Posix.java:151)
05-13 06:07:12.330: E/ProxyCache(21949): at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
05-13 06:07:12.330: E/ProxyCache(21949): at libcore.io.IoBridge.sendto(IoBridge.java:473)
05-13 06:07:12.330: E/ProxyCache(21949): ... 13 more

Can't get the AndroidVideoCache to work on certain devices

Hey man, i'm currently having issues when I try to use the lib on devices such as Samsung S3 (API 18) or Nexus 4 (API 16). This is the error i'm getting on the logcat.

com.danikula.videocache.ProxyCacheException: Error using file /mnt/sdcard/Android/data/com.tar/cache/tar_gifs/http:/k30.kn3.net/taringa/1/1/5/5/8/F/vagonettas/7B9.gif.webm as disc cache
at com.danikula.videocache.FileCache.(FileCache.java:35)
at com.tar.adapters.ShoutListCursorAdapter.handleWebmReproduction(ShoutListCursorAdapter.java:1413)
at com.tar.adapters.ShoutListCursorAdapter$13.onClick(ShoutListCursorAdapter.java:684)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)

The code I used to it is similar to the one posted on the sample. Has this library been tested on older devices like the ones I´ve just mentioned? I'm using Genymotion emulator to test this. It does work with Nexus 5, both SDK 21 and 19.

Thanks in advice, hope you can help!

SocketException: Socket closed on Android L

For some reason on api level 21 and 22 some streams can't be cached. The media player seems to do some range requests and then the proxy cache tries to access a socket that has been closed.
This is not happening on api level 23. Any ideas?

I/ProxyCache: Content info for `http://feedproxy.google.com/~r/modtv/podcast/~5/dr4aovVf3pQ/CHANEL_S16.m4v`: mime: video/mp4, content-length: 189174193
D/ProxyCache: buffered 2
D/ProxyCache: Open connection  with offset 3958950 to http://feedproxy.google.com/~r/modtv/podcast/~5/dr4aovVf3pQ/CHANEL_S16.m4v
D/ProxyCache: buffered 2
D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=47998,localPort=49705]
I/ProxyCache: Request to cache proxy:GetRequest{rangeOffset=188912049, partial=true, uri='http%3A%2F%2Ffeedproxy.google.com%2F%7Er%2Fmodtv%2Fpodcast%2F%7E5%2Fdr4aovVf3pQ%2FCHANEL_S16.m4v'}
D/ProxyCache: Open connection  with offset 188912049 to http://feedproxy.google.com/~r/modtv/podcast/~5/dr4aovVf3pQ/CHANEL_S16.m4v
D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=39932,localPort=49705]
I/ProxyCache: Request to cache proxy:GetRequest{rangeOffset=188912049, partial=true, uri='http%3A%2F%2Ffeedproxy.google.com%2F%7Er%2Fmodtv%2Fpodcast%2F%7E5%2Fdr4aovVf3pQ%2FCHANEL_S16.m4v'}
D/ProxyCache: Open connection  with offset 188912049 to http://feedproxy.google.com/~r/modtv/podcast/~5/dr4aovVf3pQ/CHANEL_S16.m4v
D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=42035,localPort=49705]
I/ProxyCache: Request to cache proxy:GetRequest{rangeOffset=188912049, partial=true, uri='http%3A%2F%2Ffeedproxy.google.com%2F%7Er%2Fmodtv%2Fpodcast%2F%7E5%2Fdr4aovVf3pQ%2FCHANEL_S16.m4v'}
D/ProxyCache: Open connection  with offset 188912049 to http://feedproxy.google.com/~r/modtv/podcast/~5/dr4aovVf3pQ/CHANEL_S16.m4v
D/ProxyCache: Closing socket… Socket is closed by client.
D/ProxyCache: Releasing input stream… Socket is closed by client.
D/ProxyCache: Opened connections: 5
D/ProxyCache: Closing socket… Socket is closed by client.
D/ProxyCache: Releasing input stream… Socket is closed by client.
D/ProxyCache: Opened connections: 4
D/ProxyCache: Closing socket… Socket is closed by client.
D/ProxyCache: Releasing input stream… Socket is closed by client.
D/ProxyCache: Opened connections: 3
E/ProxyCache: ProxyCache error
com.danikula.videocache.ProxyCacheException: Error reading data from http://feedproxy.google.com/~r/modtv/podcast/~5/dr4aovVf3pQ/CHANEL_S16.m4v
at com.danikula.videocache.HttpUrlSource.read(HttpUrlSource.java:98)
at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:126)
at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19)
at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:179)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.net.SocketException: Socket closed
at libcore.io.Posix.recvfromBytes(Native Method)
at libcore.io.Posix.recvfrom(Posix.java:185)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:250)
at libcore.io.IoBridge.recvfrom(IoBridge.java:553)
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:485)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at okio.Okio$2.read(Okio.java:139)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at okio.RealBufferedSource.read(RealBufferedSource.java:50)
at com.squareup.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:418)
at okio.RealBufferedSource$1.read(RealBufferedSource.java:371)
at java.io.BufferedInputStream.read(BufferedInputStream.java:290)
at com.danikula.videocache.HttpUrlSource.read(HttpUrlSource.java:94)
at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:126) 
at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19) 
at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:179) 
at java.lang.Thread.run(Thread.java:818) 
D/ProxyCache: Opened connections: 2

Implement a DiskLruCache that monitors the space used

As stated in getExternalCacheDir()'s documentation, the platform usually doesn't clean the external cache directory automatically. Thus, something like a DiskLruCache where you could specify the maximum size that you want the cache to store would be very useful. JakeWharton's DiskLruCache could be a very good starting point for this.

Error pinging server

Hi, i am getting the following ex;

10-18 15:41:08.993  22772-22772/com.android.** I/ProxyCache﹕ Proxy cache server started. Ping it...
10-18 15:41:08.997  22772-22900/com.android.** D/ProxyCache﹕ Open connection  to http://127.0.0.1:55999/ping
10-18 15:41:09.198  22772-22772/com.android.** E/ProxyCache﹕ Error pinging server [attempt: 0, timeout: 200].
    java.util.concurrent.TimeoutException
            at java.util.concurrent.FutureTask.get(FutureTask.java:176)
            at com.danikula.videocache.HttpProxyCacheServer.makeSureServerWorks(HttpProxyCacheServer.java:87)
            at com.danikula.videocache.HttpProxyCacheServer.<init>(HttpProxyCacheServer.java:73)
            at com.android.**.code.AApplication.newProxy(AApplication.java:45)
            at com.android.**.code.AApplication.getProxy(AApplication.java:40)
            at com.android.**.code.activity.Splash.getNextAd(Splash.java:118)
            at com.android.**.code.activity.Splash.access$000(Splash.java:44)
            at com.android.**.code.activity.Splash$1.onSuccess(Splash.java:91)
            at com.android.**.code.activity.Splash$1.onSuccess(Splash.java:83)
            at com.android.**.code.retrofit.RetrofitCallback.success(RetrofitCallback.java:87)
            at retrofit.CallbackRunnable$1.run(CallbackRunnable.java:45)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

What does it mean? how can i solve this problem? Thank yoouuu.

Closing incorrect source for new partial response without cache

This library use one HttpProxyCacheServerClients for same url ,for every single request,the HttpProxyCacheServer start a new thread to handle the request,so there would be more than one thread running with HttpProxyCacheServerClients.processRequest().
For partial request,it will go like this:
HttpProxyCacheServerClients.processRequest()->
HttpProxyCache.processRequest()->
HttpProxyCache.responseWithoutCache(),
here is the code of "responseWithoutCache()" method:

private void responseWithoutCache(OutputStream out, long offset) throws ProxyCacheException, IOException {
    try {
        HttpUrlSource source = new HttpUrlSource(this.source);
        source.open((int) offset);
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        int readBytes;
        while ((readBytes = source.read(buffer)) != -1) {
            out.write(buffer, 0, readBytes);
            offset += readBytes;
        }
        out.flush();
    } finally {
       //this is where the bug happens,the source might being used in ProxyCache.readSource()**
       //if there is a another request running with HttpProxyCache.responseWithCache()**
       source.close();
    }
}

At the finally block,the "source.close()" will close the source might being used in ProxyCache.readSource() if there is a another request running with HttpProxyCache.responseWithCache(),so the cache thread will stop,then the MediaPlayer will get no data return.
I think what the author really want to do is to close the source in the try block.

PS:The log when the MediaPlayer stop work:

12-26 13:09:48.469 1759-1759/? I/ProxyCache: Proxy cache server started. Ping it...
12-26 13:09:48.479 1759-1800/? D/ProxyCache: Open connection  to http://127.0.0.1:37550/ping
12-26 13:09:48.479 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=33754,localPort=37550]
12-26 13:09:48.479 1759-1801/? I/ProxyCache: Request to cache proxy:GetRequest{rangeOffset=0, partial=false, uri='ping'}
12-26 13:09:48.479 1759-1801/? D/ProxyCache: Opened connections: 0
12-26 13:09:48.489 1759-1800/? D/ProxyCache: Ping response: `ping ok`, pinged? true
12-26 13:09:48.649 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=52510,localPort=37550]
12-26 13:09:48.649 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=52511,localPort=37550]
12-26 13:09:48.649 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=52512,localPort=37550]
12-26 13:09:48.649 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=52513,localPort=37550]
12-26 13:09:48.649 1759-1806/? I/ProxyCache: Request to cache proxy:GetRequest{rangeOffset=0, partial=false, uri='http://video_url'}
12-26 13:09:48.679 1759-1806/? D/ProxyCache: Read content info from http://video_url
12-26 13:09:48.679 1759-1806/? D/ProxyCache: Open connection  to http://video_url
12-26 13:09:49.329 1759-1806/? I/ProxyCache: Content info for `http://video_url`: mime: video/mp4, content-length: 24051189
12-26 13:09:49.329 1759-1811/? D/ProxyCache: Open connection  to http://video_url
12-26 13:09:50.299 1759-1807/? I/ProxyCache: Request to cache proxy:GetRequest{rangeOffset=23737472, partial=true, uri='http://video_url'}
12-26 13:09:50.299 1759-1807/? D/ProxyCache: Open connection  with offset 23737472 to http://video_url
12-26 13:09:50.329 1759-1806/? D/ProxyCache: Closing socket… Socket is closed by client.
12-26 13:09:50.329 1759-1806/? D/ProxyCache: Releasing input stream… Socket is closed by client.
12-26 13:09:50.329 1759-1806/? D/ProxyCache: Opened connections: 1
12-26 13:09:51.969 1759-1807/? D/ProxyCache: Shutdown proxy for HttpUrlSource{url='http://video_url}
12-26 13:09:51.979 1759-1811/? E/ProxyCache: ProxyCache error
                                             com.danikula.videocache.ProxyCacheException: Error reading data from http://video_url
                                                 at com.danikula.videocache.HttpUrlSource.read(HttpUrlSource.java:99)
                                                 at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:126)
                                                 at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19)
                                                 at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:179)
                                                 at java.lang.Thread.run(Thread.java:856)
                                              Caused by: java.net.SocketException: Socket closed
                                                 at libcore.io.Posix.recvfromBytes(Native Method)
                                                 at libcore.io.Posix.recvfrom(Posix.java:131)
                                                 at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
                                                 at libcore.io.IoBridge.recvfrom(IoBridge.java:503)
                                                 at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
                                                 at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
                                                 at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
                                                 at java.io.BufferedInputStream.read(BufferedInputStream.java:304)
                                                 at libcore.net.http.FixedLengthInputStream.read(FixedLengthInputStream.java:45)
                                                 at java.io.BufferedInputStream.read(BufferedInputStream.java:304)
                                                 at com.danikula.videocache.HttpUrlSource.read(HttpUrlSource.java:95)
                                                 at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:126) 
                                                 at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19) 
                                                 at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:179) 
                                                 at java.lang.Thread.run(Thread.java:856) 
12-26 13:09:51.979 1759-1807/? D/ProxyCache: Opened connections: 0
12-26 13:09:58.659 1759-1808/? D/ProxyCache: Opened connections: 0
12-26 13:09:58.669 1759-1809/? D/ProxyCache: Opened connections: 0

PPS:I replaced the video url in the log.

Starts Caching then tries to close the connection and throws NullPointerException

I'm Using version 2.3.3

Fatal Exception: java.lang.NullPointerException: Attempt to read from field 'int com.android.okio.Segment.limit' on a null object reference
       at com.android.okio.OkBuffer.write(OkBuffer.java:574)
       at com.android.okio.OkBuffer.read(OkBuffer.java:610)
       at com.android.okio.RealBufferedSource.read(RealBufferedSource.java:53)
       at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:442)
       at com.android.okhttp.internal.Util.skipAll(Util.java:227)
       at com.android.okhttp.internal.http.HttpConnection.discard(HttpConnection.java:212)
       at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.close(HttpConnection.java:464)
       at com.android.okhttp.internal.Util.closeQuietly(Util.java:97)
       at com.android.okhttp.internal.http.HttpEngine.close(HttpEngine.java:433)
       at com.android.okhttp.internal.http.HttpURLConnectionImpl.disconnect(HttpURLConnectionImpl.java:113)
       at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.disconnect(DelegatingHttpsURLConnection.java:93)
       at com.android.okhttp.internal.http.HttpsURLConnectionImpl.disconnect(HttpsURLConnectionImpl.java:25)
       at com.danikula.videocache.HttpUrlSource.close(HttpUrlSource.java:79)
       at com.danikula.videocache.ProxyCache.closeSource(ProxyCache.java:159)
       at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:140)
       at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19)
       at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:178)
       at java.lang.Thread.run(Thread.java:818)

Ability to add personal header

It will be great if there's an ability to add user defined header.

private String newResponseHeaders(GetRequest request) throws IOException, ProxyCacheException {
        String mime = source.getMime();
        boolean mimeKnown = !TextUtils.isEmpty(mime);
        int length = cache.isCompleted() ? cache.available() : source.length();
        boolean lengthKnown = length >= 0;
        long contentLength = request.partial ? length - request.rangeOffset : length;
        boolean addRange = lengthKnown && request.partial;
        return new StringBuilder()
                .append(request.partial ? "HTTP/1.1 206 PARTIAL CONTENT\n" : "HTTP/1.1 200 OK\n")
                .append("Accept-Ranges: bytes\n")
                .append(lengthKnown ? String.format("Content-Length: %d\n", contentLength) : "")
                .append(addRange ? String.format("Content-Range: bytes %d-%d/%d\n", request.rangeOffset, length - 1, length) : "")
                .append(mimeKnown ? String.format("Content-Type: %s\n", mime) : "")
                .append("\n") // headers end
                .toString();
    }

Something like this:

private String newResponseHeaders(GetRequest request, HashMap<String, String> headers) {
      StringBuilder _headers = new StringBuilder(newResponseHeaders(request));
      for (Map.Entry<String, String> entry : map.entrySet()) {
            _headers.append(String.format("%s: %s\n", entry.getKey(), entry.getValue()));
      }
      return _headers.toString();
}

MPEG4Extractor: Video is malformed

Hi, I am experiencing a weird issue using this library.
sometimes, while streaming some video, i get the following exception:

MPEG4Extractor: Video is malformed - offset=943983, srcOffset=4, mNALLengthSize=-1864625292, nalLength=4, size=688

however the data reported in the exception are different every time it occurs, and then the video stops with a media player error (1, -1007)

This is all I was able to find out:

  • the issue never occurs when using direct url streaming, but occurs when using a video cache url
  • the issue occurs at random times and sometimes doesn't occur at all
  • after a video has been played completely, the issue will never occur again unless the cache is cleared
  • the issue never occurs with some videos (for example, with the annoying orange videos of the sample app, it never occurs)
  • the issue never occurs on some devices, while it frequently occurs on some other
  • the issue occurs independently of the % of caching, but very often occurs after the video is 100% cached (this makes me think that something bad happens while saving the stream to disk)
  • the issue is not related to the server where the videos are hosted. some videos stored on the same server can be played without problems
  • the issue can be reproduced in the sample app by changing one of the urls with this one:
    http://www.bravepotions.com/streaming/ninja.mp4

this video has the following specs:
mp4 using H.264 video codec and AAC audio codec
resolution 1280 x 720
fixed framerate 24fps
the video was encoded using HandBrake on mac and can be played just fine

i can try to encode my videos using some other software, but i am afraid that many other people will experience something similar

Listener to files that get deleted

Hello ! I have a requirement to store in the database what song was cached and to delete from database the song that was deleted from cache. I need to keep account on what songs do I have in cache and what songs get deleted. Can I do this ?

Streaming while caching

Caching work great and thank you for this lib, but it doesn't seem to stream (playing) while caching.
It looks like it wait for caching to be available at 100% and only then start to play the video. (Which is longer than just stream in via URL and start playing the first chunks available).

Is it normal behavior or is it a malformed code I've wrote ?

HttpProxyCacheServer proxy = VideoProxyFactory.getProxy(this);
        proxy.registerCacheListener(new CacheListener() {
            @Override
            public void onCacheAvailable(File cacheFile, String url, int percentsAvailable) {
                if(percentsAvailable<100)
                {
                    mPercentageOfVideo.setText(percentsAvailable+"%");
                    mPercentageOfVideo.setVisibility(View.VISIBLE);
                }
                else
                {
                    mPercentageOfVideo.setText("100%");
                    mVideoSharePath=cacheFile.getAbsolutePath();
                }
            }
        }, mVideoUrl);
        mVideoUrl = proxy.getProxyUrl(mVideoUrl);

android.os.NetworkOnMainThreadException

i run example, and see white background on device. And i debug, i see this exception : Method threw 'android.os.NetworkOnMainThreadException' exception. Pls help me. Tks

Media Player recording data usage

I've noticed that the Android Media player is adding to the Data Usage used counter for our application when setting the player to use getProxyUrl()

I believe this is because the Android Media Player thinks it's playing from an internet source, even though it is streaming locally from the device. This is also happening within your sample application. Is there any way to stop this from happening as it looks like the application is using much data that it really is. This is also apparent in the Android Studio Network tool which is showing a network usage EVENT though I have no data connection and if I have airplane mode off.

I am unsure whether this is more related to this library or it's completely down to Android. I've been testing this on Android 6 Nexus 5

issue in llollipop when maxsizecache is overcome

12-18 00:19:56.867 11141-11338/com.describeme D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=60658,localPort=57387]
12-18 00:20:06.869 11141-11398/com.describeme E/ProxyCache: Error fetching info from http://127.0.0.1:57387/http%3A%2F%2F127.0.0.1%3A57387%2Fhttp%253A%252F%252F127.0.0.1%253A57387%252Fhttps%25253A%25252F%25252Fd1yibi23zrwr5k.cloudfront.net%25252Fvid%25252F22%25252Fprofile_videos%25252FMOBILE_480TC_20151218031830_94df693a-af5f-4179-a66c-581950408c95.mp4
java.net.SocketTimeoutException
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at com.android.okio.Okio$2.read(Okio.java:113)
at com.android.okio.RealBufferedSource.indexOf(RealBufferedSource.java:147)
at com.android.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:94)
at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:179)
at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:101)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:628)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:388)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:332)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:500)
at com.danikula.videocache.HttpUrlSource.openConnection(HttpUrlSource.java:138)
at com.danikula.videocache.HttpUrlSource.fetchContentInfo(HttpUrlSource.java:108)
at com.danikula.videocache.HttpUrlSource.length(HttpUrlSource.java:53)
at com.danikula.videocache.HttpProxyCache.isUseCache(HttpProxyCache.java:51)
at com.danikula.videocache.HttpProxyCache.processRequest(HttpProxyCache.java:43)
at com.danikula.videocache.HttpProxyCacheServerClients.processRequest(HttpProxyCacheServerClients.java:42)
at com.danikula.videocache.HttpProxyCacheServer.processSocket(HttpProxyCacheServer.java:221)
at com.danikula.videocache.HttpProxyCacheServer.access$300(HttpProxyCacheServer.java:55)
at com.danikula.videocache.HttpProxyCacheServer$SocketProcessorRunnable.run(HttpProxyCacheServer.java:331)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)

Audio Delay

I used this library for audio buffer but the track doesn't start playing unless more than 22% is buffered first; It doesn't start instantaneously when click play song; Am using media player and API return audio with MP3 formats.

Thanks,

Cache isn't continue when pause mediaplayer.

I have using VideoCache for loading video from the url to my MediaPlayer. The cache is running to 30 - 35 percents and pause when i set datasourec. After this, i'm not playing the video, so the cache isn't continuing cache. How can I continue cache the file when the mediaplayer not play?

Proxy server isn't pinged

hello, I met this error on Android 5.0 when using v.2.3.3

Proxy server isn't pinged. Caching doesn't work. If you see this message, please, email me [email protected]

detail log :

12-28 17:39:31.910 31345-31345/? I/art: Late-enabling -Xcheck:jni
12-28 17:39:31.960 31345-31345/com.danikula.videocache.sample I/System.out: Sending WAIT chunk
12-28 17:39:33.740 31345-31359/com.danikula.videocache.sample I/art: Debugger is active
12-28 17:39:33.760 31345-31345/com.danikula.videocache.sample I/System.out: Debugger has connected
12-28 17:39:33.760 31345-31345/com.danikula.videocache.sample I/System.out: waiting for debugger to settle...
12-28 17:39:35.370 31345-31345/com.danikula.videocache.sample I/System.out: debugger has settled (1457)
12-28 17:39:35.510 31345-31345/com.danikula.videocache.sample I/View: ssignParent(ViewParent parent) parent is: android.view.ViewRootImpl@13c051c3
12-28 17:39:35.540 31345-31417/com.danikula.videocache.sample I/OpenGLRenderer: Initialized EGL, version 1.4
12-28 17:39:35.590 31345-31345/com.danikula.videocache.sample I/View: ssignParent(ViewParent parent) parent is: android.widget.ListView{34c471f VFED.VC. ......ID 0,146-1080,1719 #7f0b0007 app:id/listView}
12-28 17:39:35.590 31345-31345/com.danikula.videocache.sample I/View: ssignParent(ViewParent parent) parent is: android.widget.ListView{34c471f VFED.VC. ......ID 0,146-1080,1719 #7f0b0007 app:id/listView}
12-28 17:39:35.590 31345-31345/com.danikula.videocache.sample I/View: ssignParent(ViewParent parent) parent is: android.widget.ListView{34c471f VFED.VC. ......ID 0,146-1080,1719 #7f0b0007 app:id/listView}
12-28 17:39:35.600 31345-31345/com.danikula.videocache.sample I/View: ssignParent(ViewParent parent) parent is: android.widget.ListView{34c471f VFED.VC. ......ID 0,146-1080,1719 #7f0b0007 app:id/listView}
12-28 17:39:46.500 31345-31345/com.danikula.videocache.sample W/ContextImpl: Failed to ensure directory: /storage/sdcard1/Android/data/com.danikula.videocache.sample/cache
12-28 17:39:49.180 31345-31345/com.danikula.videocache.sample W/ContextImpl: Failed to ensure directory: /storage/sdcard1/Android/data/com.danikula.videocache.sample/cache
12-28 17:39:49.300 31345-31345/com.danikula.videocache.sample I/ProxyCache: Proxy cache server started. Ping it...
12-28 17:39:49.300 31345-31664/com.danikula.videocache.sample I/System: core_booster, getBoosterConfig = false
12-28 17:39:49.320 31345-31665/com.danikula.videocache.sample I/System: core_booster, getBoosterConfig = false
12-28 17:39:49.320 31345-31665/com.danikula.videocache.sample I/System.out: [CDS]rx timeout:0
12-28 17:39:49.320 31345-31665/com.danikula.videocache.sample I/System.out: [socket][0] connection /172.17.10.81:1311;LocalPort=58822(0)
12-28 17:39:49.320 31345-31665/com.danikula.videocache.sample I/System.out: [CDS]connect[/172.17.10.81:1311]
12-28 17:39:49.340 31345-31665/com.danikula.videocache.sample I/System.out: [CDS]port[58822]
12-28 17:39:49.340 31345-31665/com.danikula.videocache.sample I/System.out: [socket][/192.168.253.57:58822] connected
12-28 17:39:49.510 31345-31345/com.danikula.videocache.sample E/ProxyCache: Error pinging server [attempt: 0, timeout: 200]. 
                                                                            java.util.concurrent.TimeoutException
                                                                                at java.util.concurrent.FutureTask.get(FutureTask.java:176)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.makeSureServerWorks(HttpProxyCacheServer.java:99)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.<init>(HttpProxyCacheServer.java:85)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.<init>(HttpProxyCacheServer.java:71)
                                                                                at com.danikula.videocache.sample.App.newProxy(App.java:21)
                                                                                at com.danikula.videocache.sample.App.getProxy(App.java:17)
                                                                                at com.danikula.videocache.sample.VideoFragment.startVideo(VideoFragment.java:53)
                                                                                at com.danikula.videocache.sample.VideoFragment.afterViewInjected(VideoFragment.java:49)
                                                                                at com.danikula.videocache.sample.VideoFragment_.onViewChanged(VideoFragment_.java:106)
                                                                                at org.androidannotations.api.view.OnViewChangedNotifier.notifyViewChanged(OnViewChangedNotifier.java:41)
                                                                                at com.danikula.videocache.sample.VideoFragment_.onViewCreated(VideoFragment_.java:72)
                                                                                at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1097)
                                                                                at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1259)
                                                                                at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
                                                                                at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1624)
                                                                                at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
                                                                                at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
                                                                                at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1224)
                                                                                at android.app.Activity.performStart(Activity.java:6032)
                                                                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2466)
                                                                                at android.app.ActivityThread.access$1200(ActivityThread.java:152)
                                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1341)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                at android.os.Looper.loop(Looper.java:135)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5538)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:958)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:753)
12-28 17:39:49.510 31345-31671/com.danikula.videocache.sample I/System: core_booster, getBoosterConfig = false
12-28 17:39:49.510 31345-31671/com.danikula.videocache.sample I/System.out: [CDS]rx timeout:0
12-28 17:39:49.510 31345-31671/com.danikula.videocache.sample I/System.out: [socket][1] connection /172.17.10.81:1311;LocalPort=43725(0)
12-28 17:39:49.510 31345-31671/com.danikula.videocache.sample I/System.out: [CDS]connect[/172.17.10.81:1311]
12-28 17:39:49.520 31345-31671/com.danikula.videocache.sample I/System.out: [CDS]port[43725]
12-28 17:39:49.520 31345-31671/com.danikula.videocache.sample I/System.out: [socket][/192.168.253.57:43725] connected
12-28 17:39:49.910 31345-31345/com.danikula.videocache.sample E/ProxyCache: Error pinging server [attempt: 1, timeout: 400]. 
                                                                            java.util.concurrent.TimeoutException
                                                                                at java.util.concurrent.FutureTask.get(FutureTask.java:176)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.makeSureServerWorks(HttpProxyCacheServer.java:99)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.<init>(HttpProxyCacheServer.java:85)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.<init>(HttpProxyCacheServer.java:71)
                                                                                at com.danikula.videocache.sample.App.newProxy(App.java:21)
                                                                                at com.danikula.videocache.sample.App.getProxy(App.java:17)
                                                                                at com.danikula.videocache.sample.VideoFragment.startVideo(VideoFragment.java:53)
                                                                                at com.danikula.videocache.sample.VideoFragment.afterViewInjected(VideoFragment.java:49)
                                                                                at com.danikula.videocache.sample.VideoFragment_.onViewChanged(VideoFragment_.java:106)
                                                                                at org.androidannotations.api.view.OnViewChangedNotifier.notifyViewChanged(OnViewChangedNotifier.java:41)
                                                                                at com.danikula.videocache.sample.VideoFragment_.onViewCreated(VideoFragment_.java:72)
                                                                                at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1097)
                                                                                at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1259)
                                                                                at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
                                                                                at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1624)
                                                                                at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
                                                                                at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
                                                                                at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1224)
                                                                                at android.app.Activity.performStart(Activity.java:6032)
                                                                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2466)
                                                                                at android.app.ActivityThread.access$1200(ActivityThread.java:152)
                                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1341)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                at android.os.Looper.loop(Looper.java:135)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5538)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:958)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:753)
12-28 17:39:49.920 31345-31680/com.danikula.videocache.sample I/System: core_booster, getBoosterConfig = false
12-28 17:39:49.930 31345-31680/com.danikula.videocache.sample I/System.out: [CDS]rx timeout:0
12-28 17:39:49.930 31345-31680/com.danikula.videocache.sample I/System.out: [socket][2] connection /172.17.10.81:1311;LocalPort=54341(0)
12-28 17:39:49.930 31345-31680/com.danikula.videocache.sample I/System.out: [CDS]connect[/172.17.10.81:1311]
12-28 17:39:49.950 31345-31680/com.danikula.videocache.sample I/System.out: [CDS]port[54341]
12-28 17:39:49.950 31345-31680/com.danikula.videocache.sample I/System.out: [socket][/192.168.253.57:54341] connected
12-28 17:39:50.460 31345-31665/com.danikula.videocache.sample E/ProxyCache: Error reading ping response
                                                                            com.danikula.videocache.ProxyCacheException: Error opening connection for http://127.0.0.1:42486/ping with offset 0
                                                                                at com.danikula.videocache.HttpUrlSource.open(HttpUrlSource.java:66)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.pingServer(HttpProxyCacheServer.java:120)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.access$400(HttpProxyCacheServer.java:55)
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:339)
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:335)
                                                                                at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                                                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                                                                at java.lang.Thread.run(Thread.java:831)
                                                                             Caused by: java.io.FileNotFoundException: http://127.0.0.1:42486/ping
                                                                                at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:197)
                                                                                at com.danikula.videocache.HttpUrlSource.open(HttpUrlSource.java:63)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.pingServer(HttpProxyCacheServer.java:120) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer.access$400(HttpProxyCacheServer.java:55) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:339) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:335) 
                                                                                at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
                                                                                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                                                                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                                                                                at java.lang.Thread.run(Thread.java:831) 
12-28 17:39:50.460 31345-31665/com.danikula.videocache.sample I/System.out: [CDS]close[58822]
12-28 17:39:50.460 31345-31665/com.danikula.videocache.sample I/System.out: close [socket][/0.0.0.0:58822]
12-28 17:39:50.600 31345-31671/com.danikula.videocache.sample E/ProxyCache: Error reading ping response
                                                                            com.danikula.videocache.ProxyCacheException: Error opening connection for http://127.0.0.1:42486/ping with offset 0
                                                                                at com.danikula.videocache.HttpUrlSource.open(HttpUrlSource.java:66)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.pingServer(HttpProxyCacheServer.java:120)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.access$400(HttpProxyCacheServer.java:55)
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:339)
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:335)
                                                                                at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                                                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                                                                at java.lang.Thread.run(Thread.java:831)
                                                                             Caused by: java.io.FileNotFoundException: http://127.0.0.1:42486/ping
                                                                                at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:197)
                                                                                at com.danikula.videocache.HttpUrlSource.open(HttpUrlSource.java:63)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.pingServer(HttpProxyCacheServer.java:120) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer.access$400(HttpProxyCacheServer.java:55) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:339) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:335) 
                                                                                at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
                                                                                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                                                                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                                                                                at java.lang.Thread.run(Thread.java:831) 
12-28 17:39:50.600 31345-31671/com.danikula.videocache.sample I/System.out: [CDS]close[43725]
12-28 17:39:50.600 31345-31671/com.danikula.videocache.sample I/System.out: close [socket][/0.0.0.0:43725]
12-28 17:39:50.720 31345-31345/com.danikula.videocache.sample E/ProxyCache: Error pinging server [attempt: 2, timeout: 800]. 
                                                                            java.util.concurrent.TimeoutException
                                                                                at java.util.concurrent.FutureTask.get(FutureTask.java:176)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.makeSureServerWorks(HttpProxyCacheServer.java:99)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.<init>(HttpProxyCacheServer.java:85)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.<init>(HttpProxyCacheServer.java:71)
                                                                                at com.danikula.videocache.sample.App.newProxy(App.java:21)
                                                                                at com.danikula.videocache.sample.App.getProxy(App.java:17)
                                                                                at com.danikula.videocache.sample.VideoFragment.startVideo(VideoFragment.java:53)
                                                                                at com.danikula.videocache.sample.VideoFragment.afterViewInjected(VideoFragment.java:49)
                                                                                at com.danikula.videocache.sample.VideoFragment_.onViewChanged(VideoFragment_.java:106)
                                                                                at org.androidannotations.api.view.OnViewChangedNotifier.notifyViewChanged(OnViewChangedNotifier.java:41)
                                                                                at com.danikula.videocache.sample.VideoFragment_.onViewCreated(VideoFragment_.java:72)
                                                                                at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1097)
                                                                                at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1259)
                                                                                at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
                                                                                at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1624)
                                                                                at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
                                                                                at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
                                                                                at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1224)
                                                                                at android.app.Activity.performStart(Activity.java:6032)
                                                                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2466)
                                                                                at android.app.ActivityThread.access$1200(ActivityThread.java:152)
                                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1341)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                at android.os.Looper.loop(Looper.java:135)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5538)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:958)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:753)
12-28 17:39:51.070 31345-31680/com.danikula.videocache.sample E/ProxyCache: Error reading ping response
                                                                            com.danikula.videocache.ProxyCacheException: Error opening connection for http://127.0.0.1:42486/ping with offset 0
                                                                                at com.danikula.videocache.HttpUrlSource.open(HttpUrlSource.java:66)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.pingServer(HttpProxyCacheServer.java:120)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.access$400(HttpProxyCacheServer.java:55)
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:339)
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:335)
                                                                                at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                                                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                                                                at java.lang.Thread.run(Thread.java:831)
                                                                             Caused by: java.io.FileNotFoundException: http://127.0.0.1:42486/ping
                                                                                at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:197)
                                                                                at com.danikula.videocache.HttpUrlSource.open(HttpUrlSource.java:63)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.pingServer(HttpProxyCacheServer.java:120) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer.access$400(HttpProxyCacheServer.java:55) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:339) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer$PingCallable.call(HttpProxyCacheServer.java:335) 
                                                                                at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
                                                                                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                                                                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                                                                                at java.lang.Thread.run(Thread.java:831) 
12-28 17:39:51.070 31345-31680/com.danikula.videocache.sample I/System.out: [CDS]close[54341]
12-28 17:39:51.070 31345-31680/com.danikula.videocache.sample I/System.out: close [socket][/0.0.0.0:54341]
12-28 17:39:59.810 31345-31345/com.danikula.videocache.sample E/ProxyCache: Shutdown server… Error pinging server [attempt: 3, timeout: 1600]. If you see this message, please, email me [email protected]
12-28 17:39:59.810 31345-31345/com.danikula.videocache.sample I/ProxyCache: Shutdown proxy server
12-28 17:39:59.810 31345-31345/com.danikula.videocache.sample I/System.out: [CDS]close[42486]
12-28 17:39:59.810 31345-31664/com.danikula.videocache.sample I/System.out: close [socket][/0.0.0.0:-1]
12-28 17:39:59.820 31345-31664/com.danikula.videocache.sample E/ProxyCache: HttpProxyCacheServer error
                                                                            com.danikula.videocache.ProxyCacheException: Error during waiting connection
                                                                                at com.danikula.videocache.HttpProxyCacheServer.waitForRequest(HttpProxyCacheServer.java:208)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.access$200(HttpProxyCacheServer.java:55)
                                                                                at com.danikula.videocache.HttpProxyCacheServer$WaitRequestsRunnable.run(HttpProxyCacheServer.java:317)
                                                                                at java.lang.Thread.run(Thread.java:831)
                                                                             Caused by: java.net.SocketException: Socket closed
                                                                                at libcore.io.Posix.accept(Native Method)
                                                                                at libcore.io.BlockGuardOs.accept(BlockGuardOs.java:63)
                                                                                at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:89)
                                                                                at java.net.ServerSocket.implAccept(ServerSocket.java:216)
                                                                                at java.net.ServerSocket.accept(ServerSocket.java:140)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.waitForRequest(HttpProxyCacheServer.java:203)
                                                                                at com.danikula.videocache.HttpProxyCacheServer.access$200(HttpProxyCacheServer.java:55) 
                                                                                at com.danikula.videocache.HttpProxyCacheServer$WaitRequestsRunnable.run(HttpProxyCacheServer.java:317) 
                                                                                at java.lang.Thread.run(Thread.java:831) 
12-28 17:39:59.820 31345-31345/com.danikula.videocache.sample E/ProxyCache: Proxy server isn't pinged. Caching doesn't work. If you see this message, please, email me [email protected]
12-28 17:39:59.850 31345-31345/com.danikula.videocache.sample I/View: ssignParent(ViewParent parent) parent is: android.view.ViewRootImpl@3a70bc06
12-28 17:39:59.850 31345-31345/com.danikula.videocache.sample I/Choreographer: Skipped 641 frames!  The application may be doing too much work on its main thread.
12-28 17:39:59.950 31345-31345/com.danikula.videocache.sample I/AudioManager: requestAudioFocus() status : 1
12-28 17:39:59.950 31345-31345/com.danikula.videocache.sample I/AudioManager: requestAudioFocus() apk    : com.danikula.videocache.sample
12-28 17:39:59.960 31345-31345/com.danikula.videocache.sample I/MediaPlayer-JNI: throw_jni_exception_in_java;test for ART
12-28 17:39:59.960 31345-31345/com.danikula.videocache.sample I/MediaPlayer-JNI: throw_jni_exception_in_java;test for ART method
12-28 17:39:59.960 31345-31345/com.danikula.videocache.sample I/MediaPlayer-JNI: fields.throw_exception != NULL
12-28 17:39:59.960 31345-31345/com.danikula.videocache.sample I/MediaPlayer-JNI: throw_jni_exception_in_java;test for ART get method
12-28 17:39:59.960 31345-31345/com.danikula.videocache.sample I/MediaPlayer-JNI: throw_jni_exception_in_java;test for ART call java
12-28 17:39:59.960 31345-31345/com.danikula.videocache.sample E/MediaPlayer: throwsException:java/lang/IllegalStateException,callingMethod:android_media_MediaPlayer_getCurrentPosition
12-28 17:39:59.960 31345-31345/com.danikula.videocache.sample I/art_test: catch IllegalStateException
12-28 17:39:59.980 31345-31366/com.danikula.videocache.sample I/System: core_booster, getBoosterConfig = false
12-28 17:39:59.980 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]rx timeout:0
12-28 17:39:59.980 31345-31366/com.danikula.videocache.sample I/System.out: [socket][3] connection /172.17.10.81:1311;LocalPort=53456(0)
12-28 17:39:59.980 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]connect[/172.17.10.81:1311]
12-28 17:39:59.990 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]port[53456]
12-28 17:40:00.000 31345-31366/com.danikula.videocache.sample I/System.out: [socket][/192.168.253.57:53456] connected
12-28 17:40:02.190 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]rx timeout:100
12-28 17:40:02.300 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]rx timeout:0
12-28 17:40:02.300 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]close[53456]
12-28 17:40:02.300 31345-31366/com.danikula.videocache.sample I/System.out: close [socket][/0.0.0.0:53456]
12-28 17:40:02.300 31345-31366/com.danikula.videocache.sample I/System: core_booster, getBoosterConfig = false
12-28 17:40:02.300 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]rx timeout:0
12-28 17:40:02.310 31345-31366/com.danikula.videocache.sample I/System.out: [socket][4] connection /172.17.10.81:1311;LocalPort=33529(0)
12-28 17:40:02.310 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]connect[/172.17.10.81:1311]
12-28 17:40:02.330 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]port[33529]
12-28 17:40:02.330 31345-31366/com.danikula.videocache.sample I/System.out: [socket][/192.168.253.57:33529] connected
12-28 17:40:04.350 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]close[33529]
12-28 17:40:04.360 31345-31366/com.danikula.videocache.sample I/System.out: close [socket][/0.0.0.0:33529]
12-28 17:40:04.460 31345-31365/com.danikula.videocache.sample I/System: core_booster, getBoosterConfig = false
12-28 17:40:04.460 31345-31365/com.danikula.videocache.sample I/System.out: [CDS]rx timeout:0
12-28 17:40:04.460 31345-31365/com.danikula.videocache.sample I/System.out: [socket][5] connection /172.17.10.81:1311;LocalPort=45218(0)
12-28 17:40:04.460 31345-31365/com.danikula.videocache.sample I/System.out: [CDS]connect[/172.17.10.81:1311]
12-28 17:40:04.470 31345-31365/com.danikula.videocache.sample I/System.out: [CDS]port[45218]
12-28 17:40:04.480 31345-31365/com.danikula.videocache.sample I/System.out: [socket][/192.168.253.57:45218] connected
12-28 17:40:06.270 31345-31957/com.danikula.videocache.sample W/MediaPlayer: info/warning (3, 0)
12-28 17:40:12.370 31345-31359/com.danikula.videocache.sample W/art: Suspending all threads took: 5.436ms
12-28 17:40:32.440 31345-31366/com.danikula.videocache.sample I/System.out: [CDS]close[45218]
12-28 17:40:32.440 31345-31366/com.danikula.videocache.sample I/System.out: close [socket][/0.0.0.0:45218]

could you give any clue? thanks.

AndroidVideoCache can not response seek event

when i use AndroidVideoCache in my project ,when i seek the seekbar the mediapalyer stop paly.but if do not add androidVideocache ,when if seek the seekbar ,the mediaplyer is still play and response the seekCompleteListener. what should i do to solve this problem?

Cache HLS, Dash or SmoothStreaming?

Hello, I was wondering if I can implement your library to cache HLS videos. Since it is written in the description that it can add caching support to ExoPlayer, I wanted to know if it was possible. thanks!

Exception at com.android.okio.Util.checkOffsetAndCount (Util.java:29)

Got this from a user

Fatal Exception: java.lang.ArrayIndexOutOfBoundsException
com.android.okio.Util.checkOffsetAndCount (Util.java:29)
com.android.okhttp.internal.http.HttpURLConnectionImpl.disconnect (HttpURLConnectionImpl.java:113)
com.danikula.videocache.HttpUrlSource.close (HttpUrlSource.java:80)
com.danikula.videocache.ProxyCache.closeSource (ProxyCache.java:160)
com.danikula.videocache.ProxyCache.readSource (ProxyCache.java:141)
com.danikula.videocache.ProxyCache.access$100 (ProxyCache.java:19)
com.danikula.videocache.ProxyCache$SourceReaderRunnable.run (ProxyCache.java:179)
java.lang.Thread.run (Thread.java:818)

Android L: NullPointerException on HttpURLConnection.disconnect

This is a multithreading issue as seen here square/okio#79
HttpURLConnection on Lollipop uses an outdated version of okhttp, which doesn't have the fix.

A quicker "fix" is to handle the NullPointerException on HttpUrlSource.read(HttpUrlSource.java:89) and HttpUrlSource.close(HttpUrlSource.java:79)

I was willing to do it, but I can't even compile the library on Android Studio:

Error:Execution failed for task ':app:preDexDebug'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/java-8-oracle/bin/java'' finished with non-zero exit value 1

Logs:

E/ProxyCache﹕ ProxyCache error
    java.lang.NullPointerException: Attempt to read from field 'int com.android.okio.Segment.limit' on a null object reference
            at com.android.okio.OkBuffer.write(OkBuffer.java:574)
            at com.android.okio.OkBuffer.read(OkBuffer.java:610)
            at com.android.okio.RealBufferedSource.read(RealBufferedSource.java:56)
            at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:465)
            at com.android.okio.RealBufferedSource$1.read(RealBufferedSource.java:174)
            at java.io.BufferedInputStream.read(BufferedInputStream.java:290)
            at com.danikula.videocache.HttpUrlSource.read(HttpUrlSource.java:89)
            at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:125)
            at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19)
            at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:178)
            at java.lang.Thread.run(Thread.java:818)


11-01 10:15:51.916  19061-25773/com.sample.sample.debuggable E/AndroidRuntime﹕ FATAL EXCEPTION: Source reader for HttpUrlSource{url='https://www.qviky.com/sample.mp4}
    Process: com.sample.sample.debuggable, PID: 19061
    java.lang.NullPointerException: Attempt to read from field 'int com.android.okio.Segment.limit' on a null object reference
            at com.android.okio.OkBuffer.write(OkBuffer.java:574)
            at com.android.okio.OkBuffer.read(OkBuffer.java:610)
            at com.android.okio.RealBufferedSource.read(RealBufferedSource.java:56)
            at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:465)
            at com.android.okhttp.internal.Util.skipAll(Util.java:227)
            at com.android.okhttp.internal.http.HttpConnection.discard(HttpConnection.java:235)
            at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.close(HttpConnection.java:487)
            at com.android.okhttp.internal.Util.closeQuietly(Util.java:97)
            at com.android.okhttp.internal.http.HttpEngine.close(HttpEngine.java:574)
            at com.android.okhttp.internal.http.HttpURLConnectionImpl.disconnect(HttpURLConnectionImpl.java:113)
            at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.disconnect(DelegatingHttpsURLConnection.java:93)
            at com.android.okhttp.internal.http.HttpsURLConnectionImpl.disconnect(HttpsURLConnectionImpl.java:25)
            at com.danikula.videocache.HttpUrlSource.close(HttpUrlSource.java:79)
            at com.danikula.videocache.ProxyCache.closeSource(ProxyCache.java:159)
            at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:140)
            at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19)
            at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:178)
            at java.lang.Thread.run(Thread.java:818)

Crash app when I tried load file with zero size

FATAL EXCEPTION: Source reader for HttpUrlSource{url='my url to file}
 java.lang.ArithmeticException: divide by zero
 at com.danikula.videocache.ProxyCache.onCacheAvailable(ProxyCache.java:104)
 at com.danikula.videocache.ProxyCache.notifyNewCacheDataAvailable(ProxyCache.java:96)
 at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:141)
 at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19)
 at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:178)
 at java.lang.Thread.run(Thread.java:856)

Play cached video offline

I can not play cached video offline.

From this code:

private String newResponseHeaders(GetRequest request) throws IOException, ProxyCacheException {
        String mime = source.getMime();
        boolean mimeKnown = !TextUtils.isEmpty(mime);
        int length = cache.isCompleted() ? cache.available() : source.available();
        boolean lengthKnown = length >= 0;
        long contentLength = request.partial ? length - request.rangeOffset : length;
        boolean addRange = lengthKnown && request.partial;
        return new StringBuilder()
                .append(request.partial ? "HTTP/1.1 206 PARTIAL CONTENT\n" : "HTTP/1.1 200 OK\n")
                .append("Accept-Ranges: bytes\n")
                .append(lengthKnown ? String.format("Content-Length: %d\n", contentLength) : "")
                .append(addRange ? String.format("Content-Range: bytes %d-%d/%d\n", request.rangeOffset, length, length) : "")
                .append(mimeKnown ? String.format("Content-Type: %s\n", mime) : "")
                .append("\n") // headers end
                .toString();
    }

HttpProxyCache will always get mime from Internet, and throw Exception if no network.
Changed like this can work well:

private String newResponseHeaders(GetRequest request) throws IOException, ProxyCacheException {
        int length;
        String mime = null;
        if (cache.isCompleted()) {
            length = cache.available();
        } else {
            length = source.available();
            mime = source.getMime();
        }
        boolean mimeKnown = !TextUtils.isEmpty(mime);
        boolean lengthKnown = length >= 0;
        long contentLength = request.partial ? length - request.rangeOffset : length;
        boolean addRange = lengthKnown && request.partial;
        return new StringBuilder().append(
                request.partial ? "HTTP/1.1 206 PARTIAL CONTENT\n" : "HTTP/1.1 200 OK\n")
                .append("Accept-Ranges: bytes\n")
                .append(lengthKnown ? String.format("Content-Length: %d\n", contentLength) : "")
                .append(addRange ? String.format("Content-Range: bytes %d-%d/%d\n",
                        request.rangeOffset, length, length) : "")
                .append(mimeKnown ? String.format("Content-Type: %s\n", mime) : "").append(
                        "\n") // headers end
                .toString();
    }

Cannot use JDK8 to compile the sample with library module

I need changed some files in the library module, so i modified sample/build.gradle to compile the library module

dependencies {
    compile project(':library')
    //compile 'com.danikula:videocache:2.1.1'
    ...
}

And i got this exception and build failed

Execution failed for task ':sample:preDexDebug'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1

So i changed jdk version from 8 to 7 .then it build succeed.
But i also using retrolambda it need jdk8 to compile

So..how can i compile it use jdk8?

(sorry for my poor english)

Cache not working when used from a view

I am using the factory method to maintain one instance of the proxy. And feeding proxy-url to the data source for the media player.

HttpProxyCacheServer proxy = HttpProxyCacheServerFactory.getProxy(getContext());
String proxyUrl = proxy.getProxyUrl(mediaUrl);
this.mediaUrl = proxyUrl;

This logic is in my mediaplayer view, which means a new proxy-url gets created every time the view is created.

  1. Does the proxy server create a new proxy-url for the same url every time I call getProxyUrl() ?
  2. Where is the logic that if the file is previously loaded, then the proxy-url points to this file.
  3. What happens if the file was only partially loaded and I seek back, would the file stream again, or it will load from the already loaded cache?

Right now my cache doesn't seem to work as network calls are made every time I play the file.

Pinging server error when set up System Http Proxy.

Pinging server error when set up System Http Proxy.

Error pinging server [attempt: 0, timeout: 200]. 
at java.util.concurrent.TimeoutException
at com.danikula.videocache.HttpProxyCacheServer.makeSureServerWorks

And It will work when add "127.0.0.1" to bypass list.

http-proxy

percentsAvailable are sometimes negative values

percentsAvailable in onCacheAvailable sometimes return negative values (-33, -32 and count up).

It happens when starting to stream/caching video, exit app and when return it shows those negative values.

Missing something here ?

OnErrorListener gets called while using seekTo()

@baderkhan When seeking to a certain point of the video the MediaPlayer of VideoView throws error exception of: Error playing video:1, -1007. (It is not at all points, but happens always a specific one).

Which means "Bitstream is not conforming to the related coding standard or file spec." according to Android Docs.

It is also throws MediaPlayer﹕ error (-38, 0) - Which means that the MediaPlayer probably is in illegal state when I'm trying to seek.

This thing does not happen when I'm not using this library.

Error fetching content info

For some url proxy can't fetch content info.

Error fetching info from https://s3-eu-west-1.amazonaws.com/econumysecure.msgfiles.stream/msg_e_14523/CV3780.mp4?AWSAccessKeyId=AKIAJJMVLH6UM4G4RVDA&Expires=1446124316&Signature=t5IFPDHwxxx%2BOuNLiWNA9vF%2BmvY%3D
java.io.FileNotFoundException: https://s3-eu-west-1.amazonaws.com/econumysecure.msgfiles.stream/msg_e_14523/CV3780.mp4?AWSAccessKeyId=AKIAJJMVLH6UM4G4RVDA&Expires=1446124316&Signature=t5IFPDHwxxx%2BOuNLiWNA9vF%2BmvY%3D
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:238)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
    at com.danikula.videocache.HttpUrlSource.fetchContentInfo(HttpUrlSource.java:105)
    at com.danikula.videocache.HttpUrlSource.length(HttpUrlSource.java:53)
    at com.danikula.videocache.HttpProxyCache.newResponseHeaders(HttpProxyCache.java:61)
    at com.danikula.videocache.HttpProxyCache.processRequest(HttpProxyCache.java:39)
    at com.danikula.videocache.HttpProxyCacheServerClients.processRequest(HttpProxyCacheServerClients.java:42)
    at com.danikula.videocache.HttpProxyCacheServer.processSocket(HttpProxyCacheServer.java:221)
    at com.danikula.videocache.HttpProxyCacheServer.access$300(HttpProxyCacheServer.java:55)
    at com.danikula.videocache.HttpProxyCacheServer$SocketProcessorRunnable.run(HttpProxyCacheServer.java:331)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.