@openinary/core 1.1.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.
Files changed (242) hide show
  1. package/LICENSE +661 -0
  2. package/dist/config/deps.d.ts +14 -0
  3. package/dist/config/deps.d.ts.map +1 -0
  4. package/dist/config/deps.js +2 -0
  5. package/dist/config/deps.js.map +1 -0
  6. package/dist/index.d.ts +27 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +28 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/routes/authenticated.d.ts +4 -0
  11. package/dist/routes/authenticated.d.ts.map +1 -0
  12. package/dist/routes/authenticated.js +130 -0
  13. package/dist/routes/authenticated.js.map +1 -0
  14. package/dist/routes/download-folder.d.ts +4 -0
  15. package/dist/routes/download-folder.d.ts.map +1 -0
  16. package/dist/routes/download-folder.js +101 -0
  17. package/dist/routes/download-folder.js.map +1 -0
  18. package/dist/routes/download-zip.d.ts +15 -0
  19. package/dist/routes/download-zip.d.ts.map +1 -0
  20. package/dist/routes/download-zip.js +147 -0
  21. package/dist/routes/download-zip.js.map +1 -0
  22. package/dist/routes/download.d.ts +4 -0
  23. package/dist/routes/download.d.ts.map +1 -0
  24. package/dist/routes/download.js +83 -0
  25. package/dist/routes/download.js.map +1 -0
  26. package/dist/routes/invalidate.d.ts +4 -0
  27. package/dist/routes/invalidate.d.ts.map +1 -0
  28. package/dist/routes/invalidate.js +114 -0
  29. package/dist/routes/invalidate.js.map +1 -0
  30. package/dist/routes/queue-events.d.ts +4 -0
  31. package/dist/routes/queue-events.d.ts.map +1 -0
  32. package/dist/routes/queue-events.js +125 -0
  33. package/dist/routes/queue-events.js.map +1 -0
  34. package/dist/routes/queue.d.ts +4 -0
  35. package/dist/routes/queue.d.ts.map +1 -0
  36. package/dist/routes/queue.js +130 -0
  37. package/dist/routes/queue.js.map +1 -0
  38. package/dist/routes/storage.d.ts +4 -0
  39. package/dist/routes/storage.d.ts.map +1 -0
  40. package/dist/routes/storage.js +694 -0
  41. package/dist/routes/storage.js.map +1 -0
  42. package/dist/routes/transform-helpers.d.ts +62 -0
  43. package/dist/routes/transform-helpers.d.ts.map +1 -0
  44. package/dist/routes/transform-helpers.js +372 -0
  45. package/dist/routes/transform-helpers.js.map +1 -0
  46. package/dist/routes/transform.d.ts +4 -0
  47. package/dist/routes/transform.d.ts.map +1 -0
  48. package/dist/routes/transform.js +65 -0
  49. package/dist/routes/transform.js.map +1 -0
  50. package/dist/routes/video-status.d.ts +4 -0
  51. package/dist/routes/video-status.d.ts.map +1 -0
  52. package/dist/routes/video-status.js +208 -0
  53. package/dist/routes/video-status.js.map +1 -0
  54. package/dist/services/transform.service.d.ts +71 -0
  55. package/dist/services/transform.service.d.ts.map +1 -0
  56. package/dist/services/transform.service.js +362 -0
  57. package/dist/services/transform.service.js.map +1 -0
  58. package/dist/types.d.ts +82 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/dist/types.js +2 -0
  61. package/dist/types.js.map +1 -0
  62. package/dist/utils/asset-deletion.d.ts +16 -0
  63. package/dist/utils/asset-deletion.d.ts.map +1 -0
  64. package/dist/utils/asset-deletion.js +131 -0
  65. package/dist/utils/asset-deletion.js.map +1 -0
  66. package/dist/utils/cache.d.ts +44 -0
  67. package/dist/utils/cache.d.ts.map +1 -0
  68. package/dist/utils/cache.js +248 -0
  69. package/dist/utils/cache.js.map +1 -0
  70. package/dist/utils/get-unique-file-path.d.ts +8 -0
  71. package/dist/utils/get-unique-file-path.d.ts.map +1 -0
  72. package/dist/utils/get-unique-file-path.js +26 -0
  73. package/dist/utils/get-unique-file-path.js.map +1 -0
  74. package/dist/utils/image/aspect-ratio.d.ts +7 -0
  75. package/dist/utils/image/aspect-ratio.d.ts.map +1 -0
  76. package/dist/utils/image/aspect-ratio.js +40 -0
  77. package/dist/utils/image/aspect-ratio.js.map +1 -0
  78. package/dist/utils/image/background.d.ts +6 -0
  79. package/dist/utils/image/background.d.ts.map +1 -0
  80. package/dist/utils/image/background.js +22 -0
  81. package/dist/utils/image/background.js.map +1 -0
  82. package/dist/utils/image/compression.d.ts +44 -0
  83. package/dist/utils/image/compression.d.ts.map +1 -0
  84. package/dist/utils/image/compression.js +345 -0
  85. package/dist/utils/image/compression.js.map +1 -0
  86. package/dist/utils/image/gravity.d.ts +6 -0
  87. package/dist/utils/image/gravity.d.ts.map +1 -0
  88. package/dist/utils/image/gravity.js +24 -0
  89. package/dist/utils/image/gravity.js.map +1 -0
  90. package/dist/utils/image/index.d.ts +8 -0
  91. package/dist/utils/image/index.d.ts.map +1 -0
  92. package/dist/utils/image/index.js +77 -0
  93. package/dist/utils/image/index.js.map +1 -0
  94. package/dist/utils/image/param-registry.d.ts +63 -0
  95. package/dist/utils/image/param-registry.d.ts.map +1 -0
  96. package/dist/utils/image/param-registry.js +196 -0
  97. package/dist/utils/image/param-registry.js.map +1 -0
  98. package/dist/utils/image/quality.d.ts +8 -0
  99. package/dist/utils/image/quality.d.ts.map +1 -0
  100. package/dist/utils/image/quality.js +9 -0
  101. package/dist/utils/image/quality.js.map +1 -0
  102. package/dist/utils/image/resize.d.ts +7 -0
  103. package/dist/utils/image/resize.d.ts.map +1 -0
  104. package/dist/utils/image/resize.js +62 -0
  105. package/dist/utils/image/resize.js.map +1 -0
  106. package/dist/utils/image/rotation.d.ts +6 -0
  107. package/dist/utils/image/rotation.d.ts.map +1 -0
  108. package/dist/utils/image/rotation.js +20 -0
  109. package/dist/utils/image/rotation.js.map +1 -0
  110. package/dist/utils/image/round-corners.d.ts +12 -0
  111. package/dist/utils/image/round-corners.d.ts.map +1 -0
  112. package/dist/utils/image/round-corners.js +102 -0
  113. package/dist/utils/image/round-corners.js.map +1 -0
  114. package/dist/utils/image/types.d.ts +2 -0
  115. package/dist/utils/image/types.d.ts.map +1 -0
  116. package/dist/utils/image/types.js +2 -0
  117. package/dist/utils/image/types.js.map +1 -0
  118. package/dist/utils/logger.d.ts +21 -0
  119. package/dist/utils/logger.d.ts.map +1 -0
  120. package/dist/utils/logger.js +82 -0
  121. package/dist/utils/logger.js.map +1 -0
  122. package/dist/utils/parser.d.ts +8 -0
  123. package/dist/utils/parser.d.ts.map +1 -0
  124. package/dist/utils/parser.js +226 -0
  125. package/dist/utils/parser.js.map +1 -0
  126. package/dist/utils/signature.d.ts +35 -0
  127. package/dist/utils/signature.d.ts.map +1 -0
  128. package/dist/utils/signature.js +100 -0
  129. package/dist/utils/signature.js.map +1 -0
  130. package/dist/utils/storage/cache.d.ts +41 -0
  131. package/dist/utils/storage/cache.d.ts.map +1 -0
  132. package/dist/utils/storage/cache.js +90 -0
  133. package/dist/utils/storage/cache.js.map +1 -0
  134. package/dist/utils/storage/cloud-storage.d.ts +188 -0
  135. package/dist/utils/storage/cloud-storage.d.ts.map +1 -0
  136. package/dist/utils/storage/cloud-storage.js +514 -0
  137. package/dist/utils/storage/cloud-storage.js.map +1 -0
  138. package/dist/utils/storage/factory.d.ts +10 -0
  139. package/dist/utils/storage/factory.d.ts.map +1 -0
  140. package/dist/utils/storage/factory.js +17 -0
  141. package/dist/utils/storage/factory.js.map +1 -0
  142. package/dist/utils/storage/index.d.ts +7 -0
  143. package/dist/utils/storage/index.d.ts.map +1 -0
  144. package/dist/utils/storage/index.js +8 -0
  145. package/dist/utils/storage/index.js.map +1 -0
  146. package/dist/utils/storage/key-generator.d.ts +11 -0
  147. package/dist/utils/storage/key-generator.d.ts.map +1 -0
  148. package/dist/utils/storage/key-generator.js +23 -0
  149. package/dist/utils/storage/key-generator.js.map +1 -0
  150. package/dist/utils/storage/listing-cache.d.ts +14 -0
  151. package/dist/utils/storage/listing-cache.d.ts.map +1 -0
  152. package/dist/utils/storage/listing-cache.js +29 -0
  153. package/dist/utils/storage/listing-cache.js.map +1 -0
  154. package/dist/utils/storage/s3-client.d.ts +97 -0
  155. package/dist/utils/storage/s3-client.d.ts.map +1 -0
  156. package/dist/utils/storage/s3-client.js +297 -0
  157. package/dist/utils/storage/s3-client.js.map +1 -0
  158. package/dist/utils/storage/stats-tracker.d.ts +45 -0
  159. package/dist/utils/storage/stats-tracker.d.ts.map +1 -0
  160. package/dist/utils/storage/stats-tracker.js +97 -0
  161. package/dist/utils/storage/stats-tracker.js.map +1 -0
  162. package/dist/utils/storage/types.d.ts +2 -0
  163. package/dist/utils/storage/types.d.ts.map +1 -0
  164. package/dist/utils/storage/types.js +2 -0
  165. package/dist/utils/storage/types.js.map +1 -0
  166. package/dist/utils/storage-level.d.ts +66 -0
  167. package/dist/utils/storage-level.d.ts.map +1 -0
  168. package/dist/utils/storage-level.js +106 -0
  169. package/dist/utils/storage-level.js.map +1 -0
  170. package/dist/utils/storage-tree.d.ts +30 -0
  171. package/dist/utils/storage-tree.d.ts.map +1 -0
  172. package/dist/utils/storage-tree.js +81 -0
  173. package/dist/utils/storage-tree.js.map +1 -0
  174. package/dist/utils/upload-signature.d.ts +25 -0
  175. package/dist/utils/upload-signature.d.ts.map +1 -0
  176. package/dist/utils/upload-signature.js +56 -0
  177. package/dist/utils/upload-signature.js.map +1 -0
  178. package/dist/utils/video/auto-downscale.d.ts +12 -0
  179. package/dist/utils/video/auto-downscale.d.ts.map +1 -0
  180. package/dist/utils/video/auto-downscale.js +29 -0
  181. package/dist/utils/video/auto-downscale.js.map +1 -0
  182. package/dist/utils/video/command-builder.d.ts +22 -0
  183. package/dist/utils/video/command-builder.d.ts.map +1 -0
  184. package/dist/utils/video/command-builder.js +79 -0
  185. package/dist/utils/video/command-builder.js.map +1 -0
  186. package/dist/utils/video/config.d.ts +51 -0
  187. package/dist/utils/video/config.d.ts.map +1 -0
  188. package/dist/utils/video/config.js +170 -0
  189. package/dist/utils/video/config.js.map +1 -0
  190. package/dist/utils/video/format.d.ts +22 -0
  191. package/dist/utils/video/format.d.ts.map +1 -0
  192. package/dist/utils/video/format.js +64 -0
  193. package/dist/utils/video/format.js.map +1 -0
  194. package/dist/utils/video/index.d.ts +25 -0
  195. package/dist/utils/video/index.d.ts.map +1 -0
  196. package/dist/utils/video/index.js +104 -0
  197. package/dist/utils/video/index.js.map +1 -0
  198. package/dist/utils/video/param-registry.d.ts +64 -0
  199. package/dist/utils/video/param-registry.d.ts.map +1 -0
  200. package/dist/utils/video/param-registry.js +201 -0
  201. package/dist/utils/video/param-registry.js.map +1 -0
  202. package/dist/utils/video/quality.d.ts +12 -0
  203. package/dist/utils/video/quality.d.ts.map +1 -0
  204. package/dist/utils/video/quality.js +45 -0
  205. package/dist/utils/video/quality.js.map +1 -0
  206. package/dist/utils/video/queue-store.d.ts +51 -0
  207. package/dist/utils/video/queue-store.d.ts.map +1 -0
  208. package/dist/utils/video/queue-store.js +2 -0
  209. package/dist/utils/video/queue-store.js.map +1 -0
  210. package/dist/utils/video/resize.d.ts +7 -0
  211. package/dist/utils/video/resize.d.ts.map +1 -0
  212. package/dist/utils/video/resize.js +40 -0
  213. package/dist/utils/video/resize.js.map +1 -0
  214. package/dist/utils/video/sqlite-video-job-store.d.ts +29 -0
  215. package/dist/utils/video/sqlite-video-job-store.d.ts.map +1 -0
  216. package/dist/utils/video/sqlite-video-job-store.js +320 -0
  217. package/dist/utils/video/sqlite-video-job-store.js.map +1 -0
  218. package/dist/utils/video/thumbnail.d.ts +7 -0
  219. package/dist/utils/video/thumbnail.d.ts.map +1 -0
  220. package/dist/utils/video/thumbnail.js +22 -0
  221. package/dist/utils/video/thumbnail.js.map +1 -0
  222. package/dist/utils/video/trim.d.ts +7 -0
  223. package/dist/utils/video/trim.d.ts.map +1 -0
  224. package/dist/utils/video/trim.js +36 -0
  225. package/dist/utils/video/trim.js.map +1 -0
  226. package/dist/utils/video/types.d.ts +19 -0
  227. package/dist/utils/video/types.d.ts.map +1 -0
  228. package/dist/utils/video/types.js +2 -0
  229. package/dist/utils/video/types.js.map +1 -0
  230. package/dist/utils/video/video-info.d.ts +25 -0
  231. package/dist/utils/video/video-info.d.ts.map +1 -0
  232. package/dist/utils/video/video-info.js +58 -0
  233. package/dist/utils/video/video-info.js.map +1 -0
  234. package/dist/utils/video/video-worker.d.ts +52 -0
  235. package/dist/utils/video/video-worker.d.ts.map +1 -0
  236. package/dist/utils/video/video-worker.js +192 -0
  237. package/dist/utils/video/video-worker.js.map +1 -0
  238. package/dist/utils/video-job-queue.d.ts +62 -0
  239. package/dist/utils/video-job-queue.d.ts.map +1 -0
  240. package/dist/utils/video-job-queue.js +122 -0
  241. package/dist/utils/video-job-queue.js.map +1 -0
  242. package/package.json +51 -0
