流式传输HTML5-mp4-Video,JSP无法在Safari上运行

时间:2016-01-06 10:15:46

标签: html5 jsp http servlets safari

我目前正在尝试从数据库加载视频并通过JSP将其流式传输到浏览器。在大多数浏览器上一切正常,除非使用Safari,它只显示一个没有显示任何视频的空播放器。

问题在于outputStream套接字,

while ((bytesRead = inStream.read(buffer)) != -1) {
    outStream.write(buffer, 0, bytesRead);
}

Safari重启视频流几次,我收到套接字异常。

org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error

Safari不断在http-header中请求特定的字节范围:

"bytes=0-1"

代码:

<%@ page import="java.io.*"%>
<%@ page import="java.net.*"%>
<%@ page import="com.mysql.jdbc.*"%>
<%@ page import="java.sql.*"%>
<%@page language="java" trimDirectiveWhitespaces="true"%>

<%@include file="settings.jsp"%>
<%
    session = request.getSession(false);

    if (session != null) {
        int userId = 0;
        try {
            userId = (new Integer(session.getAttribute("user_id").toString())).intValue();
        }
        catch (Exception ex) {
            // nothing
        }

        int videoId = 0;
        try {
            if (request.getParameter("video_id") != null) {
                videoId = (new Integer(request.getParameter("video_id"))).intValue();
            }
        }
        catch (Exception ex) {
            // nothing
        }

        int videoType = 0;
        try {
            if (request.getParameter("video_type") != null) {
                videoType = (new Integer(request.getParameter("video_type"))).intValue();
            }
        }
        catch (Exception ex) {
            // nothing      
        }

        if (userId > 0 && videoId > 0 && videoType > 0) {
            java.sql.Connection connection = null;
            java.sql.PreparedStatement queryStatement = null;
            StringBuffer sql = null;
            try {

                String connectionURL = "jdbc:mysql://" + DB_HOST_NAME + ":" + DB_PORT + "/" + DB_NAME;

                Class.forName("com.mysql.jdbc.Driver").newInstance();
                connection = DriverManager.getConnection(connectionURL, DB_USER_NAME, DB_USER_PASSWORD);
                if (!connection.isClosed()) {
                    sql = new StringBuffer();

                    sql.append("SELECT ");
                    sql.append("video.id AS id, ");
                    sql.append("video.title AS title, ");
                    sql.append("video.video_url_hd AS video_url_hd, ");
                    sql.append("video.video_url_sd AS video_url_sd, ");
                    sql.append("video.video_img_url AS video_img_url, ");
                    sql.append("video.description AS description ");
                    sql.append("FROM " + DB_NAME + ".video ");
                    sql.append("INNER JOIN " + DB_NAME + ".video_visibility ON video_visibility.video_id = video.id ");
                    sql.append("INNER JOIN " + DB_NAME + ".users ON users.id = ? ");
                    sql.append("WHERE video_visibility.right_gr_id IN (users.right_gr_id, 0) AND video.id = ? ");
                    sql.append("ORDER BY video.sequence ");

                    queryStatement = connection.prepareStatement(sql.toString());

                    queryStatement.setInt(1, userId);
                    queryStatement.setInt(2, videoId);

                    ResultSet rs = queryStatement.executeQuery();
                    if (rs != null) {
                        if (rs.next()) {
                            String title = rs.getString("title");
                            String imgURL = rs.getString("video_img_url");
                            String videoSDURL = rs.getString("video_url_sd");
                            String videoHDURL = rs.getString("video_url_hd");
                            rs.close();

                            /*
                            * Add logging
                            */
                            String logSql = "INSERT INTO " + DB_LOG_NAME + ".webclient_log (client_type, user_id, video_id, message, client_ip) " + "VALUES('"
                                    + CLIENT_TYPE + "', '" + userId + "', '" + videoId + "', 'Show Video:" + title + " / videoType=" + videoType + "', '"
                                    + request.getRemoteAddr() + "' )";

                            queryStatement.close();
                            queryStatement = connection.prepareStatement(logSql);
                            queryStatement.executeUpdate();

                            /*
                            * Stream File
                            */
                            String filePath = null;
                            if (videoType == 1) {
                                String path = "/video/" + videoSDURL;
                                filePath = getServletContext().getRealPath(path);

                            }
                            else if (videoType == 2) {
                                String path = "/video/" + videoHDURL;
                                filePath = getServletContext().getRealPath(path);
                            }

                            File downloadFile = new File(filePath);
                            FileInputStream inStream = new FileInputStream(downloadFile);

                            // if you want to use a relative path to context root:
                            String relativePath = getServletContext().getRealPath("");

                            // obtains ServletContext
                            ServletContext context = getServletContext();

                            // gets MIME type of the file
                            String mimeType = context.getMimeType(filePath);
                            if (mimeType == null) {
                                // set to binary type if MIME mapping not found
                                mimeType = "application/octet-stream";
                            }

                            // modifies response
                            response.setContentType(mimeType);

                            response.setContentLength((int) downloadFile.length());
                            //we support skipping
                            response.setHeader("Accept-Ranges", "bytes");

                            // obtains response's output stream
                            OutputStream outStream = response.getOutputStream();

                            byte[] buffer = new byte[4096];
                            int bytesRead = -1;

                            while ((bytesRead = inStream.read(buffer)) != -1) {
                                outStream.write(buffer, 0, bytesRead);
                            }
                            outStream.flush();

                            inStream.close();
                            outStream.close();
                        }
                    }
                }
            }
            catch (Exception ex) {
                System.out.println(ex.toString());
            }
            finally {
                if (queryStatement != null)
                    queryStatement.close();

                if (connection != null)
                    connection.close();

                sql = null;
            }
        }
    }
%>

0 个答案:

没有答案