开发者

Java-Servlet: Streaming of a Quicktime-video causes a ClientAbortException

I am trying to program a small webproxy based on a java-servlet. This proxy has only one task:

  1. HTML shall be passed to the client which sent the request (GET requests with destination port 80 are rerouted to the proxy by firewall rules).
  2. An embedded quicktime-video shall be replaced by another quicktime-video and shall be passed to the client instead of the initially requested (here, too, the initially sent GET request of the client is rerouted to the proxy first. The proxy detects that the requested content type is not HTML and concludes from this issue that the content must be a quicktime-video in this special case (see HTML below)). As a result the proxy shall send/stream a particular video to the client.

This should happen for the following HTML document that is going to be requested by the client:

<html>
<head>

<h1> Heading!</h1>
</head>
<body>

<h1>My First Heading</h1>

<object width="160" height="144"
classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
codebase="http://www.apple.com/qtactivex/qtplugin.cab">
<param name="src" value="final_lion.mov">
<param name="autoplay" value="true">
<param name="controller" value="false">

<embed src="final_lion.mov" width="480" height="432"
autoplay="true" controller="false"
pluginspage="http://www.apple.com/quicktime/download/">
</embed>

</object> 

</body>
</html> 

The source code of the proxy-servlet is as follows:

protected void doGet开发者_Go百科(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    ServletContext context = getServletContext();
    PrintWriter out = null;
    try {
            String result = new String();
            String urlStr = request.getRequestURL().toString();


            URL url = new URL(urlStr);
            URLConnection conn = url.openConnection();

            response.setContentType(conn.getContentType());

            if (conn.getContentType().contains("text/"))
            {
                out = response.getWriter(); 
                out.write(getTextContent(conn));
                out.flush();
                out.close();
            }
            else
            {
                File file = new File("/var/www/final_lion.mov");
                response.setContentType("video/quicktime");
                response.setHeader("Content-Length", Long.toString(file.length()));
                response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
                FileInputStream input = new FileInputStream(file);
                OutputStream output = response.getOutputStream();

                byte[] buffer = new byte[4096];
                int read = 0;
                while((read = input.read(buffer)) != -1 ){
                    output.write(buffer,0,read);
                }
                input.close();
                output.flush();
                output.close();

            }
        } catch (Exception e) {
                context.log("error", e);
        }
}

private String getTextContent(URLConnection conn)
{
    try{
        BufferedReader rd = new BufferedReader(new InputStreamReader(
                conn.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = rd.readLine()) != null) {
            sb.append(line + "\n");
        }
        rd.close();
        return sb.toString();
    }catch (Exception e){
        return "error: " + e.toString();
    }
}

The HTML document is delivered by the proxy and rendered by the browser correctly. But the GET request for the quicktime-video respectively the response of the proxy causes a ClientAbortException: java.net.SocketException: Broken pipe at line 34 of the servlet-sourcecode.

I tried various kinds of OutputStreams (BufferedOutputStream, DataOutputStream, PipedOutputStream, ServletOutputStream). None of them did work...

Does anybody see my mistake?

Yours faithfully, Ashiaka


Lot of players for streaming media expects the server side to support Range requests. Usually the servletcontainer's (Tomcat, JBoss AS, Glassfish, etc) own default servlet supports this already. So if there's a way to publish the movie folder into the web by just adding the folder to the server configuration, so that you don't need a homegrown servlet for this, then I'd go on this route.

For example, in Tomcat you could achieve this by just moving the file into Tomcat/webapps/movies folder, or by adding the following line to its /conf/server.xml:

<Context docBase="/var/www/movies" path="/movies" />

If you put the final_lion.mov file in Tomcat/webapps/movies or /var/www/movies folder depending on the configuration choice, then you should be able to access it by http://localhost:8080/movies/final_lion.mov without the need for any homegrown servlet. Instead, Tomcat's own DefaultServlet will be used to stream the static content.

But if there's no way, then you need to rewrite your servlet code in such way that it supports Range requests (also known as download resumes). You can find a concrete kickoff example in this article.


I have same issue faced and spend few days and try to dig one by one. This is related to your browser cache issue. You may try to use this code. It works for me.

response.addHeader("Cache-Control", "no-transform, max-age=0");

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