easyrip 4.11.3__py3-none-any.whl → 4.13.0__py3-none-any.whl

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.
@@ -0,0 +1,145 @@
1
+ import enum
2
+ from dataclasses import dataclass
3
+ from typing import final
4
+
5
+
6
+ @final
7
+ @dataclass(slots=True, init=False, eq=False)
8
+ class Lang_tag_val:
9
+ en_name: str
10
+ _local_name: str | None
11
+
12
+ @property
13
+ def local_name(self) -> str:
14
+ return self.en_name if self._local_name is None else self._local_name
15
+
16
+ @local_name.setter
17
+ def local_name(self, val: str | None) -> None:
18
+ if val is not None and len(val) == 0:
19
+ raise ValueError("The length of the name cannot be 0")
20
+
21
+ self._local_name = val
22
+
23
+ def __init__(self, *, en_name: str, local_name: str | None = None) -> None:
24
+ if len(en_name) == 0:
25
+ raise ValueError("The length of the name cannot be 0")
26
+
27
+ self.en_name = en_name
28
+ self.local_name = local_name
29
+
30
+ def __str__(self) -> str:
31
+ return f"{self.__class__.__name__}(en_name={self.en_name}, local_name={self._local_name})"
32
+
33
+ def __eq__(self, other: object) -> bool:
34
+ if isinstance(other, Lang_tag_val):
35
+ return self.en_name == other.en_name
36
+ return False
37
+
38
+ def __hash__(self) -> int:
39
+ return hash(self.en_name)
40
+
41
+
42
+ class Lang_tag_language(enum.Enum):
43
+ Unknown = Lang_tag_val(en_name="Unknown")
44
+
45
+ # ISO 639-1
46
+ en = Lang_tag_val(en_name="English", local_name="English")
47
+ zh = Lang_tag_val(en_name="Chinese", local_name="中文")
48
+ fr = Lang_tag_val(en_name="French", local_name="Français")
49
+ de = Lang_tag_val(en_name="German", local_name="Deutsch")
50
+ es = Lang_tag_val(en_name="Spanish", local_name="Español")
51
+ it = Lang_tag_val(en_name="Italian", local_name="Italiano")
52
+ ja = Lang_tag_val(en_name="Japanese", local_name="日本語")
53
+ ko = Lang_tag_val(en_name="Korean", local_name="한국어")
54
+ ru = Lang_tag_val(en_name="Russian", local_name="Русский")
55
+ ar = Lang_tag_val(en_name="Arabic", local_name="العربية")
56
+
57
+ # ISO 639-2
58
+ eng = en
59
+ zho = chi = zh
60
+ fra = fre = fr
61
+ deu = ger = de
62
+ spa = es
63
+ ita = it
64
+ jpn = ja
65
+ kor = ko
66
+ rus = ru
67
+ ara = ar
68
+
69
+ # ISO 639-3
70
+ # 与 p2 重叠的放在 p2
71
+ cdo = Lang_tag_val(en_name="Min Dong Chinese", local_name="闽东语")
72
+ cjy = Lang_tag_val(en_name="Jinyu Chinese", local_name="晋语")
73
+ cmn = Lang_tag_val(en_name="Mandarin Chinese", local_name="普通话")
74
+ cnp = Lang_tag_val(en_name="Northern Ping Chinese", local_name="北平语")
75
+ wuu = Lang_tag_val(en_name="Wu Chinese", local_name="吴语")
76
+ yue = Lang_tag_val(en_name="Yue Chinese", local_name="粤语")
77
+ hak = Lang_tag_val(en_name="Hakka Chinese", local_name="客家话")
78
+ nan = Lang_tag_val(en_name="Min Nan Chinese", local_name="闽南语")
79
+ och = Lang_tag_val(en_name="Old Chinese", local_name="古汉语")
80
+
81
+ @classmethod
82
+ def _missing_(cls, value: object):
83
+ return cls.Unknown
84
+
85
+ @classmethod
86
+ def from_name(cls, name: str):
87
+ try:
88
+ return cls[name]
89
+ except KeyError:
90
+ return cls.Unknown
91
+
92
+
93
+ class Lang_tag_script(enum.Enum):
94
+ Unknown = Lang_tag_val(en_name="Unknown")
95
+
96
+ Hans = Lang_tag_val(en_name="Simplified Chinese", local_name="简体")
97
+ Hant = Lang_tag_val(en_name="Traditional Chinese", local_name="繁體")
98
+ Latn = Lang_tag_val(en_name="Latin", local_name="Latina")
99
+ Cyrl = Lang_tag_val(en_name="Cyrillic", local_name="Кириллица")
100
+ Arab = Lang_tag_val(en_name="Arabic", local_name="العربية")
101
+
102
+ @classmethod
103
+ def _missing_(cls, value: object):
104
+ return cls.Unknown
105
+
106
+ @classmethod
107
+ def from_name(cls, name: str):
108
+ try:
109
+ return cls[name]
110
+ except KeyError:
111
+ return cls.Unknown
112
+
113
+
114
+ class Lang_tag_region(enum.Enum):
115
+ Unknown = Lang_tag_val(en_name="Unknown")
116
+
117
+ US = Lang_tag_val(en_name="United States", local_name="United States")
118
+ GB = Lang_tag_val(en_name="United Kingdom", local_name="United Kingdom")
119
+ AU = Lang_tag_val(en_name="Australia", local_name="Australia")
120
+ CA = Lang_tag_val(en_name="Canada", local_name="Canada")
121
+ NZ = Lang_tag_val(en_name="New Zealand", local_name="New Zealand")
122
+ IE = Lang_tag_val(en_name="Ireland", local_name="Éire")
123
+ ZA = Lang_tag_val(en_name="South Africa", local_name="South Africa")
124
+ JM = Lang_tag_val(en_name="Jamaica", local_name="Jamaica")
125
+ TT = Lang_tag_val(en_name="Caribbean", local_name="Caribbean")
126
+ BZ = Lang_tag_val(en_name="Belize", local_name="Belize")
127
+ PH = Lang_tag_val(en_name="Philippines", local_name="Pilipinas")
128
+ IN = Lang_tag_val(en_name="India", local_name="भारत")
129
+ MY = Lang_tag_val(en_name="Malaysia", local_name="Malaysia")
130
+ SG = Lang_tag_val(en_name="Singapore", local_name="Singapura")
131
+ MO = Lang_tag_val(en_name="Macau SAR", local_name="澳門")
132
+ HK = Lang_tag_val(en_name="Hong Kong SAR", local_name="香港")
133
+ TW = Lang_tag_val(en_name="Taiwan", local_name="台灣")
134
+ CN = Lang_tag_val(en_name="China", local_name="中国大陆")
135
+
136
+ @classmethod
137
+ def _missing_(cls, value: object):
138
+ return cls.Unknown
139
+
140
+ @classmethod
141
+ def from_name(cls, name: str):
142
+ try:
143
+ return cls[name]
144
+ except KeyError:
145
+ return cls.Unknown
@@ -1,15 +1,10 @@
1
1
  from ..easyrip_command import Audio_codec, Cmd_type, Opt_type, Preset_name
