使用 HTML 5 和 servlet 的视频
下面给出的代码用于视频流。这对于 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 < 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;
}
}
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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
老实说,这种做法绝对不对。
您正在嗅探服务器端的用户代理并依赖于它的业务作业。在所有情况下这都是一个坏主意。如果您只想根据用户代理指定不同的文件,那么最好在 JavaScript 或 CSS 的帮助下在 HTML 端进行。两种客户端语言都能够识别真实浏览器,而无需嗅探用户代理字符串(即可欺骗)。
您没有正确响应
Range
请求。您将发回完整的文件,而不是请求的范围
。 Firefox 和 IE 不使用范围请求,这就是它“有效”的原因。 Chrome 和 Safari 使用范围请求。这应该是可能的,无需嗅探用户代理并通过
RandomAccessFile
而不是File
和byte[]Range
请求代码>.只需要相当多的代码即可考虑所有 HTTP 规范 要求,所以这里只是一个您可以在链接中找到此类 servlet 的具体示例:FileServlet 支持恢复和缓存。然而,更好的方法是将作业委托给 servletcontainer 的默认 servlet。例如,如果是 Tomcat,那么您所需要做的就是将以下行添加到
/conf/server.xml
中:这样就可以通过 http://localhost:8080/media/final.ogg 和 http://localhost:8080/media/final.mp4,无需自行开发 servlet。
Honestly, this approach is absolutely not right.
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).
You are not responding correctly on
Range
requests. You're sending the complete file back instead of the requestedRange
. Firefox and IE do not use range requests and that's why it "works". Chrome and Safari use range requests.This should be possible without sniffing the user agent and properly responding to
Range
requests byRandomAccessFile
instead ofFile
andbyte[]
. 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.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
: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.
这似乎更多是格式支持问题。
你可以试试ogg格式。 HTML5代码是
This seems to be more of a format support issue.
You can try ogg format. The HTML5 code is
Google Chrome 不支持 H.264(包括 mp4),因此您还需要在 Google Chrome 中使用 Final.ogg。而对于 Safari,您需要更改此行
添加“Safari”而不是“CoreMedia”,
我希望它能起作用。
Google Chrome does not support H.264 (includes mp4) so you need to use final.ogg with google chrome as well. while for safari you need to change this line
add "Safari" instead of "CoreMedia"
i hope it works.
只需注释这两行,然后在 chrome 上运行您的视频即可播放。
Just comment these two lines and then run on chrome your video will play.