Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.carvalab;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.net.URL;
- import java.nio.channels.Channels;
- import java.nio.channels.FileChannel;
- import java.nio.channels.WritableByteChannel;
- import java.util.Date;
- import javax.ws.rs.core.HttpHeaders;
- import javax.ws.rs.core.StreamingOutput;
- import spark.Request;
- import spark.Response;
- import static spark.Spark.*;
- public class App {
- static int chunk_size = 1024 * 1024; // 1MB chunks
- private static File audio;
- public static void main(String[] args) {
- // serve media from file system
- URL url = ClassLoader.getSystemClassLoader().getResource("music.mp3");
- audio = new File(url.getFile());
- head("/music", (req, resp) -> {
- System.out.println("Requesting header support...");
- return acceptRangeHeaders(resp);
- });
- get("/music", (req, resp) -> {
- System.out.println("Get stream chunk...");
- return streamAudio(req, resp);
- });
- get("/", (req, resp) -> {
- return "Online.";
- });
- }
- public static StreamingOutput streamAudio(Request req, Response resp){
- //Read range parameter
- String range = req.headers("Range");
- try {
- return buildStream(resp, audio, range);
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("Failed!");
- resp.type("text/html");
- resp.status(404);
- resp.body("WTF");
- return null;
- }
- public static Response acceptRangeHeaders(Response resp){
- resp.type("audio/mp3");
- resp.status(206);
- resp.header(HttpHeaders.CONTENT_LENGTH, String.valueOf(audio.length()));
- return resp;
- }
- private static StreamingOutput buildStream(Response resp, final File asset, final String range) throws Exception {
- resp.type("audio/mp3");
- // range not requested : Firefox, Opera, IE do not send range headers
- if (range == null) {
- StreamingOutput streamer = output -> {
- try (FileChannel inputChannel = new FileInputStream(asset).getChannel(); WritableByteChannel outputChannel = Channels.newChannel(output)) {
- inputChannel.transferTo(0, inputChannel.size(), outputChannel);
- }
- };
- resp.status(200);
- resp.header(HttpHeaders.CONTENT_LENGTH, String.valueOf(asset.length()));
- return streamer;
- }
- String[] ranges = range.split("=")[1].split("-");
- final int from = Integer.parseInt(ranges[0]);
- /**
- * Chunk media if the range upper bound is unspecified. Chrome sends "bytes=0-"
- */
- int to = chunk_size + from;
- if (to >= asset.length()) {
- to = (int) (asset.length() - 1);
- }
- if (ranges.length == 2) {
- to = Integer.parseInt(ranges[1]);
- }
- final String responseRange = String.format("bytes %d-%d/%d", from, to, asset.length());
- final RandomAccessFile raf = new RandomAccessFile(asset, "r");
- raf.seek(from);
- final int len = to - from + 1;
- final MediaStreamer streamer = new MediaStreamer(len, raf);
- resp.status(206);
- resp.header("Accept-Ranges", "bytes");
- resp.header("Content-Range", responseRange);
- resp.header(HttpHeaders.CONTENT_LENGTH, ""+streamer.getLength());
- resp.header(HttpHeaders.LAST_MODIFIED, new Date(asset.lastModified()).toString());
- return streamer;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement