mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-11-04 08:35:12 +00:00 
			
		
		
		
	[roosterteeth] fix free episode extraction(#16094)
This commit is contained in:
		@@ -4,11 +4,14 @@ from __future__ import unicode_literals
 | 
				
			|||||||
import re
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .common import InfoExtractor
 | 
					from .common import InfoExtractor
 | 
				
			||||||
 | 
					from ..compat import (
 | 
				
			||||||
 | 
					    compat_HTTPError,
 | 
				
			||||||
 | 
					    compat_str,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from ..utils import (
 | 
					from ..utils import (
 | 
				
			||||||
    ExtractorError,
 | 
					    ExtractorError,
 | 
				
			||||||
    int_or_none,
 | 
					    int_or_none,
 | 
				
			||||||
    strip_or_none,
 | 
					    str_or_none,
 | 
				
			||||||
    unescapeHTML,
 | 
					 | 
				
			||||||
    urlencode_postdata,
 | 
					    urlencode_postdata,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -21,15 +24,14 @@ class RoosterTeethIE(InfoExtractor):
 | 
				
			|||||||
        'url': 'http://roosterteeth.com/episode/million-dollars-but-season-2-million-dollars-but-the-game-announcement',
 | 
					        'url': 'http://roosterteeth.com/episode/million-dollars-but-season-2-million-dollars-but-the-game-announcement',
 | 
				
			||||||
        'md5': 'e2bd7764732d785ef797700a2489f212',
 | 
					        'md5': 'e2bd7764732d785ef797700a2489f212',
 | 
				
			||||||
        'info_dict': {
 | 
					        'info_dict': {
 | 
				
			||||||
            'id': '26576',
 | 
					            'id': '9156',
 | 
				
			||||||
            'display_id': 'million-dollars-but-season-2-million-dollars-but-the-game-announcement',
 | 
					            'display_id': 'million-dollars-but-season-2-million-dollars-but-the-game-announcement',
 | 
				
			||||||
            'ext': 'mp4',
 | 
					            'ext': 'mp4',
 | 
				
			||||||
            'title': 'Million Dollars, But...: Million Dollars, But... The Game Announcement',
 | 
					            'title': 'Million Dollars, But... The Game Announcement',
 | 
				
			||||||
            'description': 'md5:0cc3b21986d54ed815f5faeccd9a9ca5',
 | 
					            'description': 'md5:168a54b40e228e79f4ddb141e89fe4f5',
 | 
				
			||||||
            'thumbnail': r're:^https?://.*\.png$',
 | 
					            'thumbnail': r're:^https?://.*\.png$',
 | 
				
			||||||
            'series': 'Million Dollars, But...',
 | 
					            'series': 'Million Dollars, But...',
 | 
				
			||||||
            'episode': 'Million Dollars, But... The Game Announcement',
 | 
					            'episode': 'Million Dollars, But... The Game Announcement',
 | 
				
			||||||
            'comment_count': int,
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    }, {
 | 
					    }, {
 | 
				
			||||||
        'url': 'http://achievementhunter.roosterteeth.com/episode/off-topic-the-achievement-hunter-podcast-2016-i-didn-t-think-it-would-pass-31',
 | 
					        'url': 'http://achievementhunter.roosterteeth.com/episode/off-topic-the-achievement-hunter-podcast-2016-i-didn-t-think-it-would-pass-31',
 | 
				
			||||||
@@ -89,60 +91,55 @@ class RoosterTeethIE(InfoExtractor):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def _real_extract(self, url):
 | 
					    def _real_extract(self, url):
 | 
				
			||||||
        display_id = self._match_id(url)
 | 
					        display_id = self._match_id(url)
 | 
				
			||||||
 | 
					        api_episode_url = 'https://svod-be.roosterteeth.com/api/v1/episodes/%s' % display_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        webpage = self._download_webpage(url, display_id)
 | 
					        try:
 | 
				
			||||||
 | 
					            m3u8_url = self._download_json(
 | 
				
			||||||
        episode = strip_or_none(unescapeHTML(self._search_regex(
 | 
					                api_episode_url + '/videos', display_id,
 | 
				
			||||||
            (r'videoTitle\s*=\s*(["\'])(?P<title>(?:(?!\1).)+)\1',
 | 
					                'Downloading video JSON metadata')['data'][0]['attributes']['url']
 | 
				
			||||||
             r'<title>(?P<title>[^<]+)</title>'), webpage, 'title',
 | 
					        except ExtractorError as e:
 | 
				
			||||||
            default=None, group='title')))
 | 
					            if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:
 | 
				
			||||||
 | 
					                if self._parse_json(e.cause.read().decode(), display_id).get('access') is False:
 | 
				
			||||||
        title = strip_or_none(self._og_search_title(
 | 
					 | 
				
			||||||
            webpage, default=None)) or episode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        m3u8_url = self._search_regex(
 | 
					 | 
				
			||||||
            r'file\s*:\s*(["\'])(?P<url>http.+?\.m3u8.*?)\1',
 | 
					 | 
				
			||||||
            webpage, 'm3u8 url', default=None, group='url')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not m3u8_url:
 | 
					 | 
				
			||||||
            if re.search(r'<div[^>]+class=["\']non-sponsor', webpage):
 | 
					 | 
				
			||||||
                    self.raise_login_required(
 | 
					                    self.raise_login_required(
 | 
				
			||||||
                        '%s is only available for FIRST members' % display_id)
 | 
					                        '%s is only available for FIRST members' % display_id)
 | 
				
			||||||
 | 
					            raise
 | 
				
			||||||
            if re.search(r'<div[^>]+class=["\']golive-gate', webpage):
 | 
					 | 
				
			||||||
                self.raise_login_required('%s is not available yet' % display_id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            raise ExtractorError('Unable to extract m3u8 URL')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        formats = self._extract_m3u8_formats(
 | 
					        formats = self._extract_m3u8_formats(
 | 
				
			||||||
            m3u8_url, display_id, ext='mp4',
 | 
					            m3u8_url, display_id, 'mp4', 'm3u8_native', m3u8_id='hls')
 | 
				
			||||||
            entry_protocol='m3u8_native', m3u8_id='hls')
 | 
					 | 
				
			||||||
        self._sort_formats(formats)
 | 
					        self._sort_formats(formats)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        description = strip_or_none(self._og_search_description(webpage))
 | 
					        episode = self._download_json(
 | 
				
			||||||
        thumbnail = self._proto_relative_url(self._og_search_thumbnail(webpage))
 | 
					            api_episode_url, display_id,
 | 
				
			||||||
 | 
					            'Downloading episode JSON metadata')['data'][0]
 | 
				
			||||||
 | 
					        attributes = episode['attributes']
 | 
				
			||||||
 | 
					        title = attributes.get('title') or attributes['display_title']
 | 
				
			||||||
 | 
					        video_id = compat_str(episode['id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        series = self._search_regex(
 | 
					        thumbnails = []
 | 
				
			||||||
            (r'<h2>More ([^<]+)</h2>', r'<a[^>]+>See All ([^<]+) Videos<'),
 | 
					        for image in episode.get('included', {}).get('images', []):
 | 
				
			||||||
            webpage, 'series', fatal=False)
 | 
					            if image.get('type') == 'episode_image':
 | 
				
			||||||
 | 
					                img_attributes = image.get('attributes') or {}
 | 
				
			||||||
        comment_count = int_or_none(self._search_regex(
 | 
					                for k in ('thumb', 'small', 'medium', 'large'):
 | 
				
			||||||
            r'>Comments \((\d+)\)<', webpage,
 | 
					                    img_url = img_attributes.get(k)
 | 
				
			||||||
            'comment count', fatal=False))
 | 
					                    if img_url:
 | 
				
			||||||
 | 
					                        thumbnails.append({
 | 
				
			||||||
        video_id = self._search_regex(
 | 
					                            'id': k,
 | 
				
			||||||
            (r'containerId\s*=\s*["\']episode-(\d+)\1',
 | 
					                            'url': img_url,
 | 
				
			||||||
             r'<div[^<]+id=["\']episode-(\d+)'), webpage,
 | 
					                        })
 | 
				
			||||||
            'video id', default=display_id)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            'id': video_id,
 | 
					            'id': video_id,
 | 
				
			||||||
            'display_id': display_id,
 | 
					            'display_id': display_id,
 | 
				
			||||||
            'title': title,
 | 
					            'title': title,
 | 
				
			||||||
            'description': description,
 | 
					            'description': attributes.get('description') or attributes.get('caption'),
 | 
				
			||||||
            'thumbnail': thumbnail,
 | 
					            'thumbnails': thumbnails,
 | 
				
			||||||
            'series': series,
 | 
					            'series': attributes.get('show_title'),
 | 
				
			||||||
            'episode': episode,
 | 
					            'season_number': int_or_none(attributes.get('season_number')),
 | 
				
			||||||
            'comment_count': comment_count,
 | 
					            'season_id': attributes.get('season_id'),
 | 
				
			||||||
 | 
					            'episode': title,
 | 
				
			||||||
 | 
					            'episode_number': int_or_none(attributes.get('number')),
 | 
				
			||||||
 | 
					            'episode_id': str_or_none(episode.get('uuid')),
 | 
				
			||||||
            'formats': formats,
 | 
					            'formats': formats,
 | 
				
			||||||
 | 
					            'channel_id': attributes.get('channel_id'),
 | 
				
			||||||
 | 
					            'duration': int_or_none(attributes.get('length')),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user