Order Now AdSolution Sign Up | Login » Bits on the Run Sign Up | Login »

Forums

/

Servlet Streaming

8 replies [Last post]

well here is my attempt at writing xmoov-php for java servlets, it kinda works.. except you can't jump around with the slider, even parts that have been downloaded :(

i assume each time you move the slider to a part that hasn't been downloaded... it should make a new call to the streamer, with a new start position??? i only seem to be getting one request, at start = 0

package wyd;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
*
* @author Derek Knapp
*/
public class watch extends HttpServlet
{
    //    SCRIPT CONFIGURATION

    //------------------------------------------------------------------------------------------
    //    MEDIA PATH
    //
    //    you can configure these settings to point to video files outside the public html folder.
    //------------------------------------------------------------------------------------------

    // points to server root
    public static final String XMOOV_PATH_ROOT = "";

    // points to the folder containing the video files.
    public static final String XMOOV_PATH_FILES = "/ffmpeg/out/";

    //------------------------------------------------------------------------------------------
    //    SCRIPT BEHAVIOR
    //------------------------------------------------------------------------------------------

    //set to TRUE to use bandwidth limiting.
    public static final Boolean XMOOV_CONF_LIMIT_BANDWIDTH = true;

    //set to FALSE to prohibit caching of video files.
    public static final Boolean XMOOV_CONF_ALLOW_FILE_CACHE = false;

    //------------------------------------------------------------------------------------------
    //    BANDWIDTH SETTINGS
    //
    //    these settings are only needed when using bandwidth limiting.
    //
    //    bandwidth is limited my sending a limited amount of video data(XMOOV_BW_PACKET_SIZE),
    //    in specified time intervals(XMOOV_BW_PACKET_INTERVAL).
    //    avoid time intervals over 1.5 seconds for best results.
    //
    //    you can also control bandwidth limiting via http command using your video player.
    //    the function getBandwidthLimit($part) holds three preconfigured presets(low, mid, high),
    //    which can be changed to meet your needs
    //------------------------------------------------------------------------------------------

    //set how many kilobytes will be sent per time interval
    public static final Integer XMOOV_BW_PACKET_SIZE = 90;

    //set the time interval in which data packets will be sent in seconds.
    public static final Double XMOOV_BW_PACKET_INTERVAL = 1.5;

    //set to TRUE to control bandwidth externally via http.
    public static final Boolean XMOOV_CONF_ALLOW_DYNAMIC_BANDWIDTH = true;

    //------------------------------------------------------------------------------------------
    //    DYNAMIC BANDWIDTH CONTROL
    //------------------------------------------------------------------------------------------

    private Double getBandwidthIntervalLimit()
    {
        /*
        switch($_GET[XMOOV_GET_BANDWIDTH])
        {
            case 'low' :
                return 0.5;
            break;
            case 'mid' :
                return 0.5;
            break;
            case 'high' :
                return 0.2;
            break;
            case 'off' :
                return 0;
            break;
            default :
                return XMOOV_BW_PACKET_INTERVAL;
            break;
         */
        return XMOOV_BW_PACKET_INTERVAL;
    }

    private Integer getBandwidthSizeLimit()
    {
        /*
        switch($_GET[XMOOV_GET_BANDWIDTH])
        {
            case 'low' :
                return 20;
            break;
            case 'mid' :
                return 40;
            break;
            case 'high' :
                return 90;
            break;
            default :
                return XMOOV_BW_PACKET_SIZE;
            break;
        }
        */
        return XMOOV_BW_PACKET_SIZE;
    }
   
   
   
    //------------------------------------------------------------------------------------------
    //    INCOMING GET VARIABLES CONFIGURATION
    //
    //    use these settings to configure how video files, seek position and bandwidth settings are accessed by your player
    //------------------------------------------------------------------------------------------
   
    public static final String XMOOV_GET_FILE = "file";
    public static final String XMOOV_GET_POSITION = "start";
    public static final String XMOOV_GET_AUTHENTICATION = "key";
    public static final String XMOOV_GET_BANDWIDTH = "bw";
   
   
   
    //    END SCRIPT CONFIGURATION - do not change anything beyond this point if you do not know what you are doing
   
   
   
    //------------------------------------------------------------------------------------------
    //    PROCESS FILE REQUEST
    //------------------------------------------------------------------------------------------
   
    public static final byte[] FLV_HEADER = new byte[]{  
        (byte) 0x46, (byte) 0x4C, (byte) 0x56,  
        (byte) 0x01,  
        (byte) 0x05,  
        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x09,  
        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x09 
    };
   
    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        Enumeration en = request.getParameterNames();
        String str = "-----------------\n";
        while (en.hasMoreElements())
        {
            String s = (String) en.nextElement();
            str += s + " = " + request.getParameter(s) + "\n";
        }
        str += "-----------------\n";
        System.out.println(str);
       
