serlvet实现简单的伪流传输推送视频网站

来源:互联网 发布:姓名大战 源码 编辑:程序博客网 时间:2024/06/01 08:12

                对于java的基本知识掌握还有一些缺乏,还是应该把这些基本知识好好掌握住的,这几天面试,其中一家公司问我是否可以实现一个小视频推送的服务,这个没做过,也没接触过,真心有点懵逼呀。不过,作为一名志向远大的程序员,这些问题怎么能够成为我的绊脚石呢,因此开始网上各种扒知识,大概有了一些思路,至于能否成功,真心保证不了,不过,尝试一下还是可以的。

        服务器选用tomcat,这个毕竟非常熟悉,其次,视频传输利用http协议,不过需要实现断点传输,毕竟io资源是有限的,这个应该使用多线程实现多用户视频传输(这里画个???,具体实现是否这个样子还需要进行考量)。

        首先,利用servlet实现一个简单的单用户,单视频的完整传输,然后,我们在这个基础上改为单用户,单视频的断点续传,第三部,实现多用户,单视频的断点续传,第四部,是否实现多用户,多视频的传输,这个之后再进行考虑。未完待续。。。。

       ----------------------------------------------分割线------------------------------------------------------------------

       以下内容参考http://blog.csdn.net/xiaoxiaoxuewen/article/details/7701170断点续传,首先实现了断点续传下载,然后进行写播放页面,实现视频文件的播放。

package video_download;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class VideoServlet extends HttpServlet{
    
    /**
     * 文件断点传输
     */
    private static final long serialVersionUID = 860013284202278320L;

    @Override
    protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
        doPost(req,resp);
    }
    /**
     * 获取访问请求
     */
    @Override
    protected void doPost(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
        resp.reset();
        //已经传输的字节长度
        long pos = 0;
//        String fileName = req.getParameter("name");
        String fileName="temp.mp4";
        //输出文件流
        OutputStream os=null;
        //输入文件流
        InputStream is=null;
        try{
            //创建File文件
            File file = new File("/tmp/mozilla_wingchangzhuang0/"+fileName);
            //输入流
            is=new FileInputStream(file);
            //文件长度
            long fSize=file.length();
            byte[] xx=new byte[4096];
            //设置断点续传标志
            resp.setHeader("Accept-Ranges","bytes");
            //内容长度
            resp.setHeader("Content-Length", fSize+"");
            resp.setHeader("content-Disposition", "attachment;filename="+fileName);
            if(req.getHeader("Range")!=null){
                //如果Range不为空,说明之前已经下载了一部分,设置206状态(SC_PARTIAL_CONTENT)
                resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                //传输的文件范围
                pos=Long.parseLong(req.getHeader("Range").replaceAll("bytes=","").replaceAll("-", ""));
            }
            if(pos!=0){
                String contentRange=new StringBuffer("bytes").append(new Long(pos).toString())
                        .append("-").append(new Long(fSize-1).toString()).append("/")
                        .append(new Long(fSize).toString()).toString();
                resp.setHeader("Content-Range",contentRange);
                System.out.println("Conten-Range="+contentRange);
                //略过已经传输过的字节
                is.skip(pos);
            }
            os=resp.getOutputStream();
            boolean all=false;
            while(!all){
                int n=is.read(xx);
                if(n!=-1){
                    os.write(xx,0,n);
                }else{
                    all=true;
                }
            }
        }catch(IOException e){
            e.printStackTrace();
            return;
        }finally {
            if(os!=null){
                os.close();
            }
            if(is!=null){
                is.close();
            }
        }
    }
}

----------未完待续----------------------以上代码尝试时出现pip管道问题,暂未解决,又尝试另一种格式,可以播放视频,只是只能在谷歌浏览器上使用,且无法拖放进度条播放----------------------------------

以下代码来自于http://www.what21.com/programming/java/javaweb-summary/html5_video_servlet.html



import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 
 */
public class VideoStreamServlet extends HttpServlet {


private static final long serialVersionUID = 6948918204420124894L;


@Override
protected void service(HttpServletRequest request,HttpServletResponse response) 
throws ServletException, IOException {
//请求头中,第一个字节的位置和最后一个字节的位置
String range = request.getHeader("range");
//浏览器的类型
String browser = request.getHeader("User-Agent");
if (browser.indexOf("Firefox") != -1) {
// 火狐浏览器
byte[] data = getBytesFromFile(new File("/home/wingchangzhuang/下载/temp.mp4"));
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) {
os.write(content);
}
is.close();
os.close();
} else if (browser.indexOf("MSIE") != -1) {
// IE9以上浏览器
byte[] data = getBytesFromFile(new File("/home/wingchangzhuang/下载/temp.mp4"));
String diskfilename = "final.mp4";
response.setContentType("video/mpeg");
// response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"");
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) {
os.write(content);
}
is.close();
os.close();
} else if (browser.indexOf("Chrome") != -1) {
// 谷歌浏览器
byte[] data = getBytesFromFile(new File("/home/wingchangzhuang/下载/temp.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) {
os.write(content);
}
is.close();
os.close();
} else if (browser.indexOf("CoreMedia") != -1) {
// 其他浏览器
byte[] data = getBytesFromFile(new File("/home/wingchangzhuang/下载/temp.mp4"));
String diskfilename = "final.mp4";
response.setContentType("video/mpeg");
response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"");
byte[] content = new byte[1024];
BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
OutputStream os = response.getOutputStream();
while (is.read(content) != -1) {
os.write(content);
}
is.close();
os.close();
}
}


/**
* 读取文件字节

* @param file 
* @return 
* @throws IOException
*/
private static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
long length = file.length();
if (length > Integer.MAX_VALUE) {
return null;
}
byte[] bytes = new byte[(int) length];
int offset = 0;
int numRead = 0;
while ((offset < bytes.length) && ((numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file " + file.getName());
}
is.close();
return bytes;
}
}


///////////////////////////////播放器页面///////////////////////////////

直接写在body

<video width="50%" height="50%" controls="controls">
<source src="/SVO/video/video.do" type="video/ogg" />
<source src="/SVO/video/video.do" type="video/mp4" />
您的浏览器不支持 video 标签。
</video>