{"record":{"id":"d37c1e8b5bab9ad2","repo":"ytdl-org/youtube-dl","slug":"this-video-is-drm-protected-d37c1e","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/tv2.py","lineNumber":106,"sourceCode":"                    if not data.get('drmProtected'):\n                        formats.extend(self._extract_m3u8_formats(\n                            video_url, video_id, 'mp4',\n                            'm3u8' if is_live else 'm3u8_native',\n                            m3u8_id=format_id, fatal=False))\n                elif ext == 'mpd':\n                    formats.extend(self._extract_mpd_formats(\n                        video_url, video_id, format_id, fatal=False))\n                elif ext == 'ism' or video_url.endswith('.ism/Manifest'):\n                    pass\n                else:\n                    formats.append({\n                        'url': video_url,\n                        'format_id': format_id,\n                        'tbr': int_or_none(item.get('bitrate')),\n                        'filesize': int_or_none(item.get('fileSize')),\n                    })\n        if not formats and data.get('drmProtected'):\n            raise ExtractorError('This video is DRM protected.', expected=True)\n        self._sort_formats(formats)\n\n        thumbnails = [{\n            'id': thumbnail.get('@type'),\n            'url': thumbnail.get('url'),\n        } for _, thumbnail in (asset.get('imageVersions') or {}).items()]\n\n        return {\n            'id': video_id,\n            'url': video_url,\n            'title': self._live_title(title) if is_live else title,\n            'description': strip_or_none(asset.get('description')),\n            'thumbnails': thumbnails,\n            'timestamp': parse_iso8601(asset.get('createTime')),\n            'duration': float_or_none(asset.get('accurateDuration') or asset.get('duration')),\n            'view_count': int_or_none(asset.get('views')),\n            'categories': asset.get('keywords', '').split(','),\n            'formats': formats,","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/tv2.py#L88-L124","documentation":"Raised by TV2IE when the video metadata from tv2.no marks the asset as drmProtected and no playable formats could be extracted (all MPD/HLS/plain-URL extraction yielded nothing). It is an expected ExtractorError, so youtube-dl reports it as a user-facing 'video unavailable' rather than a bug. DRM content is encrypted and cannot be downloaded by youtube-dl.","triggerScenarios":"Requesting a tv2.no (or TV 2 Sumo) URL whose asset JSON contains data['drmProtected'] == true while every candidate video_url produced zero formats (e.g. only .ism/Manifest entries, which are skipped with 'pass').","commonSituations":"Premium/licensed broadcasts on TV2 Norway, Hollywood movies or live sports behind DRM licensing, region-locked assets that only expose PlayReady/Widevine manifests.","solutions":["Accept that DRM-protected TV2 content cannot be downloaded with youtube-dl; use the broadcaster's official app/portal.","Verify the video actually plays without entitlements in a browser on the same network/cookies; if the page itself refuses, nothing youtube-dl can do.","Try a different, non-DRM episode/clip ID from the same show.","Pass --cookies from an authenticated browser session if the asset requires login (only helps for non-DRM paywalls)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def is_tv2_drm(data: dict) -> bool:\n    return not data.get('formats') and bool(data.get('drmProtected'))","tryCatchPattern":"from youtube_dl.utils import ExtractorError\ntry:\n    ydl.extract_info('https://www.tv2.no/video/1234567/')\nexcept ExtractorError as e:\n    if 'DRM protected' in str(e):\n        log.warning('Skipping DRM item: %s', e)\n    else:\n        raise","preventionTips":["Treat 'DRM protected' as a terminal per-item condition; exclude such ids from retry queues.","In batch pipelines, catch ExtractorError per URL and record the reason instead of aborting the run."],"tags":["drm","extractor","tv2","streaming","paywall"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}