簡體   English   中英

在Chrome中,將Wrtie ByteArrayOutputStream轉換為Html5視頻失敗(Java Servlet)

[英]Wrtie ByteArrayOutputStream to Html5 video failed in Chrome (Java Servlet)

我在jsp中有一個視頻標簽,src是servlet的URL。

<video src="/MyApp/video" controls="true"></video>

這是對應的servlet

public class VideoServlet extends HttpServlet {

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        go(req, resp);
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    private void go(HttpServletRequest request, HttpServletResponse response) throws IOException {
        File file = new File("/Users/me/video.mp4");
        int fileSize = (int) file.length();
        FileInputStream inputStream = null;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(4096);
        try {
            inputStream = new FileInputStream(file);
            final byte[] buf = new byte[1024 * 8];
            for (int v; (v = inputStream.read(buf)) >= 0;) {
                if (v > 0)
                    outputStream.write(buf, 0, v);
            }

            response.setHeader("Accept-Ranges", "bytes");
            response.setContentType("video/mp4");
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            response.setContentLength(fileSize);
            response.setHeader("Content-Range", "bytes " + 0 + "-" + fileSize + "/" + fileSize);

            outputStream.writeTo(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            inputStream.close();
            outputStream.close();
        }
    }
}

當我使用Firefox時,它可以工作,可以在頁面加載后播放視頻,但是在Chrome中,我收到了EofException(jetty)或ClientAbortException(tomcat)。

這是使用碼頭時的異常堆棧跟蹤:

org.eclipse.jetty.io.EofException
    at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:292)
    at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:429)
    at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:322)
    at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:372)
    at org.eclipse.jetty.server.HttpConnection$SendCallback.process(HttpConnection.java:756)
    at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:241)
    at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:224)
    at org.eclipse.jetty.server.HttpConnection.send(HttpConnection.java:522)
    at org.eclipse.jetty.server.HttpChannel.sendResponse(HttpChannel.java:735)
    at org.eclipse.jetty.server.HttpChannel.write(HttpChannel.java:786)
    at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:234)
    at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:218)
    at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:530)
    at java.io.ByteArrayOutputStream.writeTo(ByteArrayOutputStream.java:167)
    at VideoServlet.go(VideoServlet.java:56)
    at VideoServlet.doGet(VideoServlet.java:25)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:833)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
    at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:206)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:219)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:561)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:334)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:104)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:679)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:597)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Broken pipe
    at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
    at sun.nio.ch.IOUtil.write(IOUtil.java:65)
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
    at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:270)
    ... 49 more

我的用法是否錯誤,或者可能是瀏覽器問題?

如果我的用法有誤,應該如何將ByteArrayOutputStream寫入瀏覽器以播放視頻?

我看到了文檔https://tools.ietf.org/html/rfc7233#section-4.2

如果Content-Range字段值包含一個byte-range-resp,則其last-byte-pos值小於其first-byte-pos值,或者一個full-length值小於或等於last-byte-resp字節位置值。

所以我改變了

response.setHeader("Content-Range", "bytes " + 0 + "-" + fileSize + "/" + fileSize);

response.setHeader("Content-Range", "bytes " + 0 + "-" + (fileSize - 1) + "/" + fileSize);

現在可以在Chrome中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM