ScreenSubtitleReader 0.1.3__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/PKG-INFO +3 -2
- screensubtitlereader-0.2.0/README.md +4 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/pyproject.toml +2 -1
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/core/__main__.py +3 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/core/screen_reader.py +6 -0
- screensubtitlereader-0.2.0/src/ScreenSubtitleReader/hotkey/__init__.py +1 -0
- screensubtitlereader-0.2.0/src/ScreenSubtitleReader/hotkey/hotkey.py +18 -0
- screensubtitlereader-0.2.0/src/ScreenSubtitleReader/setting/__init__.py +1 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/setting/setting.py +108 -97
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/speaker/speaker.py +1 -1
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader.egg-info/PKG-INFO +3 -2
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader.egg-info/SOURCES.txt +3 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader.egg-info/requires.txt +1 -0
- screensubtitlereader-0.1.3/README.md +0 -4
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/setup.cfg +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/__init__.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/__main__.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/core/__init__.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/core/ocr_fither.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/core/string_fither.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/__init__.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/angnet/__init__.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/angnet/angle.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/config.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/crnn/CRNN.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/crnn/__init__.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/crnn/keys.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/crnn/util.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/dbnet/dbnet_infer.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/dbnet/decode.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/model.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/models/__init__.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/models/angle_net.onnx +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/models/crnn_lite_lstm.onnx +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/models/dbnet.onnx +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ocr_module/utils.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/ui/ui.py +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader.egg-info/dependency_links.txt +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader.egg-info/entry_points.txt +0 -0
- {screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader.egg-info/top_level.txt +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ScreenSubtitleReader
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: 自动识别屏幕上正在放映视频的字幕并读出来
|
|
5
5
|
Requires-Python: >=3.12
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: keyboard>=0.13.5
|
|
7
8
|
Requires-Dist: numpy>=2.4.4
|
|
8
9
|
Requires-Dist: onnxruntime>=1.26.0
|
|
9
10
|
Requires-Dist: opencv-python>=4.13.0.92
|
|
@@ -17,5 +18,5 @@ Requires-Dist: tornado>=6.5.5
|
|
|
17
18
|
|
|
18
19
|
## 一个自动阅读字幕的小工具
|
|
19
20
|
|
|
20
|
-
先安装:`
|
|
21
|
+
先安装:`pip install ScreenSubtitleReader`
|
|
21
22
|
之后用`scsrt`启动
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "ScreenSubtitleReader"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "自动识别屏幕上正在放映视频的字幕并读出来"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
7
7
|
dependencies = [
|
|
8
|
+
"keyboard>=0.13.5",
|
|
8
9
|
"numpy>=2.4.4",
|
|
9
10
|
"onnxruntime>=1.26.0",
|
|
10
11
|
"opencv-python>=4.13.0.92",
|
|
@@ -2,11 +2,14 @@ from .ocr_fither import OCR
|
|
|
2
2
|
from ..speaker.speaker import Speaker
|
|
3
3
|
from PIL import ImageGrab
|
|
4
4
|
from .string_fither import is_similar_str
|
|
5
|
+
from ..setting import AppConfig
|
|
6
|
+
import time
|
|
5
7
|
|
|
6
8
|
class ScreenReader:
|
|
7
9
|
def __init__(self) -> None:
|
|
8
10
|
self.ocr = OCR()
|
|
9
11
|
self.speaker = Speaker()
|
|
12
|
+
self.config_manager = AppConfig()
|
|
10
13
|
self.last_time_readed_text = ''
|
|
11
14
|
|
|
12
15
|
def capture_and_read_once(self):
|
|
@@ -23,6 +26,9 @@ class ScreenReader:
|
|
|
23
26
|
|
|
24
27
|
def main_loop(self):
|
|
25
28
|
while True:
|
|
29
|
+
if self.config_manager.paused:
|
|
30
|
+
time.sleep(0.2)
|
|
31
|
+
continue
|
|
26
32
|
self.capture_and_read_once()
|
|
27
33
|
|
|
28
34
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .hotkey import HotkeyManager
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import keyboard
|
|
2
|
+
from ..setting.setting import AppConfig
|
|
3
|
+
from ..speaker.speaker import Speaker
|
|
4
|
+
|
|
5
|
+
class HotkeyManager:
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self._config = AppConfig()
|
|
8
|
+
self._speaker = Speaker()
|
|
9
|
+
|
|
10
|
+
def start(self):
|
|
11
|
+
keyboard.add_hotkey("f1", self._toggle_pause)
|
|
12
|
+
|
|
13
|
+
def _toggle_pause(self):
|
|
14
|
+
self._config.paused = not self._config.paused
|
|
15
|
+
if self._config.paused:
|
|
16
|
+
self._speaker.add_sentence("已暂停")
|
|
17
|
+
if not self._config.paused:
|
|
18
|
+
self._speaker.add_sentence("继续朗读")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .setting import AppConfig
|
|
@@ -1,98 +1,109 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import threading
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
# 如果尚未安装,可以运行: pip install platformdirs
|
|
5
|
-
from platformdirs import user_data_dir
|
|
6
|
-
|
|
7
|
-
class AppConfig:
|
|
8
|
-
_instance = None
|
|
9
|
-
_lock = threading.Lock() # 确保线程安全的单例模式
|
|
10
|
-
|
|
11
|
-
def __new__(cls, *args, **kwargs):
|
|
12
|
-
"""单例模式:确保全局只有一个配置实例"""
|
|
13
|
-
if not cls._instance:
|
|
14
|
-
with cls._lock:
|
|
15
|
-
if not cls._instance:
|
|
16
|
-
cls._instance = super().__new__(cls)
|
|
17
|
-
# 标记是否已经初始化,防止 __init__ 重复调用
|
|
18
|
-
cls._instance._initialized = False
|
|
19
|
-
return cls._instance
|
|
20
|
-
|
|
21
|
-
def __init__(self, app_name="ScreenSubtitleReader"):
|
|
22
|
-
if self._initialized:
|
|
23
|
-
return
|
|
24
|
-
|
|
25
|
-
# 1. 确定跨平台的 AppData 存储路径
|
|
26
|
-
# 在 Windows 上通常是: C:\Users\用户名\AppData\Local\MyTkinterApp
|
|
27
|
-
self.config_dir = Path(user_data_dir(app_name))
|
|
28
|
-
self.config_file = self.config_dir / "config.json"
|
|
29
|
-
|
|
30
|
-
# 2. 默认属性
|
|
31
|
-
self._volume = 100
|
|
32
|
-
self._speed = 270
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
self.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
self.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
self.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
self.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
1
|
+
import json
|
|
2
|
+
import threading
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
# 如果尚未安装,可以运行: pip install platformdirs
|
|
5
|
+
from platformdirs import user_data_dir
|
|
6
|
+
|
|
7
|
+
class AppConfig:
|
|
8
|
+
_instance = None
|
|
9
|
+
_lock = threading.Lock() # 确保线程安全的单例模式
|
|
10
|
+
|
|
11
|
+
def __new__(cls, *args, **kwargs):
|
|
12
|
+
"""单例模式:确保全局只有一个配置实例"""
|
|
13
|
+
if not cls._instance:
|
|
14
|
+
with cls._lock:
|
|
15
|
+
if not cls._instance:
|
|
16
|
+
cls._instance = super().__new__(cls)
|
|
17
|
+
# 标记是否已经初始化,防止 __init__ 重复调用
|
|
18
|
+
cls._instance._initialized = False
|
|
19
|
+
return cls._instance
|
|
20
|
+
|
|
21
|
+
def __init__(self, app_name="ScreenSubtitleReader"):
|
|
22
|
+
if self._initialized:
|
|
23
|
+
return
|
|
24
|
+
|
|
25
|
+
# 1. 确定跨平台的 AppData 存储路径
|
|
26
|
+
# 在 Windows 上通常是: C:\Users\用户名\AppData\Local\MyTkinterApp
|
|
27
|
+
self.config_dir = Path(user_data_dir(app_name))
|
|
28
|
+
self.config_file = self.config_dir / "config.json"
|
|
29
|
+
|
|
30
|
+
# 2. 默认属性
|
|
31
|
+
self._volume = 100
|
|
32
|
+
self._speed = 270
|
|
33
|
+
self._paused = False
|
|
34
|
+
|
|
35
|
+
# 3. 启动初始化:自动读取或创建文件
|
|
36
|
+
self._load_or_create_config()
|
|
37
|
+
self._initialized = True
|
|
38
|
+
|
|
39
|
+
def _load_or_create_config(self):
|
|
40
|
+
"""读取配置文件,如果不存在则创建默认配置"""
|
|
41
|
+
try:
|
|
42
|
+
if self.config_file.exists():
|
|
43
|
+
# 文件存在,读取数据
|
|
44
|
+
with open(self.config_file, "r", encoding="utf-8") as f:
|
|
45
|
+
data = json.load(f)
|
|
46
|
+
# 使用 get 提供降级容错,防止 JSON 被人为改坏导致崩溃
|
|
47
|
+
self._volume = int(data.get("volume", 100))
|
|
48
|
+
self._speed = int(data.get("speed", 270))
|
|
49
|
+
print(f"成功加载配置: {self.config_file}")
|
|
50
|
+
else:
|
|
51
|
+
# 文件不存在,保存当前的默认值
|
|
52
|
+
self.save()
|
|
53
|
+
print(f"创建默认配置文件: {self.config_file}")
|
|
54
|
+
except Exception as e:
|
|
55
|
+
print(f"配置加载或初始化失败,使用默认值。错误: {e}")
|
|
56
|
+
|
|
57
|
+
def save(self):
|
|
58
|
+
"""将当前属性序列化并自动存盘"""
|
|
59
|
+
try:
|
|
60
|
+
# 确保应用数据文件夹存在(不存在则自动递归创建)
|
|
61
|
+
self.config_dir.mkdir(parents=True, exist_ok=True)
|
|
62
|
+
|
|
63
|
+
data = {
|
|
64
|
+
"volume": self._volume,
|
|
65
|
+
"speed": self._speed,
|
|
66
|
+
}
|
|
67
|
+
# 写入文件
|
|
68
|
+
with open(self.config_file, "w", encoding="utf-8") as f:
|
|
69
|
+
json.dump(data, f, indent=4, ensure_ascii=False)
|
|
70
|
+
print("配置已自动保存到磁盘。")
|
|
71
|
+
except Exception as e:
|
|
72
|
+
print(f"配置保存失败: {e}")
|
|
73
|
+
|
|
74
|
+
# --- 使用 Property 属性装饰器,既能像属性一样访问,又能触发自动存盘 ---
|
|
75
|
+
@property
|
|
76
|
+
def volume(self) -> int:
|
|
77
|
+
return self._volume
|
|
78
|
+
|
|
79
|
+
@volume.setter
|
|
80
|
+
def volume(self, value: int):
|
|
81
|
+
if not isinstance(value, int):
|
|
82
|
+
raise TypeError("音量必须是整型 (int)")
|
|
83
|
+
self._volume = value
|
|
84
|
+
self.save() # 更改时自动存盘
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def speed(self) -> int:
|
|
88
|
+
return self._speed
|
|
89
|
+
|
|
90
|
+
@speed.setter
|
|
91
|
+
def speed(self, value: int):
|
|
92
|
+
if not isinstance(value, int):
|
|
93
|
+
raise TypeError("语速必须是整型 (int)")
|
|
94
|
+
self._speed = value
|
|
95
|
+
self.save() # 更改时自动存盘
|
|
96
|
+
@property
|
|
97
|
+
def paused(self) -> bool:
|
|
98
|
+
return self._paused
|
|
99
|
+
|
|
100
|
+
@paused.setter
|
|
101
|
+
def paused(self, value: bool):
|
|
102
|
+
if not isinstance(value, bool):
|
|
103
|
+
raise TypeError("语速必须是bool")
|
|
104
|
+
self._paused = value
|
|
105
|
+
self.save() # 更改时自动存盘
|
|
106
|
+
|
|
107
|
+
if __name__ == "__main__":
|
|
108
|
+
apc = AppConfig()
|
|
98
109
|
print(apc.speed)
|
{screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader.egg-info/PKG-INFO
RENAMED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ScreenSubtitleReader
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: 自动识别屏幕上正在放映视频的字幕并读出来
|
|
5
5
|
Requires-Python: >=3.12
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: keyboard>=0.13.5
|
|
7
8
|
Requires-Dist: numpy>=2.4.4
|
|
8
9
|
Requires-Dist: onnxruntime>=1.26.0
|
|
9
10
|
Requires-Dist: opencv-python>=4.13.0.92
|
|
@@ -17,5 +18,5 @@ Requires-Dist: tornado>=6.5.5
|
|
|
17
18
|
|
|
18
19
|
## 一个自动阅读字幕的小工具
|
|
19
20
|
|
|
20
|
-
先安装:`
|
|
21
|
+
先安装:`pip install ScreenSubtitleReader`
|
|
21
22
|
之后用`scsrt`启动
|
|
@@ -13,6 +13,8 @@ src/ScreenSubtitleReader/core/__main__.py
|
|
|
13
13
|
src/ScreenSubtitleReader/core/ocr_fither.py
|
|
14
14
|
src/ScreenSubtitleReader/core/screen_reader.py
|
|
15
15
|
src/ScreenSubtitleReader/core/string_fither.py
|
|
16
|
+
src/ScreenSubtitleReader/hotkey/__init__.py
|
|
17
|
+
src/ScreenSubtitleReader/hotkey/hotkey.py
|
|
16
18
|
src/ScreenSubtitleReader/ocr_module/__init__.py
|
|
17
19
|
src/ScreenSubtitleReader/ocr_module/config.py
|
|
18
20
|
src/ScreenSubtitleReader/ocr_module/model.py
|
|
@@ -29,6 +31,7 @@ src/ScreenSubtitleReader/ocr_module/models/__init__.py
|
|
|
29
31
|
src/ScreenSubtitleReader/ocr_module/models/angle_net.onnx
|
|
30
32
|
src/ScreenSubtitleReader/ocr_module/models/crnn_lite_lstm.onnx
|
|
31
33
|
src/ScreenSubtitleReader/ocr_module/models/dbnet.onnx
|
|
34
|
+
src/ScreenSubtitleReader/setting/__init__.py
|
|
32
35
|
src/ScreenSubtitleReader/setting/setting.py
|
|
33
36
|
src/ScreenSubtitleReader/speaker/speaker.py
|
|
34
37
|
src/ScreenSubtitleReader/ui/ui.py
|
|
File without changes
|
{screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/__init__.py
RENAMED
|
File without changes
|
{screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/__main__.py
RENAMED
|
File without changes
|
{screensubtitlereader-0.1.3 → screensubtitlereader-0.2.0}/src/ScreenSubtitleReader/core/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|