-
Notifications
You must be signed in to change notification settings - Fork 630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[自己已临时解决]youtube音源无法使用 #1355
Comments
我自己临时解决了,主要是request.js需要添加代理,暂时不支持和自定义上游(就是参数里的-u)共存。 const zlib = require('zlib');
const http = require('http');
const https = require('https');
const ON_CANCEL = require('./cancel');
const RequestCancelled = require('./exceptions/RequestCancelled');
const { logScope } = require('./logger');
const parse = require('url').parse;
const format = require('url').format;
const logger = logScope('request');
const timeoutThreshold = 10 * 1000;
//process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
const HttpsProxyAgent = require('https-proxy-agent').HttpsProxyAgent;
// 代理服务器的地址和端口
const proxyHost = '127.0.0.1';
const proxyPort = 10809;
const translate = (host) => (global.hosts || {})[host] || host;
const create = (url, proxy) =>
(((typeof proxy === 'undefined' ? global.proxy : proxy) || url).protocol ===
'https:'
? https
: http
).request;
const configure = (method, url, headers, proxy) => {
headers = headers || {};
proxy = typeof proxy === 'undefined' ? global.proxy : proxy;
if ('content-length' in headers) delete headers['content-length'];
const options = {};
options._headers = headers;
if (proxy && url.protocol === 'https:') {
options.method = 'CONNECT';
options.headers = Object.keys(headers).reduce(
(result, key) =>
Object.assign(
result,
['host', 'user-agent'].includes(key) && {
[key]: headers[key],
}
),
{}
);
} else {
options.method = method;
options.headers = headers;
}
if (proxy) {
options.hostname = translate(proxy.hostname);
options.port = proxy.port || (proxy.protocol === 'https:' ? 443 : 80);
options.path =
url.protocol === 'https:'
? translate(url.hostname) + ':' + (url.port || 443)
: 'http://' + translate(url.hostname) + url.path;
} else {
options.hostname = translate(url.hostname);
options.port = url.port || (url.protocol === 'https:' ? 443 : 80);
options.path = url.path;
}
if (
(url.hostname.endsWith('googlevideo.com') ||
url.hostname.endsWith('youtube.com')) &&
url.protocol === 'https:'
) {
options.agent = new HttpsProxyAgent({
host: proxyHost,
port: proxyPort,
});
}
return options;
};
/**
* @typedef {((raw: true) => Promise<Buffer>) | ((raw: false) => Promise<string>)} RequestExtensionBody
*/
/**
* @template T
* @typedef {{url: string, body: RequestExtensionBody, json: () => Promise<T>, jsonp: () => Promise<T>}} RequestExtension
*/
/**
* @template T
* @param {string} method
* @param {string} receivedUrl
* @param {Object?} receivedHeaders
* @param {unknown?} body
* @param {unknown?} proxy
* @param {CancelRequest?} cancelRequest
* @return {Promise<http.IncomingMessage & RequestExtension<T>>}
*/
const request = (
method,
receivedUrl,
receivedHeaders,
body,
proxy,
cancelRequest
) => {
const url = parse(receivedUrl);
/* @type {Partial<Record<string,string>>} */
const headers = receivedHeaders || {};
const options = configure(
method,
url,
{
host: url.hostname,
accept: 'application/json, text/plain, */*',
'accept-encoding': 'gzip, deflate',
'accept-language': 'zh-CN,zh;q=0.9',
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
...headers,
},
proxy
);
return new Promise((resolve, reject) => {
logger.debug(`Start requesting ${receivedUrl}`);
const clientRequest = create(url, proxy)(options);
const destroyClientRequest = function () {
// We destroy the request and throw RequestCancelled
// when the request has been cancelled.
clientRequest.destroy(new RequestCancelled(format(url)));
};
cancelRequest?.on(ON_CANCEL, destroyClientRequest);
if (cancelRequest?.cancelled ?? false) destroyClientRequest();
clientRequest
.setTimeout(timeoutThreshold, () => {
logger.warn(
{
url: format(url),
},
`The request timed out, or the requester didn't handle the response.`
);
destroyClientRequest();
})
.on('response', (response) => resolve(response))
.on('connect', (_, socket) => {
logger.debug(
'received CONNECT, continuing with https.request()...'
);
https
.request({
method: method,
path: url.path,
headers: options._headers,
socket: socket,
agent: false,
})
.on('response', (response) => resolve(response))
.on('error', (error) => reject(error))
.end(body);
})
.on('error', (error) => reject(error))
.end(options.method.toUpperCase() === 'CONNECT' ? undefined : body);
}).then(
/** @param {http.IncomingMessage} response */
(response) => {
if (cancelRequest?.cancelled ?? false)
return Promise.reject(new RequestCancelled(format(url)));
if ([201, 301, 302, 303, 307, 308].includes(response.statusCode)) {
const redirectTo = url.resolve(
response.headers.location || url.href
);
logger.debug(`Redirect to ${redirectTo}`);
delete headers.host;
return request(method, redirectTo, headers, body, proxy);
}
return Object.assign(response, {
url,
body: (raw) => read(response, raw),
json: () => json(response),
jsonp: () => jsonp(response),
});
}
);
};
const read = (connect, raw) =>
new Promise((resolve, reject) => {
const chunks = [];
connect
.on('data', (chunk) => chunks.push(chunk))
.on('end', () => resolve(Buffer.concat(chunks)))
.on('error', (error) => reject(error));
}).then((buffer) => {
if (buffer.length) {
switch (connect.headers['content-encoding']) {
case 'deflate':
case 'gzip':
buffer = zlib.unzipSync(buffer);
break;
case 'br':
buffer = zlib.brotliDecompressSync(buffer);
break;
}
}
return raw ? buffer : buffer.toString();
});
const json = (connect) => read(connect, false).then((body) => JSON.parse(body));
const jsonp = (connect) =>
read(connect, false).then((body) =>
JSON.parse(body.slice(body.indexOf('(') + 1, -')'.length))
);
request.read = read;
request.create = create;
request.translate = translate;
request.configure = configure;
module.exports = request; 需要在程序所在文件夹里安装 npm install https-proxy-agent |
你这个是啥?我是自己魔改的nodejs代码? |
问一下,我已经安装了ytdlp,为什么还是提示 You must install "yt-dlp" before using the "ytdlp" source. |
我是把exe和yt-dlp放一个目录就能用了 |
是的,要么放一起,要么把yt-dlp所在文件夹添加到系统环境变量的path中 |
感谢,不过我这边换成了socks: 不知道哪里有问题,还是不能下载: 看了一下src/provider/yt-dlp文件,id没有获取成功,好像完全没连上youtube,可为什么命令行里能获取啊? |
我那个文件修改了好多地方,你再看看? |
请问一下ubnuntu20.04如何操作 |
本来我也想用楼主的方法但我用着的代理没有http代理选项,然后参考了楼上用sock方法的这位 我更新一下这个问题吧。对于需要科学上网环境情况下(以下以yt-dlp为示例):
这里添加代理只能为yt-dlp程序提供代理环境,我们还需要对UnblockNeteaseMusic项目进行添加请求的代理 2、改动src/request.js文件,http的方法请参考楼主,我是参考楼上这位用的socks的方法,但似乎差点参数,然后我去找了下资料,贴下关键code
|
很感謝你們幫忙 patch YouTube 音源的問題~ 不知道有沒有興趣發個 Pull Request 到上游,方便合併,讓更多人受益~ 😄 |
其实我就是一直有一个问题要问,启动参数中的-u添加上游代理指的是什么?和我通过本地http代理有什么区别? |
手上只有黑裙6.0,只能node 12套件,只能去改precompiled/app.js, 成功了,然后挂载到docker也成功了 |
获取到音频后,你们能正常完整播放吗?我现在开着代理还是只能播放 9s |
-u 应该是指定用于和网易云音乐服务器通讯的代理,继承自 nondanee 的代码,历史问题了。 |
Bug 描述
YouTube音源没有收到信息
预期行为
No response
实际行为
No response
复现步骤
No response
启动命令及环境变量
日志内容
网易云音乐歌曲链接
No response
网易云音乐版本号
3.0.0
操作系统
win10 x64
其他信息
No response
问题排查
The text was updated successfully, but these errors were encountered: