Skip to content

Commit 9ee2d41

Browse files
Merge branch 'yt-dlp:master' into master
2 parents 025d64f + 679c682 commit 9ee2d41

File tree

6 files changed

+50
-16
lines changed

6 files changed

+50
-16
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ jobs:
240240
permissions:
241241
contents: read
242242
actions: write # For cleaning up cache
243-
runs-on: macos-12
243+
runs-on: macos-13
244244

245245
steps:
246246
- uses: actions/checkout@v4
@@ -346,7 +346,7 @@ jobs:
346346
macos_legacy:
347347
needs: process
348348
if: inputs.macos_legacy
349-
runs-on: macos-12
349+
runs-on: macos-13
350350

351351
steps:
352352
- uses: actions/checkout@v4

yt_dlp/extractor/adobepass.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,7 @@
13551355
class AdobePassIE(InfoExtractor): # XXX: Conventionally, base classes should end with BaseIE/InfoExtractor
13561356
_SERVICE_PROVIDER_TEMPLATE = 'https://sp.auth.adobe.com/adobe-services/%s'
13571357
_USER_AGENT = 'Mozilla/5.0 (X11; Linux i686; rv:47.0) Gecko/20100101 Firefox/47.0'
1358+
_MODERN_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; rv:131.0) Gecko/20100101 Firefox/131.0'
13581359
_MVPD_CACHE = 'ap-mvpd'
13591360

13601361
_DOWNLOADING_LOGIN_PAGE = 'Downloading Provider Login Page'
@@ -1454,7 +1455,11 @@ def extract_redirect_url(html, url=None, fatal=False):
14541455
'no_iframe': 'false',
14551456
'domain_name': 'adobe.com',
14561457
'redirect_url': url,
1457-
})
1458+
}, headers={
1459+
# yt-dlp's default user-agent is usually too old for Comcast_SSO
1460+
# See: https://github.com/yt-dlp/yt-dlp/issues/10848
1461+
'User-Agent': self._MODERN_USER_AGENT,
1462+
} if mso_id == 'Comcast_SSO' else None)
14581463
elif not self._cookies_passed:
14591464
raise_mvpd_required()
14601465

yt_dlp/extractor/substack.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
import urllib.parse
33

44
from .common import InfoExtractor
5-
from ..utils import js_to_json, str_or_none, traverse_obj
5+
from ..networking import HEADRequest
6+
from ..utils import (
7+
determine_ext,
8+
js_to_json,
9+
str_or_none,
10+
)
11+
from ..utils.traversal import traverse_obj
612

713

814
class SubstackIE(InfoExtractor):
@@ -43,6 +49,19 @@ class SubstackIE(InfoExtractor):
4349
'uploader': "Andrew Zimmern's Spilled Milk ",
4450
'uploader_id': '577659',
4551
},
52+
}, {
53+
# Podcast that needs its file extension resolved to mp3
54+
'url': 'https://persuasion1.substack.com/p/summers',
55+
'md5': '1456a755d46084744facdfac9edf900f',
56+
'info_dict': {
57+
'id': '141970405',
58+
'ext': 'mp3',
59+
'title': 'Larry Summers on What Went Wrong on Campus',
60+
'description': 'Yascha Mounk and Larry Summers also discuss the promise and perils of artificial intelligence.',
61+
'thumbnail': r're:https://substackcdn\.com/image/.+\.jpeg',
62+
'uploader': 'Persuasion',
63+
'uploader_id': '61579',
64+
},
4665
}]
4766

4867
@classmethod
@@ -89,7 +108,15 @@ def _real_extract(self, url):
89108
post_type = webpage_info['post']['type']
90109
formats, subtitles = [], {}
91110
if post_type == 'podcast':
92-
formats, subtitles = [{'url': webpage_info['post']['podcast_url']}], {}
111+
fmt = {'url': webpage_info['post']['podcast_url']}
112+
if not determine_ext(fmt['url'], default_ext=None):
113+
# The redirected format URL expires but the original URL doesn't,
114+
# so we only want to extract the extension from this request
115+
fmt['ext'] = determine_ext(self._request_webpage(
116+
HEADRequest(fmt['url']), display_id,
117+
'Resolving podcast file extension',
118+
'Podcast URL is invalid').url)
119+
formats.append(fmt)
93120
elif post_type == 'video':
94121
formats, subtitles = self._extract_video_formats(webpage_info['post']['videoUpload']['id'], canonical_url)
95122
else:

