vod-js-sdk-v6 1.7.4 → 1.8.0
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/lib/package.json +2 -1
- package/lib/src/uploader.d.ts +1 -1
- package/lib/src/uploader.js +79 -44
- package/package.json +3 -2
- package/src/uploader.ts +114 -82
package/lib/package.json
CHANGED
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/tencentyun/vod-js-sdk-v6#readme",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"aws-sdk": "^
|
|
34
|
+
"@aws-sdk/client-s3": "^3.1010.0",
|
|
35
|
+
"@aws-sdk/lib-storage": "^3.1010.0",
|
|
35
36
|
"axios": "^0.21.1",
|
|
36
37
|
"eventemitter3": "^4.0.7",
|
|
37
38
|
"js-sha1": "^0.6.0",
|
package/lib/src/uploader.d.ts
CHANGED
|
@@ -119,8 +119,8 @@ declare class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
119
119
|
commitRequestRetryCount: number;
|
|
120
120
|
retryDelay: number;
|
|
121
121
|
targetAccelerate: boolean;
|
|
122
|
-
expireTime: string;
|
|
123
122
|
storageType: string;
|
|
123
|
+
expireTime: string;
|
|
124
124
|
static host: HOST;
|
|
125
125
|
constructor(params: UploaderOptions);
|
|
126
126
|
getCosStrategy(params: UploaderOptions): {};
|
package/lib/src/uploader.js
CHANGED
|
@@ -66,14 +66,24 @@ exports.UploaderEvent = exports.vodAxios = void 0;
|
|
|
66
66
|
var sha1 = require("js-sha1");
|
|
67
67
|
var COS = require("./base.js");
|
|
68
68
|
var eventemitter3_1 = require("eventemitter3");
|
|
69
|
-
var
|
|
69
|
+
var client_s3_1 = require("@aws-sdk/client-s3");
|
|
70
|
+
var lib_storage_1 = require("@aws-sdk/lib-storage");
|
|
70
71
|
var axios_1 = require("axios");
|
|
71
72
|
var util_1 = require("./util");
|
|
72
73
|
var vod_reporter_1 = require("./vod_reporter");
|
|
73
74
|
var uuidv4 = require("uuid/v4");
|
|
74
75
|
exports.vodAxios = axios_1.default.create();
|
|
75
|
-
var hostList = [
|
|
76
|
-
|
|
76
|
+
var hostList = [
|
|
77
|
+
"vod-upload-accelerate2",
|
|
78
|
+
"vod-upload-accelerate",
|
|
79
|
+
"vod-upload-proxy",
|
|
80
|
+
"vod-quic"
|
|
81
|
+
];
|
|
82
|
+
var targetHostList = [
|
|
83
|
+
"vod-upload-accelerate2",
|
|
84
|
+
"vod-upload-proxy",
|
|
85
|
+
"vod-quic"
|
|
86
|
+
];
|
|
77
87
|
var trimPrefix = function (str, prefix) {
|
|
78
88
|
return str.startsWith(prefix) ? str.substring(prefix.length) : str;
|
|
79
89
|
};
|
|
@@ -151,9 +161,8 @@ var Uploader = /** @class */ (function (_super) {
|
|
|
151
161
|
CopyChunkSize: params.copyChunkSize,
|
|
152
162
|
CopySliceSize: params.copySliceSize,
|
|
153
163
|
ProgressInterval: params.progressInterval,
|
|
154
|
-
DynamicAccelerate: params.dynamicAccelerate
|
|
164
|
+
DynamicAccelerate: params.dynamicAccelerate
|
|
155
165
|
};
|
|
156
|
-
// console.log('sourceData', params, sourceData);
|
|
157
166
|
var cosStrategy = Object.keys(sourceData)
|
|
158
167
|
.filter(function (key) { return sourceData[key] !== undefined; })
|
|
159
168
|
.reduce(function (acc, key) {
|
|
@@ -280,7 +289,9 @@ var Uploader = /** @class */ (function (_super) {
|
|
|
280
289
|
if (prepareData.code === 0) {
|
|
281
290
|
self.appId = self.appId || prepareData.data.appId;
|
|
282
291
|
// 如果只有一个园区就不用竞速了
|
|
283
|
-
if (!prepareData.data.cosRegionList ||
|
|
292
|
+
if (!prepareData.data.cosRegionList ||
|
|
293
|
+
(prepareData.data.cosRegionList &&
|
|
294
|
+
prepareData.data.cosRegionList.length <= 1)) {
|
|
284
295
|
return [2 /*return*/, callback()];
|
|
285
296
|
}
|
|
286
297
|
return [2 /*return*/, self.regionRace(prepareData.data.cosRegionList, function (res) {
|
|
@@ -607,7 +618,7 @@ var Uploader = /** @class */ (function (_super) {
|
|
|
607
618
|
// 使用s3 sdk上传
|
|
608
619
|
Uploader.prototype.uploadToS3 = function (applyData) {
|
|
609
620
|
return __awaiter(this, void 0, void 0, function () {
|
|
610
|
-
var self, uploadCosParams, cosParam, s3, cosVideoParam, cosCoverParam, requestStartTime, uploadPromises;
|
|
621
|
+
var self, uploadCosParams, cosParam, s3ClientOptions, s3, sharedController, cosVideoParam, cosCoverParam, requestStartTime, uploadPromises, err_1;
|
|
611
622
|
return __generator(this, function (_a) {
|
|
612
623
|
switch (_a.label) {
|
|
613
624
|
case 0:
|
|
@@ -616,14 +627,7 @@ var Uploader = /** @class */ (function (_super) {
|
|
|
616
627
|
cosParam = {
|
|
617
628
|
bucket: applyData.storageBucket + "-" + applyData.storageAppId
|
|
618
629
|
};
|
|
619
|
-
|
|
620
|
-
aws_sdk_1.config.update({
|
|
621
|
-
s3: {
|
|
622
|
-
maxRetries: 3,
|
|
623
|
-
computeChecksums: false
|
|
624
|
-
}
|
|
625
|
-
});
|
|
626
|
-
s3 = new aws_sdk_1.S3({
|
|
630
|
+
s3ClientOptions = {
|
|
627
631
|
endpoint: "https://cos.".concat(applyData.StorageRegionV5, ".myqcloud.com"), // 标准版cos上传域名
|
|
628
632
|
credentials: {
|
|
629
633
|
accessKeyId: applyData.tempCertificate.secretId,
|
|
@@ -631,9 +635,16 @@ var Uploader = /** @class */ (function (_super) {
|
|
|
631
635
|
sessionToken: applyData.tempCertificate.token
|
|
632
636
|
},
|
|
633
637
|
region: applyData.StorageRegionV5,
|
|
634
|
-
|
|
635
|
-
|
|
638
|
+
maxAttempts: self.cosStrategy.ChunkRetryTimes, // 重试次数
|
|
639
|
+
forcePathStyle: false // 不使用路径风格
|
|
640
|
+
};
|
|
641
|
+
s3 = new client_s3_1.S3Client(s3ClientOptions);
|
|
642
|
+
sharedController = new AbortController();
|
|
636
643
|
self.cos = s3;
|
|
644
|
+
// 为s3添加cancelTask函数,以兼容cos的对应功能
|
|
645
|
+
self.cos.cancelTask = function () {
|
|
646
|
+
sharedController.abort();
|
|
647
|
+
};
|
|
637
648
|
if (self.videoFile) {
|
|
638
649
|
cosVideoParam = __assign(__assign({}, cosParam), { file: self.videoFile, key: trimPrefix(applyData.video.storagePath, "/"), onProgress: function (data) {
|
|
639
650
|
self.emit(UploaderEvent.video_progress, data);
|
|
@@ -657,51 +668,74 @@ var Uploader = /** @class */ (function (_super) {
|
|
|
657
668
|
requestStartTime = new Date();
|
|
658
669
|
uploadPromises = uploadCosParams.map(function (uploadCosParam) {
|
|
659
670
|
return new Promise(function (resolve, reject) {
|
|
660
|
-
var singleUpload =
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
671
|
+
var singleUpload = new lib_storage_1.Upload({
|
|
672
|
+
client: s3,
|
|
673
|
+
params: {
|
|
674
|
+
Bucket: uploadCosParam.bucket,
|
|
675
|
+
Key: uploadCosParam.key,
|
|
676
|
+
Body: uploadCosParam.file
|
|
677
|
+
},
|
|
678
|
+
abortController: sharedController, // 共享中断控制器
|
|
679
|
+
partSize: self.cosStrategy.ChunkSize, // 配置分片大小
|
|
680
|
+
queueSize: self.cosStrategy.ChunkParallelLimit // 配置并发数
|
|
681
|
+
});
|
|
682
|
+
singleUpload
|
|
683
|
+
.done()
|
|
684
|
+
.then(function (info) {
|
|
666
685
|
if (uploadCosParam.file === self.videoFile) {
|
|
667
686
|
self.emit(vod_reporter_1.VodReportEvent.report_cos_upload, {
|
|
668
|
-
err:
|
|
687
|
+
err: null,
|
|
669
688
|
requestStartTime: requestStartTime
|
|
670
689
|
});
|
|
671
690
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
691
|
+
// 和cos的upload事件对齐
|
|
692
|
+
var evtData = {
|
|
693
|
+
Location: info.Location ? info.Location.replace(/^https?:\/\//, "") : '', // 包含域名和路径,无协议头
|
|
694
|
+
Bucket: "".concat(info.Bucket, "-").concat(applyData.storageAppId), // 包含 APPID (BucketName-APPID 格式)
|
|
695
|
+
Key: info.Key || '',
|
|
696
|
+
ETag: info.ETag || ''
|
|
697
|
+
};
|
|
698
|
+
uploadCosParam.onUpload(evtData);
|
|
699
|
+
return resolve();
|
|
700
|
+
})
|
|
701
|
+
.catch(function (err) {
|
|
702
|
+
if (uploadCosParam.file === self.videoFile) {
|
|
703
|
+
self.emit(vod_reporter_1.VodReportEvent.report_cos_upload, {
|
|
704
|
+
err: err,
|
|
705
|
+
requestStartTime: requestStartTime
|
|
706
|
+
});
|
|
675
707
|
}
|
|
676
708
|
self.delStorage(self.sessionName);
|
|
677
|
-
reject(err);
|
|
709
|
+
return reject(err);
|
|
678
710
|
});
|
|
679
711
|
// 进度条事件
|
|
680
712
|
singleUpload.on("httpUploadProgress", function (info) {
|
|
681
|
-
var
|
|
713
|
+
var loaded = info.loaded || 0;
|
|
714
|
+
var total = info.total || 0;
|
|
715
|
+
var percent = loaded ? loaded / total : 0; // 直接得到 0-1
|
|
682
716
|
var evtData = {
|
|
683
|
-
loaded:
|
|
684
|
-
total:
|
|
717
|
+
loaded: loaded,
|
|
718
|
+
total: total,
|
|
685
719
|
speed: 0, // aws sdk没有提供上传速度,这里设置为0
|
|
686
720
|
percent: parseFloat(percent.toFixed(2)) // cos sdk的percent取值是0-1,为了和cos sdk保持一致,这里也转换成0-1,并保留两位小数
|
|
687
721
|
};
|
|
688
722
|
uploadCosParam.onProgress(evtData);
|
|
689
723
|
});
|
|
690
|
-
// 上传完成事件
|
|
691
|
-
singleUpload.on("complete", function (info) {
|
|
692
|
-
// 和cos的upload事件对齐
|
|
693
|
-
var evtData = {
|
|
694
|
-
Location: info.Location.replace(/^https?:\/\//, ""), // 包含域名和路径,无协议头
|
|
695
|
-
Bucket: "".concat(info.Bucket, "-").concat(applyData.storageAppId), // 包含 APPID (BucketName-APPID 格式)
|
|
696
|
-
Key: info.Key,
|
|
697
|
-
ETag: info.ETag
|
|
698
|
-
};
|
|
699
|
-
uploadCosParam.onUpload(evtData);
|
|
700
|
-
});
|
|
701
724
|
});
|
|
702
725
|
});
|
|
726
|
+
_a.label = 1;
|
|
727
|
+
case 1:
|
|
728
|
+
_a.trys.push([1, 3, , 4]);
|
|
703
729
|
return [4 /*yield*/, Promise.all(uploadPromises)];
|
|
704
|
-
case
|
|
730
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
731
|
+
case 3:
|
|
732
|
+
err_1 = _a.sent();
|
|
733
|
+
if (err_1 instanceof Error && err_1.name === "AbortError") {
|
|
734
|
+
// SDK 内部已自动调用 AbortMultipartUpload 清理碎片
|
|
735
|
+
console.log("本次上传任务已取消并清理");
|
|
736
|
+
}
|
|
737
|
+
return [2 /*return*/, Promise.reject(err_1)];
|
|
738
|
+
case 4: return [2 /*return*/];
|
|
705
739
|
}
|
|
706
740
|
});
|
|
707
741
|
});
|
|
@@ -855,7 +889,8 @@ var Uploader = /** @class */ (function (_super) {
|
|
|
855
889
|
return this.donePromise;
|
|
856
890
|
};
|
|
857
891
|
Uploader.prototype.cancel = function () {
|
|
858
|
-
|
|
892
|
+
var _a;
|
|
893
|
+
(_a = this.cos) === null || _a === void 0 ? void 0 : _a.cancelTask(this.taskId);
|
|
859
894
|
};
|
|
860
895
|
// domain
|
|
861
896
|
// static host = "43.156.222.23" || HOST.MAIN;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vod-js-sdk-v6",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "tencent cloud vod js sdk v6",
|
|
5
5
|
"main": "lib/src/tc_vod.js",
|
|
6
6
|
"unpkg": "dist/vod-js-sdk-v6.js",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/tencentyun/vod-js-sdk-v6#readme",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"aws-sdk": "^
|
|
34
|
+
"@aws-sdk/client-s3": "^3.1010.0",
|
|
35
|
+
"@aws-sdk/lib-storage": "^3.1010.0",
|
|
35
36
|
"axios": "^0.21.1",
|
|
36
37
|
"eventemitter3": "^4.0.7",
|
|
37
38
|
"js-sha1": "^0.6.0",
|
package/src/uploader.ts
CHANGED
|
@@ -2,7 +2,8 @@ const sha1 = require("js-sha1");
|
|
|
2
2
|
const COS = require("./base.js");
|
|
3
3
|
|
|
4
4
|
import { EventEmitter } from "eventemitter3";
|
|
5
|
-
import {
|
|
5
|
+
import { S3Client } from "@aws-sdk/client-s3";
|
|
6
|
+
import { Upload } from "@aws-sdk/lib-storage";
|
|
6
7
|
import axios from "axios";
|
|
7
8
|
import util, { HOST } from "./util";
|
|
8
9
|
import { vodError } from "./types";
|
|
@@ -10,8 +11,17 @@ import { VodReportEvent } from "./vod_reporter";
|
|
|
10
11
|
import * as uuidv4 from "uuid/v4";
|
|
11
12
|
|
|
12
13
|
export const vodAxios = axios.create();
|
|
13
|
-
const hostList = [
|
|
14
|
-
|
|
14
|
+
const hostList = [
|
|
15
|
+
"vod-upload-accelerate2",
|
|
16
|
+
"vod-upload-accelerate",
|
|
17
|
+
"vod-upload-proxy",
|
|
18
|
+
"vod-quic"
|
|
19
|
+
];
|
|
20
|
+
const targetHostList = [
|
|
21
|
+
"vod-upload-accelerate2",
|
|
22
|
+
"vod-upload-proxy",
|
|
23
|
+
"vod-quic"
|
|
24
|
+
];
|
|
15
25
|
|
|
16
26
|
const trimPrefix = (str: string, prefix: string) =>
|
|
17
27
|
str.startsWith(prefix) ? str.substring(prefix.length) : str;
|
|
@@ -19,10 +29,10 @@ const trimPrefix = (str: string, prefix: string) =>
|
|
|
19
29
|
let hostIndex = 2;
|
|
20
30
|
|
|
21
31
|
vodAxios.interceptors.response.use(
|
|
22
|
-
function(response) {
|
|
32
|
+
function (response) {
|
|
23
33
|
return response;
|
|
24
34
|
},
|
|
25
|
-
function(error) {
|
|
35
|
+
function (error) {
|
|
26
36
|
if (isNaN(error.code)) {
|
|
27
37
|
error.code = 500;
|
|
28
38
|
}
|
|
@@ -138,7 +148,8 @@ export interface UploaderOptions {
|
|
|
138
148
|
progressInterval?: number;
|
|
139
149
|
dynamicAccelerate?: boolean;
|
|
140
150
|
|
|
141
|
-
expireTime?: string
|
|
151
|
+
expireTime?: string;
|
|
152
|
+
|
|
142
153
|
storageType?: string;
|
|
143
154
|
}
|
|
144
155
|
|
|
@@ -194,8 +205,9 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
194
205
|
// 重试请求的等待时间
|
|
195
206
|
retryDelay = 1000;
|
|
196
207
|
targetAccelerate = false;
|
|
197
|
-
|
|
208
|
+
|
|
198
209
|
storageType = "cos";
|
|
210
|
+
expireTime: string;
|
|
199
211
|
|
|
200
212
|
// domain
|
|
201
213
|
// static host = "43.156.222.23" || HOST.MAIN;
|
|
@@ -243,11 +255,9 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
243
255
|
CopyChunkSize: params.copyChunkSize,
|
|
244
256
|
CopySliceSize: params.copySliceSize,
|
|
245
257
|
ProgressInterval: params.progressInterval,
|
|
246
|
-
DynamicAccelerate: params.dynamicAccelerate
|
|
258
|
+
DynamicAccelerate: params.dynamicAccelerate
|
|
247
259
|
};
|
|
248
260
|
|
|
249
|
-
// console.log('sourceData', params, sourceData);
|
|
250
|
-
|
|
251
261
|
const cosStrategy = Object.keys(sourceData)
|
|
252
262
|
.filter(key => sourceData[key] !== undefined)
|
|
253
263
|
.reduce((acc, key) => ({ ...acc, [key]: sourceData[key] }), {});
|
|
@@ -264,7 +274,7 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
264
274
|
const cname = "webugc_" + sha1(name);
|
|
265
275
|
try {
|
|
266
276
|
localStorage.setItem(cname, value);
|
|
267
|
-
} catch (e) {}
|
|
277
|
+
} catch (e) { }
|
|
268
278
|
}
|
|
269
279
|
|
|
270
280
|
// get storage
|
|
@@ -276,7 +286,7 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
276
286
|
let result = null;
|
|
277
287
|
try {
|
|
278
288
|
result = localStorage.getItem(cname);
|
|
279
|
-
} catch (e) {}
|
|
289
|
+
} catch (e) { }
|
|
280
290
|
|
|
281
291
|
return result;
|
|
282
292
|
}
|
|
@@ -289,7 +299,7 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
289
299
|
const cname = "webugc_" + sha1(name);
|
|
290
300
|
try {
|
|
291
301
|
localStorage.removeItem(cname);
|
|
292
|
-
} catch (e) {}
|
|
302
|
+
} catch (e) { }
|
|
293
303
|
}
|
|
294
304
|
|
|
295
305
|
// validate init params
|
|
@@ -373,10 +383,14 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
373
383
|
self.appId = self.appId || prepareData.data.appId;
|
|
374
384
|
// 如果只有一个园区就不用竞速了
|
|
375
385
|
|
|
376
|
-
if (
|
|
386
|
+
if (
|
|
387
|
+
!prepareData.data.cosRegionList ||
|
|
388
|
+
(prepareData.data.cosRegionList &&
|
|
389
|
+
prepareData.data.cosRegionList.length <= 1)
|
|
390
|
+
) {
|
|
377
391
|
return callback();
|
|
378
392
|
}
|
|
379
|
-
return self.regionRace(prepareData.data.cosRegionList, function(
|
|
393
|
+
return self.regionRace(prepareData.data.cosRegionList, function (
|
|
380
394
|
res: any
|
|
381
395
|
) {
|
|
382
396
|
self.emit(VodReportEvent.report_prepare, {
|
|
@@ -525,7 +539,6 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
525
539
|
return applyData.StorageRegionV5 === item;
|
|
526
540
|
});
|
|
527
541
|
|
|
528
|
-
|
|
529
542
|
this.emit(VodReportEvent.report_apply, {
|
|
530
543
|
data: applyData,
|
|
531
544
|
requestStartTime: requestStartTime
|
|
@@ -557,7 +570,7 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
557
570
|
{
|
|
558
571
|
ForceSignHost: false,
|
|
559
572
|
// UseRawKey: true,
|
|
560
|
-
getAuthorization: async function(
|
|
573
|
+
getAuthorization: async function (
|
|
561
574
|
options: object,
|
|
562
575
|
callback: Function
|
|
563
576
|
) {
|
|
@@ -589,9 +602,7 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
589
602
|
);
|
|
590
603
|
this.cos = cos;
|
|
591
604
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
cos.on("before-send", function(opt: any) {
|
|
605
|
+
cos.on("before-send", function (opt: any) {
|
|
595
606
|
var url = opt.url;
|
|
596
607
|
// console.log("self", url, self.cosStrategy.DynamicAccelerate);
|
|
597
608
|
|
|
@@ -631,15 +642,15 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
631
642
|
...cosParam,
|
|
632
643
|
file: this.videoFile,
|
|
633
644
|
key: applyData.video.storagePath,
|
|
634
|
-
onProgress: function(data: any) {
|
|
645
|
+
onProgress: function (data: any) {
|
|
635
646
|
self.emit(UploaderEvent.video_progress, data);
|
|
636
647
|
self.emit(UploaderEvent.media_progress, data);
|
|
637
648
|
},
|
|
638
|
-
onUpload: function(data: any) {
|
|
649
|
+
onUpload: function (data: any) {
|
|
639
650
|
self.emit(UploaderEvent.video_upload, data);
|
|
640
651
|
self.emit(UploaderEvent.media_upload, data);
|
|
641
652
|
},
|
|
642
|
-
onTaskReady: function(taskId: string) {
|
|
653
|
+
onTaskReady: function (taskId: string) {
|
|
643
654
|
self.taskId = taskId;
|
|
644
655
|
}
|
|
645
656
|
};
|
|
@@ -651,10 +662,10 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
651
662
|
...cosParam,
|
|
652
663
|
file: this.coverFile,
|
|
653
664
|
key: applyData.cover.storagePath,
|
|
654
|
-
onProgress: function(data: any) {
|
|
665
|
+
onProgress: function (data: any) {
|
|
655
666
|
self.emit(UploaderEvent.cover_progress, data);
|
|
656
667
|
},
|
|
657
|
-
onUpload: function(data: any) {
|
|
668
|
+
onUpload: function (data: any) {
|
|
658
669
|
self.emit(UploaderEvent.cover_upload, data);
|
|
659
670
|
},
|
|
660
671
|
onTaskReady: util.noop
|
|
@@ -663,7 +674,7 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
663
674
|
}
|
|
664
675
|
const requestStartTime = new Date();
|
|
665
676
|
const uploadPromises = uploadCosParams.map(uploadCosParam => {
|
|
666
|
-
return new Promise<void>(function(resolve, reject) {
|
|
677
|
+
return new Promise<void>(function (resolve, reject) {
|
|
667
678
|
cos.sliceUploadFile(
|
|
668
679
|
{
|
|
669
680
|
Bucket: uploadCosParam.bucket,
|
|
@@ -673,7 +684,7 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
673
684
|
onTaskReady: uploadCosParam.onTaskReady,
|
|
674
685
|
onProgress: uploadCosParam.onProgress
|
|
675
686
|
},
|
|
676
|
-
function(err: any, data: any) {
|
|
687
|
+
function (err: any, data: any) {
|
|
677
688
|
// only report video file
|
|
678
689
|
if (uploadCosParam.file === self.videoFile) {
|
|
679
690
|
self.emit(VodReportEvent.report_cos_upload, {
|
|
@@ -707,15 +718,7 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
707
718
|
bucket: applyData.storageBucket + "-" + applyData.storageAppId
|
|
708
719
|
};
|
|
709
720
|
|
|
710
|
-
|
|
711
|
-
AWSConfig.update({
|
|
712
|
-
s3: {
|
|
713
|
-
maxRetries: 3,
|
|
714
|
-
computeChecksums: false
|
|
715
|
-
}
|
|
716
|
-
});
|
|
717
|
-
|
|
718
|
-
const s3 = new S3({
|
|
721
|
+
const s3ClientOptions = {
|
|
719
722
|
endpoint: `https://cos.${applyData.StorageRegionV5}.myqcloud.com`, // 标准版cos上传域名
|
|
720
723
|
credentials: {
|
|
721
724
|
accessKeyId: applyData.tempCertificate.secretId,
|
|
@@ -723,21 +726,30 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
723
726
|
sessionToken: applyData.tempCertificate.token
|
|
724
727
|
},
|
|
725
728
|
region: applyData.StorageRegionV5,
|
|
726
|
-
|
|
727
|
-
|
|
729
|
+
maxAttempts: self.cosStrategy.ChunkRetryTimes, // 重试次数
|
|
730
|
+
forcePathStyle: false // 不使用路径风格
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
const s3 = new S3Client(s3ClientOptions);
|
|
734
|
+
const sharedController = new AbortController();
|
|
728
735
|
|
|
729
736
|
self.cos = s3;
|
|
730
737
|
|
|
738
|
+
// 为s3添加cancelTask函数,以兼容cos的对应功能
|
|
739
|
+
self.cos.cancelTask = function() {
|
|
740
|
+
sharedController.abort();
|
|
741
|
+
};
|
|
742
|
+
|
|
731
743
|
if (self.videoFile) {
|
|
732
744
|
const cosVideoParam = {
|
|
733
745
|
...cosParam,
|
|
734
746
|
file: self.videoFile,
|
|
735
747
|
key: trimPrefix(applyData.video.storagePath, "/"),
|
|
736
|
-
onProgress: function(data: IS3UploadProcessEvtData) {
|
|
748
|
+
onProgress: function (data: IS3UploadProcessEvtData) {
|
|
737
749
|
self.emit(UploaderEvent.video_progress, data);
|
|
738
750
|
self.emit(UploaderEvent.media_progress, data);
|
|
739
751
|
},
|
|
740
|
-
onUpload: function(data: IS3UploadCompleteEvtData) {
|
|
752
|
+
onUpload: function (data: IS3UploadCompleteEvtData) {
|
|
741
753
|
self.emit(UploaderEvent.video_upload, data);
|
|
742
754
|
self.emit(UploaderEvent.media_upload, data);
|
|
743
755
|
},
|
|
@@ -751,10 +763,10 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
751
763
|
...cosParam,
|
|
752
764
|
file: self.coverFile,
|
|
753
765
|
key: trimPrefix(applyData.cover.storagePath, "/"),
|
|
754
|
-
onProgress: function(data: IS3UploadProcessEvtData) {
|
|
766
|
+
onProgress: function (data: IS3UploadProcessEvtData) {
|
|
755
767
|
self.emit(UploaderEvent.cover_progress, data);
|
|
756
768
|
},
|
|
757
|
-
onUpload: function(data: IS3UploadCompleteEvtData) {
|
|
769
|
+
onUpload: function (data: IS3UploadCompleteEvtData) {
|
|
758
770
|
self.emit(UploaderEvent.cover_upload, data);
|
|
759
771
|
},
|
|
760
772
|
onTaskReady: util.noop // aws sdk没有提供taskId,先占位一个空函数
|
|
@@ -764,57 +776,78 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
764
776
|
|
|
765
777
|
const requestStartTime = new Date();
|
|
766
778
|
const uploadPromises = uploadCosParams.map(uploadCosParam => {
|
|
767
|
-
return new Promise<void>(function(resolve, reject) {
|
|
768
|
-
const singleUpload =
|
|
769
|
-
|
|
779
|
+
return new Promise<void>(function (resolve, reject) {
|
|
780
|
+
const singleUpload = new Upload({
|
|
781
|
+
client: s3,
|
|
782
|
+
params: {
|
|
770
783
|
Bucket: uploadCosParam.bucket,
|
|
771
784
|
Key: uploadCosParam.key,
|
|
772
785
|
Body: uploadCosParam.file
|
|
773
786
|
},
|
|
774
|
-
|
|
775
|
-
|
|
787
|
+
abortController: sharedController, // 共享中断控制器
|
|
788
|
+
partSize: self.cosStrategy.ChunkSize, // 配置分片大小
|
|
789
|
+
queueSize: self.cosStrategy.ChunkParallelLimit // 配置并发数
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
singleUpload
|
|
793
|
+
.done()
|
|
794
|
+
.then(info => {
|
|
776
795
|
if (uploadCosParam.file === self.videoFile) {
|
|
777
796
|
self.emit(VodReportEvent.report_cos_upload, {
|
|
778
|
-
err:
|
|
797
|
+
err: null,
|
|
779
798
|
requestStartTime: requestStartTime
|
|
780
799
|
});
|
|
781
800
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
801
|
+
// 和cos的upload事件对齐
|
|
802
|
+
const evtData: IS3UploadCompleteEvtData = {
|
|
803
|
+
Location: info.Location ? info.Location.replace(/^https?:\/\//, "") : '', // 包含域名和路径,无协议头
|
|
804
|
+
Bucket: `${info.Bucket}-${applyData.storageAppId}`, // 包含 APPID (BucketName-APPID 格式)
|
|
805
|
+
Key: info.Key || '',
|
|
806
|
+
ETag: info.ETag || ''
|
|
807
|
+
};
|
|
808
|
+
uploadCosParam.onUpload(evtData);
|
|
809
|
+
|
|
810
|
+
return resolve();
|
|
811
|
+
})
|
|
812
|
+
.catch((err: Error | null) => {
|
|
813
|
+
if (uploadCosParam.file === self.videoFile) {
|
|
814
|
+
self.emit(VodReportEvent.report_cos_upload, {
|
|
815
|
+
err: err,
|
|
816
|
+
requestStartTime: requestStartTime
|
|
817
|
+
});
|
|
785
818
|
}
|
|
786
819
|
self.delStorage(self.sessionName);
|
|
820
|
+
return reject(err);
|
|
821
|
+
});
|
|
787
822
|
|
|
788
|
-
|
|
823
|
+
// 进度条事件
|
|
824
|
+
singleUpload.on(
|
|
825
|
+
"httpUploadProgress",
|
|
826
|
+
(info) => {
|
|
827
|
+
const loaded = info.loaded || 0
|
|
828
|
+
const total = info.total || 0
|
|
829
|
+
const percent = loaded ? loaded / total : 0; // 直接得到 0-1
|
|
830
|
+
const evtData: IS3UploadProcessEvtData = {
|
|
831
|
+
loaded: loaded,
|
|
832
|
+
total: total,
|
|
833
|
+
speed: 0, // aws sdk没有提供上传速度,这里设置为0
|
|
834
|
+
percent: parseFloat(percent.toFixed(2)) // cos sdk的percent取值是0-1,为了和cos sdk保持一致,这里也转换成0-1,并保留两位小数
|
|
835
|
+
};
|
|
836
|
+
uploadCosParam.onProgress(evtData);
|
|
789
837
|
}
|
|
790
838
|
);
|
|
791
|
-
|
|
792
|
-
// 进度条事件
|
|
793
|
-
singleUpload.on("httpUploadProgress", (info: IS3UploadProcessEvtData) => {
|
|
794
|
-
const percent = info.loaded / info.total; // 直接得到 0-1
|
|
795
|
-
const evtData = {
|
|
796
|
-
loaded: info.loaded,
|
|
797
|
-
total: info.total,
|
|
798
|
-
speed: 0, // aws sdk没有提供上传速度,这里设置为0
|
|
799
|
-
percent: parseFloat(percent.toFixed(2)) // cos sdk的percent取值是0-1,为了和cos sdk保持一致,这里也转换成0-1,并保留两位小数
|
|
800
|
-
};
|
|
801
|
-
uploadCosParam.onProgress(evtData);
|
|
802
|
-
});
|
|
803
|
-
// 上传完成事件
|
|
804
|
-
singleUpload.on("complete", (info: IS3UploadCompleteEvtData) => {
|
|
805
|
-
// 和cos的upload事件对齐
|
|
806
|
-
const evtData = {
|
|
807
|
-
Location: info.Location.replace(/^https?:\/\//, ""), // 包含域名和路径,无协议头
|
|
808
|
-
Bucket: `${info.Bucket}-${applyData.storageAppId}`, // 包含 APPID (BucketName-APPID 格式)
|
|
809
|
-
Key: info.Key,
|
|
810
|
-
ETag: info.ETag
|
|
811
|
-
};
|
|
812
|
-
uploadCosParam.onUpload(evtData);
|
|
813
|
-
});
|
|
814
839
|
});
|
|
815
840
|
});
|
|
816
841
|
|
|
817
|
-
|
|
842
|
+
try {
|
|
843
|
+
return await Promise.all(uploadPromises);
|
|
844
|
+
} catch (err: unknown) {
|
|
845
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
846
|
+
// SDK 内部已自动调用 AbortMultipartUpload 清理碎片
|
|
847
|
+
console.log("本次上传任务已取消并清理");
|
|
848
|
+
}
|
|
849
|
+
return Promise.reject(err);
|
|
850
|
+
}
|
|
818
851
|
}
|
|
819
852
|
|
|
820
853
|
async commitUploadUGC(retryCount: number = 0) {
|
|
@@ -870,10 +903,10 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
870
903
|
// "firstFrameStart",
|
|
871
904
|
// "firstFrameEnd"
|
|
872
905
|
// );
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
906
|
+
// console.log(
|
|
907
|
+
// "duration",
|
|
908
|
+
// window.performance.getEntriesByName("firstFrame")[0].duration
|
|
909
|
+
// );
|
|
877
910
|
// }
|
|
878
911
|
this.emit(VodReportEvent.report_commit, {
|
|
879
912
|
data: {
|
|
@@ -921,7 +954,6 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
921
954
|
} else {
|
|
922
955
|
await this.uploadToCos(applyData);
|
|
923
956
|
}
|
|
924
|
-
|
|
925
957
|
return await this.commitUploadUGC();
|
|
926
958
|
};
|
|
927
959
|
|
|
@@ -937,7 +969,7 @@ class Uploader extends EventEmitter implements UploaderOptions {
|
|
|
937
969
|
}
|
|
938
970
|
|
|
939
971
|
cancel() {
|
|
940
|
-
this.cos
|
|
972
|
+
this.cos?.cancelTask(this.taskId);
|
|
941
973
|
}
|
|
942
974
|
}
|
|
943
975
|
|