Opera8 commited on
Commit
45284c6
·
verified ·
1 Parent(s): ab91fef

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -35
app.py CHANGED
@@ -79,6 +79,7 @@ def generate_ass_file(data: ProcessRequest, output_path: str):
79
  border_style = 1
80
  back_color = "&H00000000"
81
 
 
82
  if s.backType == 'solid':
83
  border_style = 3
84
  outline = hex_to_ass(s.outlineColor, "00")
@@ -88,13 +89,13 @@ def generate_ass_file(data: ProcessRequest, output_path: str):
88
  else:
89
  border_style = 1
90
 
91
- # نکته مهم: PlayResY روی 1080 تنظیم شده.
92
- # بنابراین فونت سایز 100 یعنی تقریبا 1/10 ارتفاع تصویر.
93
  header = f"""[Script Info]
94
  ScriptType: v4.00+
95
  PlayResX: 1080
96
  PlayResY: 1920
97
  WrapStyle: 1
 
98
 
99
  [V4+ Styles]
100
  Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
@@ -330,10 +331,23 @@ async def interface():
330
  .segment-row:focus-within { border-right-color: var(--accent); background: rgba(255,255,255,0.06); }
331
 
332
  .seg-time { font-size: 0.75rem; color: var(--text-muted); margin-bottom: 5px; font-family: monospace; }
 
 
333
  .seg-input {
334
- width: 100%; background: transparent; border: none;
335
- color: var(--text-main); font-size: 1.1rem; font-family: inherit;
336
- resize: none; overflow: hidden;
 
 
 
 
 
 
 
 
 
 
 
337
  }
338
 
339
  .control-group { margin-bottom: 18px; }
@@ -373,14 +387,18 @@ async def interface():
373
 
374
  /* --- RESULT SECTION INLINE --- */
375
  #inlineResult {
376
- margin-top: 20px;
377
- border-top: 2px dashed var(--border);
378
- padding-top: 20px;
 
 
379
  text-align: center;
380
  display: none;
381
- animation: fadeIn 0.5s;
382
  }
383
- .result-video { width: 100%; border-radius: 12px; margin-top: 10px; box-shadow: 0 0 30px rgba(0,0,0,0.5); }
 
 
384
  .dl-btn {
385
  display: inline-block; margin-top: 15px; padding: 12px 30px;
386
  background: var(--success); color: white; text-decoration: none;
@@ -436,6 +454,13 @@ async def interface():
436
  <div class="settings-panel card">
437
  <h2 style="color: var(--primary); margin-top:0;">🎨 استایل و خروجی</h2>
438
 
 
 
 
 
 
 
 
439
  <div class="preview-box">
440
  <div id="livePreview" class="preview-text">متن نمونه</div>
441
  </div>
@@ -468,9 +493,9 @@ async def interface():
468
  </div>
469
 
470
  <div class="control-group">
471
- <div class="control-label"><span>سایز متن</span> <span id="lblSize">80</span></div>
472
- <!-- SLIDER INCREASED TO 400 FOR HUGE TEXT -->
473
- <input type="range" id="rngSize" min="30" max="400" value="80" oninput="updatePreview()">
474
  </div>
475
 
476
  <div class="control-group">
@@ -479,15 +504,9 @@ async def interface():
479
  </div>
480
 
481
  <button class="btn btn-primary" onclick="startRender()">
482
- <i class="fa-solid fa-wand-magic-sparkles"></i> ساخت خروجی نهایی
483
  </button>
484
 
485
- <!-- INLINE RESULT AREA -->
486
- <div id="inlineResult">
487
- <h3 style="color: var(--success);">✅ ویدیو آماده شد!</h3>
488
- <video id="finalPlayer" controls class="result-video"></video>
489
- <a id="dlBtn" href="#" download class="dl-btn">دانلود ویدیو</a>
490
- </div>
491
  </div>
492
 
493
  <!-- TEXT EDITOR -->
@@ -532,7 +551,6 @@ async def interface():
532
 
533
  renderSegments();
534
 
535
- // Switch view
536
  document.getElementById('view-upload').classList.remove('active');
537
  document.getElementById('view-editor').classList.add('active');
538
  updatePreview();
@@ -553,17 +571,11 @@ async def interface():
553
  const div = document.createElement('div');
554
  div.className = 'segment-row';
555
  div.innerHTML = `
556
- <div class="seg-time">${formatTime(seg.start)} - ${formatTime(seg.end)}</div>
557
  <textarea class="seg-input" rows="1" oninput="updateSegment(${idx}, this)">${seg.text}</textarea>
558
  `;
559
  container.appendChild(div);
560
  });
561
-
562
- // Auto resize
563
- document.querySelectorAll('.seg-input').forEach(tx => {
564
- tx.style.height = 'auto';
565
- tx.style.height = (tx.scrollHeight) + 'px';
566
- });
567
  }
568
 
569
  function updateSegment(idx, el) {
@@ -605,8 +617,8 @@ async def interface():
605
  document.getElementById('lblSize').innerText = size;
606
 
607
  txt.style.fontFamily = font;
608
- // Scale down font size for preview box (approx 1/3 ratio)
609
- txt.style.fontSize = (size / 3) + 'px';
610
  txt.style.color = color;
611
  txt.style.bottom = (pos / 6) + 'px';
612
 
@@ -630,9 +642,7 @@ async def interface():
630
 
631
  // --- RENDER ---
632
  async function startRender() {
633
- // Hide previous result if any
634
- document.getElementById('inlineResult').style.display = 'none';
635
- showLoader("در حال رندر ویدیو...");
636
 
637
  const payload = {
638
  file_id: appState.fileId,
@@ -662,11 +672,11 @@ async def interface():
662
  const resultBox = document.getElementById('inlineResult');
663
  resultBox.style.display = 'block';
664
 
665
- // Timestamp to prevent caching
666
  document.getElementById('finalPlayer').src = data.url + "?t=" + Date.now();
667
  document.getElementById('dlBtn').href = data.url;
668
 
669
- // Smooth Scroll to result
670
  resultBox.scrollIntoView({behavior: 'smooth'});
671
 
672
  } catch(e) {
 
79
  border_style = 1
80
  back_color = "&H00000000"
81
 
82
+ # تنظیمات دقیق‌تر کادر برای دیده شدن بهتر
83
  if s.backType == 'solid':
84
  border_style = 3
85
  outline = hex_to_ass(s.outlineColor, "00")
 
89
  else:
90
  border_style = 1
91
 
92
+ # تغییر مهم: ScaledBorderAndShadow برای اینکه در رزولوشن‌های بالا حاشیه محو نشود
 
93
  header = f"""[Script Info]
