Advertisement
Guest User

Untitled

a guest
Aug 20th, 2016
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.60 KB | None | 0 0
  1. package com.carvalab;
  2.  
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.IOException;
  7. import java.io.RandomAccessFile;
  8. import java.net.URL;
  9. import java.nio.channels.Channels;
  10. import java.nio.channels.FileChannel;
  11. import java.nio.channels.WritableByteChannel;
  12. import java.util.Date;
  13.  
  14. import javax.ws.rs.core.HttpHeaders;
  15. import javax.ws.rs.core.StreamingOutput;
  16.  
  17. import spark.Request;
  18. import spark.Response;
  19.  
  20. import static spark.Spark.*;
  21.  
  22. public class App {
  23.  
  24.     static int chunk_size = 1024 * 1024; // 1MB chunks
  25.     private static File audio;
  26.    
  27.     public static void main(String[] args) {
  28.         // serve media from file system
  29.         URL url = ClassLoader.getSystemClassLoader().getResource("music.mp3");
  30.         audio = new File(url.getFile());
  31.        
  32.         head("/music", (req, resp) -> {
  33.             System.out.println("Requesting header support...");
  34.             return acceptRangeHeaders(resp);
  35.         });
  36.        
  37.         get("/music", (req, resp) -> {
  38.             System.out.println("Get stream chunk...");
  39.             return streamAudio(req, resp);
  40.         });
  41.        
  42.         get("/", (req, resp) -> {
  43.             return "Online.";
  44.         });
  45.     }
  46.    
  47.     public static StreamingOutput streamAudio(Request req, Response resp){
  48.         //Read range parameter
  49.         String range = req.headers("Range");
  50.        
  51.         try {
  52.             return buildStream(resp, audio, range);
  53.         } catch (Exception e) {
  54.             e.printStackTrace();
  55.         }
  56.        
  57.         System.out.println("Failed!");
  58.         resp.type("text/html");
  59.         resp.status(404);
  60.         resp.body("WTF");
  61.         return null;
  62.     }
  63.    
  64.     public static Response acceptRangeHeaders(Response resp){
  65.         resp.type("audio/mp3");
  66.         resp.status(206);
  67.         resp.header(HttpHeaders.CONTENT_LENGTH, String.valueOf(audio.length()));
  68.         return resp;
  69.     }
  70.    
  71.     private static StreamingOutput buildStream(Response resp, final File asset, final String range) throws Exception {
  72.         resp.type("audio/mp3");
  73.        
  74.         // range not requested : Firefox, Opera, IE do not send range headers
  75.         if (range == null) {
  76.             StreamingOutput streamer = output -> {
  77.                 try (FileChannel inputChannel = new FileInputStream(asset).getChannel(); WritableByteChannel outputChannel = Channels.newChannel(output)) {
  78.                     inputChannel.transferTo(0, inputChannel.size(), outputChannel);
  79.                 }
  80.             };
  81.             resp.status(200);
  82.             resp.header(HttpHeaders.CONTENT_LENGTH, String.valueOf(asset.length()));
  83.             return streamer;
  84.         }
  85.  
  86.         String[] ranges = range.split("=")[1].split("-");
  87.         final int from = Integer.parseInt(ranges[0]);
  88.         /**
  89.          * Chunk media if the range upper bound is unspecified. Chrome sends "bytes=0-"
  90.          */
  91.         int to = chunk_size + from;
  92.         if (to >= asset.length()) {
  93.             to = (int) (asset.length() - 1);
  94.         }
  95.         if (ranges.length == 2) {
  96.             to = Integer.parseInt(ranges[1]);
  97.         }
  98.  
  99.         final String responseRange = String.format("bytes %d-%d/%d", from, to, asset.length());
  100.         final RandomAccessFile raf = new RandomAccessFile(asset, "r");
  101.         raf.seek(from);
  102.  
  103.         final int len = to - from + 1;
  104.         final MediaStreamer streamer = new MediaStreamer(len, raf);
  105.         resp.status(206);
  106.         resp.header("Accept-Ranges", "bytes");
  107.         resp.header("Content-Range", responseRange);
  108.         resp.header(HttpHeaders.CONTENT_LENGTH, ""+streamer.getLength());
  109.         resp.header(HttpHeaders.LAST_MODIFIED, new Date(asset.lastModified()).toString());
  110.        
  111.         return streamer;
  112.     }
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement