]> jfr.im git - yt-dlp.git/blobdiff - yt_dlp/extractor/generic.py
[extractor/JWPlatform] Fix extractor (#5112)
[yt-dlp.git] / yt_dlp / extractor / generic.py
index d3ed7ce4610b59346392f0113514071af68b44fd..73422f937c35f639244c440d0d63b90101961fde 100644 (file)
@@ -3,7 +3,6 @@
 import urllib.parse
 import xml.etree.ElementTree
 
-from . import gen_extractor_classes
 from .common import InfoExtractor  # isort: split
 from .brightcove import BrightcoveLegacyIE, BrightcoveNewIE
 from .commonprotocols import RtmpIE
@@ -26,6 +25,7 @@
     parse_resolution,
     smuggle_url,
     str_or_none,
+    traverse_obj,
     try_call,
     unescapeHTML,
     unified_timestamp,
@@ -873,22 +873,6 @@ class GenericIE(InfoExtractor):
                 'thumbnail': r're:^https?://.*\.jpg$',
             },
         },
-        # Wistia embed
-        {
-            'url': 'http://study.com/academy/lesson/north-american-exploration-failed-colonies-of-spain-france-england.html#lesson',
-            'md5': '1953f3a698ab51cfc948ed3992a0b7ff',
-            'info_dict': {
-                'id': '6e2wtrbdaf',
-                'ext': 'mov',
-                'title': 'paywall_north-american-exploration-failed-colonies-of-spain-france-england',
-                'description': 'a Paywall Videos video from Remilon',
-                'duration': 644.072,
-                'uploader': 'study.com',
-                'timestamp': 1459678540,
-                'upload_date': '20160403',
-                'filesize': 24687186,
-            },
-        },
         # Wistia standard embed (async)
         {
             'url': 'https://www.getdrip.com/university/brennan-dunn-drip-workshop/',
@@ -903,7 +887,8 @@ class GenericIE(InfoExtractor):
             },
             'params': {
                 'skip_download': True,
-            }
+            },
+            'skip': 'webpage 404 not found',
         },
         # Soundcloud embed
         {
@@ -1086,18 +1071,6 @@ class GenericIE(InfoExtractor):
                 'skip_download': True,
             }
         },
-        {
-            # JWPlatform iframe
-            'url': 'https://www.covermagazine.co.uk/feature/2465255/business-protection-involved',
-            'info_dict': {
-                'id': 'AG26UQXM',
-                'ext': 'mp4',
-                'upload_date': '20160719',
-                'timestamp': 468923808,
-                'title': '2016_05_18 Cover L&G Business Protection V1 FINAL.mp4',
-            },
-            'add_ie': ['JWPlatform'],
-        },
         {
             # Video.js embed, multiple formats
             'url': 'http://ortcam.com/solidworks-урок-6-настройка-чертежа_33f9b7351.html',
@@ -2621,10 +2594,10 @@ def _real_extract(self, url):
                     default_search += ':'
                 return self.url_result(default_search + url)
 
-        url, smuggled_data = unsmuggle_url(url)
+        url, smuggled_data = unsmuggle_url(url, {})
         force_videoid = None
-        is_intentional = smuggled_data and smuggled_data.get('to_generic')
-        if smuggled_data and 'force_videoid' in smuggled_data:
+        is_intentional = smuggled_data.get('to_generic')
+        if 'force_videoid' in smuggled_data:
             force_videoid = smuggled_data['force_videoid']
             video_id = force_videoid
         else:
@@ -2638,7 +2611,10 @@ def _real_extract(self, url):
         # to accept raw bytes and being able to download only a chunk.
         # It may probably better to solve this by checking Content-Type for application/octet-stream
         # after a HEAD request, but not sure if we can rely on this.
-        full_response = self._request_webpage(url, video_id, headers={'Accept-Encoding': '*'})
+        full_response = self._request_webpage(url, video_id, headers={
+            'Accept-Encoding': '*',
+            **smuggled_data.get('http_headers', {})
+        })
         new_url = full_response.geturl()
         if url != new_url:
             self.report_following_redirect(new_url)
@@ -2657,14 +2633,15 @@ def _real_extract(self, url):
         m = re.match(r'^(?P<type>audio|video|application(?=/(?:ogg$|(?:vnd\.apple\.|x-)?mpegurl)))/(?P<format_id>[^;\s]+)', content_type)
         if m:
             self.report_detected('direct video link')
+            headers = smuggled_data.get('http_headers', {})
             format_id = str(m.group('format_id'))
             subtitles = {}
             if format_id.endswith('mpegurl'):
-                formats, subtitles = self._extract_m3u8_formats_and_subtitles(url, video_id, 'mp4')
+                formats, subtitles = self._extract_m3u8_formats_and_subtitles(url, video_id, 'mp4', headers=headers)
             elif format_id.endswith('mpd') or format_id.endswith('dash+xml'):
-                formats, subtitles = self._extract_mpd_formats_and_subtitles(url, video_id)
+                formats, subtitles = self._extract_mpd_formats_and_subtitles(url, video_id, headers=headers)
             elif format_id == 'f4m':
-                formats = self._extract_f4m_formats(url, video_id)
+                formats = self._extract_f4m_formats(url, video_id, headers=headers)
             else:
                 formats = [{
                     'format_id': format_id,
@@ -2673,8 +2650,11 @@ def _real_extract(self, url):
                 }]
                 info_dict['direct'] = True
             self._sort_formats(formats)
-            info_dict['formats'] = formats
-            info_dict['subtitles'] = subtitles
+            info_dict.update({
+                'formats': formats,
+                'subtitles': subtitles,
+                'http_headers': headers,
+            })
             return info_dict
 
         if not self.get_param('test', False) and not is_intentional:
@@ -2765,7 +2745,7 @@ def _real_extract(self, url):
             'age_limit': self._rta_search(webpage),
         })
 
