The content handler can now stream video and audio files to VirtualViewer, so that VirtualViewer can start playing them before they are fully loaded from the content store. Previously, the VirtualViewer server could stream to the client web browser, but the content handler had to provide the entire media file to the VirtualViewer server before it would start playing, which could incur a long initial wait for large files. Now the content handler can provide VirtualViewer with a continuous stream instead of the full video file, so VirtualViewer can start displaying the media on the client immediately (if the media’s format supports streaming).

Implementing Video Streaming

To take advantage of media streaming, the content handler’s getDocumentContent() method should return an InputStream to the loading file data, such as the InputStream from an HTTP response, under ContentHandlerResult’s KEY_DOCUMENT_INPUT_STREAM. The InputStream must be progressively loading data from the client for the streaming feature to work - a fully cached InputStream (such as ByteArrayInputStream) will be the same as providing VirtualViewer with the complete file all at once. VirtualViewer will start playing the media on the client as soon as the stream has provided enough header data, while caching the downloaded data for faster performance later (if the document cache is enabled).

Note that although getDocumentContent() already supported returning an InputStream, this will likely require a code change to ensure VirtualViewer receives an active progressively-loading stream. A simplified example of what this could look like in getDocumentContent() is below, using Java’s basic URL library to download a video file over HTTP.

  InputStream mediaStream = new URL("http://example.com/MyMedia.mp4").openStream();
  // VirtualViewer will continously read data from this stream until the file is downloaded,
  // while also streaming the media to the requesting client browser.
  result.put(ContentHandlerResult.KEY_DOCUMENT_INPUT_STREAM, mediaStream);
  result.put(ContentHandlerResult.KEY_DOCUMENT_DISPLAY_NAME, "My Media");