vidspotai-shared 1.0.29 → 1.0.31

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.
Files changed (108) hide show
  1. package/lib/globals/aiModels/enums.d.ts +40 -0
  2. package/lib/globals/aiModels/enums.d.ts.map +1 -0
  3. package/lib/globals/aiModels/enums.js +46 -0
  4. package/lib/globals/aiModels/index.d.ts +6 -0
  5. package/lib/globals/aiModels/index.d.ts.map +1 -0
  6. package/lib/globals/aiModels/index.js +35 -0
  7. package/lib/globals/aiModels/providers/bytedance.d.ts +4 -0
  8. package/lib/globals/aiModels/providers/bytedance.d.ts.map +1 -0
  9. package/lib/globals/aiModels/providers/bytedance.js +65 -0
  10. package/lib/globals/aiModels/providers/google.d.ts +4 -0
  11. package/lib/globals/aiModels/providers/google.d.ts.map +1 -0
  12. package/lib/globals/aiModels/providers/google.js +111 -0
  13. package/lib/globals/aiModels/providers/kling.d.ts +4 -0
  14. package/lib/globals/aiModels/providers/kling.d.ts.map +1 -0
  15. package/lib/globals/aiModels/providers/kling.js +129 -0
  16. package/lib/globals/aiModels/providers/minimax.d.ts +4 -0
  17. package/lib/globals/aiModels/providers/minimax.d.ts.map +1 -0
  18. package/lib/globals/aiModels/providers/minimax.js +66 -0
  19. package/lib/globals/aiModels/providers/openai.d.ts +4 -0
  20. package/lib/globals/aiModels/providers/openai.d.ts.map +1 -0
  21. package/lib/globals/aiModels/providers/openai.js +82 -0
  22. package/lib/globals/aiModels/providers/pixverse.d.ts +4 -0
  23. package/lib/globals/aiModels/providers/pixverse.d.ts.map +1 -0
  24. package/lib/globals/aiModels/providers/pixverse.js +108 -0
  25. package/lib/globals/aiModels/providers/runway.d.ts +4 -0
  26. package/lib/globals/aiModels/providers/runway.d.ts.map +1 -0
  27. package/lib/globals/aiModels/providers/runway.js +52 -0
  28. package/lib/globals/aiModels/types.d.ts +45 -0
  29. package/lib/globals/aiModels/types.d.ts.map +1 -0
  30. package/lib/globals/aiModels/types.js +2 -0
  31. package/lib/globals/index.d.ts +1 -0
  32. package/lib/globals/index.d.ts.map +1 -1
  33. package/lib/globals/index.js +1 -0
  34. package/lib/globals/ttsModels/index.d.ts +6 -0
  35. package/lib/globals/ttsModels/index.d.ts.map +1 -0
  36. package/lib/globals/ttsModels/index.js +25 -0
  37. package/lib/globals/ttsModels/providers/elevenlabs.d.ts +3 -0
  38. package/lib/globals/ttsModels/providers/elevenlabs.d.ts.map +1 -0
  39. package/lib/globals/ttsModels/providers/elevenlabs.js +13 -0
  40. package/lib/globals/ttsModels/types.d.ts +15 -0
  41. package/lib/globals/ttsModels/types.d.ts.map +1 -0
  42. package/lib/globals/ttsModels/types.js +2 -0
  43. package/lib/globals/ttsModels/voices.d.ts +21 -0
  44. package/lib/globals/ttsModels/voices.d.ts.map +1 -0
  45. package/lib/globals/ttsModels/voices.js +135 -0
  46. package/lib/models/user.model.d.ts +2 -0
  47. package/lib/models/user.model.d.ts.map +1 -1
  48. package/lib/models/video.model.d.ts +14 -0
  49. package/lib/models/video.model.d.ts.map +1 -1
  50. package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
  51. package/lib/services/aiGen/aiGenFactory.service.js +36 -12
  52. package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts +9 -0
  53. package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts.map +1 -0
  54. package/lib/services/aiGen/providers/bytedance/bytedance.service.js +188 -0
  55. package/lib/services/aiGen/providers/bytedance/constants.d.ts +2 -0
  56. package/lib/services/aiGen/providers/bytedance/constants.d.ts.map +1 -0
  57. package/lib/services/aiGen/providers/bytedance/constants.js +27 -0
  58. package/lib/services/aiGen/providers/bytedance/index.d.ts +2 -0
  59. package/lib/services/aiGen/providers/bytedance/index.d.ts.map +1 -0
  60. package/lib/services/aiGen/providers/bytedance/index.js +17 -0
  61. package/lib/services/aiGen/providers/bytedance/types.d.ts +5 -0
  62. package/lib/services/aiGen/providers/bytedance/types.d.ts.map +1 -0
  63. package/lib/services/aiGen/providers/bytedance/types.js +1 -0
  64. package/lib/services/aiGen/providers/google/google.service.js +1 -1
  65. package/lib/services/aiGen/providers/kling/kling.service.d.ts +7 -2
  66. package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
  67. package/lib/services/aiGen/providers/kling/kling.service.js +126 -10
  68. package/lib/services/aiGen/providers/kling/types.d.ts +13 -0
  69. package/lib/services/aiGen/providers/kling/types.d.ts.map +1 -1
  70. package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts +9 -0
  71. package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -0
  72. package/lib/services/aiGen/providers/pixverse/pixverse.service.js +188 -0
  73. package/lib/services/aiGen/providers/runway/runway.service.d.ts.map +1 -1
  74. package/lib/services/aiGen/providers/runway/runway.service.js +16 -4
  75. package/lib/services/aiGen/providers/types.d.ts +6 -0
  76. package/lib/services/aiGen/providers/types.d.ts.map +1 -1
  77. package/lib/services/credit.service.d.ts +1 -0
  78. package/lib/services/credit.service.d.ts.map +1 -1
  79. package/lib/services/credit.service.js +17 -0
  80. package/lib/services/gcp/gsheet.service.d.ts +7 -0
  81. package/lib/services/gcp/gsheet.service.d.ts.map +1 -1
  82. package/lib/services/gcp/gsheet.service.js +46 -0
  83. package/lib/services/index.d.ts +1 -0
  84. package/lib/services/index.d.ts.map +1 -1
  85. package/lib/services/index.js +1 -0
  86. package/lib/services/tts/index.d.ts +4 -0
  87. package/lib/services/tts/index.d.ts.map +1 -0
  88. package/lib/services/tts/index.js +19 -0
  89. package/lib/services/tts/providers/elevenlabs.service.d.ts +7 -0
  90. package/lib/services/tts/providers/elevenlabs.service.d.ts.map +1 -0
  91. package/lib/services/tts/providers/elevenlabs.service.js +44 -0
  92. package/lib/services/tts/ttsFactory.service.d.ts +4 -0
  93. package/lib/services/tts/ttsFactory.service.d.ts.map +1 -0
  94. package/lib/services/tts/ttsFactory.service.js +12 -0
  95. package/lib/services/tts/types.d.ts +14 -0
  96. package/lib/services/tts/types.d.ts.map +1 -0
  97. package/lib/services/tts/types.js +6 -0
  98. package/lib/utils/helpers.js +2 -2
  99. package/lib/utils/index.d.ts +1 -0
  100. package/lib/utils/index.d.ts.map +1 -1
  101. package/lib/utils/index.js +1 -0
  102. package/lib/utils/logger.d.ts +2 -1
  103. package/lib/utils/logger.d.ts.map +1 -1
  104. package/lib/utils/logger.js +2 -0
  105. package/lib/utils/ttsUtils.d.ts +11 -0
  106. package/lib/utils/ttsUtils.d.ts.map +1 -0
  107. package/lib/utils/ttsUtils.js +16 -0
  108. package/package.json +1 -1
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ByteDanceService = void 0;
7
+ // bytedance.service.ts
8
+ const baseAiGenProvider_service_1 = require("../baseAiGenProvider.service");
9
+ const helpers_1 = require("../../helpers");
10
+ const aiModels_1 = require("../../../../globals/aiModels");
11
+ const types_1 = require("../../../../globals/types");
12
+ const firebase_1 = require("../../../../libs/firebase");
13
+ const helpers_2 = require("../../../../utils/helpers");
14
+ const logger_1 = require("../../../../utils/logger");
15
+ const crypto_1 = __importDefault(require("crypto"));
16
+ class ByteDanceService extends baseAiGenProvider_service_1.BaseAiGenProviderService {
17
+ constructor() {
18
+ super(...arguments);
19
+ this.baseUrl = "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks";
20
+ }
21
+ async generateVideo(params) {
22
+ (0, helpers_1.validateParams)(params);
23
+ const modelConfig = aiModels_1.aiModelConfigs[params.modelKey];
24
+ const modelId = modelConfig.modelId;
25
+ const content = [
26
+ {
27
+ type: "text",
28
+ text: params.prompt,
29
+ },
30
+ ];
31
+ // Optional image → Image-to-Video (first frame)
32
+ if (params.inputImageUrl) {
33
+ content.push({
34
+ type: "image",
35
+ image_url: params.inputImageUrl,
36
+ });
37
+ }
38
+ const body = {
39
+ model: modelId,
40
+ content,
41
+ generate_audio: params.audio || false,
42
+ ratio: params.aspectRatio, // e.g. 16:9
43
+ resolution: params.resolution, // e.g. 720p
44
+ duration: params.duration, // seconds
45
+ watermark: false,
46
+ service_tier: "default",
47
+ execution_expires_after: 172800, // 48h
48
+ };
49
+ const resp = await fetch(this.baseUrl, {
50
+ method: "POST",
51
+ headers: {
52
+ "Content-Type": "application/json",
53
+ Authorization: `Bearer ${process.env.BYTEDANCE_API_KEY}`,
54
+ },
55
+ body: JSON.stringify(body),
56
+ });
57
+ if (!resp.ok) {
58
+ const errText = await resp.text();
59
+ throw new Error(`ByteDance generateVideo failed (${resp.status}): ${errText}`);
60
+ }
61
+ const data = await resp.json();
62
+ if (!data.id) {
63
+ throw new Error("ByteDance API did not return task id");
64
+ }
65
+ return {
66
+ task: data.id,
67
+ status: types_1.EVideoSceneStatus.TRIGGERED,
68
+ };
69
+ }
70
+ async checkVideoStatus({ task, outputFilename, outputFilePath = "videos", }) {
71
+ const url = `https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks/${task}`;
72
+ const resp = await fetch(url, {
73
+ method: "GET",
74
+ headers: {
75
+ "Content-Type": "application/json",
76
+ Authorization: `Bearer ${process.env.BYTEDANCE_API_KEY}`,
77
+ },
78
+ });
79
+ if (!resp.ok) {
80
+ const errText = await resp.text();
81
+ throw new Error(`ByteDance checkVideoStatus failed (${resp.status}): ${errText}`);
82
+ }
83
+ const data = await resp.json();
84
+ // ---- Status mapping ----
85
+ switch (data.status) {
86
+ case "queued":
87
+ case "running":
88
+ return { status: types_1.EVideoSceneStatus.PENDING };
89
+ case "failed":
90
+ case "expired":
91
+ case "cancelled":
92
+ return {
93
+ status: types_1.EVideoSceneStatus.FAILED,
94
+ errorMessage: data.error
95
+ ? JSON.stringify(data.error)
96
+ : "ByteDance video generation failed",
97
+ };
98
+ case "succeeded":
99
+ break;
100
+ default:
101
+ return {
102
+ status: types_1.EVideoSceneStatus.FAILED,
103
+ errorMessage: `Unknown ByteDance task status: ${data.status}`,
104
+ };
105
+ }
106
+ // ---- Success path ----
107
+ const sourceVideoUrl = data.content?.video_url;
108
+ if (!sourceVideoUrl) {
109
+ return {
110
+ status: types_1.EVideoSceneStatus.FAILED,
111
+ errorMessage: "ByteDance response missing video_url",
112
+ };
113
+ }
114
+ // Download generated video
115
+ const videoResp = await fetch(sourceVideoUrl);
116
+ if (!videoResp.ok) {
117
+ throw new Error(`Failed to download ByteDance video (${videoResp.status})`);
118
+ }
119
+ const buffer = Buffer.from(await videoResp.arrayBuffer());
120
+ // ---- Upload to Firebase Storage (PUBLIC URL) ----
121
+ const filePath = `${outputFilePath}/${outputFilename}.mp4`;
122
+ const bucket = (0, firebase_1.getBucket)();
123
+ const file = bucket.file(filePath);
124
+ const downloadToken = crypto_1.default.randomUUID();
125
+ await file.save(buffer, {
126
+ contentType: "video/mp4",
127
+ resumable: false,
128
+ metadata: {
129
+ cacheControl: "public, max-age=31536000",
130
+ metadata: {
131
+ firebaseStorageDownloadTokens: downloadToken,
132
+ },
133
+ },
134
+ });
135
+ const publicVideoUrl = `https://firebasestorage.googleapis.com/v0/b/${bucket.name}` +
136
+ `/o/${encodeURIComponent(filePath)}?alt=media&token=${downloadToken}`;
137
+ return {
138
+ videoUrl: publicVideoUrl,
139
+ status: types_1.EVideoSceneStatus.COMPLETED,
140
+ };
141
+ }
142
+ getCreditUsed(params) {
143
+ const modelConfig = aiModels_1.aiModelConfigs[params.modelKey];
144
+ const per1KTokens = params.audio
145
+ ? modelConfig.cost?.audio?.per1KTokens
146
+ : modelConfig.cost?.noAudio?.per1KTokens ?? modelConfig.cost?.per1KTokens;
147
+ if (!per1KTokens || !params.resolution || !params.aspectRatio || !params.duration) {
148
+ logger_1.logger.warn(`Missing cost or parameters for credit calculation. Returning default credits. Params: ${JSON.stringify(params)}, ModelConfig: ${JSON.stringify(modelConfig)}`);
149
+ return 10; // default fallback
150
+ }
151
+ const dims = dimensionsMap[params.resolution]?.[params.aspectRatio];
152
+ if (!dims) {
153
+ logger_1.logger.warn(`Unsupported resolution/aspectRatio for credit calculation. Returning default credits. Params: ${JSON.stringify(params)}`);
154
+ return 10; // default fallback
155
+ }
156
+ const FRAME_RATE = 24;
157
+ const tokensConsumed = Math.ceil((dims.width * dims.height * FRAME_RATE * params.duration) / 1024);
158
+ const cost = (per1KTokens * tokensConsumed) / 1000;
159
+ return (0, helpers_2.getCreditsFromCost)(cost);
160
+ }
161
+ }
162
+ exports.ByteDanceService = ByteDanceService;
163
+ const dimensionsMap = {
164
+ "480p": {
165
+ "16:9": { width: 848, height: 480 },
166
+ "9:16": { width: 480, height: 848 },
167
+ "1:1": { width: 480, height: 480 },
168
+ "4:3": { width: 640, height: 480 },
169
+ "3:4": { width: 480, height: 640 },
170
+ "21:9": { width: 1008, height: 432 },
171
+ },
172
+ "720p": {
173
+ "16:9": { width: 1280, height: 720 },
174
+ "9:16": { width: 720, height: 1280 },
175
+ "1:1": { width: 720, height: 720 },
176
+ "4:3": { width: 960, height: 720 },
177
+ "3:4": { width: 720, height: 960 },
178
+ "21:9": { width: 1680, height: 720 },
179
+ },
180
+ "1080p": {
181
+ "16:9": { width: 1920, height: 1080 },
182
+ "9:16": { width: 1080, height: 1920 },
183
+ "1:1": { width: 1080, height: 1080 },
184
+ "4:3": { width: 1440, height: 1080 },
185
+ "3:4": { width: 1080, height: 1440 },
186
+ "21:9": { width: 2520, height: 1080 },
187
+ },
188
+ };
@@ -0,0 +1,2 @@
1
+ declare const dimensionsMap: Record<string, Record<string, VideoDimensions>>;
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/bytedance/constants.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAyBlE,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ const dimensionsMap = {
3
+ "480p": {
4
+ "21:9": { width: 960, height: 416 },
5
+ "16:9": { width: 864, height: 480 },
6
+ "9:16": { width: 480, height: 864 },
7
+ "1:1": { width: 640, height: 640 },
8
+ "4:3": { width: 736, height: 544 },
9
+ "3:4": { width: 544, height: 736 },
10
+ },
11
+ "720p": {
12
+ "21:9": { width: 1504, height: 640 },
13
+ "16:9": { width: 1248, height: 704 },
14
+ "9:16": { width: 704, height: 1248 },
15
+ "1:1": { width: 960, height: 960 },
16
+ "4:3": { width: 1120, height: 832 },
17
+ "3:4": { width: 832, height: 1120 },
18
+ },
19
+ "1080p": {
20
+ "21:9": { width: 2176, height: 928 },
21
+ "16:9": { width: 1920, height: 1088 },
22
+ "9:16": { width: 1088, height: 1920 },
23
+ "1:1": { width: 1440, height: 1440 },
24
+ "4:3": { width: 1664, height: 1248 },
25
+ "3:4": { width: 1248, height: 1664 },
26
+ },
27
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./bytedance.service";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/bytedance/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./bytedance.service"), exports);
@@ -0,0 +1,5 @@
1
+ type VideoDimensions = {
2
+ width: number;
3
+ height: number;
4
+ };
5
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/bytedance/types.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1 @@
1
+ "use strict";
@@ -24,7 +24,7 @@ class GoogleService extends baseAiGenProvider_service_1.BaseAiGenProviderService
24
24
  (0, helpers_2.validateParams)(params);
25
25
  const modelConfig = aiModels_1.aiModelConfigs[params.modelKey];
26
26
  const modelId = modelConfig.modelId;
27
- console.log("GoogleService.generateVideo - modelId:", modelId, params);
27
+ // console.log("GoogleService.generateVideo - modelId:", modelId, params);
28
28
  const request = {
29
29
  model: modelId,
30
30
  prompt: params.prompt,
@@ -2,11 +2,16 @@ import { BaseAiGenProviderService } from "../baseAiGenProvider.service";
2
2
  import { CreditUsageParams, VideoGenerationParams, VideoGenerationResult, VideoStatusParams, VideoStatusResult } from "../types";
3
3
  export declare class KlingService extends BaseAiGenProviderService {
4
4
  private readonly baseUrl;
5
- private readonly timeout;
5
+ private readonly generateTimeout;
6
+ private readonly statusTimeout;
6
7
  constructor();
7
8
  private request;
8
9
  generateVideo(params: VideoGenerationParams): Promise<VideoGenerationResult>;
9
- checkVideoStatus({ task, outputFilename, outputFilePath, }: VideoStatusParams): Promise<VideoStatusResult>;
10
+ private generateAvatarVideo;
11
+ private requestWithTimeoutRetry;
12
+ checkVideoStatus(params: VideoStatusParams): Promise<VideoStatusResult>;
13
+ private checkRegularVideoStatus;
14
+ private checkAvatarVideoStatus;
10
15
  encodeJwtToken(): string;
11
16
  getCreditUsed({ modelKey, mode, duration, }: CreditUsageParams): number;
12
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"kling.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/kling.service.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAWlB,qBAAa,YAAa,SAAQ,wBAAwB;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;;YAWnB,OAAO;IA6Bf,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA8B3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA8DjD,cAAc,IAAI,MAAM;IAexB,aAAa,CAAC,EACZ,QAAQ,EACR,IAA8B,EAC9B,QAAY,GACb,EAAE,iBAAiB,GAAG,MAAM;CAK9B"}
1
+ {"version":3,"file":"kling.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/kling.service.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAYlB,qBAAa,YAAa,SAAQ,wBAAwB;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAW;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;;YAW1B,OAAO;IA8Bf,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;YAqCnB,mBAAmB;YAqCnB,uBAAuB;IAmC/B,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAO/D,uBAAuB;YAgEvB,sBAAsB;IA6DpC,cAAc,IAAI,MAAM;IAexB,aAAa,CAAC,EACZ,QAAQ,EACR,IAA8B,EAC9B,QAAY,GACb,EAAE,iBAAiB,GAAG,MAAM;CAc9B"}
@@ -10,6 +10,7 @@ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
10
10
  const aiModels_1 = require("../../../../globals/aiModels");
11
11
  const types_1 = require("../../../../globals/types");
12
12
  const firebase_1 = require("../../../../libs/firebase");
13
+ const logger_1 = require("../../../../utils/logger");
13
14
  const helpers_1 = require("../../helpers");
14
15
  const types_2 = require("../../types");
15
16
  const baseAiGenProvider_service_1 = require("../baseAiGenProvider.service");
@@ -18,12 +19,13 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
18
19
  constructor() {
19
20
  super();
20
21
  this.baseUrl = "https://api-singapore.klingai.com";
21
- this.timeout = 60000; // 1 min
22
+ this.generateTimeout = 120000; // 2 min — submit endpoint can be slow under Kling load
23
+ this.statusTimeout = 60000; // 1 min — status/poll should be fast
22
24
  if (!process.env.KLING_SECRET_KEY || !process.env.KLING_ACCESS_KEY) {
23
25
  throw new Error("Missing KLING_SECRET_KEY or KLING_ACCESS_KEY in environment variables");
24
26
  }
25
27
  }
26
- async request(endpoint, method, body) {
28
+ async request(endpoint, method, body, timeout = this.generateTimeout) {
27
29
  const config = {
28
30
  method,
29
31
  url: `${this.baseUrl}${endpoint}`,
@@ -31,7 +33,7 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
31
33
  Authorization: `Bearer ${this.encodeJwtToken()}`,
32
34
  "Content-Type": "application/json",
33
35
  },
34
- timeout: this.timeout,
36
+ timeout,
35
37
  data: body,
36
38
  };
37
39
  const response = await axios_1.default.request(config);
@@ -42,6 +44,9 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
42
44
  }
43
45
  async generateVideo(params) {
44
46
  (0, helpers_1.validateParams)(params);
47
+ if (params.modelKey === "kling-avatar") {
48
+ return this.generateAvatarVideo(params);
49
+ }
45
50
  const modelId = aiModels_1.aiModelConfigs[params.modelKey]?.modelId;
46
51
  if (!modelId)
47
52
  throw new Error(`Unknown modelKey: ${params.modelKey}`);
@@ -53,14 +58,75 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
53
58
  mode: params.mode || types_2.EVideoMode.STANDARD,
54
59
  };
55
60
  const starttime = Date.now();
56
- const task = await this.request("/v1/videos/text2video", "POST", request);
57
- console.log(`Kling generateVideo API call took ${Date.now() - starttime} ms`, task ? `(task ID: ${task.data.task_id})` : "(failed)");
61
+ const task = await this.requestWithTimeoutRetry("/v1/videos/text2video", "POST", request, 4, this.generateTimeout);
62
+ logger_1.logger.info("Kling generateVideo submitted", {
63
+ modelKey: params.modelKey,
64
+ taskId: task.data.task_id,
65
+ durationMs: Date.now() - starttime,
66
+ });
67
+ return { task: task.data.task_id, status: types_1.EVideoSceneStatus.TRIGGERED };
68
+ }
69
+ async generateAvatarVideo(params) {
70
+ if (!params.inputImageUrl) {
71
+ throw new Error("inputImageUrl (avatar face image) is required for Kling Avatar generation");
72
+ }
73
+ if (!params.inputAudioUrl) {
74
+ throw new Error("inputAudioUrl (audio file) is required for Kling Avatar generation");
75
+ }
76
+ const request = {
77
+ image: params.inputImageUrl,
78
+ sound_file: params.inputAudioUrl,
79
+ prompt: params.prompt,
80
+ mode: params.mode || "std",
81
+ };
82
+ const starttime = Date.now();
83
+ // Use requestWithTimeoutRetry so transient Kling server slowness doesn't fail the job outright.
84
+ // generateTimeout (2 min) gives enough headroom; up to 4 attempts before giving up.
85
+ const task = await this.requestWithTimeoutRetry("/v1/videos/avatar/image2video", "POST", request, 4, this.generateTimeout);
86
+ logger_1.logger.info("Kling generateAvatarVideo submitted", {
87
+ taskId: task.data.task_id,
88
+ durationMs: Date.now() - starttime,
89
+ });
58
90
  return { task: task.data.task_id, status: types_1.EVideoSceneStatus.TRIGGERED };
59
91
  }
