Skip to content

Commit 5ff5ad0

Browse files
committed
update:更新版本号,改了点细节
1 parent ae4e604 commit 5ff5ad0

14 files changed

+382
-54
lines changed

Diff for: .env.development

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
NODE_ENV=production
2+
3+
# just a flag
4+
ENV='staging'
5+
6+
7+
LOG_WITH_FILE = 1
8+
# trace/debug/info/warn/error/fatal
9+
LOG_LEVEL = info

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ nodejs作为服务端的drpy实现。全面升级异步写法
88
* [代码加解密工具](/admin/encoder)
99
* [V我50支付凭证生成器](/authcoder?len=10&number=1)
1010
* [接口压测教程](/docs/httpTest.md)
11+
* [央视点播解析工具](/proxy/央视大全[官]/index.html)
1112

1213
## 更新记录
1314

Diff for: controllers/fastlogger.js

+42-47
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ import pino from "pino";
44
import Fastify from "fastify";
55
import {fileURLToPath} from 'url';
66
import {createStream} from 'rotating-file-stream';
7+
import dotenv from 'dotenv';
8+
9+
dotenv.config(); //加载 .env 文件
10+
11+
const LOG_WITH_FILE = process.env.LOG_WITH_FILE;
12+
const LOG_LEVEL = process.env.LOG_LEVEL && ['trace', 'debug', 'info', 'warn', 'error', 'fatal'].includes(process.env.LOG_LEVEL) ? process.env.LOG_LEVEL : 'info';
13+
console.log('LOG_WITH_FILE:', LOG_WITH_FILE);
14+
console.log('LOG_LEVEL:', LOG_LEVEL);
15+
let _logger = true;
716

