mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-12-06 06:45:00 +01:00
Merge aa3b71ca79 into 7ec6b9bc40
This commit is contained in:
commit
9488613901
2 changed files with 109 additions and 0 deletions
|
|
@ -607,6 +607,7 @@ from .ettutv import EttuTvIE
|
|||
from .europa import (
|
||||
EuropaIE,
|
||||
EuroParlWebstreamIE,
|
||||
EuropeanCommissionIE,
|
||||
)
|
||||
from .europeantour import EuropeanTourIE
|
||||
from .eurosport import EurosportIE
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import datetime
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..utils import (
|
||||
int_or_none,
|
||||
|
|
@ -188,3 +190,109 @@ class EuroParlWebstreamIE(InfoExtractor):
|
|||
'release_timestamp': parse_iso8601(json_info.get('startDateTime')),
|
||||
'is_live': traverse_obj(webpage_nextjs, ('mediaItem', 'mediaSubType')) == 'Live',
|
||||
}
|
||||
|
||||
|
||||
class EuropeanCommissionIE(InfoExtractor):
|
||||
_VALID_URL = r'https?://webcast\.ec\.europa\.eu/(?P<id>[^/?#&]+)'
|
||||
QUALITIES = {
|
||||
'low': {
|
||||
'width': 426,
|
||||
'height': 240,
|
||||
'quality': 1,
|
||||
},
|
||||
'medium': {
|
||||
'width': 854,
|
||||
'height': 480,
|
||||
'quality': 2,
|
||||
},
|
||||
'high': {
|
||||
'width': 1280,
|
||||
'height': 720,
|
||||
'quality': 3,
|
||||
},
|
||||
}
|
||||
_TESTS = [{
|
||||
'url': 'https://webcast.ec.europa.eu/2nd-dma-enforcement-workshop-apple-update-on-first-year-of-dma-compliance-2025-06-30',
|
||||
'md5': 'ba9eefc2bb245a95854d23b222697d1f',
|
||||
'info_dict': {
|
||||
'id': '2nd-dma-enforcement-workshop-apple-update-on-first-year-of-dma-compliance-2025-06-30',
|
||||
'ext': 'mp4',
|
||||
'title': '2nd DMA enforcement workshop: Apple - Update on first year of DMA compliance',
|
||||
'release_date': '20250630',
|
||||
'release_timestamp': 1751268600,
|
||||
},
|
||||
}, {
|
||||
'url': 'https://webcast.ec.europa.eu/2nd-dma-enforcement-workshop-alphabet-update-on-first-year-of-dma-compliance-2025-07-01',
|
||||
'md5': '5d5b1b4e6365ac51daa84d8920491af0',
|
||||
'info_dict': {
|
||||
'id': '2nd-dma-enforcement-workshop-alphabet-update-on-first-year-of-dma-compliance-2025-07-01',
|
||||
'ext': 'mp4',
|
||||
'title': '2nd DMA enforcement workshop: Alphabet - Update on first year of DMA compliance',
|
||||
'release_date': '20250701',
|
||||
'release_timestamp': 1751355000,
|
||||
},
|
||||
}, {
|
||||
'url': 'https://webcast.ec.europa.eu/high-level-launch-of-the-young-citizens-assembly-on-pollinators-2025-09-27',
|
||||
'info_dict': {
|
||||
'id': 'high-level-launch-of-the-young-citizens-assembly-on-pollinators-2025-09-27',
|
||||
'ext': 'mp4',
|
||||
'title': r're:HIGH-LEVEL LAUNCH OF THE YOUNG CITIZENS ASSEMBLY ON POLLINATORS 2025-09-27',
|
||||
'release_date': '20250927',
|
||||
'release_timestamp': 1758983400,
|
||||
'live_status': 'is_live',
|
||||
},
|
||||
'skip': 'live stream',
|
||||
}]
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id = self._match_id(url)
|
||||
playlist_data = self._download_json(
|
||||
'https://webcast.ec.europa.eu/session_playlist', video_id, 'Downloading session playlist JSON',
|
||||
query={'reference': video_id})
|
||||
session_data = self._download_json(
|
||||
'https://webcast.ec.europa.eu/session_by_reference', video_id, 'Downloading session data',
|
||||
query={'reference': video_id})['data']
|
||||
formats = []
|
||||
for playlist in traverse_obj(playlist_data, ('playlists', ..., 'playlist', ...)):
|
||||
smil = traverse_obj(playlist, ('source', 'smil'))
|
||||
if (isinstance(smil, str)):
|
||||
formats.extend(self._extract_m3u8_formats(
|
||||
f'https://{playlist_data["server"]}/{playlist_data["application"]}/smil:{smil}/playlist.m3u8',
|
||||
video_id, m3u8_id='smil'))
|
||||
else:
|
||||
for lang, name in dict.items(smil or {}):
|
||||
if (lang == 'or'):
|
||||
formats.extend(self._extract_m3u8_formats(
|
||||
f'https://{playlist_data["server"]}/{playlist_data["application"]}/{name}/playlist.m3u8',
|
||||
video_id, m3u8_id='smil'))
|
||||
else:
|
||||
formats.append({**self._m3u8_meta_format(
|
||||
f'https://{playlist_data["server"]}/{playlist_data["application"]}/{name}/playlist.m3u8',
|
||||
'mp4', m3u8_id=f'smil-{lang}'), 'language': lang})
|
||||
for quality, value in traverse_obj(playlist, ('source', 'qualities', {dict.items})):
|
||||
if (isinstance(value, str)):
|
||||
formats.extend(self._extract_m3u8_formats(
|
||||
f'https://{playlist_data["server"]}/{playlist_data["application"]}/{value}/playlist.m3u8',
|
||||
video_id, m3u8_id=quality, quality=self.QUALITIES.get(quality, {}).get('quality')))
|
||||
else:
|
||||
for lang, name in dict.items(value or {}):
|
||||
if (lang == 'or'):
|
||||
formats.extend(self._extract_m3u8_formats(
|
||||
f'https://{playlist_data["server"]}/{playlist_data["application"]}/{name}/playlist.m3u8',
|
||||
video_id, m3u8_id=quality, quality=self.QUALITIES.get(quality, {}).get('quality')))
|
||||
else:
|
||||
formats.append({**self._m3u8_meta_format(
|
||||
f'https://{playlist_data["server"]}/{playlist_data["application"]}/{name}/playlist.m3u8',
|
||||
'mp4', m3u8_id=f'{quality}-{lang}'), 'language': lang, **self.QUALITIES.get(quality, {})})
|
||||
status = traverse_obj(session_data, ('channels', ..., 'status'), get_all=False)
|
||||
if (status == 'planned'):
|
||||
self.raise_no_formats('This live broadcast has not yet started', expected=True)
|
||||
|
||||
return {
|
||||
'id': video_id,
|
||||
'title': session_data.get('name'),
|
||||
'description': session_data.get('description') or None,
|
||||
'release_timestamp': parse_iso8601(session_data.get('startDateTime'), ' ', datetime.timedelta(hours=2)),
|
||||
'formats': formats,
|
||||
'live_status': 'is_live' if status == 'live' else 'is_upcoming' if status == 'planned' else None,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue