mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-08-15 17:08:29 +00:00
Merge branch 'upstream-master' into misc-2025-08
This commit is contained in:
commit
8c4d20288e
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -242,7 +242,7 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
actions: write # For cleaning up cache
|
actions: write # For cleaning up cache
|
||||||
runs-on: macos-13
|
runs-on: macos-14
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -261,6 +261,8 @@ jobs:
|
|||||||
- name: Install Requirements
|
- name: Install Requirements
|
||||||
run: |
|
run: |
|
||||||
brew install coreutils
|
brew install coreutils
|
||||||
|
# We need to use system Python in order to roll our own universal2 curl_cffi wheel
|
||||||
|
brew uninstall --ignore-dependencies python3
|
||||||
python3 -m venv ~/yt-dlp-build-venv
|
python3 -m venv ~/yt-dlp-build-venv
|
||||||
source ~/yt-dlp-build-venv/bin/activate
|
source ~/yt-dlp-build-venv/bin/activate
|
||||||
python3 devscripts/install_deps.py -o --include build
|
python3 devscripts/install_deps.py -o --include build
|
||||||
|
@ -62,16 +62,22 @@ def parse_options():
|
|||||||
|
|
||||||
def exe(onedir):
|
def exe(onedir):
|
||||||
"""@returns (name, path)"""
|
"""@returns (name, path)"""
|
||||||
|
platform_name, machine, extension = {
|
||||||
|
'win32': (None, MACHINE, '.exe'),
|
||||||
|
'darwin': ('macos', None, None),
|
||||||
|
}.get(OS_NAME, (OS_NAME, MACHINE, None))
|
||||||
|
|
||||||
name = '_'.join(filter(None, (
|
name = '_'.join(filter(None, (
|
||||||
'yt-dlp',
|
'yt-dlp',
|
||||||
{'win32': '', 'darwin': 'macos'}.get(OS_NAME, OS_NAME),
|
platform_name,
|
||||||
MACHINE,
|
machine,
|
||||||
)))
|
)))
|
||||||
|
|
||||||
return name, ''.join(filter(None, (
|
return name, ''.join(filter(None, (
|
||||||
'dist/',
|
'dist/',
|
||||||
onedir and f'{name}/',
|
onedir and f'{name}/',
|
||||||
name,
|
name,
|
||||||
OS_NAME == 'win32' and '.exe',
|
extension,
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ def is_ad_fragment_end(s):
|
|||||||
line = line.strip()
|
line = line.strip()
|
||||||
if line:
|
if line:
|
||||||
if not line.startswith('#'):
|
if not line.startswith('#'):
|
||||||
if format_index and discontinuity_count != format_index:
|
if format_index is not None and discontinuity_count != format_index:
|
||||||
continue
|
continue
|
||||||
if ad_frag_next:
|
if ad_frag_next:
|
||||||
continue
|
continue
|
||||||
@ -231,7 +231,7 @@ def is_ad_fragment_end(s):
|
|||||||
byte_range = {}
|
byte_range = {}
|
||||||
|
|
||||||
elif line.startswith('#EXT-X-MAP'):
|
elif line.startswith('#EXT-X-MAP'):
|
||||||
if format_index and discontinuity_count != format_index:
|
if format_index is not None and discontinuity_count != format_index:
|
||||||
continue
|
continue
|
||||||
if frag_index > 0:
|
if frag_index > 0:
|
||||||
self.report_error(
|
self.report_error(
|
||||||
|
@ -1781,6 +1781,7 @@
|
|||||||
RTVEALaCartaIE,
|
RTVEALaCartaIE,
|
||||||
RTVEAudioIE,
|
RTVEAudioIE,
|
||||||
RTVELiveIE,
|
RTVELiveIE,
|
||||||
|
RTVEProgramIE,
|
||||||
RTVETelevisionIE,
|
RTVETelevisionIE,
|
||||||
)
|
)
|
||||||
from .rtvs import RTVSIE
|
from .rtvs import RTVSIE
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
class FaulioLiveIE(InfoExtractor):
|
class FaulioLiveIE(InfoExtractor):
|
||||||
_DOMAINS = (
|
_DOMAINS = (
|
||||||
'aloula.sba.sa',
|
'aloula.sba.sa',
|
||||||
|
'bahry.com',
|
||||||
'maraya.sba.net.ae',
|
'maraya.sba.net.ae',
|
||||||
'sat7plus.org',
|
'sat7plus.org',
|
||||||
)
|
)
|
||||||
@ -25,6 +26,18 @@ class FaulioLiveIE(InfoExtractor):
|
|||||||
'params': {
|
'params': {
|
||||||
'skip_download': 'Livestream',
|
'skip_download': 'Livestream',
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
'url': 'https://bahry.com/live/1',
|
||||||
|
'info_dict': {
|
||||||
|
'id': 'bahry.faulio.com_1',
|
||||||
|
'title': str,
|
||||||
|
'description': str,
|
||||||
|
'ext': 'mp4',
|
||||||
|
'live_status': 'is_live',
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': 'Livestream',
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://maraya.sba.net.ae/live/1',
|
'url': 'https://maraya.sba.net.ae/live/1',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
|
@ -34,7 +34,6 @@ class NetEaseMusicBaseIE(InfoExtractor):
|
|||||||
'sky', # SVIP tier; 沉浸环绕声 (Surround Audio); flac
|
'sky', # SVIP tier; 沉浸环绕声 (Surround Audio); flac
|
||||||
)
|
)
|
||||||
_API_BASE = 'http://music.163.com/api/'
|
_API_BASE = 'http://music.163.com/api/'
|
||||||
_GEO_BYPASS = False
|
|
||||||
|
|
||||||
def _create_eapi_cipher(self, api_path, query_body, cookies):
|
def _create_eapi_cipher(self, api_path, query_body, cookies):
|
||||||
request_text = json.dumps({**query_body, 'header': cookies}, separators=(',', ':'))
|
request_text = json.dumps({**query_body, 'header': cookies}, separators=(',', ':'))
|
||||||
@ -64,6 +63,8 @@ def _download_eapi_json(self, path, video_id, query_body, headers={}, **kwargs):
|
|||||||
'MUSIC_U': ('MUSIC_U', {lambda i: i.value}),
|
'MUSIC_U': ('MUSIC_U', {lambda i: i.value}),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
if self._x_forwarded_for_ip:
|
||||||
|
headers.setdefault('X-Real-IP', self._x_forwarded_for_ip)
|
||||||
return self._download_json(
|
return self._download_json(
|
||||||
urljoin('https://interface3.music.163.com/', f'/eapi{path}'), video_id,
|
urljoin('https://interface3.music.163.com/', f'/eapi{path}'), video_id,
|
||||||
data=self._create_eapi_cipher(f'/api{path}', query_body, cookies), headers={
|
data=self._create_eapi_cipher(f'/api{path}', query_body, cookies), headers={
|
||||||
|
@ -6,9 +6,11 @@
|
|||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
|
InAdvancePagedList,
|
||||||
clean_html,
|
clean_html,
|
||||||
determine_ext,
|
determine_ext,
|
||||||
float_or_none,
|
float_or_none,
|
||||||
|
int_or_none,
|
||||||
make_archive_id,
|
make_archive_id,
|
||||||
parse_iso8601,
|
parse_iso8601,
|
||||||
qualities,
|
qualities,
|
||||||
@ -371,3 +373,62 @@ def _real_extract(self, url):
|
|||||||
raise ExtractorError('The webpage doesn\'t contain any video', expected=True)
|
raise ExtractorError('The webpage doesn\'t contain any video', expected=True)
|
||||||
|
|
||||||
return self.url_result(play_url, ie=RTVEALaCartaIE.ie_key())
|
return self.url_result(play_url, ie=RTVEALaCartaIE.ie_key())
|
||||||
|
|
||||||
|
|
||||||
|
class RTVEProgramIE(RTVEBaseIE):
|
||||||
|
IE_NAME = 'rtve.es:program'
|
||||||
|
IE_DESC = 'RTVE.es programs'
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?rtve\.es/play/videos/(?P<id>[\w-]+)/?(?:[?#]|$)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://www.rtve.es/play/videos/saber-vivir/',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '111570',
|
||||||
|
'title': 'Saber vivir - Programa de ciencia y futuro en RTVE Play',
|
||||||
|
},
|
||||||
|
'playlist_mincount': 400,
|
||||||
|
}]
|
||||||
|
_PAGE_SIZE = 60
|
||||||
|
|
||||||
|
def _fetch_page(self, program_id, page_num):
|
||||||
|
return self._download_json(
|
||||||
|
f'https://www.rtve.es/api/programas/{program_id}/videos',
|
||||||
|
program_id, note=f'Downloading page {page_num}',
|
||||||
|
query={
|
||||||
|
'type': 39816,
|
||||||
|
'page': page_num,
|
||||||
|
'size': 60,
|
||||||
|
})
|
||||||
|
|
||||||
|
def _entries(self, page_data):
|
||||||
|
for video in traverse_obj(page_data, ('page', 'items', lambda _, v: url_or_none(v['htmlUrl']))):
|
||||||
|
yield self.url_result(
|
||||||
|
video['htmlUrl'], RTVEALaCartaIE, url_transparent=True,
|
||||||
|
**traverse_obj(video, {
|
||||||
|
'id': ('id', {str}),
|
||||||
|
'title': ('longTitle', {str}),
|
||||||
|
'description': ('shortDescription', {str}),
|
||||||
|
'duration': ('duration', {float_or_none(scale=1000)}),
|
||||||
|
'series': (('programInfo', 'title'), {str}, any),
|
||||||
|
'season_number': ('temporadaOrden', {int_or_none}),
|
||||||
|
'season_id': ('temporadaId', {str}),
|
||||||
|
'season': ('temporada', {str}),
|
||||||
|
'episode_number': ('episode', {int_or_none}),
|
||||||
|
'episode': ('title', {str}),
|
||||||
|
'thumbnail': ('thumbnail', {url_or_none}),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
program_slug = self._match_id(url)
|
||||||
|
program_page = self._download_webpage(url, program_slug)
|
||||||
|
|
||||||
|
program_id = self._html_search_meta('DC.identifier', program_page, 'Program ID', fatal=True)
|
||||||
|
|
||||||
|
first_page = self._fetch_page(program_id, 1)
|
||||||
|
page_count = traverse_obj(first_page, ('page', 'totalPages', {int})) or 1
|
||||||
|
|
||||||
|
entries = InAdvancePagedList(
|
||||||
|
lambda idx: self._entries(self._fetch_page(program_id, idx + 1) if idx else first_page),
|
||||||
|
page_count, self._PAGE_SIZE)
|
||||||
|
|
||||||
|
return self.playlist_result(entries, program_id, self._html_extract_title(program_page))
|
||||||
|
@ -139,7 +139,18 @@ def _get_binary_name():
|
|||||||
|
|
||||||
|
|
||||||
def _get_system_deprecation():
|
def _get_system_deprecation():
|
||||||
MIN_SUPPORTED, MIN_RECOMMENDED = (3, 9), (3, 9)
|
MIN_SUPPORTED, MIN_RECOMMENDED = (3, 9), (3, 10)
|
||||||
|
|
||||||
|
EXE_MSG_TMPL = ('Support for {} has been deprecated. '
|
||||||
|
'See https://github.com/yt-dlp/yt-dlp/{} for details.\n{}')
|
||||||
|
STOP_MSG = 'You may stop receiving updates on this version at any time!'
|
||||||
|
variant = detect_variant()
|
||||||
|
|
||||||
|
# Temporary until macos_legacy executable builds are discontinued
|
||||||
|
if variant == 'darwin_legacy_exe':
|
||||||
|
return EXE_MSG_TMPL.format(
|
||||||
|
f'{variant} (the PyInstaller-bundled executable for macOS versions older than 10.15)',
|
||||||
|
'issues/13856', STOP_MSG)
|
||||||
|
|
||||||
if sys.version_info > MIN_RECOMMENDED:
|
if sys.version_info > MIN_RECOMMENDED:
|
||||||
return None
|
return None
|
||||||
@ -150,6 +161,13 @@ def _get_system_deprecation():
|
|||||||
if sys.version_info < MIN_SUPPORTED:
|
if sys.version_info < MIN_SUPPORTED:
|
||||||
return f'Python version {major}.{minor} is no longer supported! {PYTHON_MSG}'
|
return f'Python version {major}.{minor} is no longer supported! {PYTHON_MSG}'
|
||||||
|
|
||||||
|
# Temporary until aarch64/armv7l build flow is bumped to Ubuntu 22.04 and Python 3.10
|
||||||
|
if variant in ('linux_aarch64_exe', 'linux_armv7l_exe'):
|
||||||
|
libc_ver = version_tuple(os.confstr('CS_GNU_LIBC_VERSION').partition(' ')[2])
|
||||||
|
if libc_ver < (2, 35):
|
||||||
|
return EXE_MSG_TMPL.format('system glibc version < 2.35', 'issues/13858', STOP_MSG)
|
||||||
|
return None
|
||||||
|
|
||||||
return f'Support for Python version {major}.{minor} has been deprecated. {PYTHON_MSG}'
|
return f'Support for Python version {major}.{minor} has been deprecated. {PYTHON_MSG}'
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user