I have an embedded jetty application that has various endpoints, one of them is /stream/fileId and another one is /streamWithHTML/fileId.
The first one gets a file with the specified id from filesystem and starts writing its contents to the response, making use of the range headers to skip to different parts of the video.
The second endpoint is intended to do the same thing, except instead of the default browser player, i want my own custom player built with html.
This is the code i attempted to put together until now. This returns a web page but i dont know how to handle the video stream:
response.setContentType("text/html");
try {
PrintWriter writer = response.getWriter();
String filePath1 = "path/to/file";
String encodedFilename = URLEncoder.encode(filePath1, StandardCharsets.UTF_8);
// Get an html file and then print its contents after replacing a couple of parameters
InputStream stream = getClass().getClassLoader().getResourceAsStream("HTML/VideoPlayer/index_template.html");
String htmlPage = IOUtils.toString(stream, StandardCharsets.UTF_8);
htmlPage = htmlPage.replace("$title", fileEntity1.fileName);
htmlPage = htmlPage.replace("$video_source", encodedFilename);
writer.println(htmlPage);
writer.flush();
writer.close();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
}
And this is the contents of the html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$title</title>
</head>
<body style="background-color: #303030">
<video style="max-width: 100%; max-height: 100%;" src="$video_source"></video>
</body>
</html>
Note that $title and $video_source are just strings i use to correctly place some values when i serve the page.
Every solution i have tried or have seen up until now, is to serve a static video, but it is not possible for me, since the video is saved on a database.
Additional note: the video must be accessible from outside through only one endpoint, which will be the one with the html page, so putting the video on one endpoint and then serving i in the html of another request is not an option for me.
The
$video_sourceis just an HTTP request to a specific resource on your webserver. (it could be/videos/67328148734529)It will be up to you to implement that specific resource endpoint on your webserver. Typically as an HttpServlet. (in the above example, your endpoint would be on url-pattern
/videos/*, and you would use therequest.getPathInfo()on your servlet to obtain the video id that is being requested by the browser)Some things you'll be on the hook to handle.
Acceptheaders on the request.Content-Typeresponse.You should consider not using a general database for the video content itself, it makes for a terribly inefficient experience, as most database blob requests don't support range requests efficiently (especially with the nuances of HTTP range requests and multipart/byteranges responses).
A common technique is to put the video in it's raw form on a storage device (hdd, ssd, cdn, etc) with a UUID style name, and have the database reference the UUID name, and other metadata. That way you serve from storage to network efficiently.