60
- async checkVideoStatus({ task, outputFilename, outputFilePath = "videos", }) {
92
+ async requestWithTimeoutRetry(endpoint, method, body, maxAttempts = 4, timeout = this.statusTimeout) {
93
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
94
+ try {
95
+ return await this.request(endpoint, method, body, timeout);
96
+ }
97
+ catch (err) {
98
+ const isTimeout = err.code === "ECONNABORTED" || err.message?.includes("timeout");
99
+ const isNetworkError = err.code === "ECONNRESET" ||
100
+ err.code === "ECONNREFUSED" ||
101
+ err.code === "ENOTFOUND" ||
102
+ err.code === "ERR_NETWORK" ||
103
+ err?.name === "AggregateError";
104
+ const isRetryable = isTimeout || isNetworkError;
105
+ if (!isRetryable || attempt === maxAttempts)
106
+ throw err;
107
+ logger_1.logger.warn("Kling request failed with transient error — retrying", {
108
+ endpoint,
109
+ attempt,
110
+ maxAttempts,
111
+ timeoutMs: timeout,
112
+ errorCode: err.code,
113
+ errorName: err?.name,
114
+ });
115
+ await new Promise((r) => setTimeout(r, 1000));
116
+ }
117
+ }
118
+ throw new Error("Unreachable");
119
+ }
120
+ async checkVideoStatus(params) {
121
+ if (params.modelKey === "kling-avatar") {
122
+ return this.checkAvatarVideoStatus(params);
123
+ }
124
+ return this.checkRegularVideoStatus(params);
125
+ }
126
+ async checkRegularVideoStatus({ task, outputFilename, outputFilePath = "videos", }) {
61
127
  const startTime = Date.now();
62
- const result = await this.request(`/v1/videos/text2video/${task}`, "GET");
63
- console.log(`Kling checkVideoStatus API call took ${Date.now() - startTime} ms`);
128
+ const result = await this.requestWithTimeoutRetry(`/v1/videos/text2video/${task}`, "GET");
129
+ logger_1.logger.info("Kling checkVideoStatus polled", { task, durationMs: Date.now() - startTime, status: result?.data?.task_status });
64
130
  if (!result) {
65
131
  return {
66
132
  status: types_1.EVideoSceneStatus.FAILED,
@@ -78,10 +144,53 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
78
144
  // console.log("Kling video URL:", videoUrl);
79
145
  const filePath = `${outputFilePath}/${outputFilename}.mp4`;
80
146
  const file = (0, firebase_1.getBucket)().file(filePath);
81
- // Download video using axios
147
+ // Download video using axios — use generateTimeout since video files can be large
82
148
  const videoResp = await axios_1.default.get(videoUrl, {
83
149
  responseType: "arraybuffer",
84
- timeout: this.timeout,
150
+ timeout: this.generateTimeout,
151
+ });
152
+ const buffer = Buffer.from(videoResp.data);
153
+ await file.save(buffer, { contentType: "video/mp4" });
154
+ const [signedUrl] = await file.getSignedUrl({
155
+ action: "read",
156
+ expires: "03-09-2491",
157
+ });
158
+ return {
159
+ videoUrl: signedUrl,
160
+ status: types_1.EVideoSceneStatus.COMPLETED,
161
+ };
162
+ }
163
+ if (result.data.task_status === "failed") {
164
+ return {
165
+ status: types_1.EVideoSceneStatus.FAILED,
166
+ errorMessage: `${result.code}: ${result.message}`,
167
+ };
168
+ }
169
+ return { status: types_1.EVideoSceneStatus.PENDING };
170
+ }
171
+ async checkAvatarVideoStatus({ task, outputFilename, outputFilePath = "videos", }) {
172
+ const startTime = Date.now();
173
+ const result = await this.requestWithTimeoutRetry(`/v1/videos/avatar/image2video/${task}`, "GET");
174
+ logger_1.logger.info("Kling checkAvatarVideoStatus polled", { task, durationMs: Date.now() - startTime, status: result?.data?.task_status });
175
+ if (!result) {
176
+ return {
177
+ status: types_1.EVideoSceneStatus.FAILED,
178
+ errorMessage: "No response from Kling Avatar API",
179
+ };
180
+ }
181
+ if (result.data.task_status === "succeed") {
182
+ const videoUrl = result.data.task_result?.videos?.[0]?.url;
183
+ if (!videoUrl) {
184
+ return {
185
+ status: types_1.EVideoSceneStatus.FAILED,
186
+ errorMessage: "No video URL in avatar response",
187
+ };
188
+ }
189
+ const filePath = `${outputFilePath}/${outputFilename}.mp4`;
190
+ const file = (0, firebase_1.getBucket)().file(filePath);
191
+ const videoResp = await axios_1.default.get(videoUrl, {
192
+ responseType: "arraybuffer",
193
+ timeout: this.generateTimeout,
85
194
  });
86
195
  const buffer = Buffer.from(videoResp.data);
87
196
  await file.save(buffer, { contentType: "video/mp4" });
@@ -116,6 +225,13 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
116
225
  }
117
226
  getCreditUsed({ modelKey, mode = types_2.EVideoMode.PROFESSIONAL, duration = 5, }) {
118
227
  const modelConfig = aiModels_1.aiModelConfigs[modelKey];
228
+ // Avatar: per-second pricing based on mode
229
+ if (modelKey === "kling-avatar") {
230
+ const perSecond = modelConfig?.cost?.[mode]?.perSecond
231
+ ?? modelConfig?.cost?.["std"]?.perSecond
232
+ ?? 0.014;
233
+ return (0, helpers_2.getCreditsFromCost)(perSecond * duration);
234
+ }
119
235
  const cost = modelConfig?.cost?.table?.[mode]?.[duration];
120
236
  return (0, helpers_2.getCreditsFromCost)(cost ?? 1);
121
237
  }
@@ -68,6 +68,19 @@ export interface TaskResult {
68
68
  export interface VideoResult {
69
69
  id: string;
70
70
  url: string;
71
+ watermark_url?: string;
71
72
  duration: string;
72
73
  }
74
+ export interface KlingAvatarGenerateRequest {
75
+ image: string;
76
+ audio_id?: string;
77
+ sound_file?: string;
78
+ prompt?: string;
79
+ mode?: "std" | "pro";
80
+ watermark_info?: {
81
+ enabled: boolean;
82
+ };
83
+ callback_url?: string;
84
+ external_task_id?: string;
85
+ }
73
86
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC/D,SAAS,EAAE,QAAQ,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,YAAY,GACZ,iBAAiB,GACjB,mBAAmB,CAAC;AAExB,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,oBAAoB,GACpB,mBAAmB,CAAC;AAExB,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,CAAC;AAEnC,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAGD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,UAAU,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,QAAQ,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,UAAU,CAAC;CAC1B;AAED,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3E,MAAM,WAAW,QAAQ;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC/D,SAAS,EAAE,QAAQ,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,YAAY,GACZ,iBAAiB,GACjB,mBAAmB,CAAC;AAExB,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,oBAAoB,GACpB,mBAAmB,CAAC;AAExB,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,CAAC;AAEnC,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAGD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,UAAU,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,QAAQ,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,UAAU,CAAC;CAC1B;AAED,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3E,MAAM,WAAW,QAAQ;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACrB,cAAc,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,9 @@
1
+ import { BaseAiGenProviderService } from "../baseAiGenProvider.service";
2
+ import { CreditUsageParams, VideoGenerationParams, VideoGenerationResult, VideoStatusParams, VideoStatusResult } from "../types";
3
+ export declare class PixVerseService extends BaseAiGenProviderService {
4
+ private readonly baseUrl;
5
+ generateVideo(params: VideoGenerationParams): Promise<VideoGenerationResult>;
6
+ checkVideoStatus({ task, outputFilename, outputFilePath, }: VideoStatusParams): Promise<VideoStatusResult>;
7
+ getCreditUsed(params: CreditUsageParams): number;
8
+ }
9
+ //# sourceMappingURL=pixverse.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixverse.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/pixverse/pixverse.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AASlB,qBAAa,eAAgB,SAAQ,wBAAwB;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkD;IAKpE,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAqE3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmGjD,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CA+CjD"}