servlet + video streaming + ClientAbortException
I am facing this issue with the servlet when i am trying to stream video file from the server. The code to server the file
if (contentType == null) {
contentType = "application/octet-stream";
}
response.reset();
response.setBufferSize(ServerConfiguration.DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
response.setHeader("Cache-Control", "public") ;
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
// Open streams.
input = new BufferedInputStream(new FileInputStream(file), ServerConfiguration.DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), ServerConfiguration.DEFAULT_BUFFER_SIZE);
// Write file contents to response.
byte[] buffer = new byte[ServerConfiguration.DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
}
catch (Exception e) {
log(e);
}
finally {
// Gently close streams.
close(output);
close(input);
}
I have set the content-disposition to 'inline' and when i debug i can see the request coming to the server in an infinite loop and each time it throws this error:
ClientAbortException: java.io.IOException
at开发者_高级运维 org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:369)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:327)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:392)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:381)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:93)
at java.io.BufferedOutputStream.write(Unknown Source)
at com.venividi.ResourceManager.UploadFileManager.getMediaFiles(UploadFileManager.java:118)
at com.venividi.Servlet.VenividiServlet.doGet(VenividiServlet.java:182)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.venividi.Servlet.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:29)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:306)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:322)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1732)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException
at org.apache.coyote.http11.InternalAprOutputBuffer.flushBuffer(InternalAprOutputBuffer.java:208)
at org.apache.coyote.http11.InternalAprOutputBuffer$SocketOutputBuffer.doWrite(InternalAprOutputBuffer.java:238)
at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:84)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:190)
at org.apache.coyote.Response.doWrite(Response.java:533)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:364)
... 28 more
If i change the content disposition type to attachment - i am able to download the file and play the file from localsytem (which means the data is correct) but am not able to play this video file(thru the url)using VLC player (network stream option) or my custom iphone media player.
I want to do something like the server - http://www.yo-yo.org/mp4/yu.mp4 .. i can play this file by giving the URL to VLC or my Iphone app .. website for the file (http://www.yo-yo.org/mp4/) ..
The response header of the yo-yo mp4 file is
Accept-Ranges:bytes Connection:Keep-Alive Content-Length:7846115 Content-Type:text/plain; charset=UTF-8 Date:Mon, 15 Aug 2011 18:01:12 GMT ETag:"32a000f-77b8e3-3bd314df3c340" Keep-Alive:timeout=2 Last-Modified:Fri, 09 May 2003 01:39:49 GMT Server:Apache/2.2.8 (Fedora)
while the response header of my server is
Cache-Control:public Content-Disposition:inline; filename="3648ef48-71bf-4393-9c0e-89fda68a683c.mp4" Content-Length:7846115 Content-Type:video/mp4 Date:Mon, 15 Aug 2011 18:10:07 GMT Server:Apache-Coyote/1.1
Please provide some suggestions . I will really appreciate any help
Regards surya
I got the solution to the above issue. The chrome sends byte-range requests and the server should handle such requests, rather than writing the complete file in a single request.
This link is helpful: Servlet Supporting Resume
精彩评论