如何正确支持html5< video>与码头的来源 [英] How to correctly support html5 <video> sources with jetty

查看:105
本文介绍了如何正确支持html5< video>与码头的来源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Java / jetty应用程序中,我有一个简单的ResourceHandler,jetty服务于2个简单文件,一个是html5页面,另一个是我的video.mp4视频文件。

 <!DOCTYPE html> 
< html>
< head>< title> TEST< / title>< / head>
< body>
< video style =width:400px; height:300pxsrc =video.mp4autoplay =autoplayloop =looppreload =auto>< / video>
< / body>
< / html>

问题是...当我第一次打开html页面时,视频被下载并缓存,并在第一次播放后停止播放,并保持冻结状态,如果我按照预期做循环播放的页面刷新(永久连续播放)。

java /码头代码如下

  ResourceHandler om = new ResourceHandler(); 
om.setDirectoriesListed(true);
om.setResourceBase(BASE_PATH);
handlers.setHandlers(new Handler [] {om});

现在的问题是,任何人都知道为什么jetty 9.2.3提供的html5视频只播放第一个循环,然后冻结铬3.7.0 ...或给出一些指导,以避免在第一次播放后视频冻结,当由码头服务?

这适用于 Jetty 9.2.3.v20140905


$ b

  package org.eclipse.jetty.demo; 

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;

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

导入org.eclipse.jetty.server.Server;
导入org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
导入org.eclipse.jetty.servlet.ServletHolder;

