Reputation: 1985
I don't know how to do. Please suggest how to download a large video file in parts and play all parts one by one.
Actually I have to stream FTP large file in Android VideoView
. I have searched a lot and found that android do not support FTP streaming.
So, I tried to download the file in multiple parts and play them one by one. But the problem is that only first part of file plays, others don't. Please suggest.
Code to download file in parts.
URL url = new URL(fileUrl);
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
FileOutputStream outStream = new FileOutputStream(fileName);
byte[] buff = new byte[5 * 1024];
int len;
int maxLenth = 10000; //Some random value
int counter = 0;
//Read bytes (and store them) until there is nothing more to read(-1)
while ((len = inStream.read(buff)) != -1) {
outStream.write(buff, 0, len);
counter ++;
Log.d(TAG, "Counter: " + counter);
if(counter == maxLenth) {
counter = 0;
outStream.flush();
outStream.close();
fileName = new File(directory.getAbsolutePath() + "/"
+ context.getResources().getString(R.string.app_name) + "_"
+ System.currentTimeMillis() + "." + format);
fileName.createNewFile();
outStream = new FileOutputStream(fileName);
}
}
And when the files are downloaded, I tried to update the list to play videos when at least 1 file is downloaded. listFiles contains list of all the dowloaded files.
Uri uri = Uri.parse(listFiles.get(0));
videoView.setVideoURI(uri);
videoView.start();
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
counter ++;
if(counter < listFiles.size()) {
Uri uri = Uri.parse(listFiles.get(counter));
videoView.setVideoURI(uri);
videoView.start();
}
}
});
I don't know why the downloaded files after file 1 don't play. They don't play even in the PC. I don't know what wrong am I doing.
Upvotes: 0
Views: 1938
Reputation: 919
Decoding file this way will not play all the files. Because they are just binary files and you are trying to change the extensions of them. There is no way in android to decode files this way. But there are many libraries which you can use to decode the file into parts and then play each part separately. One of the library is ffmpeg.
Upvotes: 2
Reputation: 57173
Instead of building a local server, you can create a ContentProvider and use its Uri to initialize the VideoView. Usually we use ContentProvider to pass some data to other apps with kind of SQL access, but here it will be an intra-app provider which delivers binary data.
Here is a tutorial that shows how to handle binary data with ContentProvider.
Upvotes: 0
Reputation: 1367
If you split a View file into parts, only the first part will contain the format specifications. This is the reason only your first part is getting played. All the other parts are just binary files.
After you have downloaded all the Parts, you have to merge them in the same sequence.
private void mergeAfterDownload()
{
Log.i(LOG_TAG, "Merging now");
try {
File destinationFile = new File("Path to the Merged File");
if (destinationFile.exists()) destinationFile.delete();
// Create the parent folder(s) if necessary
destinationFile.getParentFile().mkdirs();
// Create the file
destinationFile.createNewFile();
FileOutputStream destinationOutStream = new FileOutputStream(destinationFile);
// Enumerate through all the Parts and Append them to the destinationFile
for (File file : listFiles) {
// Read the Part
InputStream inStream = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(inStream);
// Append the Part to the destinationFile
byte[] buffer = new byte[1024];
int read;
while ((read = bis.read(buffer)) != -1) {
destinationOutStream.write(buffer, 0, read);
}
bis.close();
inStream.close();
//Delete the Slice
file.delete();
}
destinationOutStream.close();
Log.i(LOG_TAG, "File Merge Complete");
}
catch (Exception e) {
e.printStackTrace();
Log.e(LOG_TAG, "Failed to merge file");
}
}
Upvotes: 0
Reputation: 1985
I tried a lot of things and none of them worked. Android APIs currently doesn't support this feature. So I have to rely on native code to decode the video and then encode.
To do that I will have to learn few things before such as JNI and NDK. Then I will have to apply native code. I have heard of a good library that supports these features ffmpeg which provides many features. But currently I am engaged in another project so I could not try that library and all these things.
Upvotes: -1
Reputation: 848
You can create local server (ServerSocket
) for streaming a video.
Create background thread and you can directly use FTP to get the stream and write same date to the output stream of local server. When you will finish download of one file, you can open second file, but still use same output stream of the local server.
In the VideoView
you will open 127.0.0.1:PORT
with the port that you will open for local server. I recommend using IP instead of localhost
, because in the past I encountered issues that some devices didn't recognized domain localhost
. With IP I never had any issue.
Please note, that in your local server you will need to send HTTP header before the data.
https://stackoverflow.com/a/34679964/5464100
Upvotes: 2