I need to support resume on Jersey REST, I'm trying to do it this way:
@Path("/helloworld")
public class RestServer {
@GET
@Path("say")
@Produces("audio/mp3")
public Response getMessage(@HeaderParam("Range") String r ) throws IOException{
String str="/Users/dima/Music/crazy_town_-_butterfly.mp3";
System.out.println(r);
RandomAccessFile f=new RandomAccessFile(str, "r");
int off=0;
int to=(int)f.length();
byte[] data ;
if(r!=null){
String from=r.split("=")[1].split("-")[0];
String t=r.split("=")[1].split("-")[1];
off=Integer.parseInt(from);
to=Integer.parseInt(t);
}
data= new byte[to-off];
f.readFully(data, off, to-off);
ResponseBuilder res=Response.ok(data)
.header("Accept-Ranges","bytes")
.header("Content-Range:", "bytes "+off+"-"+to+"/"+data.length)
.header("Pragma", "no-cache");;
if(r==null){
res=res.header("Content-Length", data.length);
}
f.close();
Response ans=res.build();
return ans;
}
}
I want to be able stream mp3 so the browser can seek the music, but in safari it still not working. any ideas?
Here is my take based on the solution provided here. It works correctly on different browsers. I am able to seek the music just fine in Safari and other browsers as well. You can find the sample project on my Github repository which has more details. Chrome and Safari nicely leverages the range headers to stream media and you can see it in the request/response trace.
Here is the MediaStreamer implementation, which is used to stream the output in your resource method.
Since I was facing the same problema, I tried a more general solution[1] with a
ContainerResponseFilter
which will trigger when aRange
header is present in the request and will work seamlessly with any media-type, entity and resource methods.This is the
ContainerResponseFilter
which will use encapsulate the output stream in aRangedOutputStream
(see below):And here's the
RangedOutputStream
:[1] https://github.com/heruan/jersey-range-filter