From d7377707e8cd9b60b4732bf066c41ebca2ed72e9 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 17:44:23 +0000 Subject: [PATCH 01/16] Add DzsecurityLiveIE --- yt_dlp/extractor/_extractors.py | 1 + yt_dlp/extractor/dzsecurity.py | 70 +++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 yt_dlp/extractor/dzsecurity.py diff --git a/yt_dlp/extractor/_extractors.py b/yt_dlp/extractor/_extractors.py index 34c98b537..56b518793 100644 --- a/yt_dlp/extractor/_extractors.py +++ b/yt_dlp/extractor/_extractors.py @@ -570,6 +570,7 @@ DWIE, DWArticleIE, ) +from .dzsecurity import DzsecurityLiveIE from .eagleplatform import ( ClipYouEmbedIE, EaglePlatformIE, diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py new file mode 100644 index 000000000..21f9b65e6 --- /dev/null +++ b/yt_dlp/extractor/dzsecurity.py @@ -0,0 +1,70 @@ +from yt_dlp.extractor.common import InfoExtractor +from yt_dlp.utils import ExtractorError +import re +from urllib.parse import urlparse + + +class DzsecurityLiveIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?(echoroukonline|ennaharonline)\.com/live(?:-news)?' + + _TESTS = [{ + 'url': 'https://www.echoroukonline.com/live', + 'info_dict': { + 'id': 'echorouktv', + 'title': r're:البث الحي لقناة الشروق تي في \d{4}-\d{2}-\d{2} \d{2}:\d{2}', + 'ext': 'mp4', + 'live_status': 'is_live', + } + }, { + 'url': 'https://www.echoroukonline.com/live-news', + 'info_dict': { + 'id': 'echorouknews', + 'title': r're:البث الحي لقناة الشروق نيوز - آخر أخبار الجزائر \d{4}-\d{2}-\d{2} \d{2}:\d{2}', + 'ext': 'mp4', + 'live_status': 'is_live', + } + }] + + def _real_extract(self, url): + webpage = self._download_webpage(url, url) + + title_match = re.search(r'(.*?)', webpage, re.IGNORECASE | re.DOTALL) + title = title_match.group(1).strip() if title_match else 'Live Stream' + + player_url_match = re.search( + r'https://live\.dzsecurity\.net/live/player/([a-zA-Z0-9_-]+)', + webpage + ) + if not player_url_match: + raise ExtractorError("Player URL not found in the page") + + player_url = player_url_match.group(0) + stream_id = player_url_match.group(1) + + parsed = urlparse(url) + base_url = f'{parsed.scheme}://{parsed.netloc}' + + headers = { + 'Referer': base_url, + } + + player_page = self._download_webpage(player_url, player_url, headers=headers) + + m3u8_match = re.search( + r'src:\s*location\.protocol\s*\+\s*"(?P//[^"]+\.m3u8\?[^"]+)"', + player_page + ) + if not m3u8_match: + raise ExtractorError("M3U8 stream URL not found in player page") + + m3u8_url = parsed.scheme + ':' + m3u8_match.group('url') + + return { + 'id': stream_id, + 'title': title, + 'formats': self._extract_m3u8_formats( + m3u8_url, stream_id, ext='mp4', entry_protocol='m3u8', + m3u8_id='hls', fatal=True + ), + 'is_live': True, + } From 3bfd03416a606d43b011c4db6cbd7eec1954c5a1 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 17:49:26 +0000 Subject: [PATCH 02/16] Update dzsecurity.py --- yt_dlp/extractor/dzsecurity.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index 21f9b65e6..2e0fc8a45 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -1,8 +1,7 @@ +import re + from yt_dlp.extractor.common import InfoExtractor from yt_dlp.utils import ExtractorError -import re -from urllib.parse import urlparse - class DzsecurityLiveIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?(echoroukonline|ennaharonline)\.com/live(?:-news)?' @@ -41,8 +40,11 @@ def _real_extract(self, url): player_url = player_url_match.group(0) stream_id = player_url_match.group(1) - parsed = urlparse(url) - base_url = f'{parsed.scheme}://{parsed.netloc}' + base_url_match = re.match(r'(https?://[^/]+)', url) + if not base_url_match: + raise ExtractorError("Failed to extract base URL from input URL") + + base_url = base_url_match.group(1) headers = { 'Referer': base_url, @@ -57,7 +59,7 @@ def _real_extract(self, url): if not m3u8_match: raise ExtractorError("M3U8 stream URL not found in player page") - m3u8_url = parsed.scheme + ':' + m3u8_match.group('url') + m3u8_url = 'https:' + m3u8_match.group('url') return { 'id': stream_id, From e08d70064348eb02e2632aa29efd09f91164bfd4 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 17:54:20 +0000 Subject: [PATCH 03/16] Update dzsecurity.py --- yt_dlp/extractor/dzsecurity.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index 2e0fc8a45..be6059485 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -3,6 +3,7 @@ from yt_dlp.extractor.common import InfoExtractor from yt_dlp.utils import ExtractorError + class DzsecurityLiveIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?(echoroukonline|ennaharonline)\.com/live(?:-news)?' @@ -13,7 +14,7 @@ class DzsecurityLiveIE(InfoExtractor): 'title': r're:البث الحي لقناة الشروق تي في \d{4}-\d{2}-\d{2} \d{2}:\d{2}', 'ext': 'mp4', 'live_status': 'is_live', - } + }, }, { 'url': 'https://www.echoroukonline.com/live-news', 'info_dict': { @@ -21,7 +22,7 @@ class DzsecurityLiveIE(InfoExtractor): 'title': r're:البث الحي لقناة الشروق نيوز - آخر أخبار الجزائر \d{4}-\d{2}-\d{2} \d{2}:\d{2}', 'ext': 'mp4', 'live_status': 'is_live', - } + }, }] def _real_extract(self, url): @@ -32,17 +33,17 @@ def _real_extract(self, url): player_url_match = re.search( r'https://live\.dzsecurity\.net/live/player/([a-zA-Z0-9_-]+)', - webpage + webpage, ) if not player_url_match: - raise ExtractorError("Player URL not found in the page") + raise ExtractorError('Player URL not found in the page') player_url = player_url_match.group(0) stream_id = player_url_match.group(1) base_url_match = re.match(r'(https?://[^/]+)', url) if not base_url_match: - raise ExtractorError("Failed to extract base URL from input URL") + raise ExtractorError('Failed to extract base URL from input URL') base_url = base_url_match.group(1) @@ -54,10 +55,10 @@ def _real_extract(self, url): m3u8_match = re.search( r'src:\s*location\.protocol\s*\+\s*"(?P//[^"]+\.m3u8\?[^"]+)"', - player_page + player_page, ) if not m3u8_match: - raise ExtractorError("M3U8 stream URL not found in player page") + raise ExtractorError('M3U8 stream URL not found in player page') m3u8_url = 'https:' + m3u8_match.group('url') @@ -66,7 +67,7 @@ def _real_extract(self, url): 'title': title, 'formats': self._extract_m3u8_formats( m3u8_url, stream_id, ext='mp4', entry_protocol='m3u8', - m3u8_id='hls', fatal=True + m3u8_id='hls', fatal=True, ), 'is_live': True, } From 26ee481f67ea4f76e38196a0ac90907800dd2abd Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:06:15 +0000 Subject: [PATCH 04/16] Update dzsecurity.py --- yt_dlp/extractor/dzsecurity.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index be6059485..c98fcb80c 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -5,7 +5,7 @@ class DzsecurityLiveIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?(echoroukonline|ennaharonline)\.com/live(?:-news)?' + _VALID_URL = r'https?://(?:www\.)?(echoroukonline\.com/live(?:-news)?|ennaharonline\.com/live(?:-news)?|elhayat\.dz/%D8%A7%D9%84%D8%A8%D8%AB-%D8%A7%D9%84%D8%AD%D9%8A)' _TESTS = [{ 'url': 'https://www.echoroukonline.com/live', @@ -23,6 +23,14 @@ class DzsecurityLiveIE(InfoExtractor): 'ext': 'mp4', 'live_status': 'is_live', }, + }, { + 'url': 'https://elhayat.dz/%D8%A7%D9%84%D8%A8%D8%AB-%D8%A7%D9%84%D8%AD%D9%8A', + 'info_dict': { + 'id': 'elhayattv', + 'title': r're:البث الحي - الحياة \d{4}-\d{2}-\d{2} \d{2}:\d{2}', + 'ext': 'mp4', + 'live_status': 'is_live', + }, }] def _real_extract(self, url): From 2edffc72cbf9aedb790e381d9fb7c2a5a90b2f09 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:14:33 +0000 Subject: [PATCH 05/16] Update yt_dlp/extractor/dzsecurity.py Co-authored-by: D Trombett --- yt_dlp/extractor/dzsecurity.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index c98fcb80c..8ebaa71c3 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -11,7 +11,7 @@ class DzsecurityLiveIE(InfoExtractor): 'url': 'https://www.echoroukonline.com/live', 'info_dict': { 'id': 'echorouktv', - 'title': r're:البث الحي لقناة الشروق تي في \d{4}-\d{2}-\d{2} \d{2}:\d{2}', + 'title': r're:البث الحي لقناة الشروق تي في', 'ext': 'mp4', 'live_status': 'is_live', }, @@ -19,7 +19,7 @@ class DzsecurityLiveIE(InfoExtractor): 'url': 'https://www.echoroukonline.com/live-news', 'info_dict': { 'id': 'echorouknews', - 'title': r're:البث الحي لقناة الشروق نيوز - آخر أخبار الجزائر \d{4}-\d{2}-\d{2} \d{2}:\d{2}', + 'title': r're:البث الحي لقناة الشروق نيوز - آخر أخبار الجزائر', 'ext': 'mp4', 'live_status': 'is_live', }, @@ -27,7 +27,7 @@ class DzsecurityLiveIE(InfoExtractor): 'url': 'https://elhayat.dz/%D8%A7%D9%84%D8%A8%D8%AB-%D8%A7%D9%84%D8%AD%D9%8A', 'info_dict': { 'id': 'elhayattv', - 'title': r're:البث الحي - الحياة \d{4}-\d{2}-\d{2} \d{2}:\d{2}', + 'title': r're:البث الحي - الحياة', 'ext': 'mp4', 'live_status': 'is_live', }, From d8f2be5e06aee9645fd7b203aba328e4d5cec223 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:15:00 +0000 Subject: [PATCH 06/16] Update dzsecurity.py --- yt_dlp/extractor/dzsecurity.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index 8ebaa71c3..0dcf09d5f 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -8,6 +8,15 @@ class DzsecurityLiveIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?(echoroukonline\.com/live(?:-news)?|ennaharonline\.com/live(?:-news)?|elhayat\.dz/%D8%A7%D9%84%D8%A8%D8%AB-%D8%A7%D9%84%D8%AD%D9%8A)' _TESTS = [{ + 'url': 'https://www.ennaharonline.com/live', + 'info_dict': { + 'id': 'ennahartv', + 'title': r're:البث الحي لقناة النهار – النهار أونلاين', + 'ext': 'mp4', + 'live_status': 'is_live', + }, + 'skip': 'Geo-restricted to Algeria', + }, { 'url': 'https://www.echoroukonline.com/live', 'info_dict': { 'id': 'echorouktv', From 94f815f2a93dd276258d92989380bbeda13af7aa Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:56:19 +0000 Subject: [PATCH 07/16] Update yt_dlp/extractor/dzsecurity.py Co-authored-by: D Trombett --- yt_dlp/extractor/dzsecurity.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index 0dcf09d5f..8b3f55e8e 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -45,8 +45,7 @@ class DzsecurityLiveIE(InfoExtractor): def _real_extract(self, url): webpage = self._download_webpage(url, url) - title_match = re.search(r'(.*?)', webpage, re.IGNORECASE | re.DOTALL) - title = title_match.group(1).strip() if title_match else 'Live Stream' + title = self._html_extract_title(webpage, default='Live Stream') player_url_match = re.search( r'https://live\.dzsecurity\.net/live/player/([a-zA-Z0-9_-]+)', From bd8498acdae2f65f043df61edd93238d9b5a8842 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:56:58 +0000 Subject: [PATCH 08/16] Update yt_dlp/extractor/dzsecurity.py Co-authored-by: D Trombett --- yt_dlp/extractor/dzsecurity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index 8b3f55e8e..926518948 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -43,7 +43,7 @@ class DzsecurityLiveIE(InfoExtractor): }] def _real_extract(self, url): - webpage = self._download_webpage(url, url) + webpage = self._download_webpage(url, url, impersonate=True) title = self._html_extract_title(webpage, default='Live Stream') From ea4ac61edd1bd0ff34206521913aadf93395b5c5 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:57:52 +0000 Subject: [PATCH 09/16] Update yt_dlp/extractor/dzsecurity.py Co-authored-by: D Trombett --- yt_dlp/extractor/dzsecurity.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index 926518948..f9a5ad9d7 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -47,15 +47,12 @@ def _real_extract(self, url): title = self._html_extract_title(webpage, default='Live Stream') - player_url_match = re.search( + player_url, stream_id = self._html_search_regex( r'https://live\.dzsecurity\.net/live/player/([a-zA-Z0-9_-]+)', webpage, + 'player URL', + group=(0, 1) ) - if not player_url_match: - raise ExtractorError('Player URL not found in the page') - - player_url = player_url_match.group(0) - stream_id = player_url_match.group(1) base_url_match = re.match(r'(https?://[^/]+)', url) if not base_url_match: From 0c6506c9662ed1c984dcb6cf83b624c6f3d02b06 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:58:23 +0000 Subject: [PATCH 10/16] Update yt_dlp/extractor/dzsecurity.py Co-authored-by: D Trombett --- yt_dlp/extractor/dzsecurity.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index f9a5ad9d7..9b889dccb 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -66,14 +66,11 @@ def _real_extract(self, url): player_page = self._download_webpage(player_url, player_url, headers=headers) - m3u8_match = re.search( - r'src:\s*location\.protocol\s*\+\s*"(?P//[^"]+\.m3u8\?[^"]+)"', + m3u8_url = 'https:' + self._search_regex( + r'src:\s*location\.protocol\s*\+\s*"(//[^"]+\.m3u8\?[^"]+)"', player_page, + 'm3u8 URL', ) - if not m3u8_match: - raise ExtractorError('M3U8 stream URL not found in player page') - - m3u8_url = 'https:' + m3u8_match.group('url') return { 'id': stream_id, From 85d55ea522cbf162e4138b55f3613ca25394f3a7 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:59:41 +0000 Subject: [PATCH 11/16] Update yt_dlp/extractor/dzsecurity.py Co-authored-by: D Trombett --- yt_dlp/extractor/dzsecurity.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index 9b889dccb..0ac452d2b 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -75,9 +75,6 @@ def _real_extract(self, url): return { 'id': stream_id, 'title': title, - 'formats': self._extract_m3u8_formats( - m3u8_url, stream_id, ext='mp4', entry_protocol='m3u8', - m3u8_id='hls', fatal=True, - ), + 'formats': self._extract_m3u8_formats(m3u8_url, stream_id), 'is_live': True, } From 5c56c1f0e373aea2a1c25a3f0eb393d79173dd4a Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Wed, 18 Jun 2025 20:02:25 +0000 Subject: [PATCH 12/16] Update dzsecurity.py --- yt_dlp/extractor/dzsecurity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index 0ac452d2b..8435c41f7 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -51,7 +51,7 @@ def _real_extract(self, url): r'https://live\.dzsecurity\.net/live/player/([a-zA-Z0-9_-]+)', webpage, 'player URL', - group=(0, 1) + group=(0, 1), ) base_url_match = re.match(r'(https?://[^/]+)', url) From 736f417e8098d20db6f21a8c6ab61b682c0ac421 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Sun, 22 Jun 2025 18:16:54 +0000 Subject: [PATCH 13/16] Update dzsecurity.py to use _EMBED_REGEX --- yt_dlp/extractor/dzsecurity.py | 104 ++++++++++++++++----------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/yt_dlp/extractor/dzsecurity.py b/yt_dlp/extractor/dzsecurity.py index 8435c41f7..f8c85daa2 100644 --- a/yt_dlp/extractor/dzsecurity.py +++ b/yt_dlp/extractor/dzsecurity.py @@ -1,70 +1,70 @@ -import re +from yt_dlp import traverse_obj from yt_dlp.extractor.common import InfoExtractor -from yt_dlp.utils import ExtractorError +from yt_dlp.utils import smuggle_url, unsmuggle_url class DzsecurityLiveIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?(echoroukonline\.com/live(?:-news)?|ennaharonline\.com/live(?:-news)?|elhayat\.dz/%D8%A7%D9%84%D8%A8%D8%AB-%D8%A7%D9%84%D8%AD%D9%8A)' + _VALID_URL = r'https?://live\.dzsecurity\.net/live/player/(?P[\w-]+)' + _EMBED_REGEX = [rf'