Java Android下载部分视频和Play结合

时间:2017-11-02 07:24:02

标签: java android ftp video-streaming multipart

我不知道该怎么做。请建议如何分批下载大型视频文件并逐个播放所有部分。 实际上我必须在Android VideoView中传输FTP大文件。我搜索了很多,发现android不支持FTP流媒体。

所以,我尝试将文件分多个部分下载并逐个播放。但问题是只有文件的第一部分播放,有些则不播放。请建议。

部分下载文件的代码。

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);
      }
  }

当下载文件时,我尝试更新列表,以便在下载至少1个文件时播放视频。 listFiles包含所有已下载文件的列表。

    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();
            }
        }
    });

我不知道为什么文件1之后的下载文件无法播放。它们即使在PC中也不会播放。我不知道我做错了什么。

5 个答案:

答案 0 :(得分:2)

您可以创建用于流式传输视频的本地服务器(ServerSocket)。

创建后台线程,您可以直接使用FTP获取流并将相同的日期写入本地服务器的输出流。当您完成一个文件的下载后,您可以打开第二个文件,但仍然使用本地服务器的相同输出流。

VideoView中,您将打开127.0.0.1:PORT,其中包含您将为本地服务器打开的端口。我建议使用IP而不是localhost,因为在过去我遇到了一些设备无法识别域localhost的问题。凭借IP,我从未遇到任何问题。

请注意,在本地服务器中,您需要在数据之前发送HTTP标头。

https://stackoverflow.com/a/34679964/5464100

答案 1 :(得分:1)

以这种方式解码文件不会播放所有文件。因为它们只是二进制文件而您正在尝试更改它们的扩展名。 android中没有办法以这种方式解码文件。但是有许多库可用于将文件解码为部分,然后分别播放每个部分。其中一个库是ffmpeg

答案 2 :(得分:0)

如果将View文件拆分为多个部分,则只有第一部分包含格式规范。这就是你第一部分上场的原因。所有其他部分都只是二进制文件。

下载完所有部件后,必须按相同的顺序合并它们。

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");
    }
}

答案 3 :(得分:0)

您可以创建ContentProvider并使用其Uri初始化VideoView,而不是构建本地服务器。通常我们使用ContentProvider将一些数据传递给具有SQL访问权限的其他应用程序,但这里它将是一个提供二进制数据的应用程序内提供程序。

Here is a tutorial,展示了如何使用ContentProvider处理二进制数据。

答案 4 :(得分:-1)

我尝试了很多东西,但没有一个能奏效。 Android API目前不支持此功能。所以我必须依靠本机代码来解码视频然后进行编码。

要做到这一点,我必须先学习一些事情,例如JNINDK。然后我将不得不应用本机代码。我听说过一个支持这些功能的好库ffmpeg,它提供了许多功能。但是目前我参与了另一个项目,所以我无法尝试这个库和所有这些东西。