mirror of https://github.com/yt-dlp/yt-dlp.git
parent
7474e4531e
commit
a057779d5e
4
Makefile
4
Makefile
|
@ -81,9 +81,9 @@ yt-dlp: yt_dlp/*.py yt_dlp/*/*.py
|
||||||
mkdir -p zip/$$d ;\
|
mkdir -p zip/$$d ;\
|
||||||
cp -pPR $$d/*.py zip/$$d/ ;\
|
cp -pPR $$d/*.py zip/$$d/ ;\
|
||||||
done
|
done
|
||||||
touch -t 200001010101 zip/yt_dlp/*.py zip/yt_dlp/*/*.py zip/yt_dlp/*/*/*.py
|
touch -t 200001010101 zip/yt_dlp/*.py zip/yt_dlp/*/*.py
|
||||||
mv zip/yt_dlp/__main__.py zip/
|
mv zip/yt_dlp/__main__.py zip/
|
||||||
cd zip ; zip -q ../yt-dlp yt_dlp/*.py yt_dlp/*/*.py yt_dlp/*/*/*.py __main__.py
|
cd zip ; zip -q ../yt-dlp yt_dlp/*.py yt_dlp/*/*.py __main__.py
|
||||||
rm -rf zip
|
rm -rf zip
|
||||||
echo '#!$(PYTHON)' > yt-dlp
|
echo '#!$(PYTHON)' > yt-dlp
|
||||||
cat yt-dlp.zip >> yt-dlp
|
cat yt-dlp.zip >> yt-dlp
|
||||||
|
|
|
@ -2426,6 +2426,8 @@ class YoutubeDL:
|
||||||
for key in live_keys:
|
for key in live_keys:
|
||||||
if info_dict.get(key) is None:
|
if info_dict.get(key) is None:
|
||||||
info_dict[key] = (live_status == key)
|
info_dict[key] = (live_status == key)
|
||||||
|
if live_status == 'post_live':
|
||||||
|
info_dict['was_live'] = True
|
||||||
|
|
||||||
# Auto generate title fields corresponding to the *_number fields when missing
|
# Auto generate title fields corresponding to the *_number fields when missing
|
||||||
# in order to always have clean titles. This is very common for TV series.
|
# in order to always have clean titles. This is very common for TV series.
|
||||||
|
@ -3683,6 +3685,8 @@ class YoutubeDL:
|
||||||
if not self.params.get('verbose'):
|
if not self.params.get('verbose'):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
from . import _IN_CLI # Must be delayed import
|
||||||
|
|
||||||
# These imports can be slow. So import them only as needed
|
# These imports can be slow. So import them only as needed
|
||||||
from .extractor.extractors import _LAZY_LOADER
|
from .extractor.extractors import _LAZY_LOADER
|
||||||
from .extractor.extractors import _PLUGIN_CLASSES as plugin_extractors
|
from .extractor.extractors import _PLUGIN_CLASSES as plugin_extractors
|
||||||
|
@ -3719,6 +3723,7 @@ class YoutubeDL:
|
||||||
__version__,
|
__version__,
|
||||||
f'[{RELEASE_GIT_HEAD}]' if RELEASE_GIT_HEAD else '',
|
f'[{RELEASE_GIT_HEAD}]' if RELEASE_GIT_HEAD else '',
|
||||||
'' if source == 'unknown' else f'({source})',
|
'' if source == 'unknown' else f'({source})',
|
||||||
|
'' if _IN_CLI else 'API',
|
||||||
delim=' '))
|
delim=' '))
|
||||||
if not _LAZY_LOADER:
|
if not _LAZY_LOADER:
|
||||||
if os.environ.get('YTDLP_NO_LAZY_EXTRACTORS'):
|
if os.environ.get('YTDLP_NO_LAZY_EXTRACTORS'):
|
||||||
|
|
|
@ -24,6 +24,7 @@ from ..utils import (
|
||||||
encodeFilename,
|
encodeFilename,
|
||||||
format_bytes,
|
format_bytes,
|
||||||
join_nonempty,
|
join_nonempty,
|
||||||
|
remove_start,
|
||||||
sanitize_open,
|
sanitize_open,
|
||||||
shell_quote,
|
shell_quote,
|
||||||
timeconvert,
|
timeconvert,
|
||||||
|
@ -120,11 +121,11 @@ class FileDownloader:
|
||||||
time = timetuple_from_msec(seconds * 1000)
|
time = timetuple_from_msec(seconds * 1000)
|
||||||
if time.hours > 99:
|
if time.hours > 99:
|
||||||
return '--:--:--'
|
return '--:--:--'
|
||||||
if not time.hours:
|
|
||||||
return ' %02d:%02d' % time[1:-1]
|
|
||||||
return '%02d:%02d:%02d' % time[:-1]
|
return '%02d:%02d:%02d' % time[:-1]
|
||||||
|
|
||||||
format_eta = format_seconds
|
@classmethod
|
||||||
|
def format_eta(cls, seconds):
|
||||||
|
return f'{remove_start(cls.format_seconds(seconds), "00:"):>8s}'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def calc_percent(byte_counter, data_len):
|
def calc_percent(byte_counter, data_len):
|
||||||
|
@ -332,6 +333,8 @@ class FileDownloader:
|
||||||
return tmpl
|
return tmpl
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
_formats_bytes = lambda k: f'{format_bytes(s.get(k)):>10s}'
|
||||||
|
|
||||||
if s['status'] == 'finished':
|
if s['status'] == 'finished':
|
||||||
if self.params.get('noprogress'):
|
if self.params.get('noprogress'):
|
||||||
self.to_screen('[download] Download completed')
|
self.to_screen('[download] Download completed')
|
||||||
|
@ -339,7 +342,7 @@ class FileDownloader:
|
||||||
s.update({
|
s.update({
|
||||||
'speed': speed,
|
'speed': speed,
|
||||||
'_speed_str': self.format_speed(speed).strip(),
|
'_speed_str': self.format_speed(speed).strip(),
|
||||||
'_total_bytes_str': format_bytes(s.get('total_bytes')),
|
'_total_bytes_str': _formats_bytes('total_bytes'),
|
||||||
'_elapsed_str': self.format_seconds(s.get('elapsed')),
|
'_elapsed_str': self.format_seconds(s.get('elapsed')),
|
||||||
'_percent_str': self.format_percent(100),
|
'_percent_str': self.format_percent(100),
|
||||||
})
|
})
|
||||||
|
@ -354,15 +357,15 @@ class FileDownloader:
|
||||||
return
|
return
|
||||||
|
|
||||||
s.update({
|
s.update({
|
||||||
'_eta_str': self.format_eta(s.get('eta')),
|
'_eta_str': self.format_eta(s.get('eta')).strip(),
|
||||||
'_speed_str': self.format_speed(s.get('speed')),
|
'_speed_str': self.format_speed(s.get('speed')),
|
||||||
'_percent_str': self.format_percent(try_call(
|
'_percent_str': self.format_percent(try_call(
|
||||||
lambda: 100 * s['downloaded_bytes'] / s['total_bytes'],
|
lambda: 100 * s['downloaded_bytes'] / s['total_bytes'],
|
||||||
lambda: 100 * s['downloaded_bytes'] / s['total_bytes_estimate'],
|
lambda: 100 * s['downloaded_bytes'] / s['total_bytes_estimate'],
|
||||||
lambda: s['downloaded_bytes'] == 0 and 0)),
|
lambda: s['downloaded_bytes'] == 0 and 0)),
|
||||||
'_total_bytes_str': format_bytes(s.get('total_bytes')),
|
'_total_bytes_str': _formats_bytes('total_bytes'),
|
||||||
'_total_bytes_estimate_str': format_bytes(s.get('total_bytes_estimate')),
|
'_total_bytes_estimate_str': _formats_bytes('total_bytes_estimate'),
|
||||||
'_downloaded_bytes_str': format_bytes(s.get('downloaded_bytes')),
|
'_downloaded_bytes_str': _formats_bytes('downloaded_bytes'),
|
||||||
'_elapsed_str': self.format_seconds(s.get('elapsed')),
|
'_elapsed_str': self.format_seconds(s.get('elapsed')),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1862,7 +1862,7 @@ class InfoExtractor:
|
||||||
alias, field = field, self._get_field_setting(field, 'field')
|
alias, field = field, self._get_field_setting(field, 'field')
|
||||||
if self._get_field_setting(alias, 'deprecated'):
|
if self._get_field_setting(alias, 'deprecated'):
|
||||||
self.ydl.deprecated_feature(f'Format sorting alias {alias} is deprecated and may '
|
self.ydl.deprecated_feature(f'Format sorting alias {alias} is deprecated and may '
|
||||||
'be removed in a future version. Please use {field} instead')
|
f'be removed in a future version. Please use {field} instead')
|
||||||
reverse = match.group('reverse') is not None
|
reverse = match.group('reverse') is not None
|
||||||
closest = match.group('separator') == '~'
|
closest = match.group('separator') == '~'
|
||||||
limit_text = match.group('limit')
|
limit_text = match.group('limit')
|
||||||
|
|
|
@ -16,6 +16,7 @@ from ..utils import (
|
||||||
|
|
||||||
|
|
||||||
class SpotifyBaseIE(InfoExtractor):
|
class SpotifyBaseIE(InfoExtractor):
|
||||||
|
_WORKING = False
|
||||||
_ACCESS_TOKEN = None
|
_ACCESS_TOKEN = None
|
||||||
_OPERATION_HASHES = {
|
_OPERATION_HASHES = {
|
||||||
'Episode': '8276d4423d709ae9b68ec1b74cc047ba0f7479059a37820be730f125189ac2bf',
|
'Episode': '8276d4423d709ae9b68ec1b74cc047ba0f7479059a37820be730f125189ac2bf',
|
||||||
|
|
|
@ -390,6 +390,8 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
|
||||||
'si', 'th', 'lo', 'my', 'ka', 'am', 'km', 'zh-CN', 'zh-TW', 'zh-HK', 'ja', 'ko'
|
'si', 'th', 'lo', 'my', 'ka', 'am', 'km', 'zh-CN', 'zh-TW', 'zh-HK', 'ja', 'ko'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
_IGNORED_WARNINGS = {'Unavailable videos will be hidden during playback'}
|
||||||
|
|
||||||
@functools.cached_property
|
@functools.cached_property
|
||||||
def _preferred_lang(self):
|
def _preferred_lang(self):
|
||||||
"""
|
"""
|
||||||
|
@ -692,12 +694,11 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
|
||||||
yield alert_type, message
|
yield alert_type, message
|
||||||
|
|
||||||
def _report_alerts(self, alerts, expected=True, fatal=True, only_once=False):
|
def _report_alerts(self, alerts, expected=True, fatal=True, only_once=False):
|
||||||
errors = []
|
errors, warnings = [], []
|
||||||
warnings = []
|
|
||||||
for alert_type, alert_message in alerts:
|
for alert_type, alert_message in alerts:
|
||||||
if alert_type.lower() == 'error' and fatal:
|
if alert_type.lower() == 'error' and fatal:
|
||||||
errors.append([alert_type, alert_message])
|
errors.append([alert_type, alert_message])
|
||||||
else:
|
elif alert_message not in self._IGNORED_WARNINGS:
|
||||||
warnings.append([alert_type, alert_message])
|
warnings.append([alert_type, alert_message])
|
||||||
|
|
||||||
for alert_type, alert_message in (warnings + errors[:-1]):
|
for alert_type, alert_message in (warnings + errors[:-1]):
|
||||||
|
|
Loading…
Reference in New Issue