Skip to content

Commit 4148522

Browse files
committed
feat(server): add global httpProxy config + HQ audio format tags
feat(server): global httpProxy config config.default.js - Add server.httpProxy block (enabled, url, username, password) src/typings/config/config.types.ts - ServerConfig: add httpProxy? field with JSDoc src/typings/utils.types.ts - NodelinkRuntime: add options?.server?.httpProxy field src/utils.ts - makeRequest(): fall back to server.httpProxy when no per-request proxy is set (HttpProxyConfig already imported) src/index.ts - Import makeRequest from utils - constructor(): log proxy URL + call _testProxyConnectivity() - Add _testProxyConnectivity(): probes generate_204 (non-fatal) feat(youtube): add HQ audio format tags 774 and 141 src/sources/youtube/common.ts - _getQualityPriority(): add itag 774 (Opus ~260-360 kbps) and 141 (AAC 256 kbps) at the top of high/medium priority lists - These formats require a valid cookiePath to be served by YouTube
1 parent bc5384e commit 4148522

6 files changed

Lines changed: 76 additions & 3 deletions

File tree

config.default.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ export default {
33
host: '0.0.0.0',
44
port: 3000,
55
password: 'youshallnotpass',
6-
useBunServer: false // set to true to use Bun.serve websocket (experimental)
6+
useBunServer: false, // set to true to use Bun.serve websocket (experimental)
7+
httpProxy: {
8+
enabled: false, // route all outbound HTTP requests through a proxy
9+
url: '', // e.g. 'http://user:pass@host:3128' or 'socks5://host:1080'
10+
username: '', // Optional — overrides credentials in the URL
11+
password: '' // Optional — overrides credentials in the URL
12+
}
713
},
814
cluster: {
915
enabled: true, // active cluster (or use env CLUSTER_ENABLED)

src/index.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
getVersion,
2020
initLogger,
2121
logger,
22+
makeRequest,
2223
parseClient,
2324
verifyDiscordID
2425
} from './utils.ts'
@@ -595,6 +596,34 @@ class NodelinkServer extends EventEmitter {
595596
'Server',
596597
`git branch: ${this.gitInfo.branch}, commit: ${this.gitInfo.commit}, committed on: ${new Date(this.gitInfo.commitTime).toISOString()}`
597598
)
599+
600+
// [feat] global-http-proxy: log proxy status and test connectivity at startup
601+
const proxyCfg = options?.server?.httpProxy
602+
if (proxyCfg?.enabled && proxyCfg.url) {
603+
logger('info', 'Proxy', `HTTP proxy enabled: ${proxyCfg.url}`)
604+
this._testProxyConnectivity(proxyCfg.url)
605+
}
606+
}
607+
608+
/**
609+
* Tests HTTP proxy connectivity at startup by probing a known endpoint.
610+
* Logs success or failure without throwing — a failed probe is non-fatal.
611+
* @internal
612+
*/
613+
private _testProxyConnectivity(proxyUrl: string): void {
614+
makeRequest('http://connectivitycheck.gstatic.com/generate_204', {
615+
proxy: { url: proxyUrl }
616+
})
617+
.then(() => {
618+
logger('info', 'Proxy', `Connected successfully via ${proxyUrl}`)
619+
})
620+
.catch((err: Error) => {
621+
logger(
622+
'warn',
623+
'Proxy',
624+
`Proxy connectivity check failed (${proxyUrl}): ${err.message}`
625+
)
626+
})
598627
}
599628

600629
/**

src/sources/youtube/common.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3111,9 +3111,12 @@ export abstract class BaseClient {
31113111
* @internal
31123112
*/
31133113
_getQualityPriority(): Record<string, number[]> {
3114+
// 774 = Opus ~260-360 kbps (premium HQ audio)
3115+
// 141 = AAC 256 kbps (premium HQ audio, non-Opus fallback)
3116+
// These are only served to authenticated/premium accounts (requires cookiePath).
31143117
return {
3115-
high: [251, 250, 140],
3116-
medium: [250, 140],
3118+
high: [774, 141, 251, 250, 140],
3119+
medium: [141, 251, 250, 140],
31173120
low: [249, 250, 140],
31183121
lowest: [249, 139]
31193122
}

src/typings/config/config.types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ export interface ServerConfig {
3232
* @experimental
3333
*/
3434
useBunServer?: boolean
35+
36+
/**
37+
* Global HTTP proxy applied to all outbound requests from NodeLink.
38+
* When enabled, every call to makeRequest() will be routed through
39+
* the proxy unless the request already specifies its own proxy.
40+
* Supports http, https, and socks5 proxy URLs.
41+
*/
42+
httpProxy?: {
43+
enabled: boolean
44+
url: string
45+
username?: string
46+
password?: string
47+
}
3548
}
3649

3750
/**

src/typings/utils.types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,17 @@ export interface NodelinkRuntime {
353353
routePlanner?: RoutePlannerRuntime
354354
/** Optional stats manager instance. */
355355
statsManager?: StatsManager
356+
/** Global HTTP proxy server options. */
357+
options?: {
358+
server?: {
359+
httpProxy?: {
360+
enabled: boolean
361+
url: string
362+
username?: string
363+
password?: string
364+
}
365+
}
366+
}
356367
}
357368

358369
/**

src/utils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,17 @@ async function makeRequest(
16581658
return http1makeRequest(urlString, options)
16591659
}
16601660

1661+
// [feat] global-http-proxy: fall back to server-wide proxy when no per-request proxy is set
1662+
const globalProxyCfg = finalNodeLink?.options?.server?.httpProxy
1663+
if (globalProxyCfg?.enabled && globalProxyCfg.url) {
1664+
const globalProxy: HttpProxyConfig = {
1665+
url: globalProxyCfg.url,
1666+
username: globalProxyCfg.username,
1667+
password: globalProxyCfg.password
1668+
}
1669+
return http1makeRequest(urlString, { ...options, proxy: globalProxy })
1670+
}
1671+
16611672
const localAddress = finalNodeLink?.routePlanner?.getIP?.() ?? undefined
16621673

16631674
try {

0 commit comments

Comments
 (0)