Opera8 commited on
Commit
e6fdeb9
·
verified ·
1 Parent(s): 1825431

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +59 -57
index.html CHANGED
@@ -102,7 +102,8 @@
102
  textarea { min-height: 120px; resize: vertical; }
103
  textarea:focus, input:focus, select:focus { border-color: var(--accent-primary); background: #fff; }
104
 
105
- input[type="file"] { padding: 10px; background: #fff; font-size: 0.9rem; }
 
106
 
107
  /* دکمه اصلی */
108
  @keyframes move-gradient {
@@ -167,43 +168,43 @@
167
  .download-btn-style.locked { background-color: #f1f5f9; color: #94a3b8; }
168
  .download-btn-style.locked:hover { background-color: #e2e8f0; }
169
 
170
- .audio-item { margin-bottom: 10px; }
171
  audio { width: 100%; height: 50px; border-radius: 25px; margin-top: 5px; }
172
 
173
- /* کانتینر لیریک هماهنگ */
174
  .lyrics-container {
175
- background: var(--input-bg); border-radius: 16px; padding: 20px;
176
- height: 320px; overflow-y: auto; scroll-behavior: smooth;
177
- border: 1px solid var(--input-border); margin-top: 15px;
178
- text-align: center; position: relative;
179
- /* افکت فید شدن بالا و پایین */
180
- mask-image: linear-gradient(to bottom, transparent, black 15%, black 85%, transparent);
181
- -webkit-mask-image: linear-gradient(to bottom, transparent, black 15%, black 85%, transparent);
 
 
182
  }
183
 
 
184
  .lyric-line {
185
- margin: 12px 0;
 
186
  font-size: 1rem;
187
- color: #718096;
188
- transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
189
- line-height: 1.8;
190
- opacity: 0.5;
191
- transform: scale(0.95);
192
  cursor: default;
 
 
193
  }
194
 
195
- /* استایل خط فعال (خوانده شده) */
196
  .lyric-line.active {
197
- color: var(--accent-primary);
198
- font-weight: 800;
199
- font-size: 1.15rem;
200
- opacity: 1;
201
- transform: scale(1.05);
202
- text-shadow: 0 5px 15px rgba(74, 108, 250, 0.2);
203
  }
204
 
205
- .lyrics-tag { color: var(--accent-secondary); font-size: 0.8em; margin-top: 15px; display: block; font-weight: 700; }
206
-
207
  /* لودر */
208
  #loader { display: none; text-align: center; padding: 20px; }
209
  .wave-bars { display: flex; justify-content: center; gap: 4px; height: 30px; align-items: flex-end; }
@@ -608,7 +609,6 @@
608
  mainDownloadBtn.style.display = 'inline-flex';
609
  mainDownloadBtn.onclick = (e) => handleSecureDownload(audioURL, e);
610
 
611
- // اگر دیتای LRC ذخیره شده باشد از آن استفاده می‌کنیم، وگرنه از متن ساده
612
  setupPlayerWithLyrics(audioURL, item.lrcData || null, item.lyrics);
613
 
614
  finalResult.style.display = 'block';
@@ -658,7 +658,6 @@
658
  resolve(msg.output);
659
  } else if (msg.msg === 'close') {
660
  eventSource.close();
661
- // گاهی اوقات close میاد ولی دیتا در process_completed بوده
662
  }
663
  };
664
 
@@ -743,17 +742,19 @@
743
 
744
  if(!audioFileObj) throw new Error("Audio generation failed");
745
 
746
- // 4. دریافت LRC (سینک کردن) - فانکشن 85 طبق لاگ
 
747
  let lrcData = null;
748
  if (!isInstrumental) {
749
  loaderText.innerText = "در حال هماهنگ‌سازی متن و آهنگ...";
750
  try {
751
- // طبق لاگ‌ها فانکشن 85 خروجی LRC متنی برمی‌گرداند [00:00.00]Text
752
- // ورودی احتمالا فایل صوتی است
753
- const lrcOutput = await runGradioFunction(85, [audioFileObj]);
754
- // خروجی فانکشن 85 معمولا یک لیست است که عنصر اولش متن LRC است
755
  if (lrcOutput && lrcOutput.data && lrcOutput.data[0]) {
756
- lrcData = lrcOutput.data[0];
 
 
 
 
757
  }
758
  } catch (e) {
759
  console.warn("LRC generation failed, using plain lyrics", e);
@@ -810,29 +811,32 @@
810
  window.scrollTo({ top: 0, behavior: 'smooth' });
811
  }
812
 
813
- // --- پارسر LRC ---
814
- function parseLRC(lrcText) {
815
  const lines = [];
816
- // فرمت استاندارد LRC: [mm:ss.xx]Text
817
- const regex = /\[(\d{2}):(\d{2})\.(\d{2,3})\](.*)/;
818
 
819
- const rawLines = lrcText.split('\n');
820
- for(let line of rawLines) {
821
- const match = line.match(regex);
822
  if(match) {
823
- const minutes = parseInt(match[1]);
824
- const seconds = parseInt(match[2]);
825
- const milliseconds = parseInt(match[3]);
826
- const time = minutes * 60 + seconds + (milliseconds / 100);
827
- const text = match[4].trim();
828
- if(text) {
829
- lines.push({ time, text });
830
  }
831
  }
832
  }
833
  return lines;
834
  }
835
 
 
 
 
 
 
836
  function setupPlayerWithLyrics(audioSrc, lrcData, rawLyrics) {
837
  playerWrapper.innerHTML = '';
838
  finalLyricsBox.innerHTML = '';
@@ -843,9 +847,9 @@
843
  audio.src = audioSrc;
844
  playerWrapper.appendChild(audio);
845
 
846
- // اگر دیتای LRC موجود باشد (سینک شده)
847
- if (lrcData && typeof lrcData === 'string' && lrcData.includes('[')) {
848
- const parsedLyrics = parseLRC(lrcData);
849
 
850
  parsedLyrics.forEach((line, index) => {
851
  const p = document.createElement('p');
@@ -859,12 +863,11 @@
859
  const currentTime = audio.currentTime;
860
  let activeIndex = -1;
861
 
862
- // پیدا کردن خطی که زمانش رد شده اما خط بعدی هنوز نرسیده
863
  for (let i = 0; i < parsedLyrics.length; i++) {
864
- if (currentTime >= parsedLyrics[i].time) {
865
  activeIndex = i;
866
- } else {
867
- break;
868
  }
869
  }
870
 
@@ -882,16 +885,15 @@
882
  } else {
883
  // حالت متن ساده (بدون سینک)
884
  if (rawLyrics) {
885
- // نمایش با استایل خط به خط اما بدون اکتیو شدن
886
  const lines = rawLyrics.split('\n').filter(l => l.trim() !== '');
887
  lines.forEach(line => {
888
  const p = document.createElement('p');
889
- p.className = 'lyric-line'; // همان استایل
890
  p.innerText = line;
891
  finalLyricsBox.appendChild(p);
892
  });
893
  } else {
894
- finalLyricsBox.innerHTML = '<span style="color:#cbd5e0; display:block; padding-top:100px;">(متن آهنگی موجود نیست یا آهنگ بی‌کلام است)</span>';
895
  }
896
  }
897
  }
 
102
  textarea { min-height: 120px; resize: vertical; }
103
  textarea:focus, input:focus, select:focus { border-color: var(--accent-primary); background: #fff; }
104
 
105
+ /* استایل اختصاصی فایل آپلود */
106
+ input[type="file"] { padding: 10px; font-size: 0.9rem; background: #fff; }
107
 
108
  /* دکمه اصلی */
109
  @keyframes move-gradient {
 
168
  .download-btn-style.locked { background-color: #f1f5f9; color: #94a3b8; }
169
  .download-btn-style.locked:hover { background-color: #e2e8f0; }
170
 
171
+ .audio-item { margin-bottom: 10px; width: 100%; }
172
  audio { width: 100%; height: 50px; border-radius: 25px; margin-top: 5px; }
173
 
174
+ /* استایل باکس لیریک (برگشت به حالت اول) */
175
  .lyrics-container {
176
+ background: var(--input-bg);
177
+ border-radius: 16px;
178
+ padding: 20px;
179
+ max-height: 350px;
180
+ overflow-y: auto;
181
+ border: 1px solid var(--input-border);
182
+ margin-top: 15px;
183
+ text-align: center;
184
+ scroll-behavior: smooth; /* اسکرول نرم */
185
  }
186
 
187
+ /* استایل خطوط متن */
188
  .lyric-line {
189
+ margin: 0;
190
+ padding: 8px 0;
191
  font-size: 1rem;
192
+ color: #4a5568; /* رنگ خاکستری تیره اصلی */
193
+ transition: all 0.3s ease;
 
 
 
194
  cursor: default;
195
+ line-height: 1.8;
196
+ font-weight: 400;
197
  }
198
 
199
+ /* استایل خط فعال */
200
  .lyric-line.active {
201
+ color: var(--accent-primary); /* آبی اصلی */
202
+ font-weight: 800; /* بولد */
203
+ transform: scale(1.05); /* کمی بزرگتر */
204
+ background: rgba(74, 108, 250, 0.05); /* پس زمینه خیلی محو */
205
+ border-radius: 8px;
 
206
  }
207
 
 
 
208
  /* لودر */
209
  #loader { display: none; text-align: center; padding: 20px; }
210
  .wave-bars { display: flex; justify-content: center; gap: 4px; height: 30px; align-items: flex-end; }
 
609
  mainDownloadBtn.style.display = 'inline-flex';
610
  mainDownloadBtn.onclick = (e) => handleSecureDownload(audioURL, e);
611
 
 
612
  setupPlayerWithLyrics(audioURL, item.lrcData || null, item.lyrics);
613
 
614
  finalResult.style.display = 'block';
 
658
  resolve(msg.output);
659
  } else if (msg.msg === 'close') {
660
  eventSource.close();
 
661
  }
662
  };
663
 
 
742
 
743
  if(!audioFileObj) throw new Error("Audio generation failed");
744
 
745
+ // 4. دریافت LRC (سینک کردن) - فانکشن 84 طبق لاگ شما
746
+ // لاگ شما نشان داد فانکشن 84 فایل VTT تولید میکند
747
  let lrcData = null;
748
  if (!isInstrumental) {
749
  loaderText.innerText = "در حال هماهنگ‌سازی متن و آهنگ...";
750
  try {
751
+ const lrcOutput = await runGradioFunction(84, [audioFileObj]);
 
 
 
752
  if (lrcOutput && lrcOutput.data && lrcOutput.data[0]) {
753
+ // دریافت محتوای فایل VTT
754
+ const vttFile = lrcOutput.data[0];
755
+ const vttUrl = vttFile.url ? vttFile.url : `${ACE_SPACE_URL}gradio_api/file=${vttFile.path}`;
756
+ const resp = await fetch(vttUrl);
757
+ lrcData = await resp.text();
758
  }
759
  } catch (e) {
760
  console.warn("LRC generation failed, using plain lyrics", e);
 
811
  window.scrollTo({ top: 0, behavior: 'smooth' });
812
  }
813
 
814
+ // --- پارسر VTT ---
815
+ function parseVTT(vttText) {
816
  const lines = [];
817
+ // Regex برای فرمت VTT: 00:00:16.320 --> 00:00:20.640
818
+ const regex = /(\d{2}:\d{2}:\d{2}\.\d{3})\s-->\s(\d{2}:\d{2}:\d{2}\.\d{3})\n(.*)/;
819
 
820
+ const blocks = vttText.split('\n\n');
821
+ for(let block of blocks) {
822
+ const match = block.match(regex);
823
  if(match) {
824
+ const startTime = timeToSeconds(match[1]);
825
+ const endTime = timeToSeconds(match[2]);
826
+ const text = match[3].trim();
827
+ if(text && text !== '[Intro]' && text !== '[Chorus]' && text !== '[Verse]') {
828
+ lines.push({ startTime, endTime, text });
 
 
829
  }
830
  }
831
  }
832
  return lines;
833
  }
834
 
835
+ function timeToSeconds(timeStr) {
836
+ const [h, m, s] = timeStr.split(':');
837
+ return parseFloat(h) * 3600 + parseFloat(m) * 60 + parseFloat(s);
838
+ }
839
+
840
  function setupPlayerWithLyrics(audioSrc, lrcData, rawLyrics) {
841
  playerWrapper.innerHTML = '';
842
  finalLyricsBox.innerHTML = '';
 
847
  audio.src = audioSrc;
848
  playerWrapper.appendChild(audio);
849
 
850
+ // اگر دیتای VTT موجود باشد (سینک شده)
851
+ if (lrcData && typeof lrcData === 'string' && lrcData.includes('WEBVTT')) {
852
+ const parsedLyrics = parseVTT(lrcData);
853
 
854
  parsedLyrics.forEach((line, index) => {
855
  const p = document.createElement('p');
 
863
  const currentTime = audio.currentTime;
864
  let activeIndex = -1;
865
 
866
+ // پیدا کردن خطی که در بازه زمانی فعلی است
867
  for (let i = 0; i < parsedLyrics.length; i++) {
868
+ if (currentTime >= parsedLyrics[i].startTime && currentTime < parsedLyrics[i].endTime) {
869
  activeIndex = i;
870
+ break;
 
871
  }
872
  }
873
 
 
885
  } else {
886
  // حالت متن ساده (بدون سینک)
887
  if (rawLyrics) {
 
888
  const lines = rawLyrics.split('\n').filter(l => l.trim() !== '');
889
  lines.forEach(line => {
890
  const p = document.createElement('p');
891
+ p.className = 'lyric-line';
892
  p.innerText = line;
893
  finalLyricsBox.appendChild(p);
894
  });
895
  } else {
896
+ finalLyricsBox.innerHTML = '<span style="color:#a0aec0; display:block; padding-top:100px;">(متن آهنگی موجود نیست یا آهنگ بی‌کلام است)</span>';
897
  }
898
  }
899
  }