2015-10-28 25 views
5

sto cercando di trasmettere un file video su resto, sto cercando di implementare qualcosa di simile a Jersey in questo modo:flusso di un file video su REST HTTP con Spark Java

 ResponseBuilder builder = Response.ok(out.toByteArray()); 
     builder.header("Content-Disposition", "attachment; filename=" + fields.get("filename")); 
     response = builder.build(); 
    } else { 
     response = Response.status(404). 
      entity(" Unable to get file with ID: " + id). 
      type("text/plain"). 
      build(); 
    } 

    return response; 
    } 

Ecco quello che ho per l'upload di file e download/streaming (scaricare semi-opere, la dimensione del file è corretto dal corrotto):

ho veramente bisogno di aiuto con questo tutti, grazie

UPDATE

cambiato:

ByteArrayOutputStream out = new ByteArrayOutputStream(); 

a:

ServletOutputStream out = res.raw().getOutputStream(); 

UPDATE 2 Ok, ho finalmente capito di lavoro, e la riproduzione del video nel browser, ma ora ottenere un molo io.EofException, ho chiuso il flusso ma ancora, deve essere qualcosa di semplice.

Qui di seguito sono sia la prima che dopo:

e il download dal funzionamento del browser, ma come posso streaming direttamente nel browser?

PRIMA (non ha funzionato)

//download a video/ trying to stream it right in the browser if possible 
    get("/post/:id", (req, res) -> { 

      res.raw().setContentType("application/octet-stream"); 

      String id = req.params(":id"); 

      ObjectId objectId = new ObjectId(id); 
      BasicDBObject query = new BasicDBObject(); 

      query.put("_id", objectId); 
      //DBObject video = collection.findOne(query); 

      GridFS gridfile = new GridFS(db, "videos"); 
      GridFSDBFile gridFSDBFile = gridfile.findOne(query); 
      res.raw().setHeader("Content-Disposition", "attachment; filename=" + gridFSDBFile.getFilename()); 

      InputStream inputStream = gridFSDBFile.getInputStream(); 

      ServletOutputStream out = res.raw().getOutputStream(); 
      // ByteArrayOutputStream out = new ByteArrayOutputStream(); 
      int data = inputStream.read(); 
      while (data >= 0) { 
       out.write((char) data); 
       data = inputStream.read(); 
      } 
      out.flush(); 
      out.close(); 
      return out; 
     }); 

DOPO (Questo funziona perfettamente, ma ottenendo alla fine d'eccezione file):

get("/post/:id", (req, res) -> { 
      //what's the difference between these 2? 
      res.raw().setContentType("video/mp4"); 
      res.type("video/mp4"); 

      String id = req.params(":id"); 

      ObjectId objectId = new ObjectId(id); 
      BasicDBObject query = new BasicDBObject(); 

      query.put("_id", objectId); 
      GridFS gridfile = new GridFS(db, "videos"); 
      GridFSDBFile gridFSDBFile = gridfile.findOne(query); 

      res.raw().setContentLengthLong(gridFSDBFile.getLength()); 
      InputStream inputStream = gridFSDBFile.getInputStream(); 

      ServletOutputStream out = res.raw().getOutputStream(); 

      int data = inputStream.read(); 
      while (data >= 0) { 
       gridFSDBFile.writeTo(out); 
       data = inputStream.read(); 
      } 

      // out.flush(); 
      out.close(); 

      return 200; 

     }); 

Carica:

post("/postvideo/:username", (req, res) -> { 
      MultipartConfigElement multipartConfigElement = 
        new MultipartConfigElement("/tmp"); 
      req.raw(). 
        setAttribute("org.eclipse.jetty.multipartConfig", 
          multipartConfigElement); 
      String username = req.params(":username"); 
      double[] location = 
        new double[2]; 
      double lattitude = 
        Double.parseDouble(req.queryParams("lat")); 
      double longitude = 
        Double.parseDouble(req.queryParams("lon")); 
      location[0] = lattitude; 
      location[1] = longitude; 

      InputStream inputStream = req.raw().getPart("file").getInputStream();; 

      Part uploadedFile = req.raw().getPart("file"); 
      // File file = new File(uploadedFile.getName()); 
      GridFS gridFS = new GridFS(db, "videos"); 

      GridFSInputFile gfsFile = gridFS.createFile(inputStream); 

      gfsFile.put("location", location); 
      gfsFile.put("username", username); 
      gfsFile.put("contentType", req.raw().getContentType()); 
      gfsFile.put("filename", uploadedFile.getSubmittedFileName()); 
      collection.insert(gfsFile); 

      gfsFile.save(); 
      return 201; 
     }); 
+0

Mi dispiace di essere il nitpicker ma io sgomento quando ho visto il modo in cui formulato la domanda. Non è possibile eseguire lo streaming di un video su uno stile architettonico. – toniedzwiedz

+0

@toniedzwiedz ??? ok, non so davvero cosa intendi. Ad ogni modo, ho migliorato la mia soluzione e funziona perfettamente. Forse ho sbagliato ma il tuo commento è in realtà inutile. – franklinexpress

risposta

5

Ecco il metodo che funziona. Sarò il caricamento di un soluzione che ti permette di saltare alle sezioni del video così, pezzo di torta;)

get("/post/:id", (req, res) -> { 
     //what's the difference between these 2? 
     res.raw().setContentType("video/mp4"); 
     res.type("video/mp4"); 

     String id = req.params(":id"); 

     ObjectId objectId = new ObjectId(id); 
     BasicDBObject query = new BasicDBObject(); 

     query.put("_id", objectId); 
     GridFS gridfile = new GridFS(db, "videos"); 
     GridFSDBFile gridFSDBFile = gridfile.findOne(query); 

     res.raw().setContentLengthLong(gridFSDBFile.getLength()); 
     InputStream inputStream = gridFSDBFile.getInputStream(); 

     ServletOutputStream out = res.raw().getOutputStream(); 

     int data = inputStream.read(); 
     while (data >= 0) { 
      gridFSDBFile.writeTo(out); 
      data = inputStream.read(); 
     } 

     // out.flush(); 
     out.close(); 

     return 200; 

    }); 
+0

Ciao @franklinexpress - Ho dato un'occhiata ai problemi di github di Sparkjava e sembra che un approccio con un flusso illimitato (di lunghezza sconosciuta) non funzionerebbe? È giusto? Il mio caso d'uso specifico è il proxy di un flusso audio dal vivo (ad esempio 'http: //82.77.137.30: 8557 /;') – yegeniy

+1

sì, dovrebbe funzionare. Ora ho implementato che usando un Servlet con funzionalità di ricerca (Accept-Ranges) la parte di ricerca non avrebbe funzionato per una lunghezza sconosciuta, ma lo streaming dovrebbe. – franklinexpress

+0

oh dolce. Quindi, vorrei solo non impostare la lunghezza. Grazie. – yegeniy