Java IO
With LibVLC 3.0.0+ and the most recent version of vlcj it is now 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 Media
classes that help you use Java IO to play your media,
without you needing to consider any of the interaction with native code.
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.
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:
If you want to play a simple MRL, you can keep doing this as you have always
done using the playMedia
method that takes a String
.
If you prefer to use a consistent API for playing simple MRLs, you can
optionally choose to use the vlcj SimpleMedia
class:
Media Options
You can pass media options when you create your Media
instance. These are the
same media options that are ordinarily passed when you invoke playMedia
on
the media player instance. All of the concrete vlcj Media
sub-classes accept
zero or more media options in 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.