mirror of
https://github.com/ytdl-org/youtube-dl
synced 2025-02-09 20:20:09 +09:00
Compare commits
3 Commits
c0d9eb7043
...
bfa345744d
Author | SHA1 | Date | |
---|---|---|---|
|
bfa345744d | ||
|
f966461476 | ||
|
b8aea53682 |
@ -1,77 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
from .common import InfoExtractor
|
|
||||||
from ..utils import (
|
|
||||||
ExtractorError,
|
|
||||||
sanitized_Request,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class EveryonesMixtapeIE(InfoExtractor):
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?everyonesmixtape\.com/#/mix/(?P<id>[0-9a-zA-Z]+)(?:/(?P<songnr>[0-9]))?$'
|
|
||||||
|
|
||||||
_TESTS = [{
|
|
||||||
'url': 'http://everyonesmixtape.com/#/mix/m7m0jJAbMQi/5',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '5bfseWNmlds',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': "Passion Pit - \"Sleepyhead\" (Official Music Video)",
|
|
||||||
'uploader': 'FKR.TV',
|
|
||||||
'uploader_id': 'frenchkissrecords',
|
|
||||||
'description': "Music video for \"Sleepyhead\" from Passion Pit's debut EP Chunk Of Change.\nBuy on iTunes: https://itunes.apple.com/us/album/chunk-of-change-ep/id300087641\n\nDirected by The Wilderness.\n\nhttp://www.passionpitmusic.com\nhttp://www.frenchkissrecords.com",
|
|
||||||
'upload_date': '20081015'
|
|
||||||
},
|
|
||||||
'params': {
|
|
||||||
'skip_download': True, # This is simply YouTube
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
'url': 'http://everyonesmixtape.com/#/mix/m7m0jJAbMQi',
|
|
||||||
'info_dict': {
|
|
||||||
'id': 'm7m0jJAbMQi',
|
|
||||||
'title': 'Driving',
|
|
||||||
},
|
|
||||||
'playlist_count': 24
|
|
||||||
}]
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
mobj = re.match(self._VALID_URL, url)
|
|
||||||
playlist_id = mobj.group('id')
|
|
||||||
|
|
||||||
pllist_url = 'http://everyonesmixtape.com/mixtape.php?a=getMixes&u=-1&linked=%s&explore=' % playlist_id
|
|
||||||
pllist_req = sanitized_Request(pllist_url)
|
|
||||||
pllist_req.add_header('X-Requested-With', 'XMLHttpRequest')
|
|
||||||
|
|
||||||
playlist_list = self._download_json(
|
|
||||||
pllist_req, playlist_id, note='Downloading playlist metadata')
|
|
||||||
try:
|
|
||||||
playlist_no = next(playlist['id']
|
|
||||||
for playlist in playlist_list
|
|
||||||
if playlist['code'] == playlist_id)
|
|
||||||
except StopIteration:
|
|
||||||
raise ExtractorError('Playlist id not found')
|
|
||||||
|
|
||||||
pl_url = 'http://everyonesmixtape.com/mixtape.php?a=getMix&id=%s&userId=null&code=' % playlist_no
|
|
||||||
pl_req = sanitized_Request(pl_url)
|
|
||||||
pl_req.add_header('X-Requested-With', 'XMLHttpRequest')
|
|
||||||
playlist = self._download_json(
|
|
||||||
pl_req, playlist_id, note='Downloading playlist info')
|
|
||||||
|
|
||||||
entries = [{
|
|
||||||
'_type': 'url',
|
|
||||||
'url': t['url'],
|
|
||||||
'title': t['title'],
|
|
||||||
} for t in playlist['tracks']]
|
|
||||||
|
|
||||||
if mobj.group('songnr'):
|
|
||||||
songnr = int(mobj.group('songnr')) - 1
|
|
||||||
return entries[songnr]
|
|
||||||
|
|
||||||
playlist_title = playlist['mixData']['name']
|
|
||||||
return {
|
|
||||||
'_type': 'playlist',
|
|
||||||
'id': playlist_id,
|
|
||||||
'title': playlist_title,
|
|
||||||
'entries': entries,
|
|
||||||
}
|
|
@ -327,7 +327,6 @@ from .espn import (
|
|||||||
)
|
)
|
||||||
from .esri import EsriVideoIE
|
from .esri import EsriVideoIE
|
||||||
from .europa import EuropaIE
|
from .europa import EuropaIE
|
||||||
from .everyonesmixtape import EveryonesMixtapeIE
|
|
||||||
from .expotv import ExpoTVIE
|
from .expotv import ExpoTVIE
|
||||||
from .expressen import ExpressenIE
|
from .expressen import ExpressenIE
|
||||||
from .extremetube import ExtremeTubeIE
|
from .extremetube import ExtremeTubeIE
|
||||||
@ -1129,7 +1128,6 @@ from .tagesschau import (
|
|||||||
TagesschauIE,
|
TagesschauIE,
|
||||||
)
|
)
|
||||||
from .tass import TassIE
|
from .tass import TassIE
|
||||||
from .tastytrade import TastyTradeIE
|
|
||||||
from .tbs import TBSIE
|
from .tbs import TBSIE
|
||||||
from .tdslifeway import TDSLifewayIE
|
from .tdslifeway import TDSLifewayIE
|
||||||
from .teachable import (
|
from .teachable import (
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import json
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import functools
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..compat import (
|
from ..compat import (
|
||||||
compat_parse_qs,
|
compat_parse_qs,
|
||||||
compat_urlparse,
|
compat_urllib_parse_urlparse,
|
||||||
)
|
)
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
determine_ext,
|
determine_ext,
|
||||||
dict_get,
|
dict_get,
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
int_or_none,
|
|
||||||
float_or_none,
|
float_or_none,
|
||||||
|
InAdvancePagedList,
|
||||||
|
int_or_none,
|
||||||
parse_duration,
|
parse_duration,
|
||||||
parse_iso8601,
|
parse_iso8601,
|
||||||
remove_start,
|
remove_start,
|
||||||
@ -181,7 +184,7 @@ class NiconicoIE(InfoExtractor):
|
|||||||
if urlh is False:
|
if urlh is False:
|
||||||
login_ok = False
|
login_ok = False
|
||||||
else:
|
else:
|
||||||
parts = compat_urlparse.urlparse(urlh.geturl())
|
parts = compat_urllib_parse_urlparse(urlh.geturl())
|
||||||
if compat_parse_qs(parts.query).get('message', [None])[0] == 'cant_login':
|
if compat_parse_qs(parts.query).get('message', [None])[0] == 'cant_login':
|
||||||
login_ok = False
|
login_ok = False
|
||||||
if not login_ok:
|
if not login_ok:
|
||||||
@ -292,7 +295,7 @@ class NiconicoIE(InfoExtractor):
|
|||||||
'http://flapi.nicovideo.jp/api/getflv/' + video_id + '?as3=1',
|
'http://flapi.nicovideo.jp/api/getflv/' + video_id + '?as3=1',
|
||||||
video_id, 'Downloading flv info')
|
video_id, 'Downloading flv info')
|
||||||
|
|
||||||
flv_info = compat_urlparse.parse_qs(flv_info_webpage)
|
flv_info = compat_parse_qs(flv_info_webpage)
|
||||||
if 'url' not in flv_info:
|
if 'url' not in flv_info:
|
||||||
if 'deleted' in flv_info:
|
if 'deleted' in flv_info:
|
||||||
raise ExtractorError('The video has been deleted.',
|
raise ExtractorError('The video has been deleted.',
|
||||||
@ -437,34 +440,76 @@ class NiconicoIE(InfoExtractor):
|
|||||||
|
|
||||||
|
|
||||||
class NiconicoPlaylistIE(InfoExtractor):
|
class NiconicoPlaylistIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:www\.)?nicovideo\.jp/mylist/(?P<id>\d+)'
|
_VALID_URL = r'https?://(?:www\.)?nicovideo\.jp/(?:user/\d+/)?mylist/(?P<id>\d+)'
|
||||||
|
|
||||||
_TEST = {
|
_TESTS = [{
|
||||||
'url': 'http://www.nicovideo.jp/mylist/27411728',
|
'url': 'http://www.nicovideo.jp/mylist/27411728',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '27411728',
|
'id': '27411728',
|
||||||
'title': 'AKB48のオールナイトニッポン',
|
'title': 'AKB48のオールナイトニッポン',
|
||||||
|
'description': 'md5:d89694c5ded4b6c693dea2db6e41aa08',
|
||||||
|
'uploader': 'のっく',
|
||||||
|
'uploader_id': '805442',
|
||||||
},
|
},
|
||||||
'playlist_mincount': 225,
|
'playlist_mincount': 225,
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.nicovideo.jp/user/805442/mylist/27411728',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
_PAGE_SIZE = 100
|
||||||
|
|
||||||
|
def _call_api(self, list_id, resource, query):
|
||||||
|
return self._download_json(
|
||||||
|
'https://nvapi.nicovideo.jp/v2/mylists/' + list_id, list_id,
|
||||||
|
'Downloading %s JSON metatdata' % resource, query=query,
|
||||||
|
headers={'X-Frontend-Id': 6})['data']['mylist']
|
||||||
|
|
||||||
|
def _parse_owner(self, item):
|
||||||
|
owner = item.get('owner') or {}
|
||||||
|
if owner:
|
||||||
|
return {
|
||||||
|
'uploader': owner.get('name'),
|
||||||
|
'uploader_id': owner.get('id'),
|
||||||
}
|
}
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def _fetch_page(self, list_id, page):
|
||||||
|
page += 1
|
||||||
|
items = self._call_api(list_id, 'page %d' % page, {
|
||||||
|
'page': page,
|
||||||
|
'pageSize': self._PAGE_SIZE,
|
||||||
|
})['items']
|
||||||
|
for item in items:
|
||||||
|
video = item.get('video') or {}
|
||||||
|
video_id = video.get('id')
|
||||||
|
if not video_id:
|
||||||
|
continue
|
||||||
|
count = video.get('count') or {}
|
||||||
|
get_count = lambda x: int_or_none(count.get(x))
|
||||||
|
info = {
|
||||||
|
'_type': 'url',
|
||||||
|
'id': video_id,
|
||||||
|
'title': video.get('title'),
|
||||||
|
'url': 'https://www.nicovideo.jp/watch/' + video_id,
|
||||||
|
'description': video.get('shortDescription'),
|
||||||
|
'duration': int_or_none(video.get('duration')),
|
||||||
|
'view_count': get_count('view'),
|
||||||
|
'comment_count': get_count('comment'),
|
||||||
|
'ie_key': NiconicoIE.ie_key(),
|
||||||
|
}
|
||||||
|
info.update(self._parse_owner(video))
|
||||||
|
yield info
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
list_id = self._match_id(url)
|
list_id = self._match_id(url)
|
||||||
webpage = self._download_webpage(url, list_id)
|
mylist = self._call_api(list_id, 'list', {
|
||||||
|
'pageSize': 1,
|
||||||
entries_json = self._search_regex(r'Mylist\.preload\(\d+, (\[.*\])\);',
|
})
|
||||||
webpage, 'entries')
|
entries = InAdvancePagedList(
|
||||||
entries = json.loads(entries_json)
|
functools.partial(self._fetch_page, list_id),
|
||||||
entries = [{
|
math.ceil(mylist['totalItemCount'] / self._PAGE_SIZE),
|
||||||
'_type': 'url',
|
self._PAGE_SIZE)
|
||||||
'ie_key': NiconicoIE.ie_key(),
|
result = self.playlist_result(
|
||||||
'url': ('http://www.nicovideo.jp/watch/%s' %
|
entries, list_id, mylist.get('name'), mylist.get('description'))
|
||||||
entry['item_data']['video_id']),
|
result.update(self._parse_owner(mylist))
|
||||||
} for entry in entries]
|
return result
|
||||||
|
|
||||||
return {
|
|
||||||
'_type': 'playlist',
|
|
||||||
'title': self._search_regex(r'\s+name: "(.*?)"', webpage, 'title'),
|
|
||||||
'id': list_id,
|
|
||||||
'entries': entries,
|
|
||||||
}
|
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from .common import InfoExtractor
|
|
||||||
from .ooyala import OoyalaIE
|
|
||||||
|
|
||||||
|
|
||||||
class TastyTradeIE(InfoExtractor):
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?tastytrade\.com/tt/shows/[^/]+/episodes/(?P<id>[^/?#&]+)'
|
|
||||||
|
|
||||||
_TESTS = [{
|
|
||||||
'url': 'https://www.tastytrade.com/tt/shows/market-measures/episodes/correlation-in-short-volatility-06-28-2017',
|
|
||||||
'info_dict': {
|
|
||||||
'id': 'F3bnlzbToeI6pLEfRyrlfooIILUjz4nM',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': 'A History of Teaming',
|
|
||||||
'description': 'md5:2a9033db8da81f2edffa4c99888140b3',
|
|
||||||
'duration': 422.255,
|
|
||||||
},
|
|
||||||
'params': {
|
|
||||||
'skip_download': True,
|
|
||||||
},
|
|
||||||
'add_ie': ['Ooyala'],
|
|
||||||
}, {
|
|
||||||
'url': 'https://www.tastytrade.com/tt/shows/daily-dose/episodes/daily-dose-06-30-2017',
|
|
||||||
'only_matching': True,
|
|
||||||
}]
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
display_id = self._match_id(url)
|
|
||||||
webpage = self._download_webpage(url, display_id)
|
|
||||||
|
|
||||||
ooyala_code = self._search_regex(
|
|
||||||
r'data-media-id=(["\'])(?P<code>(?:(?!\1).)+)\1',
|
|
||||||
webpage, 'ooyala code', group='code')
|
|
||||||
|
|
||||||
info = self._search_json_ld(webpage, display_id, fatal=False)
|
|
||||||
info.update({
|
|
||||||
'_type': 'url_transparent',
|
|
||||||
'ie_key': OoyalaIE.ie_key(),
|
|
||||||
'url': 'ooyala:%s' % ooyala_code,
|
|
||||||
'display_id': display_id,
|
|
||||||
})
|
|
||||||
return info
|
|
Loading…
Reference in New Issue
Block a user