const { spawn: spawn2 } = require('child_process'); const path = require('path'); const { cwd } = require('process'); const { readFile, createReadStream } = require("fs"); const { post } = require("axios"); const https = require('https') const fs = require('fs'); // 设置环境变量为自带的bin function spawn(exe, arg, config) { if (!config) { config = {} } config.env = { ...process.env } config.env.Path = [path.join(cwd(), '/bin'), path.join(cwd(), '/bin/MediaInfoCLI'), path.join(cwd(), '/bin/Transmission')].join(";") return spawn2(exe, arg, config) } function seep(time) { return new Promise((res) => { setTimeout(() => { res() }, time) }) } /** * 上传图片至图床 * @param filePath 图片路径 */ async function uploadImg(filePath) { let data = createReadStream(filePath) console.log(data) try { let res = await post('https://image.zmpt.cc/upload/localhost', { file: data }, { proxy: false, headers: { 'Content-Type': 'multipart/form-data' } }) console.log(res) return res.data } catch (err) { console.error(err) return err } } /** * 获取腾讯视频播放列表 * @param {String}cid 视频id * @returns {JSON} 播放列表等参数 */ function getTencentVideoPlayList(cid) { return new Promise((resolve) => { const lux = spawn("getTencentVideoPlayList.exe", [cid, 'vversion_name=8.2.95;', 1]) lux.stdout.on('data', (data) => { resolve(JSON.parse(String(data))) }); }) } /** * 获取视频截图 * @param {String} filePath 文件绝对路径 * @param {number} seconds 时间 * @param {string} save 保存绝对路径(含文件名) * @returns {Promise} 文件位置(待定) */ function getVideoSpecifyTimeImage(filePath, seconds, save) { return new Promise((resolve) => { const lux = spawn("ffmpeg", ['-ss', `${formatSeconds(seconds)}`, '-i', filePath, '-vframes', '1', save], { env: { path: path.join(cwd(), './bin/') } }) lux.stdout.on('data', (data) => { console.log(data) }); lux.on('close', (code) => { console.log("结束") console.log(code.toString()) resolve(save) }); lux.stderr.on("data", (err) => { console.log(String(err)) }) console.log(lux) }) } /** * 获取视频文件信息 * @param {String}filePath 文件绝对路径 * @return {Promise} videoInfo */ function getMediaInfo(filePath) { return new Promise((resolve) => { let all = "" const lux = spawn("MediaInfo.exe", ['--output=JSON', filePath]) lux.stdout.on('data', (data) => { all += String(data) }); lux.stdout.on('close', () => { console.log(all) resolve(JSON.parse(all)) }) }) } /** * 发布种子的获取视频文件信息 * @param {String}filePath 文件绝对路径 * @return {Promise} videoInfo */ function getMediaInfoSend(filePath) { return new Promise((resolve) => { let all = "" const lux = spawn("MediaInfo.exe", [filePath]) lux.stdout.on('data', (data) => { all += String(data) }); lux.stdout.on('close', () => { resolve(all) }) }) } /** * 制种 * @param {String}filePath 文件绝对路径 * @param {String}save 保存绝对路径(含文件名) * @return {Promise} 日志 */ function createTorrent(filePath, save) { return new Promise((resolve) => { const lux = spawn("transmission-create", [filePath, '-p', '-t https://zmpt.cc/announce.php', '-o', save]) let response = ''; lux.stdout.on('data', (data) => { response += data }); lux.stdout.on('close', () => { resolve(response) }) }) } function dow(info, callback) { console.log(['--cookies-from-browser', 'chrome', '-P', info.save, '-o', info.title + '.mp4', info.url].join(" ")) const lux = spawn("yt-dlp", ['--cookies-from-browser', 'chrome', '-P', info.save, '-o', info.title + '.mp4', info.url], { env: { path: path.join(cwd(), './bin/') } }) lux.stdout.on('data', (data) => { console.log(String(data)) callback(String(data), false) }); lux.on('close', (code) => { console.log("结束") callback(code, true) }); } /** * 秒到时分秒 * @param value 秒 * @return {string|number} 返回时间格式[00:00:00] */ function formatSeconds(value) { var secondTime = parseInt(value);// 秒 var minuteTime = 0;// 分 var hourTime = 0;// 小时 if (secondTime > 60) {//如果秒数大于60,将秒数转换成整数 //获取分钟,除以60取整数,得到整数分钟 minuteTime = parseInt(secondTime / 60); //获取秒数,秒数取佘,得到整数秒数 secondTime = parseInt(secondTime % 60); //如果分钟大于60,将分钟转换成小时 if (minuteTime > 60) { //获取小时,获取分钟除以60,得到整数小时 hourTime = parseInt(minuteTime / 60); //获取小时后取佘的分,获取分钟除以60取佘的分 minuteTime = parseInt(minuteTime % 60); } } var result = "" + secondTime >= 10 ? secondTime : '0' + secondTime; if (minuteTime > 0) { result = "" + (minuteTime >= 10 ? minuteTime : '0' + minuteTime) + ":" + result; } else { result = "" + "00" + ":" + result; } if (hourTime > 0) { result = "" + (hourTime >= 10 ? hourTime : '0' + hourTime) + ":" + result; } else { result = "" + "00" + ":" + result; } return result; } /** * 判断文件是否存在 * @param {string} filePath 文件路径 * @returns {boolean} true存在,false不存在 */ function fileIsExist(filePath) { if (fs.existsSync(filePath)) { return true } else { return false } } /** * 删除文件夹 * @param {string} filePath 删除文件夹 */ function deleteFolder(filePath) { const files = [] if (fs.existsSync(filePath)) { const files = fs.readdirSync(filePath) files.forEach((file) => { const nextFilePath = `${filePath}/${file}` const states = fs.statSync(nextFilePath) if (states.isDirectory()) { //recurse deleteFolder(nextFilePath) } else { //delete file fs.unlinkSync(nextFilePath) } }) fs.rmdirSync(filePath) } } /** * 移动文件夹下的所有文件(不包括文件夹) * @param {string} sourceFolder 源文件夹 * @param {string} targetFolder 目标文件夹 */ function moveDir(sourceFolder,targetFolder ){ try { // 读取源文件夹中的所有文件 const files = fs.readdirSync(sourceFolder); // 遍历源文件夹中的文件 files.forEach(file => { // 构建源文件和目标文件的完整路径 const sourcePath = path.join(sourceFolder, file); const targetPath = path.join(targetFolder, file); // 移动文件 fs.renameSync(sourcePath, targetPath); console.log(`成功移动文件 ${file}`); }); } catch (err) { console.error('无法读取源文件夹或移动文件:', err); } } module.exports = { seep, dow, getVideoSpecifyTimeImage, getMediaInfo, createTorrent, getTencentVideoPlayList, uploadImg, spawn, fileIsExist, getMediaInfoSend, deleteFolder, moveDir }