代码之家  ›  专栏  ›  技术社区  ›  Rakesh Yadav

Java Android部分下载视频并播放

  •  0
  • Rakesh Yadav  · 技术社区  · 7 年前

    我不知道该怎么办。请建议如何下载一个大的视频文件的一部分,并发挥所有部分一个接一个。 实际上,我必须在Android中传输FTP大文件 VideoView . 我搜索了很多,发现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之后下载的文件不能播放。他们甚至不在电脑上玩。我不知道我做错了什么。

    5 回复  |  直到 7 年前
        1
  •  2
  •   Milos Fec    7 年前

    ServerSocket

    VideoView 你会打开 127.0.0.1:PORT 使用您将为本地服务器打开的端口。我建议使用IP而不是 localhost . 有了IP,我从来没有任何问题。

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

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

        2
  •  2
  •   Surender Singh Rawat    7 年前

    以这种方式解码文件不会播放所有文件。因为它们只是二进制文件,您试图更改它们的扩展名。在android中,没有办法以这种方式解码文件。但是有很多库可以用来将文件解码成部分,然后分别播放每个部分。图书馆之一是 ffmpeg .

        3
  •  0
  •   anemo    7 年前

    如果将视图文件拆分为多个部分,则只有第一部分包含格式规范。这就是为什么只有你的第一部分得到发挥。所有其他部分都只是二进制文件。

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

    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");
        }
    }
    
        4
  •  0
  •   Alex Cohn    7 年前

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

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

        5
  •  -1
  •   Rakesh Yadav    7 年前

    我试了很多东西,但都不管用。Android API目前不支持此功能。所以我必须依靠本地代码来解码视频,然后进行编码。

    要做到这一点,我必须先学习一些东西,比如 JNI NDK . 然后我必须应用本机代码。我听说有一个很好的库支持这些功能 ffmpeg 它提供了许多功能。但目前我正在从事另一个项目,所以我不能尝试那个图书馆和所有这些东西。