How to place a large video on a server in Android?

I am trying to post a large video (almost 1 GB).

I use FTP to send video to the server, but the download stops after some time. The video crashes on the server, but I can upload a smaller video.

I also used HTTP to send video to a server sent as a Base64 encoded string, but there is an out of memory exception when encoding.

I tried to download the video as a file, but to no avail. What is the best way to upload large video to a server?

+7
source share
3 answers

Use HTTP POST and post content as Form- based file upload (type mime: multipart / form-data). This system is standard on the Internet for submitting forms and / or uploading files.

Use ex-post HTTP mode, so the size does not have to be known in advance, and you can transfer any file in small parts. You still need to make the code on the server (like PHP) in order to accept the file and do what you need.

Use HttpURLConnection to start the connection. Then use my attached class to send data. It will create the correct headers, etc., and you will use it as an OutputStream to write your raw data, then call close, and you're done. You can override it onHandleResult to handle the received error code.

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); } } 
+9
source

I suppose this failed due to a timeout of a large size.

FROM

Small video uploaded successfully

My suggestion

  • Split one large file into several small files.
  • Download one by one or more together depending on network status.
  • Connect all parts (after all successfully loaded) on the server.
  • Due to the small size, rebooting the failed part will be easy.

Just a trojan.

This site can help.


Posted on 1/8/2013

Some time has passed, I don’t know if you need all this. Anyway, I wrote some simple codes that implement the theory above, because of the interest mostly.

  • Divide one large file into several small files. Read the large file into several small parts.

     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)); 
  • Download one by one or more together depending on network status.

     Part part = parts.take(); if (part == Part.NULL) { parts.add(Part.NULL);// notify others to stop. break; } else { uploader.upload(part); } 
  • Connect all parts (after all successfully loaded) on the server. Because it is through HTTP, so it can be in any language, such as Java, PHP, Python, etc. Here is a java example.

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

I put all the codes on github . And he made an Android example .

Please see if you still need.

+2
source

private HttpsURLConnection conn = null;

conn.setDoInput (true);

conn.setDoOutput (true);

conn.setUseCaches (false);

conn.setChunkedStreamingMode (1024);

0
source

All Articles