        if (request.getParameter(XMOOV_GET_FILE) != null && request.getParameter(XMOOV_GET_POSITION) != null)
        {
            //    PROCESS VARIABLES
           
            // get seek position
            Long seekPos = Long.valueOf(request.getParameter(XMOOV_GET_POSITION));
            // get file name
            String fileName = request.getParameter(XMOOV_GET_FILE);
            // assemble file path
            String file = XMOOV_PATH_ROOT + XMOOV_PATH_FILES + fileName;
           
            // assemble packet interval
            Double packet_interval = (XMOOV_CONF_ALLOW_DYNAMIC_BANDWIDTH && request.getParameter(XMOOV_GET_BANDWIDTH) != null) ? getBandwidthIntervalLimit() : XMOOV_BW_PACKET_INTERVAL;
            // assemble packet size
            Integer packet_size = ((XMOOV_CONF_ALLOW_DYNAMIC_BANDWIDTH && request.getParameter(XMOOV_GET_BANDWIDTH) != null) ? getBandwidthSizeLimit() : XMOOV_BW_PACKET_SIZE) * 1042;
           
            File f = new File(file);
           
            if (!f.exists())
            {
                PrintWriter out = response.getWriter();
                out.println("<b>ERROR:</b> xmoov-php could not find (" + fileName + ") please check your settings.");
                System.out.println("<b>ERROR:</b> xmoov-php could not find (" + fileName + ") please check your settings.");
                out.close();
                return;
            }
            else
            {
                OutputStream out = response.getOutputStream();
                RandomAccessFile fh = new RandomAccessFile(f, "r");
               
                Long fileSize = fh.length() - ((seekPos > 0) ? seekPos  + 1 : 0);
               
                //    SEND HEADERS
                if (!XMOOV_CONF_ALLOW_FILE_CACHE)
                {
                    // prohibit caching (different methods for different clients)
                    response.addHeader("Expires", "Thu, 19 Nov 1981 08:52:00 GMT");
                    response.addHeader("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
                    response.addHeader("Pragma", "no-cache");
                }
               
                // content headers
                response.setContentType("video/x-flv");
                response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
                response.setContentLength(fileSize.intValue());
               
                // FLV file format header
                if (seekPos != 0)
                {
                    out.write(FLV_HEADER);
                }
               
                // seek to requested file position
                fh.seek(seekPos);
               
                // output file
                while (fh.getFilePointer() < fh.length())
                {
                    // use bandwidth limiting
                    if (XMOOV_CONF_LIMIT_BANDWIDTH && packet_interval > 0)
                    {
                        // get start time
                        Long time_start = System.currentTimeMillis();
                        // output packet
                        byte[] buf = new byte[packet_size];
                        fh.read(buf);
                        out.write(buf);
                        // get end time
                        Long time_stop = System.currentTimeMillis();
                        // wait if output is slower than $packet_interval
                        Long time_difference = time_stop - time_start;
                        if (time_difference < packet_interval)
                        {
                            try
                            {
                                Thread.sleep((long)(packet_interval * 1000) - time_difference * 1000);
                            }
                            catch (Exception e)
                            {
                            }
                        }
                    }
                    else
                    {
                        // output file without bandwidth limiting
                        byte[] buf = new byte[1024];
                        fh.read(buf);
                        out.write(buf);
                    }
                }
            }
        }
    }

    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo()
    {
        return "stream video";
    }
}

oh and this is all i see in my log file

[#|2008-12-02T21:10:23.734-0500|INFO|sun-appserver9.1|javax.enterprise.system.stream.out|_ThreadID=21;_ThreadName=httpSSLWorkerThread-80-1;|
-----------------
file = d2500fb3-e77a-4a16-ab7e-57be6745e0b2
start = 0
id = ply
client = FLASH WIN 10,0,12,36
version = 4.2.95
width = 420
-----------------
|#]

here is the code for the player

        <p id='${item.guid}' class="media">Here the video will be shown.</p>

        <script type='text/javascript'>
            var s1 = new SWFObject('/wyd-war/player/player.swf','ply','420','250','9','#ffffff');
            s1.addParam('allowfullscreen','true');
            s1.addParam('flashvars','file=${item.guid}&type=video&streamscript=/wyd-war/watch');
            s1.write('${item.guid}');
        </script>

ok so it was my flash video, i guess it didnt have the required meta data

Your code doesn't compile at all.

Is it a joke or what ? You have tons of basic errors all around...

JR ;-/

The code compile (my case) but when i call from flex proyect, give me error (discordant arguments).

:( If i resolve the problem, i will publish.

Greetings.

well... i don't resolve the problem, but this was the motivation for implements the same functionality for our pourposes. Actually we have a server that read a flv file and return the stream. If you want know the code, please notify me. Greetings.

Thanks very much! The servlet works perfectly for me. This was much easier than I thought it would be. I made one change, setting

String file = XMOOV_PATH_ROOT != null ? XMOOV_PATH_ROOT + XMOOV_PATH_FILES + fileName : getServletContext().getRealPath("/" + XMOOV_PATH_FILES + fileName);

That way, you can put your videos into the context directory. I like that because I can then give users the option of downloading the video if their connection (or my server) is slow.

@doesn't compile!
This is all assuming you half-way know what you're doing.