I am trying to download a video file in my server when the client access URL similar to this:
http://localhost:8088/openmrs/moduleServlet/patientnarratives/videoDownloadServlet?videoObsId=61
I have tried this code. But its not working. When i visit the servlet it only download a Blank (0 size) file.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
try {
Integer videoObsId = Integer.parseInt(request.getParameter("videoObsId"));
Obs complexObs = Context.getObsService().getComplexObs(videoObsId, OpenmrsConstants.RAW_VIEW);
ComplexData complexData = complexObs.getComplexData();
Object object2 = complexData.getData(); // <-- an API used in my service. this simply returns an object.
byte[] videoObjectData = SerializationUtils.serialize(object2);
// Get content type by filename.
String contentType = null;
if (contentType == null) {
contentType = "application/octet-stream";
}
// Init servlet response.
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(videoObjectData.length));
response.setHeader("Content-Disposition", "attachment; filename=\"" + "test.flv" + "\"");
// Prepare streams.
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
// Open streams.
input = new BufferedInputStream(new ByteArrayInputStream(videoObjectData), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
// Gently close streams.
close(output);
close(input);
}
}
// Add error handling above and remove this try/catch
catch (Exception e) {
log.error("unable to get file", e);
}
}
private static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
// Do your thing with the exception. Print it, log it or mail it.
e.printStackTrace();
}
}
}
I have used BalusC's fileservlet tutorial but in my case i dont have file object as the inputstream just the byte array object.
help..
The servlet which you found is indeed insuitable for the purpose of streaming a video file. It's more intented as a simple file download servlet for static files like PDF, XLS, etc.
A lot of video players require that the server supports so-called HTTP range requests. I.e. it must be able to return a specific byte range of the video file by a request with a Range
header. For example, only the bytes from index 1000 until 2000 on a file of 10000 bytes long. This is mandatory in order to be able to skip a certain range of the video stream quickly enough without the need to download the whole file and/or to improve buffering speed by creating multiple HTTP connections which each requests a different part of the video file.
This is however a lot of additional code in the servlet which requires a well understanding of the HTTP Range
specification. A ready to use example is provided in flavor of this extended file servlet by the very same author of the file servlet which you found. In your specific case it's perhaps recommendable to save the file to local disk file system based cache first (e.g. by File#createTempFile()
and some key in HTTP session), so that you don't need to obtain it from the external service again and again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With