Rakesh Yadav
Rakesh Yadav

Reputation: 1985

Java Android download video in parts and Play combined

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

Answers (5)

Surender Singh Rawat
Surender Singh Rawat

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

Alex Cohn
Alex Cohn

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

anemo
anemo

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

Rakesh Yadav
Rakesh Yadav

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

Milos Fec
Milos Fec

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

Related Questions