@@ -25,12 +25,12 @@ def _handle_errors(self, result):
25
25
raise ExtractorError (
26
26
'%s said: %s' % (self .IE_NAME , error ), expected = True )
27
27
28
- def _call_api (self , path , video_id ):
28
+ def _call_api (self , path , video_id , query = None ):
29
29
headers = {}
30
30
if self ._auth_token :
31
31
headers ['X-Auth-Token' ] = self ._auth_token
32
32
result = self ._download_json (
33
- self ._API_BASE_URL + path , video_id , headers = headers )
33
+ self ._API_BASE_URL + path , video_id , headers = headers , query = query )
34
34
self ._handle_errors (result )
35
35
return result ['data' ]
36
36
@@ -52,62 +52,75 @@ class CuriosityStreamIE(CuriosityStreamBaseIE):
52
52
_VALID_URL = r'https?://(?:app\.)?curiositystream\.com/video/(?P<id>\d+)'
53
53
_TEST = {
54
54
'url' : 'https://app.curiositystream.com/video/2' ,
55
- 'md5' : '262bb2f257ff301115f1973540de8983' ,
56
55
'info_dict' : {
57
56
'id' : '2' ,
58
57
'ext' : 'mp4' ,
59
58
'title' : 'How Did You Develop The Internet?' ,
60
59
'description' : 'Vint Cerf, Google\' s Chief Internet Evangelist, describes how he and Bob Kahn created the internet.' ,
61
- }
60
+ },
61
+ 'params' : {
62
+ 'format' : 'bestvideo' ,
63
+ # m3u8 download
64
+ 'skip_download' : True ,
65
+ },
62
66
}
63
67
64
68
def _real_extract (self , url ):
65
69
video_id = self ._match_id (url )
66
- media = self ._call_api ('media/' + video_id , video_id )
67
- title = media ['title' ]
68
70
69
71
formats = []
70
- for encoding in media .get ('encodings' , []):
71
- m3u8_url = encoding .get ('master_playlist_url' )
72
- if m3u8_url :
73
- formats .extend (self ._extract_m3u8_formats (
74
- m3u8_url , video_id , 'mp4' , 'm3u8_native' ,
75
- m3u8_id = 'hls' , fatal = False ))
76
- encoding_url = encoding .get ('url' )
77
- file_url = encoding .get ('file_url' )
78
- if not encoding_url and not file_url :
79
- continue
80
- f = {
81
- 'width' : int_or_none (encoding .get ('width' )),
82
- 'height' : int_or_none (encoding .get ('height' )),
83
- 'vbr' : int_or_none (encoding .get ('video_bitrate' )),
84
- 'abr' : int_or_none (encoding .get ('audio_bitrate' )),
85
- 'filesize' : int_or_none (encoding .get ('size_in_bytes' )),
86
- 'vcodec' : encoding .get ('video_codec' ),
87
- 'acodec' : encoding .get ('audio_codec' ),
88
- 'container' : encoding .get ('container_type' ),
89
- }
90
- for f_url in (encoding_url , file_url ):
91
- if not f_url :
72
+ for encoding_format in ('m3u8' , 'mpd' ):
73
+ media = self ._call_api ('media/' + video_id , video_id , query = {
74
+ 'encodingsNew' : 'true' ,
75
+ 'encodingsFormat' : encoding_format ,
76
+ })
77
+ for encoding in media .get ('encodings' , []):
78
+ playlist_url = encoding .get ('master_playlist_url' )
79
+ if encoding_format == 'm3u8' :
80
+ # use `m3u8` entry_protocol until EXT-X-MAP is properly supported by `m3u8_native` entry_protocol
81
+ formats .extend (self ._extract_m3u8_formats (
82
+ playlist_url , video_id , 'mp4' ,
83
+ m3u8_id = 'hls' , fatal = False ))
84
+ elif encoding_format == 'mpd' :
85
+ formats .extend (self ._extract_mpd_formats (
86
+ playlist_url , video_id , mpd_id = 'dash' , fatal = False ))
87
+ encoding_url = encoding .get ('url' )
88
+ file_url = encoding .get ('file_url' )
89
+ if not encoding_url and not file_url :
92
90
continue
93
- fmt = f .copy ()
94
- rtmp = re .search (r'^(?P<url>rtmpe?://(?P<host>[^/]+)/(?P<app>.+))/(?P<playpath>mp[34]:.+)$' , f_url )
95
- if rtmp :
96
- fmt .update ({
97
- 'url' : rtmp .group ('url' ),
98
- 'play_path' : rtmp .group ('playpath' ),
99
- 'app' : rtmp .group ('app' ),
100
- 'ext' : 'flv' ,
101
- 'format_id' : 'rtmp' ,
102
- })
103
- else :
104
- fmt .update ({
105
- 'url' : f_url ,
106
- 'format_id' : 'http' ,
107
- })
108
- formats .append (fmt )
91
+ f = {
92
+ 'width' : int_or_none (encoding .get ('width' )),
93
+ 'height' : int_or_none (encoding .get ('height' )),
94
+ 'vbr' : int_or_none (encoding .get ('video_bitrate' )),
95
+ 'abr' : int_or_none (encoding .get ('audio_bitrate' )),
96
+ 'filesize' : int_or_none (encoding .get ('size_in_bytes' )),
97
+ 'vcodec' : encoding .get ('video_codec' ),
98
+ 'acodec' : encoding .get ('audio_codec' ),
99
+ 'container' : encoding .get ('container_type' ),
100
+ }
101
+ for f_url in (encoding_url , file_url ):
102
+ if not f_url :
103
+ continue
104
+ fmt = f .copy ()
105
+ rtmp = re .search (r'^(?P<url>rtmpe?://(?P<host>[^/]+)/(?P<app>.+))/(?P<playpath>mp[34]:.+)$' , f_url )
106
+ if rtmp :
107
+ fmt .update ({
108
+ 'url' : rtmp .group ('url' ),
109
+ 'play_path' : rtmp .group ('playpath' ),
110
+ 'app' : rtmp .group ('app' ),
111
+ 'ext' : 'flv' ,
112
+ 'format_id' : 'rtmp' ,
113
+ })
114
+ else :
115
+ fmt .update ({
116
+ 'url' : f_url ,
117
+ 'format_id' : 'http' ,
118
+ })
119
+ formats .append (fmt )
109
120
self ._sort_formats (formats )
110
121
122
+ title = media ['title' ]
123
+
111
124
subtitles = {}
112
125
for closed_caption in media .get ('closed_captions' , []):
113
126
sub_url = closed_caption .get ('file' )
@@ -140,7 +153,7 @@ class CuriosityStreamCollectionIE(CuriosityStreamBaseIE):
140
153
'title' : 'Curious Minds: The Internet' ,
141
154
'description' : 'How is the internet shaping our lives in the 21st Century?' ,
142
155
},
143
- 'playlist_mincount' : 17 ,
156
+ 'playlist_mincount' : 16 ,
144
157
}, {
145
158
'url' : 'https://curiositystream.com/series/2' ,
146
159
'only_matching' : True ,
0 commit comments