1
0
mirror of https://codeberg.org/polarisfm/youtube-dl synced 2024-11-26 10:24:33 +01:00

[BiliBili] fit all test

This commit is contained in:
zwb 2020-05-18 11:05:49 +08:00
parent c35bdd1b8e
commit 4f8d365d88

View File

@ -6,21 +6,11 @@ import re
from datetime import datetime from datetime import datetime
from .common import InfoExtractor from .common import InfoExtractor
from ..compat import (
compat_parse_qs,
compat_urlparse,
)
from ..utils import ( from ..utils import (
ExtractorError, ExtractorError,
int_or_none, int_or_none,
float_or_none, float_or_none,
parse_iso8601,
smuggle_url,
str_or_none, str_or_none,
strip_jsonp,
unified_timestamp,
unsmuggle_url,
urlencode_postdata,
) )
@ -133,18 +123,18 @@ class BiliBiliIE(InfoExtractor):
raise ExtractorError('%s returns error %d' % (self.IE_NAME, result['code']), expected=True) raise ExtractorError('%s returns error %d' % (self.IE_NAME, result['code']), expected=True)
else: else:
raise ExtractorError('Can\'t extract Bangumi episode ID') raise ExtractorError('Can\'t extract Bangumi episode ID')
def _aid_to_bid(self, aid): def _aid_to_bid(self, aid):
''' '''
convert bilibili avid to bid convert bilibili avid to bid
''' '''
api_url = 'http://api.bilibili.com/x/web-interface/view?aid=%s' % (aid, ) api_url = 'http://api.bilibili.com/x/web-interface/view?aid=%s' % (aid, )
js = self._download_json(api_url, aid, 'convert avid to bv id', 'convert failed') js = self._download_json(api_url, aid, 'convert avid to bv id', 'convert failed')
return js['data']['bvid'] return js['data']['bvid']
def _real_extract(self, url):
url, smuggled_data = unsmuggle_url(url, {})
mobj = re.match(self._VALID_URL, url) def _real_extract(self, url):
video_id = mobj.group('id') video_id = self._match_id(url)
# save the origin video id # save the origin video id
original_video_id = video_id original_video_id = video_id
webpage = self._download_webpage(url, video_id) webpage = self._download_webpage(url, video_id)
@ -156,32 +146,20 @@ class BiliBiliIE(InfoExtractor):
uploader_name = '' uploader_name = ''
view_count = 0 view_count = 0
part_list = [] part_list = []
upload_date = ''
# normal video # normal video
if re.match(r'^\d+$', video_id): if re.match(r'^\d+$', video_id):
video_id = self._aid_to_bid(video_id) video_id = self._aid_to_bid(video_id)
self.to_screen("%s: convert to bvid %s" % (original_video_id, video_id)) self.to_screen("%s: convert to bvid %s" % (original_video_id, video_id))
list_api_url = 'https://api.bilibili.com/x/web-interface/view/detail?bvid=%s' % (video_id, ) list_api_url = 'https://api.bilibili.com/x/web-interface/view/detail?bvid=%s' % (video_id, )
js = self._download_json(list_api_url, original_video_id, 'downloading video list', 'downloding video list failed', fatal=False) js = self._download_json(list_api_url, original_video_id, 'downloading video list', 'downloding video list failed', fatal=False)['data']
if not js: video_list = js['View']['pages']
# try old method title = js['View']['title']
cid = self._search_regex( thumbnail = js.get('View', {}).get('pic')
r'\bcid(?:["\']:|=)(\d+)', webpage, 'cid', description = js.get('View', {}).get('desc')
default=None view_count = js.get('View', {}).get('stat', {}).get('view')
) or compat_parse_qs(self._search_regex( uploader_id = js.get('Card', {}).get('card', {}).get('mid')
[r'EmbedPlayer\([^)]+,\s*"([^"]+)"\)', uploader_name = js.get('Card', {}).get('card', {}).get('name')
r'EmbedPlayer\([^)]+,\s*\\"([^"]+)\\"\)',
r'<iframe[^>]+src="https://secure\.bilibili\.com/secure,([^"]+)"'],
webpage, 'player parameters'))['cid'][0]
part_list = [{'cid': cid, 'title': title}]
else:
# new method, get value from json
video_list = js['data']['View']['pages']
title = js.get('data').get('View').get('title')
thumbnail = js['data']['View']['pic']
uploader_id = js.get('data').get('Card').get('card').get('mid')
description = js.get('data').get('View').get('desc')
uploader_name = js.get('data').get('Card').get('card').get('name')
view_count = js.get('data').get('View').get('stat').get('view')
self.to_screen("%s: video count: %d" % (original_video_id, len(video_list))) self.to_screen("%s: video count: %d" % (original_video_id, len(video_list)))
part_list = [{'cid': x['cid'], 'title': x['part']} for x in video_list] part_list = [{'cid': x['cid'], 'title': x['part']} for x in video_list]
headers = { headers = {
@ -241,46 +219,33 @@ class BiliBiliIE(InfoExtractor):
'title': part_title 'title': part_title
}) })
break break
# timestamp = unified_timestamp(self._html_search_regex(
# r'<time[^>]+datetime="([^"]+)"', webpage, 'upload time',
# default=None) or self._html_search_meta(
# 'uploadDate', webpage, 'timestamp', default=None))
# upload_date =
if not title: if not title:
title = self._html_search_regex( title = self._html_search_regex(
('<h1[^>]+\btitle=(["\'])(?P<title>(?:(?!\1).)+)\1', ('<h1[^>]+\btitle=(["\'])(?P<title>(?:(?!\1).)+)\1',
'(?s)<h1[^>]*>(?P<title>.+?)</h1>'), webpage, 'title', '(?s)<h1[^>]*>(?P<title>.+?)</h1>'), webpage, 'title',
group='title') group='title', fatal=False)
if not timestamp: if not timestamp:
timestamp = self._html_search_regex( timestamp = self._html_search_regex(
(r'"pubdate":(?P<timestamp>\d+),'), webpage, 'title', (r'"pubdate":(?P<timestamp>\d+),'), webpage, 'timestamp',
group='timestamp') group='timestamp', fatal=False)
if not uploader_id or not uploader_name: if not uploader_id or not uploader_name:
uploader_mobj = re.search( uploader_id = self._html_search_regex(
r'<a[^>]+href="(?:https?:)?//space\.bilibili\.com/(?P<id>\d+)"[^>]*>(?P<name>[^<]+)', r'<a[^>]+href="(?:https?:)?//space\.bilibili\.com/\d+"[^>]*>(?P<name>[^<]+)',
webpage) webpage, 'id',
if uploader_mobj: group='id', fatal=False)
uploader_id = uploader_mobj.group('id') uploader_name = self._html_search_regex(
uploader_name = uploader_mobj.group('name') r'<a[^>]+href="(?:https?:)?//space\.bilibili\.com/(?P<id>\d+)"',
if not uploader_id or not uploader_name: webpage, 'name',
# try agagin group='name', fatal=False)
uploader_name = self._html_search_meta(
'author', webpage, 'uploader', default=None)
if not thumbnail: if not thumbnail:
thumbnail = self._html_search_meta(['og:image', 'thumbnailUrl'], webpage) thumbnail = self._html_search_meta(['og:image', 'thumbnailUrl'], webpage, fatal=False)
if not description: if not description:
description = self._html_search_meta('description', webpage) description = self._html_search_meta('description', webpage, fatal=False)
timestamp = int(timestamp) if timestamp:
timestamp = int_or_none(timestamp)
upload_date = datetime.fromtimestamp(timestamp).strftime('%Y%m%d') upload_date = datetime.fromtimestamp(timestamp).strftime('%Y%m%d')
view_count = int(view_count) if view_count:
view_count = int_or_none(view_count)
if len(entries) == 1: if len(entries) == 1:
entry = entries[0] entry = entries[0]
entry['uploader'] = uploader_name entry['uploader'] = uploader_name
@ -368,9 +333,8 @@ class BiliBiliBangumiIE(InfoExtractor):
'Downloading bangumi info', 'Downloading bangumi info',
'Downloading bangumi failed')['result'] 'Downloading bangumi failed')['result']
title = bangumi_info['season_title'] title = bangumi_info['season_title']
description = bangumi_info['evaluate'] description = bangumi_info.get('evaluate')
view_count = bangumi_info['stat']['views'] episodes = bangumi_info.get('episodes')
episodes = bangumi_info['episodes']
self.to_screen('%s: episode count: %d' % (bangumi_id, len(episodes))) self.to_screen('%s: episode count: %d' % (bangumi_id, len(episodes)))
entries = [] entries = []
for idx, episode in enumerate(episodes, start=1): for idx, episode in enumerate(episodes, start=1):
@ -383,7 +347,7 @@ class BiliBiliBangumiIE(InfoExtractor):
# some video is splited to many fragments, here is this fragments # some video is splited to many fragments, here is this fragments
formats = [{ formats = [{
'url': durl['url'], 'url': durl['url'],
'filesize': int_or_none(durl['size']), 'filesize': int_or_none(durl.get('size')),
}] }]
for backup_url in durl.get('backup_url', []): for backup_url in durl.get('backup_url', []):
formats.append({ formats.append({
@ -402,9 +366,11 @@ class BiliBiliBangumiIE(InfoExtractor):
'id': '%s_%d_%d' % (bangumi_id, idx, fragment_idx), 'id': '%s_%d_%d' % (bangumi_id, idx, fragment_idx),
'duration': float_or_none(durl.get('length'), 1000), 'duration': float_or_none(durl.get('length'), 1000),
'formats': formats, 'formats': formats,
'title': episode['long_title'] 'title': episode.get('long_title', '')
}) })
return self.playlist_result(entries, bangumi_id, title, description) return self.playlist_result(entries, bangumi_id, title, description)
class BiliBiliBangumiEpisodeIE(InfoExtractor): class BiliBiliBangumiEpisodeIE(InfoExtractor):
_VALID_URL = r'https?://(?:www\.)bilibili.com/bangumi/play/[eE][pP](?P<id>\d+)' _VALID_URL = r'https?://(?:www\.)bilibili.com/bangumi/play/[eE][pP](?P<id>\d+)'
@ -463,6 +429,8 @@ class BiliBiliBangumiEpisodeIE(InfoExtractor):
return self.url_result( return self.url_result(
'https://www.bilibili.com/bangumi/media/md%s' % bangumi_id, 'https://www.bilibili.com/bangumi/media/md%s' % bangumi_id,
ie=BiliBiliBangumiIE.ie_key(), video_id=ep_id) ie=BiliBiliBangumiIE.ie_key(), video_id=ep_id)
class BilibiliAudioBaseIE(InfoExtractor): class BilibiliAudioBaseIE(InfoExtractor):
def _call_api(self, path, sid, query=None): def _call_api(self, path, sid, query=None):
if not query: if not query: