Repository: yt-dlp/yt-dlp

Issue:
rtl.lu site request
### Checklist

- [X] I'm reporting a new site support request
- [X] I've verified that I'm running yt-dlp version **2021.11.10.1**. ([update instructions](https://github.com/yt-dlp/yt-dlp#update))
- [X] I've checked that all provided URLs are alive and playable in a browser
- [X] I've checked that none of provided URLs [violate any copyrights](https://github.com/ytdl-org/youtube-dl#can-you-add-support-for-this-anime-video-site-or-site-which-shows-current-movies-for-free) or contain any [DRM](https://en.wikipedia.org/wiki/Digital_rights_management) to the best of my knowledge
- [X] I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues including closed ones. DO NOT post duplicates
- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)
- [X] I've read about [sharing account credentials](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#are-you-willing-to-share-account-details-if-needed) and am willing to share it if required

### Region

europe

### Example URLs

https://www.rtl.lu/tele/de-journal-vun-der-tele/v/3266757.html

### Description

Thanks for adding this additional site if possible.

### Verbose log

```shell
D:\Programmes\Tools\Batch\FFMPEG>yt-dlp.exe -Uv https://www.rtl.lu/tele/de-journal-vun-der-tele/v/3266757.html
[debug] Command-line config: ['-Uv', 'https://www.rtl.lu/tele/de-journal-vun-der-tele/v/3266757.html']
[debug] Encodings: locale cp1252, fs utf-8, out utf-8, err utf-8, pref cp1252
[debug] yt-dlp version 2021.11.10.1 (win_exe)
[debug] Python version 3.8.10 (CPython 64bit) - Windows-10-10.0.19041-SP0
[debug] exe versions: ffmpeg 4.4-essentials_build-www.gyan.dev (setts), ffprobe 4.4-essentials_build-www.gyan.dev
[debug] Optional libraries: Cryptodome, mutagen, sqlite, websockets
[debug] Proxy map: {}
yt-dlp is up to date (2021.11.10.1)
[debug] [generic] Extracting URL: https://www.rtl.lu/tele/de-journal-vun-der-tele/v/3266757.html
[generic] 3266757: Requesting header
WARNING: [generic] Falling back on generic information extractor.
[generic] 3266757: Downloading webpage
[generic] 3266757: Extracting information
[debug] Looking for video embeds
ERROR: Unsupported URL: https://www.rtl.lu/tele/de-journal-vun-der-tele/v/3266757.html
Traceback (most recent call last):
  File "yt_dlp\YoutubeDL.py", line 1311, in wrapper
  File "yt_dlp\YoutubeDL.py", line 1336, in __extract_info
  File "yt_dlp\extractor\common.py", line 595, in extract
  File "yt_dlp\extractor\generic.py", line 3766, in _real_extract
yt_dlp.utils.UnsupportedError: Unsupported URL: https://www.rtl.lu/tele/de-journal-vun-der-tele/v/3266757.html
```



Discussion:
From your link, we can found the `manifest_url` from `rtl-player` tag that has `hls` attribute.

Resolving patch:
diff --git a/yt_dlp/extractor/_extractors.py b/yt_dlp/extractor/_extractors.py
--- a/yt_dlp/extractor/_extractors.py
+++ b/yt_dlp/extractor/_extractors.py
@@ -1434,7 +1434,13 @@
 from .rozhlas import RozhlasIE
 from .rtbf import RTBFIE
 from .rte import RteIE, RteRadioIE
-from .rtlnl import RtlNlIE
+from .rtlnl import (
+    RtlNlIE,
+    RTLLuTeleVODIE, 
+    RTLLuArticleIE,
+    RTLLuLiveIE,
+    RTLLuRadioIE,
+)
 from .rtl2 import (
     RTL2IE,
     RTL2YouIE,
diff --git a/yt_dlp/extractor/rtlnl.py b/yt_dlp/extractor/rtlnl.py
--- a/yt_dlp/extractor/rtlnl.py
+++ b/yt_dlp/extractor/rtlnl.py
@@ -141,3 +141,155 @@ def _real_extract(self, url):
             'duration': parse_duration(material.get('duration')),
             'thumbnails': thumbnails,
         }
+
+
+class RTLLuBaseIE(InfoExtractor):
+    _MEDIA_REGEX = {
+        'video': r'<rtl-player\s[^>]*\bhls\s*=\s*"([^"]+)',
+        'audio': r'<rtl-audioplayer\s[^>]*\bsrc\s*=\s*"([^"]+)',
+        'thumbnail': r'<rtl-player\s[^>]*\bposter\s*=\s*"([^"]+)',
+    }
+
+    def get_media_url(self, webpage, video_id, media_type):
+        return self._search_regex(self._MEDIA_REGEX[media_type], webpage, f'{media_type} url', default=None)
+
+    def get_formats_and_subtitles(self, webpage, video_id):
+        video_url, audio_url = self.get_media_url(webpage, video_id, 'video'), self.get_media_url(webpage, video_id, 'audio')
+
+        formats, subtitles = [], {}
+        if video_url is not None:
+            formats, subtitles = self._extract_m3u8_formats_and_subtitles(video_url, video_id)
+        if audio_url is not None:
+            formats.append({'url': audio_url, 'ext': 'mp3', 'vcodec': 'none'})
+
+        return formats, subtitles
+
+    def _real_extract(self, url):
+        video_id = self._match_id(url)
+        is_live = video_id in ('live', 'live-2', 'lauschteren')
+
+        # TODO: extract comment from https://www.rtl.lu/comments?status=1&order=desc&context=news|article|<video_id>
+        # we can context from <rtl-comments context=<context> in webpage
+        webpage = self._download_webpage(url, video_id)
+
+        formats, subtitles = self.get_formats_and_subtitles(webpage, video_id)
+        self._sort_formats(formats)
+
+        return {
+            'id': video_id,
+            'title': self._og_search_title(webpage),
+            'description': self._og_search_description(webpage, default=None),
+            'formats': formats,
+            'subtitles': subtitles,
+            'thumbnail': self.get_media_url(webpage, video_id, 'thumbnail') or self._og_search_thumbnail(webpage, default=None),
+            'is_live': is_live,
+        }
+
+
+class RTLLuTeleVODIE(RTLLuBaseIE):
+    IE_NAME = 'rtl.lu:tele-vod'
+    _VALID_URL = r'https?://(?:www\.)?rtl\.lu/(tele/(?P<slug>[\w-]+)/v/|video/)(?P<id>\d+)(\.html)?'
+    _TESTS = [{
+        'url': 'https://www.rtl.lu/tele/de-journal-vun-der-tele/v/3266757.html',
+        'info_dict': {
+            'id': '3266757',
+            'title': 'Informatiounsversammlung Héichwaasser',
+            'ext': 'mp4',
+            'thumbnail': 'https://replay-assets.rtl.lu/2021/11/16/d3647fc4-470d-11ec-adc2-3a00abd6e90f_00008.jpg',
+            'description': 'md5:b1db974408cc858c9fd241812e4a2a14',
+        }
+    }, {
+        'url': 'https://www.rtl.lu/video/3295215',
+        'info_dict': {
+            'id': '3295215',
+            'title': 'Kulturassisen iwwer d\'Bestandsopnam vum Lëtzebuerger Konscht',
+            'ext': 'mp4',
+            'thumbnail': 'https://replay-assets.rtl.lu/2022/06/28/0000_3295215_0000.jpg',
+            'description': 'md5:85bcd4e0490aa6ec969d9bf16927437b',
+        }
+    }]
+
+
+class RTLLuArticleIE(RTLLuBaseIE):
+    IE_NAME = 'rtl.lu:article'
+    _VALID_URL = r'https?://(?:(www|5minutes|today)\.)rtl\.lu/(?:[\w-]+)/(?:[\w-]+)/a/(?P<id>\d+)\.html'
+    _TESTS = [{
+        # Audio-only
+        'url': 'https://www.rtl.lu/sport/news/a/1934360.html',
+        'info_dict': {
+            'id': '1934360',
+            'ext': 'mp3',
+            'thumbnail': 'https://static.rtl.lu/rtl2008.lu/nt/p/2022/06/28/19/e4b37d66ddf00bab4c45617b91a5bb9b.jpeg',
+            'description': 'md5:5eab4a2a911c1fff7efc1682a38f9ef7',
+            'title': 'md5:40aa85f135578fbd549d3c9370321f99',
+        }
+    }, {
+        # 5minutes
+        'url': 'https://5minutes.rtl.lu/espace-frontaliers/frontaliers-en-questions/a/1853173.html',
+        'info_dict': {
+            'id': '1853173',
+            'ext': 'mp4',
+            'description': 'md5:ac031da0740e997a5cf4633173634fee',
+            'title': 'md5:87e17722ed21af0f24be3243f4ec0c46',
+            'thumbnail': 'https://replay-assets.rtl.lu/2022/01/26/screenshot_20220126104933_3274749_12b249833469b0d6e4440a1dec83cdfa.jpg',
+        }
+    }, {
+        # today.lu
+        'url': 'https://today.rtl.lu/entertainment/news/a/1936203.html',
+        'info_dict': {
+            'id': '1936203',
+            'ext': 'mp4',
+            'title': 'Once Upon A Time...zu Lëtzebuerg: The Three Witches\' Tower',
+            'description': 'The witchy theme continues in the latest episode of Once Upon A Time...',
+            'thumbnail': 'https://replay-assets.rtl.lu/2022/07/02/screenshot_20220702122859_3290019_412dc5185951b7f6545a4039c8be9235.jpg',
+        }
+    }]
+
+
+class RTLLuLiveIE(RTLLuBaseIE):
+    _VALID_URL = r'https?://www\.rtl\.lu/(?:tele|radio)/(?P<id>live(?:-\d+)?|lauschteren)'
+    _TESTS = [{
+        # Tele:live
+        'url': 'https://www.rtl.lu/tele/live',
+        'info_dict': {
+            'id': 'live',
+            'ext': 'mp4',
+            'live_status': 'is_live',
+            'title': r're:RTL - Télé LIVE \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
+            'thumbnail': 'https://static.rtl.lu/livestream/channel1.jpg',
+        }
+    }, {
+        # Tele:live-2
+        'url': 'https://www.rtl.lu/tele/live-2',
+        'info_dict': {
+            'id': 'live-2',
+            'ext': 'mp4',
+            'live_status': 'is_live',
+            'title': r're:RTL - Télé LIVE \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
+            'thumbnail': 'https://static.rtl.lu/livestream/channel2.jpg',
+        }
+    }, {
+        # Radio:lauschteren
+        'url': 'https://www.rtl.lu/radio/lauschteren',
+        'info_dict': {
+            'id': 'lauschteren',
+            'ext': 'mp4',
+            'live_status': 'is_live',
+            'title': r're:RTL - Radio LIVE \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
+            'thumbnail': 'https://static.rtl.lu/livestream/rtlradiowebtv.jpg',
+        }
+    }]
+
+
+class RTLLuRadioIE(RTLLuBaseIE):
+    _VALID_URL = r'https?://www\.rtl\.lu/radio/(?:[\w-]+)/s/(?P<id>\d+)(\.html)?'
+    _TESTS = [{
+        'url': 'https://www.rtl.lu/radio/5-vir-12/s/4033058.html',
+        'info_dict': {
+            'id': '4033058',
+            'ext': 'mp3',
+            'description': 'md5:f855a4f3e3235393ae47ed1db5d934b9',
+            'title': '5 vir 12 - Stau um Stau',
+            'thumbnail': 'https://static.rtl.lu/rtlg//2022/06/24/c9c19e5694a14be46a3647a3760e1f62.jpg',
+        }
+    }]


Test patch: