1
- import re
2
-
3
- from .common import InfoExtractor , SearchInfoExtractor
4
- from ..utils import (
5
- parse_iso8601 ,
6
- traverse_obj ,
7
- url_or_none ,
8
- )
1
+ from .common import InfoExtractor
2
+ from ..utils import parse_iso8601 , smuggle_url , unsmuggle_url , url_or_none
3
+ from ..utils .traversal import traverse_obj
9
4
10
5
11
6
class PiramideTVIE (InfoExtractor ):
@@ -27,21 +22,27 @@ class PiramideTVIE(InfoExtractor):
27
22
'url' : 'https://piramide.tv/video/wcYn6li79NgN' ,
28
23
'info_dict' : {
29
24
'id' : 'wcYn6li79NgN' ,
30
- 'title' : 'ACEPTO TENER UN BEBE CON MI NOVIA\u2026 ?' ,
25
+ 'ext' : 'mp4' ,
26
+ 'title' : 'ACEPTO TENER UN BEBE CON MI NOVIA\u2026 ? | Parte 1' ,
31
27
'description' : '' ,
32
28
'channel' : 'ARTA GAME' ,
33
29
'channel_id' : 'arta_game' ,
30
+ 'thumbnail' : 'https://cdn.jwplayer.com/v2/media/cnEdGp5X/thumbnails/rHAaWfP7.jpg' ,
31
+ 'timestamp' : 1703434976 ,
32
+ 'upload_date' : '20231224' ,
34
33
},
35
- 'playlist_count' : 4 ,
36
34
}]
37
35
38
- def _extract_video (self , video_id , fatal = True ):
36
+ def _extract_video (self , video_id ):
39
37
video_data = self ._download_json (
40
- f'https://hermes.piramide.tv/video/data/{ video_id } ' , video_id , fatal = fatal )
38
+ f'https://hermes.piramide.tv/video/data/{ video_id } ' , video_id , fatal = False )
41
39
formats , subtitles = self ._extract_m3u8_formats_and_subtitles (
42
- f'https://cdn.piramide.tv/video/{ video_id } /manifest.m3u8' , video_id , fatal = fatal )
43
- video_dict = {
40
+ f'https://cdn.piramide.tv/video/{ video_id } /manifest.m3u8' , video_id , fatal = False )
41
+ next_video = traverse_obj (video_data , ('video' , 'next_video' , 'id' , {str }))
42
+ return next_video , {
44
43
'id' : video_id ,
44
+ 'formats' : formats ,
45
+ 'subtitles' : subtitles ,
45
46
** traverse_obj (video_data , ('video' , {
46
47
'id' : ('id' , {str }),
47
48
'title' : ('title' , {str }),
@@ -51,77 +52,48 @@ def _extract_video(self, video_id, fatal=True):
51
52
'channel_id' : ('channel' , 'id' , {str }),
52
53
'timestamp' : ('date' , {parse_iso8601 }),
53
54
})),
54
- 'formats' : formats ,
55
- 'subtitles' : subtitles ,
56
- 'webpage_url' : f'https://piramide.tv/video/{ video_id } ' ,
57
- 'webpage_url_basename' : video_id ,
58
55
}
59
- next_video_id = traverse_obj (video_data , ('video' , 'next_video' , 'id' , {str }))
60
- return video_dict , next_video_id
61
56
62
- def _entries (self , video , video_id ):
63
- if video :
64
- yield video
65
- while video_id is not None :
66
- video , next_video_id = self ._extract_video (video_id , False )
67
- if video .get ('formats' ):
68
- yield video
69
- video_id = next_video_id if next_video_id != video_id else None
57
+ def _entries (self , video_id ):
58
+ visited = set ()
59
+ while True :
60
+ next_video , info = self ._extract_video (video_id )
61
+ yield info
62
+ if not next_video or next_video in visited :
63
+ break
64
+ visited .add (next_video )
65
+ video_id = next_video
70
66
71
67
def _real_extract (self , url ):
68
+ url , smuggled_data = unsmuggle_url (url , {})
72
69
video_id = self ._match_id (url )
73
- video , next_video_id = self ._extract_video (video_id )
74
- if next_video_id and self ._yes_playlist (video_id , video_id ):
75
- return self .playlist_result (self ._entries (video , next_video_id ),
76
- ** traverse_obj (video , {
77
- 'id' : ('id' , {str }),
78
- 'title' : ('title' , {str }, {lambda x : re .split (r'\s+\|?\s*Parte\s*\d' , x ,
79
- flags = re .IGNORECASE )[0 ]}),
80
- 'description' : ('description' , {str }),
81
- 'channel' : ('channel' , {str }),
82
- 'channel_id' : ('channel_id' , {str }),
83
- }))
84
- return video
70
+ if self ._yes_playlist (video_id , video_id , smuggled_data ):
71
+ return self .playlist_result (self ._entries (video_id ), video_id )
72
+ return self ._extract_video (video_id )[1 ]
85
73
86
74
87
- class PiramideTVChannelURLIE (InfoExtractor ):
75
+ class PiramideTVChannelIE (InfoExtractor ):
88
76
_VALID_URL = r'https?://piramide\.tv/channel/(?P<id>[\w-]+)'
89
77
_TESTS = [{
90
78
'url' : 'https://piramide.tv/channel/thekalo' ,
91
- 'playlist_count ' : 10 ,
79
+ 'playlist_mincount ' : 10 ,
92
80
'info_dict' : {
93
81
'id' : 'thekalo' ,
94
- 'title' : 'thekalo' ,
95
- },
96
- }]
97
-
98
- def _real_extract (self , url ):
99
- if channel_id := self ._match_id (url ):
100
- return self .url_result (url = f'piramidetvall:{ channel_id } ' , url_transparent = True )
101
-
102
-
103
- class PiramideTVChannelIE (SearchInfoExtractor ):
104
- IE_NAME = 'PiramideTV:channel'
105
- _SEARCH_KEY = 'piramidetv'
106
- _TESTS = [{
107
- 'url' : 'piramidetv5:bobicraft' ,
108
- 'playlist_count' : 5 ,
109
- 'info_dict' : {
110
- 'id' : 'bobicraft' ,
111
- 'title' : 'bobicraft' ,
112
82
},
113
83
}]
114
84
115
- def _search_results (self , channel_id ):
85
+ def _entries (self , channel_name ):
116
86
videos = self ._download_json (
117
- f'https://hermes.piramide.tv/channel/list/{ channel_id } /date/100000' , channel_id )
118
- for video in videos .get ('videos' , []):
119
- if video_id := video .get ('id' ):
120
- yield self .url_result (f'https://piramide.tv/video/{ video_id } ' ,
121
- ** traverse_obj (video , {
122
- 'title' : ('title' , {str }),
123
- 'description' : ('description' , {str }),
124
- 'thumbnail' : ('media' , 'thumbnail' , {url_or_none }),
125
- 'channel' : ('channel' , 'name' , {str }),
126
- 'channel_id' : ('channel' , 'id' , {str }),
127
- }))
87
+ f'https://hermes.piramide.tv/channel/list/{ channel_name } /date/100000' , channel_name )
88
+ for video in traverse_obj (videos , ('videos' , lambda _ , v : v ['id' ])):
89
+ yield self .url_result (smuggle_url (
90
+ f"https://piramide.tv/video/{ video ['id' ]} " , {'force_noplaylist' : True }),
91
+ ** traverse_obj (video , {
92
+ 'id' : ('id' , {str }),
93
+ 'title' : ('title' , {str }),
94
+ 'description' : ('description' , {str }),
95
+ }))
96
+
97
+ def _real_extract (self , url ):
98
+ channel_name = self ._match_id (url )
99
+ return self .playlist_result (self ._entries (channel_name ), channel_name )
0 commit comments