Kims12 commited on
Commit
a03d759
ยท
verified ยท
1 Parent(s): ae62c0c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -744
app.py CHANGED
@@ -107,8 +107,6 @@ def process_video(video,
107
  return output_filename, output_filename, "\n".join(global_logs)
108
 
109
  def update_thumbnails(video, start_time_str, end_time_str):
110
- if not video:
111
- return None, None
112
  video_path = video if isinstance(video, str) else video.name
113
  try:
114
  input_video = mp.VideoFileClip(video_path)
@@ -128,801 +126,120 @@ def update_thumbnails(video, start_time_str, end_time_str):
128
  end_thumb = generate_thumbnail(input_video, end_sec)
129
  return start_thumb, end_thumb
130
 
131
- def validate_input(video, start_time_str, end_time_str):
132
- if not video:
133
- return "โš ๏ธ ๋จผ์ € ์˜์ƒ์„ ์—…๋กœ๋“œํ•ด์ฃผ์„ธ์š”."
134
- try:
135
- start_sec = parse_time_to_seconds(start_time_str)
136
- end_sec = parse_time_to_seconds(end_time_str)
137
- if start_sec >= end_sec:
138
- return "โš ๏ธ ์ข…๋ฃŒ ์‹œ๊ฐ„์€ ์‹œ์ž‘ ์‹œ๊ฐ„๋ณด๋‹ค ์ปค์•ผ ํ•ฉ๋‹ˆ๋‹ค."
139
- except:
140
- return "โš ๏ธ ์‹œ๊ฐ„ ํ˜•์‹์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์˜ˆ: 00:00:10)"
141
- return None
142
-
143
  # -------------------------------
144
- # Custom CSS (ํ–ฅ์ƒ๋œ ๋””์ž์ธ)
145
  # -------------------------------
146
  custom_css = """
147
- /* ๊ธฐ๋ณธ ์Šคํƒ€์ผ */
148
  body {
149
- font-size: 1.6em;
150
- background-color: #f9f9f9;
151
- font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
152
- color: #333333;
153
  }
154
-
155
  .gradio-container {
156
- width: 90% !important;
157
- max-width: 1200px !important;
158
  margin: 0 auto;
159
- background-color: #ffffff;
160
- border-radius: 15px;
161
- box-shadow: 0 5px 30px rgba(0, 0, 0, 0.05);
162
- padding: 20px;
163
- }
164
-
165
- /* ์•ฑ ํ—ค๋” */
166
- .app-header {
167
- border-bottom: 2px solid #f0f0f0;
168
- margin-bottom: 25px;
169
- padding-bottom: 15px;
170
  }
171
-
172
  .custom-title {
173
- font-size: 3.2em;
174
- font-weight: 800;
175
- margin: 20px 0 15px 0;
176
- color: #1e88e5;
177
  text-align: left;
178
- line-height: 1.2;
179
- letter-spacing: -0.5px;
180
- padding-left: 10px;
181
- border-left: 8px solid #1e88e5;
182
  }
183
-
184
- .custom-subtitle {
185
- font-size: 1.4em;
186
- color: #555;
187
- margin-bottom: 25px;
188
- padding-left: 18px;
189
  }
190
-
191
- /* ์‚ฌ์šฉ๊ฐ€์ด๋“œ ๋ฐ•์Šค */
192
  .guide-box {
193
- border: none;
194
- border-radius: 12px;
195
- padding: 25px;
196
- background-color: #e3f2fd;
197
- margin: 20px 0 30px 0;
198
  text-align: left;
199
- font-size: 1.2em;
200
- line-height: 1.6;
201
- box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05);
202
- }
203
-
204
- .guide-box strong {
205
- font-size: 1.3em;
206
- color: #1e88e5;
207
- display: block;
208
- margin-bottom: 10px;
209
- }
210
-
211
- .guide-step {
212
- margin: 10px 0;
213
- padding-left: 15px;
214
- position: relative;
215
  }
216
-
217
- .guide-step:before {
218
- content: '';
219
- position: absolute;
220
- left: 0;
221
- top: 10px;
222
- width: 8px;
223
- height: 8px;
224
- background-color: #1e88e5;
225
- border-radius: 50%;
226
- }
227
-
228
  /* ํ”„๋ ˆ์ž„ ์Šคํƒ€์ผ */
229
  .frame {
230
- border: none;
231
- border-radius: 15px;
232
- padding: 30px;
233
  background-color: #ffffff;
234
  margin: 15px;
235
- box-shadow: 0 5px 20px rgba(0, 0, 0, 0.08);
236
- transition: all 0.3s ease;
237
  }
238
-
239
- .frame:hover {
240
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12);
241
- transform: translateY(-2px);
242
- }
243
-
244
- /* ํ”„๋ ˆ์ž„ ์ œ๋ชฉ */
245
  .frame h3 {
246
- font-size: 2.0em;
247
- font-weight: 700;
248
- margin-bottom: 25px;
249
  text-align: left;
250
- color: #1e88e5;
251
- border-bottom: 2px solid #e3f2fd;
252
- padding-bottom: 10px;
253
- display: flex;
254
- align-items: center;
255
- }
256
-
257
- .frame h3 span {
258
- margin-left: 10px;
259
  }
260
-
261
  /* ํ–‰ ๋ฐ ์ปฌ๋Ÿผ ๋ ˆ์ด์•„์›ƒ */
262
  .row-container {
263
  display: flex;
264
  justify-content: space-between;
265
- flex-wrap: wrap;
266
- gap: 20px;
267
  }
268
-
269
  .column {
270
  flex: 1;
271
- min-width: 45%;
272
  }
273
-
274
  /* ํฌ์ธํŠธ ๋ฒ„ํŠผ ์Šคํƒ€์ผ */
275
  .gif-button {
276
  margin-top: 35px;
277
- padding: 20px 35px;
278
- font-size: 1.8em;
279
- background: linear-gradient(45deg, #1e88e5, #039be5);
280
  color: #fff;
281
  border: none;
282
  border-radius: 12px;
283
  cursor: pointer;
284
- box-shadow: 0 4px 15px rgba(30, 136, 229, 0.3);
285
- transition: all 0.3s ease;
286
- font-weight: bold;
287
- text-align: center;
288
- width: 100%;
289
- max-width: 500px;
290
- margin-left: auto;
291
- margin-right: auto;
292
- display: block;
293
  }
294
-
295
- .gif-button:hover {
296
- box-shadow: 0 6px 20px rgba(30, 136, 229, 0.5);
297
- transform: translateY(-2px);
298
- }
299
-
300
- .gif-button:active {
301
- transform: translateY(1px);
302
- box-shadow: 0 2px 10px rgba(30, 136, 229, 0.3);
303
- }
304
-
305
- /* ์ž…๋ ฅ ์š”์†Œ ์Šคํƒ€์ผ */
306
- .input-element {
307
- margin-bottom: 20px;
308
- }
309
-
310
- /* ๋ผ๋””์˜ค ๋ฒ„ํŠผ ์Šคํƒ€์ผ */
311
- .radio-group label {
312
- font-size: 1.3em;
313
- padding: 10px 15px;
314
- background-color: #f1f8fe;
315
- border-radius: 8px;
316
- margin: 5px;
317
- transition: all 0.2s ease;
318
- }
319
-
320
- .radio-group input:checked + label {
321
- background-color: #1e88e5;
322
- color: white;
323
- }
324
-
325
- /* ์Šฌ๋ผ์ด๋” ์Šคํƒ€์ผ */
326
  input[type=range] {
327
- height: 30px;
328
- -webkit-appearance: none;
329
- margin: 10px 0;
330
- width: 100%;
331
- background: transparent;
332
- }
333
-
334
- input[type=range]::-webkit-slider-runnable-track {
335
- width: 100%;
336
- height: 12px;
337
- cursor: pointer;
338
- background: #e3f2fd;
339
- border-radius: 10px;
340
  }
341
-
342
  input[type=range]::-webkit-slider-thumb {
343
- height: 30px;
344
- width: 30px;
345
- border-radius: 50%;
346
- background: #1e88e5;
347
- cursor: pointer;
348
- -webkit-appearance: none;
349
- margin-top: -9px;
350
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
351
- }
352
-
353
- .slider-container {
354
- margin: 25px 0;
355
  }
356
-
357
  .slider-label {
358
- font-size: 1.5em;
359
- margin-bottom: 10px;
360
- color: #333;
361
- font-weight: 600;
362
- }
363
-
364
- .slider-value {
365
- font-size: 1.3em;
366
- color: #1e88e5;
367
- font-weight: bold;
368
- text-align: right;
369
- }
370
-
371
- /* ์ž…๋ ฅ ํ•„๋“œ ์Šคํƒ€์ผ */
372
- input[type=text], input[type=number], select, textarea {
373
- font-size: 1.5em;
374
- padding: 15px;
375
- border-radius: 8px;
376
- border: 2px solid #e3f2fd;
377
- transition: all 0.3s ease;
378
- width: 100%;
379
- box-sizing: border-box;
380
- margin-top: 5px;
381
- }
382
-
383
- input[type=text]:focus, input[type=number]:focus, select:focus, textarea:focus {
384
- border-color: #1e88e5;
385
- outline: none;
386
- box-shadow: 0 0 0 3px rgba(30, 136, 229, 0.2);
387
- }
388
-
389
- /* ๋ผ๋ฒจ ์Šคํƒ€์ผ */
390
- label, .label-wrap span {
391
- font-size: 1.4em !important;
392
- font-weight: 600;
393
- color: #333;
394
  margin-bottom: 8px;
395
- display: block;
396
- }
397
-
398
- /* ํ•„์ˆ˜ ํ‘œ์‹œ */
399
- .required:after {
400
- content: '*';
401
- color: #e53935;
402
- margin-left: 4px;
403
- }
404
-
405
- /* ์ธ๋„ค์ผ ์˜์—ญ ์Šคํƒ€์ผ */
406
- .thumbnail-container {
407
- display: flex;
408
- flex-direction: column;
409
- align-items: center;
410
- justify-content: center;
411
- min-height: 200px;
412
- border: 2px dashed #e3f2fd;
413
- border-radius: 10px;
414
- padding: 15px;
415
- background-color: #fafafa;
416
- margin-top: 10px;
417
- }
418
-
419
- .thumbnail-container img {
420
- max-width: 100%;
421
- max-height: 100%;
422
- object-fit: contain;
423
- border-radius: 8px;
424
- }
425
-
426
- .thumbnail-label {
427
- font-size: 1.2em;
428
- font-weight: bold;
429
- margin-bottom: 10px;
430
- color: #1e88e5;
431
- text-align: center;
432
- }
433
-
434
- /* ์ƒํƒœ ๋ฉ”์‹œ์ง€ */
435
- .status-message {
436
- padding: 15px;
437
- border-radius: 8px;
438
- margin: 20px 0;
439
- font-size: 1.3em;
440
- display: flex;
441
- align-items: center;
442
- }
443
-
444
- .status-message.success {
445
- background-color: #e8f5e9;
446
- color: #2e7d32;
447
- border-left: 5px solid #2e7d32;
448
- }
449
-
450
- .status-message.error {
451
- background-color: #ffebee;
452
- color: #c62828;
453
- border-left: 5px solid #c62828;
454
- }
455
-
456
- .status-message.info {
457
- background-color: #e3f2fd;
458
- color: #1565c0;
459
- border-left: 5px solid #1565c0;
460
- }
461
-
462
- .status-message i {
463
- margin-right: 10px;
464
- font-size: 1.5em;
465
  }
466
-
467
- /* ๋กœ๋”ฉ ์ƒํƒœ */
468
- .loading {
469
- display: inline-block;
470
- position: relative;
471
- width: 80px;
472
- height: 80px;
473
- }
474
-
475
- .loading div {
476
- position: absolute;
477
- border: 4px solid #1e88e5;
478
- opacity: 1;
479
- border-radius: 50%;
480
- animation: loading 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;
481
- }
482
-
483
- .loading div:nth-child(2) {
484
- animation-delay: -0.5s;
485
- }
486
-
487
- @keyframes loading {
488
- 0% {
489
- top: 36px;
490
- left: 36px;
491
- width: 0;
492
- height: 0;
493
- opacity: 1;
494
- }
495
- 100% {
496
- top: 0px;
497
- left: 0px;
498
- width: 72px;
499
- height: 72px;
500
- opacity: 0;
501
- }
502
- }
503
-
504
- /* ๋งˆ์šฐ์Šค ์˜ค๋ฒ„ ํšจ๊ณผ */
505
- .hover-effect {
506
- transition: all 0.3s ease;
507
- }
508
-
509
- .hover-effect:hover {
510
- transform: translateY(-3px);
511
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
512
- }
513
-
514
- /* ๊ฒฐ๊ณผ ์˜์—ญ ์Šคํƒ€์ผ */
515
- .result-container {
516
- display: flex;
517
- flex-direction: column;
518
- align-items: center;
519
- padding: 20px;
520
- border-radius: 10px;
521
- background-color: #f5f5f5;
522
- margin-top: 20px;
523
  }
524
-
525
- .result-title {
526
- font-size: 1.6em;
527
- font-weight: bold;
528
- margin-bottom: 15px;
529
- color: #1e88e5;
530
- }
531
-
532
- .result-image {
533
- max-width: 100%;
534
- border-radius: 8px;
535
- box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
536
- }
537
-
538
- .download-button {
539
- margin-top: 20px;
540
- padding: 12px 25px;
541
- background-color: #1e88e5;
542
- color: white;
543
- border: none;
544
- border-radius: 8px;
545
- font-size: 1.4em;
546
- cursor: pointer;
547
- transition: all 0.3s ease;
548
- }
549
-
550
- .download-button:hover {
551
- background-color: #1565c0;
552
- }
553
-
554
- /* ์•Œ๋ฆผ ๋ฐฐ๋„ˆ ์Šคํƒ€์ผ */
555
- .notification-banner {
556
- padding: 15px 20px;
557
- background-color: #fffde7;
558
- border-left: 5px solid #fbc02d;
559
- margin: 20px 0;
560
- border-radius: 0 8px 8px 0;
561
- font-size: 1.3em;
562
- display: flex;
563
- align-items: center;
564
- }
565
-
566
- .notification-banner i {
567
- margin-right: 15px;
568
- font-size: 1.6em;
569
- color: #fbc02d;
570
- }
571
-
572
- /* ๋ฐ˜์‘ํ˜• ๋””์ž์ธ */
573
- @media (max-width: 768px) {
574
- .row-container {
575
- flex-direction: column;
576
- }
577
-
578
- .column {
579
- width: 100%;
580
- }
581
-
582
- .custom-title {
583
- font-size: 2.5em;
584
- }
585
-
586
- .frame h3 {
587
- font-size: 1.8em;
588
- }
589
-
590
- .gif-button {
591
- font-size: 1.5em;
592
- padding: 15px 25px;
593
- }
594
- }
595
-
596
- /* ํฌ์ปค์Šค ์ƒํƒœ ์‹œ๊ฐ ํšจ๊ณผ */
597
- *:focus {
598
- outline: none;
599
- box-shadow: 0 0 0 3px rgba(30, 136, 229, 0.3);
600
- }
601
-
602
- /* ๋„์›€๋ง ํˆดํŒ */
603
- .tooltip {
604
- position: relative;
605
- display: inline-block;
606
- margin-left: 8px;
607
- cursor: help;
608
- }
609
-
610
- .tooltip .tooltip-icon {
611
- width: 20px;
612
- height: 20px;
613
- background-color: #1e88e5;
614
- color: white;
615
- border-radius: 50%;
616
- display: flex;
617
- align-items: center;
618
- justify-content: center;
619
- font-weight: bold;
620
- font-size: 0.8em;
621
- }
622
-
623
- .tooltip .tooltip-text {
624
- visibility: hidden;
625
- width: 250px;
626
- background-color: #555;
627
- color: #fff;
628
- text-align: center;
629
- border-radius: 6px;
630
- padding: 10px;
631
- position: absolute;
632
- z-index: 1;
633
- bottom: 125%;
634
- left: 50%;
635
- margin-left: -125px;
636
- opacity: 0;
637
- transition: opacity 0.3s;
638
- font-size: 0.9em;
639
- }
640
-
641
- .tooltip:hover .tooltip-text {
642
- visibility: visible;
643
- opacity: 1;
644
- }
645
-
646
- /* ์ž…์ถœ๋ ฅ ์˜์—ญ ๊ตฌ๋ถ„ */
647
- .input-section, .output-section {
648
- position: relative;
649
- }
650
-
651
- .section-label {
652
- position: absolute;
653
- top: -15px;
654
- left: 30px;
655
- padding: 5px 15px;
656
- background-color: #1e88e5;
657
- color: white;
658
- font-size: 1.2em;
659
- border-radius: 30px;
660
- font-weight: bold;
661
- z-index: 1;
662
- }
663
-
664
- /* ํŒŒ์ผ ์—…๋กœ๋“œ ์˜์—ญ ๊ฐœ์„  */
665
- .file-upload {
666
- border: 3px dashed #e3f2fd;
667
- border-radius: 10px;
668
- padding: 30px;
669
- text-align: center;
670
- cursor: pointer;
671
- background-color: #f8fafc;
672
- transition: all 0.3s ease;
673
- }
674
-
675
- .file-upload:hover {
676
- border-color: #1e88e5;
677
- background-color: #f0f7ff;
678
- }
679
-
680
- .file-upload-icon {
681
- font-size: 3em;
682
- color: #1e88e5;
683
- margin-bottom: 15px;
684
- }
685
-
686
- .file-upload-text {
687
- font-size: 1.3em;
688
- color: #555;
689
- }
690
-
691
- /* ํ”„๋กœ๊ทธ๋ ˆ์Šค ๋ฐ” ์Šคํƒ€์ผ */
692
- .progress-container {
693
- width: 100%;
694
- height: 15px;
695
- background-color: #e0e0e0;
696
- border-radius: 10px;
697
- margin: 20px 0;
698
- overflow: hidden;
699
- }
700
-
701
- .progress-bar {
702
- height: 100%;
703
- background: linear-gradient(90deg, #1e88e5, #29b6f6);
704
- border-radius: 10px;
705
- transition: width 0.5s ease;
706
- }
707
-
708
- /* ๋‹จ๊ณ„ ์ง„ํ–‰ ํ‘œ์‹œ๊ธฐ */
709
- .steps-container {
710
- display: flex;
711
- justify-content: space-between;
712
- margin: 30px 0;
713
- }
714
-
715
- .step {
716
- display: flex;
717
- flex-direction: column;
718
- align-items: center;
719
- width: 33%;
720
- }
721
-
722
- .step-circle {
723
- width: 40px;
724
- height: 40px;
725
- border-radius: 50%;
726
- background-color: #e0e0e0;
727
- display: flex;
728
- align-items: center;
729
- justify-content: center;
730
- font-weight: bold;
731
- color: white;
732
- margin-bottom: 10px;
733
- }
734
-
735
- .step.active .step-circle {
736
- background-color: #1e88e5;
737
- }
738
-
739
- .step.completed .step-circle {
740
- background-color: #43a047;
741
- }
742
-
743
- .step-label {
744
- font-size: 1.2em;
745
- text-align: center;
746
- color: #555;
747
- }
748
-
749
- .step.active .step-label {
750
- color: #1e88e5;
751
- font-weight: bold;
752
- }
753
-
754
- .step-line {
755
- flex-grow: 1;
756
- height: 3px;
757
- background-color: #e0e0e0;
758
- margin: 20px 10px;
759
- }
760
-
761
- .step-line.completed {
762
- background-color: #43a047;
763
- }
764
-
765
- /* ๋กœ๊ทธ ์ถœ๋ ฅ ์˜์—ญ */
766
- .log-container {
767
- padding: 15px;
768
- background-color: #f5f5f5;
769
- border-radius: 8px;
770
- font-family: 'Courier New', monospace;
771
- font-size: 1.2em;
772
- max-height: 200px;
773
- overflow-y: auto;
774
- white-space: pre-wrap;
775
- margin-top: 20px;
776
- }
777
-
778
- .log-entry {
779
- margin: 5px 0;
780
- padding: 3px 0;
781
- border-bottom: 1px dashed #e0e0e0;
782
- }
783
-
784
- .log-entry.error {
785
- color: #c62828;
786
- }
787
-
788
- .log-entry.success {
789
- color: #2e7d32;
790
- }
791
-
792
- /* ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ */
793
- @keyframes fadeIn {
794
- from { opacity: 0; transform: translateY(20px); }
795
- to { opacity: 1; transform: translateY(0); }
796
- }
797
-
798
- .fade-in {
799
- animation: fadeIn 0.5s ease forwards;
800
- }
801
-
802
- /* ์ฐจํŠธ ๋ฐ ํ†ต๊ณ„ ์˜์—ญ */
803
- .stats-container {
804
- display: flex;
805
- flex-wrap: wrap;
806
- gap: 15px;
807
- margin-top: 20px;
808
- }
809
-
810
- .stat-card {
811
- flex: 1;
812
- min-width: 200px;
813
- background-color: white;
814
- border-radius: 10px;
815
- padding: 20px;
816
- box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
817
- text-align: center;
818
- }
819
-
820
- .stat-value {
821
- font-size: 2em;
822
  font-weight: bold;
823
- color: #1e88e5;
824
- margin: 10px 0;
825
  }
826
-
827
- .stat-label {
828
- font-size: 1.2em;
829
- color: #555;
 
 
830
  }
831
-
832
- /* ์ค‘์š” ์ •๋ณด ๊ฐ•์กฐ */
833
- .highlight-text {
834
- background-color: #fff9c4;
835
- padding: 3px 5px;
836
- border-radius: 3px;
837
- font-weight: bold;
838
  }
839
-
840
- /* ๋ฒ„ํŠผ ๊ทธ๋ฃน ์Šคํƒ€์ผ */
841
- .button-group {
842
- display: flex;
843
- gap: 10px;
844
- margin: 20px 0;
845
- }
846
-
847
- .button-group button {
848
- flex: 1;
849
- padding: 12px;
850
- border: none;
851
- border-radius: 8px;
852
- font-size: 1.3em;
853
- cursor: pointer;
854
- transition: all 0.3s ease;
855
- }
856
-
857
- .primary-button {
858
- background-color: #1e88e5;
859
- color: white;
860
- }
861
-
862
- .secondary-button {
863
- background-color: #e0e0e0;
864
- color: #333;
865
- }
866
-
867
- .danger-button {
868
- background-color: #e53935;
869
- color: white;
870
- }
871
-
872
- /* ์ž…๋ ฅ ์š”์†Œ ์˜ค๋ฅ˜ ์Šคํƒ€์ผ */
873
- .input-error {
874
- border-color: #e53935 !important;
875
- }
876
-
877
- .error-message {
878
- color: #e53935;
879
- font-size: 1.1em;
880
- margin-top: 5px;
881
- }
882
-
883
- .gradio-app.dark {
884
- background-color: #1e1e1e !important;
885
- }
886
-
887
- .gradio-app.dark .frame {
888
- background-color: #2d2d2d !important;
889
- box-shadow: 0 5px 20px rgba(0, 0, 0, 0.2) !important;
890
- }
891
-
892
- .gradio-app.dark label, .gradio-app.dark .label-wrap span {
893
- color: #e0e0e0 !important;
894
- }
895
-
896
- .gradio-app.dark .guide-box {
897
- background-color: #2d3748 !important;
898
- }
899
-
900
- .gradio-app.dark input[type=text],
901
- .gradio-app.dark input[type=number],
902
- .gradio-app.dark select,
903
- .gradio-app.dark textarea {
904
- background-color: #1e1e1e !important;
905
- border-color: #3d3d3d !important;
906
- color: #e0e0e0 !important;
907
- }
908
-
909
- .gradio-app.dark input[type=range]::-webkit-slider-runnable-track {
910
- background-color: #3d3d3d !important;
911
- }
912
-
913
- .gradio-app.dark .custom-title,
914
- .gradio-app.dark .frame h3 {
915
- color: #64b5f6 !important;
916
- }
917
-
918
- .gradio-app.dark .gif-button {
919
- background: linear-gradient(45deg, #1565c0, #0d47a1) !important;
920
- }
921
-
922
- .gradio-app.dark .slider-value {
923
- color: #64b5f6 !important;
924
  }
925
  """
 
926
  # -------------------------------
927
  # Gradio UI ๊ตฌ์„ฑ (HTML/CSS ์ปค์Šคํ„ฐ๋งˆ์ด์ง•)
928
  # -------------------------------
 
107
  return output_filename, output_filename, "\n".join(global_logs)
108
 
109
  def update_thumbnails(video, start_time_str, end_time_str):
 
 
110
  video_path = video if isinstance(video, str) else video.name
111
  try:
112
  input_video = mp.VideoFileClip(video_path)
 
126
  end_thumb = generate_thumbnail(input_video, end_sec)
127
  return start_thumb, end_thumb
128
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  # -------------------------------
130
+ # Custom CSS (๊ธ€์ž ํฌ๊ธฐ ํฌ๊ฒŒ, ํšŒ์ƒ‰ ์ œ๊ฑฐ, ํฌ์ธํŠธ ๋ฒ„ํŠผ ๋“ฑ)
131
  # -------------------------------
132
  custom_css = """
 
133
  body {
134
+ font-size: 1.6em; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
135
+ background-color: #ffffff;
136
+ font-family: 'Arial', sans-serif;
 
137
  }
 
138
  .gradio-container {
139
+ width: 80% !important;
 
140
  margin: 0 auto;
141
+ background-color: #ffffff; /* ํšŒ์ƒ‰ ์ œ๊ฑฐ */
 
 
 
 
 
 
 
 
 
 
142
  }
143
+ /* ์ œ๋ชฉ ๋ฐ ์‚ฌ์šฉ๊ฐ€์ด๋“œ (์™ผ์ชฝ ์ •๋ ฌ, ํฌ๊ฒŒ) */
144
  .custom-title {
145
+ font-size: 3.5em; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
146
+ font-weight: bold;
147
+ margin: 20px 0;
148
+ color: #2c3e50;
149
  text-align: left;
 
 
 
 
150
  }
151
+ .custom-user-guide {
152
+ font-size: 1.8em; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
153
+ margin-bottom: 20px;
154
+ color: #2c3e50;
155
+ text-align: left;
 
156
  }
157
+ /* ์‚ฌ์šฉ๊ฐ€์ด๋“œ ๋ฐ•์Šค ์Šคํƒ€์ผ (ํšŒ์ƒ‰ ์ œ๊ฑฐ, ํฐ์ƒ‰ ๋ฐฐ๊ฒฝ) */
 
158
  .guide-box {
159
+ border: 3px solid #3498db; /* ํ…Œ๋‘๋ฆฌ ๋‘๊ป˜ ์ฆ๊ฐ€ */
160
+ border-radius: 10px;
161
+ padding: 20px; /* ํŒจ๋”ฉ ์ฆ๊ฐ€ */
162
+ background-color: #ffffff;
163
+ margin: 20px 0;
164
  text-align: left;
165
+ font-size: 1.2em; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  }
 
 
 
 
 
 
 
 
 
 
 
 
167
  /* ํ”„๋ ˆ์ž„ ์Šคํƒ€์ผ */
168
  .frame {
169
+ border: 3px solid #3498db; /* ํ…Œ๋‘๋ฆฌ ๋‘๊ป˜ ์ฆ๊ฐ€ */
170
+ border-radius: 20px;
171
+ padding: 25px; /* ํŒจ๋”ฉ ์ฆ๊ฐ€ */
172
  background-color: #ffffff;
173
  margin: 15px;
174
+ box-shadow: 3px 3px 10px rgba(0,0,0,0.1);
 
175
  }
176
+ /* ๊ฐ ํ”„๋ ˆ์ž„ ์ œ๋ชฉ ํฌ๊ฒŒ */
 
 
 
 
 
 
177
  .frame h3 {
178
+ font-size: 2.2em; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
179
+ margin-bottom: 20px;
 
180
  text-align: left;
 
 
 
 
 
 
 
 
 
181
  }
 
182
  /* ํ–‰ ๋ฐ ์ปฌ๋Ÿผ ๋ ˆ์ด์•„์›ƒ */
183
  .row-container {
184
  display: flex;
185
  justify-content: space-between;
 
 
186
  }
 
187
  .column {
188
  flex: 1;
189
+ margin: 10px;
190
  }
 
191
  /* ํฌ์ธํŠธ ๋ฒ„ํŠผ ์Šคํƒ€์ผ */
192
  .gif-button {
193
  margin-top: 35px;
194
+ padding: 20px 35px; /* ํŒจ๋”ฉ ์ฆ๊ฐ€ */
195
+ font-size: 1.8em; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
196
+ background-color: #e67e22;
197
  color: #fff;
198
  border: none;
199
  border-radius: 12px;
200
  cursor: pointer;
 
 
 
 
 
 
 
 
 
201
  }
202
+ /* ์Šฌ๋ผ์ด๋” ์Šคํƒ€์ผ (๊ธ€์ž์™€ ๋ฐ” ํฌ๊ฒŒ) */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  input[type=range] {
204
+ height: 30px; /* ๋†’์ด ์ฆ๊ฐ€ */
 
 
 
 
 
 
 
 
 
 
 
 
205
  }
 
206
  input[type=range]::-webkit-slider-thumb {
207
+ height: 30px; /* ๋†’์ด ์ฆ๊ฐ€ */
208
+ width: 30px; /* ๋„ˆ๋น„ ์ฆ๊ฐ€ */
 
 
 
 
 
 
 
 
 
 
209
  }
 
210
  .slider-label {
211
+ font-size: 1.6em; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  margin-bottom: 8px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  }
214
+ /* ๋ชจ๋“  input, select, button ๊ธ€์ž ํฌ๊ธฐ ํ‚ค์›€ */
215
+ input, button, select, textarea {
216
+ font-size: 1.5em; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  }
218
+ /* ๋ผ๋ฒจ ๊ธ€์ž ํฌ๊ธฐ ํ‚ค์›€ */
219
+ label, .label-wrap span {
220
+ font-size: 1.3em !important; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  font-weight: bold;
 
 
222
  }
223
+ /* ํšŒ์ƒ‰ ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ */
224
+ .gradio-container .prose,
225
+ .gradio-container .gr-box,
226
+ .gradio-container .gr-form,
227
+ .gradio-container .gr-panel {
228
+ background-color: #ffffff !important;
229
  }
230
+ .gradio-container .gr-form,
231
+ .gradio-container .gr-group {
232
+ border-color: #3498db;
233
+ background-color: #ffffff !important;
 
 
 
234
  }
235
+ .gradio-container .gr-input,
236
+ .gradio-container .gr-checkbox,
237
+ .gradio-container .gr-radio,
238
+ .gradio-container .gr-dropdown {
239
+ font-size: 1.4em; /* ๊ธ€์ž ํฌ๊ธฐ ์ฆ๊ฐ€ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  }
241
  """
242
+
243
  # -------------------------------
244
  # Gradio UI ๊ตฌ์„ฑ (HTML/CSS ์ปค์Šคํ„ฐ๋งˆ์ด์ง•)
245
  # -------------------------------