通过HTTP将大型视频文件从Tomcat服务器传输到Android客户端

时间:2012-11-11 08:09:19

标签: java android tomcat video-streaming

我已经查看了所有类似的问题,但没有一个答案似乎能解决我的问题。我正在尝试将视频文件从我的Tomcat服务器流式传输到Android Web浏览器。我可以在Chrome浏览器中流式传输视频。我也可以使用类似的代码传输图像(较小的文件)。

这是我的servlet代码,它将视频转换为字节流以通过HTTP传输

public class VideoServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

    try {
        File file = new File("C:\\Users\\ishan\\Desktop\\hisocData\\"
                + req.getPathInfo().substring(1));

        FileInputStream is = new FileInputStream(file);

        resp.setHeader("Content-Length", Long.toString(file.length()));
        resp.setContentType("video/3gpp");

        // Open the file and output streams
        OutputStream out = resp.getOutputStream();

        // Copy the contents of the file to the output stream
        byte[] buf = new byte[1024];
        int count = 0, length = 0;
        while ((count = is.read(buf)) >= 0) {
            out.write(buf, 0, count);
            length += count;
        }
        is.close();
        out.close();
        resp.setContentLength(length);
    } catch (FileNotFoundException e) {
        OutputStream out = resp.getOutputStream();
        out.write("File not found!".getBytes());
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}

当我尝试在Android网络浏览器上访问此视频文件时出现此错误:

ClientAbortException:  java.net.SocketException: Connection reset by peer: socket write error
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:388)
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:462)
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
    at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:413)
    at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:401)
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91)
    at data.VideoServlet.doGet(VideoServlet.java:40)
    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:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: Connection reset by peer: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(Unknown Source)
    at java.net.SocketOutputStream.write(Unknown Source)
    at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:462)
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
    at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:240)
    at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:84)
    at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
    at org.apache.coyote.Response.doWrite(Response.java:504)
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:383)

我真的很感谢你的帮助。我已经被困在这个问题上几天了。

4 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

您需要实现HTTP范围支持。请参阅this,几乎相同的问题/答案。

答案 2 :(得分:0)

问题很可能是由于在响应已经发送后尝试设置内容长度引起的。你应该删除这一行

resp.setContentLength(length);

请注意,它与您在请求开始时所做的相同:

resp.setHeader("Content-Length", Long.toString(file.length()));

我建议你用resp.setContentLength(file.length())替换resp.setHeader(...);

答案 3 :(得分:0)

问题是我试图以.3gp格式传输视频,这是播放器无法识别的。当我把它改成.mov时,它工作得很好。对不起,麻烦的家伙,