// ==UserScript==
// @name YouTube视频&音乐&儿童广告拦截
// @name:zh-CN YouTube视频&音乐&儿童广告拦截
// @name:zh-TW YouTube視頻&音樂&兒童廣告攔截
// @name:zh-HK YouTube視頻&音樂&兒童廣告攔截
// @name:en YouTubeVideo&music&kidsAdBlocking
// @namespace http://tampermonkey.net/
// @version 1.4.0
// @description 拦截所有youtube视频广告,音乐播放广告,儿童视频广告,不留白,不闪屏,无感,体验第一。已适配移动端,支持自定义拦截,添加影视频道
// @description:zh-CN 拦截所有youtube视频广告,音乐播放广告,儿童視頻廣告,不留白,不闪屏,无感,体验第一。已适配移动端,支持自定义拦截,添加影视频道
// @description:zh-TW 攔截所有YouTube視頻廣告,音樂播放廣告,兒童視頻廣告,不留白,不閃屏,無感,體驗第一。已適配移動端,支持自定義攔截,添加影視頻道
// @description:zh-HK 攔截所有YouTube視頻廣告,音樂播放廣告,兒童視頻廣告,不留白,不閃屏,無感,體驗第一。已適配移動端,支持自定義攔截,添加影視頻道
// @description:en Intercept all YouTube video ads, music playback ads, youtube kids ads, without leaving blank space, no flash screens, seamless experience, the first choice in user experience. Adapted for mobile devices, supports customizable interception, and allows the addition of video channels
// @author hua
// @match https://www.youtube.com/*
// @match https://m.youtube.com/*
// @match https://music.youtube.com/*
// @match https://www.youtubekids.com/watch*
// @connect https://update.gf.qytechs.cn/
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @run-at document-start
// @license MIT
// ==/UserScript==
const open_config_keyword = '2333';
const display_error_keyword = '2444';
let channel_id = GM_getValue('last_channel_id', 'default');
let user_data_api = get_user_data_api();
let user_data = user_data_api.get();
let open_recommend_tv_goodselect = 'off';
let open_recommend_featured = 'off';
let tmp_debugger_value;
let limit_eval = false;
let local_this = this;
let is_account_init;
let inject_info = {
"ytInitialPlayerResponse": false,
"ytInitialData": false,
"ytInitialReelWatchSequenceResponse": false,
"xhr": false,
"fetch": false
};
let orgin_log = console.log;
const script_url = 'https://update.gf.qytechs.cn/scripts/480192/youtube%E5%B9%BF%E5%91%8A%E6%8B%A6%E6%88%AA.user.js';
let href = location.href;
let ytInitialPlayerResponse_rule;
let ytInitialData_rule;
let ytInitialReelWatchSequenceResponse_rule;
let open_debugger = true;
let isinint = false;
let mobile_web;
let movie_channel_info;
let mobile_movie_channel_info;
let flag_info;
let debugger_ytInitialPlayerResponse;
let debugger_ytInitialData;
let debugger_ytInitialReelWatchSequenceResponse;
let page_type;
let error_messages = [];
let data_process;
let shorts_fun;
let yt_api;
const SPLIT_TAG = '###';
class DATA_PROCESS {
constructor() {
try {
let tmp;
eval('1===1');
this.limit_eval = false;
} catch (error) {
this.limit_eval = true;
}
this.obj_filter;
this.obj_storage = {};
}
storage_obj(key, obj) {
this.obj_storage[key] = obj;
}
set_obj_filter = function (obj_filter) {
this.obj_filter = typeof obj_filter === 'function' ? obj_filter : undefined;
};
text_process(data, values, mode, traverse_all) {
if (!values) return data;
mode = mode || 'cover';
if (mode === 'reg') {
for (let value of values) {
let patten_express = value.split(SPLIT_TAG)[0];
let replace_value = value.split(SPLIT_TAG)[1];
let patten = new RegExp(patten_express, "g");
data = data.replace(patten, replace_value);
}
}
if (mode === 'cover') {
data = values[0];
}
if (mode === 'insert') {
traverse_all = traverse_all || false;
let json_data;
try {
json_data = JSON.parse(data);
} catch (error) {
log('text_process JSON parse error', -1);
return data;
}
this.obj_process(json_data, values, traverse_all);
data = JSON.stringify(json_data);
}
return data;
}
value_parase(parase_value) {
parase_value = parase_value.trim();
const json_math = parase_value.match(/^json\((.*)\)$/);
if (json_math) return JSON.parse(json_math[1]);
const obj_match = parase_value.match(/^obj\((.*)\)$/);
if (obj_match) return this.string_to_value(unsafeWindow, obj_match[1]);
const number_match = parase_value.match(/^num\((.*)\)$/);
if (number_match) return Number(number_match[1]);
const method_match = parase_value.match(/^method\((.*)\)$/);
if (method_match) {
// eval 限制的时候可以使用num() obj()这些添加数字对象 方法也要放到unsafeWindow里 例:method(b("123",num(23)))
// 不限制的时候 不能使用num和obj 方法不需要放到unsafeWindow里 例:method(b("123",23))
if (limit_eval) {
method_info = method_match[1].match(/(.*?)\((.*)\)$/);
method_name = method_info[1];
method_args_string = method_info[2];
method_args = method_args_string.split(',');
const args = [];
for (let arg of method_args) {
args.push(value_parase(arg));
}
return unsafeWindow[method_name](...args);
}
return eval(method_match[1]);
}
const string_match = parase_value.match(/^["'](.*)["']$/);
if (string_match) return string_match[1];
if (parase_value === 'undefined') return undefined;
if (parase_value === 'null') return null;
return parase_value;
}
string_to_value(obj, path) {
try {
if (!this.limit_eval) {
return eval(path.replace('json_obj', 'obj'));
}
let tmp_obj = obj;
let matches = path.match(/\[(.*?)\]/g);
if (matches) {
matches.map((match) => {
if (match.includes('["')) {
tmp_obj = Reflect.get(tmp_obj, match.replace(/\["|"\]/g, ''));
} else {
tmp_obj = Reflect.get(tmp_obj, Number(match.replace(/\[|\]/g, '')));
}
});
return tmp_obj;
}
matches = path.split('.');
if (matches) {
matches.splice(0, 1);
matches.map((match) => {
tmp_obj = Reflect.get(tmp_obj, match);
});
return tmp_obj;
}
} catch (error) {
// log('获取属性值失败--->' + path, 'obj_process')
}
}
get_lastPath_and_key(path) {
let last_path, last_key;
let matches = path.match(/\[(.*?)\]/g);
if (matches && matches.length > 0) {
const tmp = matches[matches.length - 1];
if (tmp.includes('["')) {
last_key = tmp.replace(/\["|"\]/g, '');
} else {
last_key = Number(tmp.replace(/\[|\]/g, ''));
}
last_path = path.substring(0, path.lastIndexOf(tmp));
}
if (!matches) {
matches = path.split('.');
if (matches && matches.length > 0) {
last_key = matches[matches.length - 1];
last_path = path.replace('.' + last_key, '');
}
}
return [last_path, last_key];
}
obj_process(json_obj, express_list, traverse_all = false) {
let data_this = this;
let abs_path_info_list = [];
let relative_path_info_list = [];
let relative_path_list = [];
let relative_short_path_list = [];
if (!json_obj || !express_list) return;
const is_array_obj = Array.isArray(json_obj);
function add_data_to_abs_path(path, express, relative_path, operator, value, condition, array_index, path_extral, value_mode) {
let tmp;
path = path.replace(/\.[\d\w\-\_\$@]+/g, function (match) {
return '["' + match.slice(1) + '"]';
});
if (array_index !== "*") {
tmp = {};
path = path + (array_index ? '[' + array_index + ']' : '');
tmp.path = path;
tmp.relative_path = relative_path;
tmp.operator = operator;
tmp.value = value;
tmp.value_mode = value_mode;
tmp.condition = condition;
tmp.path_extral = path_extral;
tmp.express = express;
abs_path_info_list.push(tmp);
return;
}
let array_length;
try {
array_length = data_this.string_to_value(json_obj, path).length;
if (!array_length) return;
} catch (error) {
return;
}
for (let tmp_index = array_length - 1; tmp_index >= 0; tmp_index--) {
tmp = {};
tmp.path = path + "[" + tmp_index + "]";
tmp.operator = operator;
tmp.value = value;
tmp.value_mode = value_mode;
tmp.condition = condition;
tmp.path_extral = path_extral;
tmp.relative_path = relative_path;
tmp.express = express;
abs_path_info_list.push(tmp);
}
}
function obj_property_traverse(obj, cur_path, dec_infos, dec_list, dec_index_list, traverse_all = false) {
if (Array.isArray(obj)) {
obj.forEach((tmp_obj, index) => {
let tmp_path = cur_path + '[' + index + ']';
if (!tmp_obj || typeof (tmp_obj) !== 'object') return;
obj_property_traverse(tmp_obj, tmp_path, dec_infos, dec_list, dec_index_list, traverse_all);
});
return;
}
Object.keys(obj).forEach((key) => {
let tmp_path = cur_path + '.' + key;
let deal = false;
for (let i = 0; i < dec_infos["short_keys"].length; i++) {
if (dec_infos["short_keys"][i] === key) {
let len = dec_infos["real_keys"][i].length;
if (tmp_path.slice(tmp_path.length - len) === dec_infos["real_keys"][i]) {
dec_list.push(tmp_path);
dec_index_list.push(i);
if (!deal && traverse_all && typeof (obj[key]) === 'object') {
obj_property_traverse(obj[key], tmp_path, dec_infos, dec_list, dec_index_list, traverse_all);
}
deal = true;
}
}
}
let value = obj[key];
if (deal || !value || typeof (value) !== 'object') return;
obj_property_traverse(value, tmp_path, dec_infos, dec_list, dec_index_list, traverse_all);
});
}
function obj_modify(json_obj, path_info) {
let path = path_info['deal_path'];
let operator = path_info['operator'];
let value = path_info['value'];
let [last_path, last_key] = data_this.get_lastPath_and_key(path);
let last_obj = data_this.string_to_value(json_obj, last_path);
if (operator === '=-') {
let is_array = typeof last_key === 'number';
if (!last_obj) throw new Error('last_obj is null');
if (is_array)
last_obj.splice(last_key, 1);
else
delete last_obj[last_key];
log('依据:' + path_info.express, 'obj_process');
log('删除属性-->' + path, 'obj_process');
return;
}
let dec_obj = last_obj[last_key];
if (operator === '=+') {
value = data_this.value_parase(value);
if (dec_obj === null || dec_obj === undefined) throw new Error('dec_obj is null');
let type_ = typeof dec_obj;
if (Array.isArray(dec_obj)) type_ = 'array';
if (type_ === 'array') {
let mode_info = path_info.value_mode;
if (mode_info) {
try {
mode_info.mode === 'arr_insert' && last_obj[last_key].splice(Number(mode_info.params[0]), 0, value);
} catch (error) {
log(error, -1);
}
} else {
last_obj[last_key].push(value);
}
}
if (type_ === 'string' || type_ === 'number') last_obj[last_key] = last_obj[last_key] + value;
log('依据:' + path_info.express, 'obj_process');
log('修改属性-->' + path, 'obj_process');
}
if (operator === '~=') {
let search_value = value.split(SPLIT_TAG)[0];
let replace_value = value.split(SPLIT_TAG)[1];
last_obj[last_key] = dec_obj.replace(new RegExp(search_value, 'g'), replace_value);
log('依据:' + path_info.express, 'obj_process');
log('修改属性-->' + path, 'obj_process');
}
if (operator === '=') {
value = data_this.value_parase(value);
last_obj[last_key] = value;
log('依据:' + path_info.express, 'obj_process');
log('修改属性-->' + path, 'obj_process');
}
}
express_list.forEach(express => {
if (!express) return;
let reg;
let express_type = typeof (express);
let matchs;
let conditions;
let value;
reg = /^(abs:)?([a-zA-Z_0-9\.\*\[\]]*)((=\-|~=|=\+|=))(.*)?/;
if (express_type === 'string') {
matchs = express.match(reg);
} else {
matchs = express.value.match(reg);
conditions = express.conditions;
}
let abs = matchs[1];
let path = matchs[2];
let path_extral_match = path.match(/\/?\.+$/);
let path_extral;
if (path_extral_match) {
path_extral = {};
let len;
if (path_extral_match[0].startsWith('/')) {
len = path_extral_match[0].length - 1;
path_extral['child'] = len;
} else {
len = path_extral_match[0].length;
path_extral['parent'] = len;
}
path = path.slice(0, path.length - len);
}
let operator = matchs[3];
let value_mode;
if (express_type === 'string') {
let tmp_value = matchs[5] || '';
let split_index = tmp_value.indexOf(' ');
if (split_index > -1) {
value = tmp_value.substring(0, split_index);
let mode_match = value.match(/^\((.*)\)$/);
if (mode_match) {
let mode_info = mode_match[1].split(',');
value = mode_info[1];
let mode = mode_info[0];
mode_info.shift();
mode_info.shift();
value_mode = {
'mode': mode,
'params': mode_info
};
}
conditions = tmp_value.substring(split_index + 1);
conditions = {
'value': [conditions]
};
} else {
value = tmp_value;
}
}
matchs = path.match(/\[(\*?\d*)\]$/);
let array_index;
if (matchs) {
path = path.replace(/\[(\*?\d*)\]$/, '');
array_index = matchs[1];
}
if (abs) {
add_data_to_abs_path(`json_obj${is_array_obj ? '' : '.'}` + path, express, path, operator, value, conditions, array_index, path_extral, value_mode);
} else {
relative_path_list.push(path);
let tmp_short_path = path.split('.').pop();
relative_short_path_list.push(tmp_short_path);
relative_path_info_list.push({
"express": express,
"path": path,
"operator": operator,
"value": value,
"value_mode": value_mode,
"conditions": conditions,
"array_index": array_index,
"path_extral": path_extral
});
}
});
if (relative_path_list.length > 0) {
let dec_list = [];
let dec_index_list = [];
obj_property_traverse(json_obj, '', {
"short_keys": relative_short_path_list,
"real_keys": relative_path_list
}, dec_list, dec_index_list, traverse_all);
for (let i = 0; i < dec_index_list.length; i++) {
let real_index = dec_index_list[i];
let real_path_info = relative_path_info_list[real_index];
let tmp_path = 'json_obj' + dec_list[i];
add_data_to_abs_path(tmp_path, real_path_info.express, real_path_info.path, real_path_info.operator, real_path_info.value, real_path_info.conditions, real_path_info.array_index, real_path_info.path_extral, real_path_info.value_mode);
}
}
abs_path_info_list.sort((a, b) => a < b ? 1 : -1);
for (let path_info of abs_path_info_list) {
if (!this.obj_conditional(path_info, json_obj)) continue;
let operator = path_info.operator;
let path = path_info.path;
let value = path_info.value;
let path_extral = path_info.path_extral;
if (path_extral) {
let positions = [];
let regex = /\]/g;
let match;
while ((match = regex.exec(path)) !== null) {
positions.push(match.index);
}
if (positions.length === 0) continue;
if ('parent' in path_extral) {
if (positions.length - path_extral['parent'] - 1 < 0) continue;
let split_index = positions[positions.length - path_extral['parent'] - 1] + 1;
path = path.slice(0, split_index);
}
}
path_info.deal_path = path;
if (this.obj_filter && this.obj_filter(path_info, json_obj)) continue;
obj_modify(json_obj, path_info);
}
}
value_conditional(value, condition_express) {
let reg = /(\$text|\$value|\$exist|\$notexist)?((>=|<=|>|<|!~=|!=|~=|=))?(.*)/;
let match = condition_express.match(reg);
let condition_type = match[1] || '$text';
let condition_operator = match[2];
let condition_test_value = match[4];
if (condition_type === '$value') {
if (!['>=', '<=', '>', '<', '='].includes(condition_operator)) return false;
if (condition_operator === '=') return condition_test_value === value;
if (condition_operator === '>=') return value >= condition_test_value;
if (condition_operator === '<=') return value <= condition_test_value;
if (condition_operator === '>') return value > condition_test_value;
if (condition_operator === '<') return value < condition_test_value;
}
if (condition_type === '$exist') {
return value !== undefined && value !== null;
}
if (condition_type === '$notexist') {
return value === undefined || value === null;
}
if (condition_type === '$text') {
if (typeof (value) === 'object') value = JSON.stringify(value);
if (condition_operator === '!=') return condition_test_value !== value;
if (condition_operator === '=') return condition_test_value === value;
if (condition_operator === '~=') return new RegExp(condition_test_value).test(value);
if (condition_operator === '!~=') return !new RegExp(condition_test_value).test(value);
if (condition_operator === '>=') return value.length >= condition_test_value.length;
if (condition_operator === '>') return value.length > condition_test_value.length;
if (condition_operator === '<=') return value.length <= condition_test_value.length;
if (condition_operator === '>') return value.length > condition_test_value.length;
}
return false;
}
obj_conditional(express_info, json_obj) {
//json_obj 在eval里直接调用
if (!express_info['condition']) return true;
let condition_infos = express_info['condition'];
// 与
for (let condition_list of Object.values(condition_infos)) {
let result = false;
for (let condition of condition_list) {
let reg = /^([a-zA-Z_0-9\/\.@\[\]]*)?(.*)/;
let match = condition.match(reg);
let condition_path = match[1];
let mod;
if (condition_path) {
if (condition_path.startsWith('/')) {
mod = 'child';
} else if (condition_path.startsWith('.')) {
mod = 'parent';
} else if (condition_path.startsWith('@')) {
mod = 'global';
} else {
mod = 'other';
}
} else {
condition_path = express_info.path;
}
let conditional_express = match[2];
if (mod === 'child') {
condition_path = express_info.path + condition_path.slice(1).replace(/\.[\d\w\-\_\$@]+/g, function (match) {
return '["' + match.slice(1) + '"]';
});
}
if (mod === 'parent') {
let reg = /^\.+/;
let matchs = condition_path.match(reg);
let positions = [];
let regex = /\]/g;
while ((match = regex.exec(express_info.path)) !== null) {
positions.push(match.index);
}
if (positions.length > 0) {
let split_index = positions[positions.length - matchs[0].length - 1] + 1;
let short_condition_path = condition_path.replace(reg, '');
if (!/^\[/.test(short_condition_path)) {
short_condition_path = '.' + short_condition_path;
}
condition_path = express_info.path.slice(0, split_index) + short_condition_path.replace(/\.[\d\w\-\_\$@]+/g, function (match) {
return '["' + match.slice(1) + '"]';
});
}
}
if (mod === 'other') {
condition_path = (`json_obj${is_array_obj ? '' : '.'}` + condition_path).replace(/\.[\d\w\-\_\$@]+/g, function (match) {
return '["' + match.slice(1) + '"]';
});
}
if (mod === 'global') {
condition_path = condition_path.replace('@', limit_eval ? 'unsafeWindow.' : '');
}
let condition_value;
try {
condition_value = this.string_to_value(mod === 'global' ? unsafeWindow : json_obj, condition_path);
} catch (error) {
continue;
}
result = this.value_conditional(condition_value, conditional_express);
if (result) {
express_info.condition_value = condition_value;
log('条件成立-->', condition_value, 'obj_process');
break;
}
}
if (!result) return false;
}
return true;
}
}
url_observer();
init();
function init() {
log('初始化开始!', 0);
is_account_init = false;
shorts_fun = get_shorts_fun();
yt_api = get_yt_api();
page_type = get_page_type();
if (page_type === 'yt_shorts') shorts_fun.check_shorts_exist();
data_process = new DATA_PROCESS();
data_process.set_obj_filter(obj_process_filter);
try {
eval('1===1');
limit_eval = false;
} catch (error) {
limit_eval = true;
}
config_init(user_data.language);
let ytInitialPlayerResponse_value = unsafeWindow['ytInitialPlayerResponse'];
define_property_hook(unsafeWindow, 'ytInitialPlayerResponse', {
get: function () {
return ytInitialPlayerResponse_value;
},
set: function (value) {
inject_info.ytInitialPlayerResponse = true;
if (value && open_debugger) debugger_ytInitialPlayerResponse = (typeof (value) === 'string') ? JSON.parse(value) : JSON.parse(JSON.stringify(value));
let start_time = Date.now();
value && data_process.obj_process(value, ytInitialPlayerResponse_rule, true);
log('ytInitialPlayerResponse 时间:', Date.now() - start_time, 'spend_time');
ytInitialPlayerResponse_value = value;
},
configurable: false
});
let ytInitialReelWatchSequenceResponse_value = unsafeWindow['ytInitialReelWatchSequenceResponse'];
define_property_hook(unsafeWindow, 'ytInitialReelWatchSequenceResponse', {
get: function () {
return ytInitialReelWatchSequenceResponse_value;
},
set: function (value) {
inject_info.ytInitialReelWatchSequenceResponse = true;
if (/yt_shorts$/.test(page_type)) {
if (value && open_debugger) debugger_ytInitialReelWatchSequenceResponse = (typeof (value) === 'string') ? JSON.parse(value) : JSON.parse(JSON.stringify(value));
let start_time = Date.now();
value && data_process.obj_process(value, ytInitialReelWatchSequenceResponse_rule, true);
log('ytInitialReelWatchSequenceResponse 时间:', Date.now() - start_time, 'spend_time');
}
ytInitialReelWatchSequenceResponse_value = value;
},
configurable: false
});
let ytInitialData_value = unsafeWindow['ytInitialData'];
define_property_hook(unsafeWindow, 'ytInitialData', {
get: function () {
return ytInitialData_value;
},
set: function (value) {
inject_info.ytInitialData = true;
if (typeof (value) === 'string') {
ytInitialData_value = value;
return;
}
if (open_debugger && value !== undefined && value !== null) debugger_ytInitialData = JSON.parse(JSON.stringify(value));
if (ytInitialData_rule) {
let start_time = Date.now();
value && data_process.obj_process(value, ytInitialData_rule, true);
log('ytInitialData 时间:', Date.now() - start_time, 'spend_time');
}
ytInitialData_value = value;
},
configurable: false
});
define_property_hook(navigator, 'userAgent', {
get: function () {
return 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36';
}
});
let origin_createElement = document.createElement;
document.createElement = function () {
let node = origin_createElement.apply(this, arguments);
if (arguments[0] === 'template') {
let innerhtml_getter = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML").get;
let innerhtml_setter = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML").set;
define_property_hook(node, 'innerHTML', {
get: function () {
return innerhtml_getter.call(node);
},
set: function (value) {
// if (value.toString().includes('ytd-continuation-item-renderer')){
// if (href.includes('https://www.youtube.com/watch')){
// value = ''
// log(value);
// log('弹窗去掉------->ytd-continuation-item-renderer');
// }
if (value.toString().includes('yt-mealbar-promo-renderer')) {
log('弹窗去掉------->yt-mealbar-promo-renderer', 'node_process');
value = '';
}
innerhtml_setter.call(node, value);
}
});
}
return node;
};
document.createElement.toString = origin_createElement.toString.bind(origin_createElement);
async function deal_resposn(name, response, rule) {
if (!rule) return response;
let is_deal = false;
const responseClone = response.clone();
let result = await responseClone.text();
let orgin_result = result;
if (name === 'subscribe' || name === 'unsubscribe') {
let match_list = result.match(/channelId":\"(.*?)"/);
const match_channel_id = match_list && match_list.length > 1 ? match_list[1] : '';
let channel_infos = user_data.channel_infos;
if (match_channel_id) {
if (name === 'unsubscribe') {
let index = channel_infos.ids.indexOf(match_channel_id);
if (index > -1) {
channel_infos.ids.splice(index, 1);
channel_infos.names.splice(index, 1);
}
} else {
channel_infos.ids.push(match_channel_id);
channel_infos.names.push('');
}
user_data.channel_infos = channel_infos;
store_user_data();
}
is_deal = true;
}
if (!is_deal) {
let start_time = Date.now();
result = data_process.text_process(result, rule, 'insert', true);
log(name + ' 时间:', Date.now() - start_time, 'spend_time');
}
if (!result) {
result = orgin_result;
debugger;
}
return new Response(result, response);
}
const origin_fetch = unsafeWindow.fetch;
if (origin_fetch.toString() !== 'function fetch() { [native code] }') {
log('fetch have been modified', -1);
}
unsafeWindow.fetch = function () {
const fetch_ = async function (uri, options) {
async function fetch_request(response) {
let url = response.url;
inject_info.fetch = true;
return_response = response;
if (url.includes('youtubei/v1/next')) {
return await deal_resposn('next', response, ytInitialData_rule);
}
if (url.includes('youtubei/v1/player')) {
return await deal_resposn('player', response, ytInitialPlayerResponse_rule);
}
if (url.includes('youtubei/v1/reel/reel_watch_sequence')) {
return await deal_resposn('reel_watch_sequence', response, ytInitialReelWatchSequenceResponse_rule);
}
if (url.includes('youtubei/v1/browse')) {
let rule = ytInitialData_rule;
if (['yt_home', 'mobile_yt_home'].includes(page_type) && ['off', 'subscribed'].includes(user_data.open_recommend_liveroom)) {
let node, category_text;
if (mobile_web) {
node = document.querySelector('#filter-chip-bar > div > ytm-chip-cloud-chip-renderer.selected');
category_text = node && node.textContent;
} else {
node = document.querySelector('#chips > yt-chip-cloud-chip-renderer.style-scope.ytd-feed-filter-chip-bar-renderer.iron-selected');
category_text = node && node.querySelector('#text').textContent;
}
const filter_list = [flag_info.category_game, flag_info.category_live, flag_info.category_news];
if (filter_list.includes(category_text)) {
let body;
if (uri.body_) {
try {
body = JSON.parse(uri.body_);
} catch (error) {
}
}
if (!body || body.browseId !== 'FEwhat_to_watch') {
rule = ytInitialData_rule.filter(item => !item.includes(flag_info.live));
}
}
}
return await deal_resposn('browse', response, rule);
}
if (url.includes('https://m.youtube.com/youtubei/v1/guide')) {
return await deal_resposn('guide', response, ytInitialData_rule);
}
if (url.includes('/youtubei/v1/search')) {
return await deal_resposn('search', response, ytInitialData_rule);
}
if (url.includes('/unsubscribe?prettyPrint=false')) {
return await deal_resposn('unsubscribe', response);
}
if (url.includes('/subscribe?prettyPrint=false')) {
return await deal_resposn('subscribe', response);
}
return return_response;
}
return origin_fetch(uri, options).then(fetch_request);
};
const names = Object.getOwnPropertyNames(origin_fetch);
for (let i = 0; i < names.length; i++) {
if (names[i] in fetch_)
continue;
let desc = Object.getOwnPropertyDescriptor(origin_fetch, names[i]);
define_property_hook(fetch_, names[i], desc);
}
return fetch_;
}();
const origin_Request = unsafeWindow.Request;
if (origin_Request.toString() !== 'function Request() { [native code] }') {
log('Request have been modified', -1);
}
unsafeWindow.Request = class extends unsafeWindow.Request {
constructor(input, options = void 0) {
super(input, options);
if (options && 'body' in options) this['body_'] = options['body'];
}
};
unsafeWindow.XMLHttpRequest = class extends unsafeWindow.XMLHttpRequest {
open(method, url, ...opts) {
inject_info.xhr = true;
return super.open(method, url, ...opts);
}
get xhrResponseValue() {
const xhr = this;
let result = super.response;
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.responseURL.includes('youtubei/v1/player')) {
// music_watch
result = data_process.text_process(result, ytInitialPlayerResponse_rule, 'insert', true);
}
if (xhr.responseURL.includes('youtube.com/playlist')) {
let obj;
try {
obj = JSON.parse(result);
} catch (error) {
log('JSON解析失败', 1);
return result;
}
data_process.obj_process(obj[2].playerResponse, ytInitialPlayerResponse_rule, true);
data_process.obj_process(obj[3].response, ytInitialData_rule, true);
tmp_debugger_value = obj;
result = JSON.stringify(obj);
}
} else {
result = '';
}
return result;
}
get responseText() {
return this.xhrResponseValue;
}
get response() {
return this.xhrResponseValue;
}
};
document.addEventListener('DOMContentLoaded', function () {
!mobile_web && search_listener();
checke_update();
});
if (unsafeWindow.ytcfg) {
if (unsafeWindow.ytcfg.data_ && typeof (unsafeWindow.ytcfg.data_.LOGGED_IN) === 'boolean') {
unsafeWindow.ytcfg.data_.LOGGED_IN === true && account_data_init();
} else {
if (unsafeWindow.ytcfg.data_ && typeof unsafeWindow.ytcfg.data_ === 'object') {
define_property_hook(unsafeWindow.ytcfg.data_, 'LOGGED_IN', {
get: function () {
return unsafeWindow.ytcfg.data_.LOGGED_IN_;
},
set: function (value) {
unsafeWindow.ytcfg.data_.LOGGED_IN_ = value;
value === true && account_data_init();
}
});
}
}
if (!unsafeWindow.ytcfg.data_) {
if (unsafeWindow.yt && unsafeWindow.yt.config_) {
const config_ = unsafeWindow.yt.config_;
if (typeof (config_.LOGGED_IN) === 'boolean') {
config_.LOGGED_IN === true && account_data_init();
}
config_.HL && config_init(config_.HL);
}
}
if (unsafeWindow.ytcfg.data_ && unsafeWindow.ytcfg.data_.HL) config_init(unsafeWindow.ytcfg.data_.HL);
!(unsafeWindow.ytcfg.data_ && unsafeWindow.ytcfg.data_.HL) && define_property_hook(unsafeWindow.ytcfg, 'msgs', {
get: function () {
return this._msgs;
},
set: function (newValue) {
if (newValue.__lang__) config_init(newValue.__lang__);
this._msgs = newValue;
}
});
} else {
define_property_hook(unsafeWindow, 'ytcfg', {
get: function () {
return this._ytcfg;
},
set: function (newValue) {
if (newValue.set) {
const orgin_set = newValue.set;
newValue.set = function () {
orgin_set.apply(this, arguments);
if (arguments[0] && typeof arguments[0].LOGGED_IN === 'boolean') {
arguments[0].LOGGED_IN === true && account_data_init();
}
if (arguments[0].HL) {
config_init(arguments[0].HL);
}
};
}
this._ytcfg = newValue;
}
});
}
isinint = true;
log('初始化结束!', 0);
}
async function account_data_init() {
if (is_account_init) return;
yt_api.get_channel_id();
yt_api.get_subscribe_data();
is_account_init = true;
}
function native_method_hook(method_path, handler) {
let [last_path, last_key] = data_process.get_lastPath_and_key(method_path);
let last_obj = data_process.string_to_value(unsafeWindow, 'unsafeWindow.' + last_path);
let dec_obj = last_obj[last_key];
last_obj[last_key + '__'] = dec_obj;
if (typeof dec_obj !== 'function') {
log(method_path, 'have been modified', -1);
return;
}
const method_name = dec_obj.name;
if (dec_obj.toString() !== 'function ' + method_name + '() { [native code] }') {
log(method_path, 'have been modified!', -1);
}
last_obj[last_key] = handler;
}
function define_property_hook(obj, property, descriptor) {
try {
Object.defineProperty(obj, property, descriptor);
} catch (error) {
log("hook " + property + " failed!", -1);
return;
}
if (descriptor.get) {
const get_ = Object.getOwnPropertyDescriptor(obj, property).get;
if (descriptor.get !== get_) {
log("hook " + property + " failed!", -1);
return;
}
}
if (descriptor.set) {
const set_ = Object.getOwnPropertyDescriptor(obj, property).set;
if (descriptor.set !== set_)
log("hook " + property + " failed!", -1);
}
}
function config_init(tmp_language = null) {
if (isinint) {
setTimeout(search_listener, 500);
}
if (!tmp_language) {
tmp_language = unsafeWindow['ytcfg'].msgs ? unsafeWindow['ytcfg'].msgs.__lang__ : (unsafeWindow['ytcfg'].data ? unsafeWindow['ytcfg'].data.HL : undefined);
!tmp_language && (tmp_language = unsafeWindow['yt'] && unsafeWindow['yt'].config_ && unsafeWindow['yt'].config_.HL);
if (!tmp_language) {
log('语言获取错误', unsafeWindow, -1);
tmp_language = 'zh-CN';
}
}
if (!['zh-CN', 'zh-TW', 'zh-HK', 'en'].includes(tmp_language)) {
log(`Does not support language ${tmp_language}, only supports zh-CN, zh-TW, zh-HK, en, and is compatible with English locations; there may be some errors.`, -1);
tmp_language = tmp_language.startsWith('en-') ? 'en' : 'zh-CN';
}
let flag_infos = {
"zh-CN": {
"sponsored": "赞助商广告",
"free_movie": "免费(含广告)",
"live": "直播",
"movie_channel": "影视",
"free_primetime_movie": "免费 Primetime 电影",
"Playables": "游戏大本营",
"think_video": "你对这个视频有何看法?|此推荐内容怎么样?",
"try": "试用",
"recommend_popular": "时下流行",
"featured": "Featured",
"category_live": "直播",
"category_game": "游戏",
"category_news": "新闻",
"btn_recommend_movie": "电影推荐",
"btn_recommend_shorts": "Shorts推荐",
"btn_recommend_liveroom": "直播推荐",
"btn_recommend_popular": "时下流行",
"btn_recommend_game": "游戏大本营推荐",
"btn_save": "保存",
"goodselect": "精选",
"music_ad_flag": "无广告打扰",
"upcoming": "即将开始",
"init": "初始化",
"ctoc": "已复制到剪贴板",
"runing_normally": "运行正常",
"err_msg": "错误信息",
"success": "成功",
"failed": "失败",
"tips": "你可以发送错误信息或者截图发给脚本开发者",
"exists_error": "存在错误信息(建议多次刷新观察是否是同样的错误信息)",
"inject": "注入",
"btn_lable_open": "开启",
"btn_lable_close": "关闭",
"btn_lable_subscribed": "仅订阅",
"recommend_subscribed_lable_tips": "只显示已订阅的推荐",
},
"zh-TW": {
"sponsored": "贊助商廣告",
"free_movie": "免費 \\(含廣告\\)",
"live": "直播",
"movie_channel": "電影與電視節目",
"Playables": "遊戲角落",
"free_primetime_movie": "免費的特選電影",
"think_video": "你對這部影片有什麼看法?|此推荐内容怎么样?",
"try": "試用",
"recommend_popular": "發燒影片",
"featured": "Featured",
"category_live": "直播中",
"category_game": "遊戲",
"category_news": "新聞",
"btn_recommend_movie": "电影推薦",
"btn_recommend_shorts": "Shorts推薦",
"btn_recommend_liveroom": "直播推薦",
"btn_recommend_popular": "發燒影片",
"btn_recommend_game": "遊戲角落推薦",
"btn_save": "保存",
"goodselect": "精選內容",
"music_ad_flag": "零廣告",
"upcoming": "即将直播",
"init": "初始化",
"ctoc": "已複製到剪貼板",
"runing_normally": "運行正常",
"err_msg": "錯誤訊息",
"success": "成功",
"failed": "失敗",
"tips": "你可以发送錯誤訊息或截圖給腳本開發者",
"exists_error": "存在錯誤訊息(建議多次刷新觀察是否是同樣的錯誤訊息)",
"inject": "注入",
"btn_lable_open": "開啓",
"btn_lable_close": "關閉",
"btn_lable_subscribed": "僅訂閱",
"recommend_subscribed_lable_tips": "只顯示已訂閱的推薦",
},
"zh-HK": {
"sponsored": "赞助",
"free_movie": "免費 \\(有廣告\\)",
"live": "直播",
"movie_channel": "電影與電視節目",
"Playables": "Playables",
"free_primetime_movie": "免費黃金時段電影",
"think_video": "你對此影片有何意見?|此推荐内容怎么样?",
"try": "試用",
"recommend_popular": "熱爆影片",
"featured": "Featured",
"category_live": "直播",
"category_game": "遊戲",
"category_news": "新聞",
"btn_recommend_movie": "电影推薦",
"btn_recommend_shorts": "Shorts推薦",
"btn_recommend_liveroom": "直播推薦",
"btn_recommend_popular": "熱爆影片",
"btn_recommend_game": "Playables推荐",
"btn_save": "保存",
"goodselect": "精選內容",
"music_ad_flag": "零廣告音樂",
"upcoming": "即將發佈",
"init": "初始化",
"ctoc": "已複製到剪貼板",
"runing_normally": "運行正常",
"err_msg": "錯誤訊息",
"success": "成功",
"failed": "失敗",
"tips": "你可以发送錯誤訊息或截圖給腳本開發者",
"exists_error": "存在錯誤訊息(建議多次刷新觀察是否是同樣的錯誤訊息)",
"inject": "注入",
"btn_lable_open": "開啓",
"btn_lable_close": "關閉",
"btn_lable_subscribed": "僅訂閱",
"recommend_subscribed_lable_tips": "只顯示已訂閱的推薦",
},
"en": {
"sponsored": "Sponsored",
"free_movie": "Free with ads",
"live": "LIVE",
"movie_channel": "Movies & TV",
"Playables": "Playables",
"free_primetime_movie": "Free Primetime movies",
"think_video": "What did you think of this video?|此推荐内容怎么样?",
"try": "Try",
"recommend_popular": "Trending",
"featured": "Featured",
"category_live": "Live",
"category_game": "Gaming",
"category_news": "News",
"btn_recommend_movie": "MovieRecommend",
"btn_recommend_shorts": "ShortsRecommend",
"btn_recommend_liveroom": "LiveRecommend",
"btn_recommend_popular": "TrendingRecommend",
"btn_recommend_game": "PlayablesRecommend",
"btn_save": "Save",
"goodselect": "Featured",
"music_ad_flag": "ad-free",
"upcoming": "UPCOMING",
"init": "init",
"ctoc": "Copied to clipboard",
"runing_normally": "running normally",
"err_msg": "error message",
"success": "success",
"failed": "failed",
"tips": "You can send error message or screenshot to the developer",
"exists_error": "Error message exists (It is recommended to refresh multiple times to see if it is the same error message)",
"inject": "inject",
"btn_lable_open": "on",
"btn_lable_close": "off",
"btn_lable_subscribed": "onlySubscribed",
"recommend_subscribed_lable_tips": "only show subscribed recommend",
}
};
if (tmp_language !== user_data.language) {
user_data.language = tmp_language;
user_data_api.set();
}
flag_info = flag_infos[user_data.language];
movie_channel_info = {
"guideEntryRenderer": {
"navigationEndpoint": {
"clickTrackingParams": "CBQQnOQDGAIiEwj5l8SLqPiCAxUXSEwIHbf1Dw0=",
"commandMetadata": {
"webCommandMetadata": {
"url": "/feed/storefront",
"webPageType": "WEB_PAGE_TYPE_BROWSE",
"rootVe": 6827,
"apiUrl": "/youtubei/v1/browse"
}
},
"browseEndpoint": {
"browseId": "FEstorefront"
}
},
"icon": {
"iconType": "CLAPPERBOARD"
},
"trackingParams": "CBQQnOQDGAIiEwj5l8SLqPiCAxUXSEwIHbf1Dw0=",
"formattedTitle": {
"simpleText": flag_info.movie_channel
},
"accessibility": {
"accessibilityData": {
"label": flag_info.movie_channel
}
}
}
};
unsafeWindow.movie_channel_info = movie_channel_info;
mobile_movie_channel_info = {
"navigationItemViewModel": {
"text": {
"content": flag_info.movie_channel
},
"icon": {
"sources": [
{
"clientResource": {
"imageName": "CLAPPERBOARD"
}
}
]
},
"onTap": {
"parallelCommand": {
"commands": [
{
"innertubeCommand": {
"clickTrackingParams": "CBQQnOQDGAIiEwj5l8SLqPiCAxUXSEwIHbf1Dw0=",
"hideMoreDrawerCommand": {}
}
},
{
"innertubeCommand": {
"clickTrackingParams": "CBQQnOQDGAIiEwj5l8SLqPiCAxUXSEwIHbf1Dw0=",
"commandMetadata": {
"webCommandMetadata": {
"url": "/feed/storefront",
"webPageType": "WEB_PAGE_TYPE_CHANNEL",
"rootVe": 3611,
"apiUrl": "/youtubei/v1/browse"
}
},
"browseEndpoint": {
"browseId": "FEstorefront"
}
}
}
]
}
},
"loggingDirectives": {
"trackingParams": "CBQQnOQDGAIiEwj5l8SLqPiCAxUXSEwIHbf1Dw0=",
"visibility": {
"types": "12"
},
"enableDisplayloggerExperiment": true
}
}
};
unsafeWindow.mobile_movie_channel_info = mobile_movie_channel_info;
ytInitialData_rule = null;
ytInitialReelWatchSequenceResponse_rule = null;
ytInitialPlayerResponse_rule = null;
mobile_web = page_type.includes('mobile');
const common_ytInitialData_rule = [
'tvfilmOfferModuleRenderer=- /.masthead$exist',
'merchandiseShelfRenderer=-',
'adSlotRenderer.=-',
];
const common_ytInitialPlayerResponse_rule = [
"abs:playerAds=-",
"abs:adPlacements=-",
"abs:adBreakHeartbeatParams=-",
"abs:adSlots=-",
];
if (page_type === 'yt_search') {
ytInitialData_rule = common_ytInitialData_rule;
ytInitialPlayerResponse_rule = common_ytInitialPlayerResponse_rule;
return;
}
if (page_type === 'mobile_yt_search') {
ytInitialData_rule = common_ytInitialData_rule;
return;
}
if (page_type === 'yt_kids_watch') {
ytInitialData_rule = common_ytInitialData_rule;
return;
}
if (page_type === 'yt_music_watch') {
ytInitialPlayerResponse_rule = common_ytInitialPlayerResponse_rule;
return;
}
if (page_type.includes('yt_shorts')) {
ytInitialReelWatchSequenceResponse_rule = ['abs:entries[*]=- /.command.reelWatchEndpoint.adClientParams$exist'];
return;
}
if (page_type.includes('yt_watch')) {
let watch_page_ytInitialData_rule = common_ytInitialData_rule;
let lower_left_corner_tags;
let lower_left_corner_rule = mobile_web ? 'metadataBadgeRenderer.label.....=- ~=' : 'metadataBadgeRenderer.label.....=- ~=';
lower_left_corner_tags = [];
//赞助商广告
lower_left_corner_tags.push(flag_info.sponsored);
//免费电影
user_data.open_recommend_movie === 'off' && lower_left_corner_tags.push(flag_info.free_movie);
lower_left_corner_rule += lower_left_corner_tags.join('|');
watch_page_ytInitialData_rule.push(lower_left_corner_rule);
let live_rules;
//直播规则
if (['off', 'subscribed'].includes(user_data.open_recommend_liveroom)) {
live_rules = ['text.accessibility.accessibilityData.label........=- =' + flag_info.live];
!mobile_web && live_rules.push('metadataBadgeRenderer.label.....=- =' + flag_info.live);
}
live_rules && watch_page_ytInitialData_rule.push(...live_rules);
// 大标题栏目 短视频等
let recommend_rules = [];
let recommend_tags = [];
let recommend_base_rule = 'reelShelfRenderer.title.runs[0].text.....=- ~=';
['off', 'subscribed'].includes(user_data.open_recommend_shorts) && recommend_tags.push('Shorts');
if (recommend_tags.length > 0 && !mobile_web) {
recommend_rules.push(recommend_base_rule + recommend_tags.join('|'));
}
recommend_rules.length && watch_page_ytInitialData_rule.push(...recommend_rules);
// 添加已订阅短视频
let subscribed_shorts_rule;
if (user_data.open_recommend_shorts === 'subscribed') {
subscribed_shorts_rule = 'secondaryResults.results[1].itemSectionRenderer.contents=+(arr_insert,method(shorts_fun.get_shorts_section()),0) @user_data.shorts_list.length$value>0';
}
subscribed_shorts_rule && watch_page_ytInitialData_rule.push(subscribed_shorts_rule);
ytInitialData_rule = watch_page_ytInitialData_rule;
ytInitialPlayerResponse_rule = common_ytInitialPlayerResponse_rule;
return;
}
if (page_type.includes('yt_home')) {
let home_page_ytInitialData_ad_rule = [
'richItemRenderer.content.adSlotRenderer..=-'
];
// 每一个item左下角标签
let left_corner_tags;
let lower_left_corner_rule = mobile_web ? 'metadataBadgeRenderer.label.....=- ~=' : 'metadataBadgeRenderer.label......=- ~=';
left_corner_tags = [];
//赞助商广告
left_corner_tags.push(flag_info.sponsored);
//免费电影
user_data.open_recommend_movie === 'off' && left_corner_tags.push(flag_info.free_movie);
lower_left_corner_rule += left_corner_tags.join('|');
home_page_ytInitialData_ad_rule.push(lower_left_corner_rule);
//头部第一个广告
let head_ad = 'richGridRenderer.masthead=-';
home_page_ytInitialData_ad_rule.push(head_ad);
//大标题栏目 短视频 电影等
let recommend_rules = [];
let recommend_tags = [];
let recommend_base_rule = mobile_web ? 'reelShelfRenderer.title.runs[0].text.......=- ~=' : 'richShelfRenderer.title.runs[0].text......=- ~=';
['off', 'subscribed'].includes(user_data.open_recommend_shorts) && recommend_tags.push('Shorts');
user_data.open_recommend_movie === 'off' && recommend_tags.push(flag_info.free_primetime_movie);
user_data.open_recommend_popular === 'off' && recommend_tags.push(flag_info.recommend_popular);
user_data.open_recommend_playables === 'off' && recommend_tags.push(flag_info.Playables);
if (recommend_tags.length > 0) {
recommend_rules.push(recommend_base_rule + recommend_tags.join('|'));
}
recommend_rules.length && home_page_ytInitialData_ad_rule.push(...recommend_rules);
//直播规则
let live_rules;
if (['off', 'subscribed'].includes(user_data.open_recommend_liveroom)) {
live_rules = ['text.accessibility.accessibilityData.label........=- =' + flag_info.live];
if (!mobile_web) {
live_rules.push('metadataBadgeRenderer.label......=- =' + flag_info.live);
live_rules.push('thumbnailOverlayTimeStatusRenderer.text.simpleText.......=- =' + flag_info.upcoming);
} else {
live_rules.push('thumbnailOverlayTimeStatusRenderer.text.runs[0].text.........=- =' + flag_info.upcoming);
}
}
live_rules && home_page_ytInitialData_ad_rule.push(...live_rules);
//添加电影频道
let add_movie_channel_rule = "loadingStrategy.inlineContent.moreDrawerViewModel.content=+obj(" + (mobile_web ? "mobile_" : "") + "movie_channel_info) !~=" + flag_info.movie_channel;
home_page_ytInitialData_ad_rule.push(add_movie_channel_rule);
// 音乐会员
let music_premium_ad_rule;
!mobile_web && (music_premium_ad_rule = 'richSectionRenderer.content.statementBannerRenderer.title.runs[0].text.......=- ~=Music Premium|' + flag_info.music_ad_flag);
music_premium_ad_rule && home_page_ytInitialData_ad_rule.push(music_premium_ad_rule);
//电视好物
let tv_goodselect_rule;
open_recommend_tv_goodselect === 'off' && (tv_goodselect_rule = 'metadataBadgeRenderer.label.......=- ~=' + flag_info.goodselect);
tv_goodselect_rule && home_page_ytInitialData_ad_rule.push(tv_goodselect_rule);
//弹窗
let popup_window_rules = ['title.runs[0].text......=- ~=YouTube Premium|' + flag_info.think_video,
'videoOwnerRenderer=- /.purchaseButton.buttonRenderer.text.simpleText~=' + flag_info.try];
home_page_ytInitialData_ad_rule.push(...popup_window_rules);
// 特色推荐
let featured_rules;
if (open_recommend_featured === 'off') {
featured_rules = [];
featured_rules.push('brandVideoSingletonRenderer.badgeText.runs[0].text.......=- ~=' + flag_info.featured);
featured_rules.push('brandVideoShelfRenderer.badgeText.runs[0].text.......=- ~=' + flag_info.featured);
featured_rules.push('bigYoodle.statementBannerRenderer.badgeText.runs[0].text.....=- =' + flag_info.featured);
}
featured_rules && home_page_ytInitialData_ad_rule.push(...featured_rules);
// 添加已订阅短视频
let subscribed_shorts_rule;
if (user_data.open_recommend_shorts === 'subscribed') {
subscribed_shorts_rule = 'tabs[0].tabRenderer.content.richGridRenderer.contents=+(arr_insert,method(shorts_fun.get_shorts_section()),0) @user_data.shorts_list.length$value>0';
}
subscribed_shorts_rule && home_page_ytInitialData_ad_rule.push(subscribed_shorts_rule);
ytInitialData_rule = home_page_ytInitialData_ad_rule;
ytInitialPlayerResponse_rule = common_ytInitialPlayerResponse_rule;
return;
}
}
function search_listener() {
const search_selector = href.includes('https://m.youtube.com/') ? 'input.searchbox-input.title' : 'input[id="search"]';
const search_input_node = document.querySelector(search_selector);
if (search_input_node) {
search_input_node.oninput = function (event) {
if (open_config_keyword === this.value || this.value === display_error_keyword) {
setTimeout(function () {
if (search_input_node.value === open_config_keyword) {
search_input_node.value = '';
display_config_win();
}
if (search_input_node.value === display_error_keyword) {
search_input_node.value = '';
let tips = `script ${flag_info.init} ${isinint ? flag_info.success : flag_info.failed}`;
if (error_messages.length === 0 && isinint) tips += ' ' + flag_info.runing_normally;
for (let key of Object.keys(inject_info)) {
if (!mobile_web && key === 'ytInitialPlayerResponse') continue;
if (key === 'ytInitialReelWatchSequenceResponse' && !/yt_shorts$/.test(page_type)) continue;
tips += `\n${key} ${flag_info.inject} ${inject_info[key] ? flag_info.success : flag_info.failed}`;
}
if (error_messages.length !== 0) {
tips += `\n\n${flag_info.exists_error}\n-----------${flag_info.err_msg}(${flag_info.ctoc})-----------------\n${error_messages.join('\n')}\n\n${flag_info.tips}`;
}
alert(tips);
if (error_messages.length > 0) {
copyToClipboard(error_messages.join('\n'));
}
}
}, 500);
}
};
}
}
function getCookie(cookieName) {
var name = cookieName + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var cookieArray = decodedCookie.split(';');
for (var i = 0; i < cookieArray.length; i++) {
var cookie = cookieArray[i].trim();
if (cookie.startsWith(name)) {
return cookie.substring(name.length, cookie.length);
}
}
return null;
}
function copyToClipboard(text) {
if (navigator.clipboard && navigator.clipboard.writeText) return navigator.clipboard.writeText(text);
var textarea = document.createElement("textarea");
textarea.value = text;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
}
function url_observer() {
if (unsafeWindow.navigation) {
unsafeWindow.navigation.addEventListener('navigate', (event) => {
url_change(event);
});
return;
}
const _historyWrap = function (type) {
const orig = unsafeWindow.history[type];
const e = new Event(type);
return function () {
const rv = orig.apply(this, arguments);
e.arguments = arguments;
unsafeWindow.dispatchEvent(e);
return rv;
};
};
unsafeWindow.history.pushState = _historyWrap('pushState');
unsafeWindow.history.replaceState = _historyWrap('replaceState');
unsafeWindow.addEventListener('replaceState', function (event) {
url_change(event);
});
unsafeWindow.addEventListener('pushState', function (event) {
url_change(event);
});
unsafeWindow.addEventListener('popstate', function (event) {
url_change(event);
});
unsafeWindow.addEventListener('hashchange', function (event) {
url_change(event);
});
}
function url_change(event = null) {
if (event && event.destination.url.startsWith('about:blank')) return;
href = event ? event.destination.url : location.href;
log('网页url改变 href -> ' + href, 0);
let tmp_page_type = get_page_type();
if (tmp_page_type === 'yt_shorts') {
shorts_fun.check_shorts_exist();
}
if (tmp_page_type !== page_type) {
page_type = tmp_page_type;
config_init();
}
}
function get_page_type() {
let base_url = href.split('?')[0];
let tmp_page_type;
if (base_url.match('https://www.youtube.com/?$')) tmp_page_type = 'yt_home';
else if (base_url.match('https://m.youtube.com/?$')) tmp_page_type = 'mobile_yt_home';
else if (base_url.match('https://www.youtube.com/watch$')) tmp_page_type = 'yt_watch';
else if (base_url.match('https://m.youtube.com/watch$')) tmp_page_type = 'mobile_yt_watch';
else if (base_url.match('https://www.youtube.com/results$')) tmp_page_type = 'yt_search';
else if (base_url.match('https://m.youtube.com/results$')) tmp_page_type = 'mobile_yt_search';
else if (base_url.startsWith('https://www.youtube.com/shorts')) tmp_page_type = 'yt_shorts';
else if (base_url.startsWith('https://m.youtube.com/shorts')) tmp_page_type = 'mobile_yt_shorts';
else if (base_url.match('https://www.youtubekids.com/watch$')) tmp_page_type = 'yt_kids_watch';
else if (base_url.match('https://music.youtube.com/?$')) tmp_page_type = 'yt_music_home';
else if (base_url.match('https://music.youtube.com/watch$')) tmp_page_type = 'yt_music_watch';
else tmp_page_type = 'other';
return tmp_page_type;
}
let debugger_config_info = {
'ytInitialPlayerResponse': debugger_ytInitialPlayerResponse,
'ytInitialData': debugger_ytInitialData,
'ytInitialReelWatchSequenceResponse': debugger_ytInitialReelWatchSequenceResponse,
'inject_info': inject_info,
'info': [
'ytInitialData_rule',
'ytInitialPlayerResponse_rule',
'is_account_init',
'user_data',
'mobile_web',
'page_type',
'tmp_debugger_value',
],
};
unsafeWindow.debugger_ = function (action = null) {
let keys = Object.keys(debugger_config_info);
if (!action && action !== 0) { debugger; return; }
if (action === 'ytInitialPlayerResponse') log('ytInitialPlayerResponse', debugger_ytInitialPlayerResponse, 0);
if (action === 'ytInitialData') log('ytInitialData', debugger_ytInitialData, 0);
if (action === 'inject_info') log('inject_info', inject_info, 0);
if (action === 'info') {
if (limit_eval) {
log('eval限制使用了', 0);
} else {
for (let key of debugger_config_info['info']) {
log(key, eval(key), 0);
}
}
return;
}
if (action === 'list') {
keys.forEach(function (key, index) {
log(index, key, 0);
});
}
if (typeof (action) === 'number') {
if (action < keys.length) {
unsafeWindow.debugger_(keys[action]);
} else if (action >= keys.length) {
keys.forEach(function (key) {
unsafeWindow.debugger_(key);
});
}
}
};
function log() {
let arguments_arr = [...arguments];
let flag = arguments_arr.pop();
if (flag === -1) {
error_messages.push(arguments_arr.join(' '));
}
if (flag !== 0) arguments_arr.push(getCodeLocation());
if (flag === 0 || open_debugger) orgin_log(...arguments_arr);
}
function getCodeLocation() {
const callstack = new Error().stack.split("\n");
callstack.shift();
while (callstack.length && callstack[0].includes("chrome-extension://")) {
callstack.shift();
}
if (!callstack.length) {
return "";
}
return '\n' + callstack[0].trim();
}
function display_config_win() {
const css_str = '.popup{ z-index:9999999999; position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);padding:20px;background-color:#ffffff;border:1px solid #3498db;border-radius:5px;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:1000;width:200px;}.btn{cursor:pointer;background-color:#3498db;color:#ffffff;border:none;padding:5px 10px;margin:0 auto;border-radius:5px;display:block;margin-top:10px;}.recommend-title{user-select: none;font-weight:bold;font-size: large;background-color:#3498db;color:#ffffff;border:none;padding:5px;padding-left:10px;border-radius:5px;width:180px;text-align:start;}.select-group{cursor:pointer;padding:5px;list-style-type:none;margin:0;padding-left:0;user-select: none;}.item-group{list-style-type:none;margin:0;padding-left:0;} .close-btn{position:absolute;top:5px;right:5px;cursor:pointer;border:none;background-color:floralwhite;} label{font-size: large;}';
const style = document.createElement("style");
style.textContent = css_str;
document.querySelector('body').appendChild(style);
const win_config = {
"recommend_btn": [
{
"id": "open_recommend_shorts",
"title": "btn_recommend_shorts",
"items": [
{
"tag": "btn_lable_open",
"value": "on",
},
{
"tag": "btn_lable_close",
"value": "off",
},
{
"tag": "btn_lable_subscribed",
"value": "subscribed",
"tips": "recommend_subscribed_lable_tips",
}
]
}, {
"id": "open_recommend_liveroom",
"title": "btn_recommend_liveroom",
"items": [
{
"tag": "btn_lable_open",
"value": "on",
},
{
"tag": "btn_lable_close",
"value": "off",
},
{
"tag": "btn_lable_subscribed",
"value": "subscribed",
"tips": "recommend_subscribed_lable_tips",
}
]
}
,
{
"id": "open_recommend_movie",
"title": "btn_recommend_movie",
"items": [
{
"tag": "btn_lable_open",
"value": "on",
},
{
"tag": "btn_lable_close",
"value": "off",
},
]
},
{
"id": "open_recommend_popular",
"title": "btn_recommend_popular",
"items": [
{
"tag": "btn_lable_open",
"value": "on",
},
{
"tag": "btn_lable_close",
"value": "off",
},
]
},
{
"id": "open_recommend_playables",
"title": "btn_recommend_game",
"items": [
{
"tag": "btn_lable_open",
"value": "on",
},
{
"tag": "btn_lable_close",
"value": "off",
},
]
}
]
};
const popup = document.createElement('div');
popup.id = 'popup';
popup.className = 'popup';
const close_btn = document.createElement('button');
close_btn.className = 'close-btn';
close_btn.innerHTML = 'x';
close_btn.addEventListener('click', remove_popup_hander
);
popup.append(close_btn);
const item_groups = [];
const item_group = document.createElement('ul');
item_group.className = 'item-group';
win_config.recommend_btn.forEach(recommend_item_info => {
const recommend_id = recommend_item_info.id;
const recommend_title = flag_info[recommend_item_info.title];
const select_item_infos = recommend_item_info.items;
const select_items = [];
const item = document.createElement('li');
const select_group = document.createElement('ul');
select_group.className = 'select-group';
select_group.id = recommend_id;
select_item_infos.forEach(select_item_info => {
const tag = flag_info[select_item_info.tag];
const value = select_item_info.value;
const tips = flag_info[select_item_info.tips];
const select_item = document.createElement('li');
const input = document.createElement('input');
input.type = 'radio';
input.name = recommend_id + '_option';
input.id = recommend_id + '_' + value;
input.value = value;
if (user_data[recommend_id] === value) {
input.checked = true;
}
input.addEventListener('click', () => {
handle_recommend_radio(input);
});
const label = document.createElement('label');
label.htmlFor = input.id;
label.innerText = tag;
tips && (label.title = tips);
select_item.append(input, label);
select_items.push(select_item);
});
const recommend_title_div = document.createElement('div');
recommend_title_div.className = 'recommend-title';
recommend_title_div.innerText = recommend_title;
select_group.append(...select_items);
item.append(recommend_title_div, select_group);
item_groups.push(item);
});
item_group.append(...item_groups);
popup.append(item_group);
document.body.append(popup);
function remove_popup_hander(event) {
if (!popup.contains(event.target) || event.target === close_btn) {
popup.remove();
document.removeEventListener('click', remove_popup_hander);
}
}
document.addEventListener('click', remove_popup_hander);
function handle_recommend_radio(input_obj) {
user_data[input_obj.parentNode.parentNode.id] = input_obj.value;
user_data_api.set();
config_init(user_data.language);
}
}
function display_update_win() {
function btn_click() {
btn = this;
if (btn.id === 'go_btn') {
location.href = script_url;
}
container.remove();
}
const css_str = "#update_tips_win { z-index:9999999999; display: flex; position: fixed; bottom: 20px; right: 20px; padding: 10px 20px; background-color: #fff; border: 1px solid #ccc; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); border-radius: 10px; } .btn { margin: 0 10px; display: inline-block; padding: 5px 10px; background-color: #3498db; color: #fff; border: none; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } .btn:hover { background-color: #2980b9; }";
const style = document.createElement("style");
style.innerText = css_str;
document.querySelector('body').appendChild(style);
const container = document.createElement("div");
container.id = "update_tips_win";
const span = document.createElement("span");
span.textContent = GM_info.script.name + '有更新了!!';
container.appendChild(span);
const go_btn = document.createElement("button");
go_btn.textContent = 'GO';
go_btn.id = 'go_btn';
go_btn.className = 'btn';
go_btn.onclick = btn_click;
container.appendChild(go_btn);
const no_btn = document.createElement("button");
no_btn.textContent = 'NO';
no_btn.className = 'btn';
no_btn.id = 'no_btn';
no_btn.onclick = btn_click;
container.appendChild(no_btn);
document.querySelector('body').appendChild(container);
}
function checke_update() {
let last_check_time = GM_getValue('last_check_time', 0);
if ((Date.now() - last_check_time) < 1000 * 60 * 60 * 24) return;
GM_xmlhttpRequest({
method: 'GET',
url: script_url,
onload: function (response) {
const onlineScript = response.responseText;
// 从线上脚本中提取版本号和元数据信息
const onlineMeta = onlineScript.match(/@version\s+([^\s]+)/i);
const onlineVersion = onlineMeta ? onlineMeta[1] : '';
if (onlineVersion > GM_info.script.version) {
display_update_win();
}
}
});
GM_setValue('last_check_time', Date.now());
}
function obj_process_filter(path_info, json_obj) {
if (!/yt_(watch|home)$/.test(page_type)) return false;
if (!user_data.login || user_data.channel_infos.ids.length === 0) return false;
if (user_data.open_recommend_shorts === 'subscribed' && path_info.condition_value === 'Shorts') {
let shorts_relative_express = ["richShelfRenderer.title.runs[0].text", 'reelShelfRenderer.title.runs[0].text'];
if (shorts_relative_express.includes(path_info.relative_path)) {
let video_list_path;
if (path_info.relative_path === "reelShelfRenderer.title.runs[0].text") {
video_list_path = path_info.path.split('["title"]')[0] + '["items"]';
}
if (path_info.relative_path === "richShelfRenderer.title.runs[0].text") {
video_list_path = path_info.path.split('["title"]')[0] + '["contents"]';
}
const video_list = data_process.string_to_value(json_obj, video_list_path) || [];
shorts_fun.parase_shorts_infos(video_list);
}
}
if (user_data.open_recommend_liveroom === 'subscribed' && [flag_info.upcoming, flag_info.live].includes(path_info.condition_value)) {
let live_express = ['text.accessibility.accessibilityData.label........=- =' + flag_info.live,
'metadataBadgeRenderer.label......=- =' + flag_info.live,
'metadataBadgeRenderer.label.....=- =' + flag_info.live
];
let upcoming_express = ['thumbnailOverlayTimeStatusRenderer.text.runs[0].text.........=- =' + flag_info.upcoming, 'thumbnailOverlayTimeStatusRenderer.text.simpleText.......=- =' + flag_info.upcoming];
if (live_express.includes(path_info.express)) {
try {
let match = JSON.stringify(data_process.string_to_value(json_obj, path_info.deal_path)).match(/"browseId"\:"(.*?)"/);
let id;
if (match && match.length > 1) id = match[1];
if (!id) {
log('id获取失败\n' + JSON.stringify(path_info), -1);
}
if (!user_data.channel_infos.ids.includes(id)) {
log('过滤' + id + '的直播', 0);
} else {
let index = user_data.channel_infos.ids.indexOf(id);
let name = user_data.channel_infos.names[index];
log('不过滤' + name + '的直播', 0);
return true;
}
} catch (error) {
log(error, -1);
}
}
if (upcoming_express.includes(path_info.express)) {
try {
let match = JSON.stringify(data_process.string_to_value(json_obj, path_info.deal_path)).match(/"browseId"\:"(.*?)"/);
let id;
if (match && match.length > 1) id = match[1];
if (!id) {
log('id获取失败\n' + JSON.stringify(path_info), -1);
}
if (!user_data.channel_infos.ids.includes(id)) {
log('过滤' + id + '等待发布的直播', 0);
} else {
let index = user_data.channel_infos.ids.indexOf(id);
let name = user_data.channel_infos.names[index];
log('不过滤' + name + '等待发布的直播', 0);
return true;
}
} catch (error) {
log(error, -1);
}
}
}
return false;
}
function get_shorts_fun() {
return {
parase_shorts_infos: function (video_list) {
!user_data.shorts_list && (user_data.shorts_list = []);
let video_id, title, views_lable, thumbnail_url;
let count = 0;
for (let video_info of video_list) {
count++;
if (page_type === "yt_home") {
video_id = video_info.richItemRenderer.content.reelItemRenderer.videoId;
title = video_info.richItemRenderer.content.reelItemRenderer.headline.simpleText;
views_lable = video_info.richItemRenderer.content.reelItemRenderer.viewCountText.simpleText;
thumbnail_url = video_info.richItemRenderer.content.reelItemRenderer.thumbnail.thumbnails[0].url;
}
if (page_type === "yt_watch") {
video_id = video_info.reelItemRenderer.videoId;
title = video_info.reelItemRenderer.headline.simpleText;
views_lable = video_info.reelItemRenderer.viewCountText.simpleText;
thumbnail_url = video_info.reelItemRenderer.thumbnail.thumbnails[0].url;
}
if (page_type === "mobile_yt_home") {
video_id = video_info.shortsLockupViewModel.entityId.replace('shorts-shelf-item-', '');
title = video_info.shortsLockupViewModel.overlayMetadata.primaryText.content;
views_lable = video_info.shortsLockupViewModel.overlayMetadata.secondaryText.content;
thumbnail_url = video_info.shortsLockupViewModel.thumbnail.sources[0].url;
}
setTimeout((video_id, title, views_lable, thumbnail_url) => {
yt_api.get_shorts_author(video_id).then((author_info) => {
let [author_id, author_name] = author_info;
if (author_id && user_data.channel_infos.ids.includes(author_id)) {
if (user_data.shorts_list.some((value) => { return value.id === video_id; })) {
log('已存在' + author_name + '的短视频:' + title, 0);
return;
}
log('不过滤' + author_name + '的短视频:' + title, 0);
const shorts_info = {
id: video_id,
title: title,
author_id: author_id,
author_name: author_name,
views_lable: views_lable,
from: page_type,
// orgin_item: video_info,
thumbnail_url: thumbnail_url
};
user_data.shorts_list.push(shorts_info);
user_data_api.set();
} else {
log('过滤' + author_name + '的短视频:' + title, 0);
}
});
}, count * user_data.shorts_parase_delay, video_id, title, views_lable, thumbnail_url);
}
},
get_shorts_section: function () {
if (!user_data.shorts_list || !user_data.shorts_list.length) return;
let root, item_path;
const items = [];
if (page_type == 'yt_home') {
root = {
"richSectionRenderer": {
"content": {
"richShelfRenderer": {
"title": {
"runs": [
{
"text": "Shorts"
}
]
},
"contents": [],
"trackingParams": "CNMEEN-DAyITCOGA_NHuz4UDFWdqTAgdfF4E-Q==",
"menu": {
"menuRenderer": {
"trackingParams": "CNMEEN-DAyITCOGA_NHuz4UDFWdqTAgdfF4E-Q==",
"topLevelButtons": [
{
"buttonRenderer": {
"style": "STYLE_OPACITY",
"size": "SIZE_DEFAULT",
"isDisabled": false,
"serviceEndpoint": {
"clickTrackingParams": "CNYEEKqJCRgMIhMI4YD80e7PhQMVZ2pMCB18XgT5",
"commandMetadata": {
"webCommandMetadata": {
"sendPost": true,
"apiUrl": "/youtubei/v1/feedback"
}
},
"feedbackEndpoint": {
"feedbackToken": "AB9zfpIcTXNyA3lbF_28icb4umRJ5AveSSTqmF7T9gE8k-Sw7HrOTLE5wzA2TScqfTByCI-cR9nPuVMSWAgbNuuaruVBYx2-2dGAzujQTL8KGMOyCFM_wmGhkLTSdUBQzsFQRHEibpg_",
"uiActions": {
"hideEnclosingContainer": true
},
"actions": [
{
"clickTrackingParams": "CNYEEKqJCRgMIhMI4YD80e7PhQMVZ2pMCB18XgT5",
"replaceEnclosingAction": {
"item": {
"notificationMultiActionRenderer": {
"responseText": {
"runs": [
{
"text": "Shelf will be hidden for "
},
{
"text": "30"
},
{
"text": " days"
}
]
},
"buttons": [
{
"buttonRenderer": {
"style": "STYLE_BLUE_TEXT",
"text": {
"simpleText": "Undo"
},
"serviceEndpoint": {
"clickTrackingParams": "CNgEEPBbGAAiEwjhgPzR7s-FAxVnakwIHXxeBPk=",
"commandMetadata": {
"webCommandMetadata": {
"sendPost": true,
"apiUrl": "/youtubei/v1/feedback"
}
},
"undoFeedbackEndpoint": {
"undoToken": "AB9zfpLpAillN1hH9cyfSbyPRWwAhTOJo6mUTu-ony4HASc0KgCEy0ifaIrDUdJJEk4OXiPC43EMPZBEK8WGiIqeci4r97TGpabAUk84dEh7tHzF7-rsziFBGZjY92Jyk3YujrF2_wxC",
"actions": [
{
"clickTrackingParams": "CNgEEPBbGAAiEwjhgPzR7s-FAxVnakwIHXxeBPk=",
"undoFeedbackAction": {
"hack": true
}
}
]
}
},
"trackingParams": "CNgEEPBbGAAiEwjhgPzR7s-FAxVnakwIHXxeBPk="
}
}
],
"trackingParams": "CNcEEKW8ASITCOGA_NHuz4UDFWdqTAgdfF4E-Q=="
}
}
}
}
]
}
},
"icon": {
"iconType": "DISMISSAL"
},
"tooltip": "Not interested",
"trackingParams": "CNYEEKqJCRgMIhMI4YD80e7PhQMVZ2pMCB18XgT5",
"accessibilityData": {
"accessibilityData": {
"label": "Not interested"
}
}
}
}
]
}
},
"showMoreButton": {
"buttonRenderer": {
"style": "STYLE_OPACITY",
"size": "SIZE_DEFAULT",
"text": {
"runs": [
{
"text": "Show more"
}
]
},
"icon": {
"iconType": "EXPAND"
},
"accessibility": {
"label": "Show more"
},
"trackingParams": "CNUEEJnjCyITCOGA_NHuz4UDFWdqTAgdfF4E-Q=="
}
},
"isExpanded": false,
"icon": {
"iconType": "YOUTUBE_SHORTS_BRAND_24"
},
"isTopDividerHidden": false,
"isBottomDividerHidden": false,
"showLessButton": {
"buttonRenderer": {
"style": "STYLE_OPACITY",
"size": "SIZE_DEFAULT",
"text": {
"runs": [
{
"text": "Show less"
}
]
},
"icon": {
"iconType": "COLLAPSE"
},
"accessibility": {
"label": "Show less"
},
"trackingParams": "CNQEEPBbIhMI4YD80e7PhQMVZ2pMCB18XgT5"
}
}
}
},
"trackingParams": "CNIEEOOXBRgEIhMI4YD80e7PhQMVZ2pMCB18XgT5",
"fullBleed": false
}
};
item_path = 'root.richSectionRenderer.content.richShelfRenderer.contents';
}
if (page_type == 'yt_watch') {
root = {
"reelShelfRenderer": {
"title": {
"runs": [
{
"text": "Shorts"
}
]
},
"items": [],
"trackingParams": "CM4CEN-DAxgEIhMInKOvhY3QhQMVGcCXCB04HQR6",
"icon": {
"iconType": "YOUTUBE_SHORTS_BRAND_24"
}
}
};
item_path = 'root.reelShelfRenderer.items';
}
if (page_type == 'mobile_yt_home') {
root = {
"richSectionRenderer": {
"content": {
"reelShelfRenderer": {
"title": {
"runs": [
{
"text": "Shorts"
}
]
},
"button": {
"menuRenderer": {
"trackingParams": "CHYQ34MDIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"topLevelButtons": [
{
"buttonRenderer": {
"style": "STYLE_DEFAULT",
"size": "SIZE_DEFAULT",
"isDisabled": false,
"serviceEndpoint": {
"clickTrackingParams": "CLMBEKqJCRgPIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"commandMetadata": {
"webCommandMetadata": {
"sendPost": true,
"apiUrl": "/youtubei/v1/feedback"
}
},
"feedbackEndpoint": {
"feedbackToken": "AB9zfpJSnrbvskPWkpziyGduKV-4gTxm30-eNNYDobzecpLq84dL6HwCxdX_zbvm_OmxSKdlsngHEE1CF7JKYGiyDVYV_Q7p9ihGCzOYcnqKcAJfNnSp-U-njcnKLgCWu_USr-2prW3x",
"uiActions": {
"hideEnclosingContainer": true
},
"actions": [
{
"clickTrackingParams": "CLMBEKqJCRgPIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"replaceEnclosingAction": {
"item": {
"notificationMultiActionRenderer": {
"responseText": {
"runs": [
{
"text": "Shelf will be hidden for "
},
{
"text": "30"
},
{
"text": " days"
}
]
},
"buttons": [
{
"buttonRenderer": {
"style": "STYLE_MONO_TONAL",
"text": {
"runs": [
{
"text": "Undo"
}
]
},
"serviceEndpoint": {
"clickTrackingParams": "CLUBEPBbGAAiEwip6oDKjtCFAxXPeUwIHaYIDQk=",
"commandMetadata": {
"webCommandMetadata": {
"sendPost": true,
"apiUrl": "/youtubei/v1/feedback"
}
},
"undoFeedbackEndpoint": {
"undoToken": "AB9zfpK-nY3vxgYDkvJSkuFdbeBltD0r4XdLzoFqxz6OPnmJrroOAxKfUuDny8kPjB9yyWzwEerOZqe90BakCPEJXycRSrH8sZAdnlWpEs0n0lx6qOFERE6o5jkK3mgbcVCM-Al38oGV",
"actions": [
{
"clickTrackingParams": "CLUBEPBbGAAiEwip6oDKjtCFAxXPeUwIHaYIDQk=",
"undoFeedbackAction": {
"hack": true
}
}
]
}
},
"trackingParams": "CLUBEPBbGAAiEwip6oDKjtCFAxXPeUwIHaYIDQk="
}
}
],
"trackingParams": "CLQBEKW8ASITCKnqgMqO0IUDFc95TAgdpggNCQ=="
}
}
}
}
]
}
},
"icon": {
"iconType": "DISMISSAL"
},
"tooltip": "Not interested",
"trackingParams": "CLMBEKqJCRgPIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"accessibilityData": {
"accessibilityData": {
"label": "Not interested"
}
}
}
}
]
}
},
"items": [
],
"trackingParams": "CHYQ34MDIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"icon": {
"iconType": "YOUTUBE_SHORTS_BRAND_24"
}
}
},
"trackingParams": "CHUQ45cFGAEiEwip6oDKjtCFAxXPeUwIHaYIDQk=",
"fullBleed": false
}
};
item_path = 'root.richSectionRenderer.content.reelShelfRenderer.items';
}
let shorts;
while (shorts = user_data.shorts_list.pop()) {
let id = shorts['id'];
let title = shorts['title'];
let views_lable = shorts['views_lable'];
let from = shorts['from'];
let thumbnail_url = shorts['thumbnail_url'];
let tmp_item;
if (['yt_home', 'yt_watch'].includes(page_type)) {
tmp_item = {
"reelItemRenderer": {
"videoId": id,
"headline": {
"simpleText": title
},
"thumbnail": {
"thumbnails": [
{
"url": thumbnail_url,
"width": 405,
"height": 720
}
],
"isOriginalAspectRatio": true
},
"viewCountText": {
"accessibility": {
"accessibilityData": {
"label": views_lable
}
},
"simpleText": views_lable
},
"navigationEndpoint": {
"clickTrackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6mgEFCCUQ-B0=",
"commandMetadata": {
"webCommandMetadata": {
"url": "/shorts/" + id,
"webPageType": "WEB_PAGE_TYPE_SHORTS",
"rootVe": 37414
}
},
"reelWatchEndpoint": {
"videoId": id,
"playerParams": "8AEBoAMCyAMluAQGogYVAdXZ-jvMfGWnXiNDPh0oiMSTJMUn",
"thumbnail": {
"thumbnails": [
{
"url": "https://i.ytimg.com/vi/" + id + "/frame0.jpg",
"width": 1080,
"height": 1920
}
],
"isOriginalAspectRatio": true
},
"overlay": {
"reelPlayerOverlayRenderer": {
"style": "REEL_PLAYER_OVERLAY_STYLE_SHORTS",
"trackingParams": "CO4CELC1BCITCJyjr4WN0IUDFRnAlwgdOB0Eeg==",
"reelPlayerNavigationModel": "REEL_PLAYER_NAVIGATION_MODEL_UNSPECIFIED"
}
},
"params": "CAYwAg%3D%3D",
"sequenceProvider": "REEL_WATCH_SEQUENCE_PROVIDER_RPC",
"sequenceParams": "CgtLRmRCbnpnSjJZWSoCGAZQGWgA",
"loggingContext": {
"vssLoggingContext": {
"serializedContextData": "CgIIDA%3D%3D"
},
"qoeLoggingContext": {
"serializedContextData": "CgIIDA%3D%3D"
}
},
"ustreamerConfig": "CAwSHDFIakVXUytucVRyTENNWlgzMXdDZmYwamZQQ0U="
}
},
"menu": {
"menuRenderer": {
"items": [
{
"menuServiceItemRenderer": {
"text": {
"runs": [
{
"text": "Report"
}
]
},
"icon": {
"iconType": "FLAG"
},
"serviceEndpoint": {
"clickTrackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6",
"commandMetadata": {
"webCommandMetadata": {
"sendPost": true,
"apiUrl": "/youtubei/v1/flag/get_form"
}
},
"getReportFormEndpoint": {
"params": "EgtLRmRCbnpnSjJZWUABWABwAXgB2AEA6AEA"
}
},
"trackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6"
}
},
{
"menuServiceItemRenderer": {
"text": {
"runs": [
{
"text": "Not interested"
}
]
},
"icon": {
"iconType": "NOT_INTERESTED"
},
"serviceEndpoint": {
"clickTrackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6",
"commandMetadata": {
"webCommandMetadata": {
"sendPost": true,
"apiUrl": "/youtubei/v1/feedback"
}
},
"feedbackEndpoint": {
"feedbackToken": "AB9zfpIBjY8nLioWtHjvUvMvrLXfhPMooShdpv91xgNNrZuxibAl6QyPeYMe7faEHcrSUm-TIqvLe2ThmYQpNRUy9rPbV1k3jjrvqqc5cOLBvnV8oN0Kbrq3-K9IjJXYitJPyOzJU0uy",
"actions": [
{
"clickTrackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6",
"replaceEnclosingAction": {
"item": {
"notificationMultiActionRenderer": {
"responseText": {
"runs": [
{
"text": "Video removed"
}
]
},
"buttons": [
{
"buttonRenderer": {
"style": "STYLE_BLUE_TEXT",
"text": {
"runs": [
{
"text": "Undo"
}
]
},
"serviceEndpoint": {
"clickTrackingParams": "CO0CEPBbGAAiEwico6-FjdCFAxUZwJcIHTgdBHo=",
"commandMetadata": {
"webCommandMetadata": {
"sendPost": true,
"apiUrl": "/youtubei/v1/feedback"
}
},
"undoFeedbackEndpoint": {
"undoToken": "AB9zfpK74nsMbZ4OfNgKTgA9g0w3Q8o72jdm384D3y82OAuy2KgvTUOAn-iII915ZC_7aqAxTK-XNir21X_T3WQEeAzdy4hCZ6o0f12hfdHW8xI1js1WB_CEn3EW27P9_1vu5dw2kDeW",
"actions": [
{
"clickTrackingParams": "CO0CEPBbGAAiEwico6-FjdCFAxUZwJcIHTgdBHo=",
"undoFeedbackAction": {
"hack": true
}
}
]
}
},
"trackingParams": "CO0CEPBbGAAiEwico6-FjdCFAxUZwJcIHTgdBHo="
}
}
],
"trackingParams": "COwCEKW8ASITCJyjr4WN0IUDFRnAlwgdOB0Eeg=="
}
}
}
}
]
}
},
"trackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6",
"accessibility": {
"accessibilityData": {
"label": "Not interested"
}
}
}
},
{
"menuNavigationItemRenderer": {
"text": {
"runs": [
{
"text": "Send feedback"
}
]
},
"icon": {
"iconType": "FEEDBACK"
},
"navigationEndpoint": {
"clickTrackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6",
"commandMetadata": {
"webCommandMetadata": {
"ignoreNavigation": true
}
},
"userFeedbackEndpoint": {
"additionalDatas": [
{
"userFeedbackEndpointProductSpecificValueData": {
"key": "video_id",
"value": id
}
},
{
"userFeedbackEndpointProductSpecificValueData": {
"key": "lockup",
"value": "shelf"
}
}
]
}
},
"trackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6",
"accessibility": {
"accessibilityData": {
"label": "Send feedback"
}
}
}
}
],
"trackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6",
"accessibility": {
"accessibilityData": {
"label": "More actions"
}
}
}
},
"trackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6QIazp8Dzs9CrKA==",
"accessibility": {
"accessibilityData": {
"label": title + " - play Short"
}
},
"style": "REEL_ITEM_STYLE_AVATAR_CIRCLE",
"dismissalInfo": {
"feedbackToken": "AB9zfpLIJd1aRU9JzdOjpgeJBW2QvHH79sx6dM6ZCDEzyc5qrISZBSpNRe5lerckNHwQ10BOwEQhlquLlHP-nkuA4VSSCXX0XgMJHBnKWBxlIXkQ1pLIUjd6cQKhrCUioDfix7xn5Ecj"
},
"videoType": "REEL_VIDEO_TYPE_VIDEO",
"loggingDirectives": {
"trackingParams": "COsCEIf2BBgAIhMInKOvhY3QhQMVGcCXCB04HQR6",
"visibility": {
"types": "12"
},
"enableDisplayloggerExperiment": true
}
}
};
}
if (page_type == "yt_home") {
tmp_item = {
"richItemRenderer": {
"content": tmp_item,
"trackingParams": "CJsFEJmNBRgAIhMI4YD80e7PhQMVZ2pMCB18XgT5"
}
};
}
if (page_type == "mobile_yt_home") {
tmp_item = {
"shortsLockupViewModel": {
"entityId": "shorts-shelf-item-" + id,
"accessibilityText": title + ", " + views_lable + " - play Short",
"thumbnail": {
"sources": [
{
"url": thumbnail_url,
"width": 405,
"height": 720
}
]
},
"onTap": {
"innertubeCommand": {
"clickTrackingParams": "CK8BEIf2BBgAIhMIqeqAyo7QhQMVz3lMCB2mCA0JWg9GRXdoYXRfdG9fd2F0Y2iaAQUIJBCOHg==",
"commandMetadata": {
"webCommandMetadata": {
"url": "/shorts/" + id,
"webPageType": "WEB_PAGE_TYPE_SHORTS",
"rootVe": 37414
}
},
"reelWatchEndpoint": {
"videoId": id,
"playerParams": "8AEBoAMByAMkuAQFogYVAdXZ-jveUoR0s0_R7sLGUd85_xAk",
"thumbnail": {
"thumbnails": [
{
"url": "https://i.ytimg.com/vi/" + id + "/frame0.jpg",
"width": 1080,
"height": 1920
}
],
"isOriginalAspectRatio": true
},
"overlay": {
"reelPlayerOverlayRenderer": {
"style": "REEL_PLAYER_OVERLAY_STYLE_SHORTS",
"trackingParams": "CLIBELC1BCITCKnqgMqO0IUDFc95TAgdpggNCQ==",
"reelPlayerNavigationModel": "REEL_PLAYER_NAVIGATION_MODEL_UNSPECIFIED"
}
},
"params": "CAUwAg%3D%3D",
"sequenceProvider": "REEL_WATCH_SEQUENCE_PROVIDER_RPC",
"sequenceParams": "CgtwblVoZV9PUTE2byoCGAVQGWgA",
"loggingContext": {
"vssLoggingContext": {
"serializedContextData": "CgIIDA%3D%3D"
},
"qoeLoggingContext": {
"serializedContextData": "CgIIDA%3D%3D"
}
},
"ustreamerConfig": "CAwSHDFIakVXUytucVRyTENNWlgzMXdDZmYwamZQQ0U="
}
}
},
"inlinePlayerData": {
"onVisible": {
"innertubeCommand": {
"clickTrackingParams": "CK8BEIf2BBgAIhMIqeqAyo7QhQMVz3lMCB2mCA0JMgZnLWhpZ2haD0ZFd2hhdF90b193YXRjaJoBBQgkEI4e",
"commandMetadata": {
"webCommandMetadata": {
"url": "/watch?v=" + id + "&pp=YAHIAQG6AwIYAugFAQ%3D%3D",
"webPageType": "WEB_PAGE_TYPE_WATCH",
"rootVe": 3832
}
},
"watchEndpoint": {
"videoId": id,
"playerParams": "YAHIAQG6AwIYAugFAQ%3D%3D"
}
}
}
},
"menuOnTap": {
"innertubeCommand": {
"clickTrackingParams": "CK8BEIf2BBgAIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"showSheetCommand": {
"panelLoadingStrategy": {
"inlineContent": {
"sheetViewModel": {
"content": {
"listViewModel": {
"listItems": [
{
"listItemViewModel": {
"title": {
"content": "Not interested"
},
"leadingImage": {
"sources": [
{
"clientResource": {
"imageName": "NOT_INTERESTED"
}
}
]
},
"rendererContext": {
"commandContext": {
"onTap": {
"innertubeCommand": {
"clickTrackingParams": "CK8BEIf2BBgAIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"commandMetadata": {
"webCommandMetadata": {
"sendPost": true,
"apiUrl": "/youtubei/v1/feedback"
}
},
"feedbackEndpoint": {
"feedbackToken": "AB9zfpJnMNgSEnsvYAu4UXP6IN5z0VfAt-OZOs8ypsKND9Mv5RhoELjmgb_vxVOvvYoiM2f8q9QFcdGMOEOCSk7LPYMnGshEHKcis4oeot-Z5OsgYpmOP3DbMXgFHUgQhOUAjL-FIj5y",
"actions": [
{
"clickTrackingParams": "CK8BEIf2BBgAIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"replaceEnclosingAction": {
"item": {
"notificationMultiActionRenderer": {
"responseText": {
"runs": [
{
"text": "Video removed"
}
]
},
"buttons": [
{
"buttonRenderer": {
"style": "STYLE_BLUE_TEXT",
"text": {
"runs": [
{
"text": "Undo"
}
]
},
"serviceEndpoint": {
"clickTrackingParams": "CLEBEPBbGAAiEwip6oDKjtCFAxXPeUwIHaYIDQk=",
"commandMetadata": {
"webCommandMetadata": {
"sendPost": true,
"apiUrl": "/youtubei/v1/feedback"
}
},
"undoFeedbackEndpoint": {
"undoToken": "AB9zfpI_UgAQH8eSODf7gCfkDtllqeFC5Qr38N7cNnlz8NmYZ78F2KiuX3KZNcumX2jfVXRzNfd2M0V7vud8UdS2Hz7SshgqVTn2TOJApWBlkIPTbUYWuQkX2CSbVKZw1p3wIHkjQOH7",
"actions": [
{
"clickTrackingParams": "CLEBEPBbGAAiEwip6oDKjtCFAxXPeUwIHaYIDQk=",
"undoFeedbackAction": {
"hack": true
}
}
]
}
},
"trackingParams": "CLEBEPBbGAAiEwip6oDKjtCFAxXPeUwIHaYIDQk="
}
}
],
"trackingParams": "CLABEKW8ASITCKnqgMqO0IUDFc95TAgdpggNCQ=="
}
}
}
}
]
}
}
}
}
}
}
},
{
"listItemViewModel": {
"title": {
"content": "Send feedback"
},
"leadingImage": {
"sources": [
{
"clientResource": {
"imageName": "FEEDBACK"
}
}
]
},
"rendererContext": {
"commandContext": {
"onTap": {
"innertubeCommand": {
"clickTrackingParams": "CK8BEIf2BBgAIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"commandMetadata": {
"webCommandMetadata": {
"ignoreNavigation": true
}
},
"userFeedbackEndpoint": {
"additionalDatas": [
{
"userFeedbackEndpointProductSpecificValueData": {
"key": "video_id",
"value": id
}
},
{
"userFeedbackEndpointProductSpecificValueData": {
"key": "lockup",
"value": "shelf"
}
}
]
}
}
}
}
}
}
}
]
}
}
}
}
}
}
}
},
"indexInCollection": 0,
"menuOnTapA11yLabel": "More actions",
"overlayMetadata": {
"primaryText": {
"content": title,
"styleRuns": [
{
"startIndex": 0,
"fontName": "",
"fontSize": 0,
"fontColor": 4294967295
}
]
},
"secondaryText": {
"content": views_lable,
"styleRuns": [
{
"startIndex": 0,
"fontName": "",
"fontSize": 0,
"fontColor": 4294967295
}
]
}
},
"loggingDirectives": {
"trackingParams": "CK8BEIf2BBgAIhMIqeqAyo7QhQMVz3lMCB2mCA0J",
"visibility": {
"types": "12"
},
"enableDisplayloggerExperiment": true
}
}
};
}
items.push(tmp_item);
}
eval(item_path + ' = items');
user_data_api.set();
return root;
},
check_shorts_exist: function () {
const short_id = href.split('/').pop();
for (let shorts of user_data.shorts_list) {
if (shorts.id === short_id) {
user_data.shorts_list.pop(shorts);
user_data_api.set();
return;
}
}
}
};
}
function get_yt_api() {
return {
get_subscribe_data: function (retry = 0) {
const headers = {
"authority": "www.youtube.com",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
};
const url = "https://www.youtube.com/feed/channels";
const requestConfig = {
method: 'GET',
headers: headers,
url: url
};
GM_xmlhttpRequest({
...requestConfig,
onload: function (response) {
let tmp_channel_names = [], tmp_channel_ids = [];
let regex = /var ytInitialData \= (.*?);\<\/script\>/;
try {
let match = response.responseText.match(regex);
let ytInitialData_obj = JSON.parse(match[1]);
let items = ytInitialData_obj.contents.twoColumnBrowseResultsRenderer.tabs[0].tabRenderer.content.sectionListRenderer.contents[0].itemSectionRenderer.contents[0].shelfRenderer.content.expandedShelfContentsRenderer.items;
for (let item of items) {
let channel_name = item.channelRenderer.title.simpleText;
const match_channel_id = item.channelRenderer.channelId;
tmp_channel_ids.push(match_channel_id);
tmp_channel_names.push(channel_name);
}
if (tmp_channel_ids.length > 0) {
user_data.channel_infos.ids = tmp_channel_ids;
user_data.channel_infos.names = tmp_channel_names;
user_data_api.set();
}
log('获取关注列表成功' + user_data.channel_infos.ids.length + '个', 0);
} catch (error) {
if (retry < 3) {
setTimeout(() => { get_subscribe_data(retry + 1); }, 1000);
}
log('获取关注列表失败\n', error, -1);
}
},
onerror: function (error) {
if (retry < 3) {
setTimeout(() => { get_subscribe_data(retry + 1); }, 1000);
}
log('获取关注列表失败\n', error, -1);
},
});
},
get_authorization: function () {
function Vja() {
function a() {
e[0] = 1732584193;
e[1] = 4023233417;
e[2] = 2562383102;
e[3] = 271733878;
e[4] = 3285377520;
u = q = 0;
}
function b(x) {
for (var y = l, C = 0; 64 > C; C += 4)
y[C / 4] = x[C] << 24 | x[C + 1] << 16 | x[C + 2] << 8 | x[C + 3];
for (C = 16; 80 > C; C++)
x = y[C - 3] ^ y[C - 8] ^ y[C - 14] ^ y[C - 16],
y[C] = (x << 1 | x >>> 31) & 4294967295;
x = e[0];
var E = e[1]
, H = e[2]
, R = e[3]
, T = e[4];
for (C = 0; 80 > C; C++) {
if (40 > C) {
if (20 > C) {
var X = R ^ E & (H ^ R);
var la = 1518500249;
} else
X = E ^ H ^ R,
la = 1859775393;
} else
60 > C ? (X = E & H | R & (E | H),
la = 2400959708) : (X = E ^ H ^ R,
la = 3395469782);
X = ((x << 5 | x >>> 27) & 4294967295) + X + T + la + y[C] & 4294967295;
T = R;
R = H;
H = (E << 30 | E >>> 2) & 4294967295;
E = x;
x = X;
}
e[0] = e[0] + x & 4294967295;
e[1] = e[1] + E & 4294967295;
e[2] = e[2] + H & 4294967295;
e[3] = e[3] + R & 4294967295;
e[4] = e[4] + T & 4294967295;
}
function c(x, y) {
if ("string" === typeof x) {
x = unescape(encodeURIComponent(x));
for (var C = [], E = 0, H = x.length; E < H; ++E)
C.push(x.charCodeAt(E));
x = C;
}
y || (y = x.length);
C = 0;
if (0 == q)
for (; C + 64 < y;)
b(x.slice(C, C + 64)),
C += 64,
u += 64;
for (; C < y;)
if (h[q++] = x[C++],
u++,
64 == q)
for (q = 0,
b(h); C + 64 < y;)
b(x.slice(C, C + 64)),
C += 64,
u += 64;
}
function d() {
var x = []
, y = 8 * u;
56 > q ? c(m, 56 - q) : c(m, 64 - (q - 56));
for (var C = 63; 56 <= C; C--)
h[C] = y & 255,
y >>>= 8;
b(h);
for (C = y = 0; 5 > C; C++)
for (var E = 24; 0 <= E; E -= 8)
x[y++] = e[C] >> E & 255;
return x;
}
for (var e = [], h = [], l = [], m = [128], p = 1; 64 > p; ++p)
m[p] = 0;
var q, u;
a();
return {
reset: a,
update: c,
digest: d,
digestString: function () {
for (var x = d(), y = "", C = 0; C < x.length; C++)
y += "0123456789ABCDEF".charAt(Math.floor(x[C] / 16)) + "0123456789ABCDEF".charAt(x[C] % 16);
return y;
}
};
}
const sapisid_cookie = getCookie('SAPISID') || getCookie('APISID') || getCookie('__Secure-3PAPISID');
if (sapisid_cookie) {
const timestamp = Math.floor(Date.now() / 1000);
b = Vja();
b.update(timestamp + ' ' + sapisid_cookie + ' https://www.youtube.com');
const hash_value = b.digestString().toLowerCase();
return 'SAPISIDHASH ' + timestamp + '_' + hash_value;
}
return '';
},
get_channel_id: function (retry = 0) {
const authorization = this.get_authorization();
if (!authorization) {
log('获取authorization失败', 0);
return;
}
const url = "https://www.youtube.com/youtubei/v1/account/account_menu";
const params = {
"prettyPrint": "false"
};
const data = {
"context": {
"client": {
"clientName": "WEB",
"clientVersion": "2.20240308.00.00",
},
},
};
const jsonData = JSON.stringify(data);
const headers = {
"authorization": authorization,
"content-type": "application/json",
"origin": "https://www.youtube.com",
"referer": "https://www.youtube.com/",
};
const requestConfig = {
method: 'POST',
headers: headers,
data: jsonData,
url: url + "?" + new URLSearchParams(params),
};
GM_xmlhttpRequest({
...requestConfig,
onload: function (response) {
const match = response.responseText.match(/"browseId"\:"(.*?)"/);
if (match && match.length > 1) {
let tmp_id = match[1];
if (tmp_id && tmp_id != channel_id) {
channel_id = tmp_id;
user_data = user_data_api.get();
GM_setValue('last_channel_id', channel_id);
}
log('获取channel_id成功' + channel_id, 0);
} else {
if (retry < 3) {
setTimeout(() => { yt_api.get_channel_id(retry + 1); }, 1000);
} else {
debugger;
log('获取channel_id失败', response, response.responseText, 0);
}
}
},
onerror: function (error) {
if (retry < 3) {
setTimeout(() => { yt_api.get_channel_id(retry + 1); }, 1000);
yt_api.get_channel_id(retry + 1);
} else {
log('获取channel_id失败', error, 0);
}
},
});
},
get_shorts_author: function (video_id) {
return new Promise((resolve, reject) => {
let basic_url, author_id_reg, author_name_reg;
if (page_type.startsWith('mobile')) {
basic_url = 'https://m.youtube.com/watch?&v=';
author_id_reg = /"channelId":"(.*?)"/;
author_name_reg = /"ownerChannelName":"(.*?)"/;
} else {
basic_url = 'https://www.youtube.com/shorts/';
author_id_reg = /"browseId":"([a-zA-Z0-9\-_]+)","canonicalBaseUrl"/;
author_name_reg = /"channel":\{"simpleText":"(.*?)"/;
}
const url = basic_url + video_id;
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader('accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7');
let author_id, author_name = '';
xhr.onload = function () {
if (xhr.status === 200) {
match = xhr.responseText.match(author_id_reg);
if (match && match.length > 1) author_id = match[1];
match = xhr.responseText.match(author_name_reg);
if (match && match.length > 1) author_name = match[1];
resolve([author_id, author_name]);
} else {
reject(xhr.responseText);
}
};
xhr.onerror = function () {
reject(new Error('XHR request failed'));
};
xhr.send();
});
},
};
}
function get_user_data_api() {
return {
get() {
const default_user_data = {
"open_recommend_shorts": 'off',
"open_recommend_movie": 'off',
"open_recommend_popular": 'off',
"open_recommend_liveroom": 'off',
"open_recommend_playables": "off",
"language": 'zh-CN',
"channel_infos": {
"ids": [],
"names": []
},
"shorts_list": [],
"login": false,
"shorts_parase_delay": 2000
};
let diff = false;
const tmp_user_data = GM_getValue(channel_id);
if (!tmp_user_data) {
tmp_user_data = default_user_data;
diff = true;
}
for (let key in default_user_data) {
if (!(key in tmp_user_data)) {
diff = true;
tmp_user_data[key] = default_user_data[key];
}
}
let tmp_login = channel_id !== 'default';
if (tmp_user_data.login !== tmp_login) {
diff = true;
tmp_user_data.login = tmp_login;
}
(diff || this.update(tmp_user_data)) && GM_setValue(channel_id, tmp_user_data);
return tmp_user_data;
},
set() {
return GM_setValue(channel_id, user_data);
},
update(tmp_user_data) {
let diff = false;
last_version = GM_getValue('last_version', -1);
if (last_version === -1) {
tmp_user_data.open_recommend_shorts = GM_getValue("open_recommend_shorts", "off");
tmp_user_data.open_recommend_movie = GM_getValue("open_recommend_movie", "off");
tmp_user_data.open_recommend_popular = GM_getValue("open_recommend_popular", "off");
tmp_user_data.open_recommend_liveroom = GM_getValue("open_recommend_liveroom", "off");
diff = true;
}
if (typeof (tmp_user_data.open_recommend_shorts) === 'boolean') {
tmp_user_data.open_recommend_shorts = user_data.open_recommend_shorts ? 'on' : 'off';
tmp_user_data.open_recommend_movie = user_data.open_recommend_movie ? 'on' : 'off';
tmp_user_data.open_recommend_popular = user_data.open_recommend_popular ? 'on' : 'off';
tmp_user_data.open_recommend_liveroom = user_data.open_recommend_liveroom ? 'on' : 'off';
diff = true;
}
last_version !== GM_info.script.version && GM_setValue("last_version", GM_info.script.version);
return diff;
}
};
}