Video Using HTML 5 and servlet

17,809

Solution 1

Honestly, this approach is absolutely not right.

  • You are sniffing the user agent in the server side and depending the business job on it. This is in all cases a bad idea. If all you want is to specify a different file depending on the user agent, then rather do it in the HTML side, with help of JavaScript or CSS. Both client side languages are able to identify the real browser without the need to sniff the user agent string (which is namely spoofable).

  • You are not responding correctly on Range requests. You're sending the complete file back instead of the requested Range. Firefox and IE do not use range requests and that's why it "works". Chrome and Safari use range requests.

This should be possible without sniffing the user agent and properly responding to Range requests by RandomAccessFile instead of File and byte[]. It's only pretty a lot of code to take all HTTP specification requirements into account, so here's just a link where you can find a concrete example of such a servlet: FileServlet supporting resume and caching.

However, much better is to delegate the job to the servletcontainer's default servlet. If it's for example Tomcat, then all you need to do is to add the following line to /conf/server.xml:

<Context docBase="D:\media" path="/media" />

This way the desired media files are just available by http://localhost:8080/media/final.ogg and http://localhost:8080/media/final.mp4 without the need to homegrow a servlet.

Solution 2

This seems to be more of a format support issue.

You can try ogg format. The HTML5 code is

<audio controls="controls">
  <source src="song.ogg" type="audio/ogg" />
  Your browser does not support the audio tag.
</audio>
Share:
17,809
Sushant Kumar Singh
Author by

Sushant Kumar Singh

I have 10 years of Software Development experience using Java based tech stack. I define, design and develop Software.

Updated on June 09, 2022

Comments

  • Sushant Kumar Singh
    Sushant Kumar Singh almost 2 years

    Below given code is for video streaming. This is fine with IE9 and firefox but it is not fine with Chrome and Mac Safari.

    import java.io.*;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class VideoStreamServlet
     */
    
    public class VideoStreamServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        /**
         * Default constructor. 
         */
        public VideoStreamServlet() {
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            String range = request.getHeader("range");
            String browser = request.getHeader("User-Agent");
            System.out.println(browser);
            if(browser.indexOf("Firefox") != -1){
                System.out.println("==========ITS FIREFOX=============");
                byte[] data = getBytesFromFile(new File("D:/media/final.ogg"));
                response.setContentType("video/ogg");
                response.setContentLength(data.length);
                response.setHeader("Content-Range", range + Integer.valueOf(data.length-1));
                response.setHeader("Accept-Ranges", "bytes");
                response.setHeader("Etag", "W/\"9767057-1323779115364\"");
                byte[] content = new byte[1024];
                BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
                OutputStream os = response.getOutputStream();
                while (is.read(content) != -1) {
                    //System.out.println("... write bytes");
                    os.write(content);
                }
                is.close();
                os.close();
            }
    
            else if(browser.indexOf("Chrome") != -1){
                System.out.println("==========ITS Chrome=============");
                byte[] data = getBytesFromFile(new File("D:/media/final.mp4"));
                String diskfilename = "final.mp4";
                response.setContentType("video/mp4");
                //response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"" );
                System.out.println("data.length " + data.length);
                response.setContentLength(data.length);
                response.setHeader("Content-Range", range + Integer.valueOf(data.length-1));
                response.setHeader("Accept-Ranges", "bytes");
                response.setHeader("Etag", "W/\"9767057-1323779115364\"");
                byte[] content = new byte[1024];
                BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
                OutputStream os = response.getOutputStream();
                while (is.read(content) != -1) {
                    //System.out.println("... write bytes");
                    os.write(content);
                }
                is.close();
                os.close();
            }
    
            else if(browser.indexOf("MSIE") != -1) {
                System.out.println("==========ITS IE9=============");
                byte[] data = getBytesFromFile(new File("D:/media/final.mp4"));
                String diskfilename = "final.mp4";
                response.setContentType("video/mpeg");
                //response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"" );
                System.out.println("data.length " + data.length);
                response.setContentLength(data.length);
                response.setHeader("Content-Range", range + Integer.valueOf(data.length-1));
                response.setHeader("Accept-Ranges", "text/x-dvi");
                response.setHeader("Etag", "W/\"9767057-1323779115364\"");
                byte[] content = new byte[1024];
                BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
                OutputStream os = response.getOutputStream();
                while (is.read(content) != -1) {
                    //System.out.println("... write bytes");
                    os.write(content);
                }
                is.close();
                os.close();
            }
            else if( browser.indexOf("CoreMedia") != -1) {
                System.out.println("============ Safari=============");
                byte[] data = getBytesFromFile(new File("D:/media/final.mp4"));
                String diskfilename = "final.mp4";
                response.setContentType("video/mpeg");
                //response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"" );
                System.out.println("data.length " + data.length);
                //response.setContentLength(data.length);
                //response.setHeader("Content-Range", range + Integer.valueOf(data.length-1));
               // response.setHeader("Accept-Ranges", " text/*, text/html, text/html;level=1, */* ");
               // response.setHeader("Etag", "W/\"9767057-1323779115364\"");
                byte[] content = new byte[1024];
                BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
                OutputStream os = response.getOutputStream();
                while (is.read(content) != -1) {
                    //System.out.println("... write bytes");
                    os.write(content);
                }
                is.close();
                os.close();
            }
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
        }   
         private static byte[] getBytesFromFile(File file) throws IOException {
            InputStream is = new FileInputStream(file);
            //System.out.println("\nDEBUG: FileInputStream is " + file);
            // Get the size of the file
            long length = file.length();
            //System.out.println("DEBUG: Length of " + file + " is " + length + "\n");
            /*
             * You cannot create an array using a long type. It needs to be an int
             * type. Before converting to an int type, check to ensure that file is
             * not loarger than Integer.MAX_VALUE;
             */
            if (length > Integer.MAX_VALUE) {
                System.out.println("File is too large to process");
                return null;
            }
            // Create the byte array to hold the data
            byte[] bytes = new byte[(int)length];
            // Read in the bytes
            int offset = 0;
            int numRead = 0;
            while ( (offset < bytes.length)
                    &&
                    ( (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) ) {
                offset += numRead;
            }
            // Ensure all the bytes have been read in
            if (offset < bytes.length) {
                throw new IOException("Could not completely read file " + file.getName());
            }
            is.close();
            return bytes;
        }
    
    }
    
  • Sushant Kumar Singh
    Sushant Kumar Singh over 12 years
    Thanks, this is very helpful for me" FileServlet supporting resume and caching".
  • jwi
    jwi over 6 years
    For the tomcat context approach: Is there a way to implement a request filter to the media files?