【问题标题】:servlet + video streaming + ClientAbortExceptionservlet + 视频流 + ClientAbortException
【发布时间】:2011-10-27 11:51:12
【问题描述】:

当我尝试从服务器流式传输视频文件时,我遇到了 servlet 的这个问题。 服务器文件的代码

    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);
        }

我已将 content-disposition 设置为“内联”,当我调试时,我可以看到请求以无限循环的形式到达服务器,并且每次它都会抛出此错误:

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

如果我将 内容处置类型更改为附件 - 我可以从本地系统下载文件并播放文件(这意味着数据正确)但无法播放此视频文件(通过 url)使用 VLC 播放器(网络流选项)或我的自定义 iphone 媒体播放器。

我想做一些类似服务器的事情 - http://www.yo-yo.org/mp4/yu.mp4 .. 我可以通过将 URL 提供给 VLC 或我的 Iphone 应用程序来播放这个文件 .. 文件的网站 (http://www.yo-yo.org /mp4/) ..

悠悠球mp4文件的响应头是

接受范围:字节 连接:保活 内容长度:7846115 内容类型:文本/纯文本;字符集=UTF-8 日期:2011 年 8 月 15 日星期一 18:01:12 GMT ETag:“32a000f-77b8e3-3bd314df3c340” 保活:超时=2 最后修改时间:格林威治标准时间 2003 年 5 月 9 日星期五 01:39:49 服务器:Apache/2.2.8 (Fedora)

而我服务器的响应头是

缓存控制:公共 内容处置:内联;文件名="3648ef48-71bf-4393-9c0e-89fda68a683c.mp4" 内容长度:7846115 内容类型:视频/mp4 日期:2011 年 8 月 15 日星期一 18:10:07 GMT 服务器:Apache-Coyote/1.1

请提供一些建议。我将非常感谢任何帮助

问候 苏里亚

【问题讨论】:

    标签: java servlets streaming


    【解决方案1】:

    我得到了上述问题的解决方案。 chrome 发送字节范围请求,服务器应处理此类请求,而不是在单个请求中写入完整文件。

    此链接很有帮助:Servlet Supporting Resume

    【讨论】:

    • 嗨 surya,你能发布示例代码吗,因为我在视频流中也有同样的问题。 BalusC 链接具有仅处理文本、图像和 Zip 文件的示例。但我想处理视频文件。您能否分享一些示例代码以及编写代码以在 servlet 中处理视频文件的方法...
    • BalusC 代码适用于我的音频/视频文件。在所有浏览器/设备上。您可以使用 Java 的网络 i/o 库来优化代码,但代码中的逻辑是有效的
    • 谢谢苏利亚,我会努力的
    猜你喜欢
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 2016-04-10
    相关资源
    最近更新 更多