mb-rrvideo-server 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCKER.md +7 -0
- package/Dockerfile +8 -3
- package/config.example.json +10 -4
- package/ecosystem.docker.config.js +2 -1
- package/package.json +2 -1
- package/src/config.js +10 -2
- package/src/storage.js +60 -1
package/DOCKER.md
CHANGED
package/Dockerfile
CHANGED
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
FROM node:22-slim
|
|
8
8
|
|
|
9
|
+
# 设置代理参数(可从构建参数传入,也可在此处直接定义默认值)
|
|
10
|
+
# 如果不想每次构建都传参,可以在这里写死默认值
|
|
11
|
+
ARG HTTP_PROXY="http://172.168.1.117:10809"
|
|
12
|
+
ARG HTTPS_PROXY="http://172.168.1.117:10809"
|
|
13
|
+
|
|
9
14
|
# 设置环境变量
|
|
10
15
|
ENV TZ=Asia/Shanghai \
|
|
11
16
|
NODE_ENV=production \
|
|
@@ -70,10 +75,10 @@ RUN npm install -g --verbose --ignore-scripts \
|
|
|
70
75
|
|
|
71
76
|
# ============================================
|
|
72
77
|
# 第六步:安装 Playwright 浏览器(Chromium)
|
|
73
|
-
#
|
|
78
|
+
# 使用构建参数中的代理(只在此步骤生效)
|
|
74
79
|
# ============================================
|
|
75
|
-
RUN export
|
|
76
|
-
export
|
|
80
|
+
RUN export HTTP_PROXY=$HTTP_PROXY && \
|
|
81
|
+
export HTTPS_PROXY=$HTTPS_PROXY && \
|
|
77
82
|
npx playwright install chromium
|
|
78
83
|
|
|
79
84
|
# ============================================
|
package/config.example.json
CHANGED
|
@@ -7,23 +7,29 @@
|
|
|
7
7
|
|
|
8
8
|
// 存储配置
|
|
9
9
|
"storage": {
|
|
10
|
-
"type": "
|
|
10
|
+
"type": "aliyun", // 存储类型: "local" 或 "minio"
|
|
11
11
|
|
|
12
12
|
// 本地存储配置
|
|
13
13
|
"local": {
|
|
14
14
|
"video_dir": "./Video", // 视频存储目录
|
|
15
15
|
"temp_dir": "./temp" // 临时文件目录
|
|
16
16
|
},
|
|
17
|
+
"aliyun":{
|
|
18
|
+
"accessKeyId": "",
|
|
19
|
+
"accessKeySecret": "",
|
|
20
|
+
"endpoint": "",
|
|
21
|
+
"bucket": ""
|
|
22
|
+
},
|
|
17
23
|
|
|
18
24
|
// MinIO 对象存储配置
|
|
19
25
|
"minio": {
|
|
20
|
-
"endpoint": "
|
|
26
|
+
"endpoint": "",
|
|
21
27
|
"port": 9000,
|
|
22
28
|
"useSSL": false,
|
|
23
29
|
"accessKey": "your-access-key",
|
|
24
30
|
"secretKey": "your-secret-key",
|
|
25
|
-
"bucket": "
|
|
26
|
-
"
|
|
31
|
+
"bucket": "",
|
|
32
|
+
"publicHost": ""
|
|
27
33
|
}
|
|
28
34
|
},
|
|
29
35
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mb-rrvideo-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "视频转码服务 - 接收可回溯机请求,执行转码/合并,上传MinIO/本地存储",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"author": "",
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
|
+
"ali-oss": "^6.23.0",
|
|
38
39
|
"minio": "^7.1.3"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
package/src/config.js
CHANGED
|
@@ -138,8 +138,8 @@ class ConfigManager {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
const storageType = this.config.storage.type;
|
|
141
|
-
if (storageType !== 'local' && storageType !== 'minio') {
|
|
142
|
-
throw new Error('storage.type 必须是 local 或
|
|
141
|
+
if (storageType !== 'local' && storageType !== 'minio' && storageType !== 'aliyun') {
|
|
142
|
+
throw new Error('storage.type 必须是 local, minio 或 aliyun');
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
// 如果使用 MinIO,验证 MinIO 配置
|
|
@@ -150,6 +150,14 @@ class ConfigManager {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
// 如果使用 Aliyun OSS,验证 Aliyun OSS 配置
|
|
154
|
+
if (storageType === 'aliyun') {
|
|
155
|
+
const aliyun = this.config.storage.aliyun;
|
|
156
|
+
if (!aliyun || !aliyun.accessKeyId || !aliyun.accessKeySecret || !aliyun.endpoint || !aliyun.bucket) {
|
|
157
|
+
throw new Error('阿里云 OSS 配置不完整');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
153
161
|
console.log('[Config] 配置验证通过');
|
|
154
162
|
console.log('[Config] 存储类型:', storageType);
|
|
155
163
|
}
|
package/src/storage.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const Minio = require('minio');
|
|
4
|
+
const OSS = require('ali-oss');
|
|
4
5
|
const config = require('./config');
|
|
5
6
|
|
|
6
7
|
class StorageManager {
|
|
7
8
|
constructor() {
|
|
8
9
|
this.storageType = null;
|
|
9
10
|
this.minioClient = null;
|
|
11
|
+
this.ossClient = null;
|
|
10
12
|
this.init();
|
|
11
13
|
}
|
|
12
14
|
|
|
@@ -24,6 +26,17 @@ class StorageManager {
|
|
|
24
26
|
secretKey: minioConfig.secretKey
|
|
25
27
|
});
|
|
26
28
|
console.log('[Storage] MinIO 客户端已初始化');
|
|
29
|
+
} else if (this.storageType === 'aliyun') {
|
|
30
|
+
const aliyunConfig = storageConfig.aliyun;
|
|
31
|
+
this.ossClient = new OSS({
|
|
32
|
+
// region: aliyunConfig.region || 'oss-cn-hangzhou', // 默认为杭州,或者从endpoint解析
|
|
33
|
+
accessKeyId: aliyunConfig.accessKeyId,
|
|
34
|
+
accessKeySecret: aliyunConfig.accessKeySecret,
|
|
35
|
+
bucket: aliyunConfig.bucket,
|
|
36
|
+
endpoint: aliyunConfig.endpoint,
|
|
37
|
+
secure: true // 默认使用 HTTPS
|
|
38
|
+
});
|
|
39
|
+
console.log('[Storage] 阿里云 OSS 客户端已初始化');
|
|
27
40
|
} else {
|
|
28
41
|
console.log('[Storage] 使用本地存储');
|
|
29
42
|
}
|
|
@@ -64,6 +77,8 @@ class StorageManager {
|
|
|
64
77
|
|
|
65
78
|
if (this.storageType === 'minio') {
|
|
66
79
|
return await this.uploadToMinio(localPath, remotePath);
|
|
80
|
+
} else if (this.storageType === 'aliyun') {
|
|
81
|
+
return await this.uploadToOss(localPath, remotePath);
|
|
67
82
|
} else {
|
|
68
83
|
return await this.saveToLocal(localPath, remotePath);
|
|
69
84
|
}
|
|
@@ -95,7 +110,7 @@ class StorageManager {
|
|
|
95
110
|
await this.minioClient.fPutObject(bucket, remotePath, localPath, metaData);
|
|
96
111
|
|
|
97
112
|
// 生成公网访问 URL
|
|
98
|
-
const publicHost = minioConfig.
|
|
113
|
+
const publicHost = minioConfig.publicHost;
|
|
99
114
|
const videoUrl = `${publicHost}/${bucket}/${remotePath}`;
|
|
100
115
|
|
|
101
116
|
console.log('[Storage] MinIO 上传成功:', videoUrl);
|
|
@@ -106,6 +121,50 @@ class StorageManager {
|
|
|
106
121
|
}
|
|
107
122
|
}
|
|
108
123
|
|
|
124
|
+
/**
|
|
125
|
+
* 上传到 阿里云 OSS
|
|
126
|
+
*/
|
|
127
|
+
async uploadToOss(localPath, remotePath) {
|
|
128
|
+
try {
|
|
129
|
+
// 检查文件是否存在
|
|
130
|
+
if (!fs.existsSync(localPath)) {
|
|
131
|
+
throw new Error(`本地文件不存在: ${localPath}`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 上传选项
|
|
135
|
+
const headers = {
|
|
136
|
+
// 指定Object的存储类型。
|
|
137
|
+
'x-oss-storage-class': 'Standard',
|
|
138
|
+
// 指定Object的访问权限。
|
|
139
|
+
'x-oss-object-acl': 'public-read', // 通常视频需要公共读权限以便播放
|
|
140
|
+
// 指定PutObject操作时是否覆盖同名目标Object。此处设置为true,表示禁止覆盖同名Object。
|
|
141
|
+
'x-oss-forbid-overwrite': 'false', // 允许覆盖
|
|
142
|
+
'Content-Type': 'video/mp4'
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const result = await this.ossClient.put(remotePath, path.normalize(localPath), { headers });
|
|
146
|
+
|
|
147
|
+
// 生成访问 URL
|
|
148
|
+
// 优先使用 result.url,如果配置了自定义域名(publicHost)则使用自定义域名
|
|
149
|
+
const aliyunConfig = config.get('storage.aliyun');
|
|
150
|
+
let videoUrl = result.url;
|
|
151
|
+
|
|
152
|
+
if (aliyunConfig.publicHost) {
|
|
153
|
+
// 确保 publicHost 不带末尾斜杠
|
|
154
|
+
const host = aliyunConfig.publicHost.replace(/\/$/, '');
|
|
155
|
+
// 确保 remotePath 不带开头斜杠
|
|
156
|
+
const key = remotePath.replace(/^\//, '');
|
|
157
|
+
videoUrl = `${host}/${key}`;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
console.log('[Storage] 阿里云 OSS 上传成功:', videoUrl);
|
|
161
|
+
return videoUrl;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error('[Storage] 阿里云 OSS 上传失败:', error.message);
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
109
168
|
/**
|
|
110
169
|
* 保存到本地
|
|
111
170
|
*/
|