Skip to content

Commit 99228d6

Browse files
Dolly132Rushaway
andauthored
feat(yts): cookies support (#117)
Co-authored-by: Rushaway <rushaway@hotmail.fr>
1 parent a3ccd40 commit 99228d6

5 files changed

Lines changed: 95 additions & 9 deletions

File tree

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,75 @@ You can find more information about available commands with
6767
torchlight --help
6868
```
6969

70+
## YouTube Cookies
71+
72+
In some environments (VPS, dedicated servers, VPN/WARP containers), YouTube search may fail due to rate limits or bot protection.
73+
Providing a valid YouTube cookie file can resolve this issue.
74+
75+
Configure the cookie file in:
76+
77+
`Sounds > CookieFile`
78+
79+
inside your JSON configuration.
80+
81+
---
82+
83+
### How to Get YouTube Cookies
84+
85+
1. Install a browser extension that exports cookies in **Netscape format (`cookies.txt`)**
86+
- Chrome: **Get cookies.txt LOCALLY**
87+
- Firefox: **cookies.txt**
88+
89+
2. Open https://youtube.com and make sure you are logged in.
90+
91+
3. Use the extension to export cookies for `youtube.com`.
92+
93+
4. Save the file as:
94+
95+
```
96+
cookies.txt
97+
```
98+
99+
5. Upload it to your server (example):
100+
101+
```
102+
/app/config/cookies.txt
103+
```
104+
105+
6. Set the path in your configuration:
106+
107+
```json
108+
{
109+
"YoutubeSearch": {
110+
"parameters": {
111+
"proxy": "",
112+
"keywords_banned": [],
113+
"cookies": "config/cookies.txt"
114+
}
115+
}
116+
}
117+
```
118+
119+
7. Restart the container after updating the configuration.
120+
121+
8. It's preferred to use **Cloudflare WARP** (recommended for VPS environments), you can run it using:
122+
https://github.com/cmj2002/warp-docker
123+
124+
Then configure Torchlight to use the WARP container's socks5 proxy:
125+
126+
```yaml
127+
"proxy": "socks5://0.0.0.0:PORT"
128+
```
129+
130+
This routes all requests through WARP, which helps prevent YouTube blocking server IP addresses.
131+
---
132+
133+
### Notes
134+
135+
- Keep your cookie file private (it contains session authentication data).
136+
- If YouTube search stops working, export fresh cookies.
137+
- Do **not** share your cookie file publicly.
138+
70139
## Docker
71140
```
72141
version: '3.7'

config/config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,8 @@
289289
"porn",
290290
"algorithm",
291291
"loud"
292-
]
292+
],
293+
"cookies": "config/cookies.txt"
293294
},
294295
"description": "Search YouTube or play a YouTube link (e.g. !yt never gonna give you up)."
295296
},

src/torchlight/Commands.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -911,10 +911,21 @@ async def _func(self, message: list[str], player: Player) -> int:
911911

912912
real_time = get_url_real_time(url=input_url)
913913

914-
proxy = command_config.get("parameters", {}).get("proxy", "")
914+
proxy: str = command_config.get("parameters", {}).get("proxy", "")
915+
cookies: str = command_config.get("parameters", {}).get("cookies", "")
916+
if not cookies:
917+
self.logger.warning("Parameters/Cookies is empty, please consider adding your own cookies file")
918+
919+
if cookies:
920+
if not os.path.isfile(cookies):
921+
self.logger.warning(f"Cookies file not found: {cookies}, ignoring")
922+
cookies = ""
923+
elif os.path.getsize(cookies) == 0:
924+
self.logger.warning(f"Cookies file is empty: {cookies}, ignoring")
925+
cookies = ""
915926

916927
try:
917-
info = get_url_youtube_info(url=input_url, proxy=proxy)
928+
info = get_url_youtube_info(url=input_url, proxy=proxy, cookies=cookies)
918929
except Exception as exc:
919930
self.logger.error(f"Failed to extract youtube info from: {input_url}")
920931
self.logger.error(exc)
@@ -925,9 +936,9 @@ async def _func(self, message: list[str], player: Player) -> int:
925936
return 1
926937

927938
if "title" not in info and "url" in info:
928-
info = get_url_youtube_info(url=info["url"], proxy=proxy)
939+
info = get_url_youtube_info(url=info["url"], proxy=proxy, cookies=cookies)
929940
if info["extractor_key"] == "YoutubeSearch":
930-
info = get_first_valid_entry(entries=info["entries"], proxy=proxy)
941+
info = get_first_valid_entry(entries=info["entries"], proxy=proxy, cookies=cookies)
931942

932943
title = info["title"]
933944
url = get_audio_format(info=info)

src/torchlight/URLInfo.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def get_url_real_time(url: str) -> int:
102102

103103

104104
# @profile
105-
def get_url_youtube_info(url: str, proxy: str = "") -> dict:
105+
def get_url_youtube_info(url: str, proxy: str = "", cookies: str = "") -> dict:
106106
# https://github.com/ytdl-org/youtube-dl/blob/3e4cedf9e8cd3157df2457df7274d0c842421945/youtube_dl/YoutubeDL.py#L137-L312
107107
# https://github.com/yt-dlp/yt-dlp/blob/master/yt_dlp/YoutubeDL.py#L192
108108
ydl_opts = {
@@ -115,19 +115,24 @@ def get_url_youtube_info(url: str, proxy: str = "") -> dict:
115115
"simulate": True,
116116
"keepvideo": False,
117117
}
118+
118119
if proxy:
119120
ydl_opts["proxy"] = proxy
121+
122+
if cookies:
123+
ydl_opts["cookiefile"] = cookies
124+
120125
ydl = yt_dlp.YoutubeDL(ydl_opts)
121126
ydl.add_default_info_extractors()
122127
return ydl.extract_info(url, download=False)
123128

124129

125130
# @profile
126-
def get_first_valid_entry(entries: list[Any], proxy: str = "") -> dict[str, Any]:
131+
def get_first_valid_entry(entries: list[Any], proxy: str = "", cookies: str = "") -> dict[str, Any]:
127132
for entry in entries:
128133
input_url = f"https://youtube.com/watch?v={entry['id']}"
129134
try:
130-
info = get_url_youtube_info(url=input_url, proxy=proxy)
135+
info = get_url_youtube_info(url=input_url, proxy=proxy, cookies=cookies)
131136
return info
132137
except yt_dlp.utils.DownloadError:
133138
logger.warning(f"Error trying to download <{input_url}>")

src/torchlight/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.7.0"
1+
__version__ = "1.8.0"

0 commit comments

Comments
 (0)