public class VideoServerMain
{
@SuppressWarnings(serial)
public class IndexerServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException
{
resp.setContentType(text / html);

PrintWriter out = resp.getWriter();
out.println(<!DOCTYPE html>);
out.println(< html>< head>< title> Videos< / title>< / head>);
out.println(< body>); (文件file:baseDir.listFiles())
{
if(file.isFile()&& file.getName()。endsWith(。mp4))
{
String encodedFilename = URLEncoder.encode(file.getName(),UTF-8);
out.println(< video style = \width:400px; height:300px\controls loop>);
out.printf(< source src = \%s \type = \video / mp4 \>%n,encodedFilename);
out.println(< / video>);
out.printf(< p>%s< / p>%n,file.getName());
out.println(< hr />);
}
}
out.println(< / body>);
out.println(< / html>);



public static void main(String [] args)
{
if(args.length!= 1)
{
System.err.printf(ERROR:Usage%s [videos-dir]%n,VideoServerMain.class.getName());
System.exit(-1);
}

文件baseDir = new File(args [0]);
if(!baseDir.exists()||!baseDir.isDirectory())
{
System.err.printf(错误:不是有效目录:%s%n, BASEDIR);
System.exit(-1);
}

尝试
{
new VideoServerMain(baseDir).start();
}
catch(Throwable t)
{
t.printStackTrace(System.err);
}
}

private final File baseDir;

public VideoServerMain(File baseDir)
{
this.baseDir = baseDir;
}

public void start()throws Exception
{
Server server = new Server(8080);

//建立Servlet上下文的临时目录(由JSP编译使用)
文件tempDir = new File(System.getProperty(java.io.tmpdir));
文件scratchDir = new File(tempDir.toString(),embedded-jetty-html5-vide-server);

if(!scratchDir.exists())
{
if(!scratchDir.mkdirs())
{
throw new IOException(Unable创建scratch目录:+ scratchDir);



//为这个应用程序在/
//设置基本应用程序的上下文//这也被称为处理程序树(in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath(/);
context.setAttribute(javax.servlet.context.tempdir,scratchDir);
context.setResourceBase(baseDir.toURI()。toASCIIString());

//添加servlet以显示已发现视频的html
ServletHolder holderIndexer = new ServletHolder(new IndexerServlet());
context.addServlet(holderIndexer,/ indexer);

//确保我们的欢迎文件是索引器servlet
context.setWelcomeFiles(new String [] {indexer});

//允许通过DefaultServlet
//添加默认Servlet(必须命名为default)允许视频自身的静态文件服务
ServletHolder holderDefault = new ServletHolder(default ,DefaultServlet.class);
holderDefault.setInitParameter(resourceBase,baseDir.getAbsolutePath());
holderDefault.setInitParameter(dirAllowed,true);
holderDefault.setInitParameter(welcomeServlets,true);
holderDefault.setInitParameter(redirectWelcome,true);

context.addServlet(holderDefault,/);

server.setHandler(context);

server.start();
server.join();
}
}

你似乎有两个问题。 p>


  1. ResourceHandler 对浏览器的要求来说太简单了。

    浏览器似乎会执行大量的部分请求,长时间的请求以及需要时的恢复。这些类型的请求最好使用 DefaultServlet


  2. 您用于视频标记的HTML没有工作,但是当我将其更改为以下版本时,它工作正常。




  3.  < video style =width:400px; height:300pxcontrols loop => 
    < source src =VID_20130822.mp4type =video / mp4>
    < / video>

    然后chrome似乎再次开心。


    i have a simple ResourceHandler on my Java/jetty application, jetty is serving a 2 simple files, one is a html5 page and the other is my video.mp4 video file.

    <!DOCTYPE html>
    <html>
    <head><title>TEST</title></head>
    <body>
        <video style="width: 400px; height: 300px" src="video.mp4" autoplay="autoplay" loop="loop" preload="auto"></video>
    </body>
    </html>
    

    The problem is... when i open the html page for first time the video is downloaded and cached, and stops playing after first playback and just stay frozen, if i do a refresh of the page the loop plays as i expected (forever continuous playback).

    The java/jetty code is following

    ResourceHandler om = new ResourceHandler();
    om.setDirectoriesListed(true);
    om.setResourceBase(BASE_PATH);
    handlers.setHandlers(new Handler[] { om });
    

    The question is, anyone knows why html5 video served by jetty 9.2.3 plays only first loop and then freezes on chrome 3.7.0... or give some guidance to avoid the freeze of the video after first playback when is served by jetty?

    解决方案

    This works with Jetty 9.2.3.v20140905

    package org.eclipse.jetty.demo;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.URLEncoder;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.servlet.DefaultServlet;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    
    public class VideoServerMain
    {
        @SuppressWarnings("serial")
        public class IndexerServlet extends HttpServlet
        {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
            {
                resp.setContentType("text/html");
    
                PrintWriter out = resp.getWriter();
                out.println("<!DOCTYPE html>");
                out.println("<html><head><title>Videos</title></head>");
                out.println("<body>");
                for (File file : baseDir.listFiles())
                {
                    if (file.isFile() && file.getName().endsWith(".mp4"))
                    {
                        String encodedFilename = URLEncoder.encode(file.getName(), "UTF-8");
                        out.println("<video style=\"width: 400px; height: 300px\" controls loop>");
                        out.printf("  <source src=\"%s\" type=\"video/mp4\">%n",encodedFilename);
                        out.println("</video>");
                        out.printf("<p>%s</p>%n",file.getName());
                        out.println("<hr/>");
                    }
                }
                out.println("</body>");
                out.println("</html>");
            }
        }
    
        public static void main(String[] args)
        {
            if (args.length != 1)
            {
                System.err.printf("ERROR: Usage %s [videos-dir]%n",VideoServerMain.class.getName());
                System.exit(-1);
            }
    
            File baseDir = new File(args[0]);
            if (!baseDir.exists() || !baseDir.isDirectory())
            {
                System.err.printf("ERROR: not a valid directory: %s%n",baseDir);
                System.exit(-1);
            }
    
            try
            {
                new VideoServerMain(baseDir).start();
            }
            catch (Throwable t)
            {
                t.printStackTrace(System.err);
            }
        }
    
        private final File baseDir;
    
        public VideoServerMain(File baseDir)
        {
            this.baseDir = baseDir;
        }
    
        public void start() throws Exception
        {
            Server server = new Server(8080);
    
            // Establish Scratch directory for the servlet context (used by JSP compilation)
            File tempDir = new File(System.getProperty("java.io.tmpdir"));
            File scratchDir = new File(tempDir.toString(),"embedded-jetty-html5-vide-server");
    
            if (!scratchDir.exists())
            {
                if (!scratchDir.mkdirs())
                {
                    throw new IOException("Unable to create scratch directory: " + scratchDir);
                }
            }
    
            // Setup the basic application "context" for this application at "/"
            // This is also known as the handler tree (in jetty speak)
            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
            context.setContextPath("/");
            context.setAttribute("javax.servlet.context.tempdir",scratchDir);
            context.setResourceBase(baseDir.toURI().toASCIIString());
    
            // Add servlet to present html for found videos
            ServletHolder holderIndexer = new ServletHolder(new IndexerServlet());
            context.addServlet(holderIndexer,"/indexer");
    
            // Make sure that our welcome-file is the indexer servlet
            context.setWelcomeFiles(new String[]{ "indexer" });
    
            // Allow static file serving of videos themselves, via DefaultServlet
            // Add Default Servlet (must be named "default")
            ServletHolder holderDefault = new ServletHolder("default",DefaultServlet.class);
            holderDefault.setInitParameter("resourceBase",baseDir.getAbsolutePath());
            holderDefault.setInitParameter("dirAllowed","true");
            holderDefault.setInitParameter("welcomeServlets","true");
            holderDefault.setInitParameter("redirectWelcome","true");
    
            context.addServlet(holderDefault,"/");
    
            server.setHandler(context);
    
            server.start();
            server.join();
        }
    }
    

    There seems to be 2 issues for you.

    1. The ResourceHandler is too simple for the demands that the browser puts on it.

      The browser seems to do a lot of partial requests, long duration requests, and recovery when needed. These kinds of requests are best done with the DefaultServlet

    2. The HTML you are using for the video tag didn't work, but when I changed it to the following it worked fine.

    <video style="width: 400px; height: 300px" controls loop=>
      <source src="VID_20130822.mp4" type="video/mp4">
    </video>
    

    then chrome seemed to be happy again.

    这篇关于如何正确支持html5&lt; video&gt;与码头的来源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