Skip to content

Commit 05b23b4

Browse files
[iq.com] Add VIP support (yt-dlp#2444)
Authored by: MinePlayersPE
1 parent 8f028b5 commit 05b23b4

File tree

1 file changed

+37
-8
lines changed

1 file changed

+37
-8
lines changed

yt_dlp/extractor/iqiyi.py

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
from ..compat import (
1111
compat_str,
1212
compat_urllib_parse_urlencode,
13+
compat_urllib_parse_unquote
1314
)
1415
from .openload import PhantomJSwrapper
1516
from ..utils import (
1617
clean_html,
1718
decode_packed_codes,
1819
ExtractorError,
1920
float_or_none,
21+
format_field,
2022
get_element_by_id,
2123
get_element_by_attribute,
2224
int_or_none,
@@ -431,6 +433,10 @@ class IqIE(InfoExtractor):
431433
'format': '500',
432434
},
433435
'expected_warnings': ['format is restricted']
436+
}, {
437+
# VIP-restricted video
438+
'url': 'https://www.iq.com/play/mermaid-in-the-fog-2021-gbdpx13bs4',
439+
'only_matching': True
434440
}]
435441
_BID_TAGS = {
436442
'100': '240P',
@@ -457,8 +463,8 @@ class IqIE(InfoExtractor):
457463
_DASH_JS = '''
458464
console.log(page.evaluate(function() {
459465
var tvid = "%(tvid)s"; var vid = "%(vid)s"; var src = "%(src)s";
460-
var dfp = "%(dfp)s"; var mode = "%(mode)s"; var lang = "%(lang)s"; var bid_list = %(bid_list)s;
461-
var tm = new Date().getTime();
466+
var uid = "%(uid)s"; var dfp = "%(dfp)s"; var mode = "%(mode)s"; var lang = "%(lang)s";
467+
var bid_list = %(bid_list)s; var ut_list = %(ut_list)s; var tm = new Date().getTime();
462468
var cmd5x_func = %(cmd5x_func)s; var cmd5x_exporter = {}; cmd5x_func({}, cmd5x_exporter, {}); var cmd5x = cmd5x_exporter.cmd5x;
463469
var authKey = cmd5x(cmd5x('') + tm + '' + tvid);
464470
var k_uid = Array.apply(null, Array(32)).map(function() {return Math.floor(Math.random() * 15).toString(16)}).join('');
@@ -472,7 +478,7 @@ class IqIE(InfoExtractor):
472478
'src': src,
473479
'vt': 0,
474480
'rs': 1,
475-
'uid': 0,
481+
'uid': uid,
476482
'ori': 'pcw',
477483
'ps': 1,
478484
'k_uid': k_uid,
@@ -509,12 +515,14 @@ class IqIE(InfoExtractor):
509515
'version': '10.0',
510516
'dfp': dfp
511517
}),
512-
'ut': 0, // TODO: Set ut param for VIP members
513518
};
514519
var enc_params = [];
515520
for (var prop in query) {
516521
enc_params.push(encodeURIComponent(prop) + '=' + encodeURIComponent(query[prop]));
517522
}
523+
ut_list.forEach(function(ut) {
524+
enc_params.push('ut=' + ut);
525+
})
518526
var dash_path = '/dash?' + enc_params.join('&'); dash_path += '&vf=' + cmd5x(dash_path);
519527
dash_paths[bid] = dash_path;
520528
});
@@ -571,17 +579,37 @@ def _real_extract(self, url):
571579
page_data = next_props['initialState']['play']
572580
video_info = page_data['curVideoInfo']
573581

582+
uid = traverse_obj(
583+
self._parse_json(
584+
self._get_cookie('I00002', '{}'), video_id, transform_source=compat_urllib_parse_unquote, fatal=False),
585+
('data', 'uid'), default=0)
586+
587+
if uid:
588+
vip_data = self._download_json(
589+
'https://pcw-api.iq.com/api/vtype', video_id, note='Downloading VIP data', errnote='Unable to download VIP data', query={
590+
'batch': 1,
591+
'platformId': 3,
592+
'modeCode': self._get_cookie('mod', 'intl'),
593+
'langCode': self._get_cookie('lang', 'en_us'),
594+
'deviceId': self._get_cookie('QC005', '')
595+
}, fatal=False)
596+
ut_list = traverse_obj(vip_data, ('data', 'all_vip', ..., 'vipType'), expected_type=str_or_none, default=[])
597+
else:
598+
ut_list = ['0']
599+
574600
# bid 0 as an initial format checker
575601
dash_paths = self._parse_json(PhantomJSwrapper(self).get(
576602
url, html='<!DOCTYPE html>', video_id=video_id, note2='Executing signature code', jscode=self._DASH_JS % {
577603
'tvid': video_info['tvId'],
578604
'vid': video_info['vid'],
579605
'src': traverse_obj(next_props, ('initialProps', 'pageProps', 'ptid'),
580-
expected_type=str, default='01010031010018000000'),
606+
expected_type=str, default='04022001010011000000'),
607+
'uid': uid,
581608
'dfp': self._get_cookie('dfp', ''),
582609
'mode': self._get_cookie('mod', 'intl'),
583610
'lang': self._get_cookie('lang', 'en_us'),
584611
'bid_list': '[' + ','.join(['0', *self._BID_TAGS.keys()]) + ']',
612+
'ut_list': '[' + ','.join(ut_list) + ']',
585613
'cmd5x_func': self._extract_cmd5x_function(webpage, video_id),
586614
})[1].strip(), video_id)
587615

@@ -590,9 +618,10 @@ def _real_extract(self, url):
590618
urljoin('https://cache-video.iq.com', dash_paths['0']), video_id,
591619
note='Downloading initial video format info', errnote='Unable to download initial video format info')['data']
592620

593-
preview_time = traverse_obj(initial_format_data, ('boss_ts', 'data', 'previewTime'), expected_type=float_or_none)
594-
if preview_time:
595-
self.report_warning(f'This preview video is limited to {preview_time} seconds')
621+
preview_time = traverse_obj(
622+
initial_format_data, ('boss_ts', (None, 'data'), ('previewTime', 'rtime')), expected_type=float_or_none, get_all=False)
623+
if traverse_obj(initial_format_data, ('boss_ts', 'data', 'prv'), expected_type=int_or_none):
624+
self.report_warning('This preview video is limited%s' % format_field(preview_time, template='to %s seconds'))
596625

597626
# TODO: Extract audio-only formats
598627
for bid in set(traverse_obj(initial_format_data, ('program', 'video', ..., 'bid'), expected_type=str_or_none, default=[])):

0 commit comments

Comments
 (0)