Introduction to Players#
MCAV provides a variety of players that you can choose to play your media from. In general, all players follow a similar logic, where frames are supplied via some source, and the result is processed.
Warning
Note that for every video player, you must release the video player after you are done using it. This is done by
calling the release() method on the player. Failing to do so will result in memory leaks and potentially crashes. Not
all players need to be released, so check the documentation for the specific player you are using.
Video Players#
There are several different types of video players. There are multiplexer video players, which are able to play
from different audio and video inputs at once. For example, the VLCPlayer is a multiplexer video player that can play
from a separated audio and video input at the same time. It automatically synchronizes the audio and video streams to
ensure that they are in sync.
All video players will automatically have a wrapper callback (called VideoAttachableCallback for video and
AudioAttachableCallback for audio) that allows you to attach a VideoPipelineStep or AudioPipelineStep to the player
for callbacks. They wrap the respective pipeline callbacks.
Note
As an implementation note. All image and audio samples follow a standard format throughout the pipeline and should always maintain this same type at all times. The image frames are always encoded in BGR24 format with 8-bits of padding. The audio samples are always encoded in Signed PCM 16-bit Little-Endian format, with 48kHz sample rate and 2 channels.
final AudioPipelineStep audioPipelineStep = ...;
final VideoPipelineStep videoPipelineStep = ...;
final FileSource videoSource = ...;
final FileSource audioSource = ...;
final VideoPlayerMultiplexer multiplexer = VideoPlayer.vlc();
// audioPipelineStep and videoPipelineStep from above
final VideoAttachableCallback videoCallback = multiplexer.getVideoAttachableCallback();
videoCallback.attach(videoPipelineStep);
final AudioAttachableCallback audioCallback = multiplexer.getAudioAttachableCallback();
audioCallback.attach(audioPipelineStep);
multiplexer.start(videoSource, audioSource);
// ... do something with the player
multiplexer.release();
Warning
The ImageBuffer provided in a VideoPipelineStep is always released after the frame is processed. If you would like to store the frame, you must copy the frame to a new ImageBuffer object.
All multiplexer players support single input video and audio sources. For example, you’re able to play a video file like so.
final AudioPipelineStep audioPipelineStep = ...;
final VideoPipelineStep videoPipelineStep = ...;
final FileSource source = ...;
final VideoPlayerMultiplexer player = VideoPlayer.vlc();
// audioPipelineStep and videoPipelineStep from above
final VideoAttachableCallback videoCallback = player.getVideoAttachableCallback();
videoCallback.attach(videoPipelineStep);
final AudioAttachableCallback audioCallback = player.getAudioAttachableCallback();
audioCallback.attach(audioPipelineStep);
player.start(source);
// ... do something with the player
player.release();
The VLCPlayer, FFmpegPlayer, VideoInputPlayer, and OpenCVPlayer are all multiplexer video players.
Note
Note that the VideoInputPlayer, however, requires an integer device input, so you must use the DeviceSource to
specify a device identifier. Otherwise, the VideoInputPlayer will not work.
Image Players#
For any other image-based video players, MCAV provides an ImagePlayer, which is a video player that plays a series of
images given a FrameSource. This is incredibly useful for other miscellaneous tasks, such as taking the input from a
JFreeChart chart and displaying it.
final VideoPipelineStep videoPipelineStep = ...;
final FrameSource frameSource = FrameSource.image(...); // provide your frames in a supplier
final ImagePlayer player = ImagePlayer.player();
final VideoAttachableCallback videoCallback = player.getVideoAttachableCallback();
videoCallback.attach(videoPipelineStep);
player.start(frameSource);
// ... do something with the player
player.release();
If you want to play a GIF image, you can use the RepeatingFrameSource which accepts any DynamicImageBuffer. You can pass
this into ImagePlayer directly.
final VideoPipelineStep videoPipelineStep = ...;
final DynamicImageBuffer gif = DynamicImageBuffer.path(FileSource.path(Path.of("example.gif"))); // provide your gif image
final RepeatingFrameSource frameSource = RepeatingFrameSource.repeating(gif); // provide your gif frames in a supplier
final ImagePlayer player = ImagePlayer.player();
final VideoAttachableCallback videoCallback = player.getVideoAttachableCallback();
videoCallback.attach(videoPipelineStep);
player.start(videoPipelineStep, frameSource);
// ... do something with the player
player.release();
This will play the GIF indefinitely until you stop the player. You’re also welcome to play the GIF in the
FFmpegPlayer, as it’s able to play GIFs as well.