最近项目需要用到视频播放,播放文件需要登录验证,及权限控制,所以写了个测试例子。
1)前端界面
<!DOCTYPE html>
<html lang="en"><head>
</head>
<body style="background-color:transparent">
<div>
<video id="video" controls="" preload="none" poster="5.png">
<source id="mp4" src="5.mp4" type="video/mp4">
<div style="height:300px;line-height:300px;text-align:center;font-size:18px;">您的浏览器不支持HTML5视频</div>
</video>
</div>
</body></html>
图片如下:
2)java 后台
package test;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Html5VideoServlet extends HttpServlet {
private static final long serialVersionUID = 6948918204420124894L;
@Override
protected void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
/*测试文件*/
File sf=new File("E:\\workspace\\jstexam\\webapp\\web\\phone\\3\\5.mp4");
this.transfer(sf, request.getHeader("Range"), response);
}
public void transfer(File sf,String reqRange, HttpServletResponse response){
try {
RspInfo ri= getPartFileRsp( sf, reqRange) ;
response.setContentLength((int)ri.content_Length);
response.setHeader("Content-Range", ri.content_Range);
response.setHeader("Accept-Ranges", "bytes");
response.setStatus(206);
sendToClient(ri, response.getOutputStream(), sf);
} catch (Exception e) {
e.printStackTrace();
}
}
public RspInfo getPartFileRsp(File sf,String reqRange) throws Exception {
RspInfo rinfo = new RspInfo();
/* 1、Range 类型 1)bytes=x...- 2)bytes=x...-x... //Range:(unit=first byte pos)-[last byte pos]
如:Range: bytes=0- Range: bytes=0-801
2、对应 Content-Range: bytes x...(开始读取位置)-y...(读取结束位置)/z...(文件总大小) //Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]
如:Content-Range: bytes 0-800/801 //801:文件总大小
*/
System.out.print(reqRange);
if(null!=reqRange){
String[] ranplits= reqRange.split("=");
if(ranplits.length!=2)throw new Exception("range format wrong ");
String lenstr=ranplits[1];
String[] flens=lenstr.split("-",-1);
if(flens.length!=2)throw new Exception("rangelen format wrong ");
long fpos =Long.valueOf(flens[0]);
long lpos= flens[1].length()>0?Long.valueOf(flens[1]):sf.length()-1; //表示文件读取文件大小
rinfo.skipLenth=fpos;
rinfo.content_Length=lpos-fpos+1;
rinfo.content_Range=ranplits[0]+" "+fpos+"-"+lpos+"/"+sf.length();
}
return rinfo;
}
public void sendToClient(RspInfo rinfo ,OutputStream os,File sf) {
RandomAccessFile raf;
try {
raf = new RandomAccessFile(sf, "r");
byte[] b=new byte[102400];
raf.seek(rinfo.skipLenth);
long readlen=rinfo.content_Length; //需要读取的字节长度
int clen=0;
while(readlen>0&&(clen=raf.read(b))!=-1){
if(readlen>clen){
os.write(b,0,clen);
}else{
os.write(b,0, (int)readlen);
}
readlen-=clen;
}
raf.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(os!=null){
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class RspInfo{
public long content_Length=-1;
public String content_Range="";
public long skipLenth=-1;
}
}