Files
cat-catch/js/pupup-utils.js
ChuXun 53f9554f38 1
2025-10-19 20:55:27 +08:00

232 lines
7.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 复制选项
function copyLink(data) {
let text = data.url;
if (data.parsing == "m3u8") {
text = G.copyM3U8;
} else if (data.parsing == "mpd") {
text = G.copyMPD;
} else {
text = G.copyOther;
}
return templates(text, data);
}
function isM3U8(data) {
return (
data.ext == "m3u8" ||
data.ext == "m3u" ||
data.type?.endsWith("/vnd.apple.mpegurl") ||
data.type?.endsWith("/x-mpegurl") ||
data.type?.endsWith("/mpegurl") ||
data.type?.endsWith("/octet-stream-m3u8")
)
}
function isMPD(data) {
return (data.ext == "mpd" ||
data.type == "application/dash+xml"
)
}
function isJSON(data) {
return (data.ext == "json" ||
data.type == "application/json" ||
data.type == "text/json"
)
}
function isPicture(data) {
return (data.type?.startsWith("image/") ||
data.ext == "jpg" ||
data.ext == "png" ||
data.ext == "jpeg" ||
data.ext == "bmp" ||
data.ext == "gif" ||
data.ext == "webp" ||
data.ext == "svg"
)
}
function isMediaExt(ext) {
return ['ogg', 'ogv', 'mp4', 'webm', 'mp3', 'wav', 'm4a', '3gp', 'mpeg', 'mov', 'm4s', 'aac'].includes(ext);
}
function isMedia(data) {
return isMediaExt(data.ext) || data.type?.startsWith("video/") || data.type?.startsWith("audio/");
}
/**
* ari2a RPC发送一套资源
* @param {object} data 资源对象
* @param {Function} success 成功运行函数
* @param {Function} error 失败运行函数
*/
function aria2AddUri(data, success, error) {
const json = {
"jsonrpc": "2.0",
"id": "cat-catch-" + data.requestId,
"method": "aria2.addUri",
"params": []
};
if (G.aria2RpcToken) {
json.params.push(`token:${G.aria2RpcToken}`);
}
const params = { out: data.downFileName };
if (G.enableAria2RpcReferer) {
params.header = [];
params.header.push(G.userAgent ? G.userAgent : navigator.userAgent);
if (data.requestHeaders?.referer) {
params.header.push("Referer: " + data.requestHeaders.referer);
}
if (data.cookie) {
params.header.push("Cookie: " + data.cookie);
}
if (data.requestHeaders?.authorization) {
params.header.push("Authorization: " + data.requestHeaders.authorization);
}
}
json.params.push([data.url], params);
fetch(G.aria2Rpc, {
method: "POST",
headers: {
"Content-Type": "application/json; charset=utf-8"
},
body: JSON.stringify(json)
}).then(response => {
return response.json();
}).then(data => {
success && success(data);
}).catch(errMsg => {
error && error(errMsg);
});
}
// MQTT 相关功能
/**
* 发送数据到 MQTT 服务器
* @param {Object} data - 要发送的媒体数据
* @returns {Promise} - 返回发送结果的 Promise
*/
function sendToMQTT(data, config) {
return new Promise((resolve, reject) => {
if (!G.mqttEnable) {
reject("MQTT is not enabled");
return;
}
// 使用配置的标题长度如果未设置则默认为100
const titleLength = G.mqttTitleLength || 100;
data.title = data.title.slice(0, titleLength) || "";
data.action = "media_found";
data = trimData(data);
// 创建 MQTT 连接并发送数据
connectAndSendMQTT(data, config)
.then(() => {
resolve(true);
})
.catch((error) => {
console.error("MQTT send error:", error);
reject("MQTT send failed: " + error.message);
});
});
}
/**
* 连接到 MQTT 服务器并发送消息
* @param {Object} data - 要发送的数据
* @returns {Promise} - 连接和发送的 Promise
*/
function connectAndSendMQTT(data, config) {
return new Promise((resolve, reject) => {
try {
// 构建 MQTT 连接 URL
const protocol = G.mqttProtocol;
const broker = G.mqttBroker;
const port = G.mqttPort;
const path = G.mqttPath;
if (!protocol || !broker || !port || !path) {
throw new Error("MQTT connection parameters are missing");
}
const mqttUrl = `${protocol}://${broker}:${port}${path}`;
// 创建 MQTT 客户端选项
const options = {
clientId: `${G.mqttClientId || "cat-catch-client"}-${Math.random().toString(16).slice(2)}`,
clean: true,
connectTimeout: 10000,
reconnectPeriod: 0 // 不自动重连,用完即断
};
// 添加用户名和密码(如果有)
if (G.mqttUser) {
options.username = G.mqttUser;
}
if (G.mqttPassword) {
options.password = G.mqttPassword;
}
const mqttLib = window.mqtt || (typeof mqtt !== 'undefined' ? mqtt : null);
if (!mqttLib) {
throw new Error("MQTT library not found. Please check if lib/mqtt.min.js is loaded correctly.");
}
if (!mqttLib.connect) {
throw new Error("MQTT.connect method not found. Available methods: " + Object.keys(mqttLib));
}
// 如果提供了提示回调函数,则使用它
if (typeof config?.alert === 'function') {
Tips = config.alert;
}
// 2. 创建连接阶段提示:正在连接 MQTT 服务器
Tips(i18n.connectingToMQTT || "Connecting to MQTT server...", 2000);
const client = mqttLib.connect(mqttUrl, options);
// 连接成功
client.on('connect', () => {
const topic = G.mqttTopic || "cat-catch/media";
const qos = parseInt(G.mqttQos) || 2;
// 处理自定义数据格式
let message;
if (G.mqttDataFormat?.trim()) {
message = templates(G.mqttDataFormat, data);
} else {
// 使用默认JSON格式
message = JSON.stringify(data);
}
// 3. 正在发送消息到 MQTT 服务器
Tips(i18n.sendingMessageToMQTT || "Sending message to MQTT server...", 2000);
// 发送消息
client.publish(topic, message, { qos: qos }, (error) => {
if (error) {
console.error("MQTT publish error:", error);
reject(error);
} else {
resolve();
}
});
});
// 连接错误
client.on('error', (error) => {
console.error("MQTT connection error:", error);
reject(error);
});
// 连接超时
setTimeout(() => {
if (!client.connected) {
client.end();
reject(new Error("MQTT connection timeout"));
}
}, 6000);
// client.on('close', () => {
// console.log('MQTT connection closed');
// });
} catch (error) {
console.error("MQTT setup error:", error);
reject(error);
}
});
}