Java IO
It is possible to play media using standard Java IO.
There are however some limitations, and in some cases they may be critical limitations.
The vast majority of applications will not need to use this feature and can instead rely on the native media playback via a Media Resource Locator (MRL) as has always been the case with vlcj.
How it Works
LibVLC 3.0.0 added new native "media callbacks" which are used to open, read, seek and close a media "stream". Essentially this enables VLC to callback into a Java application to open the media, read a sequence of bytes from the media data to populate a native IO buffer, seek to any position within the media data, and when done to close the media.
The key step is to populate a supplied native IO buffer with media data on demand.
vlcj provides CallbackMedia
classes that help you use Java IO to play your
media.
Seekability
The first consideration is that of "seekability" - is it possible, using Java IO, to seek to any position within the media?
The natural choice for seekability is to use a RandomAccessFile
, where by
definition it is possible to seek to any position within such a file before
reading the data.
With vlcj 5.0.0, the callback media using a RandomAccessFile
has been
removed and is superseded by an implementation that uses a MappedByteBuffer
.
Just about every Java InputStream
is not seekable - rather the data is
consumed from the stream in a linear manner from start to finish. Some
InputStream
implementations allow to seek forwards by skipping bytes, but
seeking backwards within a stream is rarely possible. It is possible to create
a bespoke implementation of an InputStream
that allows seeking, but this may
not be straightforward, and in the simplest case it would require that the
entire media data be held in an in-memory buffer.
Seekability is therefore a factor that you must consider - some media types simply can not be played without the ability to seek.
Let's Get Started
You should now already have a basic template for how to create a vlcj application, so this tutorial will no longer duplicate all of the code each time - instead we'll just show the new code fragments.
We start by assuming we already have a media player component:
Rather than play an MRL as is the norm with vlcj, we play a Media
instance...
Create a Media Instance
For seekable media, we use the vlcj RandomAccessFileMedia
class, and pass it
when invoke playMedia
on the media player:
For non-seekable media, in this case we want to use a FileInputStream
and the
vlcj FileInputStreamMedia
class:
Media Options
You can pass media options when you create your CallbackMedia
instance.
These are the same media options that are ordinarily passed when you invoke
play
on the media player instance. All of the concrete vlcj CallbackMedia
implementation classes accept zero or more media options via their
constructors.
Custom Media Types
vlcj provides scaffolding and implementations for the most common use-cases, but if you need to it is possible to extend the vlcj classes to implement your own bespoke behaviour.
Summary
You can play media with vlcj using standard Java IO - however, there are constraints particularly with regard to the non-seekability of the standard Java input streams.