13

我想使用 servlet 将我的音频/视频文件流式传输到网络。

我尝试使用以下 servlet:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    File file = new File("/Users/myfolder/Documents/workspace/love.mp3");
    response.setContentType(getServletContext().getMimeType(file.getName()));
    response.setContentLength((int) file.length());
    Files.copy(file.toPath(), response.getOutputStream());
}

以及以下 HTML:

<a href="/media" data-format="mp3 ogg">Click Here!</a>

然而,播放器只是在加载……加载……加载……

这是如何引起的,我该如何解决?

4

1 回答 1

24

许多媒体播放器要求服务器支持所谓的 HTTP 范围请求。即它必须能够根据请求返回带有Range标题的媒体文件的特定部分。例如,在 10MB 长的文件中,只有索引 1000 处的字节直到 2000 为止。这对于许多媒体播放器来说是强制性的,以便能够足够快地跳过特定范围的媒体流和/或通过创建多个连接来提高缓冲速度,每个连接都请求文件的不同部分。

然而,这在您的 servlet 中有很多额外的代码,需要对 HTTPRange规范有很好的理解。通常 servlet 容器(Tomcat、JBoss AS、Glassfish 等)自己的默认 servlet 已经支持这个。因此,如果有一种方法可以通过标准方式将媒体文件夹发布到网络中,这样您就不需要为此自行开发一个 servlet,那么我会走这条路。

目前尚不清楚您使用的是哪个 servletcontainer,因此我将在此示例中假设 Tomcat:

  1. 只需将love.mp3文件放到 web 项目的公共 web 内容中,这样它就可以直接使用,<a href="love.mp3">而不需要整个 servlet。

  2. 或者,将love.mp3文件放在文件夹的新子Tomcat/webapps文件夹中,例如Tomcat/webapps/media/love.mp3. 这样它就可以通过<a href="/media/love.mp3">.

  3. 或者,将love.mp3文件放在磁盘上的其他位置,例如/path/to/media/love.mp3/media通过将以下行添加到 Tomcat 中,将文件夹添加为新上下文/conf/server.xml

     <Context docBase="/path/to/media" path="/media" />
    

    这样它也可以使用<a href="/media/love.mp3">

无论哪种方式,Tomcat 自己的DefaultServlet对请求都有适当支持的Range将用于流式传输内容。

但是,如果绝对没有办法使用 servletcontainer 自己的默认 servlet,那么您需要重写您的 servlet 代码以使其正确支持Range请求。您可以从TomcatDefaultServletOmniFacesFileServlet等开源示例中获得灵感。

也可以看看:

于 2012-11-27T16:16:50.893 回答