@sigmaott/base-library-next 2.1.9

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 (71) hide show
  1. package/README.md +1 -0
  2. package/locales/en.yaml +289 -0
  3. package/locales/vi.yaml +294 -0
  4. package/nuxt.config.ts +18 -0
  5. package/package.json +33 -0
  6. package/public/routes.json +34 -0
  7. package/src/api/axios.ts +3 -0
  8. package/src/api/index.ts +86 -0
  9. package/src/api-client-library/.openapi-generator/FILES +20 -0
  10. package/src/api-client-library/.openapi-generator/VERSION +1 -0
  11. package/src/api-client-library/.openapi-generator-ignore +23 -0
  12. package/src/api-client-library/api/health-api.ts +119 -0
  13. package/src/api-client-library/api/presets-api.ts +599 -0
  14. package/src/api-client-library/api/profiles-api.ts +676 -0
  15. package/src/api-client-library/api.ts +20 -0
  16. package/src/api-client-library/base.ts +72 -0
  17. package/src/api-client-library/common.ts +150 -0
  18. package/src/api-client-library/configuration.ts +101 -0
  19. package/src/api-client-library/git_push.sh +57 -0
  20. package/src/api-client-library/index.ts +18 -0
  21. package/src/api-client-library/models/create-preset-dto.ts +223 -0
  22. package/src/api-client-library/models/create-profile-dto.ts +45 -0
  23. package/src/api-client-library/models/health-controller-get-health200-response-info-value.ts +32 -0
  24. package/src/api-client-library/models/health-controller-get-health200-response.ts +51 -0
  25. package/src/api-client-library/models/health-controller-get-health503-response.ts +51 -0
  26. package/src/api-client-library/models/index.ts +7 -0
  27. package/src/api-client-library/models/update-preset-dto.ts +223 -0
  28. package/src/api-client-library/models/update-profile-dto.ts +45 -0
  29. package/src/components/MediaSelection.vue +40 -0
  30. package/src/components/PresetModify.vue +154 -0
  31. package/src/components/PresetTable.vue +114 -0
  32. package/src/components/ProfileAllList.vue +137 -0
  33. package/src/components/ProfileFormModal.vue +79 -0
  34. package/src/components/ProfileModify.vue +152 -0
  35. package/src/components/ProfileTable.vue +68 -0
  36. package/src/components/WatermarkDraggableItem.vue +88 -0
  37. package/src/components/channel/ConfigWatermarkItem.vue +239 -0
  38. package/src/components/channel/WatermarkPreview.vue +19 -0
  39. package/src/components/common/Vue3DraggableResizable/Container.vue +71 -0
  40. package/src/components/common/Vue3DraggableResizable/index.vue +1327 -0
  41. package/src/components/common/Vue3DraggableResizable/utils/dom.js +63 -0
  42. package/src/components/common/Vue3DraggableResizable/utils/fns.js +37 -0
  43. package/src/components/common/VueDraggableResizable/dom.js +63 -0
  44. package/src/components/common/VueDraggableResizable/fns.js +37 -0
  45. package/src/components/common/VueDraggableResizable/index.vue +958 -0
  46. package/src/components/preset/ConfigItem.vue +956 -0
  47. package/src/components/profile/ConfigItem.vue +765 -0
  48. package/src/components/profile/TableColumns.vue +137 -0
  49. package/src/components/shared/AudioInfoViewer.vue +101 -0
  50. package/src/components/shared/MediaInfoViewer.vue +249 -0
  51. package/src/components/shared/MediaInfoViewerSmall.vue +105 -0
  52. package/src/components/shared/PopoverProfile.vue +17 -0
  53. package/src/components/shared/VideoInfoViewer.vue +136 -0
  54. package/src/components/shared/fileSizeFilter.ts +26 -0
  55. package/src/composables/preset.ts +141 -0
  56. package/src/public/apple-touch-icon-180x180.png +0 -0
  57. package/src/public/build-time.json +1 -0
  58. package/src/public/favicon.ico +0 -0
  59. package/src/public/favicon.svg +15 -0
  60. package/src/public/logo.png +0 -0
  61. package/src/public/logo.svg +9 -0
  62. package/src/public/maskable-icon-512x512.png +0 -0
  63. package/src/public/pwa-192x192.png +0 -0
  64. package/src/public/pwa-512x512.png +0 -0
  65. package/src/public/pwa-64x64.png +0 -0
  66. package/src/public/routes.json +87 -0
  67. package/src/utils/common.ts +175 -0
  68. package/src/utils/config.ts +19 -0
  69. package/src/utils/preset.ts +353 -0
  70. package/src/utils/profile.ts +30 -0
  71. package/tsconfig.json +3 -0
