From 15d91f99caf70e7573fd28e07f7770595b1b3876 Mon Sep 17 00:00:00 2001 From: kclauhk <78251477+kclauhk@users.noreply.github.com> Date: Sat, 17 Aug 2024 23:36:49 +0800 Subject: [PATCH 1/3] [ie/piramidetv] Add extractor --- yt_dlp/extractor/_extractors.py | 5 ++ yt_dlp/extractor/piramidetv.py | 112 ++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 yt_dlp/extractor/piramidetv.py diff --git a/yt_dlp/extractor/_extractors.py b/yt_dlp/extractor/_extractors.py index 9b73fcd75e..d355449188 100644 --- a/yt_dlp/extractor/_extractors.py +++ b/yt_dlp/extractor/_extractors.py @@ -1522,6 +1522,11 @@ PinterestCollectionIE, PinterestIE, ) +from .piramidetv import ( + PiramideTVChannelIE, + PiramideTVChannelURLIE, + PiramideTVIE, +) from .pixivsketch import ( PixivSketchIE, PixivSketchUserIE, diff --git a/yt_dlp/extractor/piramidetv.py b/yt_dlp/extractor/piramidetv.py new file mode 100644 index 0000000000..114aee39a4 --- /dev/null +++ b/yt_dlp/extractor/piramidetv.py @@ -0,0 +1,112 @@ +from .common import InfoExtractor, SearchInfoExtractor +from ..utils import ( + traverse_obj, + unified_timestamp, + url_or_none, +) + + +class PiramideTVIE(InfoExtractor): + _VALID_URL = r'https?://piramide\.tv/video/(?P[\w-]+)' + _TESTS = [{ + 'url': 'https://piramide.tv/video/wWtBAORdJUTh', + 'info_dict': { + 'id': 'wWtBAORdJUTh', + 'ext': 'mp4', + 'title': 'md5:79f9c8183ea6a35c836923142cf0abcc', + 'description': '', + 'thumbnail': 'https://cdn.jwplayer.com/v2/media/W86PgQDn/thumbnails/B9gpIxkH.jpg', + 'channel': 'León Picarón', + 'channel_id': 'leonpicaron', + 'timestamp': 1696460362, + 'upload_date': '20231004', + }, + }, { + 'url': 'https://piramide.tv/video/wcYn6li79NgN', + 'info_dict': { + 'id': 'wcYn6li79NgN', + 'title': 'ACEPTO TENER UN BEBE CON MI NOVIA\u2026? | Parte 1', + 'description': '', + 'channel': 'ARTA GAME', + 'channel_id': 'arta_game', + }, + 'playlist_count': 4, + }] + + def _real_extract(self, url): + def extract_video(video_id, fatal=False): + video_data = self._download_json(f'https://hermes.piramide.tv/video/data/{video_id}', + video_id, fatal=fatal) + formats, subtitles = self._extract_m3u8_formats_and_subtitles( + f'https://cdn.piramide.tv/video/{video_id}/manifest.m3u8', video_id, fatal=fatal) + video_info = {**traverse_obj(video_data, { + 'id': ('video', 'id', {str}), + 'title': ('video', 'title', {str}), + 'description': ('video', 'description', {str}), + 'thumbnail': ('video', 'media', 'thumbnail', {url_or_none}), + 'channel': ('video', 'channel', 'name', {str}), + 'channel_id': ('video', 'channel', 'id', {str}), + 'timestamp': ('video', 'date', {unified_timestamp}), + }), + 'formats': formats, + 'subtitles': subtitles, + } + next_video_id = traverse_obj(video_data, ('video', 'next_video', 'id', {str})) + return video_info, next_video_id + + video_id = self._match_id(url) + entries = [] + while video_id is not None: + video, next_video = extract_video(video_id, (not entries)) + if video.get('formats'): + entries.append(video) + if next_video != video_id: + video_id = next_video + + if len(entries) == 1: + return entries[0] + elif len(entries) > 1: + return self.playlist_result(entries, **traverse_obj(entries[0], { + 'id': ('id'), + 'title': ('title'), + 'description': ('description'), + 'channel': ('channel'), + 'channel_id': ('channel_id'), + })) + else: + return {'id': video_id} + + +class PiramideTVChannelURLIE(InfoExtractor): + _VALID_URL = r'https?://piramide\.tv/channel/(?P[\w-]+)' + _TESTS = [{ + 'url': 'https://piramide.tv/channel/thekalo', + 'playlist_count': 10, + 'info_dict': { + 'id': 'thekalo', + 'title': 'thekalo', + }, + }] + + def _real_extract(self, url): + if query := self._match_id(url): + return self.url_result(url=f'piramidetvall:{query}', url_transparent=True) + + +class PiramideTVChannelIE(SearchInfoExtractor): + IE_NAME = 'PiramideTV:channel' + _SEARCH_KEY = 'piramidetv' + _TESTS = [{ + 'url': 'piramidetv5:bobicraft', + 'playlist_count': 5, + 'info_dict': { + 'id': 'bobicraft', + 'title': 'bobicraft', + }, + }] + + def _search_results(self, query): + videos = self._download_json(f'https://hermes.piramide.tv/channel/list/{query}/date/100000', query) + for video in videos.get('videos'): + if video_id := video.get('id'): + yield self.url_result(f'https://piramide.tv/video/{video_id}') From 1c5d9b91f5391c435b1e0c7695a6d85ad825ed97 Mon Sep 17 00:00:00 2001 From: kclauhk <78251477+kclauhk@users.noreply.github.com> Date: Sun, 18 Aug 2024 00:21:17 +0800 Subject: [PATCH 2/3] Update piramidetv.py --- yt_dlp/extractor/piramidetv.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/yt_dlp/extractor/piramidetv.py b/yt_dlp/extractor/piramidetv.py index 114aee39a4..d94379282e 100644 --- a/yt_dlp/extractor/piramidetv.py +++ b/yt_dlp/extractor/piramidetv.py @@ -60,8 +60,7 @@ def extract_video(video_id, fatal=False): video, next_video = extract_video(video_id, (not entries)) if video.get('formats'): entries.append(video) - if next_video != video_id: - video_id = next_video + video_id = next_video if next_video != video_id else None if len(entries) == 1: return entries[0] From 26d876f972e4be4a0f6300aae21cdb7b78430202 Mon Sep 17 00:00:00 2001 From: kclauhk <78251477+kclauhk@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:30:48 +0800 Subject: [PATCH 3/3] add webpage_url, webpage_url_basename --- yt_dlp/extractor/piramidetv.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yt_dlp/extractor/piramidetv.py b/yt_dlp/extractor/piramidetv.py index d94379282e..ed7de211d5 100644 --- a/yt_dlp/extractor/piramidetv.py +++ b/yt_dlp/extractor/piramidetv.py @@ -50,6 +50,8 @@ def extract_video(video_id, fatal=False): }), 'formats': formats, 'subtitles': subtitles, + 'webpage_url': f'https://piramide.tv/video/{video_id}', + 'webpage_url_basename': video_id, } next_video_id = traverse_obj(video_data, ('video', 'next_video', 'id', {str})) return video_info, next_video_id