mirror of
https://github.com/yt-dlp/yt-dlp
synced 2024-12-26 21:59:08 +01:00
Merge branch 'yt-dlp:master' into patch-2
This commit is contained in:
commit
aed5241187
8 changed files with 33 additions and 15 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -468,7 +468,7 @@ jobs:
|
||||||
- name: Install Requirements
|
- name: Install Requirements
|
||||||
run: |
|
run: |
|
||||||
python devscripts/install_deps.py -o --include build
|
python devscripts/install_deps.py -o --include build
|
||||||
python devscripts/install_deps.py
|
python devscripts/install_deps.py --include curl-cffi
|
||||||
python -m pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/i686/pyinstaller-6.7.0-py3-none-any.whl"
|
python -m pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/i686/pyinstaller-6.7.0-py3-none-any.whl"
|
||||||
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
|
|
|
@ -202,7 +202,7 @@ The following provide support for impersonating browser requests. This may be re
|
||||||
|
|
||||||
* [**curl_cffi**](https://github.com/yifeikong/curl_cffi) (recommended) - Python binding for [curl-impersonate](https://github.com/lwthiker/curl-impersonate). Provides impersonation targets for Chrome, Edge and Safari. Licensed under [MIT](https://github.com/yifeikong/curl_cffi/blob/main/LICENSE)
|
* [**curl_cffi**](https://github.com/yifeikong/curl_cffi) (recommended) - Python binding for [curl-impersonate](https://github.com/lwthiker/curl-impersonate). Provides impersonation targets for Chrome, Edge and Safari. Licensed under [MIT](https://github.com/yifeikong/curl_cffi/blob/main/LICENSE)
|
||||||
* Can be installed with the `curl-cffi` group, e.g. `pip install "yt-dlp[default,curl-cffi]"`
|
* Can be installed with the `curl-cffi` group, e.g. `pip install "yt-dlp[default,curl-cffi]"`
|
||||||
* Currently only included in `yt-dlp.exe` and `yt-dlp_macos` builds
|
* Currently included in `yt-dlp.exe`, `yt-dlp_x86.exe`, `yt-dlp_linux` and `yt-dlp_macos` builds
|
||||||
|
|
||||||
|
|
||||||
### Metadata
|
### Metadata
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
source ~/.local/share/pipx/venvs/pyinstaller/bin/activate
|
source ~/.local/share/pipx/venvs/pyinstaller/bin/activate
|
||||||
python -m devscripts.install_deps --include secretstorage
|
python -m devscripts.install_deps --include secretstorage --include curl-cffi
|
||||||
python -m devscripts.make_lazy_extractors
|
python -m devscripts.make_lazy_extractors
|
||||||
python devscripts/update-version.py -c "${channel}" -r "${origin}" "${version}"
|
python devscripts/update-version.py -c "${channel}" -r "${origin}" "${version}"
|
||||||
python -m bundle.pyinstaller
|
python -m bundle.pyinstaller
|
||||||
|
|
|
@ -53,7 +53,9 @@ dependencies = [
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
default = []
|
default = []
|
||||||
curl-cffi = ["curl-cffi==0.5.10; implementation_name=='cpython'"]
|
curl-cffi = [
|
||||||
|
"curl-cffi>=0.5.10,!=0.6.*,<0.8; implementation_name=='cpython'",
|
||||||
|
]
|
||||||
secretstorage = [
|
secretstorage = [
|
||||||
"cffi",
|
"cffi",
|
||||||
"secretstorage",
|
"secretstorage",
|
||||||
|
|
|
@ -914,7 +914,6 @@ class TestRequestsRequestHandler(TestRequestHandlerBase):
|
||||||
class TestCurlCFFIRequestHandler(TestRequestHandlerBase):
|
class TestCurlCFFIRequestHandler(TestRequestHandlerBase):
|
||||||
|
|
||||||
@pytest.mark.parametrize('params,extensions', [
|
@pytest.mark.parametrize('params,extensions', [
|
||||||
({}, {'impersonate': ImpersonateTarget('chrome')}),
|
|
||||||
({'impersonate': ImpersonateTarget('chrome', '110')}, {}),
|
({'impersonate': ImpersonateTarget('chrome', '110')}, {}),
|
||||||
({'impersonate': ImpersonateTarget('chrome', '99')}, {'impersonate': ImpersonateTarget('chrome', '110')}),
|
({'impersonate': ImpersonateTarget('chrome', '99')}, {'impersonate': ImpersonateTarget('chrome', '110')}),
|
||||||
])
|
])
|
||||||
|
|
|
@ -1458,9 +1458,11 @@ class TikTokLiveIE(TikTokBaseIE):
|
||||||
|
|
||||||
if webpage:
|
if webpage:
|
||||||
data = self._get_sigi_state(webpage, uploader or room_id)
|
data = self._get_sigi_state(webpage, uploader or room_id)
|
||||||
room_id = (traverse_obj(data, ('UserModule', 'users', ..., 'roomId', {str_or_none}), get_all=False)
|
room_id = (
|
||||||
or self._search_regex(r'snssdk\d*://live\?room_id=(\d+)', webpage, 'room ID', default=None)
|
traverse_obj(data, ((
|
||||||
or room_id)
|
('LiveRoom', 'liveRoomUserInfo', 'user'),
|
||||||
|
('UserModule', 'users', ...)), 'roomId', {str}, any))
|
||||||
|
or self._search_regex(r'snssdk\d*://live\?room_id=(\d+)', webpage, 'room ID', default=room_id))
|
||||||
uploader = uploader or traverse_obj(
|
uploader = uploader or traverse_obj(
|
||||||
data, ('LiveRoom', 'liveRoomUserInfo', 'user', 'uniqueId'),
|
data, ('LiveRoom', 'liveRoomUserInfo', 'user', 'uniqueId'),
|
||||||
('UserModule', 'users', ..., 'uniqueId'), get_all=False, expected_type=str)
|
('UserModule', 'users', ..., 'uniqueId'), get_all=False, expected_type=str)
|
||||||
|
|
|
@ -3142,7 +3142,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||||
|
|
||||||
def _extract_n_function_code(self, video_id, player_url):
|
def _extract_n_function_code(self, video_id, player_url):
|
||||||
player_id = self._extract_player_info(player_url)
|
player_id = self._extract_player_info(player_url)
|
||||||
func_code = self.cache.load('youtube-nsig', player_id, min_ver='2022.09.1')
|
func_code = self.cache.load('youtube-nsig', player_id, min_ver='2024.07.09')
|
||||||
jscode = func_code or self._load_player(video_id, player_url)
|
jscode = func_code or self._load_player(video_id, player_url)
|
||||||
jsi = JSInterpreter(jscode)
|
jsi = JSInterpreter(jscode)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import io
|
import io
|
||||||
import math
|
import math
|
||||||
|
import re
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
from ._helper import InstanceStoreMixin, select_proxy
|
from ._helper import InstanceStoreMixin, select_proxy
|
||||||
|
@ -27,11 +28,12 @@ from ..utils import int_or_none
|
||||||
if curl_cffi is None:
|
if curl_cffi is None:
|
||||||
raise ImportError('curl_cffi is not installed')
|
raise ImportError('curl_cffi is not installed')
|
||||||
|
|
||||||
curl_cffi_version = tuple(int_or_none(x, default=0) for x in curl_cffi.__version__.split('.'))
|
|
||||||
|
|
||||||
if curl_cffi_version != (0, 5, 10):
|
curl_cffi_version = tuple(map(int, re.split(r'[^\d]+', curl_cffi.__version__)[:3]))
|
||||||
|
|
||||||
|
if curl_cffi_version != (0, 5, 10) and not ((0, 7, 0) <= curl_cffi_version < (0, 8, 0)):
|
||||||
curl_cffi._yt_dlp__version = f'{curl_cffi.__version__} (unsupported)'
|
curl_cffi._yt_dlp__version = f'{curl_cffi.__version__} (unsupported)'
|
||||||
raise ImportError('Only curl_cffi 0.5.10 is supported')
|
raise ImportError('Only curl_cffi versions 0.5.10, 0.7.X are supported')
|
||||||
|
|
||||||
import curl_cffi.requests
|
import curl_cffi.requests
|
||||||
from curl_cffi.const import CurlECode, CurlOpt
|
from curl_cffi.const import CurlECode, CurlOpt
|
||||||
|
@ -110,6 +112,13 @@ class CurlCFFIRH(ImpersonateRequestHandler, InstanceStoreMixin):
|
||||||
_SUPPORTED_FEATURES = (Features.NO_PROXY, Features.ALL_PROXY)
|
_SUPPORTED_FEATURES = (Features.NO_PROXY, Features.ALL_PROXY)
|
||||||
_SUPPORTED_PROXY_SCHEMES = ('http', 'https', 'socks4', 'socks4a', 'socks5', 'socks5h')
|
_SUPPORTED_PROXY_SCHEMES = ('http', 'https', 'socks4', 'socks4a', 'socks5', 'socks5h')
|
||||||
_SUPPORTED_IMPERSONATE_TARGET_MAP = {
|
_SUPPORTED_IMPERSONATE_TARGET_MAP = {
|
||||||
|
**({
|
||||||
|
ImpersonateTarget('chrome', '124', 'macos', '14'): curl_cffi.requests.BrowserType.chrome124,
|
||||||
|
ImpersonateTarget('chrome', '123', 'macos', '14'): curl_cffi.requests.BrowserType.chrome123,
|
||||||
|
ImpersonateTarget('chrome', '120', 'macos', '14'): curl_cffi.requests.BrowserType.chrome120,
|
||||||
|
ImpersonateTarget('chrome', '119', 'macos', '14'): curl_cffi.requests.BrowserType.chrome119,
|
||||||
|
ImpersonateTarget('chrome', '116', 'windows', '10'): curl_cffi.requests.BrowserType.chrome116,
|
||||||
|
} if curl_cffi_version >= (0, 7, 0) else {}),
|
||||||
ImpersonateTarget('chrome', '110', 'windows', '10'): curl_cffi.requests.BrowserType.chrome110,
|
ImpersonateTarget('chrome', '110', 'windows', '10'): curl_cffi.requests.BrowserType.chrome110,
|
||||||
ImpersonateTarget('chrome', '107', 'windows', '10'): curl_cffi.requests.BrowserType.chrome107,
|
ImpersonateTarget('chrome', '107', 'windows', '10'): curl_cffi.requests.BrowserType.chrome107,
|
||||||
ImpersonateTarget('chrome', '104', 'windows', '10'): curl_cffi.requests.BrowserType.chrome104,
|
ImpersonateTarget('chrome', '104', 'windows', '10'): curl_cffi.requests.BrowserType.chrome104,
|
||||||
|
@ -118,9 +127,15 @@ class CurlCFFIRH(ImpersonateRequestHandler, InstanceStoreMixin):
|
||||||
ImpersonateTarget('chrome', '99', 'windows', '10'): curl_cffi.requests.BrowserType.chrome99,
|
ImpersonateTarget('chrome', '99', 'windows', '10'): curl_cffi.requests.BrowserType.chrome99,
|
||||||
ImpersonateTarget('edge', '101', 'windows', '10'): curl_cffi.requests.BrowserType.edge101,
|
ImpersonateTarget('edge', '101', 'windows', '10'): curl_cffi.requests.BrowserType.edge101,
|
||||||
ImpersonateTarget('edge', '99', 'windows', '10'): curl_cffi.requests.BrowserType.edge99,
|
ImpersonateTarget('edge', '99', 'windows', '10'): curl_cffi.requests.BrowserType.edge99,
|
||||||
|
**({
|
||||||
|
ImpersonateTarget('safari', '17.0', 'macos', '14'): curl_cffi.requests.BrowserType.safari17_0,
|
||||||
|
} if curl_cffi_version >= (0, 7, 0) else {}),
|
||||||
ImpersonateTarget('safari', '15.5', 'macos', '12'): curl_cffi.requests.BrowserType.safari15_5,
|
ImpersonateTarget('safari', '15.5', 'macos', '12'): curl_cffi.requests.BrowserType.safari15_5,
|
||||||
ImpersonateTarget('safari', '15.3', 'macos', '11'): curl_cffi.requests.BrowserType.safari15_3,
|
ImpersonateTarget('safari', '15.3', 'macos', '11'): curl_cffi.requests.BrowserType.safari15_3,
|
||||||
ImpersonateTarget('chrome', '99', 'android', '12'): curl_cffi.requests.BrowserType.chrome99_android,
|
ImpersonateTarget('chrome', '99', 'android', '12'): curl_cffi.requests.BrowserType.chrome99_android,
|
||||||
|
**({
|
||||||
|
ImpersonateTarget('safari', '17.2', 'ios', '17.2'): curl_cffi.requests.BrowserType.safari17_2_ios,
|
||||||
|
} if curl_cffi_version >= (0, 7, 0) else {}),
|
||||||
}
|
}
|
||||||
|
|
||||||
def _create_instance(self, cookiejar=None):
|
def _create_instance(self, cookiejar=None):
|
||||||
|
@ -187,7 +202,7 @@ class CurlCFFIRH(ImpersonateRequestHandler, InstanceStoreMixin):
|
||||||
timeout = self._calculate_timeout(request)
|
timeout = self._calculate_timeout(request)
|
||||||
|
|
||||||
# set CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME to act as a read timeout. [1]
|
# set CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME to act as a read timeout. [1]
|
||||||
# curl_cffi does not currently do this. [2]
|
# This is required only for 0.5.10 [2]
|
||||||
# Note: CURLOPT_LOW_SPEED_TIME is in seconds, so we need to round up to the nearest second. [3]
|
# Note: CURLOPT_LOW_SPEED_TIME is in seconds, so we need to round up to the nearest second. [3]
|
||||||
# [1] https://unix.stackexchange.com/a/305311
|
# [1] https://unix.stackexchange.com/a/305311
|
||||||
# [2] https://github.com/yifeikong/curl_cffi/issues/156
|
# [2] https://github.com/yifeikong/curl_cffi/issues/156
|
||||||
|
@ -203,7 +218,7 @@ class CurlCFFIRH(ImpersonateRequestHandler, InstanceStoreMixin):
|
||||||
data=request.data,
|
data=request.data,
|
||||||
verify=self.verify,
|
verify=self.verify,
|
||||||
max_redirects=5,
|
max_redirects=5,
|
||||||
timeout=timeout,
|
timeout=(timeout, timeout),
|
||||||
impersonate=self._SUPPORTED_IMPERSONATE_TARGET_MAP.get(
|
impersonate=self._SUPPORTED_IMPERSONATE_TARGET_MAP.get(
|
||||||
self._get_request_target(request)),
|
self._get_request_target(request)),
|
||||||
interface=self.source_address,
|
interface=self.source_address,
|
||||||
|
@ -222,7 +237,7 @@ class CurlCFFIRH(ImpersonateRequestHandler, InstanceStoreMixin):
|
||||||
|
|
||||||
elif (
|
elif (
|
||||||
e.code == CurlECode.PROXY
|
e.code == CurlECode.PROXY
|
||||||
or (e.code == CurlECode.RECV_ERROR and 'Received HTTP code 407 from proxy after CONNECT' in str(e))
|
or (e.code == CurlECode.RECV_ERROR and 'CONNECT' in str(e))
|
||||||
):
|
):
|
||||||
raise ProxyError(cause=e) from e
|
raise ProxyError(cause=e) from e
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue