Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 61 additions & 6 deletions static/js/studio/player-render.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import * as playerControls from './player-controls.js';
import * as playerChunk from './player-chunk.js';
import * as playerQueue from './player-queue.js';
import * as playerWaveform from './player-waveform.js';
import * as state from './state.js';
import { createElement, clearContent } from './dom.js';

const SPEED_STEPS = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3];
Expand Down Expand Up @@ -327,6 +328,24 @@ function renderChunkSegments() {
}

function updateSubtitleDisplay(chunk) {
const settings = state.get('settings') || {};
const showSubtitles = settings.show_subtitles !== 'false' && settings.show_subtitles !== false;
const subtitleMode = settings.subtitle_mode || 'full';

const container = $('fs-subtitles-container');
if (container) {
container.style.display = showSubtitles ? 'flex' : 'none';
}

if (!showSubtitles) {
playerState.setCurrentSubtitleText('');
playerState.setSubtitleSentences([]);
playerState.setSubtitleTimings([]);
const el = $('fs-subtitle-text');
if (el) clearContent(el);
return;
}

if (chunk && chunk.text) {
playerState.setCurrentSubtitleText(chunk.text);
const sentences = chunk.text.split(/(?<=[.!?])\s+/).filter(s => s.trim());
Expand All @@ -336,7 +355,12 @@ function updateSubtitleDisplay(chunk) {
return wordCount / 2.5;
});
playerState.setSubtitleTimings(timings);
renderKaraoke(sentences, 0, -1);

if (subtitleMode === 'full') {
renderFullText(sentences);
} else {
renderKaraoke(sentences, 0, -1);
}
} else {
playerState.setCurrentSubtitleText('');
playerState.setSubtitleSentences([]);
Expand All @@ -358,6 +382,21 @@ function renderKaraokeIdle(message) {
el.appendChild(fragment);
}

function renderFullText(sentences) {
const el = $('fs-subtitle-text');
if (!el || !sentences.length) return;

clearContent(el);
const fragment = document.createDocumentFragment();
sentences.forEach((sentence, i) => {
if (i > 0) {
fragment.appendChild(document.createTextNode(' '));
}
fragment.appendChild(createElement('span', { className: 'full-sentence' }, [sentence]));
});
el.appendChild(fragment);
}

function renderKaraoke(sentences, sentenceIndex, wordIndex) {
const el = $('fs-subtitle-text');
if (!el || !sentences.length) return;
Expand All @@ -379,17 +418,30 @@ function renderKaraoke(sentences, sentenceIndex, wordIndex) {
}

export function updateSubtitles(text) {
const settings = state.get('settings') || {};
const showSubtitles = settings.show_subtitles !== 'false' && settings.show_subtitles !== false;
const subtitleMode = settings.subtitle_mode || 'full';

if (!showSubtitles) return;

const subtitleEl = $('fs-subtitle-text');
if (!subtitleEl) return;
if (!text) {
renderKaraokeIdle('No subtitle available');
return;
}
const sentences = text.split(/(?<=[.!?])\s+/).filter(s => s.trim());
renderKaraoke(sentences, 0, -1);
if (subtitleMode === 'full') {
renderFullText(sentences);
} else {
renderKaraoke(sentences, 0, -1);
}
}

export function updateSubtitlesSync() {
const settings = state.get('settings') || {};
const subtitleMode = settings.subtitle_mode || 'full';

const audio = playerState.getAudio();
const currentSubtitleText = playerState.getCurrentSubtitleText();
if (!audio || !isFinite(audio.duration) || !currentSubtitleText) return;
Expand Down Expand Up @@ -418,10 +470,13 @@ export function updateSubtitlesSync() {
const timeInSentence = currentTime - sentenceStart;
const progress = Math.max(0, Math.min(1, timeInSentence / sentenceDuration));

const words = sentence.split(/\s+/);
const activeWordIndex = Math.floor(progress * words.length);

renderKaraoke(subtitleSentences, currentSentenceIndex, activeWordIndex);
if (subtitleMode === 'full') {
renderFullText(subtitleSentences);
} else {
const words = sentence.split(/\s+/);
const activeWordIndex = Math.floor(progress * words.length);
renderKaraoke(subtitleSentences, currentSentenceIndex, activeWordIndex);
}
}

export function updateCoverArt() {
Expand Down