[英]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.