2016-09-15 8 views
0

Ich lief erfolgreich Videos mit dem Play-Framework, aber ich habe ein Problem: Jedes Mal, wenn eine Datei geliefert wird, erstellt das Play-Framework eine Kopie in C: \ Users \ user \ AppData \ Temp. Ich verwalte große Dateien, daher entsteht schnell ein Problem mit Speicherplatz.Play Framework Speicherplatz auffressen

Gibt es eine Möglichkeit, eine Datei in Play zu liefern, ohne eine Kopie zu erstellen? Oder muss Play automatisch die temporäre Datei löschen?

-Code Ich verwende zu dienen im Wesentlichen:

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

genannt Wenn Wiedergabe tut, dass ich würde sagen, dass dies auf jeden Fall ein Fehler ist. Welche Version verwendest du? – cbley

Antwort

1

Verwenden Streaming

Ich verwende folgende Methode für Video-Streaming. Dieser Code erstellt keine temporären Kopien der Mediendatei.

Grundsätzlich reagiert dieser Code auf die RANGE Abfragen, die vom Browser gesendet werden. Wenn der Browser RANGE Abfragen nicht unterstützt, falle ich zurück zu der Methode, wo ich versuche, die ganze Datei mit Ok.sendFile zu senden (intern versucht auch, die Datei zu streamen) (dies könnte temporäre Dateien erstellen). Dies geschieht jedoch sehr selten, wenn Bereichsabfragen nicht vom Browser unterstützt werden.

GET /media  controllers.MediaController.media 

diesen Code Setzen einer innen ControllerMediaController

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" 
    ) 
    }