使用ストリーミング
私は、ビデオストリーミングのための次のメソッドを使用します。このコードは、メディアファイルの一時コピーを作成しません。
基本的にこのコードは、ブラウザから送信された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"
)
}
呼ば
Controller
の内側にこのコードを入れてください。どのバージョンを使用していますか? – cbley