Overlay
Building on previous tutorials, we will now show you how to use the video overlay.
Background Information
Needing to draw graphics or to overlay user interface widgets on top of a video surface is not an unreasonable requirement, but there are some severe constraints that make this a difficult thing to do.
The main constraint is that when a native media player is embedded inside a Java application that media player needs to be told which window to render the video into. It can only do this by being given an operating system window handle. This essentially means that you can only render video into a user interface widget that is backed by a native window.
In a Java application this basically means that you must use a heavyweight AWT
component, and for the specific case of embedding a video surface your only
real choice is to use an AWT Canvas
class (or some other AWT Component
).
You can not use any lightweight Swing component - specifically you can not
use a JPanel
- why? Because Swing components are not backed by native
widgets. The native media player knows nothing about Swing and certainly can
not access any lightweight components.
This is a real shame because it is pretty easy to do your own graphics
rendering in, or to add your own widgets to, a JPanel
.
So you just have to deal with the fact that you can't use a JPanel
, and
consequently that you can't do lightweight painting or add lightweight widgets.
Well, What Can Be Done?
The EmbeddedMediaPlayer
provides a reasonable but not ideal solution to help
you create a useful overlay.
This overlay works by keeping a second top-level heavyweight window in sync
with the media player video surface. This means resizing the overlay window
when the video window size changes, and moving the overlay window when the
video window is moved. A top level window can be made transparent, you can
paint into it using a regular Graphics2D
context, and you can add widgets.
This gives the illusion of overlaying painting and widgets on top of your video
window.
This is not an ideal approach because there is a notable lag when dragging or resizing the video window - when the window size and position event notification is received, the overlay window must then reposition and or resize itself. Due to how the events are delivered the lag is inevitable. In practical terms it means that you while you drag your video window, the overlay remains in its original position until you finish your drag at which point it snaps back to the right position.
On the other hand, this approach works really well when using native full-screen mode.
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.
Creating the Overlay
An overlay is just a top-level Window
. You create a Window
, configure it
appropriately (importantly for the overlay you give it a transparent
background) and attach it to the media player.
This shows the minimal code required to create an overlay.
Note that prior to Java7 you may need to use
AWTUtilities.setWindowOpaque(this, false);
instead of setting a fully
transparent background colour on the window.
So far this overlay implementation does not really do anything useful. We need
to add some custom painting. Inside our Overlay
class we simply override the
paint
method.
We'll use some arbitrary Java2D code in the paint
method to demonstrate that
the transparency is working, and that our painting is alpha-blended correctly
on top of the video.
You could render text here, draw icons, whatever you want using Java2D painting operations. You can use layout managers, add regular Swing widgets - remember that this overlay window is completely independent of the underlying video window.
Note that the overlay constructor accepts an owner
parameter - this should
always be the window or frame that contains your video surface.
Using the Overlay
First you associate the overlay with the media player.
Next you show or hide the overlay whenever you want, in response to some event or a user interaction or whatever your application needs.
Be Careful
When overlaying top-level windows as described in this tutorial, there is a chance that your desktop window manager may apply its own compositing effects and may actually blend your overlay window with the video underneath it. Usually this is not what you want as it may have unintended consequences like inadvertently darkening or lightening the video surface underneath. Therefore you may need to check whether or not you need to disable your compositing window manager if you want to use this overlay.
When you set an overlay, your application is still the 'owner' of the overlay
and responsible for its lifecycle - what this means is that you must dispose
of the overlay when you no longer need it. If you set an overlay once and never
change it then you likely won't have a problem, but if you set a different
overlay instance on your media player you must remember to dispose
the old
one (if you no longer need it) otherwise you will incur resource leaks.
Alternatives
If you only need to paint text or images over the video surface you should consider using the marquee or logo features of the media player - it will be much simpler.
You can also consider using a so-called "direct rendering" media player.
These concepts are explained in other tutorials.