[youtube,twitch] Allow waiting for channels to become live

Closes #2597
This commit is contained in:
pukkandan 2022-07-26 09:23:10 +05:30
parent 3bec830a59
commit 693f060040
No known key found for this signature in database
GPG key ID: 7EEE9E1E817D0A39
4 changed files with 25 additions and 8 deletions

View file

@ -80,6 +80,7 @@
RejectedVideoReached, RejectedVideoReached,
SameFileError, SameFileError,
UnavailableVideoError, UnavailableVideoError,
UserNotLive,
YoutubeDLCookieProcessor, YoutubeDLCookieProcessor,
YoutubeDLHandler, YoutubeDLHandler,
YoutubeDLRedirectHandler, YoutubeDLRedirectHandler,
@ -1456,7 +1457,7 @@ def wrapper(self, *args, **kwargs):
break break
return wrapper return wrapper
def _wait_for_video(self, ie_result): def _wait_for_video(self, ie_result={}):
if (not self.params.get('wait_for_video') if (not self.params.get('wait_for_video')
or ie_result.get('_type', 'video') != 'video' or ie_result.get('_type', 'video') != 'video'
or ie_result.get('formats') or ie_result.get('url')): or ie_result.get('formats') or ie_result.get('url')):
@ -1480,7 +1481,7 @@ def progress(msg):
if diff is None and ie_result.get('live_status') == 'is_upcoming': if diff is None and ie_result.get('live_status') == 'is_upcoming':
diff = round(random.uniform(min_wait, max_wait) if (max_wait and min_wait) else (max_wait or min_wait), 0) diff = round(random.uniform(min_wait, max_wait) if (max_wait and min_wait) else (max_wait or min_wait), 0)
self.report_warning('Release time of video is not known') self.report_warning('Release time of video is not known')
elif (diff or 0) <= 0: elif ie_result and (diff or 0) <= 0:
self.report_warning('Video should already be available according to extracted info') self.report_warning('Video should already be available according to extracted info')
diff = min(max(diff or 0, min_wait or 0), max_wait or float('inf')) diff = min(max(diff or 0, min_wait or 0), max_wait or float('inf'))
self.to_screen(f'[wait] Waiting for {format_dur(diff)} - Press Ctrl+C to try now') self.to_screen(f'[wait] Waiting for {format_dur(diff)} - Press Ctrl+C to try now')
@ -1504,7 +1505,14 @@ def progress(msg):
@_handle_extraction_exceptions @_handle_extraction_exceptions
def __extract_info(self, url, ie, download, extra_info, process): def __extract_info(self, url, ie, download, extra_info, process):
try:
ie_result = ie.extract(url) ie_result = ie.extract(url)
except UserNotLive as e:
if process:
if self.params.get('wait_for_video'):
self.report_warning(e)
self._wait_for_video()
raise
if ie_result is None: # Finished already (backwards compatibility; listformats and friends should be moved here) if ie_result is None: # Finished already (backwards compatibility; listformats and friends should be moved here)
self.report_warning(f'Extractor {ie.IE_NAME} returned nothing{bug_reports_message()}') self.report_warning(f'Extractor {ie.IE_NAME} returned nothing{bug_reports_message()}')
return return

View file

@ -12,10 +12,11 @@
compat_urllib_parse_urlparse, compat_urllib_parse_urlparse,
) )
from ..utils import ( from ..utils import (
ExtractorError,
UserNotLive,
base_url, base_url,
clean_html, clean_html,
dict_get, dict_get,
ExtractorError,
float_or_none, float_or_none,
int_or_none, int_or_none,
parse_duration, parse_duration,
@ -940,7 +941,7 @@ def _real_extract(self, url):
stream = user['stream'] stream = user['stream']
if not stream: if not stream:
raise ExtractorError('%s is offline' % channel_name, expected=True) raise UserNotLive(video_id=channel_name)
access_token = self._download_access_token( access_token = self._download_access_token(
channel_name, 'stream', 'channelName') channel_name, 'stream', 'channelName')

View file

@ -22,6 +22,7 @@
from ..utils import ( from ..utils import (
NO_DEFAULT, NO_DEFAULT,
ExtractorError, ExtractorError,
UserNotLive,
bug_reports_message, bug_reports_message,
classproperty, classproperty,
clean_html, clean_html,
@ -5383,9 +5384,8 @@ def get_mobj(url):
selected_tab_name = 'featured' selected_tab_name = 'featured'
requested_tab_name = mobj['tab'][1:] requested_tab_name = mobj['tab'][1:]
if 'no-youtube-channel-redirect' not in compat_opts: if 'no-youtube-channel-redirect' not in compat_opts:
if requested_tab_name == 'live': if requested_tab_name == 'live': # Live tab should have redirected to the video
# Live tab should have redirected to the video raise UserNotLive(video_id=mobj['id'])
raise ExtractorError('The channel is not currently live', expected=True)
if requested_tab_name not in ('', selected_tab_name): if requested_tab_name not in ('', selected_tab_name):
redirect_warning = f'The channel does not have a {requested_tab_name} tab' redirect_warning = f'The channel does not have a {requested_tab_name} tab'
if not original_tab_name: if not original_tab_name:

View file

@ -1072,6 +1072,14 @@ def __init__(self, msg, countries=None, **kwargs):
self.countries = countries self.countries = countries
class UserNotLive(ExtractorError):
"""Error when a channel/user is not live"""
def __init__(self, msg=None, **kwargs):
kwargs['expected'] = True
super().__init__(msg or 'The channel is not currently live', **kwargs)
class DownloadError(YoutubeDLError): class DownloadError(YoutubeDLError):
"""Download Error exception. """Download Error exception.