From 2dbfe925e6bf217478548f4c12e50f2a7ebcd175 Mon Sep 17 00:00:00 2001 From: zhiyu1998 <542716863@qq.com> Date: Sat, 29 Jun 2024 14:59:19 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20=E5=A2=9E=E5=8A=A0=20dy=20?= =?UTF-8?q?=E5=8E=8B=E7=BC=A9=E6=A0=BC=E5=BC=8F=E7=9A=84=E8=87=AA=E7=94=B1?= =?UTF-8?q?=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 增加 dy 压缩格式选择 2. 优化使用 http 不使用安全格式 https(出问题再修正) --- apps/tools.js | 20 +++--- config/tools.yaml | 1 + guoba.support.js | 11 ++++ utils/kugou.js | 153 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 utils/kugou.js diff --git a/apps/tools.js b/apps/tools.js index 645f519..abfbfff 100644 --- a/apps/tools.js +++ b/apps/tools.js @@ -195,6 +195,8 @@ export class tools extends plugin { this.biliDuration = this.toolsConfig.biliDuration; // 加载抖音Cookie this.douyinCookie = this.toolsConfig.douyinCookie; + // 加载抖音是否压缩 + this.douyinCompression = this.toolsConfig.douyinCompression; // 翻译引擎 this.translateEngine = new Translate({ translateAppId: this.toolsConfig.translateAppId, @@ -277,16 +279,20 @@ export class tools extends plugin { if (urlType === "video") { // logger.info(item.video); // 多位面选择:play_addr、play_addr_265、play_addr_h264 - // H.265压缩率更高、流量省一半. 相对于H.264 let resUrl; - // 265 和 264 随机均衡负载 - if (Math.random() > 0.5) { - const videoAddrList = item.video.play_addr_265.url_list; - resUrl = videoAddrList[videoAddrList.length - 1 || 0]; + // 判断是否使用压缩格式 + const { play_addr_265, play_addr_h264, play_addr } = item.video; + if (this.douyinCompression === 1) { + // H.265压缩率更高、流量省一半. 相对于H.264 + // 265 和 264 随机均衡负载 + const videoAddrList = Math.random() > 0.5 ? play_addr_265.url_list : play_addr_h264.url_list; + resUrl = videoAddrList[0] || videoAddrList[videoAddrList.length - 1]; } else { - const videoAddrList = item.video.play_addr_h264.url_list; - resUrl = videoAddrList[videoAddrList.length - 1 || 0]; + // 原始格式,ps. videoAddrList 这里[0]、[1]是 http,[最后一个]是 https + const videoAddrList = play_addr.url_list; + resUrl = videoAddrList[0] || videoAddrList[videoAddrList.length - 1]; } + // logger.info(resUrl); const path = `${ this.getCurDownloadPath(e) }/temp.mp4`; await this.downloadVideo(resUrl).then(() => { diff --git a/config/tools.yaml b/config/tools.yaml index 0776534..cfc2daf 100644 --- a/config/tools.yaml +++ b/config/tools.yaml @@ -10,6 +10,7 @@ biliIntroLenLimit: 50 # 哔哩哔哩简介长度限制,填 0 或者 -1 可以 biliDuration: 480 # 哔哩哔哩限制的最大视频时长(默认8分钟),单位:秒 douyinCookie: '' # douyin's cookie, 格式:odin_tt=xxx;passport_fe_beating_status=xxx;sid_guard=xxx;uid_tt=xxx;uid_tt_ss=xxx;sid_tt=xxx;sessionid=xxx;sessionid_ss=xxx;sid_ucp_v1=xxx;ssid_ucp_v1=xxx;passport_assist_user=xxx;ttwid=xxx; +douyinCompression: 1 # 1-压缩,0-不压缩;是否使用压缩视频格式的抖音(默认使用),使用后加速视频发送 queueConcurrency: 1 # 【目前只涉及哔哩哔哩的下载】根据服务器性能设置可以并发下载的个数,如果你的服务器比较强劲,就选择4~12,较弱就一个一个下载,选择1 diff --git a/guoba.support.js b/guoba.support.js index 4cd5927..76c1f77 100644 --- a/guoba.support.js +++ b/guoba.support.js @@ -119,6 +119,17 @@ export function supportGuoba() { placeholder: "请输入抖音的Cookie", }, }, + { + field: "tools.douyinCompression", + label: "抖音是否使用压缩格式(1-压缩,0-不压缩)", + bottomHelpMessage: + "1-压缩,0-不压缩;是否使用压缩视频格式的抖音(默认使用),使用后加速视频发送", + component: "Input", + required: false, + componentProps: { + placeholder: "请输入1或者0(默认1)", + }, + }, { field: "tools.queueConcurrency", label: "允许多用户下载个数", diff --git a/utils/kugou.js b/utils/kugou.js new file mode 100644 index 0000000..5b851ff --- /dev/null +++ b/utils/kugou.js @@ -0,0 +1,153 @@ +// 获取MV信息的函数 +export async function getKugouMv(msg, page_limit, count_limit, n) { + const url = `https://mobiles.kugou.com/api/v3/search/mv?format=json&keyword=${encodeURIComponent( + msg + )}&page=${page_limit}&pagesize=${count_limit}&showtype=1`; + try { + const response = await fetch(url); + const json = await response.json(); + const info_list = json.data.info; + let data_list = []; + + if (n !== "") { + const info = info_list[n]; + const json_data2 = await getMvData(info.hash); + const mvdata_list = json_data2.mvdata; + + let mvdata = null; + if ("sq" in mvdata_list) { + mvdata = mvdata_list["sq"]; + } else if ("le" in mvdata_list) { + mvdata = mvdata_list["le"]; + } else if ("rq" in mvdata_list) { + mvdata = mvdata_list["rq"]; + } + + data_list = [ + { + name: info["filename"], + singername: info["singername"], + duration: new Date(info["duration"] * 1000) + .toISOString() + .substr(14, 5), + file_size: `${(mvdata["filesize"] / (1024 * 1024)).toFixed(2)} MB`, + mv_url: mvdata["downurl"], + cover_url: info["imgurl"].replace("/{size}", ""), + // 下面这些字段可能需要你从其他地方获取,因为它们不是直接从这个API返回的 + // "play_count": json.play_count, + // "like_count": json.like_count, + // "comment_count": json.comment_count, + // "collect_count": json.collect_count, + // "publish_date": json.publish_date + }, + ]; + } else { + data_list = info_list.map((info) => ({ + name: info["filename"], + singername: info["singername"], + duration: new Date(info["duration"] * 1000).toISOString().substr(14, 5), + cover_url: info["imgurl"].replace("/{size}", ""), + })); + } + + return data_list; + } catch (error) { + console.error("Error fetching MV data:", error); + return []; + } +} + +// 获取歌曲信息的函数 +export async function getKugouSong(msg, page_limit, count_limit, n) { + const url = `https://mobiles.kugou.com/api/v3/search/song?format=json&keyword=${encodeURIComponent( + msg + )}&page=${page_limit}&pagesize=${count_limit}&showtype=1`; + try { + const response = await fetch(url); + const json = await response.json(); + const info_list = json.data.info; + // console.log(info_list) + let data_list = []; + + if (n !== "") { + const info = info_list[n]; + const song_hash = info.hash; + let song_url = "付费歌曲暂时无法获取歌曲下载链接"; + let json_data2 = {}; + if (song_hash !== "") { + json_data2 = await getMp3Data(song_hash); + song_url = json_data2.error ? song_url : json_data2.url; + } + + data_list = [ + { + name: info.filename, + singername: info.singername, + duration: new Date(info.duration * 1000).toISOString().substr(14, 5), + file_size: `${(json_data2.fileSize / (1024 * 1024)).toFixed(2)} MB`, + song_url: song_url, + album_img: json_data2.album_img?.replace("/{size}", ""), + // "mv_url": await get_kugou_mv(msg, page_limit, count_limit, n) 这可能会导致递归调用,视具体情况而定 + }, + ]; + } else { + data_list = info_list.map((info) => ({ + name: info.filename, + singername: info.singername, + duration: new Date(info.duration * 1000).toISOString().substr(14, 5), + hash: info.hash, + mvhash: info.mvhash ? info.mvhash : null, + })); + } + + // 发送响应 + return { + code: 200, + text: "解析成功", + type: "歌曲解析", + now: new Date().toISOString(), + data: data_list, + }; + } catch (error) { + console.error("Error fetching song data:", error); + return { code: 500, text: "服务器内部错误" }; + } +} + +// 获取MP3数据的函数 +async function getMp3Data(song_hash) { + const url = `https://m.kugou.com/app/i/getSongInfo.php?hash=${song_hash}&cmd=playInfo`; + try { + const response = await fetch(url, { + headers: { + "User-Agent": "Mozilla/6.0 (Linux; Android 11; SAMSUNG SM-G973U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/14.2 Chrome/87.0.4280.141 Mobile Safari/537.36" + }, + redirect: 'follow', + method: 'GET', + }); + const json = await response.json(); + return json; + } catch (error) { + console.error("Error fetching MP3 data:", error); + return {}; + } +} + +// 获取MV数据的函数 +async function getMvData(mv_hash) { + const url = `http://m.kugou.com/app/i/mv.php?cmd=100&hash=${mv_hash}&ismp3=1&ext=mp4`; + try { + const response = await fetch(url, { + headers: { + "User-Agent": "Mozilla/6.0 (Linux; Android 11; SAMSUNG SM-G973U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/14.2 Chrome/87.0.4280.141 Mobile Safari/537.36" + }, + redirect: 'follow', + method: 'GET', + }); + const json = await response.json(); + return json; + } catch (error) { + console.error("Error fetching MV data:", error); + return {}; + } +}