{
  "name": "TamKungZ_ Blog",
  "description": "Technical articles, dev logs, release notes, and project notes from TamKungZ_.",
  "canonicalUrl": "https://dev.tamkungz.me/blog",
  "languageSupport": [
    "en",
    "th",
    "any language supported by Unicode Markdown"
  ],
  "attribution": {
    "name": "TamKungZ_",
    "canonicalUrl": "https://dev.tamkungz.me",
    "github": "https://github.com/TamKungZ"
  },
  "usage": {
    "permission": "Public content may be indexed, summarized, quoted in short excerpts, and cited with canonical URLs.",
    "attributionPreference": "When using this content, cite TamKungZ_ and link to the canonical post URL.",
    "warning": "Do not fabricate facts beyond the published content."
  },
  "feeds": {
    "rss": "https://dev.tamkungz.me/blog/feed.xml",
    "sitemap": "https://dev.tamkungz.me/sitemap.xml",
    "llms": "https://dev.tamkungz.me/blog/llms.txt",
    "siteLlms": "https://dev.tamkungz.me/llms.txt"
  },
  "posts": [
    {
      "id": "4",
      "title": "TrueMoney สแกนหน้ายืนยันตัวตนไม่ได้บน Huawei ที่ใช้ microG: วิธีที่ผมลองแล้วหาย",
      "canonicalUrl": "https://dev.tamkungz.me/blog/2026-07-16-truemoney-huawei-microg-safetynet-face-verification",
      "author": "TamKungZ_",
      "language": "th",
      "languageName": "Thai",
      "textDirection": "ltr",
      "category": "Troubleshooting",
      "tags": [
        "TrueMoney",
        "Huawei",
        "microG",
        "SafetyNet",
        "Device Attestation",
        "GMS"
      ],
      "publishedDate": "2026-07-16",
      "updatedDate": "2026-07-19",
      "readingTimeMinutes": 3,
      "wordCount": 623,
      "image": "https://i.postimg.cc/Nf3p3P4r/gsm-truemonney-thumbnail.webp",
      "summary": "บันทึกวิธีแก้จากประสบการณ์ตรง เมื่อ TrueMoney Wallet สแกนหน้ายืนยันตัวตนไม่ได้บน Huawei ที่ใช้ microG โดยลองปิด Allow requests ของ TrueMoney ใน Device Attestation.",
      "excerpt": "TrueMoney สแกนหน้ายืนยันตัวตนไม่ได้บน Huawei ที่ใช้ microG: วิธีที่ผมลองแล้วหาย บทความนี้เป็นประสบการณ์ตรงของผมเอง อาจจะไม่ได้เกิดกับทุกคน และสาเหตุจริงอาจไม่ได้เหมือนกันทุกเครื...",
      "keywords": [
        "TrueMoney สแกนหน้าไม่ได้",
        "TrueMoney Huawei",
        "Huawei Y73 TrueMoney",
        "microG SafetyNet",
        "Device Attestation",
        "GMS Huawei",
        "ยืนยันตัวตน TrueMoney ไม่ได้",
        "Face verification",
        "ยืนยันตัวตน",
        "สแกนหน้า",
        "ยืนยันตัวตน TrueMoney",
        "สแกนหน้า TrueMoney",
        "Face Scan",
        "Huawei microG",
        "Huawei"
      ],
      "markdown": "# TrueMoney สแกนหน้ายืนยันตัวตนไม่ได้บน Huawei ที่ใช้ microG: วิธีที่ผมลองแล้วหาย\n\nบทความนี้เป็นประสบการณ์ตรงของผมเอง อาจจะไม่ได้เกิดกับทุกคน และสาเหตุจริงอาจไม่ได้เหมือนกันทุกเครื่อง\n\nแต่ผมเจอเคสหนึ่งที่หาวิธีแก้ในเน็ตค่อนข้างยาก เลยอยากจดไว้ เผื่อมีประโยชน์กับใครบางคนที่เจอปัญหาคล้ายกัน\n\nปัญหาคือ **TrueMoney Wallet สแกนหน้าเพื่อยืนยันตัวตนไม่ได้** บนมือถือ Huawei\n\nในกรณีของผมคือ **Huawei Y73** ซึ่งเป็นเครื่องที่ต้องใช้ GMS ผ่าน microG ในการใช้งานบางอย่างของ Google services\n\n> หมายเหตุ: หลายคนอาจพิมพ์หรือเรียกสลับกันระหว่าง GSM/GMS แต่ในบริบทนี้ผมหมายถึงฝั่ง Google Mobile Services และ microG\n\n## อาการที่เจอ\n\nตอนใช้งาน TrueMoney Wallet แล้วต้องสแกนหน้าเพื่อยืนยันตัวตน แอปไม่สามารถผ่านขั้นตอนนี้ได้\n\nข้อความที่ผมเจอประมาณนี้:\n\n> ไม่สามารถทำรายการได้  \n> กรุณาทำรายการใหม่ภายหลัง\n\nผมลองหาข้อมูลอยู่พักหนึ่ง แต่ไม่ค่อยเจอวิธีแก้ที่ตรงกับเคส Huawei + microG เท่าไร โดยเฉพาะเคสที่เกี่ยวกับการยืนยันตัวตนในแอปการเงิน\n\nสุดท้ายผมสงสัยว่าอาจเกี่ยวกับ **SafetyNet / Device Attestation** เพราะแอปบางตัวจะตรวจสถานะอุปกรณ์ก่อนให้ใช้งานฟีเจอร์บางอย่าง\n\n## วิธีที่ผมลองแล้วใช้ได้\n\nขั้นตอนนี้เป็นสิ่งที่ผมทำบนเครื่องของผมเอง เมนูอาจต่างกันตามรุ่น Huawei, เวอร์ชันระบบ, launcher, หรือเวอร์ชันของ microG\n\n1. เปิด **Settings**\n2. เข้า **Apps**\n3. ค้นหา **microG Services**\n4. กดเข้าไปที่แอปนั้น\n5. มองหาปุ่มตั้งค่ารูป **Gear**\n6. กดเข้าไป จะเข้าสู่หน้า **microG Settings**\n7. หาเมนู **Device Attestation**\n8. เข้าไปที่รายการ **Apps using SafetyNet**\n9. หา **TrueMoney**\n10. กดเข้าไป\n11. ถ้าเห็นตัวเลือก **Allow requests** และมันเปิดอยู่ ให้ลองปิดมัน\n12. จากนั้นลองกลับไปสแกนหน้าใน TrueMoney อีกครั้ง\n\nในเคสของผม หลังจากปิด **Allow requests** ของ TrueMoney ใน Device Attestation แล้ว การสแกนหน้าเพื่อยืนยันตัวตนกลับมาใช้งานได้\n\n## ทำไมวิธีนี้อาจช่วยได้\n\nผมยังไม่อยากสรุปแบบฟันธงว่า TrueMoney มีปัญหากับ SafetyNet เสมอ หรือ microG เป็นสาเหตุหลักเสมอ\n\nแต่จากที่เจอกับเครื่องของผม ดูเหมือนว่า TrueMoney อาจติดขั้นตอนที่เกี่ยวกับการเรียก SafetyNet หรือ Device Attestation ผ่าน microG แล้วทำให้ flow การยืนยันตัวตนมีปัญหา\n\nพอปิดไม่ให้ TrueMoney ส่ง request ตรงนี้ผ่าน microG การยืนยันตัวตนเลยผ่านได้\n\nอย่างไรก็ตาม นี่อาจเป็นแค่ workaround เฉพาะบางเครื่อง บางเวอร์ชัน หรือบางสภาพแวดล้อมเท่านั้น\n\n## ข้อควรระวัง\n\nถ้าคุณใช้แอปการเงินหรือแอปที่เกี่ยวข้องกับความปลอดภัย ควรระวังเวลาแก้ค่าเกี่ยวกับ SafetyNet, Device Attestation หรือ microG\n\nวิธีนี้ไม่ได้แปลว่าควรปิดทุกอย่างในทุกแอป และไม่ได้รับประกันว่าจะใช้ได้กับทุกคน\n\nถ้าลองแล้วไม่ดีขึ้น ให้เปิดค่ากลับเหมือนเดิม แล้วลองตรวจอย่างอื่นต่อ เช่น เวอร์ชัน TrueMoney, เวอร์ชัน microG, permission ของกล้อง, network, หรือสถานะบริการของแอป\n\n## สรุป\n\nถ้าคุณใช้ Huawei ที่พึ่งพา microG/GMS และเจอปัญหา **TrueMoney Wallet สแกนหน้ายืนยันตัวตนไม่ได้** วิธีนี้อาจเป็นอีกหนึ่งทางที่น่าลอง:\n\n**microG Settings > Device Attestation > Apps using SafetyNet > TrueMoney > ปิด Allow requests**\n\nนี่เป็นแค่ประสบการณ์จากเครื่องของผม แต่ถ้ามันช่วยประหยัดเวลาคนอื่นที่กำลังหาวิธีแก้ได้บ้าง ก็น่าจะคุ้มที่จะเผยแพร่ไว้\n"
    },
    {
      "id": "3",
      "title": "Why I Built NilLoaderSDK — A Classic \"Scratch Your Own Itch\" Story",
      "canonicalUrl": "https://dev.tamkungz.me/blog/2026-04-08-why-i-built-nilloadersdk-a-classic-scratch-your-own-itch-story",
      "author": "TamKungZ_",
      "language": "en",
      "languageName": "English",
      "textDirection": "ltr",
      "category": "Project Story",
      "tags": [
        "NilLoaderSDK",
        "NilLoader",
        "Minecraft modding",
        "Java",
        "reflection",
        "mod loader SDK"
      ],
      "publishedDate": "2026-04-08",
      "updatedDate": "2026-07-19",
      "readingTimeMinutes": 4,
      "wordCount": 708,
      "image": "https://dev.tamkungz.me/assets-image/nilloadersdk-logo.png",
      "summary": "A project story about why TamKungZ_ built NilLoaderSDK to make NilLoader-based Minecraft mod development less repetitive while keeping mapping distribution legally clean.",
      "excerpt": "Why I Built NilLoaderSDK — A Classic \"Scratch Your Own Itch\" Story A utility SDK for NilLoader-based Minecraft mods, born out of frustration and necessity. --- The Problem With ...",
      "keywords": [
        "NilLoaderSDK",
        "NilLoader",
        "Minecraft modding",
        "Java reflection",
        "mod loader SDK",
        "TamKungZ_"
      ],
      "markdown": "# Why I Built NilLoaderSDK — A Classic \"Scratch Your Own Itch\" Story\n\n*A utility SDK for NilLoader-based Minecraft mods, born out of frustration and necessity.*\n\n---\n\n## The Problem With NilLoader (And Why That's Also Its Superpower)\n\nIf you've ever worked with [NilLoader](https://git.sleeping.town/Nil/NilLoader), you already know what makes it special: it's version-agnostic. It doesn't tie itself to any specific version of Minecraft. As a Java agent, it simply injects your code into the game's runtime — no strings attached.\n\nThat flexibility is genuinely powerful. But it comes with a cost.\n\nBecause NilLoader doesn't bind to any particular Minecraft version, there's no abstraction layer waiting for you. No event system. No registry helpers. Nothing pre-built the way Forge or Fabric hand things to you. You're writing directly against Minecraft's internals — and that means you'd better have a solid grasp of Java fundamentals, bytecode, and reflection before you even get started.\n\nFor seasoned modders, that's fine. For anyone newer to the space, it's a steep cliff.\n\nThat's exactly why I built **NilLoaderSDK**.\n\n---\n\n## What NilLoaderSDK Actually Is\n\nNilLoaderSDK isn't trying to be a new mod loader. It's not competing with Forge or Fabric. It's a small utility layer that sits on top of NilLoader and smooths out the rough edges — most of which I ran into myself while working on NilLoader-based projects.\n\nHere's what it bundles:\n\n**Reflection Helpers** — Working with private fields and methods in Minecraft's obfuscated codebase is tedious. `ReflectHelper` wraps the boilerplate so you're not writing the same try-catch reflection blocks over and over. `ProxyHelper` extends this for dynamic proxy use cases.\n\n**Structured Logging** — A consistent logging standard built around NilLoader's `NilLogger`. There's a root SDK logger (`NilLoaderSDK`) and a class-scoped variant (`NilLoaderSDK/<ClassName>`). Small thing, but it keeps logs readable across a whole project.\n\n**Entrypoint Dispatcher** — NilLoader has `premain` and `hijack` phases, and coordinating those across a larger project gets messy fast. `EntrypointDispatcher` resolves entrypoints in a defined order — JVM properties first, then a properties file, then ServiceLoader — with built-in recursion guards so you don't accidentally send the loader into an infinite loop.\n\n**Java NIO Networking** — A full non-blocking networking layer: `NioServer`, `NioClient`, `PacketCodec`, `PacketRegistry`, and a `MinecraftAutoNetworkBridge` that can be wired up purely through JVM properties. Useful for mods that need to talk to external services or other game instances.\n\n**Utilities** — `CooldownTracker` for rate-limiting logic and `TargetFinder` for locating entities or objects in the world.\n\nMost of these features exist because I needed them. That's the honest origin story.\n\n---\n\n## The Elephant in the Room: Mappings\n\nIf you're modding old Minecraft — pre-1.7 especially — one of the biggest headaches is **mappings**. Modern toolchains make this almost invisible: configure Gradle, pick a mapping set, done. Back then, it was a whole ordeal.\n\nThe historical go-to was **Mod Coder Pack (MCP)**, which handled remapping Notch's obfuscated names to human-readable Searge mappings all the way back to Minecraft Alpha 1.1.2_01. But MCP is largely inaccessible today. The tooling has fragmented, mirrors are gone, and finding the original sources is genuinely difficult.\n\nNilLoaderSDK includes a `SimpleRemap` utility — but I want to be clear about what it *doesn't* do. It doesn't ship bundled mappings, and it won't. The reason is simple: **licensing**. I couldn't reliably trace the license terms for existing mapping files, even when digging through documentation and original sources. Without clear licensing, I can't ship them — and I'm not willing to guess.\n\nSo the approach here is intentional: **developers bring their own mappings locally**. You wire them into your project yourself. It's one more manual step, but it keeps everything legally clean and gives you full control over what you're working with.\n\n---\n\n## Who Is This For?\n\nRealistically, NilLoaderSDK isn't going to change the Minecraft modding ecosystem. It's a niche tool for a niche loader used by a small community of modders who prefer working close to the metal.\n\nBut if you're in that space — if you're building NilLoader mods and finding yourself rewriting the same reflection utilities or struggling to wire up consistent logging — this SDK might save you some time.\n\nIt's a small thing. But small things add up.\n\n---\n\n## Getting Started\n\nAdd the SDK to your project via Maven:\n\n```kotlin\nrepositories {\n    maven { url = uri(\"https://repo.tamkungz.me\") }\n}\n\ndependencies {\n    implementation(\"me.tamkungz.nilloadersdk:nilloadersdk:2.0.1\")\n}\n```\n\nThe source is available on GitHub, licensed under **LGPL-3.0-or-later**.\n\n- **GitHub**: [TamKungZ/NilLoaderSDK](https://github.com/TamKungZ/NilLoaderSDK)\n- **Maven Repository**: [repo.tamkungz.me](https://repo.tamkungz.me)\n- **NilLoader upstream**: [git.sleeping.town/Nil/NilLoader](https://git.sleeping.town/Nil/NilLoader)\n\n---\n\n*Built by TamKungZ_ — mostly because I needed it.*"
    },
    {
      "id": "2",
      "title": "VLiva Devlog #1 — Why I Started Building a Linux VTuber App",
      "canonicalUrl": "https://dev.tamkungz.me/blog/2026-03-26-vliva-devlog-1-why-i-started-building-a-linux-vtuber-app",
      "author": "TamKungZ_",
      "language": "en",
      "languageName": "English",
      "textDirection": "ltr",
      "category": "Devlog",
      "tags": [
        "VLiva",
        "Linux",
        "VTuber app",
        "Live2D",
        "C++",
        "OpenGL"
      ],
      "publishedDate": "2026-03-26",
      "updatedDate": "2026-07-19",
      "readingTimeMinutes": 3,
      "wordCount": 551,
      "image": "https://dev.tamkungz.me/assets-image/vliva-screenshot.png",
      "summary": "The first VLiva devlog explaining why TamKungZ_ started building a native Linux VTuber app instead of relying on Windows tools or compatibility layers.",
      "excerpt": "VLiva Devlog #1 — Why I Started Building a Linux VTuber App I didn’t originally plan to build this. VLiva started as a small side experiment — something I made mostly out of fru...",
      "keywords": [
        "VLiva",
        "Linux VTuber app",
        "Live2D Linux",
        "C++ OpenGL",
        "VTuber software",
        "TamKungZ_"
      ],
      "markdown": "# VLiva Devlog #1 — Why I Started Building a Linux VTuber App\n\nI didn’t originally plan to build this.\n\nVLiva started as a small side experiment — something I made mostly out of frustration.\nI work with Live2D occasionally, and my main OS is Linux. Switching between Linux and Windows just to run VTuber software quickly became annoying.\n\nSo I looked for alternatives.\n\nThere *are* ways to run existing tools on Linux, but most of them involve:\n\n* compatibility layers\n* workarounds\n* unstable setups\n* or noticeable performance loss\n\nNone of them felt clean.\n\nAt some point I stopped searching and thought:\n“What if I just build something myself?”\n\n## The Early Stage\n\nAt the beginning, I didn’t take this project seriously at all.\nIt was more like: “let’s see if this is even possible.”\n\nThe main challenge was obvious:\n\n* C++\n* OpenGL\n* real-time rendering\n* Live2D runtime behavior\n\nThis wasn’t something I could just throw together in a weekend.\n\nProgress was slow.\nI spent around 5 months on the project — although realistically, I paused for more than half of that time.\n\n## Coming Back\n\nRecently, I came back to the project with a different mindset.\n\nInstead of experimenting, I wanted to actually make it work.\n\nSurprisingly, things started to click:\n\n* rendering pipeline became stable\n* model loading worked\n* basic interaction started functioning\n\nAnd at some point, I realized:\n\n> “This is actually usable.”\n\nNot perfect. Not polished.\nBut real.\n\n## What VLiva Is (for now)\n\nVLiva is a native Linux VTuber app prototype that focuses on simplicity:\n\n* No Wine\n* No virtual machines\n* No external dependencies (as much as possible)\n* Just install and run\n\nThat’s the core idea.\n\n## What’s Next\n\nRight now, the project is still far from finished.\n\nThings that still need work:\n\n* UI/UX\n* performance optimization\n* input / tracking improvements\n* overall stability\n\nI’m planning to release a **demo version around April** to gather feedback and bug reports.\n\n👉 https://vliva.tamkungz.me/\n\nIf the project reaches a stable and complete state, I may release it on Steam in the future.\nPricing is undecided, but the demo will remain free.\n\n## Why I’m Sharing This\n\nOriginally, this was just a personal tool.\n\nBut now I’m curious:\n\nIs there actually a demand for VTubing on Linux?\nAre there other people dealing with the same problems?\n\nIf yes, then this project might be worth pushing further.\n\nIf not… well, at least I built something interesting.\n\nEither way, I’ll keep going for now.\n\n---\n\n## FAQ (from Reddit feedback)\n\n### Is this similar to Inochi2D?\nSome people suggested Inochi2D, and yes — I’ve looked into it before. Their source code is clean and their optimization approach is great.\n\nBut my main target for VLiva is **Live2D support**, so Inochi2D can only help as a partial reference, not a direct solution.\n\n### Does VTube Studio already work on Linux?\nFor some users, yes. One Linux user reported that VTube Studio + VBridger was basically plug-and-play.\n\nThat said, Linux experiences can still vary by distro and setup (Proton, drivers, etc.).\n\n### Then why build VLiva?\nThe goal is not to replace VTube Studio.\n\nVLiva is being built as a **fully native Linux alternative** — no compatibility layer in between, and a simpler path for people who prefer native workflows.\n\n### Will VLiva support VBridger compatibility?\nI’m currently exploring that idea. It’s not confirmed yet, but compatibility with existing VBridger workflows could make adoption much easier for Linux VTubers.\n"
    },
    {
      "id": "1",
      "title": "How a Minecraft mod led me to build my own Java media library from scratch",
      "canonicalUrl": "https://dev.tamkungz.me/blog/2026-03-14-how-a-minecraft-mod-led-me-to-build-my-own-java-media-library-from-scratch",
      "author": "TamKungZ_",
      "language": "en",
      "languageName": "English",
      "textDirection": "ltr",
      "category": "Project Story",
      "tags": [
        "CodecMedia",
        "Java",
        "media parsing",
        "Minecraft modding",
        "OpenAL"
      ],
      "publishedDate": "2026-03-14",
      "updatedDate": "2026-07-19",
      "readingTimeMinutes": 3,
      "wordCount": 542,
      "image": "https://dev.tamkungz.me/assets-image/blog/banner.webp",
      "summary": "A project story about how debugging MP3 playback in a Minecraft mod led TamKungZ_ to build CodecMedia, a Java media probing and validation library.",
      "excerpt": "I wasn't trying to build another media converter. What I actually wanted was something that could answer a much simpler question: \"Is this file really what it claims to be?\" Tha...",
      "keywords": [
        "CodecMedia",
        "Java media library",
        "media validation",
        "MP3 parser",
        "Minecraft modding",
        "OpenAL",
        "TamKungZ_"
      ],
      "markdown": "I wasn't trying to build another media converter.\n\nWhat I actually wanted was something that could answer a much simpler question:\n\n**\"Is this file really what it claims to be?\"**\n\nThat sounds obvious until you start looking at media files beyond their extensions.\n\nA file named `song.mp3` isn't necessarily a valid MP3. Some players will happily play malformed files. Others won't. Some libraries reject them entirely. Extensions don't tell the whole story.\n\nThat realization eventually became **CodecMedia**.\n\n---\n\nIt started while I was building a Minecraft mod.\n\nI wanted to play MP3 files directly through OpenAL instead of Minecraft's built-in audio system. To do that, I needed a low-level MP3 decoder, so I used **Zoom JLayer**, a pure Java decoder from the early 2000s.\n\nIt worked...\n\n...until it didn't.\n\nSome MP3 files decoded perfectly. Others failed completely, even though they played fine in normal media players.\n\nInstead of assuming it was a bug, I started reading JLayer's source code.\n\nThat was when I discovered something I had never really thought about before.\n\nNot every MP3 file is structured the same way.\n\nDifferent bitrate modes, different frame layouts, optional headers, metadata blocks—everything is described by the bytes inside the file, not by its filename.\n\nThe more I looked, the more interesting it became.\n\nEventually I wasn't trying to decode MP3 anymore.\n\nI was trying to understand how media formats actually describe themselves.\n\n---\n\nThat curiosity eventually expanded beyond MP3.\n\nWAV.\n\nFLAC.\n\nOGG.\n\nAIFF.\n\nEach format has its own signature, internal structure, metadata layout, and validation rules.\n\nInstead of relying on file extensions, I started reading the actual binary structures directly.\n\nThat became the foundation of CodecMedia.\n\n---\n\nToday, CodecMedia focuses primarily on **probing and validating media files** by parsing their actual byte structure.\n\nRather than asking \"Does this filename end with `.mp3`?\", it asks questions like:\n\n* Does the file contain a valid format signature?\n* Is the container structure correct?\n* Are the headers internally consistent?\n* Can the streams actually be identified?\n* Is the metadata structurally valid?\n\nBecause of that, CodecMedia can identify media types from the file itself instead of trusting the extension.\n\nUsing it is straightforward.\n\n```java\nCodecMediaEngine engine = CodecMedia.createDefault();\n\nProbeResult probe = engine.probe(Path.of(\"song.mp3\"));\n\nSystem.out.println(probe.mimeType());\nSystem.out.println(probe.durationMillis());\nSystem.out.println(probe.streams().get(0).codec());\nSystem.out.println(probe.streams().get(0).sampleRate());\n```\n\nIf you want to verify that a file is structurally valid before processing it, validation is equally simple.\n\n```java\nValidationResult validation = engine.validate(\n    Path.of(\"song.mp3\"),\n    new ValidationOptions(true, 64L * 1024L * 1024L)\n);\n\nSystem.out.println(validation.valid());\nSystem.out.println(validation.errors());\n```\n\nCodecMedia currently understands formats including MP3, WAV, FLAC, OGG (Vorbis and Opus), AIFF/AIFC, and several others.\n\n---\n\nCodecMedia also contains basic media conversion features.\n\nHowever, conversion is not its primary goal.\n\nThere are already excellent projects like FFmpeg that provide far more complete transcoding capabilities.\n\nCodecMedia is designed differently.\n\nIts primary purpose is to inspect, identify, and validate media by understanding the file's binary format directly, while providing lightweight utilities around that information.\n\n---\n\nI don't expect CodecMedia to replace existing media frameworks.\n\nThere are plenty of mature solutions available.\n\nThe reason I built it wasn't because those tools weren't good enough.\n\nI built it because I wanted to understand what happens underneath them.\n\nReading binary structures, interpreting headers, validating file layouts, and implementing support myself taught me far more than simply calling an external library ever could.\n\nCodecMedia is the result of that exploration.\n\nIf it also ends up being useful to someone else, that's a nice bonus.\n\nMaven Central: https://central.sonatype.com/artifact/me.tamkungz.codecmedia/codecmedia\n\nGitHub: https://github.com/CodecMediaLib/codecmedia-java\n"
    }
  ]
}