Skip to content

EN US Home

J-RAP edited this page Nov 7, 2026 · 3 revisions

🦆 INTRODUCTION

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.

🪁 VERSION SCHEMA

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)

🗺 INDEX

Pick the path that matches what you're building.

MINECRAFT: MODDERS ADDING VIDEO

  1. Setup: add the dependency and respect the version range.
  2. Software restrictions: supported Minecraft and loader versions.
  3. Managing links: turn a link into media sources.
  4. Creating and controlling a player.
  5. Choosing engines: OpenGL, Vulkan and OpenAL on the game's own contexts.
  6. Spatial audio: positional screens, stereo pairs and speakers.
  7. Synchronized playback: every player watches the same moment.
  8. Uploading and downloading files: share files through the file server.

DESKTOP APPLICATIONS

  1. Setup: Gradle dependencies, runtime libraries and configuration.
  2. Startup: start WATERMeDIA once and show a loading screen.
  3. Managing links and searching.
  4. Creating and controlling a player and audio tracks.
  5. Choosing engines: AWT, JavaFX, OpenGL or Vulkan, plus OpenAL or Java Sound.
  6. Diagnostics and examples.

CODE TOOLS

Command-line tools, bots, converters and services that work without a window.

  1. Setup and startup: what needs a start and what doesn't.
  2. Platforms and searching: resolve and search links with PlatformAPI, no startup needed.
  3. Downloads: NetRequest with bounded, verified downloads.
  4. Decoders and encoders: pictures, animations and video files.
  5. Headless engine: capture decoded frames without a graphics context.
  6. Synchronized playback: ServerMediaPlayer runs on servers too.

AI AGENTS

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 from PlayerAPI; 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 as CodecsAPI.ffmpegLoaded()) instead of assuming them.
  • Resolution is asynchronous: poll mrl.status() from a tick and never call mrl.await(...) on the game or render thread.
  • PlayerAPI.player(...) can return null. Release the player when start() 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, hold queueLock() around your own submits and presents, and never call vkDeviceWaitIdle while players exist.
  • Status listeners are consumed by the transition into STOPPED, ENDED or ERROR; register again from the callback to keep listening.
  • Boolean controls return true when the call took effect and false when 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. The CodecsAPI decode, reader, sniff and encoder calls are experimental: don't use them in mods; its status checks are safe.
  • Dedicated servers get ServerMediaPlayer, PlatformAPI, NetworkAPI uploads, the file server and the pure Java image codecs; players and engines throw there.

Clone this wiki locally