diff --git a/built/web/player/.DS_Store b/built/web/player/.DS_Store index 22516bb4..ded92aab 100644 Binary files a/built/web/player/.DS_Store and b/built/web/player/.DS_Store differ diff --git a/built/web/player/FastStreamClient.mjs b/built/web/player/FastStreamClient.mjs index 27a4c82f..51cbb26f 100644 --- a/built/web/player/FastStreamClient.mjs +++ b/built/web/player/FastStreamClient.mjs @@ -256,6 +256,7 @@ export class FastStreamClient extends EventEmitter { } async setSource(source) { source = source.copy(); + const autoPlay = this.options.autoPlay; console.log('setSource', source); await this.resetPlayer(); this.source = source; @@ -266,7 +267,7 @@ export class FastStreamClient extends EventEmitter { this.bindPlayer(this.player); await this.player.setSource(source); this.interfaceController.addVideo(this.player.getVideo()); - if (this.options.autoPlay) { + if (autoPlay) { this.player.getVideo().autoplay = true; } this.audioContext = new AudioContext(); @@ -290,7 +291,7 @@ export class FastStreamClient extends EventEmitter { await this.videoAnalyzer.setSource(this.player.getSource()); this.updateCSSFilters(); this.interfaceController.updateToolVisibility(); - if (this.options.autoPlay) { + if (autoPlay) { this.play(); } } @@ -761,4 +762,13 @@ export class FastStreamClient extends EventEmitter { get currentVideo() { return this.player?.getVideo() || null; } + debugDemo() { + this.interfaceController.hideControlBar = ()=>{}; + this.videoAnalyzer.introAligner.detectedStartTime = 0; + this.videoAnalyzer.introAligner.detectedEndTime = 30; + this.videoAnalyzer.introAligner.found = true; + this.videoAnalyzer.introAligner.emit('match', true); + this.currentTime = 6; + this.player.getVideo().style.objectFit = 'cover'; + } } diff --git a/built/web/player/assets/.DS_Store b/built/web/player/assets/.DS_Store index 3120cf3e..49f49ff5 100644 Binary files a/built/web/player/assets/.DS_Store and b/built/web/player/assets/.DS_Store differ diff --git a/built/web/player/assets/fluidplayer/.DS_Store b/built/web/player/assets/fluidplayer/.DS_Store index 982e5a4f..2e4a9694 100644 Binary files a/built/web/player/assets/fluidplayer/.DS_Store and b/built/web/player/assets/fluidplayer/.DS_Store differ diff --git a/built/web/player/assets/fluidplayer/css/fluidplayer.css b/built/web/player/assets/fluidplayer/css/fluidplayer.css index 459ebe41..401d6e90 100644 --- a/built/web/player/assets/fluidplayer/css/fluidplayer.css +++ b/built/web/player/assets/fluidplayer/css/fluidplayer.css @@ -1109,6 +1109,7 @@ body { z-index: 2; transition: bottom 0.5s; cursor: auto; + outline: none; } .popwindow .title { @@ -1432,7 +1433,7 @@ body { box-sizing: border-box; height: 20px; background-color: var(--timeline-cue-background-color); - border-radius: 2px; + border-radius: 3px; font-size: 12px; color: var(--timeline-cue-text-color); padding: 0px 2px; diff --git a/built/web/player/modules/Localize.mjs b/built/web/player/modules/Localize.mjs index 269a716f..adb9ef45 100644 --- a/built/web/player/modules/Localize.mjs +++ b/built/web/player/modules/Localize.mjs @@ -140,7 +140,7 @@ const TranslationMap = { "player_savevideo_fail": "Failed to save video!", "player_savevideo_failed_ask_archive": "Failed to save video!\nWould you like to archive the player's buffer storage instead?\n- Drag and drop archive files on the player to load it", "player_savevideo_complete": "Save complete!", - "player_archiver_progress": "Archiving $1", + "player_archiver_progress": "Archiving $1%", "player_archiver_saved": "Archive saved!", "player_quality_current": "(current)", "player_buffer_incognito_warning": "Not enough space to predownload in incognito mode, will buffer $1s", diff --git a/built/web/player/players/.DS_Store b/built/web/player/players/.DS_Store index 8d19195a..0ddc2b7c 100644 Binary files a/built/web/player/players/.DS_Store and b/built/web/player/players/.DS_Store differ diff --git a/built/web/player/players/dash/DashPlayer.mjs b/built/web/player/players/dash/DashPlayer.mjs index 65961e74..b51d5cce 100644 --- a/built/web/player/players/dash/DashPlayer.mjs +++ b/built/web/player/players/dash/DashPlayer.mjs @@ -30,6 +30,7 @@ export default class DashPlayer extends EventEmitter { bufferToKeep: 10, bufferTimeAtTopQuality: 10, bufferTimeAtTopQualityLongForm: 10, + bufferPruningInterval: 1, }, }, }); diff --git a/built/web/player/ui/.DS_Store b/built/web/player/ui/.DS_Store index ee99052b..8e684ed3 100644 Binary files a/built/web/player/ui/.DS_Store and b/built/web/player/ui/.DS_Store differ diff --git a/built/web/player/ui/InterfaceController.mjs b/built/web/player/ui/InterfaceController.mjs index 365dba07..804b2798 100644 --- a/built/web/player/ui/InterfaceController.mjs +++ b/built/web/player/ui/InterfaceController.mjs @@ -118,6 +118,7 @@ export class InterfaceController { this.progressCacheAudio = []; this.hasShownSkip = false; this.failed = false; + this.setStatusMessage('error', null, 'error'); this.reuseDownloadURL = false; if (this.downloadURL) { URL.revokeObjectURL(this.downloadURL); @@ -841,10 +842,15 @@ export class InterfaceController { async dumpBuffer(name) { const entries = this.client.downloadManager.getCompletedEntries(); const filestream = streamSaver.createWriteStream(name + '.fsa'); - await FastStreamArchiveUtils.writeFSAToStream(filestream, this.client.player, entries, (progress)=>{ - this.setStatusMessage('save-video', Localize.getMessage('player_archiver_progress', [Math.floor(progress * 100)]), 'info'); - }); - this.setStatusMessage('save-video', Localize.getMessage('player_archiver_saved'), 'info', 2000); + try { + await FastStreamArchiveUtils.writeFSAToStream(filestream, this.client.player, entries, (progress)=>{ + this.setStatusMessage('save-video', Localize.getMessage('player_archiver_progress', [Math.floor(progress * 100)]), 'info'); + }); + this.setStatusMessage('save-video', Localize.getMessage('player_archiver_saved'), 'info', 2000); + } catch (e) { + console.error(e); + this.setStatusMessage('save-video', 'Unreachable Error', 'error', 2000); + } } updateMarkers() { const pastSeeks = this.client.pastSeeks; @@ -1116,6 +1122,8 @@ export class InterfaceController { }); }); } + let currentSegment = null; + const time = this.client.currentTime; skipSegments.forEach((segment) => { const segmentElement = document.createElement('div'); segmentElement.classList.add('skip_segment'); @@ -1123,15 +1131,16 @@ export class InterfaceController { segmentElement.style.left = segment.startTime / duration * 100 + '%'; segmentElement.style.width = (segment.endTime - segment.startTime) / duration * 100 + '%'; DOMElements.skipSegmentsContainer.appendChild(segmentElement); + if (!currentSegment && time >= segment.startTime && time < segment.endTime) { + currentSegment = segment; + segmentElement.classList.add('active'); + } }); this.skipSegments = skipSegments; - const time = this.client.currentTime; - const currentSegment = skipSegments.find((segment) => time >= segment.startTime && time < segment.endTime); if (currentSegment) { DOMElements.skipButton.style.display = ''; DOMElements.skipButton.textContent = currentSegment.skipText; DOMElements.progressContainer.classList.add('skip_freeze'); - currentSegment.classList.add('active'); } else { DOMElements.progressContainer.classList.remove('skip_freeze'); DOMElements.skipButton.style.display = 'none'; diff --git a/built/web/player/ui/OptionsWindow.mjs b/built/web/player/ui/OptionsWindow.mjs index 36f0400f..aa8cab86 100644 --- a/built/web/player/ui/OptionsWindow.mjs +++ b/built/web/player/ui/OptionsWindow.mjs @@ -13,8 +13,8 @@ export class OptionsWindow { if (e.key === 'Escape') { this.closeUI(); e.preventDefault(); + e.stopPropagation(); } - e.stopPropagation(); }); DOMElements.optionsContainer.addEventListener('keyup', (e) => { e.stopPropagation(); diff --git a/built/web/player/ui/SourcesBrowser.mjs b/built/web/player/ui/SourcesBrowser.mjs index 77409723..5b6c4e38 100644 --- a/built/web/player/ui/SourcesBrowser.mjs +++ b/built/web/player/ui/SourcesBrowser.mjs @@ -64,6 +64,9 @@ export class SourcesBrowser { } } }); + sourceURL.addEventListener('keydown', (e) => { + e.stopPropagation(); + }); const sourceHeadersBtn = WebUtils.create('div', null, 'linkui-source-headers-button'); sourceHeadersBtn.textContent = Localize.getMessage('player_source_headerbtn', [Object.keys(source.headers).length]); sourceHeadersBtn.title = Localize.getMessage('player_source_headerbtn_label'); @@ -123,6 +126,9 @@ export class SourcesBrowser { sourceHeadersBtn.textContent = Localize.getMessage('player_source_headerbtn', [Object.keys(source.headers).length]); this.updateSources(); }); + headersInput.addEventListener('keydown', (e) => { + e.stopPropagation(); + }); headersInput.style.display = 'none'; sourceContainer.appendChild(headersInput); source.sourceBrowserElements = { @@ -183,8 +189,8 @@ export class SourcesBrowser { if (e.key === 'Escape') { this.closeUI(); e.preventDefault(); + e.stopPropagation(); } - e.stopPropagation(); }); DOMElements.linkuiContainer.addEventListener('keyup', (e) => { e.stopPropagation(); diff --git a/built/web/player/ui/audio/AudioConfigManager.mjs b/built/web/player/ui/audio/AudioConfigManager.mjs index 82ba65ad..4043a68f 100644 --- a/built/web/player/ui/audio/AudioConfigManager.mjs +++ b/built/web/player/ui/audio/AudioConfigManager.mjs @@ -194,8 +194,8 @@ export class AudioConfigManager extends EventEmitter { if (e.key === 'Escape') { this.closeUI(); e.preventDefault(); + e.stopPropagation(); } - e.stopPropagation(); }); DOMElements.audioConfigContainer.addEventListener('keyup', (e) => { e.stopPropagation(); diff --git a/built/web/player/ui/subtitles/OpenSubtitlesSearch.mjs b/built/web/player/ui/subtitles/OpenSubtitlesSearch.mjs index fc2efe63..f21099a3 100644 --- a/built/web/player/ui/subtitles/OpenSubtitlesSearch.mjs +++ b/built/web/player/ui/subtitles/OpenSubtitlesSearch.mjs @@ -42,8 +42,8 @@ export class OpenSubtitlesSearch extends EventEmitter { if (e.key === 'Escape') { this.closeUI(); e.preventDefault(); + e.stopPropagation(); } - e.stopPropagation(); }); DOMElements.subuiContainer.addEventListener('keyup', (e) => { e.stopPropagation(); @@ -62,6 +62,9 @@ export class OpenSubtitlesSearch extends EventEmitter { const searchInput = WebUtils.create('input', null, 'text_input'); searchInput.placeholder = Localize.getMessage('player_opensubtitles_search_placeholder'); searchInput.classList.add('subtitle-search-input'); + searchInput.addEventListener('keydown', (e) => { + e.stopPropagation(); + }); this.subui.searchContainer.appendChild(searchInput); this.subui.search = searchInput; const searchBtn = WebUtils.create('div', null, 'textbutton subtitle-search-btn'); @@ -72,10 +75,16 @@ export class OpenSubtitlesSearch extends EventEmitter { seasonInput.placeholder = Localize.getMessage('player_opensubtitles_seasonnum'); seasonInput.classList.add('subtitle-season-input'); seasonInput.style.display = 'none'; + seasonInput.addEventListener('keydown', (e) => { + e.stopPropagation(); + }); const episodeInput = WebUtils.create('input', null, 'text_input'); episodeInput.placeholder = Localize.getMessage('player_opensubtitles_episodenum'); episodeInput.classList.add('subtitle-episode-input'); episodeInput.style.display = 'none'; + episodeInput.addEventListener('keydown', (e) => { + e.stopPropagation(); + }); const typeSelector = WebUtils.createDropdown('all', 'Type', { 'all': Localize.getMessage('player_opensubtitles_type_all'), @@ -100,10 +109,16 @@ export class OpenSubtitlesSearch extends EventEmitter { languageInput.classList.add('subtitle-language-input'); this.subui.searchContainer.appendChild(languageInput); this.subui.languageInput = languageInput; + languageInput.addEventListener('keydown', (e) => { + e.stopPropagation(); + }); const yearInput = WebUtils.create('input', null, 'text_input'); yearInput.placeholder = Localize.getMessage('player_opensubtitles_year'); yearInput.classList.add('subtitle-year-input'); this.subui.searchContainer.appendChild(yearInput); + yearInput.addEventListener('keydown', (e) => { + e.stopPropagation(); + }); const sortSelector = WebUtils.createDropdown('download_count', Localize.getMessage('player_opensubtitles_sortby'), { 'download_count': Localize.getMessage('player_opensubtitles_sortby_downloads'), diff --git a/built/web/player/ui/subtitles/SubtitleSyncer.mjs b/built/web/player/ui/subtitles/SubtitleSyncer.mjs index 717c3f5d..6fc9edf4 100644 --- a/built/web/player/ui/subtitles/SubtitleSyncer.mjs +++ b/built/web/player/ui/subtitles/SubtitleSyncer.mjs @@ -266,11 +266,15 @@ export class SubtitleSyncer extends EventEmitter { return true; }); this.visibleCues.forEach((cue) => { + if (cue.text.length === 0) return; if (this.trackElements.find((el) => el.cue === cue)) return; const el = WebUtils.create('div', '', 'timeline_track_cue'); el.style.left = cue.startTime / this.video.duration * 100 + '%'; el.style.width = (cue.endTime - cue.startTime) / this.video.duration * 100 + '%'; - el.appendChild(WebVTT.convertCueToDOMTree(window, cue.text)); + if (!cue.dom2) { + cue.dom2 = WebVTT.convertCueToDOMTree(window, cue.text); + } + el.appendChild(cue.dom2); el.title = cue.text; this.ui.timelineTrack.appendChild(el); this.trackElements.push({ diff --git a/built/web/player/utils/EnvUtils.mjs b/built/web/player/utils/EnvUtils.mjs index 813c8288..b74be267 100644 --- a/built/web/player/utils/EnvUtils.mjs +++ b/built/web/player/utils/EnvUtils.mjs @@ -19,7 +19,7 @@ export class EnvUtils { static getVersion() { // eslint-disable-next-line prefer-const let version = '1.0.0.web'; -version = '1.2.3'; +version = '1.2.4'; return this.isExtension() ? chrome.runtime.getManifest().version : version; } static isIncognito() { diff --git a/built/web/player/utils/WebUtils.mjs b/built/web/player/utils/WebUtils.mjs index 07c82cac..e70c9b5c 100644 --- a/built/web/player/utils/WebUtils.mjs +++ b/built/web/player/utils/WebUtils.mjs @@ -193,15 +193,12 @@ export class WebUtils { if (e.key === 'Enter') { span.blur(); e.stopPropagation(); - e.preventDefault(); } + e.preventDefault(); }); span.addEventListener('click', (e) => { e.stopPropagation(); }); - span.addEventListener('keydown', (e) => { - e.stopPropagation(); - }); } return container; }