Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
459 views
in Technique[技术] by (71.8m points)

java - How to correctly support html5 <video> sources with jetty

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...