@@ -0,0 +1,201 @@
1
+ import { applyResize } from './resize.js';
2
+ import { applyQuality } from './quality.js';
3
+ import { applyTrimming } from './trim.js';
4
+ import { applyThumbnailExtraction } from './thumbnail.js';
5
+ /**
6
+ * Complete parameter registry for video transformations
7
+ * Single source of truth for all video transformation parameters
8
+ */
9
+ export const VIDEO_PARAMS = [
10
+ {
11
+ param: 't',
12
+ name: 'Thumbnail',
13
+ description: 'Extracts a single frame as an image thumbnail. When enabled, the output will be an image format (jpg, png, webp, etc.) instead of a video.',
14
+ example: 't_true',
15
+ defaultValue: false,
16
+ validValues: ['true', 'false', '1', '0'],
17
+ processor: (command, _value, context) => {
18
+ return applyThumbnailExtraction(command, context);
19
+ },
20
+ priority: 1, // Thumbnail extraction should happen first
21
+ },
22
+ {
23
+ param: 'tt',
24
+ name: 'Thumbnail Time',
25
+ description: 'Specifies the time (in seconds) from which to extract the thumbnail. Works in conjunction with the thumbnail parameter.',
26
+ example: 'tt_5.5',
27
+ defaultValue: 0,
28
+ validValues: ['any positive number (seconds)'],
29
+ aliases: ['thumbnail_time'],
30
+ dependencies: ['t'],
31
+ processor: (command, _value, context) => {
32
+ // Thumbnail time is used by thumbnail extraction
33
+ return command;
34
+ },
35
+ priority: 0, // Config parameter
36
+ },
37
+ {
38
+ param: 'so',
39
+ name: 'Start Offset',
40
+ description: 'Trims the video by starting from the specified time in seconds. Can be used alone or with end offset.',
41
+ example: 'so_10',
42
+ validValues: ['any positive number (seconds)'],
43
+ aliases: ['start_offset', 'start'],
44
+ processor: (command, _value, context) => {
45
+ return applyTrimming(command, context);
46
+ },
47
+ priority: 2, // Trimming before resize
48
+ },
49
+ {
50
+ param: 'eo',
51
+ name: 'End Offset',
52
+ description: 'Trims the video by ending at the specified time in seconds. If used with start offset, creates a segment between the two times.',
53
+ example: 'eo_30',
54
+ validValues: ['any positive number (seconds)'],
55
+ aliases: ['end_offset', 'end'],
56
+ processor: (command, _value, context) => {
57
+ // End offset is processed together with start offset in trim
58
+ return command;
59
+ },
60
+ priority: 2, // Trimming before resize
61
+ },
62
+ {
63
+ param: 'w',
64
+ name: 'Width',
65
+ description: 'Sets the width of the video in pixels. Should be used with height for proper scaling.',
66
+ example: 'w_1280',
67
+ validValues: ['any positive integer'],
68
+ processor: (command, _value, context) => {
69
+ // Width is processed together with height in the resize step
70
+ return command;
71
+ },
72
+ priority: 3, // Resize operations
73
+ },
74
+ {
75
+ param: 'h',
76
+ name: 'Height',
77
+ description: 'Sets the height of the video in pixels. Should be used with width for proper scaling.',
78
+ example: 'h_720',
79
+ validValues: ['any positive integer'],
80
+ processor: (command, _value, context) => {
81
+ // Height is processed together with width in the resize step
82
+ return command;
83
+ },
84
+ priority: 3, // Resize operations
85
+ },
86
+ {
87
+ param: 'r',
88
+ name: 'Resize',
89
+ description: 'Specifies dimensions in WxH format (e.g., 1280x720). Alternative to using separate width and height parameters.',
90
+ example: 'r_1920x1080',
91
+ validValues: ['WxH format (e.g., 1920x1080)'],
92
+ aliases: ['resize', 'size'],
93
+ processor: (command, _value, context) => {
94
+ return applyResize(command, context);
95
+ },
96
+ priority: 3, // Resize operations
97
+ },
98
+ {
99
+ param: 'c',
100
+ name: 'Crop Mode',
101
+ description: 'Defines how the video should be resized. Options: fill/crop (cover entire area with cropping, no stretching), fit (fit within dimensions maintaining aspect ratio), scale (exact dimensions, may stretch), pad (fit within dimensions and pad with background).',
102
+ example: 'c_fill',
103
+ defaultValue: 'fill',
104
+ validValues: ['fill', 'fit', 'scale', 'crop', 'pad'],
105
+ aliases: ['crop_mode'],
106
+ dependencies: ['w', 'h'],
107
+ processor: (command, _value, context) => {
108
+ // Crop mode is applied together with width/height in applyResize
109
+ return command;
110
+ },
111
+ priority: 3, // Resize operations
112
+ },
113
+ {
114
+ param: 'g',
115
+ name: 'Gravity',
116
+ description: 'Defines the focal point when cropping (future support). Options: center (center), north (top), south (bottom), east (right), west (left), auto (entropy-based).',
117
+ example: 'g_center',
118
+ defaultValue: 'center',
119
+ validValues: ['center', 'north', 'south', 'east', 'west', 'auto'],
120
+ aliases: ['gravity'],
121
+ processor: (command, _value, context) => {
122
+ // Gravity will be used by resize operations (not yet fully implemented)
123
+ return command;
124
+ },
125
+ priority: 0, // Config parameter
126
+ },
127
+ {
128
+ param: 'q',
129
+ name: 'Quality',
130
+ description: 'Sets the quality of the output video (0-100). Uses CRF (Constant Rate Factor) encoding. Higher values produce better quality and larger files. Quality 100 ≈ CRF 18, Quality 50 ≈ CRF 28.',
131
+ example: 'q_80',
132
+ defaultValue: undefined,
133
+ validValues: ['0-100'],
134
+ processor: (command, _value, context) => {
135
+ return applyQuality(command, context);
136
+ },
137
+ priority: 4, // Quality after transformations
138
+ },
139
+ {
140
+ param: 'f',
141
+ name: 'Format',
142
+ description: 'Specifies the output format. Video formats: mp4, mov, webm. Image formats (for thumbnails): jpg, jpeg, png, webp, avif, gif. If not specified, defaults to mp4 for videos or jpg for thumbnails.',
143
+ example: 'f_webm',
144
+ defaultValue: 'mp4',
145
+ validValues: ['mp4', 'mov', 'webm', 'jpg', 'jpeg', 'png', 'webp', 'avif', 'gif'],
146
+ aliases: ['format'],
147
+ processor: (command, _value, context) => {
148
+ // Format is handled by the determineOutputFormat function
149
+ return command;
150
+ },
151
+ priority: 5, // Format conversion last
152
+ },
153
+ ];
154
+ /**
155
+ * Helper function to apply resize with all related parameters
156
+ * This is a composite operation that uses w, h, r, c, and g parameters
157
+ */
158
+ export const applyResizeComposite = (command, context) => {
159
+ const { resize, width, height } = context.params;
160
+ if (!width && !height && !resize) {
161
+ return command;
162
+ }
163
+ return applyResize(command, context);
164
+ };
165
+ /**
166
+ * Get parameter definition by param key
167
+ */
168
+ export const getVideoParamDefinition = (param) => {
169
+ return VIDEO_PARAMS.find(p => p.param === param || p.aliases?.includes(param));
170
+ };
171
+ /**
172
+ * Get all parameter definitions sorted by priority
173
+ */
174
+ export const getVideoParamsByPriority = () => {
175
+ return [...VIDEO_PARAMS].sort((a, b) => a.priority - b.priority);
176
+ };
177
+ /**
178
+ * Get default value for a parameter
179
+ */
180
+ export const getVideoParamDefault = (param) => {
181
+ const def = getVideoParamDefinition(param);
182
+ return def?.defaultValue;
183
+ };
184
+ /**
185
+ * Validate if a parameter value is valid
186
+ */
187
+ export const isValidVideoParamValue = (param, value) => {
188
+ const def = getVideoParamDefinition(param);
189
+ if (!def)
190
+ return false;
191
+ // If no validValues specified, assume any value is valid
192
+ if (!def.validValues || def.validValues.length === 0)
193
+ return true;
194
+ // Check if value matches any valid value or pattern
195
+ return def.validValues.some(valid => {
196
+ if (valid.includes('any'))
197
+ return true; // Pattern like "any positive integer"
198
+ return value === valid || value.startsWith(valid);
199
+ });
200
+ };
201
+ //# sourceMappingURL=param-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"param-registry.js","sourceRoot":"","sources":["../../../src/utils/video/param-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { TransformFunction } from './types';
2
+ /**
3
+ * Apply quality settings to a video using CRF (Constant Rate Factor)
4
+ * CRF range: 0 (lossless) to 51 (lowest quality)
5
+ *
6
+ * Quality mapping:
7
+ * - quality 100 → CRF 18 (very high quality)
8
+ * - quality 50 → CRF 28 (medium quality)
9
+ * - quality 10 → CRF 45 (low quality)
10
+ */
11
+ export declare const applyQuality: TransformFunction;
12
+ //# sourceMappingURL=quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../../src/utils/video/quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,iBA0C1B,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Apply quality settings to a video using CRF (Constant Rate Factor)
3
+ * CRF range: 0 (lossless) to 51 (lowest quality)
4
+ *
5
+ * Quality mapping:
6
+ * - quality 100 → CRF 18 (very high quality)
7
+ * - quality 50 → CRF 28 (medium quality)
8
+ * - quality 10 → CRF 45 (low quality)
9
+ */
10
+ export const applyQuality = (command, context) => {
11
+ // Skip quality settings for thumbnail extraction
12
+ if (context.isThumbnail) {
13
+ return command;
14
+ }
15
+ const { quality } = context.params;
16
+ // Default quality if not specified: 60 (CRF 31 - faster encoding for 8K)
17
+ // This prevents ffmpeg from re-encoding without compression
18
+ // Lower quality = faster encoding, especially important for 8K videos
19
+ const defaultQuality = 60;
20
+ const qualityValue = quality !== undefined
21
+ ? (typeof quality === 'string' ? parseInt(quality, 10) : quality)
22
+ : defaultQuality;
23
+ // Validate quality range (0-100)
24
+ if (isNaN(qualityValue) || qualityValue < 0 || qualityValue > 100) {
25
+ // Use default if invalid
26
+ const crf = Math.round(51 - (defaultQuality / 100) * 33);
27
+ return command
28
+ .videoCodec('libx264')
29
+ .addOption('-preset', 'ultrafast') // Ultra fast preset for local dev
30
+ .addOption('-crf', crf.toString())
31
+ .audioCodec('copy'); // Copy audio without re-encoding
32
+ }
33
+ // Convert quality (0-100) to CRF (51-0)
34
+ // Higher quality = lower CRF
35
+ const crf = Math.round(51 - (qualityValue / 100) * 33);
36
+ return command
37
+ .videoCodec('libx264')
38
+ .addOption('-preset', 'ultrafast')
39
+ .addOption('-crf', crf.toString())
40
+ .addOption('-tune', 'fastdecode') // Optimize for fast decoding
41
+ .addOption('-profile:v', 'baseline') // Use baseline profile for compatibility & speed
42
+ .addOption('-level', '3.0') // Lower level = simpler encoding
43
+ .audioCodec('copy'); // Copy audio without re-encoding
44
+ };
45
+ //# sourceMappingURL=quality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.js","sourceRoot":"","sources":["../../../src/utils/video/quality.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAAsB,CAC7C,OAAO,EACP,OAAO,EACP,EAAE;IACF,iDAAiD;IACjD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAEnC,yEAAyE;IACzE,4DAA4D;IAC5D,sEAAsE;IACtE,MAAM,cAAc,GAAG,EAAE,CAAC;IAC1B,MAAM,YAAY,GAAG,OAAO,KAAK,SAAS;QACxC,CAAC,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACjE,CAAC,CAAC,cAAc,CAAC;IAEnB,iCAAiC;IACjC,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,GAAG,EAAE,CAAC;QAClE,yBAAyB;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,cAAc,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QACzD,OAAO,OAAO;aACX,UAAU,CAAC,SAAS,CAAC;aACrB,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAE,kCAAkC;aACrE,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;aACjC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAE,iCAAiC;IAC3D,CAAC;IAED,wCAAwC;IACxC,6BAA6B;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IAEvD,OAAO,OAAO;SACX,UAAU,CAAC,SAAS,CAAC;SACrB,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC;SACjC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;SACjC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAI,6BAA6B;SACjE,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,iDAAiD;SACrF,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAU,iCAAiC;SACrE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAE,iCAAiC;AAC3D,CAAC,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { parseParams } from "../parser";
2
+ export type JobStatus = "pending" | "processing" | "completed" | "error" | "cancelled";
3
+ export interface VideoJob {
4
+ id: string;
5
+ file_path: string;
6
+ params_json: string;
7
+ cache_path: string;
8
+ status: JobStatus;
9
+ priority: number;
10
+ progress: number;
11
+ error: string | null;
12
+ retry_count: number;
13
+ max_retries: number;
14
+ created_at: number;
15
+ started_at: number | null;
16
+ completed_at: number | null;
17
+ }
18
+ export interface JobStats {
19
+ total: number;
20
+ pending: number;
21
+ processing: number;
22
+ completed: number;
23
+ error: number;
24
+ }
25
+ /**
26
+ * Persistence contract for the video transformation queue. The self-hosted
27
+ * app backs this with SQLite (see sqlite-video-job-store.ts); a multi-tenant
28
+ * deployment can implement the same contract against a different backend
29
+ * (e.g. Cloudflare D1) without touching VideoJobQueue, VideoWorker, or any
30
+ * route that depends on this interface instead of a concrete database.
31
+ */
32
+ export interface VideoJobStore {
33
+ createJob(filePath: string, params: ReturnType<typeof parseParams>, cachePath: string, priority?: number): string;
34
+ /** Atomically claims and returns the next pending job, or null if none. */
35
+ getNextPendingJob(): VideoJob | null;
36
+ updateJobStatus(jobId: string, status: JobStatus, progress?: number, error?: string): void;
37
+ getJobByFileAndParams(filePath: string, params: ReturnType<typeof parseParams>): VideoJob | null;
38
+ getJobById(jobId: string): VideoJob | null;
39
+ getJobStats(): JobStats;
40
+ getRecentJobs(limit?: number, offset?: number): VideoJob[];
41
+ getJobsByStatus(status: JobStatus, limit?: number): VideoJob[];
42
+ countProcessingJobs(): number;
43
+ cleanupOldJobs(olderThanHours?: number): number;
44
+ retryFailedJob(jobId: string): boolean;
45
+ cancelJob(jobId: string): boolean;
46
+ deleteJob(jobId: string): boolean;
47
+ /** Resets jobs orphaned by a crash/restart (stuck in "processing") back to "pending". */
48
+ resetOrphanedProcessingJobs(): number;
49
+ deleteJobsByFilePath(filePath: string): number;
50
+ }
51
+ //# sourceMappingURL=queue-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-store.d.ts","sourceRoot":"","sources":["../../../src/utils/video/queue-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,YAAY,GACZ,WAAW,GACX,OAAO,GACP,WAAW,CAAC;AAEhB,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,EACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAAC;IAEV,2EAA2E;IAC3E,iBAAiB,IAAI,QAAQ,GAAG,IAAI,CAAC;IAErC,eAAe,CACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAAC;IAER,qBAAqB,CACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,GACrC,QAAQ,GAAG,IAAI,CAAC;IAEnB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAE3C,WAAW,IAAI,QAAQ,CAAC;IAExB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IAE3D,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IAE/D,mBAAmB,IAAI,MAAM,CAAC;IAE9B,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEhD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAEvC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAElC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAElC,yFAAyF;IACzF,2BAA2B,IAAI,MAAM,CAAC;IAEtC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAChD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=queue-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-store.js","sourceRoot":"","sources":["../../../src/utils/video/queue-store.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { TransformFunction } from './types';
2
+ /**
3
+ * Apply resize transformation to a video
4
+ * Supports multiple crop modes: fill, crop, fit, scale, pad
5
+ */
6
+ export declare const applyResize: TransformFunction;
7
+ //# sourceMappingURL=resize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../../src/utils/video/resize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,iBAyCzB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Apply resize transformation to a video
3
+ * Supports multiple crop modes: fill, crop, fit, scale, pad
4
+ */
5
+ export const applyResize = (command, context) => {
6
+ const { resize, width, height, crop } = context.params;
7
+ let w;
8
+ let h;
9
+ // Parse dimensions from resize parameter
10
+ if (resize) {
11
+ const [wStr, hStr] = resize.split('x');
12
+ w = wStr ? parseInt(wStr, 10) : undefined;
13
+ h = hStr ? parseInt(hStr, 10) : undefined;
14
+ }
15
+ // Individual width/height parameters take precedence
16
+ if (width !== undefined) {
17
+ w = typeof width === 'string' ? parseInt(width, 10) : width;
18
+ }
19
+ if (height !== undefined) {
20
+ h = typeof height === 'string' ? parseInt(height, 10) : height;
21
+ }
22
+ // Skip if no valid dimensions
23
+ if (!w || !h || isNaN(w) || isNaN(h) || w <= 0 || h <= 0) {
24
+ return command;
25
+ }
26
+ // Apply resize based on crop mode
27
+ if (crop === 'fill' || crop === 'crop') {
28
+ // Cover behavior (no stretching):
29
+ // 1) scale until the smallest side reaches the target, preserving aspect ratio
30
+ // 2) crop to exact WxH from the center
31
+ const filter = `scale=${w}:${h}:force_original_aspect_ratio=increase,crop=${w}:${h}`;
32
+ return command.videoFilters(filter);
33
+ }
34
+ else {
35
+ // Backwards-compatible behavior: simple resize to exact dimensions,
36
+ // which may stretch to fit
37
+ return command.size(`${w}x${h}`);
38
+ }
39
+ };
40
+ //# sourceMappingURL=resize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resize.js","sourceRoot":"","sources":["../../../src/utils/video/resize.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAsB,CAC5C,OAAO,EACP,OAAO,EACP,EAAE;IACF,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAEvD,IAAI,CAAqB,CAAC;IAC1B,IAAI,CAAqB,CAAC;IAE1B,yCAAyC;IACzC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1C,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5C,CAAC;IAED,qDAAqD;IACrD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9D,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,CAAC,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjE,CAAC;IAED,8BAA8B;IAC9B,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACzD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,kCAAkC;IAClC,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACvC,kCAAkC;QAClC,+EAA+E;QAC/E,uCAAuC;QACvC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,8CAA8C,CAAC,IAAI,CAAC,EAAE,CAAC;QACrF,OAAO,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,oEAAoE;QACpE,2BAA2B;QAC3B,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { parseParams } from "../parser";
3
+ import type { VideoJob, JobStats, JobStatus, VideoJobStore } from "./queue-store";
4
+ /**
5
+ * SQLite-backed VideoJobStore, used by the self-hosted app. Takes the
6
+ * database instance as a constructor argument rather than importing a
7
+ * global, so callers control which database (and which schema/migrations)
8
+ * it operates against.
9
+ */
10
+ export declare class SqliteVideoJobStore implements VideoJobStore {
11
+ private db;
12
+ constructor(db: Database.Database);
13
+ createJob(filePath: string, params: ReturnType<typeof parseParams>, cachePath: string, priority?: number): string;
14
+ getNextPendingJob(): VideoJob | null;
15
+ updateJobStatus(jobId: string, status: JobStatus, progress?: number, error?: string): void;
16
+ getJobByFileAndParams(filePath: string, params: ReturnType<typeof parseParams>): VideoJob | null;
17
+ getJobById(jobId: string): VideoJob | null;
18
+ getJobStats(): JobStats;
19
+ getRecentJobs(limit?: number, offset?: number): VideoJob[];
20
+ getJobsByStatus(status: JobStatus, limit?: number): VideoJob[];
21
+ countProcessingJobs(): number;
22
+ cleanupOldJobs(olderThanHours?: number): number;
23
+ retryFailedJob(jobId: string): boolean;
24
+ cancelJob(jobId: string): boolean;
25
+ deleteJob(jobId: string): boolean;
26
+ resetOrphanedProcessingJobs(): number;
27
+ deleteJobsByFilePath(filePath: string): number;
28
+ }
29
+ //# sourceMappingURL=sqlite-video-job-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-video-job-store.d.ts","sourceRoot":"","sources":["../../../src/utils/video/sqlite-video-job-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,aAAa,EACd,MAAM,eAAe,CAAC;AAqBvB;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IAC3C,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAEzC,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,EACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,MAAU,GACnB,MAAM;IA2DT,iBAAiB,IAAI,QAAQ,GAAG,IAAI;IA6CpC,eAAe,CACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,IAAI;IAuCP,qBAAqB,CACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,GACrC,QAAQ,GAAG,IAAI;IAmBlB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAgB1C,WAAW,IAAI,QAAQ;IAqBvB,aAAa,CAAC,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,QAAQ,EAAE;IAgBjE,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,GAAE,MAAW,GAAG,QAAQ,EAAE;IAgBlE,mBAAmB,IAAI,MAAM;IAkB7B,cAAc,CAAC,cAAc,GAAE,MAAW,GAAG,MAAM;IA6BnD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAmDtC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAkCjC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAsBjC,2BAA2B,IAAI,MAAM;IA2BrC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAwB/C"}