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'