@@ -0,0 +1,956 @@
1
+ <script lang="ts" setup>
2
+ import { langOptions } from '@sigma-streaming/base/src/constants/languageCode'
3
+
4
+ const { schemaObj } = useAsyncSchema('/api/transcode/api-docs-json', 'PresetDto')
5
+
6
+ const { defaultMediaType, isPackage, prop, videoCodecs, encoderOptions, mode, isConfigEncoder, isShowType } = definePropsRefs<{
7
+ defaultMediaType?: 'video' | 'audio' | 'data'
8
+ isPackage?: boolean
9
+ prop?: string
10
+ videoCodecs?: Record<string, string>
11
+ encoderOptions?: any
12
+ mode?: 'create' | 'edit' | 'clone'
13
+ isConfigEncoder?: boolean
14
+ isShowType?: boolean
15
+ }>()
16
+
17
+ const { t } = useI18n()
18
+
19
+ function getProp(key: string) {
20
+ return () => prop.value ? `${prop.value}.${key}` : key
21
+ }
22
+
23
+ const [typeValue, typeAttrs] = useElField<string>(getProp('type'), [
24
+ {
25
+ required: true,
26
+ message: t('library_preset.type_is_required'),
27
+ },
28
+ ])
29
+ const [encoderValue, encoderAttrs] = useElField<string | undefined>(getProp('encoderType'), [
30
+ {
31
+ required: true,
32
+ message: t('library_preset.preset_encoder_is_required'),
33
+ },
34
+ ])
35
+ const [presetValue, presetAttrs] = useElField<string | undefined>(getProp('preset'), [
36
+ {
37
+ required: true,
38
+ message: t('library_preset.preset_is_required'),
39
+ },
40
+ ])
41
+ const [nameValue, nameAttrs] = useElField<string>(getProp('name'), [
42
+ {
43
+ required: true,
44
+ validator: nameValidatorLow(t('library_preset.name')),
45
+ trigger: ['blur', 'change'],
46
+ },
47
+ ])
48
+ const [groupIdValue, groupIdAttrs] = useElField<string>(getProp('audioGroupId'), [
49
+ {
50
+ validator: (rule, value, callback) => {
51
+ if (!/^[\w-\s]*$/.test(value))
52
+ callback(new Error(t('library_preset.group_id')))
53
+ else
54
+ callback()
55
+ },
56
+ trigger: ['blur', 'change'],
57
+ },
58
+ ])
59
+
60
+ const [codecValue, codecAttrs] = useElField<string>(getProp('codec'), [
61
+ {
62
+ validator: (rule, value, callback) => {
63
+ if (!value)
64
+ callback(new Error(t('please_select_codec')))
65
+ else
66
+ callback()
67
+ },
68
+ trigger: ['blur', 'change'],
69
+ required: true,
70
+ },
71
+ ])
72
+
73
+ const enableValid = computed(() => {
74
+ return !!(codecValue.value !== 'copy') as boolean
75
+ })
76
+ const [descriptionValue, descriptionAttrs] = useElField<string>(getProp('description'), [
77
+ {
78
+ validator: (rule, value, callback) => {
79
+ if (!/^[\w-\s]*$/.test(value))
80
+ callback(new Error(t('description.format_description')))
81
+ else
82
+ callback()
83
+ },
84
+ trigger: ['blur', 'change'],
85
+ },
86
+ ])
87
+
88
+ const [minrateValue, minrateAttrs] = useElField<number>(getProp('minrate'), [
89
+ {
90
+ trigger: ['blur', 'change'],
91
+ validator: (rule, value, callback) => {
92
+ if (typeValue.value === 'video' && (convertStringToNumber(value) < 64000))
93
+ callback(new Error($t('minrate_khong_duoc_lon_hon_bitrate')))
94
+ else
95
+ callback()
96
+ },
97
+ },
98
+ ])
99
+ const [bitrateValue, bitrateAttrs] = useElField<number>(getProp('bitrate'), [
100
+ {
101
+ required: true,
102
+ trigger: ['blur', 'change'],
103
+ validator: (rule, value, callback) => {
104
+ if (!value && typeValue.value !== 'data')
105
+ callback(new Error(t(`library_preset.${typeValue.value}_is_required`)))
106
+ else if (typeValue.value === 'video' && (convertStringToNumber(minrateValue.value || 0) >= convertStringToNumber(value)))
107
+ callback(new Error($t('bitrate_khong_duoc_be_hon_minrate')))
108
+ else if (typeValue.value === 'audio' && (convertStringToNumber(value) < 64000 || convertStringToNumber(value) > 60000000))
109
+ callback(new Error($t('audiorate_khong_duoc_be_hon_minrate')))
110
+ else
111
+ callback()
112
+ },
113
+ },
114
+ ])
115
+
116
+ const [maxrateValue, maxrateAttrs] = useElField<number>(getProp('maxrate'), [
117
+ {
118
+ trigger: ['blur', 'change'],
119
+ validator: (rule, value, callback) => {
120
+ if (typeValue.value === 'video' && (convertStringToNumber(bitrateValue.value || 0) > convertStringToNumber(value || 0)))
121
+ callback(new Error($t('maxrate_khong_duoc_lon_hon_bitrate')))
122
+ else if (typeValue.value === 'video' && (convertStringToNumber(value) > 60000000))
123
+ callback(new Error($t('maxrate_khong_duoc_lon_hon_60m')))
124
+ else
125
+ callback()
126
+ },
127
+ },
128
+ ])
129
+ const [fpsValue, fpsAttrs] = useElField<number | undefined>(getProp('fps'), [
130
+ {
131
+ required: true,
132
+ trigger: ['blur', 'change'],
133
+ validator: (rule, value, callback) => {
134
+ if (convertStringToNumber(value) < 10 || convertStringToNumber(value) > 60) {
135
+ callback(new Error($t('fps_less_10_greater_60')))
136
+ }
137
+ else {
138
+ callback()
139
+ }
140
+ },
141
+ },
142
+ ])
143
+ const [widthValue, widthAttrs] = useElField<number | undefined>(getProp('width'), [
144
+ {
145
+ required: true,
146
+ trigger: ['blur', 'change'],
147
+ validator: (rule, value, callback) => {
148
+ if (convertStringToNumber(value) < 0 || convertStringToNumber(value) > 7680) {
149
+ callback(new Error($t('width_less_0_greater_7680')))
150
+ }
151
+ else {
152
+ callback()
153
+ }
154
+ },
155
+ },
156
+ ])
157
+ const [heightValue, heightAttrs] = useElField<number | undefined>(getProp('height'), [
158
+ {
159
+ required: true,
160
+ trigger: ['blur', 'change'],
161
+ validator: (rule, value, callback) => {
162
+ if (convertStringToNumber(value) < 0 || convertStringToNumber(value) > 4320) {
163
+ callback(new Error($t('height_less_0_greater_7680')))
164
+ }
165
+ else {
166
+ callback()
167
+ }
168
+ },
169
+ },
170
+ ])
171
+ const [bframeValue, bframeAttrs] = useElField<number | undefined>(getProp('bframe'), [])
172
+ const [pixelFormatValue, pixelFormatAttrs] = useElField<string | undefined>(getProp('pixelFormat'), [])
173
+ const [scaleTypeValue, scaleTypeAttrs] = useElField<string | undefined>(getProp('scaleType'), [])
174
+ const [hdrValue, hdrAttrs] = useElField<string | undefined>(getProp('hdr'), [])
175
+ const [cqValue, cqAttrs] = useElField<number | undefined>(getProp('cq'), [
176
+ {
177
+ trigger: ['blur', 'change'],
178
+ validator: (rule, value, callback) => {
179
+ if (convertStringToNumber(value) < 0 || convertStringToNumber(value) > 51) {
180
+ callback(new Error($t('cbr_less_0_greater_51')))
181
+ }
182
+ else {
183
+ callback()
184
+ }
185
+ },
186
+ },
187
+ ])
188
+ const [interlacedValue, interlacedAttrs] = useElField<boolean | undefined>(getProp('interlaced'), [])
189
+ const [cbrValue, cbrAttrs] = useElField<boolean | undefined>(getProp('cbr'), [])
190
+
191
+ // Audio
192
+ const [sampleRateValue, sampleRateAttrs] = useElField<number | undefined>(getProp('sampleRate'), [])
193
+ const [channelValue, channelAttrs] = useElField<number | undefined>(getProp('channel'), [
194
+ {
195
+ required: true,
196
+ message: t('library_preset.preset_channel'),
197
+ trigger: ['blur', 'change'],
198
+ },
199
+ ], {
200
+ enabled: enableValid,
201
+ })
202
+ const [profileValue, profileAttrs] = useElField<string | undefined>(getProp('profile'), [])
203
+ const [volumeValue, volumeAttrs] = useElField<string | undefined>(getProp('volume'), [])
204
+ const [languageValue, languageAttrs] = useElField<string | undefined>(getProp('language'), [])
205
+ const [labelValue, labelAttrs] = useElField<string | undefined>(getProp('label'), [])
206
+ const [defaultValue, defaultAttrs] = useElField<boolean | undefined>(getProp('defaultAudio'), [])
207
+
208
+ const isCopiedVideoCodec = computed(() => {
209
+ return codecValue.value === 'copy'
210
+ })
211
+
212
+ const isCopiedAudioCodec = computed(() => {
213
+ return codecValue.value === 'copy'
214
+ })
215
+
216
+ function fillAudio() {
217
+ typeValue.value = 'audio'
218
+ nameValue.value = nameValue.value ?? ''
219
+ descriptionValue.value = descriptionValue.value ?? ''
220
+
221
+ codecValue.value = 'aac'
222
+ bitrateValue.value = 64000
223
+ sampleRateValue.value = 44100
224
+ groupIdValue.value = undefined
225
+ defaultValue.value = undefined
226
+ minrateValue.value = undefined
227
+ maxrateValue.value = undefined
228
+ fpsValue.value = undefined
229
+ widthValue.value = undefined
230
+ heightValue.value = undefined
231
+ pixelFormatValue.value = ''
232
+ bframeValue.value = undefined
233
+ scaleTypeValue.value = ''
234
+ cqValue.value = undefined
235
+ interlacedValue.value = false
236
+ cbrValue.value = false
237
+ channelValue.value = 2
238
+ profileValue.value = ''
239
+ volumeValue.value = ''
240
+ languageValue.value = ''
241
+ labelValue.value = ''
242
+ }
243
+
244
+ function fillVideo() {
245
+ typeValue.value = 'video'
246
+ nameValue.value = nameValue.value ?? ''
247
+ descriptionValue.value = descriptionValue.value ?? ''
248
+
249
+ codecValue.value = 'h264'
250
+ encoderValue.value = 'open_h264'
251
+ presetValue.value = 'veryfast'
252
+ bitrateValue.value = 4000000
253
+ minrateValue.value = undefined
254
+ maxrateValue.value = undefined
255
+ sampleRateValue.value = undefined
256
+ fpsValue.value = 25
257
+ widthValue.value = 1920
258
+ heightValue.value = 1080
259
+ pixelFormatValue.value = ''
260
+ bframeValue.value = undefined
261
+ scaleTypeValue.value = ''
262
+ cqValue.value = undefined
263
+ interlacedValue.value = false
264
+ cbrValue.value = false
265
+ hdrValue.value = undefined
266
+ channelValue.value = undefined
267
+ profileValue.value = ''
268
+ volumeValue.value = ''
269
+ }
270
+
271
+ function fillData() {
272
+ typeValue.value = 'data'
273
+ nameValue.value = nameValue.value ?? ''
274
+ descriptionValue.value = descriptionValue.value ?? ''
275
+ codecValue.value = 'copy'
276
+ bitrateValue.value = undefined
277
+ minrateValue.value = undefined
278
+ maxrateValue.value = undefined
279
+ sampleRateValue.value = undefined
280
+ fpsValue.value = undefined
281
+ widthValue.value = undefined
282
+ heightValue.value = undefined
283
+ pixelFormatValue.value = undefined
284
+ bframeValue.value = undefined
285
+ scaleTypeValue.value = undefined
286
+ cqValue.value = undefined
287
+ interlacedValue.value = undefined
288
+ cbrValue.value = undefined
289
+ channelValue.value = undefined
290
+ profileValue.value = undefined
291
+ volumeValue.value = undefined
292
+ }
293
+
294
+ const { formRef } = useElFormContext()
295
+ async function handleChangeType(type: string) {
296
+ if (type === 'data')
297
+ fillData()
298
+
299
+ else if (type === 'audio')
300
+ fillAudio()
301
+
302
+ else if (type === 'video')
303
+ fillVideo()
304
+
305
+ await formRef.value?.validateField('bitrate')
306
+ }
307
+
308
+ function setUndefined(type: string, value: any) {
309
+ switch (type) {
310
+ case 'volume':
311
+ !value ? volumeValue.value = undefined : volumeValue.value = value
312
+ break
313
+ case 'hdr':
314
+ !value ? hdrValue.value = undefined : hdrValue.value = value
315
+ break
316
+ case 'pixel':
317
+ !value ? pixelFormatValue.value = undefined : pixelFormatValue.value = value
318
+ break
319
+ case 'scale':
320
+ !value ? scaleTypeValue.value = undefined : scaleTypeValue.value = value
321
+ break
322
+ case 'profile':
323
+ !value ? profileValue.value = undefined : profileValue.value = value
324
+ break
325
+ case 'label':
326
+ !value ? labelValue.value = undefined : labelValue.value = value
327
+ break
328
+ }
329
+ }
330
+
331
+ const optionsEncoder = ref([
332
+ {
333
+ label: 'OpenH264',
334
+ value: 'open_h264',
335
+ },
336
+ {
337
+ label: 'OpenHEVC',
338
+ value: 'open_hevc',
339
+ },
340
+ {
341
+ label: 'NVENC',
342
+ value: 'nvenc',
343
+ },
344
+ // {
345
+ // label: 'Aurora4',
346
+ // value: 'aurora4',
347
+ // },
348
+ {
349
+ label: 'Passthrough',
350
+ value: 'passthrough',
351
+ },
352
+ ])
353
+
354
+ const optionsPreset = computed(() => {
355
+ return encoderValue.value === 'nvenc'
356
+ ? [
357
+ {
358
+ label: 'SLOW',
359
+ value: 'slow',
360
+ },
361
+ {
362
+ label: 'MEDIUM',
363
+ value: 'medium',
364
+ },
365
+ {
366
+ label: 'FAST',
367
+ value: 'fast',
368
+ },
369
+ {
370
+ label: 'HP',
371
+ value: 'hp',
372
+ },
373
+ {
374
+ label: 'HQ',
375
+ value: 'hq',
376
+ },
377
+ {
378
+ label: 'BD',
379
+ value: 'bd',
380
+ },
381
+ {
382
+ label: 'LL',
383
+ value: 'll',
384
+ },
385
+ {
386
+ label: 'LLHQ',
387
+ value: 'llhq',
388
+ },
389
+ {
390
+ label: 'LLHP',
391
+ value: 'llhp',
392
+ },
393
+ ]
394
+ : [
395
+ {
396
+ label: 'MEDIUM',
397
+ value: 'medium',
398
+ },
399
+ {
400
+ label: 'FAST',
401
+ value: 'fast',
402
+ },
403
+ {
404
+ label: 'FASTER',
405
+ value: 'faster',
406
+ },
407
+ {
408
+ label: 'VERYFAST',
409
+ value: 'veryfast',
410
+ },
411
+ {
412
+ label: 'SUPERFAST',
413
+ value: 'superfast',
414
+ },
415
+ {
416
+ label: 'ULTRAFAST',
417
+ value: 'ultrafast',
418
+ },
419
+ ]
420
+ })
421
+
422
+ const codecSelection = computed(() => {
423
+ return {
424
+ video: videoCodecs.value || (encoderValue.value === 'open_h264' || encoderValue.value === 'aurora4')
425
+ ? { H264: 'h264' }
426
+ : encoderValue.value === 'open_hevc'
427
+ ? { HEVC: 'hevc' }
428
+ : encoderValue.value === 'nvenc'
429
+ ? { H264: 'h264', HEVC: 'hevc' }
430
+ : { COPY: 'copy' },
431
+ audio: AUDIO_CODECS,
432
+ data: DATA_CODECS,
433
+ }[typeValue.value]
434
+ })
435
+ function handleChangeEncoder(newValue: string) {
436
+ switch (newValue) {
437
+ case 'open_h264':
438
+ if (!isPackage.value) {
439
+ codecValue.value = 'h264'
440
+ presetValue.value = 'veryfast'
441
+ }
442
+ break
443
+ case 'open_hevc':
444
+ if (!isPackage.value) {
445
+ codecValue.value = 'hevc'
446
+ presetValue.value = 'veryfast'
447
+ }
448
+ break
449
+ case 'nvenc':
450
+ if (!isPackage.value) {
451
+ codecValue.value = 'h264'
452
+ presetValue.value = 'llhq'
453
+ }
454
+ break
455
+ case 'aurora4':
456
+ if (!isPackage.value) {
457
+ codecValue.value = 'h264'
458
+ presetValue.value = 'veryfast'
459
+ }
460
+ break
461
+ case 'passthrough':
462
+ if (!isPackage.value) {
463
+ codecValue.value = 'copy'
464
+ }
465
+ break
466
+ default:
467
+ }
468
+ }
469
+
470
+ function formatter(value: string) {
471
+ return value.replace(/\D/g, '').replace(/\B(?=(\d{3})+(?!\d))/g, '.')
472
+ }
473
+
474
+ function parser(value: string) {
475
+ return Number.parseInt(value.replace(/\D/g, '').replace(/\$\s?|(\.*)/g, ''))
476
+ }
477
+ const optionsLang = computed(() => {
478
+ return langOptions.value?.map(item => ({
479
+ label: `${item[0]} (${item[1]})`,
480
+ value: item[1],
481
+ }))
482
+ })
483
+ </script>
484
+
485
+ <template>
486
+ <div class="flex gap-2">
487
+ <div class="flex gap-2" :class="encoderValue === 'passthrough' ? 'w-68%' : 'w-50%'">
488
+ <el-form-item class="w-full" v-bind="nameAttrs">
489
+ <template #label>
490
+ <SSInformationLabel :label="$t('general.name')" :info="schemaObj.name" />
491
+ </template>
492
+ <el-input
493
+ v-model="nameValue"
494
+ :placeholder="$t('library_preset.enter_name')"
495
+ autocomplete="off"
496
+ clearable
497
+ :minlength="1"
498
+ :maxlength="50"
499
+ show-word-limit
500
+ />
501
+ </el-form-item>
502
+ <el-form-item v-if="isConfigEncoder && typeValue === 'video'" :class="encoderValue === 'passthrough' ? 'w-100%' : 'w-49%'" v-bind="encoderAttrs">
503
+ <template #label>
504
+ <SSInformationLabel :label="$t('library_preset.encoder')" :info="schemaObj.encoderType" />
505
+ </template>
506
+ <el-select
507
+ v-model="encoderValue"
508
+ :disabled="isPackage"
509
+ class="w-full"
510
+ @change="handleChangeEncoder"
511
+ >
512
+ <el-option
513
+ v-for="(e, idx) in optionsEncoder"
514
+ :key="e + idx"
515
+ :value="e.value"
516
+ :label="e.label"
517
+ />
518
+ </el-select>
519
+ </el-form-item>
520
+ </div>
521
+
522
+ <div class="flex justify-between gap-2" :class="encoderValue === 'passthrough' ? 'w-33.33%' : 'w-50%'">
523
+ <el-form-item v-if="isShowType" class="w-full" v-bind="typeAttrs">
524
+ <template #label>
525
+ <SSInformationLabel :label="$t('library_preset.type')" :info="schemaObj.type" />
526
+ </template>
527
+ <el-select
528
+ v-model="typeValue"
529
+ class="w-full"
530
+ :disabled="!!defaultMediaType || mode === 'edit'"
531
+ @change="handleChangeType"
532
+ >
533
+ <el-option
534
+ v-for="(type, idx) in ['video', 'audio', 'data']"
535
+ :key="type + idx"
536
+ :value="type"
537
+ :label="type"
538
+ />
539
+ </el-select>
540
+ </el-form-item>
541
+
542
+ <el-form-item class="w-full" label="Codec" v-bind="codecAttrs">
543
+ <template #label>
544
+ <SSInformationLabel label="Codec" :info="schemaObj.codec" />
545
+ </template>
546
+ <el-select
547
+ v-model="codecValue"
548
+ class="w-full"
549
+ default-first-option
550
+ :disabled="isPackage && typeValue !== 'data'"
551
+ >
552
+ <el-option
553
+ v-for="(type, idx) in codecSelection"
554
+ :key="type + idx"
555
+ :value="type"
556
+ :label="type"
557
+ />
558
+ </el-select>
559
+ </el-form-item>
560
+ <el-form-item v-if="isConfigEncoder && typeValue === 'video' && encoderValue !== 'passthrough' && !isPackage" class="w-full" v-bind="presetAttrs">
561
+ <template #label>
562
+ <SSInformationLabel label="Preset" :info="schemaObj.preset" />
563
+ </template>
564
+ <el-select v-model="presetValue" class="w-full" @change="handleChangeType">
565
+ <el-option
566
+ v-for="(e) in optionsPreset"
567
+ :key="e.value"
568
+ :value="e.value"
569
+ :label="e.label"
570
+ />
571
+ </el-select>
572
+ </el-form-item>
573
+ <el-form-item v-if="typeValue === 'video' && encoderValue !== 'passthrough' && !isPackage" class="w-full" v-bind="bitrateAttrs">
574
+ <template #label>
575
+ <SSInformationLabel label="Bitrate" :info="schemaObj.bitrate" />
576
+ </template>
577
+ <el-input
578
+ v-model="bitrateValue"
579
+ class="w-full"
580
+ :disabled="isCopiedVideoCodec"
581
+ :formatter="formatter"
582
+ :parser="parser"
583
+ />
584
+ </el-form-item>
585
+ <el-form-item
586
+ v-if="typeValue === 'audio' && encoderValue !== 'passthrough' && !isPackage"
587
+ class="w-full"
588
+ label="Audio rate"
589
+ v-bind="bitrateAttrs"
590
+ >
591
+ <template #label>
592
+ <SSInformationLabel label="Audio rate" :info="schemaObj.bitrate" />
593
+ </template>
594
+ <el-input
595
+ v-model="bitrateValue"
596
+ class="w-full"
597
+ :disabled="isCopiedVideoCodec"
598
+ :formatter="formatter"
599
+ :parser="parser"
600
+ />
601
+ </el-form-item>
602
+ <el-form-item v-if="typeValue === 'audio' && isConfigEncoder && encoderValue !== 'passthrough'" class="w-full" v-bind="groupIdAttrs">
603
+ <template #label>
604
+ <SSInformationLabel :label="$t('general.groupId')" :info="schemaObj.name" />
605
+ </template>
606
+ <el-input
607
+ v-model="groupIdValue"
608
+ :placeholder="$t('library_preset.enter_group_id')"
609
+ autocomplete="off"
610
+ clearable
611
+ :maxlength="50"
612
+ show-word-limit
613
+ />
614
+ </el-form-item>
615
+ </div>
616
+ </div>
617
+ <template v-if="typeValue === 'video' && encoderValue !== 'passthrough' && !isPackage">
618
+ <div class="flex gap-2">
619
+ <div class="w-50% flex gap-2">
620
+ <el-form-item v-bind="minrateAttrs" class="w-full">
621
+ <template #label>
622
+ <SSInformationLabel label="Minrate" :info="schemaObj.minrate" />
623
+ </template>
624
+ <el-input
625
+ v-model="minrateValue"
626
+ class="w-full"
627
+ :disabled="isCopiedVideoCodec"
628
+ :formatter="formatter"
629
+ :parser="parser"
630
+ />
631
+ </el-form-item>
632
+
633
+ <el-form-item v-bind="maxrateAttrs" class="w-full">
634
+ <template #label>
635
+ <SSInformationLabel label="Maxrate" :info="schemaObj.maxrate" />
636
+ </template>
637
+ <el-input
638
+ v-model="maxrateValue"
639
+ class="w-full"
640
+ :disabled="isCopiedVideoCodec"
641
+ :formatter="formatter"
642
+ :parser="parser"
643
+ />
644
+ </el-form-item>
645
+
646
+ <el-form-item v-bind="fpsAttrs" label="FPS" class="w-full">
647
+ <template #label>
648
+ <SSInformationLabel label="FPS" :info="schemaObj.fps" />
649
+ </template>
650
+ <el-input-number
651
+ v-model="fpsValue"
652
+ :min="10"
653
+ :max="60"
654
+ class="w-full [&_.el-input\_\_inner]:text-start"
655
+ :disabled="isCopiedVideoCodec"
656
+ :precision="0"
657
+ :controls="false"
658
+ step-strictly
659
+ />
660
+ </el-form-item>
661
+ </div>
662
+ <div class="w-50% flex gap-2">
663
+ <el-form-item label="Width" class="w-full" v-bind="widthAttrs">
664
+ <template #label>
665
+ <SSInformationLabel label="Width" :info="schemaObj.width" />
666
+ </template>
667
+ <el-input-number
668
+ v-model="widthValue"
669
+ :min="0"
670
+ :max="7680"
671
+ class="w-full [&_.el-input\_\_inner]:text-start"
672
+ :disabled="isCopiedVideoCodec"
673
+ :precision="0"
674
+ :controls="false"
675
+ step-strictly
676
+ />
677
+ </el-form-item>
678
+
679
+ <el-form-item label="Height" class="w-full" v-bind="heightAttrs">
680
+ <template #label>
681
+ <SSInformationLabel label="Height" :info="schemaObj.height" />
682
+ </template>
683
+ <el-input-number
684
+ v-model="heightValue"
685
+ :min="0"
686
+ :max="4320"
687
+ class="w-full [&_.el-input\_\_inner]:text-start"
688
+ :disabled="isCopiedVideoCodec"
689
+ :precision="0"
690
+ :controls="false"
691
+ step-strictly
692
+ />
693
+ </el-form-item>
694
+
695
+ <el-form-item label="Hdr" class="w-full" v-bind="hdrAttrs">
696
+ <template #label>
697
+ <SSInformationLabel label="Hdr" :info="schemaObj.hdr" />
698
+ </template>
699
+ <el-select
700
+ v-model="hdrValue"
701
+ :disabled="isCopiedVideoCodec"
702
+ clearable
703
+ @change="(value) => setUndefined('hdr', value)"
704
+ >
705
+ <el-option
706
+ v-for="(type, idx) in ['COPY', 'NONE', 'HDR10', 'HLG10', 'PQ10']"
707
+ :key="type + idx"
708
+ :value="type"
709
+ :label="type"
710
+ />
711
+ </el-select>
712
+ </el-form-item>
713
+ </div>
714
+ </div>
715
+
716
+ <div class="flex gap-2">
717
+ <div class="w-50% flex gap-2">
718
+ <el-form-item label="Bframe" class="w-full" v-bind="bframeAttrs">
719
+ <template #label>
720
+ <SSInformationLabel label="Bframe" :info="schemaObj.bframe" />
721
+ </template>
722
+ <el-input-number
723
+ v-model="bframeValue"
724
+ class="w-full [&_.el-input\_\_inner]:text-start"
725
+ :disabled="isCopiedVideoCodec"
726
+ :controls="false"
727
+ :precision="1"
728
+ :step="0.1"
729
+ :max="3"
730
+ :min="0"
731
+ />
732
+ </el-form-item>
733
+
734
+ <el-form-item label="Pixel format" class="w-full" v-bind="pixelFormatAttrs">
735
+ <template #label>
736
+ <SSInformationLabel label="Pixel format" :info="schemaObj.pixelFormat" />
737
+ </template>
738
+ <el-select
739
+ v-model="pixelFormatValue"
740
+ :disabled="isCopiedVideoCodec"
741
+ class="w-full"
742
+ clearable
743
+ @change="(value) => setUndefined('pixel', value)"
744
+ >
745
+ <el-option
746
+ v-for="(type, idx) in ['yuv420p', 'yuv444p', 'yuv420p10le', 'yuv444p10le']"
747
+ :key="type + idx"
748
+ :value="type"
749
+ :label="type"
750
+ />
751
+ </el-select>
752
+ </el-form-item>
753
+
754
+ <el-form-item label="Scale Type" class="w-full" v-bind="scaleTypeAttrs">
755
+ <template #label>
756
+ <SSInformationLabel label="Scale Type" :info="schemaObj.scaleType" />
757
+ </template>
758
+ <el-select
759
+ v-model="scaleTypeValue"
760
+ class="w-full"
761
+ :disabled="isCopiedVideoCodec"
762
+ clearable
763
+ @change="(value) => setUndefined('scale', value)"
764
+ >
765
+ <el-option
766
+ v-for="(type, idx) in [
767
+ 'fitWidth',
768
+ 'fitHeight',
769
+ 'fitInside',
770
+ 'fitCrop',
771
+ 'fitBoth',
772
+ 'source',
773
+ ]"
774
+ :key="type + idx"
775
+ :value="type"
776
+ :label="type"
777
+ />
778
+ </el-select>
779
+ </el-form-item>
780
+ </div>
781
+ <div class="w-50% flex gap-2">
782
+ <el-form-item label="Constant quality" class="w-full" v-bind="cqAttrs">
783
+ <template #label>
784
+ <SSInformationLabel label="Constant quality" min-width="min-w-112px" :info="schemaObj.cq" />
785
+ </template>
786
+ <el-input-number
787
+ v-model="cqValue"
788
+ :controls="false"
789
+ :precision="0"
790
+ class="w-full [&_.el-input\_\_inner]:text-start"
791
+ :disabled="isCopiedVideoCodec"
792
+ :min="0"
793
+ :max="51"
794
+ />
795
+ </el-form-item>
796
+
797
+ <el-form-item label="Interlaced mode" class="w-full" v-bind="interlacedAttrs">
798
+ <template #label>
799
+ <SSInformationLabel min-width="min-w-112px" label="Interlaced mode" :info="schemaObj.interlaced" />
800
+ </template>
801
+ <el-switch
802
+ v-model="interlacedValue"
803
+ :disabled="isCopiedVideoCodec"
804
+ :active-value="true"
805
+ :inactive-value="false"
806
+ />
807
+ </el-form-item>
808
+
809
+ <el-form-item label="Constant birate mode" class="w-full" v-bind="cbrAttrs">
810
+ <template #label>
811
+ <SSInformationLabel min-width="min-w-148px" label="Constant birate mode" />
812
+ </template>
813
+ <el-switch
814
+ v-model="cbrValue"
815
+ :active-value="true"
816
+ :disabled="isCopiedVideoCodec"
817
+ :inactive-value="false"
818
+ />
819
+ </el-form-item>
820
+ </div>
821
+ </div>
822
+ </template>
823
+
824
+ <template v-if="typeValue === 'audio' && encoderValue !== 'passthrough'">
825
+ <div class="grid grid-cols-6 gap-2">
826
+ <el-form-item v-if="!isPackage" label="Sample rate" v-bind="sampleRateAttrs">
827
+ <template #label>
828
+ <SSInformationLabel label="Sample rate" :info="schemaObj.sampleRate" />
829
+ </template>
830
+ <el-select
831
+ v-model="sampleRateValue"
832
+ :disabled="isCopiedAudioCodec"
833
+ class="w-full"
834
+ default-first-option
835
+ >
836
+ <el-option
837
+ v-for="(type, idx) in [44100, 48000]"
838
+ :key="type + idx"
839
+ :value="type"
840
+ :label="type"
841
+ />
842
+ </el-select>
843
+ </el-form-item>
844
+ <el-form-item v-if="!isPackage" label="Channel" v-bind="channelAttrs">
845
+ <template #label>
846
+ <SSInformationLabel label="Channel" :info="schemaObj.channel" />
847
+ </template>
848
+ <el-select
849
+ v-model="channelValue"
850
+ :disabled="isCopiedAudioCodec"
851
+ class="w-full"
852
+ >
853
+ <el-option
854
+ v-for="(type, idx) in [1, 2, 6]"
855
+ :key="type + idx"
856
+ :value="type"
857
+ :label="type"
858
+ />
859
+ </el-select>
860
+ </el-form-item>
861
+ <el-form-item v-if="!isPackage" label="Sample rate" v-bind="profileAttrs">
862
+ <template #label>
863
+ <SSInformationLabel label="Profile" :info="schemaObj.profile" />
864
+ </template>
865
+ <el-select
866
+ v-model="profileValue"
867
+ :disabled="isCopiedAudioCodec || codecValue !== 'aac'"
868
+ class="w-full"
869
+ default-first-option
870
+ clearable
871
+ @change="(value) => setUndefined('profile', value)"
872
+ >
873
+ <el-option
874
+ v-for="(type, idx) in [
875
+ 'aac_low',
876
+ 'aac_he',
877
+ 'aac_he_v2',
878
+ 'aac_main',
879
+ 'aac_ld',
880
+ 'aac_eld',
881
+ ]"
882
+ :key="type + idx"
883
+ :value="type"
884
+ :label="type"
885
+ />
886
+ </el-select>
887
+ </el-form-item>
888
+ <el-form-item v-if="!isPackage" label="Volume" v-bind="volumeAttrs">
889
+ <template #label>
890
+ <SSInformationLabel label="Volume" :info="schemaObj.volume" />
891
+ </template>
892
+ <el-select
893
+ v-model="volumeValue"
894
+ :disabled="isCopiedAudioCodec"
895
+ class="w-full"
896
+ default-first-option
897
+ clearable
898
+ @change="(value) => setUndefined('volume', value)"
899
+ >
900
+ <el-option
901
+ v-for="(type, idx) in ['+5dB', '-10dB', '0.5', '2', 'loudnorm']"
902
+ :key="type + idx"
903
+ :value="type"
904
+ :label="type"
905
+ />
906
+ </el-select>
907
+ </el-form-item>
908
+
909
+ <el-form-item :label="$t('profile.description')" v-bind="languageAttrs">
910
+ <template #label>
911
+ <SSInformationLabel :label="$t('profile.language')" :info="schemaObj.language" />
912
+ </template>
913
+ <el-select-v2
914
+ v-model="languageValue"
915
+ :options="optionsLang"
916
+ placeholder="Select"
917
+ />
918
+ </el-form-item>
919
+ <el-form-item :label="$t('profile.label')" v-bind="labelAttrs">
920
+ <template #label>
921
+ <SSInformationLabel :label="$t('profile.label')" :info="schemaObj.label" />
922
+ </template>
923
+ <el-input
924
+ v-model="labelValue"
925
+ :disabled="isCopiedAudioCodec && !isPackage"
926
+ :placeholder="$t('profile.placeholder_label')"
927
+ autocomplete="off"
928
+ clearable
929
+ show-word-limit
930
+ maxlength="50"
931
+ @change="(value) => setUndefined('label', value)"
932
+ />
933
+ </el-form-item>
934
+ </div>
935
+ <el-form-item :label="$t('profile.default')" v-bind="defaultAttrs">
936
+ <template #label>
937
+ <SSInformationLabel :label="$t('profile.default')" :info="schemaObj.default" />
938
+ </template>
939
+ <el-switch
940
+ v-model="defaultValue"
941
+ :active-text="$t('profile.default')"
942
+ />
943
+ </el-form-item>
944
+ </template>
945
+ <DevOnly>
946
+ <el-button @click="fillVideo">
947
+ Fill Video
948
+ </el-button>
949
+ <el-button @click="fillAudio">
950
+ Fill Audio
951
+ </el-button>
952
+ <el-button @click="fillData">
953
+ Fill Data
954
+ </el-button>
955
+ </DevOnly>
956
+ </template>