video使用HTML 5和servlet

下面给出的代码用于video流。 这对于IE9和Firefox来说很不错,但Chrome和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 = 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; } } 

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

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

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

这应该是可能的,无需嗅探用户代理并通过RandomAccessFile而不是Filebyte[]正确响应Range请求。 考虑所有HTTP规范要求只需要很多代码,所以这里只是一个链接,您可以在其中找到这样一个servlet的具体示例: FileServlet支持简历和缓存 。

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

  

这样,所需的媒体文件只能通过http:// localhost:8080 / media / final.ogg和http:// localhost:8080 / media / final.mp4获得,而无需自行生成servlet。

这似乎更像是一种格式支持问题。

你可以试试ogg格式。 HTML5代码是

  

谷歌浏览器不支持H.264(包括mp4),因此您还需要将final.ogg与谷歌浏览器一起使用。 而对于safari,你需要改变这一行

 browser.indexOf("CoreMedia") != -1 

添加“Safari”而不是“CoreMedia”

我希望它有效。

 String diskfilename = "final.mp4"; response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"" ); 

只需评论这两行,然后在Chrome上播放您的video即可播放。