Repository navigation
EN US Home
WATERMeDIA is a library with a multimedia API to play, decode, encode and handle video, audio and pictures. If you've used ExoPlayer or VLCJ it will feel familiar, but here everything comes ready: you never fight with buffers, planes, byte order or strides.
It resolves media links (YouTube, Twitch, direct files and many more), decodes them and hands the frames to your graphics engine (OpenGL, Vulkan, AWT, JavaFX) and the sound to your audio engine (OpenAL, Java Sound). Pictures and animations go through our own pure-Java decoders; video and audio go through FFmpeg, bundled in the companion mod WATERMeDIA: Binaries. It needs Java 17 or newer.
Every example in this guide is an integration fragment: variables such as renderThread,
renderExecutor or mrl come from your own code.
Important
This schema doesn't apply to experimental APIs or internal code
Each number tells you what changed and whether it can break something.
BUMPING SCHEMA
X.Y.Z-<channel>.W
-
X: Full rewrite: everything you know about the library got scrapped and rebuilt from scratch -
Y: Breaking changes: Refactors, renames, and API removals that might or will break your implementation -
Z: Hotfix, Enhancements, new API and deprecation Annotations, nothing breaking. -
<channel>: ALPHA or BETA channels, release doesn't use this version suffix- Note: sometimes it's left out on purpose, because some modloaders break version ranges with it.
-
W: ALPHA or BETA version drop, omitted when on the release channel
This is a WARRANTY that NO BREAKING CHANGES WILL BE COMMITTED ON Z BUMPS, so it is safe for you to require
watermedia in a range of [3.0.1,3.1)
Pick the path that matches what you're building.
- Setup: add the dependency and respect the version range.
- Software restrictions: supported Minecraft and loader versions.
- Managing links: turn a link into media sources.
- Creating and controlling a player.
- Choosing engines: OpenGL, Vulkan and OpenAL on the game's own contexts.
- Spatial audio: positional screens, stereo pairs and speakers.
- Synchronized playback: every player watches the same moment.
- Uploading and downloading files: share files through the file server.
- Setup: Gradle dependencies, runtime libraries and configuration.
- Startup: start WATERMeDIA once and show a loading screen.
- Managing links and searching.
- Creating and controlling a player and audio tracks.
- Choosing engines: AWT, JavaFX, OpenGL or Vulkan, plus OpenAL or Java Sound.
- Diagnostics and examples.
Command-line tools, bots, converters and services that work without a window.
- Setup and startup: what needs a start and what doesn't.
-
Platforms and searching: resolve and search links with
PlatformAPI, no startup needed. -
Downloads:
NetRequestwith bounded, verified downloads. - Decoders and encoders: pictures, animations and video files.
- Headless engine: capture decoded frames without a graphics context.
-
Synchronized playback:
ServerMediaPlayerruns on servers too.
Read startup, public and internal packages, managing links, creating and controlling a player and choosing engines before writing integration code. These rules are hard requirements:
- Use only the public packages (
org.watermedia,api.codecs,api.network,api.platform,api.player,api.util, without their subpackages). Players and engines come only fromPlayerAPI; engine classes are sealed. - Inside Minecraft never call
WaterMedia.start: the loader does it. Elsewhere call it once per process, never from a WATERMeDIA callback or worker thread. There's no stop. - Check
WaterMedia.loaded()and the capability you need (such asCodecsAPI.ffmpegLoaded()) instead of assuming them. - Resolution is asynchronous: poll
mrl.status()from a tick and never callmrl.await(...)on the game or render thread. -
PlayerAPI.player(...)can return null. Release the player whenstart()throws or the host drops the surface. - Pass engines as suppliers, never share one between players, and let the player own them.
- Read
player.texture()fresh on every draw, on the render thread; 0 means nothing to draw. - Never call
release()from a status listener or a playback thread, and release every player before destroying the OpenGL, Vulkan or OpenAL context it uses. - The OpenGL executor runs on the GL thread and is pumped every frame, once more after
release()too. OpenAL needs its context current on every thread driving audio. On Vulkan, holdqueueLock()around your own submits and presents, and never callvkDeviceWaitIdlewhile players exist. - Status listeners are consumed by the transition into
STOPPED,ENDEDorERROR; register again from the callback to keep listening. - Boolean controls return
truewhen the call took effect andfalsewhen it was refused; check the result instead of assuming. - Times are in milliseconds (encoder timestamps in microseconds), volume goes from 0 to 100 and speed from just above 0 up to 4.
-
ImageReader.next()reuses its buffer: copy it before the next call. TheCodecsAPIdecode, reader, sniff and encoder calls are experimental: don't use them in mods; its status checks are safe. - Dedicated servers get
ServerMediaPlayer,PlatformAPI,NetworkAPIuploads, the file server and the pure Java image codecs; players and engines throw there.