mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-11-04 08:35:12 +00:00 
			
		
		
		
	[picarto] Use API and add token support
This is just more reliable than trying to extract it from the page itself.
This commit is contained in:
		
				
					committed by
					
						
						Sergey M․
					
				
			
			
				
	
			
			
			
						parent
						
							83852e57bf
						
					
				
				
					commit
					f17a24a6df
				
			@@ -8,14 +8,13 @@ from ..compat import compat_str
 | 
				
			|||||||
from ..utils import (
 | 
					from ..utils import (
 | 
				
			||||||
    ExtractorError,
 | 
					    ExtractorError,
 | 
				
			||||||
    js_to_json,
 | 
					    js_to_json,
 | 
				
			||||||
    try_get,
 | 
					 | 
				
			||||||
    update_url_query,
 | 
					    update_url_query,
 | 
				
			||||||
    urlencode_postdata,
 | 
					    urlencode_postdata,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PicartoIE(InfoExtractor):
 | 
					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 = {
 | 
					    _TEST = {
 | 
				
			||||||
        'url': 'https://picarto.tv/Setz',
 | 
					        'url': 'https://picarto.tv/Setz',
 | 
				
			||||||
        'info_dict': {
 | 
					        'info_dict': {
 | 
				
			||||||
@@ -34,19 +33,11 @@ class PicartoIE(InfoExtractor):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def _real_extract(self, url):
 | 
					    def _real_extract(self, url):
 | 
				
			||||||
        channel_id = self._match_id(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:
 | 
					        if metadata.get('online') is False:
 | 
				
			||||||
            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:
 | 
					 | 
				
			||||||
            raise ExtractorError('Stream is offline', expected=True)
 | 
					            raise ExtractorError('Stream is offline', expected=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cdn_data = self._download_json(
 | 
					        cdn_data = self._download_json(
 | 
				
			||||||
@@ -54,20 +45,13 @@ class PicartoIE(InfoExtractor):
 | 
				
			|||||||
            data=urlencode_postdata({'loadbalancinginfo': channel_id}),
 | 
					            data=urlencode_postdata({'loadbalancinginfo': channel_id}),
 | 
				
			||||||
            note='Downloading load balancing info')
 | 
					            note='Downloading load balancing info')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def get_event(key):
 | 
					        token = self._VALID_URL_RE.match(url).group('token') or 'public'
 | 
				
			||||||
            return try_get(player, lambda x: x['event'][key], compat_str) or ''
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        params = {
 | 
					        params = {
 | 
				
			||||||
            'token': player.get('token') or '',
 | 
					 | 
				
			||||||
            'ticket': get_event('ticket'),
 | 
					 | 
				
			||||||
            'con': int(time.time() * 1000),
 | 
					            'con': int(time.time() * 1000),
 | 
				
			||||||
            'type': get_event('ticket'),
 | 
					            'token': token,
 | 
				
			||||||
            'scope': get_event('scope'),
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        prefered_edge = cdn_data.get('preferedEdge')
 | 
					        prefered_edge = cdn_data.get('preferedEdge')
 | 
				
			||||||
        default_tech = player.get('defaultTech')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        formats = []
 | 
					        formats = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for edge in cdn_data['edges']:
 | 
					        for edge in cdn_data['edges']:
 | 
				
			||||||
@@ -81,8 +65,6 @@ class PicartoIE(InfoExtractor):
 | 
				
			|||||||
                preference = 0
 | 
					                preference = 0
 | 
				
			||||||
                if edge_id == prefered_edge:
 | 
					                if edge_id == prefered_edge:
 | 
				
			||||||
                    preference += 1
 | 
					                    preference += 1
 | 
				
			||||||
                if tech_type == default_tech:
 | 
					 | 
				
			||||||
                    preference += 1
 | 
					 | 
				
			||||||
                format_id = []
 | 
					                format_id = []
 | 
				
			||||||
                if edge_id:
 | 
					                if edge_id:
 | 
				
			||||||
                    format_id.append(edge_id)
 | 
					                    format_id.append(edge_id)
 | 
				
			||||||
@@ -109,7 +91,7 @@ class PicartoIE(InfoExtractor):
 | 
				
			|||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
        self._sort_formats(formats)
 | 
					        self._sort_formats(formats)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mature = player.get('mature')
 | 
					        mature = metadata.get('adult')
 | 
				
			||||||
        if mature is None:
 | 
					        if mature is None:
 | 
				
			||||||
            age_limit = None
 | 
					            age_limit = None
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
@@ -119,7 +101,7 @@ class PicartoIE(InfoExtractor):
 | 
				
			|||||||
            'id': channel_id,
 | 
					            'id': channel_id,
 | 
				
			||||||
            'title': self._live_title(channel_id),
 | 
					            'title': self._live_title(channel_id),
 | 
				
			||||||
            'is_live': True,
 | 
					            'is_live': True,
 | 
				
			||||||
            'thumbnail': player.get('vodThumb'),
 | 
					            'thumbnail': metadata.get('thumbnails', {}).get('web'),
 | 
				
			||||||
            'age_limit': age_limit,
 | 
					            'age_limit': age_limit,
 | 
				
			||||||
            'formats': formats,
 | 
					            'formats': formats,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user