{"id":32566041,"url":"https://github.com/samfun75/ktvine","last_synced_at":"2025-10-29T04:59:21.468Z","repository":{"id":321184771,"uuid":"1075381963","full_name":"Samfun75/ktvine","owner":"Samfun75","description":"A KMP library for widevine DRM ported from python lib pywidevine","archived":false,"fork":false,"pushed_at":"2025-10-28T08:29:12.000Z","size":149,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-28T10:10:30.938Z","etag":null,"topics":["android","drm","kmp","kotlin","widevine"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Samfun75.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-13T12:28:03.000Z","updated_at":"2025-10-28T08:28:33.000Z","dependencies_parsed_at":"2025-10-28T10:10:56.938Z","dependency_job_id":"abef43a0-73d9-4a8a-8a53-d14bc6a883f3","html_url":"https://github.com/Samfun75/ktvine","commit_stats":null,"previous_names":["samfun75/ktvine"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Samfun75/ktvine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samfun75%2Fktvine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samfun75%2Fktvine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samfun75%2Fktvine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samfun75%2Fktvine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Samfun75","download_url":"https://codeload.github.com/Samfun75/ktvine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samfun75%2Fktvine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281496927,"owners_count":26511657,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-28T02:00:06.022Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","drm","kmp","kotlin","widevine"],"created_at":"2025-10-29T04:59:20.251Z","updated_at":"2025-10-29T04:59:21.459Z","avatar_url":"https://github.com/Samfun75.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ktvine\n\nKotlin Multiplatform library that mirrors the core functionality of pywidevine: open/close Widevine sessions, build signed license requests from PSSH, verify and parse license responses, and expose decrypted content keys.\n\nBuilt on the same protobuf models as pywidevine and designed to run on JVM and Android targets.\n\n- Open/close sessions\n- Build SignedMessage(LICENSE_REQUEST) from a Widevine PSSH\n- Verify SignedMessage(LICENSE) responses, decrypt keys\n- Parse/build PSSH boxes (Widevine ⇄ PlayReady), extract KIDs\n\nSee also: API docs in docs/API.md\n\n## Installation\n\nGradle (Kotlin DSL):\n\n```kotlin\ndependencies {\n    implementation(\"io.github.samfun75:ktvine:0.0.2\")\n}\n```\n\nThis is a Kotlin Multiplatform library. The artifact publishes for JVM and Android. iOS/Linux targets may be added later.\n\n## Quickstart\n\nThe typical flow is the same as pywidevine, adapted to Kotlin:\n\n1) Load a Widevine device (WVD v2) and create a CDM\n\n```kotlin\nimport org.samfun.ktvine.core.Device\nimport org.samfun.ktvine.cdm.Cdm\n\nval device = Device.loads(base64Wvd) // or Device.loads(bytes)\nval cdm = Cdm.fromDevice(device)\n```\n\n2) Open a session and optionally set a service certificate (privacy mode)\n\n```kotlin\nval sessionId = cdm.open()\n// Optional: service cert as raw SignedDrmCertificate bytes or SignedMessage-wrapped bytes\n// cdm.setServiceCertificate(sessionId, serviceCertBytes)\n```\n\n3) Build a license challenge from a PSSH\n\n```kotlin\nimport org.samfun.ktvine.core.PSSH\n\nval pssh = PSSH(psshBase64) // or PSSH(psshBytes)\nval challenge = cdm.getLicenseChallenge(\n    sessionId = sessionId,\n    pssh = pssh\n)\n// Send `challenge` bytes to your Widevine license server (not provided by this library)\n```\n\n4) Parse the license response and read keys\n\n```kotlin\n// licenseMessage: SignedMessage(LICENSE) payload from your server (raw bytes)\ncdm.parseLicense(sessionId, licenseMessage)\n\nval keys = cdm.getKeys(sessionId) // List\u003cKey\u003e\nkeys.forEach { println(it) }\n\ncdm.close(sessionId)\n```\n\n## PSSH utilities\n\nPSSH parsing and conversion helpers are included:\n\n- Construct from Base64 or bytes: `PSSH(psshBase64)`, `PSSH(psshBytes)`\n- Extract KIDs: `pssh.keyIds()` → List\u003cUUID\u003e\n- Export: `pssh.dump()` (bytes), `pssh.dumps()` (Base64)\n- Convert between systems:\n  - `pssh.toWidevine()`\n  - `pssh.toPlayready(laUrl, luiUrl, dsId, decryptorSetup, customData)` (builds v4.3.0.0 header)\n- Create new boxes: `PSSH.new(systemId, keyIds = ..., initData = ..., version = 0/1)`\n- Overwrite KIDs (Widevine): `pssh.setKeyIds(listOf(uuid1, uuid2))`\n\n## Error handling\n\nPublic methods throw typed exceptions you can catch:\n\n- TooManySessionsException\n- InvalidSessionException\n- InvalidInitDataException\n- InvalidLicenseTypeException\n- DecodeException\n- SignatureMismatchException\n- ValueException\n\n## Differences from pywidevine\n\n- No built-in HTTP client or license server integration. You send/receive bytes yourself.\n- No device provisioning included. Use a valid WVD v2 file as with pywidevine.\n- Uses Kotlin coroutines-friendly, multiplatform-safe crypto (cryptography-kotlin).\n- Protobuf models are generated with Square Wire and are compatible with pywidevine’s schemas.\n\n## Minimal example (JVM)\n\n```kotlin\nsuspend fun main() {\n    val device = Device.loads(System.getenv(\"WVD_BASE64\"))\n    val cdm = Cdm.fromDevice(device)\n    val session = cdm.open()\n\n    val pssh = PSSH(System.getenv(\"PSSH_BASE64\"))\n    val challenge = cdm.getLicenseChallenge(session, pssh)\n\n    val licenseMessage: ByteArray = postToYourServer(challenge) // implement yourself\n    cdm.parseLicense(session, licenseMessage)\n\n    cdm.getKeys(session).forEach { println(it) }\n    cdm.close(session)\n}\n```\n\n## API reference\n\nKDoc is provided throughout the codebase; you can also read a compact overview in docs/API.md.\n\n## License\n\nSee LICENSE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamfun75%2Fktvine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamfun75%2Fktvine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamfun75%2Fktvine/lists"}