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 requires Android API 24 or higher, Kotlin coroutines, and a functioning system WebView. The library loads YouTube player JS into an off-screen WebView for signature deobfuscation and n-parameter transformation, so the WebView component must be present and not stripped from the system image. Before integrating, verify that your project meets these baseline requirements.

Requirements

RequirementDetails
Android APIMinimum SDK 24 (Android 7.0 Nougat)
Kotlin1.9 or higher
System WebViewMust be present and functional. On Android Go or minimal/custom system images, verify WebView availability before calling ZemerCipher.initialize().
Internet permissionRequired for player JS fetching and remote config refresh.

Add the Dependency

Zemer Cipher is published via maven-publish. Make sure google() and mavenCentral() are listed in your project’s dependency resolution repositories, then declare the library in your app module. settings.gradle.kts
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
app/build.gradle.kts
dependencies {
    implementation("com.zemer:cipher:1.0.0")
}

Transitive dependencies

The following dependencies are pulled in automatically when you add com.zemer:cipher:
ArtifactNotes
org.jetbrains.kotlinx:kotlinx-coroutines-coreCore coroutines library
org.jetbrains.kotlinx:kotlinx-coroutines-androidCoroutine dispatcher support for Android main thread
org.jetbrains.kotlinx:kotlinx-serialization-jsonPlayer config JSON parsing
com.squareup.okhttp3:okhttpHTTP client for player JS and remote config fetching
com.squareup.okio:okioOkHttp I/O dependency
androidx.collection:collection-ktxKotlin-friendly collection utilities
androidx.annotation:annotationAnnotation support
timber is a compileOnly dependency — see Timber (Optional Logging) below.

Permissions

Add the internet permission to your AndroidManifest.xml. The library requires network access to fetch YouTube player JS and to refresh the remote player config from GitHub.
<uses-permission android:name="android.permission.INTERNET" />
No additional permissions are required. The library does not use camera, microphone, storage, or location APIs.

Timber (Optional Logging)

Timber is declared as compileOnly in the library, which means it is an optional dependency at runtime. If you include Timber in your own app and plant a tree, Zemer Cipher’s debug log statements will appear in your logcat output. If you do not include Timber, all logging calls are silently skipped — there is no NoClassDefFoundError or runtime crash. To enable Zemer Cipher’s debug logs, plant a Timber.DebugTree before calling ZemerCipher.initialize():
// In Application.onCreate(), before ZemerCipher.initialize():
if (BuildConfig.DEBUG) {
    Timber.plant(Timber.DebugTree())
}

ZemerCipher.initialize(
    context = applicationContext,
    debugLogging = BuildConfig.DEBUG
)
Add Timber to your app module if it is not already present:
// app/build.gradle.kts
dependencies {
    implementation("com.jakewharton.timber:timber:5.0.1")
}

ProGuard / R8

No manual keep rules are needed for the Zemer Cipher library itself. The AAR ships a consumer-rules.pro file that is automatically merged into your app’s ProGuard configuration by the Android Gradle Plugin when you build a minified release. If you use R8 in full-mode, the consumer rules are still applied in the same way.
The library loads approximately 2.8 MB of YouTube player.js into a WebView on first use. This is expected behavior — the JS is the real YouTube player, required to run the obfuscation functions that decipher stream signatures and transform n-parameters. The file is cached with a 6-hour TTL (plus ETag validation) so subsequent launches reuse the cached copy from disk. Call CipherDeobfuscator.prewarm() after initialization to absorb this one-time cost before the user requests playback.

Build docs developers (and LLMs) love