94
  ScriptType: v4.00+
95
  PlayResX: 1080
96
  PlayResY: 1920
97
  WrapStyle: 1
98
+ ScaledBorderAndShadow: yes
99
 
100
  [V4+ Styles]
101
  Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
 
331
  .segment-row:focus-within { border-right-color: var(--accent); background: rgba(255,255,255,0.06); }
332
 
333
  .seg-time { font-size: 0.75rem; color: var(--text-muted); margin-bottom: 5px; font-family: monospace; }
334
+
335
+ /* اصلاح استایل تکست باکس برای دیده شدن متن */
336
  .seg-input {
337
+ width: 100%;
338
+ background: rgba(0, 0, 0, 0.2); /* پس‌زمینه تیره */
339
+ border: 1px solid var(--border); /* کادر مشخص */
340
+ border-radius: 8px;
341
+ color: #fff; /* متن سفید */
342
+ font-size: 1.1rem;
343
+ font-family: inherit;
344
+ resize: vertical;
345
+ padding: 10px;
346
+ min-height: 60px;
347
+ }
348
+ .seg-input:focus {
349
+ border-color: var(--primary);
350
+ background: rgba(0, 0, 0, 0.3);
351
  }
352
 
353
  .control-group { margin-bottom: 18px; }
 
387
 
