mirror of
https://codeberg.org/polarisfm/youtube-dl
synced 2025-01-08 14:17:54 +01:00
Merge remote-tracking branch 'upstream/master' into fix-zing-mp3
This commit is contained in:
commit
742132ae00
6
.github/ISSUE_TEMPLATE.md
vendored
6
.github/ISSUE_TEMPLATE.md
vendored
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2018.11.07*. If it's not, read [this FAQ entry](https://github.com/rg3/youtube-dl/blob/master/README.md#how-do-i-update-youtube-dl) and update. Issues with outdated version will be rejected.
|
### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2018.11.18*. If it's not, read [this FAQ entry](https://github.com/rg3/youtube-dl/blob/master/README.md#how-do-i-update-youtube-dl) and update. Issues with outdated version will be rejected.
|
||||||
- [ ] I've **verified** and **I assure** that I'm running youtube-dl **2018.11.07**
|
- [ ] I've **verified** and **I assure** that I'm running youtube-dl **2018.11.18**
|
||||||
|
|
||||||
### Before submitting an *issue* make sure you have:
|
### Before submitting an *issue* make sure you have:
|
||||||
- [ ] At least skimmed through the [README](https://github.com/rg3/youtube-dl/blob/master/README.md), **most notably** the [FAQ](https://github.com/rg3/youtube-dl#faq) and [BUGS](https://github.com/rg3/youtube-dl#bugs) sections
|
- [ ] At least skimmed through the [README](https://github.com/rg3/youtube-dl/blob/master/README.md), **most notably** the [FAQ](https://github.com/rg3/youtube-dl#faq) and [BUGS](https://github.com/rg3/youtube-dl#bugs) sections
|
||||||
@ -36,7 +36,7 @@ Add the `-v` flag to **your command line** you run youtube-dl with (`youtube-dl
|
|||||||
[debug] User config: []
|
[debug] User config: []
|
||||||
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
||||||
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
||||||
[debug] youtube-dl version 2018.11.07
|
[debug] youtube-dl version 2018.11.18
|
||||||
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
||||||
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
||||||
[debug] Proxy map: {}
|
[debug] Proxy map: {}
|
||||||
|
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
version 2018.11.18
|
||||||
|
|
||||||
|
Extractors
|
||||||
|
+ [wwe] Extract subtitles
|
||||||
|
+ [wwe] Add support for playlistst (#14781)
|
||||||
|
+ [wwe] Add support for wwe.com (#14781, #17450)
|
||||||
|
* [vk] Detect geo restriction (#17767)
|
||||||
|
* [openload] Use original host during extraction (#18211)
|
||||||
|
* [atvat] Fix extraction (#18041)
|
||||||
|
+ [rte] Add support for new API endpoint (#18206)
|
||||||
|
* [tnaflixnetwork:embed] Fix extraction (#18205)
|
||||||
|
* [picarto] Use API and add token support (#16518)
|
||||||
|
+ [zype] Add support for player.zype.com (#18143)
|
||||||
|
* [vivo] Fix extraction (#18139)
|
||||||
|
* [ruutu] Update API endpoint (#18138)
|
||||||
|
|
||||||
|
|
||||||
version 2018.11.07
|
version 2018.11.07
|
||||||
|
|
||||||
Extractors
|
Extractors
|
||||||
|
@ -1080,6 +1080,7 @@
|
|||||||
- **wrzuta.pl:playlist**
|
- **wrzuta.pl:playlist**
|
||||||
- **WSJ**: Wall Street Journal
|
- **WSJ**: Wall Street Journal
|
||||||
- **WSJArticle**
|
- **WSJArticle**
|
||||||
|
- **WWE**
|
||||||
- **XBef**
|
- **XBef**
|
||||||
- **XboxClips**
|
- **XboxClips**
|
||||||
- **XFileShare**: XFileShare based sites: DaClips, FileHoot, GorillaVid, MovPod, PowerWatch, Rapidvideo.ws, TheVideoBee, Vidto, Streamin.To, XVIDSTAGE, Vid ABC, VidBom, vidlo, RapidVideo.TV, FastVideo.me
|
- **XFileShare**: XFileShare based sites: DaClips, FileHoot, GorillaVid, MovPod, PowerWatch, Rapidvideo.ws, TheVideoBee, Vidto, Streamin.To, XVIDSTAGE, Vid ABC, VidBom, vidlo, RapidVideo.TV, FastVideo.me
|
||||||
@ -1139,3 +1140,4 @@
|
|||||||
- **ZDF**
|
- **ZDF**
|
||||||
- **ZDFChannel**
|
- **ZDFChannel**
|
||||||
- **zingmp3**: mp3.zing.vn
|
- **zingmp3**: mp3.zing.vn
|
||||||
|
- **Zype**
|
||||||
|
@ -43,10 +43,6 @@ class AmericasTestKitchenIE(InfoExtractor):
|
|||||||
|
|
||||||
webpage = self._download_webpage(url, video_id)
|
webpage = self._download_webpage(url, video_id)
|
||||||
|
|
||||||
partner_id = self._search_regex(
|
|
||||||
r'src=["\'](?:https?:)?//(?:[^/]+\.)kaltura\.com/(?:[^/]+/)*(?:p|partner_id)/(\d+)',
|
|
||||||
webpage, 'kaltura partner id')
|
|
||||||
|
|
||||||
video_data = self._parse_json(
|
video_data = self._parse_json(
|
||||||
self._search_regex(
|
self._search_regex(
|
||||||
r'window\.__INITIAL_STATE__\s*=\s*({.+?})\s*;\s*</script>',
|
r'window\.__INITIAL_STATE__\s*=\s*({.+?})\s*;\s*</script>',
|
||||||
@ -58,7 +54,18 @@ class AmericasTestKitchenIE(InfoExtractor):
|
|||||||
(lambda x: x['episodeDetail']['content']['data'],
|
(lambda x: x['episodeDetail']['content']['data'],
|
||||||
lambda x: x['videoDetail']['content']['data']), dict)
|
lambda x: x['videoDetail']['content']['data']), dict)
|
||||||
ep_meta = ep_data.get('full_video', {})
|
ep_meta = ep_data.get('full_video', {})
|
||||||
external_id = ep_data.get('external_id') or ep_meta['external_id']
|
|
||||||
|
zype_id = ep_meta.get('zype_id')
|
||||||
|
if zype_id:
|
||||||
|
embed_url = 'https://player.zype.com/embed/%s.js?api_key=jZ9GUhRmxcPvX7M3SlfejB6Hle9jyHTdk2jVxG7wOHPLODgncEKVdPYBhuz9iWXQ' % zype_id
|
||||||
|
ie_key = 'Zype'
|
||||||
|
else:
|
||||||
|
partner_id = self._search_regex(
|
||||||
|
r'src=["\'](?:https?:)?//(?:[^/]+\.)kaltura\.com/(?:[^/]+/)*(?:p|partner_id)/(\d+)',
|
||||||
|
webpage, 'kaltura partner id')
|
||||||
|
external_id = ep_data.get('external_id') or ep_meta['external_id']
|
||||||
|
embed_url = 'kaltura:%s:%s' % (partner_id, external_id)
|
||||||
|
ie_key = 'Kaltura'
|
||||||
|
|
||||||
title = ep_data.get('title') or ep_meta.get('title')
|
title = ep_data.get('title') or ep_meta.get('title')
|
||||||
description = clean_html(ep_meta.get('episode_description') or ep_data.get(
|
description = clean_html(ep_meta.get('episode_description') or ep_data.get(
|
||||||
@ -72,8 +79,8 @@ class AmericasTestKitchenIE(InfoExtractor):
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
'_type': 'url_transparent',
|
'_type': 'url_transparent',
|
||||||
'url': 'kaltura:%s:%s' % (partner_id, external_id),
|
'url': embed_url,
|
||||||
'ie_key': 'Kaltura',
|
'ie_key': ie_key,
|
||||||
'title': title,
|
'title': title,
|
||||||
'description': description,
|
'description': description,
|
||||||
'thumbnail': thumbnail,
|
'thumbnail': thumbnail,
|
||||||
|
@ -28,8 +28,10 @@ class ATVAtIE(InfoExtractor):
|
|||||||
display_id = self._match_id(url)
|
display_id = self._match_id(url)
|
||||||
webpage = self._download_webpage(url, display_id)
|
webpage = self._download_webpage(url, display_id)
|
||||||
video_data = self._parse_json(unescapeHTML(self._search_regex(
|
video_data = self._parse_json(unescapeHTML(self._search_regex(
|
||||||
r'class="[^"]*jsb_video/FlashPlayer[^"]*"[^>]+data-jsb="([^"]+)"',
|
[r'flashPlayerOptions\s*=\s*(["\'])(?P<json>(?:(?!\1).)+)\1',
|
||||||
webpage, 'player data')), display_id)['config']['initial_video']
|
r'class="[^"]*jsb_video/FlashPlayer[^"]*"[^>]+data-jsb="(?P<json>[^"]+)"'],
|
||||||
|
webpage, 'player data', group='json')),
|
||||||
|
display_id)['config']['initial_video']
|
||||||
|
|
||||||
video_id = video_data['id']
|
video_id = video_data['id']
|
||||||
video_title = video_data['title']
|
video_title = video_data['title']
|
||||||
|
@ -37,7 +37,7 @@ class BitChuteIE(InfoExtractor):
|
|||||||
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.57 Safari/537.36',
|
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.57 Safari/537.36',
|
||||||
})
|
})
|
||||||
|
|
||||||
title = self._search_regex(
|
title = self._html_search_regex(
|
||||||
(r'<[^>]+\bid=["\']video-title[^>]+>([^<]+)', r'<title>([^<]+)'),
|
(r'<[^>]+\bid=["\']video-title[^>]+>([^<]+)', r'<title>([^<]+)'),
|
||||||
webpage, 'title', default=None) or self._html_search_meta(
|
webpage, 'title', default=None) or self._html_search_meta(
|
||||||
'description', webpage, 'title',
|
'description', webpage, 'title',
|
||||||
|
@ -1386,6 +1386,7 @@ from .wsj import (
|
|||||||
WSJIE,
|
WSJIE,
|
||||||
WSJArticleIE,
|
WSJArticleIE,
|
||||||
)
|
)
|
||||||
|
from .wwe import WWEIE
|
||||||
from .xbef import XBefIE
|
from .xbef import XBefIE
|
||||||
from .xboxclips import XboxClipsIE
|
from .xboxclips import XboxClipsIE
|
||||||
from .xfileshare import XFileShareIE
|
from .xfileshare import XFileShareIE
|
||||||
|
@ -192,6 +192,8 @@ class KalturaIE(InfoExtractor):
|
|||||||
'entryId': video_id,
|
'entryId': video_id,
|
||||||
'service': 'baseentry',
|
'service': 'baseentry',
|
||||||
'ks': '{1:result:ks}',
|
'ks': '{1:result:ks}',
|
||||||
|
'responseProfile:fields': 'createdAt,dataUrl,duration,name,plays,thumbnailUrl,userId',
|
||||||
|
'responseProfile:type': 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'action': 'getbyentryid',
|
'action': 'getbyentryid',
|
||||||
|
@ -35,7 +35,7 @@ class NovaEmbedIE(InfoExtractor):
|
|||||||
|
|
||||||
bitrates = self._parse_json(
|
bitrates = self._parse_json(
|
||||||
self._search_regex(
|
self._search_regex(
|
||||||
r'(?s)bitrates\s*=\s*({.+?})\s*;', webpage, 'formats'),
|
r'(?s)(?:src|bitrates)\s*=\s*({.+?})\s*;', webpage, 'formats'),
|
||||||
video_id, transform_source=js_to_json)
|
video_id, transform_source=js_to_json)
|
||||||
|
|
||||||
QUALITIES = ('lq', 'mq', 'hq', 'hd')
|
QUALITIES = ('lq', 'mq', 'hq', 'hd')
|
||||||
|
@ -243,7 +243,18 @@ class PhantomJSwrapper(object):
|
|||||||
|
|
||||||
|
|
||||||
class OpenloadIE(InfoExtractor):
|
class OpenloadIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:www\.)?(?:openload\.(?:co|io|link)|oload\.(?:tv|stream|site|xyz|win|download|cloud|cc|icu|fun))/(?:f|embed)/(?P<id>[a-zA-Z0-9-_]+)'
|
_VALID_URL = r'''(?x)
|
||||||
|
https?://
|
||||||
|
(?P<host>
|
||||||
|
(?:www\.)?
|
||||||
|
(?:
|
||||||
|
openload\.(?:co|io|link)|
|
||||||
|
oload\.(?:tv|stream|site|xyz|win|download|cloud|cc|icu|fun)
|
||||||
|
)
|
||||||
|
)/
|
||||||
|
(?:f|embed)/
|
||||||
|
(?P<id>[a-zA-Z0-9-_]+)
|
||||||
|
'''
|
||||||
|
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://openload.co/f/kUEfGclsU9o',
|
'url': 'https://openload.co/f/kUEfGclsU9o',
|
||||||
@ -334,8 +345,11 @@ class OpenloadIE(InfoExtractor):
|
|||||||
webpage)
|
webpage)
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
video_id = self._match_id(url)
|
mobj = re.match(self._VALID_URL, url)
|
||||||
url_pattern = 'https://openload.co/%%s/%s/' % video_id
|
host = mobj.group('host')
|
||||||
|
video_id = mobj.group('id')
|
||||||
|
|
||||||
|
url_pattern = 'https://%s/%%s/%s/' % (host, video_id)
|
||||||
headers = {
|
headers = {
|
||||||
'User-Agent': self._USER_AGENT,
|
'User-Agent': self._USER_AGENT,
|
||||||
}
|
}
|
||||||
@ -368,7 +382,7 @@ class OpenloadIE(InfoExtractor):
|
|||||||
r'>\s*([\w~-]+~[a-f0-9:]+~[\w~-]+)'), webpage,
|
r'>\s*([\w~-]+~[a-f0-9:]+~[\w~-]+)'), webpage,
|
||||||
'stream URL'))
|
'stream URL'))
|
||||||
|
|
||||||
video_url = 'https://openload.co/stream/%s?mime=true' % decoded_id
|
video_url = 'https://%s/stream/%s?mime=true' % (host, decoded_id)
|
||||||
|
|
||||||
title = self._og_search_title(webpage, default=None) or self._search_regex(
|
title = self._og_search_title(webpage, default=None) or self._search_regex(
|
||||||
r'<span[^>]+class=["\']title["\'][^>]*>([^<]+)', webpage,
|
r'<span[^>]+class=["\']title["\'][^>]*>([^<]+)', webpage,
|
||||||
@ -379,7 +393,7 @@ class OpenloadIE(InfoExtractor):
|
|||||||
entry = entries[0] if entries else {}
|
entry = entries[0] if entries else {}
|
||||||
subtitles = entry.get('subtitles')
|
subtitles = entry.get('subtitles')
|
||||||
|
|
||||||
info_dict = {
|
return {
|
||||||
'id': video_id,
|
'id': video_id,
|
||||||
'title': title,
|
'title': title,
|
||||||
'thumbnail': entry.get('thumbnail') or self._og_search_thumbnail(webpage, default=None),
|
'thumbnail': entry.get('thumbnail') or self._og_search_thumbnail(webpage, default=None),
|
||||||
@ -388,4 +402,3 @@ class OpenloadIE(InfoExtractor):
|
|||||||
'subtitles': subtitles,
|
'subtitles': subtitles,
|
||||||
'http_headers': headers,
|
'http_headers': headers,
|
||||||
}
|
}
|
||||||
return info_dict
|
|
||||||
|
@ -27,7 +27,7 @@ class PornHubIE(InfoExtractor):
|
|||||||
_VALID_URL = r'''(?x)
|
_VALID_URL = r'''(?x)
|
||||||
https?://
|
https?://
|
||||||
(?:
|
(?:
|
||||||
(?:[^/]+\.)?pornhub\.com/(?:(?:view_video\.php|video/show)\?viewkey=|embed/)|
|
(?:[^/]+\.)?pornhub\.(?:com|net)/(?:(?:view_video\.php|video/show)\?viewkey=|embed/)|
|
||||||
(?:www\.)?thumbzilla\.com/video/
|
(?:www\.)?thumbzilla\.com/video/
|
||||||
)
|
)
|
||||||
(?P<id>[\da-z]+)
|
(?P<id>[\da-z]+)
|
||||||
@ -121,6 +121,9 @@ class PornHubIE(InfoExtractor):
|
|||||||
}, {
|
}, {
|
||||||
'url': 'http://www.pornhub.com/video/show?viewkey=648719015',
|
'url': 'http://www.pornhub.com/video/show?viewkey=648719015',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.pornhub.net/view_video.php?viewkey=203640933',
|
||||||
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -340,7 +343,7 @@ class PornHubPlaylistBaseIE(InfoExtractor):
|
|||||||
|
|
||||||
|
|
||||||
class PornHubPlaylistIE(PornHubPlaylistBaseIE):
|
class PornHubPlaylistIE(PornHubPlaylistBaseIE):
|
||||||
_VALID_URL = r'https?://(?:[^/]+\.)?pornhub\.com/playlist/(?P<id>\d+)'
|
_VALID_URL = r'https?://(?:[^/]+\.)?pornhub\.(?:com|net)/playlist/(?P<id>\d+)'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'http://www.pornhub.com/playlist/4667351',
|
'url': 'http://www.pornhub.com/playlist/4667351',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
@ -355,7 +358,7 @@ class PornHubPlaylistIE(PornHubPlaylistBaseIE):
|
|||||||
|
|
||||||
|
|
||||||
class PornHubUserVideosIE(PornHubPlaylistBaseIE):
|
class PornHubUserVideosIE(PornHubPlaylistBaseIE):
|
||||||
_VALID_URL = r'https?://(?:[^/]+\.)?pornhub\.com/(?:(?:user|channel)s|model|pornstar)/(?P<id>[^/]+)/videos'
|
_VALID_URL = r'https?://(?:[^/]+\.)?pornhub\.(?:com|net)/(?:(?:user|channel)s|model|pornstar)/(?P<id>[^/]+)/videos'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'http://www.pornhub.com/users/zoe_ph/videos/public',
|
'url': 'http://www.pornhub.com/users/zoe_ph/videos/public',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
|
@ -8,7 +8,10 @@ from ..compat import compat_HTTPError
|
|||||||
from ..utils import (
|
from ..utils import (
|
||||||
float_or_none,
|
float_or_none,
|
||||||
parse_iso8601,
|
parse_iso8601,
|
||||||
|
str_or_none,
|
||||||
|
try_get,
|
||||||
unescapeHTML,
|
unescapeHTML,
|
||||||
|
url_or_none,
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,65 +20,87 @@ class RteBaseIE(InfoExtractor):
|
|||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
item_id = self._match_id(url)
|
item_id = self._match_id(url)
|
||||||
|
|
||||||
try:
|
info_dict = {}
|
||||||
json_string = self._download_json(
|
|
||||||
'http://www.rte.ie/rteavgen/getplaylist/?type=web&format=json&id=' + item_id,
|
|
||||||
item_id)
|
|
||||||
except ExtractorError as ee:
|
|
||||||
if isinstance(ee.cause, compat_HTTPError) and ee.cause.code == 404:
|
|
||||||
error_info = self._parse_json(ee.cause.read().decode(), item_id, fatal=False)
|
|
||||||
if error_info:
|
|
||||||
raise ExtractorError(
|
|
||||||
'%s said: %s' % (self.IE_NAME, error_info['message']),
|
|
||||||
expected=True)
|
|
||||||
raise
|
|
||||||
|
|
||||||
# NB the string values in the JSON are stored using XML escaping(!)
|
|
||||||
show = json_string['shows'][0]
|
|
||||||
title = unescapeHTML(show['title'])
|
|
||||||
description = unescapeHTML(show.get('description'))
|
|
||||||
thumbnail = show.get('thumbnail')
|
|
||||||
duration = float_or_none(show.get('duration'), 1000)
|
|
||||||
timestamp = parse_iso8601(show.get('published'))
|
|
||||||
|
|
||||||
mg = show['media:group'][0]
|
|
||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
|
|
||||||
if mg.get('url'):
|
ENDPOINTS = (
|
||||||
m = re.match(r'(?P<url>rtmpe?://[^/]+)/(?P<app>.+)/(?P<playpath>mp4:.*)', mg['url'])
|
'https://feeds.rasset.ie/rteavgen/player/playlist?type=iptv&format=json&showId=',
|
||||||
if m:
|
'http://www.rte.ie/rteavgen/getplaylist/?type=web&format=json&id=',
|
||||||
m = m.groupdict()
|
)
|
||||||
formats.append({
|
|
||||||
'url': m['url'] + '/' + m['app'],
|
|
||||||
'app': m['app'],
|
|
||||||
'play_path': m['playpath'],
|
|
||||||
'player_url': url,
|
|
||||||
'ext': 'flv',
|
|
||||||
'format_id': 'rtmp',
|
|
||||||
})
|
|
||||||
|
|
||||||
if mg.get('hls_server') and mg.get('hls_url'):
|
for num, ep_url in enumerate(ENDPOINTS, start=1):
|
||||||
formats.extend(self._extract_m3u8_formats(
|
try:
|
||||||
mg['hls_server'] + mg['hls_url'], item_id, 'mp4',
|
data = self._download_json(ep_url + item_id, item_id)
|
||||||
entry_protocol='m3u8_native', m3u8_id='hls', fatal=False))
|
except ExtractorError as ee:
|
||||||
|
if num < len(ENDPOINTS) or formats:
|
||||||
|
continue
|
||||||
|
if isinstance(ee.cause, compat_HTTPError) and ee.cause.code == 404:
|
||||||
|
error_info = self._parse_json(ee.cause.read().decode(), item_id, fatal=False)
|
||||||
|
if error_info:
|
||||||
|
raise ExtractorError(
|
||||||
|
'%s said: %s' % (self.IE_NAME, error_info['message']),
|
||||||
|
expected=True)
|
||||||
|
raise
|
||||||
|
|
||||||
if mg.get('hds_server') and mg.get('hds_url'):
|
# NB the string values in the JSON are stored using XML escaping(!)
|
||||||
formats.extend(self._extract_f4m_formats(
|
show = try_get(data, lambda x: x['shows'][0], dict)
|
||||||
mg['hds_server'] + mg['hds_url'], item_id,
|
if not show:
|
||||||
f4m_id='hds', fatal=False))
|
continue
|
||||||
|
|
||||||
|
if not info_dict:
|
||||||
|
title = unescapeHTML(show['title'])
|
||||||
|
description = unescapeHTML(show.get('description'))
|
||||||
|
thumbnail = show.get('thumbnail')
|
||||||
|
duration = float_or_none(show.get('duration'), 1000)
|
||||||
|
timestamp = parse_iso8601(show.get('published'))
|
||||||
|
info_dict = {
|
||||||
|
'id': item_id,
|
||||||
|
'title': title,
|
||||||
|
'description': description,
|
||||||
|
'thumbnail': thumbnail,
|
||||||
|
'timestamp': timestamp,
|
||||||
|
'duration': duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
mg = try_get(show, lambda x: x['media:group'][0], dict)
|
||||||
|
if not mg:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if mg.get('url'):
|
||||||
|
m = re.match(r'(?P<url>rtmpe?://[^/]+)/(?P<app>.+)/(?P<playpath>mp4:.*)', mg['url'])
|
||||||
|
if m:
|
||||||
|
m = m.groupdict()
|
||||||
|
formats.append({
|
||||||
|
'url': m['url'] + '/' + m['app'],
|
||||||
|
'app': m['app'],
|
||||||
|
'play_path': m['playpath'],
|
||||||
|
'player_url': url,
|
||||||
|
'ext': 'flv',
|
||||||
|
'format_id': 'rtmp',
|
||||||
|
})
|
||||||
|
|
||||||
|
if mg.get('hls_server') and mg.get('hls_url'):
|
||||||
|
formats.extend(self._extract_m3u8_formats(
|
||||||
|
mg['hls_server'] + mg['hls_url'], item_id, 'mp4',
|
||||||
|
entry_protocol='m3u8_native', m3u8_id='hls', fatal=False))
|
||||||
|
|
||||||
|
if mg.get('hds_server') and mg.get('hds_url'):
|
||||||
|
formats.extend(self._extract_f4m_formats(
|
||||||
|
mg['hds_server'] + mg['hds_url'], item_id,
|
||||||
|
f4m_id='hds', fatal=False))
|
||||||
|
|
||||||
|
mg_rte_server = str_or_none(mg.get('rte:server'))
|
||||||
|
mg_url = str_or_none(mg.get('url'))
|
||||||
|
if mg_rte_server and mg_url:
|
||||||
|
hds_url = url_or_none(mg_rte_server + mg_url)
|
||||||
|
if hds_url:
|
||||||
|
formats.extend(self._extract_f4m_formats(
|
||||||
|
hds_url, item_id, f4m_id='hds', fatal=False))
|
||||||
|
|
||||||
self._sort_formats(formats)
|
self._sort_formats(formats)
|
||||||
|
|
||||||
return {
|
info_dict['formats'] = formats
|
||||||
'id': item_id,
|
return info_dict
|
||||||
'title': title,
|
|
||||||
'description': description,
|
|
||||||
'thumbnail': thumbnail,
|
|
||||||
'timestamp': timestamp,
|
|
||||||
'duration': duration,
|
|
||||||
'formats': formats,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class RteIE(RteBaseIE):
|
class RteIE(RteBaseIE):
|
||||||
|
@ -64,7 +64,7 @@ class SixPlayIE(InfoExtractor):
|
|||||||
for asset in clip_data['assets']:
|
for asset in clip_data['assets']:
|
||||||
asset_url = asset.get('full_physical_path')
|
asset_url = asset.get('full_physical_path')
|
||||||
protocol = asset.get('protocol')
|
protocol = asset.get('protocol')
|
||||||
if not asset_url or protocol == 'primetime' or asset_url in urls:
|
if not asset_url or protocol == 'primetime' or asset.get('type') == 'usp_hlsfp_h264' or asset_url in urls:
|
||||||
continue
|
continue
|
||||||
urls.append(asset_url)
|
urls.append(asset_url)
|
||||||
container = asset.get('video_container')
|
container = asset.get('video_container')
|
||||||
@ -81,19 +81,17 @@ class SixPlayIE(InfoExtractor):
|
|||||||
if not urlh:
|
if not urlh:
|
||||||
continue
|
continue
|
||||||
asset_url = urlh.geturl()
|
asset_url = urlh.geturl()
|
||||||
asset_url = re.sub(r'/([^/]+)\.ism/[^/]*\.m3u8', r'/\1.ism/\1.m3u8', asset_url)
|
for i in range(3, 0, -1):
|
||||||
formats.extend(self._extract_m3u8_formats(
|
asset_url = asset_url = asset_url.replace('_sd1/', '_sd%d/' % i)
|
||||||
asset_url, video_id, 'mp4', 'm3u8_native',
|
m3u8_formats = self._extract_m3u8_formats(
|
||||||
m3u8_id='hls', fatal=False))
|
asset_url, video_id, 'mp4', 'm3u8_native',
|
||||||
formats.extend(self._extract_f4m_formats(
|
m3u8_id='hls', fatal=False)
|
||||||
asset_url.replace('.m3u8', '.f4m'),
|
formats.extend(m3u8_formats)
|
||||||
video_id, f4m_id='hds', fatal=False))
|
formats.extend(self._extract_mpd_formats(
|
||||||
formats.extend(self._extract_mpd_formats(
|
asset_url.replace('.m3u8', '.mpd'),
|
||||||
asset_url.replace('.m3u8', '.mpd'),
|
video_id, mpd_id='dash', fatal=False))
|
||||||
video_id, mpd_id='dash', fatal=False))
|
if m3u8_formats:
|
||||||
formats.extend(self._extract_ism_formats(
|
break
|
||||||
re.sub(r'/[^/]+\.m3u8', '/Manifest', asset_url),
|
|
||||||
video_id, ism_id='mss', fatal=False))
|
|
||||||
else:
|
else:
|
||||||
formats.extend(self._extract_m3u8_formats(
|
formats.extend(self._extract_m3u8_formats(
|
||||||
asset_url, video_id, 'mp4', 'm3u8_native',
|
asset_url, video_id, 'mp4', 'm3u8_native',
|
||||||
|
@ -18,8 +18,9 @@ from ..utils import (
|
|||||||
class TNAFlixNetworkBaseIE(InfoExtractor):
|
class TNAFlixNetworkBaseIE(InfoExtractor):
|
||||||
# May be overridden in descendants if necessary
|
# May be overridden in descendants if necessary
|
||||||
_CONFIG_REGEX = [
|
_CONFIG_REGEX = [
|
||||||
r'flashvars\.config\s*=\s*escape\("([^"]+)"',
|
r'flashvars\.config\s*=\s*escape\("(?P<url>[^"]+)"',
|
||||||
r'<input[^>]+name="config\d?" value="([^"]+)"',
|
r'<input[^>]+name="config\d?" value="(?P<url>[^"]+)"',
|
||||||
|
r'config\s*=\s*(["\'])(?P<url>(?:https?:)?//(?:(?!\1).)+)\1',
|
||||||
]
|
]
|
||||||
_HOST = 'tna'
|
_HOST = 'tna'
|
||||||
_VKEY_SUFFIX = ''
|
_VKEY_SUFFIX = ''
|
||||||
@ -85,7 +86,8 @@ class TNAFlixNetworkBaseIE(InfoExtractor):
|
|||||||
webpage = self._download_webpage(url, display_id)
|
webpage = self._download_webpage(url, display_id)
|
||||||
|
|
||||||
cfg_url = self._proto_relative_url(self._html_search_regex(
|
cfg_url = self._proto_relative_url(self._html_search_regex(
|
||||||
self._CONFIG_REGEX, webpage, 'flashvars.config', default=None), 'http:')
|
self._CONFIG_REGEX, webpage, 'flashvars.config', default=None,
|
||||||
|
group='url'), 'http:')
|
||||||
|
|
||||||
if not cfg_url:
|
if not cfg_url:
|
||||||
inputs = self._hidden_inputs(webpage)
|
inputs = self._hidden_inputs(webpage)
|
||||||
|
@ -293,8 +293,12 @@ class VKIE(VKBaseIE):
|
|||||||
# This video is no longer available, because its author has been blocked.
|
# This video is no longer available, because its author has been blocked.
|
||||||
'url': 'https://vk.com/video-10639516_456240611',
|
'url': 'https://vk.com/video-10639516_456240611',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
|
# The video is not available in your region.
|
||||||
|
'url': 'https://vk.com/video-51812607_171445436',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
mobj = re.match(self._VALID_URL, url)
|
mobj = re.match(self._VALID_URL, url)
|
||||||
@ -354,6 +358,9 @@ class VKIE(VKBaseIE):
|
|||||||
|
|
||||||
r'<!>This video is no longer available, because it has been deleted.':
|
r'<!>This video is no longer available, because it has been deleted.':
|
||||||
'Video %s is no longer available, because it has been deleted.',
|
'Video %s is no longer available, because it has been deleted.',
|
||||||
|
|
||||||
|
r'<!>The video .+? is not available in your region.':
|
||||||
|
'Video %s is not available in your region.',
|
||||||
}
|
}
|
||||||
|
|
||||||
for error_re, error_msg in ERRORS.items():
|
for error_re, error_msg in ERRORS.items():
|
||||||
|
140
youtube_dl/extractor/wwe.py
Normal file
140
youtube_dl/extractor/wwe.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..compat import compat_str
|
||||||
|
from ..utils import (
|
||||||
|
try_get,
|
||||||
|
unescapeHTML,
|
||||||
|
url_or_none,
|
||||||
|
urljoin,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class WWEBaseIE(InfoExtractor):
|
||||||
|
_SUBTITLE_LANGS = {
|
||||||
|
'English': 'en',
|
||||||
|
'Deutsch': 'de',
|
||||||
|
}
|
||||||
|
|
||||||
|
def _extract_entry(self, data, url, video_id=None):
|
||||||
|
video_id = compat_str(video_id or data['nid'])
|
||||||
|
title = data['title']
|
||||||
|
|
||||||
|
formats = self._extract_m3u8_formats(
|
||||||
|
data['file'], video_id, 'mp4', entry_protocol='m3u8_native',
|
||||||
|
m3u8_id='hls')
|
||||||
|
|
||||||
|
description = data.get('description')
|
||||||
|
thumbnail = urljoin(url, data.get('image'))
|
||||||
|
series = data.get('show_name')
|
||||||
|
episode = data.get('episode_name')
|
||||||
|
|
||||||
|
subtitles = {}
|
||||||
|
tracks = data.get('tracks')
|
||||||
|
if isinstance(tracks, list):
|
||||||
|
for track in tracks:
|
||||||
|
if not isinstance(track, dict):
|
||||||
|
continue
|
||||||
|
if track.get('kind') != 'captions':
|
||||||
|
continue
|
||||||
|
track_file = url_or_none(track.get('file'))
|
||||||
|
if not track_file:
|
||||||
|
continue
|
||||||
|
label = track.get('label')
|
||||||
|
lang = self._SUBTITLE_LANGS.get(label, label) or 'en'
|
||||||
|
subtitles.setdefault(lang, []).append({
|
||||||
|
'url': track_file,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
'id': video_id,
|
||||||
|
'title': title,
|
||||||
|
'description': description,
|
||||||
|
'thumbnail': thumbnail,
|
||||||
|
'series': series,
|
||||||
|
'episode': episode,
|
||||||
|
'formats': formats,
|
||||||
|
'subtitles': subtitles,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class WWEIE(WWEBaseIE):
|
||||||
|
_VALID_URL = r'https?://(?:[^/]+\.)?wwe\.com/(?:[^/]+/)*videos/(?P<id>[^/?#&]+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://www.wwe.com/videos/daniel-bryan-vs-andrade-cien-almas-smackdown-live-sept-4-2018',
|
||||||
|
'md5': '92811c6a14bfc206f7a6a9c5d9140184',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '40048199',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Daniel Bryan vs. Andrade "Cien" Almas: SmackDown LIVE, Sept. 4, 2018',
|
||||||
|
'description': 'md5:2d7424dbc6755c61a0e649d2a8677f67',
|
||||||
|
'thumbnail': r're:^https?://.*\.jpg$',
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'url': 'https://de.wwe.com/videos/gran-metalik-vs-tony-nese-wwe-205-live-sept-4-2018',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
display_id = self._match_id(url)
|
||||||
|
webpage = self._download_webpage(url, display_id)
|
||||||
|
|
||||||
|
landing = self._parse_json(
|
||||||
|
self._html_search_regex(
|
||||||
|
r'(?s)Drupal\.settings\s*,\s*({.+?})\s*\)\s*;',
|
||||||
|
webpage, 'drupal settings'),
|
||||||
|
display_id)['WWEVideoLanding']
|
||||||
|
|
||||||
|
data = landing['initialVideo']['playlist'][0]
|
||||||
|
video_id = landing.get('initialVideoId')
|
||||||
|
|
||||||
|
info = self._extract_entry(data, url, video_id)
|
||||||
|
info['display_id'] = display_id
|
||||||
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
class WWEPlaylistIE(WWEBaseIE):
|
||||||
|
_VALID_URL = r'https?://(?:[^/]+\.)?wwe\.com/(?:[^/]+/)*(?P<id>[^/?#&]+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://www.wwe.com/shows/raw/2018-11-12',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '2018-11-12',
|
||||||
|
},
|
||||||
|
'playlist_mincount': 11,
|
||||||
|
}, {
|
||||||
|
'url': 'http://www.wwe.com/article/walk-the-prank-wwe-edition',
|
||||||
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.wwe.com/shows/wwenxt/article/matt-riddle-interview',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def suitable(cls, url):
|
||||||
|
return False if WWEIE.suitable(url) else super(WWEPlaylistIE, cls).suitable(url)
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
display_id = self._match_id(url)
|
||||||
|
webpage = self._download_webpage(url, display_id)
|
||||||
|
|
||||||
|
entries = []
|
||||||
|
for mobj in re.finditer(
|
||||||
|
r'data-video\s*=\s*(["\'])(?P<data>{.+?})\1', webpage):
|
||||||
|
video = self._parse_json(
|
||||||
|
mobj.group('data'), display_id, transform_source=unescapeHTML,
|
||||||
|
fatal=False)
|
||||||
|
if not video:
|
||||||
|
continue
|
||||||
|
data = try_get(video, lambda x: x['playlist'][0], dict)
|
||||||
|
if not data:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
entry = self._extract_entry(data, url)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
entry['extractor_key'] = WWEIE.ie_key()
|
||||||
|
entries.append(entry)
|
||||||
|
|
||||||
|
return self.playlist_result(entries, display_id)
|
@ -1,3 +1,3 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
__version__ = '2018.11.07'
|
__version__ = '2018.11.18'
|
||||||
|
Loading…
Reference in New Issue
Block a user