2
- from .global_lang_val import (
3
- Lang_tag,
4
- Lang_tag_language,
5
- Lang_tag_region,
6
- Lang_tag_script,
7
- )
2
+ from .global_lang_val import Lang_tag
8
3
 
9
4
  LANG_TAG = Lang_tag(
10
- language=Lang_tag_language.zh,
11
- script=Lang_tag_script.Hans,
12
- region=Lang_tag_region.CN,
5
+ language=Lang_tag.Language.zh,
6
+ script=Lang_tag.Script.Hans,
7
+ region=Lang_tag.Region.CN,
13
8
  )
14
9
 
15
10
  LANG_MAP: dict[str, str] = {
@@ -135,7 +130,8 @@ LANG_MAP: dict[str, str] = {
135
130
  ),
136
131
  Opt_type._preset.value.description: (
137
132
  "设置预设\n"
138
- "预设名:\n" # .
133
+ "\n" # .
134
+ "预设名:\n"
139
135
  f"{Preset_name.to_help_string(' ')}"
140
136
  ),
141
137
  Opt_type._pipe.value.description: (
@@ -178,7 +174,7 @@ LANG_MAP: dict[str, str] = {
178
174
  'e.g. "11\\{22}33" ->\n'
179
175
  ' "11\\33" (VSFilter)\n'
180
176
  ' "11{22}33" (libass)\n'
181
- "默认: 0"
177
+ "默认: 1"
182
178
  ),
183
179
  Opt_type._subset_drop_non_render.value.description: (
184
180
  "丢弃 ASS 中的注释行、Name、Effect等非渲染内容\n" # .
@@ -199,13 +195,14 @@ LANG_MAP: dict[str, str] = {
199
195
  ),
200
196
  Opt_type._c_a.value.description: (
201
197
  "设置音频编码器\n"
202
- "音频编码器:\n" # .
198
+ "\n" # .
199
+ "音频编码器:\n"
203
200
  f"{Audio_codec.to_help_string(' ')}"
204
201
  ),
205
202
  Opt_type._b_a.value.description: "设置音频码率。默认值 '160k'",
206
203
  Opt_type._muxer.value.description: (
207
204
  "设置复用器\n"
208
- " \n" # .
205
+ "\n" # .
209
206
  "可用的复用器:\n"
210
207
  " mp4\n"
211
208
  " mkv"
@@ -280,7 +277,8 @@ LANG_MAP: dict[str, str] = {
280
277
  "Check env...": "检测环境中...",
281
278
  # "The MediaInfo must be CLI ver": "MediaInfo 必须是 CLI 版本",
282
279
  "Easy Rip command": "Easy Rip 命令",
283
- "Stop run Ripper": "Ripper 执行终止",
280
+ "Stop run and clear Ripper list": "终止执行并清空 Ripper list",
281
+ "Manually stop run and clear Ripper list": "手动终止执行并清空 Ripper list",
284
282
  "There are {} {} during run": "执行期间有 {} 个 {}",
285
283
  "Execute shutdown in {}s": "{}s 后执行关机",
286
284
  "{} run completed, shutdown in {}s": "{} 执行完成, {}s 后关机",
@@ -303,10 +301,11 @@ LANG_MAP: dict[str, str] = {
303
301
  "There is no audio stream in the video, so '-c:a' cannot be used": "视频中没有音频流,所以无法使用 '-c:a'",
304
302
  "Unsupported '{}' param: {}": "'{}' 不支持此参数: {}",
305
303
  "Manually force exit": "手动强制退出",
304
+ "Command run terminated": "命令执行终止",
305
+ "Manually stop run command": "手动终止执行命令",
306
306
  "Suggest running the following command to upgrade using pip: {}": "建议运行以下命令以使用 pip 更新: {}",
307
307
  "Wrong sec in -shutdown, change to default 60s": "-shutdown 设定的秒数错误, 改为默认值 60s",
308
308
  "Current work directory has an other Easy Rip is running: {}": "当前工作目录存在其他 Easy Rip 正在运行: {}",
309
- "Stop run command": "命令执行终止",
310
309
  # log
311
310
  "EasyRip_log.html": "EasyRip日志.html",
312
311
  "Start": "开始",
@@ -323,6 +322,9 @@ LANG_MAP: dict[str, str] = {
323
322
  "Failed to add Ripper: {}": "添加 Ripper 失败: {}",
324
323
  "'{}' is not a valid '{}', set to default value '{}'. Valid options are: {}": "'{}' 不存在于 '{}', 已设为默认值 '{}'。有以下值可用: {}",
325
324
  "The preset custom must have custom:format or custom:template": "custom 预设必须要有 custom:format 或 custom:template",
325
+ "Run the following commands in order:\n{}": "按顺序执行以下命令:\n{}",
326
+ "Run the command {}": "执行命令 {}",
327
+ "Command run failed: status code {}\n Failed command: {}": "命令执行失败: 状态码 {}\n 失败的命令: {}",
326
328
  "There have error in running": "执行时出错",
327
329
  "{} param illegal": "{} 参数非法",
328
330
  'The file "{}" already exists, skip translating it': '文件 "{}" 已存在, 跳过翻译',
@@ -5,12 +5,7 @@ from time import sleep
5
5
  from typing import Final
6
6
 
7
7
  from ..easyrip_web.third_party_api import zhconvert
8
- from .global_lang_val import (
9
- Lang_tag,
10
- Lang_tag_language,
11
- Lang_tag_region,
12
- Lang_tag_script,
13
- )
8
+ from .global_lang_val import Lang_tag
14
9
 
15
10
 
16
11
  def translate_subtitles(
@@ -64,52 +59,52 @@ def translate_subtitles(
64
59
  match Lang_tag.from_str(infix):
65
60
  case (
66
61
  Lang_tag(
67
- language=Lang_tag_language.zh,
68
- script=Lang_tag_script.Hans,
62
+ language=Lang_tag.Language.zh,
63
+ script=Lang_tag.Script.Hans,
69
64
  region=_,
70
65
  )
71
66
  | Lang_tag(
72
- language=Lang_tag_language.zh,
67
+ language=Lang_tag.Language.zh,
73
68
  script=_,
74
- region=Lang_tag_region.CN,
69
+ region=Lang_tag.Region.CN,
75
70
  )
76
71
  ):
77
72
  # 简体 -> 繁体 or 非 CN 简体 CN 化
78
73
  match target_lang_tag:
79
74
  case Lang_tag(
80
- language=Lang_tag_language.zh,
75
+ language=Lang_tag.Language.zh,
81
76
  script=_,
82
- region=Lang_tag_region.HK,
77
+ region=Lang_tag.Region.HK,
83
78
  ):
84
79
  zhconvert_target_lang = zhconvert.Target_lang.HK
85
80
 
86
81
  case Lang_tag(
87
- language=Lang_tag_language.zh,
82
+ language=Lang_tag.Language.zh,
88
83
  script=_,
89
- region=Lang_tag_region.TW,
84
+ region=Lang_tag.Region.TW,
90
85
  ):
91
86
  zhconvert_target_lang = zhconvert.Target_lang.TW
92
87
 
93
88
  case Lang_tag(
94
- language=Lang_tag_language.zh,
95
- script=Lang_tag_script.Hant,
89
+ language=Lang_tag.Language.zh,
90
+ script=Lang_tag.Script.Hant,
96
91
  region=_,
97
92
  ):
98
93
  zhconvert_target_lang = zhconvert.Target_lang.Hant
99
94
 
100
95
  case Lang_tag(
101
- language=Lang_tag_language.zh,
102
- script=Lang_tag_script.Hant,
103
- region=Lang_tag_region.CN,
96
+ language=Lang_tag.Language.zh,
97
+ script=Lang_tag.Script.Hant,
98
+ region=Lang_tag.Region.CN,
104
99
  ): # 特殊情况
105
100
  raise Exception(
106
101
  gettext("Unsupported language tag: {}", target_lang_tag)
107
102
  )
108
103
 
109
104
  case Lang_tag(
110
- language=Lang_tag_language.zh,
105
+ language=Lang_tag.Language.zh,
111
106
  script=_,
112
- region=Lang_tag_region.CN,
107
+ region=Lang_tag.Region.CN,
113
108
  ):
114
109
  zhconvert_target_lang = zhconvert.Target_lang.CN
115
110
 
@@ -120,28 +115,28 @@ def translate_subtitles(
120
115
 
121
116
  case (
122
117
  Lang_tag(
123
- language=Lang_tag_language.zh,
124
- script=Lang_tag_script.Hant,
118
+ language=Lang_tag.Language.zh,
119
+ script=Lang_tag.Script.Hant,
125
120
  region=_,
126
121
  )
127
122
  | Lang_tag(
128
- language=Lang_tag_language.zh,
123
+ language=Lang_tag.Language.zh,
129
124
  script=_,
130
- region=Lang_tag_region.HK | Lang_tag_region.TW,
125
+ region=Lang_tag.Region.HK | Lang_tag.Region.TW,
131
126
  )
132
127
  ):
133
128
  # 繁体 -> 简体
134
129
  match target_lang_tag:
135
130
  case Lang_tag(
136
- language=Lang_tag_language.zh,
131
+ language=Lang_tag.Language.zh,
137
132
  script=_,
138
- region=Lang_tag_region.CN,
133
+ region=Lang_tag.Region.CN,
139
134
  ):
140
135
  zhconvert_target_lang = zhconvert.Target_lang.CN
141
136
 
142
137
  case Lang_tag(
143
- language=Lang_tag_language.zh,
144
- script=Lang_tag_script.Hans,
138
+ language=Lang_tag.Language.zh,
139
+ script=Lang_tag.Script.Hans,
145
140
  region=_,
146
141
  ):
147
142
  zhconvert_target_lang = zhconvert.Target_lang.Hans
easyrip/global_val.py CHANGED
@@ -4,7 +4,7 @@ from functools import cache
4
4
  from pathlib import Path
5
5
 
6
6
  PROJECT_NAME = "Easy Rip"
7
- PROJECT_VERSION = "4.11.3"
7
+ PROJECT_VERSION = "4.13.0"
8
8
  PROJECT_TITLE = f"{PROJECT_NAME} v{PROJECT_VERSION}"
9
9
  PROJECT_URL = "https://github.com/op200/EasyRip"
10
10
  PROJECT_RELEASE_API = "https://api.github.com/repos/op200/EasyRip/releases/latest"
easyrip/ripper/param.py CHANGED
@@ -29,6 +29,8 @@ class Preset_name(enum.Enum):
29
29
 
30
30
  vvenc = "vvenc"
31
31
 
32
+ ffv1 = "ffv1"
33
+
32
34
  h264_amf = "h264_amf"
33
35
  h264_nvenc = "h264_nvenc"
34
36
  h264_qsv = "h264_qsv"
@@ -66,6 +68,16 @@ class Preset_name(enum.Enum):
66
68
  prefix=prefix,
67
69
  )
68
70
 
71
+ def get_param_name_set[T: set[LiteralString] | None](
72
+ self, default: T = None, /
73
+ ) -> set[LiteralString] | T:
74
+ return _PRESET__PARAM_NAME_SET.get(self, default)
75
+
76
+ def get_param_default_dict[T: dict[LiteralString, LiteralString] | None](
77
+ self, default: T = None, /
78
+ ) -> dict[LiteralString, LiteralString] | T:
79
+ return _PRESET__DEFAULT_PARAMS.get(self, default)
80
+
69
81
 
70
82
  class Audio_codec(enum.Enum):
71
83
  copy = "copy"
@@ -119,8 +131,19 @@ class Muxer(enum.Enum):
119
131
  )
120
132
  return DEFAULT
121
133
 
134
+ @classmethod
135
+ def to_help_string(cls, prefix: str = ""):
136
+ return textwrap.indent(
137
+ reduce(
138
+ lambda acc,
139
+ add: f"{acc}{' ' if add.endswith(acc.split()[-1][-4:]) else '\n'}{add}",
140
+ tuple[str](cls._member_map_),
141
+ ),
142
+ prefix=prefix,
143
+ )
144
+
122
145
 
123
- X265_PARAMS_NAME: Final[tuple[LiteralString, ...]] = (
146
+ _X265_PARAM_NAME_SET: Final[set[LiteralString]] = {
124
147
  "crf",
125
148
  "qpmin",
126
149
  "qpmax",
@@ -148,6 +171,7 @@ X265_PARAMS_NAME: Final[tuple[LiteralString, ...]] = (
148
171
  "open-gop",
149
172
  "gop-lookahead",
150
173
  "rc-lookahead",
174
+ "lookahead-slices",
151
175
  "rect",
152
176
  "amp",
153
177
  "cbqpoffs",
@@ -160,8 +184,13 @@ X265_PARAMS_NAME: Final[tuple[LiteralString, ...]] = (
160
184
  "max-tu-size",
161
185
  "level-idc",
162
186
  "sao",
163
- )
164
- X264_PARAMS_NAME: Final[tuple[LiteralString, ...]] = (
187
+ # 性能
188
+ "lookahead-threads",
189
+ "asm",
190
+ "frame-threads",
191
+ "pools",
192
+ }
193
+ _X264_PARAM_NAME_SET: Final[set[LiteralString]] = {
165
194
  "threads",
166
195
  "crf",
167
196
  "psy-rd",
@@ -182,8 +211,29 @@ X264_PARAMS_NAME: Final[tuple[LiteralString, ...]] = (
182
211
  "fast-pskip",
183
212
  "partitions",
184
213
  "direct",
185
- )
214
+ }
215
+ _FFV1_PARAM_NAME_SET: Final[set[LiteralString]] = {
216
+ "slicecrc",
217
+ "coder",
218
+ "context",
219
+ "qtable",
220
+ "remap_mode",
221
+ "remap_optimizer",
222
+ }
186
223
 
224
+ _PRESET__PARAM_NAME_SET: Final[dict[Preset_name, set[LiteralString]]] = {
225
+ Preset_name.x264: _X264_PARAM_NAME_SET,
226
+ Preset_name.x264fast: _X264_PARAM_NAME_SET,
227
+ Preset_name.x264slow: _X264_PARAM_NAME_SET,
228
+ Preset_name.x265: _X265_PARAM_NAME_SET,
229
+ Preset_name.x265fast4: _X265_PARAM_NAME_SET,
230
+ Preset_name.x265fast3: _X265_PARAM_NAME_SET,
231
+ Preset_name.x265fast2: _X265_PARAM_NAME_SET,
232
+ Preset_name.x265fast: _X265_PARAM_NAME_SET,
233
+ Preset_name.x265slow: _X265_PARAM_NAME_SET,
234
+ Preset_name.x265full: _X265_PARAM_NAME_SET,
235
+ Preset_name.ffv1: _FFV1_PARAM_NAME_SET,
236
+ }
187
237
 
188
238
  _DEFAULT_X265_PARAMS: Final[dict[LiteralString, LiteralString]] = {
189
239
  "crf": "20",
@@ -236,19 +286,9 @@ _DEFAULT_X265_PARAMS: Final[dict[LiteralString, LiteralString]] = {
236
286
  }
237
287
 
238
288
 
239
- PRESET_OPT_NAME: Final[dict[Preset_name, tuple[LiteralString, ...]]] = {
240
- Preset_name.x264: X264_PARAMS_NAME,
241
- Preset_name.x264fast: X264_PARAMS_NAME,
242
- Preset_name.x264slow: X264_PARAMS_NAME,
243
- Preset_name.x265: X265_PARAMS_NAME,
244
- Preset_name.x265fast4: X265_PARAMS_NAME,
245
- Preset_name.x265fast3: X265_PARAMS_NAME,
246
- Preset_name.x265fast2: X265_PARAMS_NAME,
247
- Preset_name.x265fast: X265_PARAMS_NAME,
248
- Preset_name.x265slow: X265_PARAMS_NAME,
249
- Preset_name.x265full: X265_PARAMS_NAME,
250
- }
251
- DEFAULT_PRESET_PARAMS: Final[dict[Preset_name, dict[LiteralString, LiteralString]]] = {
289
+ _PRESET__DEFAULT_PARAMS: Final[
290
+ dict[Preset_name, dict[LiteralString, LiteralString]]
291
+ ] = {
252
292
  Preset_name.x264fast: {
253
293
  "threads": "auto",
254
294
  "crf": "20",