388
  /* --- RESULT SECTION INLINE --- */
389
  #inlineResult {
390
+ margin-bottom: 20px; /* فاصله از دکمه */
391
+ padding: 20px;
392
+ border: 2px solid var(--success);
393
+ border-radius: 16px;
394
+ background: rgba(16, 185, 129, 0.05);
395
  text-align: center;
396
  display: none;
397
+ animation: slideDown 0.5s ease;
398
  }
399
+ @keyframes slideDown { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } }
400
+
401
+ .result-video { width: 100%; border-radius: 12px; margin-top: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
402
  .dl-btn {
403
  display: inline-block; margin-top: 15px; padding: 12px 30px;
404
  background: var(--success); color: white; text-decoration: none;
 
454
  <div class="settings-panel card">
455
  <h2 style="color: var(--primary); margin-top:0;">🎨 استایل و خروجی</h2>
456
 
457
+ <!-- INLINE RESULT AREA (MOVED UP) -->
458
+ <div id="inlineResult">
459
+ <h3 style="color: var(--success); margin:0;">✅ ویدیو آماده شد!</h3>
460
+ <video id="finalPlayer" controls class="result-video"></video>
461
+ <a id="dlBtn" href="#" download class="dl-btn">دانلود ویدیو</a>
462
+ </div>
463
+
464
  <div class="preview-box">
465
  <div id="livePreview" class="preview-text">متن نمونه</div>
466
  </div>
 
493
  </div>
494
 
495
  <div class="control-group">
496
+ <div class="control-label"><span>سایز متن</span> <span id="lblSize">100</span></div>
497
+ <!-- افزایش بازه برای فونت‌های بزرگ -->
498
+ <input type="range" id="rngSize" min="30" max="300" value="100" oninput="updatePreview()">
499
  </div>
500
 
501
  <div class="control-group">
 
504
  </div>
505
 
506
  <button class="btn btn-primary" onclick="startRender()">
507
+ <i class="fa-solid fa-wand-magic-sparkles"></i> شروع ساخت / بروزرسانی
508
  </button>
509
 
 
 
 
 
 
 
510
  </div>
511
 
512
  <!-- TEXT EDITOR -->
 
551
 
552
  renderSegments();
553
 
 
554
  document.getElementById('view-upload').classList.remove('active');
555
  document.getElementById('view-editor').classList.add('active');
556
  updatePreview();
 
571
  const div = document.createElement('div');
572
  div.className = 'segment-row';
573
  div.innerHTML = `
574
+ <div class="seg-time">${formatTime(seg.start)} -> ${formatTime(seg.end)}</div>
575
  <textarea class="seg-input" rows="1" oninput="updateSegment(${idx}, this)">${seg.text}</textarea>
576
  `;
577
  container.appendChild(div);
578
  });
 
 
 
 
 
 
579
  }
580
 
581
  function updateSegment(idx, el) {
 
617
  document.getElementById('lblSize').innerText = size;
618
 
619
  txt.style.fontFamily = font;
620
+ // تقسیم بر ۵ برای واقعی‌تر شدن پیش‌نمایش
621
+ txt.style.fontSize = (size / 5) + 'px';
622
  txt.style.color = color;
623
  txt.style.bottom = (pos / 6) + 'px';
624
 
 
642
 
643
  // --- RENDER ---
644
  async function startRender() {
645
+ showLoader("در حال ساخت ویدیو...");
 
 
646
 
647
  const payload = {
648
  file_id: appState.fileId,
 
672
  const resultBox = document.getElementById('inlineResult');
673
  resultBox.style.display = 'block';
674
 
675
+ // اضافه کردن زمان برای جلوگیری از کش
676
  document.getElementById('finalPlayer').src = data.url + "?t=" + Date.now();
677
  document.getElementById('dlBtn').href = data.url;
678
 
679
+ // اسکرول به نتیجه
680
  resultBox.scrollIntoView({behavior: 'smooth'});
681
 
682
  } catch(e) {