在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML5  Java/ video標(biāo)簽用自己寫的文件流在ios的safari里播不了,求解決辦法

video標(biāo)簽用自己寫的文件流在ios的safari里播不了,求解決辦法

video標(biāo)簽讀的是java寫的文件流(MP4視頻編碼是h264),頁面代碼如下:

<video width="320" height="240" controls="controls">
    <source src="http://192.168.254.107:8080/testvideo!test.do" type="video/mp4" />
    您的瀏覽器不支持video標(biāo)簽
</video>

java代碼如下:

public void test() {
        try {
            File f = new File("F:/MyWorkSpace/wrote/c測試用文件/cath264.mp4");
            if (!f.exists()) {
                response.sendError(404, "File not found!");
                return;
            }
            BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
            byte[] buf = new byte[1024];
            int len = 0;

            response.reset();
            response.setContentType("video/mp4");
            response.setHeader("Accept-Ranges", "0-" + f.length());
            response.setHeader("Content-Range",
                    "bytes " + 0 + "-" + (f.length() - 1) + "/" + f.length());
            response.setHeader("Content-Length", f.length() + "");

            OutputStream out = response.getOutputStream();
            while ((len = br.read(buf)) > 0)
                out.write(buf, 0, len);
            br.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

視頻在PC端和安卓手機(jī)的瀏覽器中均可以播放,但是在iPhone中的Safari上放不了

clipboard.png
PC端運(yùn)行時(shí)系統(tǒng)也不會報(bào)錯,在Safari上運(yùn)行時(shí)會報(bào)以下錯誤:

Caused by: java.net.SocketException: Connection reset by peer: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
    at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
    at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:240)
    at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:84)
    at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
    at org.apache.coyote.Response.doWrite(Response.java:517)
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:408)
    ... 54 more

如果把視頻放到工程里,video標(biāo)簽直接引用,視頻在Safari里是可以播放的

<video width="320" height="240" controls="controls">
          <source src="${path}/jsp/reception/cath264.mp4" type="video/mp4" />
          您的瀏覽器不支持video標(biāo)簽
      </video>

左邊的視頻是引用的文件流,右邊是直接引的視頻

clipboard.png

回答
編輯回答
瘋子范

下面的代碼可以解決這個(gè)問題,但是手機(jī)訪問頁面,還是會報(bào) Connection reset by peer: socket write error 這個(gè)錯誤,希望能有解決辦法。

    public void test() {
        try {
            File f = new File("E:/cath264.mp4");
            if (!f.exists()) {
                response.sendError(404, "File not found!");
                return;
            }
            RandomAccessFile randomFile = new RandomAccessFile(f, "r");//只讀模式
            long contentLength = randomFile.length();
            String range = request.getHeader("Range");
            int start = 0, end = 0;
            if(range != null && range.startsWith("bytes=")){
                String[] values = range.split("=")[1].split("-");
                start = Integer.parseInt(values[0]);
                if(values.length > 1){
                    end = Integer.parseInt(values[1]);
                }
            }
            int requestSize = 0;
            if(end != 0 && end > start){
                requestSize = end - start + 1;
            } else {
                requestSize = Integer.MAX_VALUE;
            }
     
            byte[] buffer = new byte[4096];
            response.setContentType("video/mp4");
            response.setHeader("Accept-Ranges", "bytes");
            response.setHeader("ETag", "cath264");
            response.setHeader("Last-Modified", new Date().toString());
            //第一次請求只返回content length來讓客戶端請求多次實(shí)際數(shù)據(jù)
            if(range == null){
                response.setHeader("Content-length", contentLength + "");
            }else{
                //以后的多次以斷點(diǎn)續(xù)傳的方式來返回視頻數(shù)據(jù)
                response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);//206
                long requestStart = 0, requestEnd = 0;
                String[] ranges = range.split("=");
                if(ranges.length > 1){
                    String[] rangeDatas = ranges[1].split("-");
                    requestStart = Integer.parseInt(rangeDatas[0]);
                    if(rangeDatas.length > 1){
                        requestEnd = Integer.parseInt(rangeDatas[1]);
                    }
                }
                long length = 0;
                if(requestEnd > 0){
                    length = requestEnd - requestStart + 1;
                    response.setHeader("Content-length", "" + length);
                    response.setHeader("Content-Range", "bytes " + requestStart + "-" + requestEnd + "/" + contentLength);
                }else{
                    length = contentLength - requestStart;
                    response.setHeader("Content-length", "" + length);
                    response.setHeader("Content-Range", "bytes "+ requestStart + "-" + (contentLength - 1) + "/" + contentLength);
                }
            }
            ServletOutputStream out = response.getOutputStream();
            int needSize = requestSize;
            randomFile.seek(start);
            while(needSize > 0){
                int len = randomFile.read(buffer);
                if(needSize < buffer.length){
                    out.write(buffer, 0, needSize);
                } else {
                    out.write(buffer, 0, len);
                    if(len < buffer.length){
                        break;
                    }
                }
                needSize -= buffer.length;
            }
            randomFile.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
2017年7月6日 07:04