servlet / grails如何正确地将mp4文件提供给Safari?

时间:2015-11-23 02:42:33

标签: java servlets grails safari video-streaming

在这个简单的代码中:

return $http.delete(baseURI + 'services/v6.0/agent-sessions/' + sessionId, {
    headers: {
        Authorization: 'Bearer ' + access_token,
    },
    data: endAgentSessionPayload
});

它可以正确地向Firefox提供mp4文件,但在Safari(OS / X上的9.0.1)中,它没有播放,服务器报告:

def index() {
    def file = new File('/tmp/big_buck_bunny_720p_50mb.mp4')
    println "file = ${file} , length = ${file.length()}"

    if (file.exists()) {
      webRequest.renderView = false;
      response.setContentType("video/mp4")
      response.setHeader("Content-disposition", "inline; filename=" + URLEncoder.encode(file.name, "UTF-8"));
      response.setHeader("Content-Length", String.valueOf(file.length()));

      InputStream is = new FileInputStream(file);

      response.outputStream << is
      response.outputStream.flush()
      response.outputStream.close()
      is.close()
    }
  } // index 

为什么代码在Firefox中运行但在Safari中抛出断管 getOutputStream()已被调用此响应异常?

如何解决?感谢。

环境:Grails 2.5.1

=====更新=====

我发现了这个问题:

Mp4 downloading instead of playing in Safari,并且有一个网址http://techslides.com/demos/sample-videos/small.mp4

我的Safari可以成功播放视频。

我尝试模拟标题

file = /tmp/big_buck_bunny_720p_50mb.mp4 , length = 52464391
| Error 2015-11-23 10:37:13,339 [http-bio-8080-exec-3] ERROR errors.GrailsExceptionResolver  - SocketException occurred when processing request: [GET] /hello2/stream/index
Broken pipe. Stacktrace follows:
Message: Broken pipe
    Line | Method
->>  109 | socketWrite in java.net.SocketOutputStream
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    153 | write       in     ''
|     17 | index . . . in hello2.StreamController$$EPUpAtg0
|    198 | doFilter    in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|     63 | doFilter .  in grails.plugin.cache.web.filter.AbstractFilter
|   1142 | runWorker   in java.util.concurrent.ThreadPoolExecutor
|    617 | run . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run         in java.lang.Thread
| Error 2015-11-23 10:37:13,349 [http-bio-8080-exec-3] ERROR errors.GrailsExceptionResolver  - IllegalStateException occurred when processing request: [GET] /hello2/stream/index
getOutputStream() has already been called for this response. Stacktrace follows:
Message: Error processing GroovyPageView: getOutputStream() has already been called for this response
    Line | Method
->>  648 | doFilter  in /hello2/grails-app/views/error.gsp
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Caused by IllegalStateException: getOutputStream() has already been called for this response
->>  100 | flush     in java.io.FilterWriter
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    198 | doFilter  in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|     63 | doFilter  in grails.plugin.cache.web.filter.AbstractFilter
|   1142 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    617 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run       in java.lang.Thread
| Error 2015-11-23 10:37:13,354 [http-bio-8080-exec-3] ERROR [/hello2].[grails]  - Servlet.service() for servlet grails threw exception

除ETag外,还插入了其他标题。 但是Safari仍然无法播放,而服务器报告同样的异常。

1 个答案:

答案 0 :(得分:1)

对于在这个问题上感兴趣(或陷入困境)的任何人,我找到了解决方案。这不是一个简单的解决方案。

解决方案位于以下网址:FileServlet supporting resume and caching and GZIP

它适用于servlet和Grails。