|
)([^<]+)', webpage, 'episode title')
+ if episode_title:
+ episode_title = episode_title.strip()
title = '%s - %s' % (podcast_title, episode_title) if podcast_title else episode_title
description = self._html_search_regex(
- r'
(.+?)
', webpage,
+ r'(.+?)
', webpage,
'description', default=None)
- thumbnail = self._search_regex(
- r'
![]()
]+class="info-show-icon"[^>]+src="([^"]+)"',
- webpage, 'thumbnail', fatal=False)
+ if description:
+ # Strip non-breaking and normal spaces
+ description = description.replace('\u00A0', ' ').strip()
release_date = unified_strdate(self._search_regex(
r'
Released: ([^<]+)<', webpage, 'release date', fatal=False))
+ data_json = self._search_regex(r'var\s+playlistItem\s*=\s*(\{.*?\});\n', webpage, 'JSON data block')
+ data = json.loads(data_json)
+
+ formats = [{
+ 'url': data['media_url'],
+ 'format_id': 'main',
+ }, {
+ 'url': data['media_url_libsyn'],
+ 'format_id': 'libsyn',
+ }]
+ thumbnail = data.get('thumbnail_url')
+ duration = parse_duration(data.get('duration'))
+
return {
'id': video_id,
'title': title,
'description': description,
'thumbnail': thumbnail,
'upload_date': release_date,
+ 'duration': duration,
'formats': formats,
}
diff --git a/youtube_dl/extractor/liveleak.py b/youtube_dl/extractor/liveleak.py
index 246aac576..26671753c 100644
--- a/youtube_dl/extractor/liveleak.py
+++ b/youtube_dl/extractor/liveleak.py
@@ -7,7 +7,7 @@ from ..utils import int_or_none
class LiveLeakIE(InfoExtractor):
- _VALID_URL = r'https?://(?:\w+\.)?liveleak\.com/view\?(?:.*?)i=(?P
[\w_]+)(?:.*)'
+ _VALID_URL = r'https?://(?:\w+\.)?liveleak\.com/view\?.*?\b[it]=(?P[\w_]+)'
_TESTS = [{
'url': 'http://www.liveleak.com/view?i=757_1364311680',
'md5': '0813c2430bea7a46bf13acf3406992f4',
@@ -79,6 +79,9 @@ class LiveLeakIE(InfoExtractor):
'title': 'Fuel Depot in China Explosion caught on video',
},
'playlist_count': 3,
+ }, {
+ 'url': 'https://www.liveleak.com/view?t=HvHi_1523016227',
+ 'only_matching': True,
}]
@staticmethod
diff --git a/youtube_dl/extractor/medialaan.py b/youtube_dl/extractor/medialaan.py
index f8c30052f..50d5db802 100644
--- a/youtube_dl/extractor/medialaan.py
+++ b/youtube_dl/extractor/medialaan.py
@@ -141,6 +141,7 @@ class MedialaanIE(GigyaBaseIE):
vod_id = config.get('vodId') or self._search_regex(
(r'\\"vodId\\"\s*:\s*\\"(.+?)\\"',
+ r'"vodId"\s*:\s*"(.+?)"',
r'<[^>]+id=["\']vod-(\d+)'),
webpage, 'video_id', default=None)
diff --git a/youtube_dl/extractor/nationalgeographic.py b/youtube_dl/extractor/nationalgeographic.py
index 246f6795a..4d2ee6408 100644
--- a/youtube_dl/extractor/nationalgeographic.py
+++ b/youtube_dl/extractor/nationalgeographic.py
@@ -68,11 +68,11 @@ class NationalGeographicVideoIE(InfoExtractor):
class NationalGeographicIE(ThePlatformIE, AdobePassIE):
IE_NAME = 'natgeo'
- _VALID_URL = r'https?://channel\.nationalgeographic\.com/(?:(?:wild/)?[^/]+/)?(?:videos|episodes)/(?P[^/?]+)'
+ _VALID_URL = r'https?://channel\.nationalgeographic\.com/(?:(?:(?:wild/)?[^/]+/)?(?:videos|episodes)|u)/(?P[^/?]+)'
_TESTS = [
{
- 'url': 'http://channel.nationalgeographic.com/the-story-of-god-with-morgan-freeman/videos/uncovering-a-universal-knowledge/',
+ 'url': 'http://channel.nationalgeographic.com/u/kdi9Ld0PN2molUUIMSBGxoeDhD729KRjQcnxtetilWPMevo8ZwUBIDuPR0Q3D2LVaTsk0MPRkRWDB8ZhqWVeyoxfsZZm36yRp1j-zPfsHEyI_EgAeFY/',
'md5': '518c9aa655686cf81493af5cc21e2a04',
'info_dict': {
'id': 'vKInpacll2pC',
@@ -86,7 +86,7 @@ class NationalGeographicIE(ThePlatformIE, AdobePassIE):
'add_ie': ['ThePlatform'],
},
{
- 'url': 'http://channel.nationalgeographic.com/wild/destination-wild/videos/the-stunning-red-bird-of-paradise/',
+ 'url': 'http://channel.nationalgeographic.com/u/kdvOstqYaBY-vSBPyYgAZRUL4sWUJ5XUUPEhc7ISyBHqoIO4_dzfY3K6EjHIC0hmFXoQ7Cpzm6RkET7S3oMlm6CFnrQwSUwo/',
'md5': 'c4912f656b4cbe58f3e000c489360989',
'info_dict': {
'id': 'Pok5lWCkiEFA',
@@ -106,6 +106,14 @@ class NationalGeographicIE(ThePlatformIE, AdobePassIE):
{
'url': 'http://channel.nationalgeographic.com/videos/treasures-rediscovered/',
'only_matching': True,
+ },
+ {
+ 'url': 'http://channel.nationalgeographic.com/the-story-of-god-with-morgan-freeman/videos/uncovering-a-universal-knowledge/',
+ 'only_matching': True,
+ },
+ {
+ 'url': 'http://channel.nationalgeographic.com/wild/destination-wild/videos/the-stunning-red-bird-of-paradise/',
+ 'only_matching': True,
}
]
diff --git a/youtube_dl/extractor/naver.py b/youtube_dl/extractor/naver.py
index 2047d4402..bb3d94413 100644
--- a/youtube_dl/extractor/naver.py
+++ b/youtube_dl/extractor/naver.py
@@ -1,8 +1,6 @@
# coding: utf-8
from __future__ import unicode_literals
-import re
-
from .common import InfoExtractor
from ..utils import (
ExtractorError,
@@ -43,9 +41,14 @@ class NaverIE(InfoExtractor):
video_id = self._match_id(url)
webpage = self._download_webpage(url, video_id)
- m_id = re.search(r'var rmcPlayer = new nhn\.rmcnmv\.RMCVideoPlayer\("(.+?)", "(.+?)"',
- webpage)
- if m_id is None:
+ vid = self._search_regex(
+ r'videoId["\']\s*:\s*(["\'])(?P(?:(?!\1).)+)\1', webpage,
+ 'video id', fatal=None, group='value')
+ in_key = self._search_regex(
+ r'inKey["\']\s*:\s*(["\'])(?P(?:(?!\1).)+)\1', webpage,
+ 'key', default=None, group='value')
+
+ if not vid or not in_key:
error = self._html_search_regex(
r'(?s)',
webpage, 'error', default=None)
@@ -53,9 +56,9 @@ class NaverIE(InfoExtractor):
raise ExtractorError(error, expected=True)
raise ExtractorError('couldn\'t extract vid and key')
video_data = self._download_json(
- 'http://play.rmcnmv.naver.com/vod/play/v2.0/' + m_id.group(1),
+ 'http://play.rmcnmv.naver.com/vod/play/v2.0/' + vid,
video_id, query={
- 'key': m_id.group(2),
+ 'key': in_key,
})
meta = video_data['meta']
title = meta['subject']
diff --git a/youtube_dl/extractor/ninenow.py b/youtube_dl/extractor/ninenow.py
index 351bea7ba..f32f530f7 100644
--- a/youtube_dl/extractor/ninenow.py
+++ b/youtube_dl/extractor/ninenow.py
@@ -4,15 +4,17 @@ from __future__ import unicode_literals
from .common import InfoExtractor
from ..compat import compat_str
from ..utils import (
+ ExtractorError,
int_or_none,
float_or_none,
- ExtractorError,
+ smuggle_url,
)
class NineNowIE(InfoExtractor):
IE_NAME = '9now.com.au'
_VALID_URL = r'https?://(?:www\.)?9now\.com\.au/(?:[^/]+/){2}(?P[^/?#]+)'
+ _GEO_COUNTRIES = ['AU']
_TESTS = [{
# clip
'url': 'https://www.9now.com.au/afl-footy-show/2016/clip-ciql02091000g0hp5oktrnytc',
@@ -75,7 +77,9 @@ class NineNowIE(InfoExtractor):
return {
'_type': 'url_transparent',
- 'url': self.BRIGHTCOVE_URL_TEMPLATE % brightcove_id,
+ 'url': smuggle_url(
+ self.BRIGHTCOVE_URL_TEMPLATE % brightcove_id,
+ {'geo_countries': self._GEO_COUNTRIES}),
'id': video_id,
'title': title,
'description': common_data.get('description'),
diff --git a/youtube_dl/extractor/odnoklassniki.py b/youtube_dl/extractor/odnoklassniki.py
index 5c8b37e18..190d8af4d 100644
--- a/youtube_dl/extractor/odnoklassniki.py
+++ b/youtube_dl/extractor/odnoklassniki.py
@@ -19,7 +19,18 @@ from ..utils import (
class OdnoklassnikiIE(InfoExtractor):
- _VALID_URL = r'https?://(?:(?:www|m|mobile)\.)?(?:odnoklassniki|ok)\.ru/(?:video(?:embed)?|web-api/video/moviePlayer|live)/(?P[\d-]+)'
+ _VALID_URL = r'''(?x)
+ https?://
+ (?:(?:www|m|mobile)\.)?
+ (?:odnoklassniki|ok)\.ru/
+ (?:
+ video(?:embed)?/|
+ web-api/video/moviePlayer/|
+ live/|
+ dk\?.*?st\.mvId=
+ )
+ (?P[\d-]+)
+ '''
_TESTS = [{
# metadata in JSON
'url': 'http://ok.ru/video/20079905452',
@@ -101,6 +112,9 @@ class OdnoklassnikiIE(InfoExtractor):
}, {
'url': 'https://www.ok.ru/live/484531969818',
'only_matching': True,
+ }, {
+ 'url': 'https://m.ok.ru/dk?st.cmd=movieLayer&st.discId=863789452017&st.retLoc=friend&st.rtu=%2Fdk%3Fst.cmd%3DfriendMovies%26st.mode%3Down%26st.mrkId%3D%257B%2522uploadedMovieMarker%2522%253A%257B%2522marker%2522%253A%25221519410114503%2522%252C%2522hasMore%2522%253Atrue%257D%252C%2522sharedMovieMarker%2522%253A%257B%2522marker%2522%253Anull%252C%2522hasMore%2522%253Afalse%257D%257D%26st.friendId%3D561722190321%26st.frwd%3Don%26_prevCmd%3DfriendMovies%26tkn%3D7257&st.discType=MOVIE&st.mvId=863789452017&_prevCmd=friendMovies&tkn=3648#lst#',
+ 'only_matching': True,
}]
def _real_extract(self, url):
diff --git a/youtube_dl/extractor/openload.py b/youtube_dl/extractor/openload.py
index eaaaf8a08..650f95656 100644
--- a/youtube_dl/extractor/openload.py
+++ b/youtube_dl/extractor/openload.py
@@ -243,7 +243,7 @@ class PhantomJSwrapper(object):
class OpenloadIE(InfoExtractor):
- _VALID_URL = r'https?://(?:www\.)?(?:openload\.(?:co|io|link)|oload\.(?:tv|stream))/(?:f|embed)/(?P[a-zA-Z0-9-_]+)'
+ _VALID_URL = r'https?://(?:www\.)?(?:openload\.(?:co|io|link)|oload\.(?:tv|stream|site|xyz))/(?:f|embed)/(?P[a-zA-Z0-9-_]+)'
_TESTS = [{
'url': 'https://openload.co/f/kUEfGclsU9o',
@@ -298,6 +298,9 @@ class OpenloadIE(InfoExtractor):
}, {
'url': 'https://oload.stream/f/KnG-kKZdcfY',
'only_matching': True,
+ }, {
+ 'url': 'https://oload.xyz/f/WwRBpzW8Wtk',
+ 'only_matching': True,
}]
_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
@@ -334,10 +337,11 @@ class OpenloadIE(InfoExtractor):
decoded_id = (get_element_by_id('streamurl', webpage) or
get_element_by_id('streamuri', webpage) or
- get_element_by_id('streamurj', webpage))
-
- if not decoded_id:
- raise ExtractorError('Can\'t find stream URL', video_id=video_id)
+ get_element_by_id('streamurj', webpage) or
+ self._search_regex(
+ (r'>\s*([\w-]+~\d{10,}~\d+\.\d+\.0\.0~[\w-]+)\s*<',
+ r'>\s*([\w~-]+~\d+\.\d+\.\d+\.\d+~[\w~-]+)'), webpage,
+ 'stream URL'))
video_url = 'https://openload.co/stream/%s?mime=true' % decoded_id
diff --git a/youtube_dl/extractor/pornhub.py b/youtube_dl/extractor/pornhub.py
index 9ce513aeb..23e24d216 100644
--- a/youtube_dl/extractor/pornhub.py
+++ b/youtube_dl/extractor/pornhub.py
@@ -33,7 +33,7 @@ class PornHubIE(InfoExtractor):
_VALID_URL = r'''(?x)
https?://
(?:
- (?:[a-z]+\.)?pornhub\.com/(?:(?:view_video\.php|video/show)\?viewkey=|embed/)|
+ (?:[^/]+\.)?pornhub\.com/(?:(?:view_video\.php|video/show)\?viewkey=|embed/)|
(?:www\.)?thumbzilla\.com/video/
)
(?P[\da-z]+)
@@ -264,7 +264,7 @@ class PornHubPlaylistBaseIE(InfoExtractor):
class PornHubPlaylistIE(PornHubPlaylistBaseIE):
- _VALID_URL = r'https?://(?:www\.)?pornhub\.com/playlist/(?P\d+)'
+ _VALID_URL = r'https?://(?:[^/]+\.)?pornhub\.com/playlist/(?P\d+)'
_TESTS = [{
'url': 'http://www.pornhub.com/playlist/4667351',
'info_dict': {
@@ -272,11 +272,14 @@ class PornHubPlaylistIE(PornHubPlaylistBaseIE):
'title': 'Nataly Hot',
},
'playlist_mincount': 2,
+ }, {
+ 'url': 'https://de.pornhub.com/playlist/4667351',
+ 'only_matching': True,
}]
class PornHubUserVideosIE(PornHubPlaylistBaseIE):
- _VALID_URL = r'https?://(?:www\.)?pornhub\.com/(?:user|channel)s/(?P[^/]+)/videos'
+ _VALID_URL = r'https?://(?:[^/]+\.)?pornhub\.com/(?:user|channel)s/(?P[^/]+)/videos'
_TESTS = [{
'url': 'http://www.pornhub.com/users/zoe_ph/videos/public',
'info_dict': {
@@ -305,6 +308,9 @@ class PornHubUserVideosIE(PornHubPlaylistBaseIE):
# Most Viewed Videos
'url': 'https://www.pornhub.com/channels/povd/videos?o=vi',
'only_matching': True,
+ }, {
+ 'url': 'http://www.pornhub.com/users/zoe_ph/videos/public',
+ 'only_matching': True,
}]
def _real_extract(self, url):
diff --git a/youtube_dl/extractor/prosiebensat1.py b/youtube_dl/extractor/prosiebensat1.py
index 7efff4566..d0955d079 100644
--- a/youtube_dl/extractor/prosiebensat1.py
+++ b/youtube_dl/extractor/prosiebensat1.py
@@ -133,7 +133,7 @@ class ProSiebenSat1IE(ProSiebenSat1BaseIE):
(?:
prosieben(?:maxx)?|sixx|sat1(?:gold)?|kabeleins(?:doku)?|the-voice-of-germany|7tv|advopedia
)\.(?:de|at|ch)|
- ran\.de|fem\.com|advopedia\.de
+ ran\.de|fem\.com|advopedia\.de|galileo\.tv/video
)
/(?P.+)
'''
@@ -326,6 +326,11 @@ class ProSiebenSat1IE(ProSiebenSat1BaseIE):
'url': 'http://www.sat1gold.de/tv/edel-starck/video/11-staffel-1-episode-1-partner-wider-willen-ganze-folge',
'only_matching': True,
},
+ {
+ # geo restricted to Germany
+ 'url': 'https://www.galileo.tv/video/diese-emojis-werden-oft-missverstanden',
+ 'only_matching': True,
+ },
{
'url': 'http://www.sat1gold.de/tv/edel-starck/playlist/die-gesamte-1-staffel',
'only_matching': True,
@@ -343,7 +348,7 @@ class ProSiebenSat1IE(ProSiebenSat1BaseIE):
r'"clip_id"\s*:\s+"(\d+)"',
r'clipid: "(\d+)"',
r'clip[iI]d=(\d+)',
- r'clip[iI]d\s*=\s*["\'](\d+)',
+ r'clip[iI][dD]\s*=\s*["\'](\d+)',
r"'itemImageUrl'\s*:\s*'/dynamic/thumbnails/full/\d+/(\d+)",
r'proMamsId"\s*:\s*"(\d+)',
r'proMamsId"\s*:\s*"(\d+)',
diff --git a/youtube_dl/extractor/sevenplus.py b/youtube_dl/extractor/sevenplus.py
index 9792f820a..84568ac69 100644
--- a/youtube_dl/extractor/sevenplus.py
+++ b/youtube_dl/extractor/sevenplus.py
@@ -4,22 +4,30 @@ from __future__ import unicode_literals
import re
from .brightcove import BrightcoveNewIE
-from ..utils import update_url_query
+from ..compat import compat_str
+from ..utils import (
+ try_get,
+ update_url_query,
+)
class SevenPlusIE(BrightcoveNewIE):
IE_NAME = '7plus'
_VALID_URL = r'https?://(?:www\.)?7plus\.com\.au/(?P[^?]+\?.*?\bepisode-id=(?P[^]+))'
_TESTS = [{
- 'url': 'https://7plus.com.au/BEAT?episode-id=BEAT-001',
+ 'url': 'https://7plus.com.au/MTYS?episode-id=MTYS7-003',
'info_dict': {
- 'id': 'BEAT-001',
+ 'id': 'MTYS7-003',
'ext': 'mp4',
- 'title': 'S1 E1 - Help / Lucy In The Sky With Diamonds',
- 'description': 'md5:37718bea20a8eedaca7f7361af566131',
+ 'title': 'S7 E3 - Wind Surf',
+ 'description': 'md5:29c6a69f21accda7601278f81b46483d',
'uploader_id': '5303576322001',
- 'upload_date': '20171031',
- 'timestamp': 1509440068,
+ 'upload_date': '20171201',
+ 'timestamp': 1512106377,
+ 'series': 'Mighty Ships',
+ 'season_number': 7,
+ 'episode_number': 3,
+ 'episode': 'Wind Surf',
},
'params': {
'format': 'bestvideo',
@@ -63,5 +71,14 @@ class SevenPlusIE(BrightcoveNewIE):
value = item.get(src_key)
if value:
info[dst_key] = value
+ info['series'] = try_get(
+ item, lambda x: x['seriesLogo']['name'], compat_str)
+ mobj = re.search(r'^S(\d+)\s+E(\d+)\s+-\s+(.+)$', info['title'])
+ if mobj:
+ info.update({
+ 'season_number': int(mobj.group(1)),
+ 'episode_number': int(mobj.group(2)),
+ 'episode': mobj.group(3),
+ })
return info
diff --git a/youtube_dl/extractor/steam.py b/youtube_dl/extractor/steam.py
index e5ac586a7..a6a191ceb 100644
--- a/youtube_dl/extractor/steam.py
+++ b/youtube_dl/extractor/steam.py
@@ -75,6 +75,9 @@ class SteamIE(InfoExtractor):
gameID = m.group('gameID')
playlist_id = gameID
videourl = self._VIDEO_PAGE_TEMPLATE % playlist_id
+
+ self._set_cookie('steampowered.com', 'mature_content', '1')
+
webpage = self._download_webpage(videourl, playlist_id)
if re.search('Please enter your birth date to continue:
', webpage) is not None:
diff --git a/youtube_dl/extractor/svt.py b/youtube_dl/extractor/svt.py
index 48bc4529e..b544da414 100644
--- a/youtube_dl/extractor/svt.py
+++ b/youtube_dl/extractor/svt.py
@@ -4,11 +4,17 @@ from __future__ import unicode_literals
import re
from .common import InfoExtractor
+from ..compat import (
+ compat_parse_qs,
+ compat_urllib_parse_urlparse,
+)
from ..utils import (
determine_ext,
dict_get,
int_or_none,
try_get,
+ urljoin,
+ compat_str,
)
@@ -122,7 +128,11 @@ class SVTIE(SVTBaseIE):
return info_dict
-class SVTPlayIE(SVTBaseIE):
+class SVTPlayBaseIE(SVTBaseIE):
+ _SVTPLAY_RE = r'root\s*\[\s*(["\'])_*svtplay\1\s*\]\s*=\s*(?P{.+?})\s*;\s*\n'
+
+
+class SVTPlayIE(SVTPlayBaseIE):
IE_DESC = 'SVT Play and Öppet arkiv'
_VALID_URL = r'https?://(?:www\.)?(?:svtplay|oppetarkiv)\.se/(?:video|klipp)/(?P[0-9]+)'
_TESTS = [{
@@ -157,8 +167,8 @@ class SVTPlayIE(SVTBaseIE):
data = self._parse_json(
self._search_regex(
- r'root\["__svtplay"\]\s*=\s*([^;]+);',
- webpage, 'embedded data', default='{}'),
+ self._SVTPLAY_RE, webpage, 'embedded data', default='{}',
+ group='json'),
video_id, fatal=False)
thumbnail = self._og_search_thumbnail(webpage)
@@ -189,3 +199,84 @@ class SVTPlayIE(SVTBaseIE):
r'\s*\|\s*.+?$', '',
info_dict.get('episode') or self._og_search_title(webpage))
return info_dict
+
+
+class SVTSeriesIE(SVTPlayBaseIE):
+ _VALID_URL = r'https?://(?:www\.)?svtplay\.se/(?P[^/?]+)'
+ _TESTS = [{
+ 'url': 'https://www.svtplay.se/rederiet',
+ 'info_dict': {
+ 'id': 'rederiet',
+ 'title': 'Rederiet',
+ 'description': 'md5:505d491a58f4fcf6eb418ecab947e69e',
+ },
+ 'playlist_mincount': 318,
+ }, {
+ 'url': 'https://www.svtplay.se/rederiet?tab=sasong2',
+ 'info_dict': {
+ 'id': 'rederiet-sasong2',
+ 'title': 'Rederiet - Säsong 2',
+ 'description': 'md5:505d491a58f4fcf6eb418ecab947e69e',
+ },
+ 'playlist_count': 12,
+ }]
+
+ @classmethod
+ def suitable(cls, url):
+ return False if SVTIE.suitable(url) or SVTPlayIE.suitable(url) else super(SVTSeriesIE, cls).suitable(url)
+
+ def _real_extract(self, url):
+ series_id = self._match_id(url)
+
+ qs = compat_parse_qs(compat_urllib_parse_urlparse(url).query)
+ season_slug = qs.get('tab', [None])[0]
+
+ if season_slug:
+ series_id += '-%s' % season_slug
+
+ webpage = self._download_webpage(
+ url, series_id, 'Downloading series page')
+
+ root = self._parse_json(
+ self._search_regex(
+ self._SVTPLAY_RE, webpage, 'content', group='json'),
+ series_id)
+
+ season_name = None
+
+ entries = []
+ for season in root['relatedVideoContent']['relatedVideosAccordion']:
+ if not isinstance(season, dict):
+ continue
+ if season_slug:
+ if season.get('slug') != season_slug:
+ continue
+ season_name = season.get('name')
+ videos = season.get('videos')
+ if not isinstance(videos, list):
+ continue
+ for video in videos:
+ content_url = video.get('contentUrl')
+ if not content_url or not isinstance(content_url, compat_str):
+ continue
+ entries.append(
+ self.url_result(
+ urljoin(url, content_url),
+ ie=SVTPlayIE.ie_key(),
+ video_title=video.get('title')
+ ))
+
+ metadata = root.get('metaData')
+ if not isinstance(metadata, dict):
+ metadata = {}
+
+ title = metadata.get('title')
+ season_name = season_name or season_slug
+
+ if title and season_name:
+ title = '%s - %s' % (title, season_name)
+ elif season_slug:
+ title = season_slug
+
+ return self.playlist_result(
+ entries, series_id, title, metadata.get('description'))
diff --git a/youtube_dl/extractor/tube8.py b/youtube_dl/extractor/tube8.py
index 1853a1104..368c45729 100644
--- a/youtube_dl/extractor/tube8.py
+++ b/youtube_dl/extractor/tube8.py
@@ -31,6 +31,12 @@ class Tube8IE(KeezMoviesIE):
'only_matching': True,
}]
+ @staticmethod
+ def _extract_urls(webpage):
+ return re.findall(
+ r'