使用Java servlet下载/流媒体视频

7
我正在尝试在客户端访问URL时,从我的服务器下载一个视频文件,该URL类似于此:
http://localhost:8088/openmrs/moduleServlet/patientnarratives/videoDownloadServlet?videoObsId=61

我尝试了这段代码。但它没有起作用。当我访问servlet时,它只下载一个空的(0大小)文件。
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
{
    try {
        Integer videoObsId = Integer.parseInt(request.getParameter("videoObsId"));

        Obs complexObs = Context.getObsService().getComplexObs(videoObsId, OpenmrsConstants.RAW_VIEW); 
        ComplexData complexData = complexObs.getComplexData();
        Object object2 = complexData.getData(); // <-- an API used in my service. this simply returns an object.

        byte[] videoObjectData = SerializationUtils.serialize(object2);

        // Get content type by filename.
        String contentType = null;
        if (contentType == null) {
            contentType = "application/octet-stream";
        }

        // Init servlet response.
        response.reset();
        response.setBufferSize(DEFAULT_BUFFER_SIZE);
        response.setContentType(contentType);
        response.setHeader("Content-Length", String.valueOf(videoObjectData.length));
        response.setHeader("Content-Disposition", "attachment; filename=\"" + "test.flv" + "\"");

        // Prepare streams.
        BufferedInputStream input = null;
        BufferedOutputStream output = null;

        try {
            // Open streams.
            input = new BufferedInputStream(new ByteArrayInputStream(videoObjectData), DEFAULT_BUFFER_SIZE);              
            output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

            // Write file contents to response.
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            int length;
            while ((length = input.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
        } finally {
            // Gently close streams.
            close(output);
            close(input);
        }
    }

    // Add error handling above and remove this try/catch
    catch (Exception e) {
        log.error("unable to get file", e);
    }
}
private static void close(Closeable resource) {
    if (resource != null) {
        try {
            resource.close();
        } catch (IOException e) {
            // Do your thing with the exception. Print it, log it or mail it.
            e.printStackTrace();
        }
    }
}

我使用了BalusC的《文件servlet教程》(链接:http://balusc.blogspot.com/2007/07/fileservlet.html),但在我的情况下,我没有输入流的文件对象,只有字节数组对象。
请帮忙......

1
дҪ жҳҜеҗҰжЈҖжҹҘиҝҮеҲқе§ӢеҢ–еҗҺvideoObjectDataзҡ„еҖјпјҢд»ҘжҹҘзңӢе…¶дёӯеҢ…еҗ«дәҶд»Җд№Ҳпјҹ - chrylis -cautiouslyoptimistic-
是的,videoObjectData 包含了初始化数据。 - harshadura
1个回答

10
你找到的servlet确实不适合用于流式传输视频文件,它更适用于像PDF、XLS等静态文件的简单文件下载servlet。
很多视频播放器要求服务器支持所谓的HTTP范围请求。即,必须能够通过带有Range头的请求返回视频文件的特定字节范围。例如,只返回长度为10000字节的文件中从索引1000到2000的字节。这是必需的,以便能够快速跳过视频流的某个范围,而无需下载整个文件和/或通过创建每个请求不同部分的HTTP连接来提高缓冲速度。

然而,这需要在servlet中编写大量额外的代码,并且需要对HTTP Range规范有很好的理解。提供了一个现成的示例,就是由你找到的文件servlet的作者提供的扩展文件servlet。在你的特定情况下,建议先将文件保存到本地磁盘文件系统缓存中(例如使用File#createTempFile()和HTTP会话中的一些密钥),这样你就不需要一遍又一遍地从外部服务获取它。


1
非常感谢 @BalusC,使用您的最新文件下载servlet并采用java临时文件方法,而不是通过字节数组对象传递,现在它可以正常工作。解决方案:https://gist.github.com/harshadura/6420565 - harshadura

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接