yt_dlp/extractor/twitter.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -934,14 +934,13 @@ class TwitterIE(TwitterBaseIE):
934934
'uploader_id': 'MoniqueCamarra',
935935
'live_status': 'was_live',
936936
'release_timestamp': 1658417414,
937-
'description': 'md5:acce559345fd49f129c20dbcda3f1201',
937+
'description': r're:Twitter Space participated by Sergej Sumlenny.+',
938938
'timestamp': 1658407771,
939939
'release_date': '20220721',
940940
'upload_date': '20220721',
941941
},
942942
'add_ie': ['TwitterSpaces'],
943943
'params': {'skip_download': 'm3u8'},
944-
'skip': 'Requires authentication',
945944
}, {
946945
# URL specifies video number but --yes-playlist
947946
'url': 'https://twitter.com/CTVJLaidlaw/status/1600649710662213632/video/1',
@@ -1856,8 +1855,6 @@ def _build_graphql_query(self, space_id):
18561855

18571856
def _real_extract(self, url):
18581857
space_id = self._match_id(url)
1859-
if not self.is_logged_in:
1860-
self.raise_login_required('Twitter Spaces require authentication')
18611858
space_data = self._call_graphql_api('HPEisOmj1epUNLCWTYhUWw/AudioSpaceById', space_id)['audioSpace']
18621859
if not space_data:
18631860
raise ExtractorError('Twitter Space not found', expected=True)

yt_dlp/extractor/youtube.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4701,11 +4701,12 @@ def process_language(container, base_url, lang_code, sub_name, query):
47014701
headers=self.generate_api_headers(ytcfg=master_ytcfg),
47024702
note='Downloading initial data API JSON')
47034703

4704+
COMMENTS_SECTION_IDS = ('comment-item-section', 'engagement-panel-comments-section')
47044705
info['comment_count'] = traverse_obj(initial_data, (
47054706
'contents', 'twoColumnWatchNextResults', 'results', 'results', 'contents', ..., 'itemSectionRenderer',
47064707
'contents', ..., 'commentsEntryPointHeaderRenderer', 'commentCount',
47074708
), (
4708-
'engagementPanels', lambda _, v: v['engagementPanelSectionListRenderer']['panelIdentifier'] == 'comment-item-section',
4709+
'engagementPanels', lambda _, v: v['engagementPanelSectionListRenderer']['panelIdentifier'] in COMMENTS_SECTION_IDS,
47094710
'engagementPanelSectionListRenderer', 'header', 'engagementPanelTitleHeaderRenderer', 'contextualInfo',
47104711
), expected_type=self._get_count, get_all=False)
47114712

yt_dlp/utils/_utils.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -824,14 +824,18 @@ class Popen(subprocess.Popen):
824824
_startupinfo = None
825825

826826
@staticmethod
827-
def _fix_pyinstaller_ld_path(env):
828-
"""Restore LD_LIBRARY_PATH when using PyInstaller
829-
Ref: https://github.com/pyinstaller/pyinstaller/blob/develop/doc/runtime-information.rst#ld_library_path--libpath-considerations
830-
https://github.com/yt-dlp/yt-dlp/issues/4573
831-
"""
827+
def _fix_pyinstaller_issues(env):
832828
if not hasattr(sys, '_MEIPASS'):
833829
return
834830

831+
# Force spawning independent subprocesses for exes bundled with PyInstaller>=6.10
832+
# Ref: https://pyinstaller.org/en/v6.10.0/CHANGES.html#incompatible-changes
833+
# https://github.com/yt-dlp/yt-dlp/issues/11259
834+
env['PYINSTALLER_RESET_ENVIRONMENT'] = '1'
835+
836+
# Restore LD_LIBRARY_PATH when using PyInstaller
837+
# Ref: https://pyinstaller.org/en/v6.10.0/runtime-information.html#ld-library-path-libpath-considerations
838+
# https://github.com/yt-dlp/yt-dlp/issues/4573
835839
def _fix(key):
836840
orig = env.get(f'{key}_ORIG')
837841
if orig is None:
@@ -845,7 +849,7 @@ def _fix(key):
845849
def __init__(self, args, *remaining, env=None, text=False, shell=False, **kwargs):
846850
if env is None:
847851
env = os.environ.copy()
848-
self._fix_pyinstaller_ld_path(env)
852+
self._fix_pyinstaller_issues(env)
849853

850854
self.__text_mode = kwargs.get('encoding') or kwargs.get('errors') or text or kwargs.get('universal_newlines')
851855
if text is True:

0 commit comments

Comments
 (0)