[generic] Add KVS player extraction
This commit is contained in:
parent
604762a9f8
commit
c2f9be3e63
1 changed files with 183 additions and 0 deletions
|
@ -28,6 +28,7 @@ from ..utils import (
|
||||||
mimetype2ext,
|
mimetype2ext,
|
||||||
orderedSet,
|
orderedSet,
|
||||||
parse_duration,
|
parse_duration,
|
||||||
|
parse_resolution,
|
||||||
sanitized_Request,
|
sanitized_Request,
|
||||||
smuggle_url,
|
smuggle_url,
|
||||||
unescapeHTML,
|
unescapeHTML,
|
||||||
|
@ -2227,6 +2228,97 @@ class GenericIE(InfoExtractor):
|
||||||
# Sibnet embed (https://help.sibnet.ru/?sibnet_video_embed)
|
# Sibnet embed (https://help.sibnet.ru/?sibnet_video_embed)
|
||||||
'url': 'https://phpbb3.x-tk.ru/bbcode-video-sibnet-t24.html',
|
'url': 'https://phpbb3.x-tk.ru/bbcode-video-sibnet-t24.html',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
# KVS Player
|
||||||
|
'url': 'https://www.kvs-demo.com/videos/105/kelis-4th-of-july/',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '105',
|
||||||
|
'display_id': 'kelis-4th-of-july',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Kelis - 4th Of July',
|
||||||
|
'thumbnail': r're:https://(?:www\.)?kvs-demo.com/contents/videos_screenshots/0/105/preview.jpg',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
# KVS Player
|
||||||
|
'url': 'https://www.kvs-demo.com/embed/105/',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '105',
|
||||||
|
'display_id': 'kelis-4th-of-july',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Kelis - 4th Of July / Embed Player',
|
||||||
|
'thumbnail': r're:https://(?:www\.)?kvs-demo.com/contents/videos_screenshots/0/105/preview.jpg',
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
# KVS Player
|
||||||
|
'url': 'https://thisvid.com/videos/fruit-is-healthy/',
|
||||||
|
'md5': 'f83e52f409b9139a7efee58ef926a72e',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '7079579',
|
||||||
|
'display_id': 'fruit-is-healthy',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Fruit is healthy - ThisVid.com',
|
||||||
|
'thumbnail': 'https://media.thisvid.com/contents/videos_screenshots/7079000/7079579/preview.jpg',
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
# KVS Player
|
||||||
|
'url': 'https://thisvid.com/embed/7079579/',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '7079579',
|
||||||
|
'display_id': 'fruit-is-healthy',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Fruit is healthy - ThisVid.com',
|
||||||
|
'thumbnail': 'https://media.thisvid.com/contents/videos_screenshots/7079000/7079579/preview.jpg',
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
# KVS Player
|
||||||
|
'url': 'https://youix.com/video/leningrad-zoj/',
|
||||||
|
'md5': '94f96ba95706dc3880812b27b7d8a2b8',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '18485',
|
||||||
|
'display_id': 'leningrad-zoj',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Клип: Ленинград - ЗОЖ скачать, смотреть онлайн | Youix.com',
|
||||||
|
'thumbnail': r're:https://youix.com/contents/videos_screenshots/18000/18485/preview(?:_480x320_youix_com.mp4)?\.jpg',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
# KVS Player
|
||||||
|
'url': 'https://youix.com/embed/18485',
|
||||||
|
'md5': '94f96ba95706dc3880812b27b7d8a2b8',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '18485',
|
||||||
|
'display_id': 'leningrad-zoj',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Ленинград - ЗОЖ',
|
||||||
|
'thumbnail': r're:https://youix.com/contents/videos_screenshots/18000/18485/preview(?:_480x320_youix_com.mp4)?\.jpg',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
# KVS Player
|
||||||
|
'url': 'https://bogmedia.org/videos/21217/40-nochey-40-nights-2016/',
|
||||||
|
'md5': '94166bdb26b4cb1fb9214319a629fc51',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '21217',
|
||||||
|
'display_id': '40-nochey-2016',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': '40 ночей (2016) - BogMedia.org',
|
||||||
|
'thumbnail': 'https://bogmedia.org/contents/videos_screenshots/21000/21217/preview_480p.mp4.jpg',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
# KVS Player (for sites that serve kt_player.js via non-https urls)
|
||||||
|
'url': 'http://www.camhub.world/embed/389508',
|
||||||
|
'md5': 'fbe89af4cfb59c8fd9f34a202bb03e32',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '389508',
|
||||||
|
'display_id': 'syren-de-mer-onlyfans-05-07-2020have-a-happy-safe-holiday5f014e68a220979bdb8cd-source',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Syren De Mer onlyfans_05-07-2020Have_a_happy_safe_holiday5f014e68a220979bdb8cd_source / Embed плеер',
|
||||||
|
'thumbnail': r're:https?://www\.camhub\.world/contents/videos_screenshots/389000/389508/preview\.mp4\.jpg',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2332,6 +2424,87 @@ class GenericIE(InfoExtractor):
|
||||||
'title': title,
|
'title': title,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _extract_kvs(self, url, webpage, video_id):
|
||||||
|
|
||||||
|
def getlicensetoken(license):
|
||||||
|
modlicense = license.replace('$', '').replace('0', '1')
|
||||||
|
center = int(len(modlicense) / 2)
|
||||||
|
fronthalf = int(modlicense[:center + 1])
|
||||||
|
backhalf = int(modlicense[center:])
|
||||||
|
|
||||||
|
modlicense = compat_str(4 * abs(fronthalf - backhalf))
|
||||||
|
|
||||||
|
def parts():
|
||||||
|
for o in range(0, center + 1):
|
||||||
|
for i in range(1, 5):
|
||||||
|
yield compat_str((int(license[o + i]) + int(modlicense[o])) % 10)
|
||||||
|
|
||||||
|
return ''.join(parts())
|
||||||
|
|
||||||
|
def getrealurl(video_url, license_code):
|
||||||
|
if not video_url.startswith('function/0/'):
|
||||||
|
return video_url # not obfuscated
|
||||||
|
|
||||||
|
url_path, _, url_query = video_url.partition('?')
|
||||||
|
urlparts = url_path.split('/')[2:]
|
||||||
|
license = getlicensetoken(license_code)
|
||||||
|
newmagic = urlparts[5][:32]
|
||||||
|
|
||||||
|
def spells(x, o):
|
||||||
|
l = (o + sum(int(n) for n in license[o:])) % 32
|
||||||
|
for i in range(0, len(x)):
|
||||||
|
yield {l: x[o], o: x[l]}.get(i, x[i])
|
||||||
|
|
||||||
|
for o in range(len(newmagic) - 1, -1, -1):
|
||||||
|
newmagic = ''.join(spells(newmagic, o))
|
||||||
|
|
||||||
|
urlparts[5] = newmagic + urlparts[5][32:]
|
||||||
|
return '/'.join(urlparts) + '?' + url_query
|
||||||
|
|
||||||
|
flashvars = self._search_regex(
|
||||||
|
r'(?s)<script\b[^>]*>.*?var\s+flashvars\s*=\s*(\{.+?\});.*?</script>',
|
||||||
|
webpage, 'flashvars')
|
||||||
|
flashvars = self._parse_json(flashvars, video_id, transform_source=js_to_json)
|
||||||
|
|
||||||
|
# extract the part after the last / as the display_id from the
|
||||||
|
# canonical URL.
|
||||||
|
display_id = self._search_regex(
|
||||||
|
r'(?:<link href="https?://[^"]+/(.+?)/?" rel="canonical"\s*/?>'
|
||||||
|
r'|<link rel="canonical" href="https?://[^"]+/(.+?)/?"\s*/?>)',
|
||||||
|
webpage, 'display_id', fatal=False
|
||||||
|
)
|
||||||
|
title = self._html_search_regex(r'<(?:h1|title)>(?:Video: )?(.+?)</(?:h1|title)>', webpage, 'title')
|
||||||
|
|
||||||
|
thumbnail = flashvars['preview_url']
|
||||||
|
if thumbnail.startswith('//'):
|
||||||
|
protocol, _, _ = url.partition('/')
|
||||||
|
thumbnail = protocol + thumbnail
|
||||||
|
|
||||||
|
url_keys = list(filter(re.compile(r'^video_(?:url|alt_url\d*)$').match, flashvars.keys()))
|
||||||
|
formats = []
|
||||||
|
for key in url_keys:
|
||||||
|
if '/get_file/' not in flashvars[key]:
|
||||||
|
continue
|
||||||
|
format_id = flashvars.get(key + '_text', key)
|
||||||
|
formats.append(merge_dicts(
|
||||||
|
parse_resolution(format_id) or parse_resolution(flashvars[key]), {
|
||||||
|
'url': getrealurl(flashvars[key], flashvars['license_code']),
|
||||||
|
'format_id': format_id,
|
||||||
|
'ext': 'mp4',
|
||||||
|
}))
|
||||||
|
if not formats[-1].get('height'):
|
||||||
|
formats[-1]['quality'] = 1
|
||||||
|
|
||||||
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'id': flashvars['video_id'],
|
||||||
|
'display_id': display_id,
|
||||||
|
'title': title,
|
||||||
|
'thumbnail': thumbnail,
|
||||||
|
'formats': formats,
|
||||||
|
}
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
if url.startswith('//'):
|
if url.startswith('//'):
|
||||||
return self.url_result(self.http_scheme() + url)
|
return self.url_result(self.http_scheme() + url)
|
||||||
|
@ -3389,6 +3562,16 @@ class GenericIE(InfoExtractor):
|
||||||
info_dict['formats'] = formats
|
info_dict['formats'] = formats
|
||||||
return info_dict
|
return info_dict
|
||||||
|
|
||||||
|
# Look for generic KVS player (before ld+json for tests)
|
||||||
|
found = re.search(
|
||||||
|
r'<script\b[^>]+?\bsrc\s*=\s*(["\'])https?://(?:\S+?/)+kt_player\.js\?v=(?P<ver>(?P<maj_ver>\d+)(\.\d+)+)\1[^>]*>',
|
||||||
|
webpage)
|
||||||
|
if found:
|
||||||
|
self.report_extraction('KVS Player')
|
||||||
|
if found.group('maj_ver') not in ('4', '5', '6'):
|
||||||
|
self.report_warning('Untested major version (%s) in player engine - download may fail.' % (found.group('ver'), ))
|
||||||
|
return self._extract_kvs(url, webpage, video_id)
|
||||||
|
|
||||||
# Looking for http://schema.org/VideoObject
|
# Looking for http://schema.org/VideoObject
|
||||||
json_ld = self._search_json_ld(
|
json_ld = self._search_json_ld(
|
||||||
webpage, video_id, default={}, expected_type='VideoObject')
|
webpage, video_id, default={}, expected_type='VideoObject')
|
||||||
|
|
Loading…
Reference in a new issue