Preloading only a part of videos
Hi guys, I'm currently using this awesome library for my app.
Nowaday, I want to do preloading: while users is watching a video, I start downloading a part of each upcoming videos.
For example, my videos are about 12MB in size on average, I want to preload only 5MB of each video, so that users will not have to wait for loading.
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
URL url = new URL(videoUrl);
is = url.openStream();
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int lengthInByte;
int readByteCount = 0;
while ((lengthInByte = is.read(buffer)) != -1) {
readByteCount += lengthInByte;
fileOutputStream.write(buffer, 0, lengthInByte);
if (readByteCount >= MAX_FILE_SIZE_TO_PRELOAD_IN_BYTE) {
break;
}
}
The videoUrl here is the original one, not the one from HttpProxyCacheServer.getProxyUrl(String)
The videoPath is the same as the path that the library will use to storage the cache file, because I'm using the same FileNameGenerator to build up the path, with the .download postfix also.
I will stop downloading when the cached file length is bigger than the maximum size I want to cache.
Everything works just fine, the library will append to my preloaded file instead of downloading a new one.
Except that, each time I play a video, it seems that the MediaPlayer has to wait before the library can connect to the remote file, instead of getting access to the cached file immediately.
Is that right? If yes, anyway that I can customize to open the cached file and play the video immediately while the library continue downloading?
Thank you.
Hi @ltpquang were you able to find some other solution for pre caching ? Also when are you executing the above codes you posted ? Do you have any sample code that you could show ?
@thangmam Hi, I haven't got a chance to revisit the problem since everything is working just fine in my app and I have other higher priority things to do.
About the code, put it any where you want to preload a video that hasn't been played yet. The tricky part to make it resumable later is build up the filePath to be as same as the path built by the library. To do that, you need to use the same fileNameGenerator and the same cacheDirectory provided to the cache server
new HttpProxyCacheServer.Builder(application)
.cacheDirectory(fileCacheManager.getLocalStreamingCacheDir())
.fileNameGenerator(fileCacheManager.getFileNameGenerator())
.build();
Dont forget to mark your filePath with .download postfix, because the library will do the same.
@ltpquang Is there a specific implementation of preloading, what method does the video address I get is loaded into the corresponding file directory? new HttpProxyCacheServer.Builder(application) .cacheDirectory(fileCacheManager.getLocalStreamingCacheDir()) .fileNameGenerator(fileCacheManager.getFileNameGenerator()) .build(); Are these lines of code created initially What method is used for preloaded video, and is it a method in HttpProxyCacheServer?
@darkrevier
Are these lines of code created initially
No, it is another way to create an HttpProxyCacheServer
// Instead using this
private HttpProxyCacheServer newProxy() {
return new HttpProxyCacheServer(this);
}
// You can use this
private HttpProxyCacheServer newProxy() {
return new HttpProxyCacheServer.Builder(application)
.cacheDirectory(fileCacheManager.getLocalStreamingCacheDir())
.fileNameGenerator(fileCacheManager.getFileNameGenerator())
.build();
}
The fileCacheManager is an instance of my own class, used to manager cache directories in my own app.
The library doesn't have preloading method itself, you need to have your own one, like my example in the post above.
In a nutshell, you do preloading by downloading the video yourself, save to the same path as the one the library uses, and the library will use it later.
@ltpquang As you wrote, can you play without downloading a full video file? My can't play it.
@darkrevier yes, it is playable in my case, if you cannot play it, maybe because of another reasons, such as player's requirement, file format,...
@ltpquang thanks, but I have two questions How do you name the pre-loaded video file name, I don't quite understand. And androidvideocache? How to find your pre-loaded video and the video you want to play is one?
@darkrevier you need to mock the way androidvideocache name the cached file, find it here and here, use that way to name your preloaded files. So that when the library receive a link, it will jump in and check if the file is already cached or not, then it will see your preloaded file and continue its flow using that file.
@darkrevier you need to mock the way
androidvideocachename the cached file, find it here and here, use that way to name your preloaded files. So that when the library receive a link, it will jump in and check if the file is already cached or not, then it will see your preloaded file and continue its flow using that file.
@ltpquang can you please give some example to implement it?
if complete code is not possible then can you just provide code to filename same as this library uses?
@rocky8roy
First you need to create your own FileNameGenerator
public class MyOwnFileNameGenerator implements FileNameGenerator {
// Do your naming logic
}
Then init cache server proxy using with your name generator
FileNameGenerator myVeryOwnGenerator = new MyOwnFileNameGenerator();
HttpProxyCacheServer proxy = new HttpProxyCacheServer.Builder(this)
.fileNameGenerator(myVeryOwnGenerator)
.build();
Then whenever you download a file, use your generator to get the saving path
String savePath = myVeryOwnGenerator.generate(url);
Downloader.download(url, savePath);
@rocky8roy
First you need to create your own FileNameGenerator
public class MyOwnFileNameGenerator implements FileNameGenerator { // Do your naming logic }Then init cache server proxy using with your name generator
FileNameGenerator myVeryOwnGenerator = new MyOwnFileNameGenerator(); HttpProxyCacheServer proxy = new HttpProxyCacheServer.Builder(this) .fileNameGenerator(myVeryOwnGenerator) .build();Then whenever you download a file, use your generator to get the saving path
String savePath = myVeryOwnGenerator.generate(url); Downloader.download(url, savePath);
thanks a lot.. implemented it successfully!
I have another question:
can we pause or stop the current caching of this library code? my problem scenario is a follows: i have implemented in this way: I have exoplayer in recycler view and is showing videos in vertically one by one. when user is watching the first video it starts caching the video . but problem is for eg if user scrolles fast and directly skip from 1st video to 6th video then also this library will cache all the 5 videos and the 6th too.. so caching last 5 was of no use as user didnt see that video. any solution to this?
@rocky8roy
can we pause or stop the current caching of this library code? my problem scenario is a follows: i have implemented in this way: I have exoplayer in recycler view and is showing videos in vertically one by one. when user is watching the first video it starts caching the video . but problem is for eg if user scrolles fast and directly skip from 1st video to 6th video then also this library will cache all the 5 videos and the 6th too.. so caching last 5 was of no use as user didnt see that video. any solution to this?
This is another problem, find a proper event to trigger your preloading mechanism, for example: only trigger when user stop scrolling.
@rocky8roy
can we pause or stop the current caching of this library code? my problem scenario is a follows: i have implemented in this way: I have exoplayer in recycler view and is showing videos in vertically one by one. when user is watching the first video it starts caching the video . but problem is for eg if user scrolles fast and directly skip from 1st video to 6th video then also this library will cache all the 5 videos and the 6th too.. so caching last 5 was of no use as user didnt see that video. any solution to this?
This is another problem, find a proper event to trigger your preloading mechanism, for example: only trigger when user stop scrolling.
yes but that will be very difficult as we never know when user will start scolling fast again my implementation is like i first pass video url to proxy url and then pass the proxy url to exoplayer. @ltpquang any solution to this problem? @danikula can you provide some method to stop the cache or pause it for eg what happens when your library is caching and internet is gone..how it handles it? does it pause it / stops it/deletes the incomplete cache and start from scratch when internet is available?
@rocky8roy
can we pause or stop the current caching of this library code? my problem scenario is a follows: i have implemented in this way: I have exoplayer in recycler view and is showing videos in vertically one by one. when user is watching the first video it starts caching the video . but problem is for eg if user scrolles fast and directly skip from 1st video to 6th video then also this library will cache all the 5 videos and the 6th too.. so caching last 5 was of no use as user didnt see that video. any solution to this?
This is another problem, find a proper event to trigger your preloading mechanism, for example: only trigger when user stop scrolling.
yes but that will be very difficult as we never know when user will start scolling fast again my implementation is like i first pass video url to proxy url and then pass the proxy url to exoplayer. @ltpquang any solution to this problem? @danikula can you provide some method to stop the cache or pause it for eg what happens when your library is caching and internet is gone..how it handles it? does it pause it / stops it/deletes the incomplete cache and start from scratch when internet is available?
It's quite hard for me to suggest any solution, without any context/knowledge about for current codebase