浏览代码

切换显示不切断tts

sequoia00 1 月之前
父节点
当前提交
42608d9683
共有 3 个文件被更改,包括 67 次插入5 次删除
  1. 4 0
      config.py
  2. 13 4
      main_server.py
  3. 50 1
      static/web/viewer.html

+ 4 - 0
config.py

@@ -6,3 +6,7 @@ MYSQL_PORT = int(os.getenv("READER_PRO_DB_PORT", "3306"))
 MYSQL_USER = os.getenv("READER_PRO_DB_USER", "root")
 MYSQL_PASSWORD = os.getenv("READER_PRO_DB_PASSWORD", "792199Zhao*")
 MYSQL_DATABASE = os.getenv("READER_PRO_DB_NAME", "reader_pro")
+
+# TTS upstream service configuration
+TTS_API_BASE_URL = os.getenv("READER_PRO_TTS_API_BASE_URL", "http://141.140.15.30:8028")
+TTS_GENERATE_ENDPOINT = os.getenv("READER_PRO_TTS_GENERATE_ENDPOINT", "/generate")

+ 13 - 4
main_server.py

@@ -19,7 +19,15 @@ from datetime import datetime, timedelta, timezone
 import secrets
 import pymysql
 
-from config import MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE
+from config import (
+    MYSQL_HOST,
+    MYSQL_PORT,
+    MYSQL_USER,
+    MYSQL_PASSWORD,
+    MYSQL_DATABASE,
+    TTS_API_BASE_URL,
+    TTS_GENERATE_ENDPOINT,
+)
 
 # Set up logging
 logging.basicConfig(level=logging.INFO)
@@ -54,6 +62,7 @@ os.makedirs(CACHE_DIR, exist_ok=True)
 SESSION_COOKIE = "reader_pro_session"
 SESSION_TTL_DAYS = 1
 SESSION_TTL_DAYS_REMEMBER = 30
+TTS_GENERATE_URL = f"{TTS_API_BASE_URL.rstrip('/')}/{TTS_GENERATE_ENDPOINT.lstrip('/')}"
 
 
 def db_conn():
@@ -788,7 +797,7 @@ async def generate_proxy(request: TextToSpeechRequest):
         try:
             async with aiohttp.ClientSession() as session:
                 async with session.post(
-                    "http://141.140.15.30:8028/generate",
+                    TTS_GENERATE_URL,
                     headers={"Content-Type": "application/json"},
                     json={"text": user_input, "voice": request.voice, "speed": request.speed},
                 ) as response:
@@ -821,7 +830,7 @@ async def text_to_speech(request: TextToSpeechRequest):
         try:
             async with aiohttp.ClientSession() as session:
                 async with session.post(
-                    "http://141.140.15.30:8028/generate",
+                    TTS_GENERATE_URL,
                     headers={"Content-Type": "application/json"},
                     json={"text": user_input, "voice": request.voice, "speed": request.speed},
                 ) as response:
@@ -909,7 +918,7 @@ async def generate_api_audio(chunk: str, voice: str, speed: float) -> AsyncGener
         try:
             async with aiohttp.ClientSession() as session:
                 async with session.post(
-                    "http://141.140.15.30:8028/generate",
+                    TTS_GENERATE_URL,
                     headers={"Content-Type": "application/json"},
                     json={"text": chunk, "voice": voice, "speed": speed},
                 ) as response:

+ 50 - 1
static/web/viewer.html

@@ -1657,6 +1657,7 @@
                     updateNightModeButton(enabled);
                     localStorage.setItem(NIGHT_MODE_STORAGE_KEY, enabled ? '1' : '0');
                     syncPdfJsNightPreferences(enabled);
+                    applyPdfNightMode(enabled);
                 }
 
                 function syncPdfJsNightPreferences(enabled) {
@@ -1680,6 +1681,55 @@
                     setNightMode(enabled);
                 }
 
+                function applyPdfNightMode(enabled) {
+                    const app = window.PDFViewerApplication;
+                    const options = window.PDFViewerApplicationOptions;
+                    const pdfViewer = app?.pdfViewer;
+                    const pdfThumbnailViewer = app?.pdfThumbnailViewer;
+                    const renderingQueue = app?.pdfRenderingQueue;
+
+                    if (!options || !pdfViewer?.pdfDocument) {
+                        return;
+                    }
+
+                    const pageColors = enabled
+                        ? { background: '#0b0b0b', foreground: '#f5f5f5' }
+                        : null;
+
+                    options.set('forcePageColors', enabled);
+                    options.set('pageColorsBackground', '#0b0b0b');
+                    options.set('pageColorsForeground', '#f5f5f5');
+
+                    pdfViewer.pageColors = pageColors;
+                    if (pdfViewer.viewer) {
+                        if (pageColors?.background) {
+                            pdfViewer.viewer.style.setProperty('--page-bg-color', pageColors.background);
+                        } else {
+                            pdfViewer.viewer.style.removeProperty('--page-bg-color');
+                        }
+                    }
+
+                    for (let i = 0; i < pdfViewer.pagesCount; i++) {
+                        const pageView = pdfViewer.getPageView(i);
+                        if (!pageView) continue;
+                        pageView.pageColors = pageColors;
+                        pageView.reset();
+                    }
+
+                    if (pdfThumbnailViewer) {
+                        pdfThumbnailViewer.pageColors = pageColors;
+                        for (let i = 0; i < pdfViewer.pagesCount; i++) {
+                            const thumbnail = pdfThumbnailViewer.getThumbnail(i);
+                            if (!thumbnail) continue;
+                            thumbnail.pageColors = pageColors;
+                            thumbnail.reset();
+                        }
+                    }
+
+                    pdfViewer.update();
+                    renderingQueue?.renderHighestPriority();
+                }
+
                 function getFullscreenElement() {
                     return document.fullscreenElement ||
                         document.webkitFullscreenElement ||
@@ -1777,7 +1827,6 @@
                 nightModeButton.addEventListener('click', function () {
                     const nextEnabled = !document.body.classList.contains('night-reading-mode');
                     setNightMode(nextEnabled);
-                    window.location.reload();
                 });
                 browserFullscreenButton.addEventListener('click', () => {
                     toggleBrowserFullscreen();