-        domain_name = self._search_regex(r'^(?:https?://)?([^/]*)/.*', url, 'video uploader')
+        domain_name = self._search_regex(r'^(?:https?://)?([^/]*)/.*', url, 'video uploader', default=None)
 
         # Sometimes embedded video player is hidden behind percent encoding
         # (e.g. https://github.com/ytdl-org/youtube-dl/issues/2448)
@@ -2805,7 +2785,7 @@ def _real_extract(self, url):
 
         self._downloader.write_debug('Looking for embeds')
         embeds = []
-        for ie in gen_extractor_classes():
+        for ie in self._downloader._ies.values():
             gen = ie.extract_from_webpage(self._downloader, url, webpage)
             current_embeds = []
             try:
@@ -2840,8 +2820,9 @@ def _real_extract(self, url):
             try:
                 info = self._parse_jwplayer_data(
                     jwplayer_data, video_id, require_title=False, base_url=url)
-                self.report_detected('JW Player data')
-                return merge_dicts(info, info_dict)
+                if traverse_obj(info, 'formats', ('entries', ..., 'formats')):
+                    self.report_detected('JW Player data')
+                    return merge_dicts(info, info_dict)
             except ExtractorError:
                 # See https://github.com/ytdl-org/youtube-dl/pull/16735
                 pass
@@ -2917,8 +2898,12 @@ def _real_extract(self, url):
         if json_ld.get('url') not in (url, None):
             self.report_detected('JSON LD')
             return merge_dicts({
-                '_type': 'url_transparent',
-                'url': smuggle_url(json_ld['url'], {'force_videoid': video_id, 'to_generic': True}),
+                '_type': 'video' if json_ld.get('ext') else 'url_transparent',
+                'url': smuggle_url(json_ld['url'], {
+                    'force_videoid': video_id,
+                    'to_generic': True,
+                    'http_headers': {'Referer': url},
+                }),
             }, json_ld, info_dict)
 
         def check_video(vurl):
@@ -3035,7 +3020,7 @@ def filter_video(urls):
                 self.report_detected('Twitter card')
         if not found:
             # We look for Open Graph info:
-            # We have to match any number spaces between elements, some sites try to align them (eg.: statigr.am)
+            # We have to match any number spaces between elements, some sites try to align them, e.g.: statigr.am
             m_video_type = re.findall(r'<meta.*?property="og:video:type".*?content="video/(.*?)"', webpage)
             # We only look in og:video if the MIME type is a video, don't try if it's a Flash player:
             if m_video_type is not None: