
WATERMeDIA: Multimedia API
Библиотека для Minecraft с поддержкой видео и аудио. Работает на Forge, NeoForge, Fabric через VLC и поддерживает YouTube, Twitch, Google Drive и другие платформы. Используется модами вроде WaterFrames, LittleFrames.
Оцените первым
1.1M
112
Список изменений
📦 UPDATE 3.0.0.17 (BETA)
⚡ Core / lifecycle
- ⚙️ Added:
org.watermedia.api.WaterMediaAPIabstract base class — every top-level API now inheritsname(),load(WaterMedia),start(WaterMedia),release(WaterMedia)plus boot-progress fieldsstep/steps/stepNamefor loading screens - ⚙️ Added:
WaterMedia#steps(),step(),currentAPI(),totalWorkSteps(),completedWorkSteps()to surface boot progress - ⚙️ Changed: APIs are now registered as
WaterMediaAPIinstances (CodecsAPI→PlatformAPI→MediaAPI→NetworkAPI), each driven throughload()+start()with per-API try/catch - ⚙️ Changed:
WaterMedia#start(name, ...)now rejects blank names (IllegalArgumentException) - ⚙️ Changed:
WaterMediaConfig.Decoders#defaultQualityretyped fromMRL.Qualitytoorg.watermedia.api.util.MediaQuality
⚡ CodecsAPI
- ⚙️ Added:
ImageReader— new abstract pull-based per-frame decoder (Closeable) withwidth/height/pixelFormat/planeCount/plane/planeStride/scan/loopCount/frameCount/duration/delays/averageFps/variableFrameRate/metadata/readAll/hasNext/next - ⚙️ Added:
ImageWriter— streaming frame encoder skeleton (writeFrame(ByteBuffer),writeFrame(ByteBuffer, long)) - ⚙️ Added:
ImageMetadata— normalized metadata bag with typed accessors (title,description,authors,copyright,comments,creationTime,software,source) and free-form map - ⚙️ Added:
PNG_METAKEY_*,GIF_METAKEY_*,WEBP_METAKEY_*metadata key constants onCodecsAPI - ⚙️ Added:
ImageData.Scanrecord (frameCount,delays,duration,loopCount) withScan.EMPTYconstant - ⚙️ Added:
UnsupportedFormatException extends XCodecException - ⚙️ Added:
CodecsAPI#getMediaType(InputStream)— byte-signature sniffer returning aMediaType(resolves ambiguousapplication/octet-streamresponses) - ⚙️ Changed:
CodecsAPI#decodeImage(byte[]|ByteBuffer)now declaresthrows IOExceptionand returns anImageReader. New overloadsdecodeImage(ByteBuffer|byte[], PixelFormat requestedFormat). Unknown magic throwsUnsupportedFormatException(was returningnull) - ⚙️ Removed: pluggable decoder registry —
CodecsAPI#register(ImageCodec), theIMAGE_CODECSlist and theorg.watermedia.api.codecs.ImageCodecabstract base (superseded byImageReader)
⚡ MediaAPI
- ⚙️ Added:
MediaAPI#getMRL(URI),MediaAPI#createPlayer(MRL, [int sourceIndex,] Supplier<GFXEngine>, Supplier<SFXEngine>)— player factory now lives onMediaAPI(was onMRL) - ⚙️ Added:
MRL#reloadAll(),MRL#subscribe(Consumer<MRL>)(fires once and drops),MRL#hasError(),MRL#exception(),MRL#forgotten(),MRL#blocked()(true when gated by mature-content) - ⚙️ Added:
MRL.Source#qualityOf(URI)and a newMRL.SlaveEntry(name, lang, uri)record - ⚙️ Added:
MediaPlayer.NO_SOURCEconstant - ⚙️ Changed:
MRL#get(URI)renamed toMRL#getMRL(URI);MRL#preload(URI...)now returnsMRL[] - ⚙️ Changed:
MRL#sources()/MRL#sourcesByType(MediaType)returnList<Source>(wasSource[]) - ⚙️ Changed:
MRL.Sourcerewritten as record(MediaType type, URI thumbnail, Metadata metadata, RequestHeaders headers, EnumMap<MediaQuality,URI> qualities, List<SlaveEntry> audioSlaves, List<SlaveEntry> subSlaves); non-emptyqualitiesinvariant enforced - ⚙️ Changed:
MediaPlayerconstructor now takes(MRL, int sourceIndex, GFXEngine, SFXEngine)instead of a resolvedSource - ⚙️ Changed:
MediaPlayer#quality(MediaQuality)/quality()retyped fromMRL.QualitytoMediaQuality - ⚙️ Changed:
MediaPlayer#audioSource()returnsNO_SOURCE(wasNO_TEXTURE) - ⚙️ Removed (from
MRL):invalidate(URI),clearCache(),cacheSize(),error(),busy(),createPlayer(...),createThumbnailPlayer(...),sourceBuilder(...),SourceBuilder,Source.withQuality/reassignQuality/withSlave/withMetadata/slaveByLanguage - ⚙️ Removed (from
MediaAPI):registerPlatform(...)overloads and the internalPLATFORMSlist (moved to newPlatformAPI) - ⚙️ Relocated:
MRL.MediaType→api.util.MediaType;MRL.Quality→api.util.MediaQuality;MRL.Metadata→api.util.Metadata - ⚙️ Added: optional fast-path on
GFXEngine—supportsFrameTextures(),uploadFrameTextures(ByteBuffer[] frames, int stride),useFrameTexture(int) - ⚙️ Added:
GLEngine.Builderaccepts four extra GL function consumers —activeTexture,bindVertexArray,bindFrameBuffer,bindBuffer— so a host can intercept GL state - ⚙️ Removed:
GFXEngine.ColorSpaceinner enum — replaced by top-levelorg.watermedia.api.util.PixelFormat - ⚙️ Changed:
colorSpaceparameters/fields renamedpixelFormatacrossGFXEngine/GLEngine/FFMediaPlayer - ⚙️ Fixed typo:
MediaPlayer#foward()→forward()(also inServerMediaPlayer,FFMediaPlayer,TxMediaPlayer)
⚡ [NEW] PlatformsAPI (api/platform/ package)
- ⚙️ Added:
org.watermedia.api.platform.PlatformAPI extends WaterMediaAPI— registry withstatic PlatformData fetch(URI),static void register(IPlatform); iteration is reverse-registration so apps can override built-ins - ⚙️ Added:
IPlatform(new contract —name(),validate(URI),PlatformData getData(URI)),PlatformData(Instant expires, DataSource... entries),DataSource(MediaType, URI thumbnail, Metadata, RequestHeaders, DataQuality[], List<DataSlave> audioSlaves, List<DataSlave> subSlaves),DataQuality(URI, int width, int height),DataSlave(name, lang, uri) - ⚙️ Added:
internal.WaterPlatform— handleswater://local/remote/globalURIs (constantsHOST_LOCAL/REMOTE/GLOBAL,GLOBAL_SERVER,toHttpURL(URI)) - ⚙️ Relocated:
BiliBiliPlatform,ImgurPlatform,KickPlatform,PornHubPlatform,TwitterPlatformmoved fromapi/media/platform/toapi/platform/web/and migrated to the newPlatformData/DataSource/DataQualityshape - ⚙️ Removed:
api/media/platform/DefaultPlatform, the oldapi/media/platform/IPlatform, and the oldapi/media/platform/{Lightshot,Streamable,Twitch,Youtube}Platform - ⚙️ Removed:
YoutubePlatform(no replacement in this beta)
⚡ NetworkAPI
- ⚙️ Added:
org.watermedia.api.util.NetRequest— builder-style HTTP/FTP/file:// client (create(URI|String),Builder.method/accept/contentType/referer/userAgent/header/addHeader/body/connectTimeout/readTimeout/maxRedirects/headers/send;uri(),statusCode(),contentType(),contentLength(),header(),requestHeaders(),responseHeaders(),getInputStream(),getInputStream(Function),readAllAsString(),json(),json(Class),UserAgentenum,installExtraMimeTypes()) - ⚙️ Added:
org.watermedia.api.util.RequestHeaders— insertion-ordered case-insensitive multi-value header bag (set/add/get/getAll/has/removeAll/entries/iterator/toRawString,defaults(URI)factory; FFmpeg-ready blob viatoRawString()) - ⚙️ Added:
org.watermedia.api.util.MediaQualityenum (UNKNOWN,Q144P/LOWEST…Q8K) withof(int),of(int,int),higher(),lower(),closest(Set, MediaQuality) - ⚙️ Added:
org.watermedia.api.util.MediaTypeenum (IMAGE/VIDEO/AUDIO/SUBTITLES/UNKNOWN) withof(String mimeType)andofExtension(String) - ⚙️ Added:
org.watermedia.api.util.Metadatarecord(title, desc, Instant postedAt, long duration, author) - ⚙️ Added:
HlsTool#fetch(URI, String userAgent)overload (internals migrated fromHttpClienttoNetRequest) - ⚙️ Changed:
NetworkAPInowextends WaterMediaAPI;start(WaterMedia)becomes an instance override; reports two boot steps (MIME registry,FileServer); also installs MIME mappings (webp, apng, mkv, opus, m3u8, mpd, vtt, NETPBM, …) intoURLConnection.getFileNameMap() - ⚙️ Changed:
NetworkAPI#upload(...)return type is nowNetworkServer.UploadStatus(was top-levelUploadStatus) - ⚙️ Removed (from
NetworkAPI):parseQuery(String),waterURL(String),parseWaterURL(URI), the staticWATER_HANDLERfield —water://URL handling is gone from the public API - ⚙️ Renamed:
NetServer→NetworkServer(UploadStatusmoved inside as nested class) - ⚙️ Removed:
WaterStreamHandler, top-levelUploadStatus,NetTool(replaced byNetRequest)
⚡ GENERAL
- ✨ Added TikTok platform support (with full Metadata and Multi-variant qualities)
- ✨ Added D.Tube platform support (with full Metadata and Multi-variant qualities)
- ✨ Added Bluesky platform support (with full Metadata, Gallery support and Multi-variant qualities)
- ✨ Added Odysee platform support (with full Metadata and Multi-variant qualities)
- ✨ Added VidLii platform support
- ✨ Added Sendvid platform support (with half metadata and status-poll wait)
- ✨ Added back Google Drive, Dropbox and MediaFire platform support (limited support due to platform restrictions)
- ✨ Rewrote and Enhanced Twitch platform: now covers VOD, live, clips and better codecs
- ✨ Rewrote and Enhanced Kick platform: now covers clips
- ✨ Rewrote and Enhanced Streamable platform: both
mp4andmp4-mobilequalities exposed as quality variants - ✨ Rewrote Lightshot platform on the new platform API (produces
DataSource(MediaType.IMAGE, ...)) - ✨ Added on-disk media
NetworkCache— two-tier cache (NETWORK live; CODEC reserved for upcoming BC7/DDS) with atomic writes, lock striping, expiry index (WMICv3 format). Wired intoMediaAPI.start()underinstance.tmp/cache. Honored byFFMediaPlayerHTTP body fetches (config-gated, skips HLS/DASH manifests) and byTxMediaPlayer - ✨ Rewrote
TxMediaPlayerwith three playback modes: (1) static one-shot upload, (2) pre-uploaded per-frame textures via the newGFXEngine#uploadFrameTexturesfast-path when frame count ≤txMultiTextureFrameThreshold, (3) streamingImageReaderdecode driven by the playback clock with a bounded prefetch queue (64 MB budget) and direct-ByteBufferpool. Supports seek/loop/step-backwards, falls intoBUFFERINGon under-run - ✨ Added IPTV channel support —
m3u/m3u8channel playlists are expanded into individual channel sources (title, group and logo per channel), with a bundled channel catalog - ✨ Added a house-made JPEG decoder (pure Java, no
ImageIOdependency; baseline + progressive, all common chroma subsamplings) - ✨ Optimized PNG/APNG decoder (~40% faster on animated PNG) and added rich image metadata reporting (text, gamma, chromaticities, sRGB/ICC color profile, physical dimensions, timestamps, and ancillary chunks)
- ✨ Optimized GIF decoder (~12–24% faster); Netscape loop count now surfaced in metadata
- ✨ Optimized WEBP lossless decoder (~40% faster)
- ✨ Optimized WEBP lossy decoder (~2–14% faster); static lossy VP8 without alpha now decodes to native
YUV420Pplanes (no RGB conversion) - ✨ Added new config options:
decoders.maxImageSourceBytesMB(128),media.mrlManagerCleanupInterval(60 min),media.txMultiTextureFrameThreshold(5),media.txNetworkCache,media.ffmpegNetworkCache,media.ffmpegNetworkCacheMaxBytesMB(10),media.ffmpegAnalyzeDurationMs(7000),media.ffmpegProbeSizeMB(10),media.platforms.allowMatureContent,network.requestTimeoutMs(15000),network.maxRedirects(10),network.maxTextBytes(16 MiB) - ✨ Added JOML 1.10.8 as a library dependency
- ✨ [WaterMediaApp] Redesigned the entire standalone app on a new backend-agnostic 2D
RenderEngine/RenderSystem(OpenGL 3.2 core backend; architected so Vulkan can drop in without touching widgets), vertex batching, rounded rects / circles / arcs / gradients / glow / shadow primitives - ✨ [WaterMediaApp] Added more test cases, thumbnail previews, status badges.
- ✨ [WaterMediaApp] Enhanced Mouse experience on controls and buttons
- ✨ [WaterMediaApp] Added a
FrameLimiterwith monitor-aware pacing for drivers ignoring swap interval - ✨ [WaterMediaApp] New
LoadingScreenwith animated boot splash and 8-frame duck animation, eased progress driven byWaterMedia.completedWorkSteps()/totalWorkSteps() - ✨ [WaterMediaApp] Exit-confirmation dialog with
ENTER/ESCbindings - 🛠️ Changed:
MRLreadystate flips true on success or failure; callers must now checkhasError()/exception()separately - 🛠️ Changed:
FFMediaPlayerHW-decoder priority —D3D11VAnow precedesD3D12VA - 🛠️ Changed:
FFMediaPlayerquality auto-aligns — when initial quality isUNKNOWN, it is corrected once real video stream dimensions are known - 🛠️ Changed:
FFMediaPlayeropen-failure logs now include decodedav_strerrortext instead of swallowing the return code - 🛠️ Changed: HTTP requests across
FFMediaPlayer,TxMediaPlayer, and audio slaves now build headers from a unifiedRequestHeaders.defaults(uri)(no more hand-bakedUser-Agent/Accept/Referer) - 🛠️ Changed:
MRLsource resolution delegated toPlatformAPI.fetch(URI); loader threadpool switched toThreadTool.createRecomendedThreadPool(...) - 🛠️ Changed: ambiguous/wrong
Content-Type(e.g.application/octet-stream) is now resolved by sniffing the leading bytes with a URL-extension fallback, so mislabeled media from CDNs no longer fails to open; non-HTTP requests force a real connection instead of letting the URL handler guess the MIME type and existence - 🛠️ Changed: the MRL manager periodically forgets expired or errored MRLs to free memory (interval configurable via
media.mrlManagerCleanupInterval) - 🛠️ Changed: BiliBili CDN cookie/UA/Referer now flow through
RequestHeaderson everyDataSource(including live);WaterMediaConfig.media.platforms.biliBiliCookiehonored at request time - 🛠️ Changed: Mature content is now gated behind
media.platforms.allowMatureContent(disabled by default) — Twitch (streams, VODs, clips) and PornHub throwMatureContentExceptionbefore any data fetch;MRL#blocked()reports the gated state - 🛠️ Changed:
NetworkServer.maxUploadSizeMB <= 0now disables the size cap (was always enforced);NetworkAPI.uploadhonorsWaterMediaConfig.network.requestTimeoutMs - 🛠️ Changed: [WaterMediaApp]
AppBootstrapquick-scan fast-path skips the GUI when all jars are cached; otherwise a console window with progress and 5-second auto-launch is shown; renamedSideloadable→Extension,BOOTSTRAPPED_FLAG→APP_FLAG - 🛠️ Changed: [WaterMediaApp]
HomeScreen,PlayerScreen,MRLSelectorScreen,OpenMultimediaScreenrebuilt (ConsoleScreenandSourceSelectorScreenremoved;GridandSelectorremoved in favor ofListView/StackContainer) - 🐛 Fixed: GIF decoder writing
0x00000000at the transparent index even on frames whose GCE had no transparent-color flag (non-transparent GIFs were getting holes) - 🐛 Fixed: NETPBM
PAMRGB_ALPHAdecode was emitting an extra0xFFbyte between RGB and A, shifting every subsequent pixel - 🐛 Fixed:
NetworkServer#handleUploadno longer NPEs / throwsNumberFormatExceptionon missing or malformedContent-Length(returns 400) - 🐛 Fixed:
NetworkServerpartial/aborted uploads are cleaned up — half-written file and its ID directory are deleted on mid-transferIOException - 🐛 Fixed:
TxMediaPlayerreset/release no longer leaks lifecycle threads or theImageReader - 🐛 Fixed: implausible frame rates reported by some HLS streams (e.g. the 90 kHz clock) no longer break frame pacing — values outside a sane range are now rejected
- 🐛 Fixed: JVM crash on HLS streams whose audio/video parameters fail to probe (sample rate 0) — the stream is now torn down cleanly instead of dividing by zero
Метаданные
Канал релиза
Beta
Номер версии
3.0.0.17
Загрузчики
FabricForgeNeoForge
Версии игры
1.18.2–1.21.11
Загрузок
8.9K
Дата публикации
01.06.2026
