Loading pkgs/by-name/wi/widevine-cdm/package.nix +1 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ }: let # TODO: update aarch64 to use crx3 targets = lib.genAttrs [ "aarch64-linux" "x86_64-linux" Loading pkgs/by-name/wi/widevine-cdm/update-x86_64.py 0 → 100755 +107 −0 Original line number Diff line number Diff line #! /usr/bin/env nix-shell #! nix-shell -i python3 -p python3 from __future__ import annotations import sys, os, json, base64, re, argparse, urllib.request, time from typing import Dict, Optional, Tuple from pathlib import Path DEFAULT_JSON = "https://raw.githubusercontent.com/mozilla/gecko-dev/master/toolkit/content/gmp-sources/widevinecdm.json" ARCH_PATTERNS = { "linux_x86_64": ["Linux_x86_64-gcc3"], "linux_aarch64": ["Linux_aarch64-gcc3"] } def fetch_json(url: str) -> dict: with urllib.request.urlopen(url) as r: return json.load(r) def hex_to_sri(hexstr: str) -> str: b = bytes.fromhex(hexstr) return "sha512-" + base64.b64encode(b).decode() def find_widevine_vendor(data: dict) -> dict: vendors = data.get("vendors") or {} for key, value in vendors.items(): if "gmp-widevinecdm" in key.lower(): return value raise SystemExit("ERR: couldn't find a widevine vendor entry in JSON !") def judge_platforms(platforms: dict, patterns) -> Optional[Tuple[str, dict]]: for plkey, plvalue in platforms.items(): if plvalue.get("alias"): continue low = plkey.lower() for pat in patterns: if pat.lower() in low: return plkey, plvalue return None def normalize_fileurl(entry: dict) -> Optional[str]: if entry.get("fileUrl"): return entry["fileUrl"] m = entry.get("mirrorUrls") if isinstance(m, list) and m: return m[0] return None def extract_ver_from_url(url: str) -> Optional[str]: m = re.search(r'[_-](\d+\.\d+\.\d+\.\d+)[_-]', url) if m: return m.group(1) m = re.search(r'(\d+\.\d+\.\d+\.\d+)', url) return m.group(1) if m else None def build_entry(pkey: str, pentry: dict) -> dict: url = normalize_fileurl(pentry) hv = pentry.get("hashValue") if not url or not hv: raise SystemExit(f"ERR: platform {pkey} is missing a file URL or hash !") sri = hex_to_sri(hv) version = extract_ver_from_url(url) return {"platform_key": pkey, "url": url, "sri": sri, "version": version} def main(): WIDEVINE_DIR = Path(__file__).resolve().parent DEFAULT_FILE = WIDEVINE_DIR / "x86_64-manifest.json" ap = argparse.ArgumentParser() ap.add_argument("file", type=Path, nargs="?", default=DEFAULT_FILE) ap.add_argument("--json-url", default=DEFAULT_JSON) args = ap.parse_args() print(f"# fetching {args.json_url} !", file=sys.stderr) data = fetch_json(args.json_url) vendor = find_widevine_vendor(data) platforms = vendor.get("platforms") or {} # should never be null but moz could forseeably delete it if not platforms: raise SystemExit("ERR: no widevine platforms !") results = {} for arch, patterns in ARCH_PATTERNS.items(): found = judge_platforms(platforms, patterns) if not found: print(f"# WARN: no platform for {arch}. skipping !", file=sys.stderr) continue pkey, pentry = found print(f"# found {arch} --> {pkey}", file=sys.stderr) entry = build_entry(pkey, pentry) results[arch] = entry if not results: raise SystemExit("ERR: no linux platform entries !") linux_x64 = results["linux_x86_64"] args.file.write_text(json.dumps(linux_x64, indent=2) + "\n", encoding="utf-8") print("# updated", file=sys.stderr) if __name__ == "__main__": main() pkgs/by-name/wi/widevine-cdm/x86_64-linux.nix +24 −9 Original line number Diff line number Diff line { lib, stdenv, fetchzip, fetchurl, go-crx3, }: let manifest = builtins.fromJSON (builtins.readFile ./x86_64-manifest.json); in stdenv.mkDerivation (finalAttrs: { pname = "widevine-cdm"; version = "4.10.2891.0"; version = manifest.version; src = fetchzip { # The download 404s url = "https://web.archive.org/web/20250725071306/https://dl.google.com/widevine-cdm/4.10.2891.0-linux-x64.zip"; hash = "sha256-ZO6FmqJUnB9VEJ7caJt58ym8eB3/fDATri3iOWCULRI="; stripRoot = false; src = fetchurl { url = manifest.url; hash = manifest.sri; }; nativeBuildInputs = [ go-crx3 ]; unpackPhase = '' unpackDir="src" cp "$src" "$unpackDir".crx # go-crx3 doesn't like .crx3 extensions crx3 unpack "$unpackDir".crx cd "$unpackDir" ''; installPhase = '' runHook preInstall install -vD manifest.json $out/share/google/chrome/WidevineCdm/manifest.json install -vD LICENSE.txt $out/share/google/chrome/WidevineCdm/LICENSE.txt install -vD libwidevinecdm.so $out/share/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so install -vD LICENSE $out/share/google/chrome/WidevineCdm/LICENSE.txt install -vD _platform_specific/linux_x64/libwidevinecdm.so $out/share/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so runHook postInstall ''; passthru.updateScript = ./update-x86_64.py; meta = import ./meta.nix lib; }) pkgs/by-name/wi/widevine-cdm/x86_64-manifest.json 0 → 100644 +6 −0 Original line number Diff line number Diff line { "platform_key": "Linux_x86_64-gcc3", "url": "https://edgedl.me.gvt1.com/edgedl/release2/chrome_component/aclxnidwwkj5di3vduduj2gqpgpq_4.10.2891.0/oimompecagnajdejgnnjijobebaeigek_4.10.2891.0_linux_b4hin3q5s66ws2322cyyfp35lu.crx3", "sri": "sha512-8S/4FRQQmQAO9wJ7QGJg8KUVxUQgm5/oEl6l9N2/WGAdMCIqxBoBPrCkPadrpwQUpK0WYX2fIZ8Zzfx3lNm8lA==", "version": "4.10.2891.0" } Loading
pkgs/by-name/wi/widevine-cdm/package.nix +1 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ }: let # TODO: update aarch64 to use crx3 targets = lib.genAttrs [ "aarch64-linux" "x86_64-linux" Loading
pkgs/by-name/wi/widevine-cdm/update-x86_64.py 0 → 100755 +107 −0 Original line number Diff line number Diff line #! /usr/bin/env nix-shell #! nix-shell -i python3 -p python3 from __future__ import annotations import sys, os, json, base64, re, argparse, urllib.request, time from typing import Dict, Optional, Tuple from pathlib import Path DEFAULT_JSON = "https://raw.githubusercontent.com/mozilla/gecko-dev/master/toolkit/content/gmp-sources/widevinecdm.json" ARCH_PATTERNS = { "linux_x86_64": ["Linux_x86_64-gcc3"], "linux_aarch64": ["Linux_aarch64-gcc3"] } def fetch_json(url: str) -> dict: with urllib.request.urlopen(url) as r: return json.load(r) def hex_to_sri(hexstr: str) -> str: b = bytes.fromhex(hexstr) return "sha512-" + base64.b64encode(b).decode() def find_widevine_vendor(data: dict) -> dict: vendors = data.get("vendors") or {} for key, value in vendors.items(): if "gmp-widevinecdm" in key.lower(): return value raise SystemExit("ERR: couldn't find a widevine vendor entry in JSON !") def judge_platforms(platforms: dict, patterns) -> Optional[Tuple[str, dict]]: for plkey, plvalue in platforms.items(): if plvalue.get("alias"): continue low = plkey.lower() for pat in patterns: if pat.lower() in low: return plkey, plvalue return None def normalize_fileurl(entry: dict) -> Optional[str]: if entry.get("fileUrl"): return entry["fileUrl"] m = entry.get("mirrorUrls") if isinstance(m, list) and m: return m[0] return None def extract_ver_from_url(url: str) -> Optional[str]: m = re.search(r'[_-](\d+\.\d+\.\d+\.\d+)[_-]', url) if m: return m.group(1) m = re.search(r'(\d+\.\d+\.\d+\.\d+)', url) return m.group(1) if m else None def build_entry(pkey: str, pentry: dict) -> dict: url = normalize_fileurl(pentry) hv = pentry.get("hashValue") if not url or not hv: raise SystemExit(f"ERR: platform {pkey} is missing a file URL or hash !") sri = hex_to_sri(hv) version = extract_ver_from_url(url) return {"platform_key": pkey, "url": url, "sri": sri, "version": version} def main(): WIDEVINE_DIR = Path(__file__).resolve().parent DEFAULT_FILE = WIDEVINE_DIR / "x86_64-manifest.json" ap = argparse.ArgumentParser() ap.add_argument("file", type=Path, nargs="?", default=DEFAULT_FILE) ap.add_argument("--json-url", default=DEFAULT_JSON) args = ap.parse_args() print(f"# fetching {args.json_url} !", file=sys.stderr) data = fetch_json(args.json_url) vendor = find_widevine_vendor(data) platforms = vendor.get("platforms") or {} # should never be null but moz could forseeably delete it if not platforms: raise SystemExit("ERR: no widevine platforms !") results = {} for arch, patterns in ARCH_PATTERNS.items(): found = judge_platforms(platforms, patterns) if not found: print(f"# WARN: no platform for {arch}. skipping !", file=sys.stderr) continue pkey, pentry = found print(f"# found {arch} --> {pkey}", file=sys.stderr) entry = build_entry(pkey, pentry) results[arch] = entry if not results: raise SystemExit("ERR: no linux platform entries !") linux_x64 = results["linux_x86_64"] args.file.write_text(json.dumps(linux_x64, indent=2) + "\n", encoding="utf-8") print("# updated", file=sys.stderr) if __name__ == "__main__": main()
pkgs/by-name/wi/widevine-cdm/x86_64-linux.nix +24 −9 Original line number Diff line number Diff line { lib, stdenv, fetchzip, fetchurl, go-crx3, }: let manifest = builtins.fromJSON (builtins.readFile ./x86_64-manifest.json); in stdenv.mkDerivation (finalAttrs: { pname = "widevine-cdm"; version = "4.10.2891.0"; version = manifest.version; src = fetchzip { # The download 404s url = "https://web.archive.org/web/20250725071306/https://dl.google.com/widevine-cdm/4.10.2891.0-linux-x64.zip"; hash = "sha256-ZO6FmqJUnB9VEJ7caJt58ym8eB3/fDATri3iOWCULRI="; stripRoot = false; src = fetchurl { url = manifest.url; hash = manifest.sri; }; nativeBuildInputs = [ go-crx3 ]; unpackPhase = '' unpackDir="src" cp "$src" "$unpackDir".crx # go-crx3 doesn't like .crx3 extensions crx3 unpack "$unpackDir".crx cd "$unpackDir" ''; installPhase = '' runHook preInstall install -vD manifest.json $out/share/google/chrome/WidevineCdm/manifest.json install -vD LICENSE.txt $out/share/google/chrome/WidevineCdm/LICENSE.txt install -vD libwidevinecdm.so $out/share/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so install -vD LICENSE $out/share/google/chrome/WidevineCdm/LICENSE.txt install -vD _platform_specific/linux_x64/libwidevinecdm.so $out/share/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so runHook postInstall ''; passthru.updateScript = ./update-x86_64.py; meta = import ./meta.nix lib; })
pkgs/by-name/wi/widevine-cdm/x86_64-manifest.json 0 → 100644 +6 −0 Original line number Diff line number Diff line { "platform_key": "Linux_x86_64-gcc3", "url": "https://edgedl.me.gvt1.com/edgedl/release2/chrome_component/aclxnidwwkj5di3vduduj2gqpgpq_4.10.2891.0/oimompecagnajdejgnnjijobebaeigek_4.10.2891.0_linux_b4hin3q5s66ws2322cyyfp35lu.crx3", "sri": "sha512-8S/4FRQQmQAO9wJ7QGJg8KUVxUQgm5/oEl6l9N2/WGAdMCIqxBoBPrCkPadrpwQUpK0WYX2fIZ8Zzfx3lNm8lA==", "version": "4.10.2891.0" }