Android 在安卓系统中,如何在服务器上发布大型视频?

Android 在安卓系统中,如何在服务器上发布大型视频?,android,video,upload,Android,Video,Upload,我试图发布一个大视频(接近1GB) 我正在使用FTP将视频发送到服务器,但上传会在一段时间后停止。在服务器上,视频崩溃,但我可以上传较小尺寸的视频 我还使用HTTP将视频发送到服务器,作为Base64 enoded字符串发送,但编码时出现内存不足的异常 我尝试将视频作为文件上传,但没有成功。将大型视频上传到服务器的最佳方式是什么?使用HTTP POST,并将内容发布为(mime类型:多部分/表单数据)。该系统是web上发送表单和/或上载文件的标准系统 使用HTTP分块post模式,这样就不需要事

我试图发布一个大视频(接近1GB)

我正在使用FTP将视频发送到服务器,但上传会在一段时间后停止。在服务器上,视频崩溃,但我可以上传较小尺寸的视频

我还使用HTTP将视频发送到服务器,作为Base64 enoded字符串发送,但编码时出现内存不足的异常


我尝试将视频作为文件上传,但没有成功。将大型视频上传到服务器的最佳方式是什么?

使用HTTP POST,并将内容发布为(mime类型:多部分/表单数据)。该系统是web上发送表单和/或上载文件的标准系统

使用HTTP分块post模式,这样就不需要事先知道大小,并且您可以将任何文件以小部分进行流式传输。您仍然需要在服务器上编写一些代码(例如PHP)来接受文件并执行所需操作

使用HttpURLConnection启动连接。然后使用我附加的类发送数据。它将创建适当的头文件等,您将使用它作为OutputStream将原始数据写入其中,然后调用close,就完成了。您可以过度使用其OnHandlerResult来处理产生的错误代码

public class FormDataWriter extends FilterOutputStream{
   private final HttpURLConnection con;

   /**
    * @param formName name of form in which data are sent
    * @param fileName
    * @param fileSize   size of file, or -1 to use chunked encoding
    */
   FormDataWriter(HttpURLConnection con, String formName, String fileName, long fileSize) throws IOException{
      super(null);
      this.con = con;
      con.setDoOutput(true);

      String boundary = generateBoundary();
      con.setRequestProperty(HTTP.CONTENT_TYPE, "multipart/form-data; charset=UTF-8; boundary="+boundary);
      {
         StringBuilder sb = new StringBuilder();
         writePartHeader(boundary, formName, fileName==null ? null : "filename=\""+fileName+"\"",
               "application/octet-stream", sb);
         headerBytes = sb.toString().getBytes("UTF-8");

         sb = new StringBuilder();
         sb.append("\r\n");
         sb.append("--"+boundary+"--\r\n");
         footerBytes = sb.toString().getBytes();
      }
      if(fileSize!=-1) {
         fileSize += headerBytes.length + footerBytes.length;
         con.setFixedLengthStreamingMode((int)fileSize);
      }else
         con.setChunkedStreamingMode(0x4000);
      out = con.getOutputStream();
   }

   private byte[] headerBytes, footerBytes;

   private String generateBoundary() {
      StringBuilder sb = new StringBuilder();
      Random rand = new Random();
      int count = rand.nextInt(11) + 30;
      int N = 10+26+26;
      for(int i=0; i<count; i++) {
         int r = rand.nextInt(N);
         sb.append((char)(r<10 ? '0'+r : r<36 ? 'a'+r-10 : 'A'+r-36));
      }
      return sb.toString();
   }

   private void writePartHeader(String boundary, String name, String extraContentDispositions, String contentType, StringBuilder sb) {
      sb.append("--"+boundary+"\r\n");
      sb.append("Content-Disposition: form-data; charset=UTF-8; name=\""+name+"\"");
      if(extraContentDispositions!=null)
         sb.append("; ").append(extraContentDispositions);
      sb.append("\r\n");
      if(contentType!=null)
         sb.append("Content-Type: "+contentType+"\r\n");
      sb.append("\r\n");
   }

   @Override
   public void write(byte[] buffer, int offset, int length) throws IOException{
      if(headerBytes!=null) {
         out.write(headerBytes);
         headerBytes = null;
      }
      out.write(buffer, offset, length);
   }

