Cómo publicar videos grandes en un servidor, en Android?

Estoy intentando publicar un video grande (casi 1 GB).

Estoy utilizando FTP para enviar video a un servidor, pero la carga se detiene después de un tiempo. En el servidor, el video se bloquea, pero puedo subir un video de menor tamaño.

También he utilizado el HTTP para enviar el vídeo al servidor, enviado como cadena Base64 enoded, pero hay una excepción de la memoria durante la codificación.

He intentado subir el video como un archivo, pero sin éxito. ¿Cuál es la mejor manera de subir un video grande a un servidor?

Utilice HTTP POST y publique contenido como Carga de archivos basada en formularios (tipo mime: multipart / form-data). Este sistema es estándar en la web para enviar formularios y / o cargar archivos.

Utilice el modo de post chunked HTTP, por lo que el tamaño no necesita ser conocido de antemano, y puede transmitir cualquier archivo en pequeñas partes. Usted todavía tiene que hacer algún código en el servidor (por ejemplo, en PHP) para aceptar el archivo y hacer lo que se necesita.

Utilice HttpURLConnection para iniciar la conexión. A continuación, utilice mi clase adjunta para enviar los datos. Se creará los encabezados adecuados, etc, y lo usará como OutputStream para escribir sus datos sin procesar, a continuación, llamar a cerrar, y ya está. Puede sobrescribir su onHandleResult para manejar el código de error resultante.

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

Supongo que falló debido a un tiempo de espera por el gran tamaño.

Ya que

Vídeo de tamaño pequeño cargado correctamente

Mi sugerencia es

  1. Dividir un archivo grande en varios archivos pequeños.
  2. Cargar uno por uno o varios juntos sobre la base de la condición de la red.
  3. Únete a todas las partes (después de todas las subidas correctamente) en el servidor.
  4. Debido a su tamaño pequeño, volver a cargar la parte fallada será fácil.

Sólo un theroy.

Este sitio puede ayudar.


Añadido 08.01.2013

Ha pasado un tiempo, no sé si todavía necesitas esto. De todos modos, escribí algunos códigos simples implementar la teoría anterior, debido principalmente al interés.

  1. Dividir un archivo grande en varios archivos pequeños. Lea el archivo grande en varias partes pequeñas.

     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)); 
  2. Cargar uno por uno o varios juntos sobre la base de la condición de la red.

     Part part = parts.take(); if (part == Part.NULL) { parts.add(Part.NULL);// notify others to stop. break; } else { uploader.upload(part); } 
  3. Únete a todas las partes (después de todas las subidas correctamente) en el servidor. Porque es a través de HTTP, por lo que puede ser en cualquier idioma, como Java, PHP, Python, etc Aquí es un ejemplo de 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); } 

Pongo todos los códigos en GitHub . Y hizo un ejemplo de Android también.

Por favor, eche un vistazo si todavía necesita.

Privado HttpsURLConnection conn = null;

Conn.setDoInput (true);

Conn.setDoOutput (true);

Conn.setUseCaches (false);

Conn.setChunkedStreamingMode (1024);

  • Cómo hacer que una videoview NO se inicie automáticamente después de preparado
  • Android: streaming de video por servidor HTTPS local: certificado SSL rechazado
  • ¿Cómo puedo asegurar la correcta orientación de reproducción del video grabado?
  • Obtención de pantalla en negro cuando se agrega ExoPlayer a GLSurfaceView
  • No se pueden transmitir vídeos
  • Vídeo con iframe no se muestra en la vista web de Android
  • Error al reproducir el video subido a través de PhoneGap FileTransfer
  • ¿Se admiten los subtítulos en cualquiera de los controles de vídeo nativos?
  • Reproducción de vídeo en TextureView
  • ¿Cómo puedo capturar una grabación de vídeo en Android?
  • Elemento HTML5 <video> en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.