8-
const __filename = fileURLToPath(import.meta.url);
9-
const __dirname = path.dirname(__filename);
10-
const logDirectory = path.join(__dirname, '../logs');
11-
if (!fs.existsSync(logDirectory)) {
12-
fs.mkdirSync(logDirectory);
13-
}
1417
// 自定义时间戳函数,格式为 YYYY-MM-DD HH:mm:ss
1518
const customTimestamp = () => {
1619
const now = new Date();
@@ -24,48 +27,40 @@ const customTimestamp = () => {
2427
return `,"time":"${formattedTime}"`; // 返回格式化后的时间戳
2528
};
2629

27-
// const logStream = fs.createWriteStream(path.join(logDirectory, 'output.log'), {
28-
// flags: 'a',
29-
// encoding: 'utf8',
30-
// });
31-
// 配置日志文件的轮转
32-
33-
const logStream = createStream(path.join(logDirectory, 'output.log'), {
34-
size: '500M', // 设置最大文件大小为 500MB
35-
compress: true, // 自动压缩旧的日志文件
36-
encoding: 'utf8', // 设置日志文件的编码为 utf8
37-
interval: '1d' // 每天轮转一次日志
38-
});
39-
export const fileLogger = pino(
40-
{
41-
// 使用标准的时间戳函数并格式化为 ISO 格式
42-
// timestamp: pino.stdTimeFunctions.isoTime,
30+
if (LOG_WITH_FILE) {
31+
const __filename = fileURLToPath(import.meta.url);
32+
const __dirname = path.dirname(__filename);
33+
const logDirectory = path.join(__dirname, '../logs');
34+
if (!fs.existsSync(logDirectory)) {
35+
fs.mkdirSync(logDirectory);
36+
}
37+
const logStream = createStream(path.join(logDirectory, 'output.log'), {
38+
size: '500M', // 设置最大文件大小为 500MB
39+
compress: true, // 自动压缩旧的日志文件
40+
encoding: 'utf8', // 设置日志文件的编码为 utf8
41+
interval: '1d' // 每天轮转一次日志
42+
});
43+
_logger = pino({
44+
level: LOG_LEVEL, // 设置记录的最低日志级别
45+
serializers: {
46+
req: pino.stdSerializers.req, // 标准请求序列化器
47+
res: pino.stdSerializers.res, // 标准响应序列化器
48+
},
49+
timestamp: customTimestamp,
50+
}, logStream);
51+
console.log('日志输出到文件');
52+
} else {
53+
_logger = pino({
54+
level: LOG_LEVEL, // 设置记录的最低日志级别
55+
serializers: {
56+
req: pino.stdSerializers.req, // 标准请求序列化器
57+
res: pino.stdSerializers.res, // 标准响应序列化器
58+
},
4359
timestamp: customTimestamp,
44-
},
45-
logStream
46-
);
60+
});
61+
console.log('日志输出到控制台');
62+
}
4763

48-
// 创建两个 logger 实例
49-
const consoleLogger = pino({
50-
level: "debug", // 设置记录的最低日志级别
51-
serializers: {
52-
req: pino.stdSerializers.req, // 标准请求序列化器
53-
res: pino.stdSerializers.res, // 标准响应序列化器
54-
},
55-
// timestamp: pino.stdTimeFunctions.isoTime,
56-
timestamp: customTimestamp,
57-
// transport: {
58-
// target: 'pino-pretty',
59-
// options: {
60-
// translateTime: true,
61-
// singleLine: true, // 强制单行输出
62-
// colorize: false, // 禁用颜色,保持纯 JSON
63-
// ignore: 'reqId,remoteAddress,remotePort',
64-
// },
65-
// },
66-
}, logStream);
67-
// const fastify = Fastify({logger: true});
68-
// 初始化 Fastify 实例,使用 consoleLogger 输出控制台日志
6964
export const fastify = Fastify({
70-
logger: consoleLogger,
65+
logger: _logger,
7166
});

Diff for: data/cntv/index.html

+258
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Video Parser by 道长</title>
7+
<link rel="icon" href="/public/icon.svg" type="image/x-icon">
8+
<style>
9+
* {
10+
box-sizing: border-box;
11+
}
12+
13+
body {
14+
display: flex;
15+
justify-content: center;
16+
align-items: center;
17+
min-height: 100vh;
18+
margin: 0;
19+
font-family: Arial, sans-serif;
20+
background-color: #f4f7fa;
21+
}
22+
23+
.container {
24+
width: 100%;
25+
max-width: 600px;
26+
padding: 30px;
27+
background-color: #fff;
28+
border-radius: 8px;
29+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
30+
text-align: center;
31+
}
32+
33+
.container h2 {
34+
margin-bottom: 10px;
35+
font-size: 22px;
36+
color: #333;
37+
}
38+
39+
.container p {
40+
font-size: 16px;
41+
color: #666;
42+
margin-bottom: 20px;
43+
}
44+
45+
.input-group {
46+
position: relative;
47+
display: flex;
48+
align-items: center;
49+
margin-bottom: 15px;
50+
}
51+
52+
textarea {
53+
width: 100%;
54+
min-height: 60px;
55+
padding: 12px;
56+
font-size: 16px;
57+
border: 1px solid #ddd;
58+
border-radius: 4px;
59+
outline: none;
60+
resize: none;
61+
line-height: 1.5;
62+
overflow-y: auto;
63+
}
64+
65+
.clear-button {
66+
position: absolute;
67+
bottom: 8px;
68+
right: 8px;
69+
background: #ff6b6b;
70+
border: none;
71+
border-radius: 50%;
72+
width: 24px;
73+
height: 24px;
74+
cursor: pointer;
75+
font-weight: bold;
76+
color: #fff;
77+
display: flex;
78+
align-items: center;
79+
justify-content: center;
80+
transition: background-color 0.3s;
81+
opacity: 0.8;
82+
}
83+
84+
.clear-button:hover {
85+
background-color: #ff4949;
86+
}
87+
88+
.button-group {
89+
display: flex;
90+
justify-content: center;
91+
gap: 10px;
92+
margin-top: 10px;
93+
}
94+
95+
button {
96+
padding: 10px 24px;
97+
font-size: 16px;
98+
color: #fff;
99+
background-color: #007bff;
100+
border: none;
101+
border-radius: 4px;
102+
cursor: pointer;
103+
transition: background-color 0.3s;
104+
}
105+
106+
button:hover {
107+
background-color: #0056b3;
108+
}
109+
110+
.example-button {
111+
font-size: 16px;
112+
color: #333;
113+
background-color: #f1f1f1;
114+
border: 1px solid #ddd;
115+
border-radius: 4px;
116+
padding: 10px 20px;
117+
cursor: pointer;
118+
transition: background-color 0.3s;
119+
}
120+
121+
.example-button:hover {
122+
background-color: #e2e2e2;
123+
}
124+
125+
.result {
126+
margin-top: 20px;
127+
padding: 15px;
128+
font-size: 16px;
129+
color: #333;
130+
background-color: #f9f9f9;
131+
border: 1px solid #ddd;
132+
border-radius: 4px;
133+
position: relative;
134+
word-break: break-all;
135+
text-align: left;
136+
}
137+
138+
.copy-button {
139+
position: absolute;
140+
bottom: 8px;
141+
right: 8px;
142+
padding: 6px 12px;
143+
font-size: 14px;
144+
color: #333;
145+
background-color: #e6e6e6;
146+
border: none;
147+
border-radius: 4px;
148+
cursor: pointer;
149+
opacity: 0.8;
150+
}
151+
152+
.copy-button:hover {
153+
background-color: #d4d4d4;
154+
}
155+
</style>
156+
</head>
157+
<body>
158+
<div class="container">
159+
<h2>视频直链解析器 v1.0.2 2024/11/26</h2>
160+
<p>请输入抓包获取的央视网点播视频直链</p>
161+
<div class="input-group">
162+
<textarea id="urlInput" placeholder="输入网页链接"></textarea>
163+
<button class="clear-button" onclick="clearInput()">×</button>
164+
</div>
165+
<div class="button-group">
166+
<button onclick="parseUrl()">解析</button>
167+
<button class="example-button" onclick="fillExample1()">示例地址1</button>
168+
<button class="example-button" onclick="fillExample2()">示例地址2</button>
169+
</div>
170+
<div id="result" class="result" style="display: none;">
171+
<span id="parsedUrl"></span>
172+
<button class="copy-button" onclick="copyToClipboard()">复制</button>
173+
</div>
174+
</div>
175+
176+
<script>
177+
function parseUrl() {
178+
const inputUrl = document.getElementById("urlInput").value.trim();
179+
const resultDiv = document.getElementById("result");
180+
const parsedUrlSpan = document.getElementById("parsedUrl");
181+
182+
if (!inputUrl) {
183+
resultDiv.style.display = 'none';
184+
alert("请输入有效的链接");
185+
return;
186+
}
187+
188+
try {
189+
const baseUrl = `${location.origin}/proxy/央视大全[官]/asp/h5e/hls`;
190+
const regex = /\/asp\/(?:h5e\/)?hls\/(.+)/;
191+
const match = inputUrl.match(regex);
192+
193+
if (match) {
194+
const proxyUrl = `${baseUrl}/${match[1]}`;
195+
parsedUrlSpan.textContent = proxyUrl;
196+
resultDiv.style.display = 'block';
197+
} else {
198+
resultDiv.style.display = 'none';
199+
alert("链接格式无效,请输入包含 /asp/h5e 或 /asp/hls 的链接");
200+
}
201+
} catch (error) {
202+
resultDiv.style.display = 'none';
203+
alert("处理链接时出错,请检查输入格式");
204+
}
205+
}
206+
207+
function copyToClipboard() {
208+
const parsedUrl = document.getElementById("parsedUrl").textContent;
209+
copyText(parsedUrl);
210+
}
211+
212+
function copyText(str) {
213+
if (navigator.clipboard && window.isSecureContext) {
214+
navigator.clipboard.writeText(str).then(() => {
215+
alert("链接已通过第1种方式复制到剪贴板");
216+
}, () => {
217+
alert("复制失败,请手动复制");
218+
});
219+
} else {
220+
let textArea = document.createElement("textarea");
221+
textArea.value = str;
222+
textArea.style.position = "absolute";
223+
textArea.style.opacity = 0;
224+
textArea.style.left = "-999999px";
225+
textArea.style.top = "-999999px";
226+
document.body.appendChild(textArea);
227+
textArea.focus();
228+
textArea.select();
229+
let res = new Promise((res, rej) => {
230+
res(() => {
231+
document.execCommand('copy');
232+
textArea.remove();
233+
});
234+
rej(false);
235+
});
236+
res.then((res) => {
237+
res();
238+
alert("链接已通过第2种方式复制到剪贴板");
239+
})
240+
}
241+
242+
}
243+
244+
function fillExample1() {
245+
document.getElementById("urlInput").value = "https://dh5.cntv.myalicdn.com/asp/h5e/hls/2000/0303000a/3/default/7048673ae21f4929a30701318754497b/2000.m3u8";
246+
}
247+
248+
function fillExample2() {
249+
document.getElementById("urlInput").value = "https://hls09.cntv.myhwcdn.cn/asp/hls/2000/0303000a/3/default/d9b0eaa065934f25abd193d391f731b6/2000.m3u8";
250+
}
251+
252+
function clearInput() {
253+
document.getElementById("urlInput").value = "";
254+
document.getElementById("result").style.display = "none";
255+
}
256+
</script>
257+
</body>
258+
</html>

0 commit comments

Comments
 (0)