   @Override
   public void close() throws IOException{
      flush();
      if(footerBytes!=null) {
         out.write(footerBytes);
         footerBytes = null;
      }
      super.close();
      int code = con.getResponseCode();
      onHandleResult(code);
   }
   protected void onHandleResult(int code) throws IOException{
      if(code!=200 && code!=201)
         throw new IOException("Upload error code: "+code);
   }
}
公共类FormDataWriter扩展FilterOutputStream{
私有最终HttpURLConnection;
/**
*@param formName发送数据的表单的名称
*@param文件名
*@param fileSize文件大小,或-1使用分块编码
*/
FormDataWriter(HttpURLConnection con、字符串formName、字符串文件名、长文件大小)引发IOException{
超级(空);
this.con=con;
con.设置输出(真);
字符串边界=generateBoundary();
con.setRequestProperty(HTTP.CONTENT_TYPE,“多部分/表单数据;字符集=UTF-8;boundary=“+boundary”);
{
StringBuilder sb=新的StringBuilder();
WritePartnerHeader(边界,formName,文件名==null?null:“文件名=\”“+文件名+”\“”,
“应用程序/八位字节流”,sb);
headerBytes=sb.toString().getBytes(“UTF-8”);
sb=新的StringBuilder();
sb.追加(“\r\n”);
sb.追加(“--”+边界+”--\r\n”);
footerBytes=sb.toString().getBytes();
}
如果(文件大小!=-1){
fileSize+=headerBytes.length+footerBytes.length;
con.setFixedLengthStreamingMode((int)文件大小);
}否则
con.setChunkedStreamingMode(0x4000);
out=con.getOutputStream();
}
专用字节[]头字节,尾字节;
私有字符串生成器基础(){
StringBuilder sb=新的StringBuilder();
Random rand=新的Random();
整数计数=下一次随机数(11)+30;
int N=10+26+26;

对于(inti=0;i我想它失败是因为超时太大了

已成功上载小尺寸视频

,我的建议是

  • 将一个大文件拆分为几个小文件
  • 根据网络情况逐个上传或多个一起上传
  • 在服务器上加入所有部件(在所有这些部件成功上载之后)
  • 由于体积小,重新上传失败的部分将很容易
  • 只是一个理论

    也许会有帮助


    2013年1月8日增补 已经有一段时间了,不知道你是否还需要这个。无论如何,我写了一些简单的代码来实现上述理论,主要是出于兴趣

  • 将一个大文件拆分为几个小文件。将大文件读入几个小部分

    ByteBuffer bb = ByteBuffer.allocate(partSize);
    int bytesRead = fc.read(bb);
    if (bytesRead == -1) {
        break;
    }
    byte[] bytes = bb.array();
    parts.put(new Part(createFileName(fileName, i), bytes));
    
  • 根据网络情况逐个上传或多个一起上传

    Part part = parts.take();
    if (part == Part.NULL) {
        parts.add(Part.NULL);// notify others to stop.
        break;
    } else {
        uploader.upload(part);
    }
    
  • 在服务器上加入所有部件(在所有这些部件成功上载之后)。 因为它是通过HTTP的,所以它可以是任何语言,如Java、PHP、Python等。这里是一个Java示例

    ...
    try (FileOutputStream dest = new FileOutputStream(destFile, true)) {
    
        FileChannel dc = dest.getChannel();// the final big file.
        for (long i = 0; i < count; i++) {
            File partFile = new File(destFileName + "." + i);// every small parts.
            if (!partFile.exists()) {
                break;
            }
            try (FileInputStream part = new FileInputStream(partFile)) {
                FileChannel pc = part.getChannel();
                pc.transferTo(0, pc.size(), dc);// combine.
            }
            partFile.delete();
        }
        statusCode = OK;// set ok at last.
    } catch (Exception e) {
        log.error("combine failed.", e);
    }
    
    。。。
    try(FileOutputStream dest=newfileoutputstream(destFile,true)){
    FileChannel dc=dest.getChannel();//最后一个大文件。
    用于(长i=0;i
  • 我把所有的密码都挂上了,还做了一个


    如果您仍然需要,请查看。

    专用HttpsURLConnection conn=null

    conn.setDoInput(真)

    连接设置输出(真)

    conn.SETUSECHACHES(假)


    conn.setChunkedStreamingMode(1024);

    什么是formName?是用于创建上载xml或json的服务器表单的formName吗?对于PHP端,请参阅.formName是将在PHP中使用的$_文件['name']中的变量名称。这是否也取决于服务器最大上载大小和执行时间?请帮助我,我上载文件不成功。仅通过文件大小,这是可能的。如何在我的项目中实施它?