From 3266d08af29bbd6078aca172741458ddee180ab9 Mon Sep 17 00:00:00 2001 From: John Hawkinson Date: Sat, 25 Mar 2017 19:47:48 -0400 Subject: [PATCH 001/128] [wsj:article] Add extractor --- youtube_dl/extractor/extractors.py | 5 ++++- youtube_dl/extractor/wsj.py | 28 +++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index 1671090f4..72d28a7e6 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -1233,7 +1233,10 @@ from .wrzuta import ( WrzutaIE, WrzutaPlaylistIE, ) -from .wsj import WSJIE +from .wsj import ( + WSJIE, + WSJArticleIE, +) from .xbef import XBefIE from .xboxclips import XboxClipsIE from .xfileshare import XFileShareIE diff --git a/youtube_dl/extractor/wsj.py b/youtube_dl/extractor/wsj.py index deb7483ae..ec38a2ad8 100644 --- a/youtube_dl/extractor/wsj.py +++ b/youtube_dl/extractor/wsj.py @@ -10,10 +10,11 @@ from ..utils import ( class WSJIE(InfoExtractor): - _VALID_URL = r'''(?x)https?:// + _VALID_URL = r'''(?x) (?: - video-api\.wsj\.com/api-video/player/iframe\.html\?guid=| - (?:www\.)?wsj\.com/video/[^/]+/ + https?://video-api\.wsj\.com/api-video/player/iframe\.html\?guid=| + https?://(?:www\.)?wsj\.com/video/[^/]+/| + wsj: ) (?P[a-zA-Z0-9-]+)''' IE_DESC = 'Wall Street Journal' @@ -87,3 +88,24 @@ class WSJIE(InfoExtractor): 'title': title, 'categories': info.get('keywords'), } + + +class WSJArticleIE(InfoExtractor): + _VALID_URL = r'(?i)https?://(?:www\.)?wsj\.com/articles/(?P\w[^/]+)' + _TESTS = [{ + 'url': 'https://www.wsj.com/articles/dont-like-china-no-pandas-for-you-1490366939?', + 'info_dict': { + 'id': '4B13FA62-1D8C-45DB-8EA1-4105CB20B362', + 'ext': 'mp4', + 'upload_date': '20170221', + 'uploader_id': 'ralcaraz', + 'title': 'Bao Bao the Panda Leaves for China', + } + }] + + def _real_extract(self, url): + article_id = self._match_id(url) + webpage = self._download_webpage(url, article_id) + video_id = self._search_regex(r'data-src=["\']([A-Z0-9\-]+)', + webpage, 'video id') + return self.url_result('wsj:%s' % video_id, WSJIE.ie_key(), video_id) From b2a19e38293206a4ff687315baf0369c205bcd6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sat, 15 Apr 2017 20:51:47 +0700 Subject: [PATCH 002/128] [wsj] Improve and modernize (closes #12558) --- youtube_dl/extractor/wsj.py | 40 +++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/youtube_dl/extractor/wsj.py b/youtube_dl/extractor/wsj.py index ec38a2ad8..45cfca7c5 100644 --- a/youtube_dl/extractor/wsj.py +++ b/youtube_dl/extractor/wsj.py @@ -11,12 +11,13 @@ from ..utils import ( class WSJIE(InfoExtractor): _VALID_URL = r'''(?x) - (?: - https?://video-api\.wsj\.com/api-video/player/iframe\.html\?guid=| - https?://(?:www\.)?wsj\.com/video/[^/]+/| - wsj: - ) - (?P[a-zA-Z0-9-]+)''' + (?: + https?://video-api\.wsj\.com/api-video/player/iframe\.html\?.*?\bguid=| + https?://(?:www\.)?wsj\.com/video/[^/]+/| + wsj: + ) + (?P[a-fA-F0-9-]{36}) + ''' IE_DESC = 'Wall Street Journal' _TESTS = [{ 'url': 'http://video-api.wsj.com/api-video/player/iframe.html?guid=1BD01A4C-BFE8-40A5-A42F-8A8AF9898B1A', @@ -39,12 +40,17 @@ class WSJIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) - api_url = ( - 'http://video-api.wsj.com/api-video/find_all_videos.asp?' - 'type=guid&count=1&query=%s&fields=type,hls,videoMP4List,' - 'thumbnailList,author,description,name,duration,videoURL,' - 'titletag,formattedCreationDate,keywords,editor' % video_id) - info = self._download_json(api_url, video_id)['items'][0] + info = self._download_json( + 'http://video-api.wsj.com/api-video/find_all_videos.asp', video_id, + query={ + 'type': 'guid', + 'count': 1, + 'query': video_id, + 'fields': ','.join(( + 'type', 'hls', 'videoMP4List', 'thumbnailList', 'author', + 'description', 'name', 'duration', 'videoURL', 'titletag', + 'formattedCreationDate', 'keywords', 'editor')), + })['items'][0] title = info.get('name', info.get('titletag')) formats = [] @@ -91,8 +97,8 @@ class WSJIE(InfoExtractor): class WSJArticleIE(InfoExtractor): - _VALID_URL = r'(?i)https?://(?:www\.)?wsj\.com/articles/(?P\w[^/]+)' - _TESTS = [{ + _VALID_URL = r'(?i)https?://(?:www\.)?wsj\.com/articles/(?P[^/?#&]+)' + _TEST = { 'url': 'https://www.wsj.com/articles/dont-like-china-no-pandas-for-you-1490366939?', 'info_dict': { 'id': '4B13FA62-1D8C-45DB-8EA1-4105CB20B362', @@ -101,11 +107,11 @@ class WSJArticleIE(InfoExtractor): 'uploader_id': 'ralcaraz', 'title': 'Bao Bao the Panda Leaves for China', } - }] + } def _real_extract(self, url): article_id = self._match_id(url) webpage = self._download_webpage(url, article_id) - video_id = self._search_regex(r'data-src=["\']([A-Z0-9\-]+)', - webpage, 'video id') + video_id = self._search_regex( + r'data-src=["\']([a-fA-F0-9-]{36})', webpage, 'video id') return self.url_result('wsj:%s' % video_id, WSJIE.ie_key(), video_id) From 4db79fa1bc482ef5d97c8b73f0bf3683d5cc383c Mon Sep 17 00:00:00 2001 From: Marvin Ewald Date: Tue, 4 Apr 2017 19:18:23 +0200 Subject: [PATCH 003/128] [streamango] Add extractor --- youtube_dl/extractor/extractors.py | 1 + youtube_dl/extractor/streamango.py | 54 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 youtube_dl/extractor/streamango.py diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index 72d28a7e6..a92cbefed 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -939,6 +939,7 @@ from .srmediathek import SRMediathekIE from .stanfordoc import StanfordOpenClassroomIE from .steam import SteamIE from .streamable import StreamableIE +from .streamango import StreamangoIE from .streamcloud import StreamcloudIE from .streamcz import StreamCZIE from .streetvoice import StreetVoiceIE diff --git a/youtube_dl/extractor/streamango.py b/youtube_dl/extractor/streamango.py new file mode 100644 index 000000000..a4ef06b66 --- /dev/null +++ b/youtube_dl/extractor/streamango.py @@ -0,0 +1,54 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor + + +class StreamangoIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?streamango\.com/(?:f|embed)/(?P.+?)/(?:.+)' + _TESTS = [{ + 'url': 'https://streamango.com/f/clapasobsptpkdfe/20170315_150006_mp4', + 'md5': 'e992787515a182f55e38fc97588d802a', + 'info_dict': { + 'id': 'clapasobsptpkdfe', + 'ext': 'mp4', + 'title': '20170315_150006.mp4', + 'url': r're:https://streamango\.com/v/d/clapasobsptpkdfe~[0-9]{10}~(?:[0-9]+\.){3}[0-9]+~.{8}/720', + } + }, { + 'url': 'https://streamango.com/embed/clapasobsptpkdfe/20170315_150006_mp4', + 'only_matching': True, + }] + + def _real_extract(self, url): + def extract_url(urltype): + return self._search_regex( + r'type\s*:\s*["\']{}["\']\s*,\s*src\s*:\s*["\'](?P.+?)["\'].*'.format(urltype), + webpage, 'video URL', group='url') + + video_id = self._match_id(url) + webpage = self._download_webpage(url, video_id) + + title = self._og_search_title(webpage) + url = 'https:' + extract_url('video/mp4') + dashurl = extract_url(r'application/dash\+xml') + + formats = [{ + 'url': url, + 'ext': 'mp4', + 'width': 1280, + 'height': 720, + 'format_id': 'mp4', + }] + + formats.extend(self._extract_mpd_formats( + dashurl, video_id, mpd_id='dash', fatal=False)) + + self._sort_formats(formats) + + return { + 'id': video_id, + 'url': url, + 'title': title, + 'formats': formats, + } From 8068296276657c9d888338c2211c112d69de6fc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sat, 15 Apr 2017 21:50:15 +0700 Subject: [PATCH 004/128] [streamango] Improve extraction (closes #12643) --- youtube_dl/extractor/streamango.py | 50 ++++++++++++++++++------------ 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/youtube_dl/extractor/streamango.py b/youtube_dl/extractor/streamango.py index a4ef06b66..aa4fad162 100644 --- a/youtube_dl/extractor/streamango.py +++ b/youtube_dl/extractor/streamango.py @@ -1,11 +1,18 @@ # coding: utf-8 from __future__ import unicode_literals +import re + from .common import InfoExtractor +from ..utils import ( + determine_ext, + int_or_none, + js_to_json, +) class StreamangoIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?streamango\.com/(?:f|embed)/(?P.+?)/(?:.+)' + _VALID_URL = r'https?://(?:www\.)?streamango\.com/(?:f|embed)/(?P[^/?#&]+)' _TESTS = [{ 'url': 'https://streamango.com/f/clapasobsptpkdfe/20170315_150006_mp4', 'md5': 'e992787515a182f55e38fc97588d802a', @@ -13,7 +20,6 @@ class StreamangoIE(InfoExtractor): 'id': 'clapasobsptpkdfe', 'ext': 'mp4', 'title': '20170315_150006.mp4', - 'url': r're:https://streamango\.com/v/d/clapasobsptpkdfe~[0-9]{10}~(?:[0-9]+\.){3}[0-9]+~.{8}/720', } }, { 'url': 'https://streamango.com/embed/clapasobsptpkdfe/20170315_150006_mp4', @@ -21,29 +27,33 @@ class StreamangoIE(InfoExtractor): }] def _real_extract(self, url): - def extract_url(urltype): - return self._search_regex( - r'type\s*:\s*["\']{}["\']\s*,\s*src\s*:\s*["\'](?P.+?)["\'].*'.format(urltype), - webpage, 'video URL', group='url') - video_id = self._match_id(url) + webpage = self._download_webpage(url, video_id) title = self._og_search_title(webpage) - url = 'https:' + extract_url('video/mp4') - dashurl = extract_url(r'application/dash\+xml') - - formats = [{ - 'url': url, - 'ext': 'mp4', - 'width': 1280, - 'height': 720, - 'format_id': 'mp4', - }] - - formats.extend(self._extract_mpd_formats( - dashurl, video_id, mpd_id='dash', fatal=False)) + formats = [] + for format_ in re.findall(r'({[^}]*\bsrc\s*:\s*[^}]*})', webpage): + video = self._parse_json( + format_, video_id, transform_source=js_to_json, fatal=False) + if not video: + continue + src = video.get('src') + if not src: + continue + ext = determine_ext(src, default_ext=None) + if video.get('type') == 'application/dash+xml' or ext == 'mpd': + formats.extend(self._extract_mpd_formats( + src, video_id, mpd_id='dash', fatal=False)) + else: + formats.append({ + 'url': src, + 'ext': ext or 'mp4', + 'width': int_or_none(video.get('width')), + 'height': int_or_none(video.get('height')), + 'tbr': int_or_none(video.get('bitrate')), + }) self._sort_formats(formats) return { From 413c1f8e2fc9ef8a9fae2767ef79905510e8c37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 00:52:15 +0700 Subject: [PATCH 005/128] [extractor/generic] Extract RSS entries as url_transparent (#11163) --- youtube_dl/extractor/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index bc7c21f7a..6a34c2491 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -1693,7 +1693,7 @@ class GenericIE(InfoExtractor): continue entries.append({ - '_type': 'url', + '_type': 'url_transparent', 'url': next_url, 'title': it.find('title').text, }) From 0563f7ac6ed49929e1b488d92439928271c403df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 00:56:53 +0700 Subject: [PATCH 006/128] [YoutubeDL] Propagate overridden metadata to IE results of type url (closes #11163) --- youtube_dl/YoutubeDL.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index 7953670a7..3da5200d7 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -851,7 +851,14 @@ class YoutubeDL(object): new_result = info.copy() new_result.update(force_properties) - assert new_result.get('_type') != 'url_transparent' + # Extracted info may not be a video result (i.e. + # info.get('_type', 'video') != video) but rather an url or + # url_transparent. In such cases outer metadata (from ie_result) + # should be propagated to inner one (info). For this to happen + # _type of info should be overridden with url_transparent. This + # fixes issue from https://github.com/rg3/youtube-dl/pull/11163. + if new_result.get('_type') == 'url': + new_result['_type'] = 'url_transparent' return self.process_ie_result( new_result, download=download, extra_info=extra_info) From 51350db5a395c45cb181b1813a71b5e1aff86993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 01:14:05 +0700 Subject: [PATCH 007/128] [test_YoutubeDL] Add test for #11163 --- test/test_YoutubeDL.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/test_YoutubeDL.py b/test/test_YoutubeDL.py index 8491a88bd..75945e38f 100644 --- a/test/test_YoutubeDL.py +++ b/test/test_YoutubeDL.py @@ -755,6 +755,7 @@ class TestYoutubeDL(unittest.TestCase): '_type': 'url_transparent', 'url': 'foo2:', 'ie_key': 'Foo2', + 'title': 'foo1 title' } class Foo2IE(InfoExtractor): @@ -771,7 +772,7 @@ class TestYoutubeDL(unittest.TestCase): _VALID_URL = r'foo3:' def _real_extract(self, url): - return _make_result([{'url': TEST_URL}]) + return _make_result([{'url': TEST_URL}], title='foo3 title') ydl.add_info_extractor(Foo1IE(ydl)) ydl.add_info_extractor(Foo2IE(ydl)) @@ -779,6 +780,7 @@ class TestYoutubeDL(unittest.TestCase): ydl.extract_info('foo1:') downloaded = ydl.downloaded_info_dicts[0] self.assertEqual(downloaded['url'], TEST_URL) + self.assertEqual(downloaded['title'], 'foo1 title') if __name__ == '__main__': From d35dc344af8ca0b4cc9ea738a290c04842adb9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 01:39:07 +0700 Subject: [PATCH 008/128] [YoutubeDL] Apply expand_path after output template substitution os.path.expandvars translates '%%' into '%' making output template invalid. Before: '%%(ext)s' -(expand path)-> '%(ext)s' -(outtmpl subst.)-> 'mp4' After: '%%(ext)s' -(outtmpl subst.)-> '%(ext)s' -(expand path)-> '%(ext)s' --- youtube_dl/YoutubeDL.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index 3da5200d7..819b374ef 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -672,8 +672,7 @@ class YoutubeDL(object): FORMAT_RE.format(numeric_field), r'%({0})s'.format(numeric_field), outtmpl) - tmpl = expand_path(outtmpl) - filename = tmpl % template_dict + filename = expand_path(outtmpl % template_dict) # Temporary fix for #4787 # 'Treat' all problem characters by passing filename through preferredencoding # to workaround encoding issues with subprocess on python2 @ Windows From 76b5f99617f5b1ecdf64bb6445962f4db9685282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 01:47:58 +0700 Subject: [PATCH 009/128] [ChangeLog] Actualize --- ChangeLog | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ChangeLog b/ChangeLog index cf5ee84a4..34ef32c1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +version + +Core +* [YoutubeDL] Apply expand_path after output template substitution ++ [YoutubeDL] Propagate overridden meta fields to extraction results of type + url (#11163) + +Extractors ++ [generic] Extract RSS entries as url_transparent (#11163) ++ [streamango] Add support for streamango.com (#12643) ++ [wsj:article] Add support for articles (#12558) +* [brightcove] Relax video tag embeds extraction and validate ambiguous embeds' + URLs (#9163, #12005, #12178, #12480) ++ [udemy] Add support for react rendition (#12744) + + version 2017.04.15 Extractors From 022250a594750cf6d2e000e9ea142146d028bfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 01:49:02 +0700 Subject: [PATCH 010/128] release 2017.04.16 --- .github/ISSUE_TEMPLATE.md | 6 +++--- ChangeLog | 2 +- docs/supportedsites.md | 2 ++ youtube_dl/version.py | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 70f6b51ed..5d5adb199 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -6,8 +6,8 @@ --- -### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2017.04.15*. 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 **2017.04.15** +### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2017.04.16*. 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 **2017.04.16** ### Before submitting an *issue* make sure you have: - [ ] At least skimmed through [README](https://github.com/rg3/youtube-dl/blob/master/README.md) and **most notably** [FAQ](https://github.com/rg3/youtube-dl#faq) and [BUGS](https://github.com/rg3/youtube-dl#bugs) sections @@ -35,7 +35,7 @@ $ youtube-dl -v [debug] User config: [] [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] youtube-dl version 2017.04.15 +[debug] youtube-dl version 2017.04.16 [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] Proxy map: {} diff --git a/ChangeLog b/ChangeLog index 34ef32c1d..6be86a090 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -version +version 2017.04.16 Core * [YoutubeDL] Apply expand_path after output template substitution diff --git a/docs/supportedsites.md b/docs/supportedsites.md index b29b50c8d..afae82214 100644 --- a/docs/supportedsites.md +++ b/docs/supportedsites.md @@ -745,6 +745,7 @@ - **Steam** - **Stitcher** - **Streamable** + - **Streamango** - **streamcloud.eu** - **StreamCZ** - **StreetVoice** @@ -966,6 +967,7 @@ - **wrzuta.pl** - **wrzuta.pl:playlist** - **WSJ**: Wall Street Journal + - **WSJArticle** - **XBef** - **XboxClips** - **XFileShare**: XFileShare based sites: DaClips, FileHoot, GorillaVid, MovPod, PowerWatch, Rapidvideo.ws, TheVideoBee, Vidto, Streamin.To, XVIDSTAGE, Vid ABC, VidBom, vidlo diff --git a/youtube_dl/version.py b/youtube_dl/version.py index 612b50f7b..8b01fbc0a 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,3 +1,3 @@ from __future__ import unicode_literals -__version__ = '2017.04.15' +__version__ = '2017.04.16' From 334f41e0d827a361b4b8d39f55b66221281d92ae Mon Sep 17 00:00:00 2001 From: "Jeremie J. Jarosh" Date: Sat, 15 Apr 2017 10:12:08 -0500 Subject: [PATCH 011/128] [go90] Improve extraction - add metadata for 'series', 'episode', 'season', 'season_id', 'season_number', and 'episode_number' - integrate series title into the title - extract subtitles (fallback to `vtt` if the subtitle file type detection fails as that is the most likely extension) --- youtube_dl/extractor/go90.py | 38 ++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/go90.py b/youtube_dl/extractor/go90.py index 3550eca7c..9b2e1c164 100644 --- a/youtube_dl/extractor/go90.py +++ b/youtube_dl/extractor/go90.py @@ -5,6 +5,7 @@ import re from .common import InfoExtractor from ..utils import ( + determine_ext, int_or_none, parse_iso8601, ) @@ -18,7 +19,7 @@ class Go90IE(InfoExtractor): 'info_dict': { 'id': '84BUqjLpf9D', 'ext': 'mp4', - 'title': 'Inside The Utah Coalition Against Pornography Convention', + 'title': 'Daily VICE - Inside The Utah Coalition Against Pornography Convention', 'description': 'VICE\'s Karley Sciortino meets with activists who discuss the state\'s strong anti-porn stance. Then, VICE Sports explains NFL contracts.', 'timestamp': 1491868800, 'upload_date': '20170411', @@ -32,11 +33,28 @@ class Go90IE(InfoExtractor): video_id, headers={ 'Content-Type': 'application/json; charset=utf-8', }, data=b'{"client":"web","device_type":"pc"}') - title = video_data['title'] main_video_asset = video_data['main_video_asset'] + episode_number = int_or_none(video_data.get('episode_number')) + series = None + season = None + season_id = None + season_number = None + for metadata in video_data.get('__children', {}).get('Item', {}).values(): + if metadata.get('type') == 'show': + series = metadata.get('title') + elif metadata.get('type') == 'season': + season = metadata.get('title') + season_id = metadata.get('id') + season_number = int_or_none(metadata.get('season_number')) + + title = episode = video_data.get('title') or series + if series and series != title: + title = '%s - %s' % (series, title) + thumbnails = [] formats = [] + subtitles = {} for asset in video_data.get('assets'): if asset.get('id') == main_video_asset: for source in asset.get('sources', []): @@ -70,6 +88,15 @@ class Go90IE(InfoExtractor): 'height': int_or_none(source.get('height')), 'tbr': int_or_none(source.get('bitrate')), }) + + for caption in asset.get('caption_metadata', []): + caption_url = caption.get('source_url') + if not caption_url: + continue + subtitles.setdefault(caption.get('language', 'en'), []).append({ + 'url': caption_url, + 'ext': determine_ext(caption_url, 'vtt'), + }) elif asset.get('type') == 'image': asset_location = asset.get('location') if not asset_location: @@ -89,4 +116,11 @@ class Go90IE(InfoExtractor): 'description': video_data.get('short_description'), 'like_count': int_or_none(video_data.get('like_count')), 'timestamp': parse_iso8601(video_data.get('released_at')), + 'series': series, + 'episode': episode, + 'season': season, + 'season_id': season_id, + 'season_number': season_number, + 'episode_number': episode_number, + 'subtitles': subtitles, } From 1183e22c7e107938a64a3f4d920999ea00871d86 Mon Sep 17 00:00:00 2001 From: Remita Amine Date: Sat, 15 Apr 2017 23:19:23 +0100 Subject: [PATCH 012/128] Credit @triple-j for extracting more metadata from go90.com(#12721) --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 9abd5fdf4..1bdb74285 100644 --- a/AUTHORS +++ b/AUTHORS @@ -211,3 +211,4 @@ Juanjo Benages Xiao Di Guan Thomas Winant Daniel Twardowski +Jeremie Jarosh From 5935ef3c5d9c70c412a0c49f03feb3d0da8dedc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 21:52:07 +0700 Subject: [PATCH 013/128] [itv] Lower preference for rtmp formats (closes #12759) --- youtube_dl/extractor/itv.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/youtube_dl/extractor/itv.py b/youtube_dl/extractor/itv.py index 021c6b278..7f24f14ce 100644 --- a/youtube_dl/extractor/itv.py +++ b/youtube_dl/extractor/itv.py @@ -122,6 +122,8 @@ class ITVIE(InfoExtractor): 'play_path': play_path, 'tbr': tbr, 'ext': 'flv', + # rtmp formats are now stop downloading at ~72MiB + 'preference': -10, }) ios_playlist_url = params.get('data-video-playlist') From f67177cae8a2e616d265bbbafe1ceabc7df8dbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 21:52:45 +0700 Subject: [PATCH 014/128] [itv] Use native hls --- youtube_dl/extractor/itv.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/youtube_dl/extractor/itv.py b/youtube_dl/extractor/itv.py index 7f24f14ce..5ff7e1aaa 100644 --- a/youtube_dl/extractor/itv.py +++ b/youtube_dl/extractor/itv.py @@ -174,7 +174,9 @@ class ITVIE(InfoExtractor): href = ios_base_url + href ext = determine_ext(href) if ext == 'm3u8': - formats.extend(self._extract_m3u8_formats(href, video_id, 'mp4', m3u8_id='hls', fatal=False)) + formats.extend(self._extract_m3u8_formats( + href, video_id, 'mp4', entry_protocol='m3u8_native', + m3u8_id='hls', fatal=False)) else: formats.append({ 'url': href, From c2d7d76efd37c16d01100635f308f03deb9c04aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 23:15:24 +0700 Subject: [PATCH 015/128] [itv] Fix rtmp formats (#12759) --- youtube_dl/extractor/itv.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/youtube_dl/extractor/itv.py b/youtube_dl/extractor/itv.py index 5ff7e1aaa..7442c24d9 100644 --- a/youtube_dl/extractor/itv.py +++ b/youtube_dl/extractor/itv.py @@ -116,15 +116,25 @@ class ITVIE(InfoExtractor): if not play_path: continue tbr = int_or_none(media_file.get('bitrate'), 1000) - formats.append({ + f = { 'format_id': 'rtmp' + ('-%d' % tbr if tbr else ''), - 'url': rtmp_url, 'play_path': play_path, + # Providing this swfVfy allows to avoid truncated downloads + 'player_url': 'http://www.itv.com/mercury/Mercury_VideoPlayer.swf', + 'page_url': url, 'tbr': tbr, 'ext': 'flv', - # rtmp formats are now stop downloading at ~72MiB - 'preference': -10, - }) + } + app = self._search_regex( + 'rtmpe?://[^/]+/(.+)$', rtmp_url, 'app', default=None) + if app: + f.update({ + 'url': rtmp_url.split('?', 1)[0], + 'app': app, + }) + else: + f['url'] = rtmp_url + formats.append(f) ios_playlist_url = params.get('data-video-playlist') hmac = params.get('data-video-hmac') From 751c89a27d68c54375e96789cc90d4c8a3ce3dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Sun, 16 Apr 2017 23:19:20 +0700 Subject: [PATCH 016/128] [itv] Extract series metadata --- youtube_dl/extractor/itv.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/itv.py b/youtube_dl/extractor/itv.py index 7442c24d9..f3156804d 100644 --- a/youtube_dl/extractor/itv.py +++ b/youtube_dl/extractor/itv.py @@ -203,7 +203,8 @@ class ITVIE(InfoExtractor): 'ext': 'ttml' if ext == 'xml' else ext, }) - return { + info = self._search_json_ld(webpage, video_id, default={}) + info.update({ 'id': video_id, 'title': title, 'formats': formats, @@ -212,4 +213,5 @@ class ITVIE(InfoExtractor): 'episode_number': int_or_none(xpath_text(playlist, 'EpisodeNumber')), 'series': xpath_text(playlist, 'ProgrammeTitle'), 'duartion': parse_duration(xpath_text(playlist, 'Duration')), - } + }) + return info From e5d39886ec8e4e40b2b7257d16cc5d8505cc1f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Mon, 17 Apr 2017 00:23:16 +0700 Subject: [PATCH 017/128] [limelight] Improve embeds extraction (closes #12761) * Move extraction code to extractor * Add extraction for LimelightEmbeddedPlayerFlash embeds * Extract multiple video --- youtube_dl/extractor/generic.py | 6 +++++ youtube_dl/extractor/limelight.py | 37 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index 6a34c2491..c523abb25 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -85,6 +85,7 @@ from .ustream import UstreamIE from .openload import OpenloadIE from .videopress import VideoPressIE from .rutube import RutubeIE +from .limelight import LimelightBaseIE class GenericIE(InfoExtractor): @@ -2483,6 +2484,11 @@ class GenericIE(InfoExtractor): return self.url_result(piksel_url, PikselIE.ie_key()) # Look for Limelight embeds + limelight_urls = LimelightBaseIE._extract_urls(webpage, url) + if limelight_urls: + return self.playlist_result( + limelight_urls, video_id, video_title, video_description) + mobj = re.search(r'LimelightPlayer\.doLoad(Media|Channel|ChannelList)\(["\'](?P[a-z0-9]{32})', webpage) if mobj: lm = { diff --git a/youtube_dl/extractor/limelight.py b/youtube_dl/extractor/limelight.py index f52c2e169..0041453af 100644 --- a/youtube_dl/extractor/limelight.py +++ b/youtube_dl/extractor/limelight.py @@ -9,6 +9,7 @@ from ..utils import ( determine_ext, float_or_none, int_or_none, + smuggle_url, unsmuggle_url, ExtractorError, ) @@ -18,6 +19,42 @@ class LimelightBaseIE(InfoExtractor): _PLAYLIST_SERVICE_URL = 'http://production-ps.lvp.llnw.net/r/PlaylistService/%s/%s/%s' _API_URL = 'http://api.video.limelight.com/rest/organizations/%s/%s/%s/%s.json' + @classmethod + def _extract_urls(cls, webpage, source_url): + lm = { + 'Media': 'media', + 'Channel': 'channel', + 'ChannelList': 'channel_list', + } + entries = [] + for kind, video_id in re.findall( + r'LimelightPlayer\.doLoad(Media|Channel|ChannelList)\(["\'](?P[a-z0-9]{32})', + webpage): + print('video_id', video_id) + entries.append(cls.url_result( + smuggle_url( + 'limelight:%s:%s' % (lm[kind], video_id), + {'source_url': source_url}), + 'Limelight%s' % kind, video_id)) + for mobj in re.finditer( + # As per [1] class attribute should be exactly equal to + # LimelightEmbeddedPlayerFlash but numerous examples seen + # that don't exactly match it (e.g. [2]). + # 1. http://support.3playmedia.com/hc/en-us/articles/227732408-Limelight-Embedding-the-Captions-Plugin-with-the-Limelight-Player-on-Your-Webpage + # 2. http://www.sedona.com/FacilitatorTraining2017 + r'''(?sx) + ]+class=(["\'])(?:(?!\1).)*\bLimelightEmbeddedPlayerFlash\b(?:(?!\1).)*\1[^>]*>.*? + ]+ + name=(["\'])flashVars\2[^>]+ + value=(["\'])(?:(?!\3).)*mediaId=(?P[a-z0-9]{32}) + ''', webpage): + entries.append(cls.url_result( + smuggle_url( + 'limelight:media:%s' % mobj.group('id'), + {'source_url': source_url}), + 'LimelightMedia', mobj.group('id'))) + return entries + def _call_playlist_service(self, item_id, method, fatal=True, referer=None): headers = {} if referer: From 91bc57e4c527f918c7735d67f4bceb3cf1e2332c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Mon, 17 Apr 2017 00:33:47 +0700 Subject: [PATCH 018/128] [limelight] Add support for channels and channels lists embedded using LimelightEmbeddedPlayerFlash (#12761) --- youtube_dl/extractor/limelight.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/youtube_dl/extractor/limelight.py b/youtube_dl/extractor/limelight.py index 0041453af..0a5a3956c 100644 --- a/youtube_dl/extractor/limelight.py +++ b/youtube_dl/extractor/limelight.py @@ -30,7 +30,6 @@ class LimelightBaseIE(InfoExtractor): for kind, video_id in re.findall( r'LimelightPlayer\.doLoad(Media|Channel|ChannelList)\(["\'](?P[a-z0-9]{32})', webpage): - print('video_id', video_id) entries.append(cls.url_result( smuggle_url( 'limelight:%s:%s' % (lm[kind], video_id), @@ -46,13 +45,14 @@ class LimelightBaseIE(InfoExtractor): ]+class=(["\'])(?:(?!\1).)*\bLimelightEmbeddedPlayerFlash\b(?:(?!\1).)*\1[^>]*>.*? ]+ name=(["\'])flashVars\2[^>]+ - value=(["\'])(?:(?!\3).)*mediaId=(?P[a-z0-9]{32}) + value=(["\'])(?:(?!\3).)*(?Pmedia|channel(?:List)?)Id=(?P[a-z0-9]{32}) ''', webpage): + kind, video_id = mobj.group('kind'), mobj.group('id') entries.append(cls.url_result( smuggle_url( - 'limelight:media:%s' % mobj.group('id'), + 'limelight:%s:%s' % (kind, video_id), {'source_url': source_url}), - 'LimelightMedia', mobj.group('id'))) + 'Limelight%s' % kind.capitalize(), video_id)) return entries def _call_playlist_service(self, item_id, method, fatal=True, referer=None): From ab87c2600922bf093fb1fbb81f263c2acada8824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Mon, 17 Apr 2017 00:36:59 +0700 Subject: [PATCH 019/128] [extractor/generic] Add test for #12761 --- youtube_dl/extractor/generic.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index c523abb25..b22c3122a 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -1652,6 +1652,15 @@ class GenericIE(InfoExtractor): }, 'add_ie': [SenateISVPIE.ie_key()], }, + { + # Limelight embeds (1 channel embed + 4 media embeds) + 'url': 'http://www.sedona.com/FacilitatorTraining2017', + 'info_dict': { + 'id': 'FacilitatorTraining2017', + 'title': 'Facilitator Training 2017', + }, + 'playlist_mincount': 5, + }, # { # # TODO: find another test # # http://schema.org/VideoObject From fa7a6e6de66a8d8ce9af09d85a678ca5d91988f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Mon, 17 Apr 2017 00:43:56 +0700 Subject: [PATCH 020/128] [ChangeLog] Actualize --- ChangeLog | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6be86a090..e923372c8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +version + +Extractors +* [limelight] Improve extraction LimelightEmbeddedPlayerFlash media embeds and + add support for channel and channelList embeds +* [generic] Extract multiple Limelight embeds (#12761) ++ [itv] Extract series metadata +* [itv] Fix RTMP formats downloading (#12759) +* [itv] Use native HLS downloader by default ++ [go90] Extract subtitles (#12752) ++ [go90] Extract series metadata (#12752) + + version 2017.04.16 Core From 16a09aefe33ba2d0122926d761f89a93c0c7e7d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Mon, 17 Apr 2017 00:46:32 +0700 Subject: [PATCH 021/128] release 2017.04.17 --- .github/ISSUE_TEMPLATE.md | 6 +++--- ChangeLog | 2 +- youtube_dl/version.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 5d5adb199..45f8db721 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -6,8 +6,8 @@ --- -### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2017.04.16*. 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 **2017.04.16** +### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2017.04.17*. 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 **2017.04.17** ### Before submitting an *issue* make sure you have: - [ ] At least skimmed through [README](https://github.com/rg3/youtube-dl/blob/master/README.md) and **most notably** [FAQ](https://github.com/rg3/youtube-dl#faq) and [BUGS](https://github.com/rg3/youtube-dl#bugs) sections @@ -35,7 +35,7 @@ $ youtube-dl -v [debug] User config: [] [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] youtube-dl version 2017.04.16 +[debug] youtube-dl version 2017.04.17 [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] Proxy map: {} diff --git a/ChangeLog b/ChangeLog index e923372c8..03ef0363b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -version +version 2017.04.17 Extractors * [limelight] Improve extraction LimelightEmbeddedPlayerFlash media embeds and diff --git a/youtube_dl/version.py b/youtube_dl/version.py index 8b01fbc0a..480e04e06 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,3 +1,3 @@ from __future__ import unicode_literals -__version__ = '2017.04.16' +__version__ = '2017.04.17' From 1c35b3da44a087890b7144e5e626a573f2a80bf7 Mon Sep 17 00:00:00 2001 From: Remita Amine Date: Sun, 16 Apr 2017 21:24:34 +0100 Subject: [PATCH 022/128] [odnoklassniki] extract m3u8 formats --- youtube_dl/extractor/odnoklassniki.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/odnoklassniki.py b/youtube_dl/extractor/odnoklassniki.py index 0ee56a45b..b9369cea5 100644 --- a/youtube_dl/extractor/odnoklassniki.py +++ b/youtube_dl/extractor/odnoklassniki.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals from .common import InfoExtractor from ..compat import ( + compat_etree_fromstring, compat_parse_qs, compat_urllib_parse_unquote, compat_urllib_parse_urlparse, @@ -176,14 +177,32 @@ class OdnoklassnikiIE(InfoExtractor): }) return info - quality = qualities(('mobile', 'lowest', 'low', 'sd', 'hd', 'full')) + quality = qualities(('4', '0', '1', '2', '3', '5')) formats = [{ 'url': f['url'], 'ext': 'mp4', 'format_id': f['name'], - 'quality': quality(f['name']), } for f in metadata['videos']] + + m3u8_url = metadata.get('hlsManifestUrl') + if m3u8_url: + formats.extend(self._extract_m3u8_formats( + m3u8_url, video_id, 'mp4', 'm3u8_native', + m3u8_id='hls', fatal=False)) + + dash_manifest = metadata.get('metadataEmbedded') + if dash_manifest: + formats.extend(self._parse_mpd_formats( + compat_etree_fromstring(dash_manifest), 'mpd')) + + for fmt in formats: + fmt_type = self._search_regex( + r'\btype[/=](\d)', fmt['url'], + 'format type', default=None) + if fmt_type: + fmt['quality'] = quality(fmt_type) + self._sort_formats(formats) info['formats'] = formats From bf1b87cd919f07b7fef204838be73981e122ee11 Mon Sep 17 00:00:00 2001 From: Remita Amine Date: Mon, 17 Apr 2017 08:48:24 +0100 Subject: [PATCH 023/128] [common] Relax JWPlayer regex and remove duplicate urls(#12768) --- youtube_dl/extractor/common.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index dcc9d628a..12e010a0d 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -2182,7 +2182,7 @@ class InfoExtractor(object): def _find_jwplayer_data(self, webpage, video_id=None, transform_source=js_to_json): mobj = re.search( - r'jwplayer\((?P[\'"])[^\'" ]+(?P=quote)\)\.setup\s*\((?P[^)]+)\)', + r'(?s)jwplayer\((?P[\'"])[^\'" ]+(?P=quote)\).*?\.setup\s*\((?P[^)]+)\)', webpage) if mobj: try: @@ -2258,11 +2258,17 @@ class InfoExtractor(object): def _parse_jwplayer_formats(self, jwplayer_sources_data, video_id=None, m3u8_id=None, mpd_id=None, rtmp_params=None, base_url=None): + urls = [] formats = [] for source in jwplayer_sources_data: - source_url = self._proto_relative_url(source['file']) + source_url = self._proto_relative_url(source.get('file')) + if not source_url: + continue if base_url: source_url = compat_urlparse.urljoin(base_url, source_url) + if source_url in urls: + continue + urls.append(source_url) source_type = source.get('type') or '' ext = mimetype2ext(source_type) or determine_ext(source_url) if source_type == 'hls' or ext == 'm3u8': From f631b557915eae6c72f2f503255903c92481e85e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergey=20M=E2=80=A4?= Date: Tue, 18 Apr 2017 21:46:25 +0700 Subject: [PATCH 024/128] [brightcove] Fix _extract_url (closes #12782) --- youtube_dl/extractor/brightcove.py | 4 ++-- youtube_dl/extractor/nowness.py | 2 +- youtube_dl/extractor/yahoo.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/youtube_dl/extractor/brightcove.py b/youtube_dl/extractor/brightcove.py index 124497e95..c4fd96b3d 100644 --- a/youtube_dl/extractor/brightcove.py +++ b/youtube_dl/extractor/brightcove.py @@ -484,8 +484,8 @@ class BrightcoveNewIE(InfoExtractor): }] @staticmethod - def _extract_url(webpage): - urls = BrightcoveNewIE._extract_urls(webpage) + def _extract_url(ie, webpage): + urls = BrightcoveNewIE._extract_urls(ie, webpage) return urls[0] if urls else None @staticmethod diff --git a/youtube_dl/extractor/nowness.py b/youtube_dl/extractor/nowness.py index b6c5ee6e4..f26dafb8f 100644 --- a/youtube_dl/extractor/nowness.py +++ b/youtube_dl/extractor/nowness.py @@ -28,7 +28,7 @@ class NownessBaseIE(InfoExtractor): bc_url = BrightcoveLegacyIE._extract_brightcove_url(player_code) if bc_url: return self.url_result(bc_url, BrightcoveLegacyIE.ie_key()) - bc_url = BrightcoveNewIE._extract_url(player_code) + bc_url = BrightcoveNewIE._extract_url(self, player_code) if bc_url: return self.url_result(bc_url, BrightcoveNewIE.ie_key()) raise ExtractorError('Could not find player definition') diff --git a/youtube_dl/extractor/yahoo.py b/youtube_dl/extractor/yahoo.py index 4951414e9..38f82bf44 100644 --- a/youtube_dl/extractor/yahoo.py +++ b/youtube_dl/extractor/yahoo.py @@ -258,7 +258,7 @@ class YahooIE(InfoExtractor): return self.url_result(bc_url, BrightcoveLegacyIE.ie_key()) # Look for Brightcove New Studio embeds - bc_url = BrightcoveNewIE._extract_url(webpage) + bc_url = BrightcoveNewIE._extract_url(self, webpage) if bc_url: return self.url_result(bc_url, BrightcoveNewIE.ie_key()) From 06d0ad9a4e2266b1cc74b45a59a53fad3f23fe15 Mon Sep 17 00:00:00 2001 From: Yen Chi Hsuan Date: Tue, 18 Apr 2017 23:03:03 +0800 Subject: [PATCH 025/128] [brightcove] Support URLs with bcpid instead of playerID Fixes #12482 --- ChangeLog | 7 +++++++ youtube_dl/extractor/brightcove.py | 20 +++++++++++++++++--- youtube_dl/extractor/generic.py | 16 ++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 03ef0363b..f8084fda5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +version + +Extractors ++ [generic] Support Brightcove videos in