2016-09-15 59 views
0

我成功地使用Play框架来播放视频,但遇到了一个问题:每次提供文件时,Play框架都会在C:\ Users \ user \ AppData \温度。我正在处理大文件,因此很快就会造成磁盘空间问题。播放框架吃掉磁盘空间

有什么办法可以在没有创建副本的情况下在Play中投放文件?或者让Play自动删除临时文件?我使用的服务

代码基本上是:

public Result video() { 
    return ok(new File("whatever")); 
} 
+0

如果玩的是这样做,我会说这绝对是一个错误Controller内。你正在使用哪个版本? – cbley

回答

1

使用流式播放

我用下面的视频流的方法。此代码不会创建媒体文件的临时副本。

基本上这段代码会响应浏览器发送的RANGE查询。如果浏览器不支持RANGE查询,我回退到我尝试使用Ok.sendFile发送整个文件的方法(内部播放也会尝试传输文件)(这可能会创建临时文件)。但是当浏览器不支持范围查询时,这种情况很少发生。

GET /media  controllers.MediaController.media 

将这个代码名为MediaController

def media = Action { req => 
    val file = new File("/Users/something/Downloads/somefile.mp4") 
    val rangeHeaderOpt = req.headers.get(RANGE) 
    rangeHeaderOpt.map { range => 
     val strs = range.substring("bytes=".length).split("-") 
     if (strs.length == 1) { 
     val start = strs.head.toLong 
     val length = file.length() - 1L 
     partialContentHelper(file, start, length) 
     } else { 
     val start = strs.head.toLong 
     val length = strs.tail.head.toLong 
     partialContentHelper(file, start, length) 
     } 
    }.getOrElse { 
     Ok.sendFile(file) 
    } 
    } 

    def partialContentHelper(file: File, start: Long, length: Long) = { 
    val fis = new FileInputStream(file) 
    fis.skip(start) 
    val byteStringEnumerator = Enumerator.fromStream(fis).&>(Enumeratee.map(ByteString.fromArray(_))) 
    val mediaSource = Source.fromPublisher(Streams.enumeratorToPublisher(byteStringEnumerator)) 
    PartialContent.sendEntity(HttpEntity.Streamed(mediaSource, None, None)).withHeaders(
     CONTENT_TYPE -> MimeTypes.forExtension("mp4").get, 
     CONTENT_LENGTH -> ((length - start) + 1).toString, 
     CONTENT_RANGE -> s"bytes $start-$length/${file.length()}", 
     ACCEPT_RANGES -> "bytes", 
     CONNECTION -> "keep-alive" 
    ) 
    }