使用Java servlet的视频下载/流 [英] Video download/stream using Java servlet

查看:119
本文介绍了使用Java servlet的视频下载/流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在客户端访问URL时在我的服务器中下载视频文件,类似于:

I am trying to download a video file in my server when the client access URL similar to this:

http://localhost:8088/openmrs/moduleServlet/patientnarratives/videoDownloadServlet?videoObsId=61

我试过这段代码。但它不起作用。当我访问servlet时,它只下载一个空白(0大小)文件。

I have tried this code. But its not working. When i visit the servlet it only download a Blank (0 size) file.

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的 fileservlet教程但在我的情况下,我没有文件对象作为输入流只是字节数组对象。

I have used BalusC's fileservlet tutorial but in my case i dont have file object as the inputstream just the byte array object.

帮助..

推荐答案

您找到的servlet确实可用于此目的流式传输视频文件。它更像是一个简单的文件下载servlet,用于静态文件,如PDF,XLS等。

The servlet which you found is indeed insuitable for the purpose of streaming a video file. It's more intented as a simple file download servlet for static files like PDF, XLS, etc.

许多视频播放器要求服务器支持所谓的HTTP范围请求。即它必须能够通过 <的请求返回视频文件的特定字节范围code>范围 标题。例如,在10000字节长的文件上只有索引1000到2000的字节。这是必需的,以便能够足够快地跳过特定范围的视频流而无需下载整个文件和/或通过创建多个HTTP连接来提高缓冲速度,每个HTTP连接请求视频文件的不同部分。

A lot of video players require that the server supports so-called HTTP range requests. I.e. it must be able to return a specific byte range of the video file by a request with a Range header. For example, only the bytes from index 1000 until 2000 on a file of 10000 bytes long. This is mandatory in order to be able to skip a certain range of the video stream quickly enough without the need to download the whole file and/or to improve buffering speed by creating multiple HTTP connections which each requests a different part of the video file.

然而,这是servlet中的许多额外代码,需要很好地理解HTTP Range 规范。这个扩展文件servlet 的风格提供了一个随时可用的示例。您找到的文件servlet的同一作者。在您的特定情况下,可能建议首先将文件保存到基于本地磁盘文件系统的缓存(例如,通过 File#createTempFile()和HTTP会话中的某些键),以便您不需要一次又一次地从外部服务获取它。

This is however a lot of additional code in the servlet which requires a well understanding of the HTTP Range specification. A ready to use example is provided in flavor of this extended file servlet by the very same author of the file servlet which you found. In your specific case it's perhaps recommendable to save the file to local disk file system based cache first (e.g. by File#createTempFile() and some key in HTTP session), so that you don't need to obtain it from the external service again and again.

这篇关于使用Java servlet的视频下载/流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