Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ZemerTeam/zemer-cipher/llms.txt

Use this file to discover all available pages before exploring further.

Zemer Cipher is a Kotlin Android library that solves one of the most painful problems in building YouTube clients: keeping stream URLs working as YouTube continuously rotates its player JavaScript. Without correct deciphering, stream URLs either 403 immediately or get CDN-throttled to unusable speeds. Zemer Cipher handles signature deobfuscation, n-parameter transformation, and BotGuard PoToken generation — all by running the actual YouTube player JS inside an Android WebView, so there is no reverse-engineered reimplementation to break and maintain. YouTube rotates its player_ias JS frequently. Each new player version changes the obfuscation function names used to decipher stream signatures and transform the throttling n parameter. Hard-coded function names go stale within days. Zemer Cipher addresses this with a self-healing remote config: a single JSON file is pushed to the master branch of the GitHub repository and deployed apps fetch it automatically (6-hour TTL, force-refreshed on a 403), healing themselves within minutes of a player rotation — no APK update required.

Quickstart

Initialize the library and decipher your first stream URL in five minutes.

Signature Cipher

How signature deobfuscation works and what the signatureCipher parameter contains.

N-Transform

Why the n parameter exists and how transforming it prevents CDN throttling.

PoToken

BotGuard PoToken generation for web client streams and how to attach tokens to requests.

Key Features

  • Signature cipher deobfuscation via Android WebView running the actual YouTube player JS — the library executes window._cipherSigFunc injected directly from the live player, not a re-implementation.
  • N-parameter transformation to prevent CDN throttling: the n-IIFE is extracted from the player JS and executed in the same WebView, transforming the opaque n value before each stream request.
  • PoToken (BotGuard) generation for web client streams: a dedicated PoTokenWebView runs the BotGuard JS to produce both a session-bound playerRequestPoToken and a video-bound streamingDataPoToken.
  • Self-healing remote player configs: a player_configs.json is pushed to this repository’s master branch and apps fetch it at runtime (6-hour TTL + ETag). A config push fixes deployed apps within minutes — no APK release needed.
  • Bundled offline fallback config for cold-start reliability: the same JSON is shipped inside the APK as an asset, so the library works immediately on first launch before any network fetch.
  • Config security boundary: all remote config values are regex-validated by PlayerConfigParser before any JS is injected into the cipher WebView — remote data can never introduce free-form JavaScript.
  • Renderer recovery policy with backoff: after repeated OOM-killed WebView renderer processes (common on low-RAM devices under sustained memory pressure), the library enters a short half-open backoff window so playback fails over fast instead of stalling on a doomed 2.8 MB player.js parse.

Library Info

PropertyValue
Group IDcom.zemer
Artifact IDcipher
Version1.0.0
Min SDK24 (Android 7.0)
LanguageKotlin
LicenseGPL-3.0

How it Works

When deciphering is first needed, PlayerJsFetcher downloads the current YouTube player_ias.js (roughly 2.8 MB) and caches it with a 6-hour TTL. FunctionNameExtractor then consults the player_configs.json table — fetched remotely or bundled as a fallback asset — to resolve the obfuscated function names for the signature cipher call and the n-transform IIFE for the current player hash. Those function names, together with the full player JS, are loaded into a CipherWebView (an Android WebView running off-screen). From that point forward, every call to deobfuscateStreamUrl or transformNParamInUrl executes the real YouTube JavaScript inside that WebView — the library never reimplements YouTube’s obfuscation logic, it just drives the original code. Because the WebView always runs the genuine player JS, a config update that provides correct function names for a rotated player is all that is needed to restore deciphering, and that config is pushed to GitHub rather than shipped in an APK.
Zemer Cipher is released under the GPL-3.0 license. Source code, player configs, and issue tracking are available at https://github.com/ZemerTeam/zemer-cipher.

Build docs developers (and LLMs) love