视频使用HTML 5和servlet [英] Video Using HTML 5 and servlet

查看:127
本文介绍了视频使用HTML 5和servlet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下给出的代码用于视频流。这对于IE9和Firefox来说很好,但是对于Chrome和Mac Safari来说这不太好。

Below given code is for video streaming. This is fine with IE9 and firefox but it is not fine with Chrome and Mac Safari.

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class VideoStreamServlet
 */

public class VideoStreamServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * Default constructor. 
     */
    public VideoStreamServlet() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        String range = request.getHeader("range");
        String browser = request.getHeader("User-Agent");
        System.out.println(browser);
        if(browser.indexOf("Firefox") != -1){
            System.out.println("==========ITS FIREFOX=============");
            byte[] data = getBytesFromFile(new File("D:/media/final.ogg"));
            response.setContentType("video/ogg");
            response.setContentLength(data.length);
            response.setHeader("Content-Range", range + Integer.valueOf(data.length-1));
            response.setHeader("Accept-Ranges", "bytes");
            response.setHeader("Etag", "W/\"9767057-1323779115364\"");
            byte[] content = new byte[1024];
            BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
            OutputStream os = response.getOutputStream();
            while (is.read(content) != -1) {
                //System.out.println("... write bytes");
                os.write(content);
            }
            is.close();
            os.close();
        }

        else if(browser.indexOf("Chrome") != -1){
            System.out.println("==========ITS Chrome=============");
            byte[] data = getBytesFromFile(new File("D:/media/final.mp4"));
            String diskfilename = "final.mp4";
            response.setContentType("video/mp4");
            //response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"" );
            System.out.println("data.length " + data.length);
            response.setContentLength(data.length);
            response.setHeader("Content-Range", range + Integer.valueOf(data.length-1));
            response.setHeader("Accept-Ranges", "bytes");
            response.setHeader("Etag", "W/\"9767057-1323779115364\"");
            byte[] content = new byte[1024];
            BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
            OutputStream os = response.getOutputStream();
            while (is.read(content) != -1) {
                //System.out.println("... write bytes");
                os.write(content);
            }
            is.close();
            os.close();
        }

        else if(browser.indexOf("MSIE") != -1) {
            System.out.println("==========ITS IE9=============");
            byte[] data = getBytesFromFile(new File("D:/media/final.mp4"));
            String diskfilename = "final.mp4";
            response.setContentType("video/mpeg");
            //response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"" );
            System.out.println("data.length " + data.length);
            response.setContentLength(data.length);
            response.setHeader("Content-Range", range + Integer.valueOf(data.length-1));
            response.setHeader("Accept-Ranges", "text/x-dvi");
            response.setHeader("Etag", "W/\"9767057-1323779115364\"");
            byte[] content = new byte[1024];
            BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
            OutputStream os = response.getOutputStream();
            while (is.read(content) != -1) {
                //System.out.println("... write bytes");
                os.write(content);
            }
            is.close();
            os.close();
        }
        else if( browser.indexOf("CoreMedia") != -1) {
            System.out.println("============ Safari=============");
            byte[] data = getBytesFromFile(new File("D:/media/final.mp4"));
            String diskfilename = "final.mp4";
            response.setContentType("video/mpeg");
            //response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"" );
            System.out.println("data.length " + data.length);
            //response.setContentLength(data.length);
            //response.setHeader("Content-Range", range + Integer.valueOf(data.length-1));
           // response.setHeader("Accept-Ranges", " text/*, text/html, text/html;level=1, */* ");
           // response.setHeader("Etag", "W/\"9767057-1323779115364\"");
            byte[] content = new byte[1024];
            BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
            OutputStream os = response.getOutputStream();
            while (is.read(content) != -1) {
                //System.out.println("... write bytes");
                os.write(content);
            }
            is.close();
            os.close();
        }
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }   
     private static byte[] getBytesFromFile(File file) throws IOException {
        InputStream is = new FileInputStream(file);
        //System.out.println("\nDEBUG: FileInputStream is " + file);
        // Get the size of the file
        long length = file.length();
        //System.out.println("DEBUG: Length of " + file + " is " + length + "\n");
        /*
         * You cannot create an array using a long type. It needs to be an int
         * type. Before converting to an int type, check to ensure that file is
         * not loarger than Integer.MAX_VALUE;
         */
        if (length > Integer.MAX_VALUE) {
            System.out.println("File is too large to process");
            return null;
        }
        // Create the byte array to hold the data
        byte[] bytes = new byte[(int)length];
        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while ( (offset < bytes.length)
                &&
                ( (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) ) {
            offset += numRead;
        }
        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file " + file.getName());
        }
        is.close();
        return bytes;
    }

}


推荐答案

老实说,这种做法绝对不对。

Honestly, this approach is absolutely not right.


  • 您正在嗅探服务器端的用户代理并依赖其上的业务作业。在所有情况下,这都是一个坏主意。如果你想要的只是根据用户代理指定一个不同的文件,那么在JavaScript方面,借助JavaScript或CSS来做它。两种客户端语言都能够识别真实的浏览器,而无需嗅探用户代理字符串(即可欺骗)。

  • You are sniffing the user agent in the server side and depending the business job on it. This is in all cases a bad idea. If all you want is to specify a different file depending on the user agent, then rather do it in the HTML side, with help of JavaScript or CSS. Both client side languages are able to identify the real browser without the need to sniff the user agent string (which is namely spoofable).

您在范围请求中没有正确响应。您正在发送完整文件而不是请求的范围。 Firefox和IE不使用范围请求,这就是它工作的原因。 Chrome和Safari使用范围请求。

You are not responding correctly on Range requests. You're sending the complete file back instead of the requested Range. Firefox and IE do not use range requests and that's why it "works". Chrome and Safari use range requests.

这可以在不嗅探用户代理并正确回复<$ c的情况下实现$ c>范围请求 RandomAccessFile 而不是文件字节[] 。考虑到所有 HTTP规范要求,只需要很多代码,所以这里只是一个链接,您可以在其中找到此类servlet的具体示例:支持简历和缓存的FileServlet

This should be possible without sniffing the user agent and properly responding to Range requests by RandomAccessFile instead of File and byte[]. It's only pretty a lot of code to take all HTTP specification requirements into account, so here's just a link where you can find a concrete example of such a servlet: FileServlet supporting resume and caching.

然而,更好的方法是将作业委托给servletcontainer的默认servlet。如果它是例如Tomcat,那么你需要做的就是将以下行添加到 /conf/server.xml

However, much better is to delegate the job to the servletcontainer's default servlet. If it's for example Tomcat, then all you need to do is to add the following line to /conf/server.xml:

<Context docBase="D:\media" path="/media" />

这样, http:// localhost:8080 / media / final.ogg http:/ /localhost:8080/media/final.mp4 ,无需自行生成servlet。

This way the desired media files are just available by http://localhost:8080/media/final.ogg and http://localhost:8080/media/final.mp4 without the need to homegrow a servlet.

这篇关于视频使用HTML 5和servlet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