[picarto] Use API and add token support
authorPatrick Griffis <tingping@tingping.se>
Mon, 21 May 2018 21:02:16 +0000 (17:02 -0400)
committerSergey M․ <dstftw@gmail.com>
Sun, 11 Nov 2018 09:17:56 +0000 (16:17 +0700)
This is just more reliable than trying to extract
it from the page itself.

youtube_dl/extractor/picarto.py

index 2366dfb34748c31e0046901fe75ca558c7643346..27ee9643b93c7b8c5f565290c1b35b71ef7ce556 100644 (file)
@@ -8,14 +8,13 @@ from ..compat import compat_str
 from ..utils import (
     ExtractorError,
     js_to_json,
-    try_get,
     update_url_query,
     urlencode_postdata,
 )
 
 
 class PicartoIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www.)?picarto\.tv/(?P<id>[a-zA-Z0-9]+)'
+    _VALID_URL = r'https?://(?:www.)?picarto\.tv/(?P<id>[a-zA-Z0-9]+)(?:/(?P<token>[a-zA-Z0-9]+))?'
     _TEST = {
         'url': 'https://picarto.tv/Setz',
         'info_dict': {
@@ -34,19 +33,11 @@ class PicartoIE(InfoExtractor):
 
     def _real_extract(self, url):
         channel_id = self._match_id(url)
-        stream_page = self._download_webpage(url, channel_id)
+        metadata = self._download_json(
+            'https://api.picarto.tv/v1/channel/name/' + channel_id,
+            channel_id)
 
-        if '>This channel does not exist' in stream_page:
-            raise ExtractorError(
-                'Channel %s does not exist' % channel_id, expected=True)
-
-        player = self._parse_json(
-            self._search_regex(
-                r'(?s)playerSettings\[\d+\]\s*=\s*(\{.+?\}\s*\n)', stream_page,
-                'player settings'),
-            channel_id, transform_source=js_to_json)
-
-        if player.get('online') is False:
+        if metadata.get('online') is False:
             raise ExtractorError('Stream is offline', expected=True)
 
         cdn_data = self._download_json(
@@ -54,20 +45,13 @@ class PicartoIE(InfoExtractor):
             data=urlencode_postdata({'loadbalancinginfo': channel_id}),
             note='Downloading load balancing info')
 
-        def get_event(key):
-            return try_get(player, lambda x: x['event'][key], compat_str) or ''
-
+        token = self._VALID_URL_RE.match(url).group('token') or 'public'
         params = {
-            'token': player.get('token') or '',
-            'ticket': get_event('ticket'),
             'con': int(time.time() * 1000),
-            'type': get_event('ticket'),
-            'scope': get_event('scope'),
+            'token': token,
         }
 
         prefered_edge = cdn_data.get('preferedEdge')
-        default_tech = player.get('defaultTech')
-
         formats = []
 
         for edge in cdn_data['edges']:
@@ -81,8 +65,6 @@ class PicartoIE(InfoExtractor):
                 preference = 0
                 if edge_id == prefered_edge:
                     preference += 1
-                if tech_type == default_tech:
-                    preference += 1
                 format_id = []
                 if edge_id:
                     format_id.append(edge_id)
@@ -109,7 +91,7 @@ class PicartoIE(InfoExtractor):
                     continue
         self._sort_formats(formats)
 
-        mature = player.get('mature')
+        mature = metadata.get('adult')
         if mature is None:
             age_limit = None
         else:
@@ -119,7 +101,7 @@ class PicartoIE(InfoExtractor):
             'id': channel_id,
             'title': self._live_title(channel_id),
             'is_live': True,
-            'thumbnail': player.get('vodThumb'),
+            'thumbnail': metadata.get('thumbnails', {}).get('web'),
             'age_limit': age_limit,
             'formats': formats,
         }