比较完美了
Browse files- youtube_sub.js +41 -32
youtube_sub.js
CHANGED
|
@@ -386,13 +386,17 @@ GM_addStyle(`
|
|
| 386 |
.map(event => ({
|
| 387 |
startTime: event.tStartMs / 1000,
|
| 388 |
endTime: (event.tStartMs + event.dDurationMs) / 1000,
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
|
|
|
|
|
|
|
|
|
| 394 |
}))
|
| 395 |
-
|
|
|
|
| 396 |
|
| 397 |
debug.log(`Loaded ${subtitles.length} subtitles`);
|
| 398 |
return subtitles;
|
|
@@ -549,35 +553,40 @@ GM_addStyle(`
|
|
| 549 |
this.container.classList.toggle('collapsed', this.isCollapsed);
|
| 550 |
}
|
| 551 |
|
| 552 |
-
// Update displaySingleLanguage
|
| 553 |
displaySingleLanguage(container, subtitles) {
|
| 554 |
subtitles.forEach((sub, index) => {
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
|
| 561 |
-
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
|
| 565 |
-
|
| 566 |
-
|
| 567 |
-
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
timestamp.textContent = this.formatTime(sub.startTime);
|
| 575 |
-
|
| 576 |
-
line.appendChild(timestamp);
|
| 577 |
-
line.dataset.time = sub.startTime;
|
| 578 |
-
line.dataset.index = index;
|
| 579 |
|
| 580 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 581 |
});
|
| 582 |
}
|
| 583 |
|
|
|
|
| 386 |
.map(event => ({
|
| 387 |
startTime: event.tStartMs / 1000,
|
| 388 |
endTime: (event.tStartMs + event.dDurationMs) / 1000,
|
| 389 |
+
// Filter out empty segments
|
| 390 |
+
words: event.segs
|
| 391 |
+
.filter(seg => seg.utf8 && seg.utf8.trim())
|
| 392 |
+
.map(seg => ({
|
| 393 |
+
text: seg.utf8,
|
| 394 |
+
startTime: seg.tOffsetMs ? (event.tStartMs + seg.tOffsetMs) / 1000 : event.tStartMs / 1000,
|
| 395 |
+
endTime: (seg.tOffsetMs ? event.tStartMs + seg.tOffsetMs + (seg.dDurationMs || 0) : event.tStartMs + event.dDurationMs) / 1000
|
| 396 |
+
}))
|
| 397 |
}))
|
| 398 |
+
// Filter out subtitles with no words
|
| 399 |
+
.filter(sub => sub.words && sub.words.length > 0);
|
| 400 |
|
| 401 |
debug.log(`Loaded ${subtitles.length} subtitles`);
|
| 402 |
return subtitles;
|
|
|
|
| 553 |
this.container.classList.toggle('collapsed', this.isCollapsed);
|
| 554 |
}
|
| 555 |
|
| 556 |
+
// Update displaySingleLanguage method
|
| 557 |
displaySingleLanguage(container, subtitles) {
|
| 558 |
subtitles.forEach((sub, index) => {
|
| 559 |
+
// Only create lines with actual content
|
| 560 |
+
if (sub.words && sub.words.length > 0) {
|
| 561 |
+
const line = document.createElement('div');
|
| 562 |
+
line.className = 'subtitle-line';
|
| 563 |
+
|
| 564 |
+
sub.words.forEach((word, i) => {
|
| 565 |
+
if (word.text && word.text.trim()) {
|
| 566 |
+
const wordSpan = document.createElement('span');
|
| 567 |
+
wordSpan.className = 'subtitle-word';
|
| 568 |
+
wordSpan.textContent = word.text.trim();
|
| 569 |
+
wordSpan.dataset.start = word.startTime;
|
| 570 |
+
wordSpan.dataset.end = word.endTime;
|
| 571 |
+
line.appendChild(wordSpan);
|
| 572 |
+
|
| 573 |
+
if (i < sub.words.length - 1) {
|
| 574 |
+
line.appendChild(document.createTextNode(' '));
|
| 575 |
+
}
|
| 576 |
+
}
|
| 577 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 578 |
|
| 579 |
+
// Only add lines with content
|
| 580 |
+
if (line.textContent.trim()) {
|
| 581 |
+
const timestamp = document.createElement('span');
|
| 582 |
+
timestamp.className = 'timestamp';
|
| 583 |
+
timestamp.textContent = this.formatTime(sub.startTime);
|
| 584 |
+
line.appendChild(timestamp);
|
| 585 |
+
line.dataset.time = sub.startTime;
|
| 586 |
+
line.dataset.index = index;
|
| 587 |
+
container.appendChild(line);
|
| 588 |
+
}
|
| 589 |
+
}
|
| 590 |
});
|
| 591 |
}
|
| 592 |
|