微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尝试在 servlet 的帮助下将视频mp4从网络服务器nginx流式传输到使用视频标签HTML的客户端

如何解决尝试在 servlet 的帮助下将视频mp4从网络服务器nginx流式传输到使用视频标签HTML的客户端

public class VideoStreamingServlet extends HttpServlet{
    
    private static final Logger LOGGER = Logger.getLogger(VideoStreamingServlet.class);
    private static final int BUFFER_LENGTH = 1024 * 16;
      private static final long EXPIRE_TIME = 1000 * 60 * 60 * 24;
      private static final Pattern RANGE_PATTERN = Pattern.compile("bytes=(?<start>\\d*)-(?<end>\\d*)");
      private String videoPath;
     
      @Override
      public void init() throws servletexception {
        videoPath = getinitParameter("videoPath");
      }
     
      @Override
      protected void doGet(final HttpServletRequest request,final HttpServletResponse response) throws servletexception,IOException {
        processRequest(request,response);
      }
     
      private void processRequest(final HttpServletRequest request,final HttpServletResponse response) throws IOException {
     
        String videoFilename = URLDecoder.decode(request.getParameter("video"),"UTF-8");
        //String videoFilename = request.getParameter("video");
        Path video = Paths.get(videoPath,videoFilename);
        LOGGER.info("Absolute File Path "+video.toAbsolutePath());
     
        int length = (int) Files.size(video);
        int start = 0;
        int end = length - 1;
     
        String range = request.getHeader("Range");
        Matcher matcher = RANGE_PATTERN.matcher(range);
         
        if (matcher.matches()) {
          String startGroup = matcher.group("start");
          start = startGroup.isEmpty() ? start : Integer.valueOf(startGroup);
          start = start < 0 ? 0 : start;
     
          String endGroup = matcher.group("end");
          end = endGroup.isEmpty() ? end : Integer.valueOf(endGroup);
          end = end > length - 1 ? length - 1 : end;
        }
     
        int contentLength = end - start + 1;
     
        response.reset();
        response.setBufferSize(BUFFER_LENGTH);
        response.setHeader("Content-disposition",String.format("inline;filename=\"%s\"",videoFilename));
        response.setHeader("Accept-Ranges","bytes");
        response.setDateHeader("Last-Modified",Files.getLastModifiedTime(video).toMillis());
        response.setDateHeader("Expires",System.currentTimeMillis() + EXPIRE_TIME);
        response.setContentType(Files.probeContentType(video));
        response.setHeader("Content-Range",String.format("bytes %s-%s/%s",start,end,length));
        response.setHeader("Content-Length",String.format("%s",contentLength));
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
     
        int bytesRead;
        int bytesLeft = contentLength;
        ByteBuffer buffer = ByteBuffer.allocate(length);
     
        try (SeekableByteChannel input = Files.newByteChannel(video,READ);
                OutputStream output = response.getoutputStream()) {
     
          input.position(start);
     
          while ((bytesRead = input.read(buffer)) != -1 && bytesLeft > 0) {
            buffer.clear();
            output.write(buffer.array(),bytesLeft < bytesRead ? bytesLeft : bytesRead);
            bytesLeft -= bytesRead;
          }
        }
      }
}

这是控制器,index.html 有视图,web.xml 有 servlet 的映射。问题是,每当我执行 html 时,它都不会加载视频,但在 2 次重新加载后,它会加载并正常播放。范围标头按原样发送,响应也按要求发送。但视频不会加载到第 3 次重新加载。

header shot when i load it 1st time 尽管图中显示了 206,但它显示错误 net::ERR_CONTENT_LENGTH_MISMATCH 206(部分内容)和失败而不是 206。

header shot when i load it for 2nd time 显示与上述相同的错误

从第三次开始,它以某种方式获取数据并在标题显示 206 和相同的数据。但是当我播放视频时,它不断失败并出现上述错误,但视频以某种方式播放。在 350 个请求中,只有 5-6 个真正成功。休息都失败了。 after realoading it 3rd time 在上面的 ss 中,您可以看到 11 个,7 个失败,而只有 3 个成功。但是当我在 localhost 中使用相同的代码时,一切都很好,视频按预期播放,没有任何错误。有人可以告诉我代码是否有任何错误Nginx 服务器的问题。正如我所说,当我用我的 tomcat 8.5 在 eclipse 中尝试它并在 localhost 上使用它时它工作正常。请帮忙。在过去的 7 天里,我一直在努力解决这个问题。任何帮助将不胜感激,并提前致谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。