{"record":{"id":"c86585a1a9492d8d","repo":"ytdl-org/youtube-dl","slug":"this-video-is-drm-protected-c86585","errorCode":null,"errorMessage":"This video is DRM protected.","messagePattern":"This video is DRM protected\\.","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/ninecninemedia.py","lineNumber":38,"sourceCode":"    _API_BASE_TEMPLATE = 'http://capi.9c9media.com/destinations/%s/platforms/desktop/contents/%s/'\n\n    def _real_extract(self, url):\n        destination_code, content_id = re.match(self._VALID_URL, url).groups()\n        api_base_url = self._API_BASE_TEMPLATE % (destination_code, content_id)\n        content = self._download_json(api_base_url, content_id, query={\n            '$include': '[Media.Name,Season,ContentPackages.Duration,ContentPackages.Id]',\n        })\n        title = content['Name']\n        content_package = content['ContentPackages'][0]\n        package_id = content_package['Id']\n        content_package_url = api_base_url + 'contentpackages/%s/' % package_id\n        content_package = self._download_json(\n            content_package_url, content_id, query={\n                '$include': '[HasClosedCaptions]',\n            })\n\n        if try_get(content_package, lambda x: x['Constraints']['Security']['Type']):\n            raise ExtractorError('This video is DRM protected.', expected=True)\n\n        manifest_base_url = content_package_url + 'manifest.'\n        formats = []\n        formats.extend(self._extract_m3u8_formats(\n            manifest_base_url + 'm3u8', content_id, 'mp4',\n            'm3u8_native', m3u8_id='hls', fatal=False))\n        formats.extend(self._extract_f4m_formats(\n            manifest_base_url + 'f4m', content_id,\n            f4m_id='hds', fatal=False))\n        formats.extend(self._extract_mpd_formats(\n            manifest_base_url + 'mpd', content_id,\n            mpd_id='dash', fatal=False))\n        self._sort_formats(formats)\n\n        thumbnails = []\n        for image in (content.get('Images') or []):\n            image_url = image.get('Url')\n            if not image_url:","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/ninecninemedia.py#L20-L56","documentation":"Raised by the 9c9media (CBC etc.) extractor when the content package's Constraints.Security.Type is truthy — the platform flags the package as DRM-protected. HLS/HDS/DASH manifests may still be fetched, but streams are encrypted, so the extractor refuses up front. Marked expected=True.","triggerScenarios":"Downloading any 9c9media-backed content whose contentpackages API response has Constraints.Security.Type set (e.g. Widevine/PlayReady-protected broadcasts).","commonSituations":"Premium or live CBC/GEM content; syndicated shows with DRM requirements; attempts to archive streaming platforms' protected catalogs — by design not downloadable by youtube-dl.","solutions":["Accept it: DRM content cannot be downloaded with youtube-dl/yt-dlp; use the platform's official offline/app option if available.","Look for a non-DRM on-demand replay of the same program (news clips are often unprotected while live streams are not).","Do not retry with proxies/cookies — DRM is independent of region and session."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import requests\npkg = requests.get(f'{api_base}contentpackages/{package_id}/', params={'$include': '[HasClosedCaptions]'}).json()\nif (pkg.get('Constraints') or {}).get('Security', {}).get('Type'):\n    print('DRM protected — not downloadable')","typeGuard":null,"tryCatchPattern":"except ExtractorError as e:\n    if e.expected and 'DRM' in str(e):\n        give_up_permanently(url)  # no proxy/cookie/retry will help\n    else:\n        raise","preventionTips":["Pre-check Constraints.Security.Type via the contentpackages API before batching.","Never retry DRM failures — they are permanent by design.","Use official apps/offline features for protected content instead."],"tags":["drm","streaming-platform","extractor","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}