diff --git a/requirements-cpu-or-mac.txt b/requirements-cpu-or-mac.txt index b94fe03f..b21f5e86 100644 --- a/requirements-cpu-or-mac.txt +++ b/requirements-cpu-or-mac.txt @@ -115,9 +115,9 @@ pyinstaller==6.6.0 pyinstaller-hooks-contrib==2024.4 pyparsing==3.1.1 pyreadline3==3.4.1 -PySide6==6.6.1 -PySide6-Addons==6.6.1 -PySide6-Essentials==6.6.1 +PySide6==6.7.0 +PySide6_Addons==6.7.0 +PySide6_Essentials==6.7.0 PySoundFile==0.9.0.post1 python-dateutil==2.8.2 pytz==2023.3.post1 @@ -135,7 +135,7 @@ rsa==4.9 samplerate==0.2.1 scikit-learn==1.3.2 scipy==1.11.3 -shiboken6==6.6.1 +shiboken6==6.7.0 six==1.16.0 sniffio==1.3.0 soundfile==0.12.1 diff --git a/requirements-linux-gpu.txt b/requirements-linux-gpu.txt index f6d12561..bbdb3ead 100644 --- a/requirements-linux-gpu.txt +++ b/requirements-linux-gpu.txt @@ -115,9 +115,9 @@ pyinstaller==6.6.0 pyinstaller-hooks-contrib==2024.4 pyparsing==3.1.1 pyreadline3==3.4.1 -PySide6==6.6.1 -PySide6-Addons==6.6.1 -PySide6-Essentials==6.6.1 +PySide6==6.7.0 +PySide6_Addons==6.7.0 +PySide6_Essentials==6.7.0 PySoundFile==0.9.0.post1 python-dateutil==2.8.2 pytz==2023.3.post1 @@ -135,7 +135,7 @@ rsa==4.9 samplerate==0.2.1 scikit-learn==1.3.2 scipy==1.11.3 -shiboken6==6.6.1 +shiboken6==6.7.0 six==1.16.0 sniffio==1.3.0 soundfile==0.12.1 diff --git a/requirements-win-gpu.txt b/requirements-win-gpu.txt index f92efaf4..182d56fa 100644 --- a/requirements-win-gpu.txt +++ b/requirements-win-gpu.txt @@ -115,9 +115,9 @@ pyinstaller==6.6.0 pyinstaller-hooks-contrib==2024.4 pyparsing==3.1.1 pyreadline3==3.4.1 -PySide6==6.6.1 -PySide6-Addons==6.6.1 -PySide6-Essentials==6.6.1 +PySide6==6.7.0 +PySide6_Addons==6.7.0 +PySide6_Essentials==6.7.0 PySoundFile==0.9.0.post1 python-dateutil==2.8.2 pytz==2023.3.post1 @@ -135,7 +135,7 @@ rsa==4.9 samplerate==0.2.1 scikit-learn==1.3.2 scipy==1.11.3 -shiboken6==6.6.1 +shiboken6==6.7.0 six==1.16.0 sniffio==1.3.0 soundfile==0.12.1 diff --git a/videotrans/__init__.py b/videotrans/__init__.py index 9cb3effc..f9433cf7 100644 --- a/videotrans/__init__.py +++ b/videotrans/__init__.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- -VERSION="v1.64" -VERSION_NUM=11064 \ No newline at end of file +VERSION="v1.66" +VERSION_NUM=11066 \ No newline at end of file diff --git a/videotrans/language/en.json b/videotrans/language/en.json index 360382aa..7e32a4a7 100644 --- a/videotrans/language/en.json +++ b/videotrans/language/en.json @@ -1,5 +1,11 @@ { "translate_language": { + "chaochu255":"The original video path and name is too long, please shorten the video name and move it to a shorter path to avoid subsequent errors.", + "teshufuhao":"Please do not include any special symbols such as + & ? : | etc. in the path or name of the original video to avoid subsequent errors.", + + "notjson": "Return response is not valid json data", + "fanyicuowu2": "The number of translation errors is more than half, please check", + "azureinfo": "Did you set the speech resource key and region values", "yuchulichucuo": "Error in preprocessing stage", diff --git a/videotrans/language/es.json b/videotrans/language/es.json index 6cd7302e..97c1acc7 100644 --- a/videotrans/language/es.json +++ b/videotrans/language/es.json @@ -1,5 +1,11 @@ { "translate_language" : { + "chaochu255":"The original video path and name is too long, please shorten the video name and move it to a shorter path to avoid subsequent errors.", + "teshufuhao":"Please do not include any special symbols such as + & ? : | etc. in the path or name of the original video to avoid subsequent errors.", + + "notjson": "Return response is not valid json data", + "fanyicuowu2": "The number of translation errors is more than half, please check", + "azureinfo": "Did you set the speech resource key and region values", "yuchulichucuo": "Error in preprocessing stage", diff --git a/videotrans/language/zh.json b/videotrans/language/zh.json index 3ce5d5f1..aeea92f4 100644 --- a/videotrans/language/zh.json +++ b/videotrans/language/zh.json @@ -1,5 +1,11 @@ { "translate_language": { + "chaochu255":"视频路径加名称过长,请缩短视频名称并移动到简短路径下,避免后续出错", + "teshufuhao":"视频路径或名称中请勿存在 + & ? : | 等特殊符号,以避免后续出错", + + "notjson": "返回响应不是有效json数据", + "fanyicuowu2": "翻译出错数量超过一半,请检查", + "azureinfo": "必须正确填写 Azure TTS 的相关信息", "yuchulichucuo": "预处理阶段出错", @@ -236,7 +242,7 @@ "onlyruanzimu": "正在嵌入软字幕,无配音", "zimuhangshu": "当前字幕行数 ", "huituicpu": "GPU上执行出错,回退到CPU执行", - "zimuwenjianbuzhengque": "字幕文件不正确,尺寸是0", + "zimuwenjianbuzhengque": "字幕文件不正确,无有效字幕", "mansuchucuo": "视频自动慢速出错,请尝试取消‘视频自动慢速’选项", "qianyiwenjian": "路径或名称含有空格或特殊符号,为避免后续处理出错,将移动到" }, diff --git a/videotrans/mainwin/secwin.py b/videotrans/mainwin/secwin.py index 175d32d0..8ec03296 100644 --- a/videotrans/mainwin/secwin.py +++ b/videotrans/mainwin/secwin.py @@ -674,7 +674,7 @@ def model_type_change(self): # 判断模型是否存在 def check_whisper_model(self, name): - if self.main.model_type.currentIndex() == 2: + if self.main.model_type.currentIndex() in [2,3]: return True slang = self.main.source_language.currentText() if name.endswith('.en') and translator.get_code(show_text=slang) != 'en': @@ -1095,6 +1095,15 @@ def check_start(self): # 视频自动减速 # 语音模型 config.params['whisper_model'] = self.main.whisper_model.currentText() + model_index=self.main.model_type.currentIndex() + if model_index==1: + config.params['model_type']='openai' + elif model_index==2: + config.params['model_type']='GoogleSpeech' + elif model_index==3: + config.params['model_type']='zh_recogn' + else: + config.params['model_type']='faster' # 字幕嵌入类型 config.params['subtitle_type'] = int(self.main.subtitle_type.currentIndex()) @@ -1295,8 +1304,12 @@ def update_status(self, type): # 更新 UI def update_data(self, json_data): d = json.loads(json_data) + if d['type']=='alert': + QMessageBox.critical(self.main, config.transobj['anerror'], d['text']) + return + # 一行一行插入字幕到字幕编辑区 - if d['type'] == 'set_start_btn': + elif d['type'] == 'set_start_btn': self.main.startbtn.setText(config.transobj["running"]) elif d['type'] == "subtitle": self.main.subtitle_area.moveCursor(QTextCursor.End) diff --git a/videotrans/recognition/__init__.py b/videotrans/recognition/__init__.py index 572b1ef8..e3d64a98 100644 --- a/videotrans/recognition/__init__.py +++ b/videotrans/recognition/__init__.py @@ -625,13 +625,13 @@ def zh_recogn(audio_file=None, cache_folder=None, set_p=None, inst=None): tools.set_process(f"识别可能较久,请耐心等待,进度可查看zh_recogn终端", 'logs',btnkey=inst.btnkey if inst else "") try: res=requests.post(f"{api_url}",files=files,proxies={"http":"","https":""},timeout=3600) - config.logger.info(f'clone-voice{res=}') + config.logger.info(f'zh_recogn:{res=}') except Exception as e: raise Exception(e) - - res = res.json() - if "code" not in res or res['code'] != 0: - raise Exception(f'{res["msg"]}') - if "data" not in res or len(res['data'])<1: - raise Exception('识别出错') - return res['data'] \ No newline at end of file + else: + res = res.json() + if "code" not in res or res['code'] != 0: + raise Exception(f'{res["msg"]}') + if "data" not in res or len(res['data'])<1: + raise Exception('识别出错') + return res['data'] \ No newline at end of file diff --git a/videotrans/separate/st.py b/videotrans/separate/st.py index ab948e26..088f67b6 100644 --- a/videotrans/separate/st.py +++ b/videotrans/separate/st.py @@ -15,7 +15,7 @@ import hashlib -def uvr(*,model_name=None, save_root=None, inp_path=None,source="logs"): +def uvr(*,model_name=None, save_root=None, inp_path=None,source="logs",btnkey=None): infos = [] try: func = AudioPre @@ -35,7 +35,7 @@ def uvr(*,model_name=None, save_root=None, inp_path=None,source="logs"): need_reformat = 0 pre_fun._path_audio_( inp_path, - ins_root=save_root + ins_root=save_root,btnkey=btnkey ) done = 1 else: @@ -60,7 +60,7 @@ def uvr(*,model_name=None, save_root=None, inp_path=None,source="logs"): try: if done == 0: pre_fun._path_audio_( - inp_path, ins_root=save_root + inp_path, ins_root=save_root,btnkey=btnkey ) infos.append("%s->Success" % (os.path.basename(inp_path))) yield "\n".join(infos) @@ -68,7 +68,7 @@ def uvr(*,model_name=None, save_root=None, inp_path=None,source="logs"): try: if done == 0: pre_fun._path_audio_( - inp_path, ins_root=save_root + inp_path, ins_root=save_root,btnkey=btnkey ) infos.append("%s->Success" % (os.path.basename(inp_path))) yield "\n".join(infos) @@ -106,13 +106,13 @@ def convert_to_pure_eng_num(string): # path 是需要保存vocal.wav的目录 -def start(audio,path,source="logs"): +def start(audio,path,source="logs",btnkey=None): dist=int(config.settings['separate_sec']) try: # 获取总时长秒 sec=tools.get_audio_time(audio) #if sec<=dist: - gr = uvr(model_name="HP2", save_root=path, inp_path=audio,source=source) + gr = uvr(model_name="HP2", save_root=path, inp_path=audio,source=source,btnkey=btnkey) print(next(gr)) print(next(gr)) except Exception as e: diff --git a/videotrans/separate/utils.py b/videotrans/separate/utils.py index ba6fb23d..cc208805 100644 --- a/videotrans/separate/utils.py +++ b/videotrans/separate/utils.py @@ -26,7 +26,7 @@ def make_padding(width, cropsize, offset): return left, right, roi_size -def inference(X_spec, device, model, aggressiveness, data,source="logs"): +def inference(X_spec, device, model, aggressiveness, data,source="logs",btnkey=None): """ data : dic configs """ @@ -45,7 +45,7 @@ def _execute( if source!='logs' and config.separate_status !='ing': return jd=(i+1)*100/n_window - tools.set_process(f"{config.transobj['Separating background music']} {round(jd,1)}%",source) + tools.set_process(f"{config.transobj['Separating background music']} {round(jd,1)}%",source,btnkey=btnkey) print(f"{config.transobj['Separating background music']} {round(jd,1)}%") start = i * roi_size X_mag_window = X_mag_pad[ diff --git a/videotrans/separate/vr.py b/videotrans/separate/vr.py index 644bbecf..c76cef46 100644 --- a/videotrans/separate/vr.py +++ b/videotrans/separate/vr.py @@ -39,7 +39,7 @@ def __init__(self, agg, model_path, device, is_half, tta=False,source="logs"): self.model = model def _path_audio_( - self, music_file, ins_root=None, format="wav", is_hp3=False + self, music_file, ins_root=None, format="wav", is_hp3=False,btnkey=None ): if ins_root is None: return "No save root." @@ -104,7 +104,7 @@ def _path_audio_( } with torch.no_grad(): pred, X_mag, X_phase = inference( - X_spec_m, self.device, self.model, aggressiveness, self.data,self.source + X_spec_m, self.device, self.model, aggressiveness, self.data,self.source,btnkey=btnkey ) # Postprocess if self.data["postprocess"]: diff --git a/videotrans/task/main_worker.py b/videotrans/task/main_worker.py index 4d2c6299..7a9ec876 100644 --- a/videotrans/task/main_worker.py +++ b/videotrans/task/main_worker.py @@ -9,6 +9,7 @@ from videotrans.util import tools from videotrans.util.tools import set_process, send_notification from pathlib import Path +import re class Worker(QThread): @@ -70,6 +71,16 @@ def run(self) -> None: return self.stop() # 格式化每个视频信息 obj_format = tools.format_video(it.replace('\\', '/'), config.params['target_dir']) + target_dir_mp4=obj_format['output']+f"/{obj_format['raw_noextname']}.mp4" + if len(target_dir_mp4)>=250: + set_process(config.transobj['chaochu255']+"\n\n"+it, 'alert') + self.stop() + return + if re.search(r'[\&\+\:\?\|]+',it[2:]): + set_process(config.transobj['teshufuhao']+"\n\n"+it, 'alert') + self.stop() + return + videolist.append(obj_format) self.unidlist.append(obj_format['unid']) # 添加进度按钮 unid @@ -134,7 +145,7 @@ def run(self) -> None: return self.stop() video.dubbing() except Exception as e: - err=f'{config.transobj["peyinchucuo"]}:' + str(e) + err=f'{config.transobj["peiyinchucuo"]}:' + str(e) config.errorlist[video.btnkey]=err set_process(err, 'error', btnkey=video.btnkey) continue @@ -152,6 +163,7 @@ def run(self) -> None: return self.stop() video.move_at_end() except Exception as e: + err=f'{config.transobj["hebingchucuo"]}:' + str(e) config.errorlist[video.btnkey]=err set_process(err, 'error', btnkey=video.btnkey) diff --git a/videotrans/task/trans_create.py b/videotrans/task/trans_create.py index 2cbd5a12..d75a99e2 100644 --- a/videotrans/task/trans_create.py +++ b/videotrans/task/trans_create.py @@ -316,7 +316,7 @@ def _split_wav_novicemp4(self): # 背景分离音 try: tools.set_process(config.transobj['Separating background music'], btnkey=self.btnkey) - tools.split_audio_byraw(self.source_mp4, self.targetdir_source_wav, True) + tools.split_audio_byraw(self.source_mp4, self.targetdir_source_wav, True,btnkey=self.btnkey) except Exception as e: pass finally: @@ -355,20 +355,11 @@ def recogn(self): self.regcon_end = True self._unlink(self.shibie_audio) return True - if tools.vail_file(self.targetdir_source_sub): - self.regcon_end = True + if self._srt_vail(self.targetdir_source_sub): + # 判断已存在的字幕文件中是否存在有效字幕纪录 if self.obj and self.obj['output']!=self.obj['linshi_output']: shutil.copy2(self.targetdir_source_sub,f'{self.obj["output"]}/{Path(self.targetdir_source_sub).name}') - self._unlink(self.shibie_audio) - return True - #####识别阶段 存在已识别后的字幕,并且不存在目标语言字幕,则更新替换界面字幕 - if tools.vail_file(self.targetdir_target_sub): - # 通知前端替换字幕 - with open(self.targetdir_target_sub, 'r', encoding="utf-8", errors="ignore") as f: - tools.set_process(f.read().strip(), 'replace_subtitle', btnkey=self.btnkey) self.regcon_end = True - if self.obj and self.obj['output']!=self.obj['linshi_output']: - shutil.copy2(self.targetdir_target_sub,f'{self.obj["output"]}/{Path(self.targetdir_target_sub).name}') self._unlink(self.shibie_audio) return True @@ -398,26 +389,33 @@ def recogn(self): if re.search(r'cub[a-zA-Z0-9_.-]+?\.dll', msg, re.I | re.M) is not None: msg = f'【缺少cuBLAS.dll】请点击菜单栏-帮助/支持-下载cublasxx.dll,或者切换为openai模型 ' if config.defaulelang == 'zh' else f'[missing cublasxx.dll] Open menubar Help&Support->Download cuBLASxx.dll or use openai model' raise Exception(f'{msg}') + else: + if not raw_subtitles or len(raw_subtitles) < 1: + self.regcon_end = True + raise Exception(self.obj['raw_basename'] + config.transobj['recogn result is empty'].replace('{lang}',self.config_params['source_language'])) + self._save_srt_target(raw_subtitles, self.targetdir_source_sub) + + if self.obj and self.obj['output'] != self.obj['linshi_output']: + shutil.copy2(self.targetdir_source_sub, f'{self.obj["output"]}/{Path(self.targetdir_source_sub).name}') + # 仅提取字幕 + if self.app_mode=='tiqu': + shutil.copy2(self.targetdir_source_sub, f'{self.obj["output"]}/{self.obj["raw_noextname"]}.srt') + if self.config_params['target_language'] == '-' or self.config_params['target_language'] == self.config_params['source_language']: + self.compose_end=True - - if not raw_subtitles or len(raw_subtitles) < 1: - self.regcon_end = True - raise Exception(self.obj['raw_basename'] + config.transobj['recogn result is empty'].replace('{lang}', - self.config_params['source_language'])) - self._save_srt_target(raw_subtitles, self.targetdir_source_sub) - if self.obj and self.obj['output'] != self.obj['linshi_output']: - shutil.copy2(self.targetdir_source_sub, f'{self.obj["output"]}/{Path(self.targetdir_source_sub).name}') - # 仅提取字幕 - if self.app_mode=='tiqu': - shutil.copy2(self.targetdir_source_sub, f'{self.obj["output"]}/{self.obj["raw_noextname"]}.srt') - if self.config_params['target_language'] == '-' or self.config_params['target_language'] == self.config_params['source_language']: - self.compose_end=True - - - # 删除识别音频 self.regcon_end = True return True + #字幕是否存在并且有效 + def _srt_vail(self,file): + if not tools.vail_file(file): + return False + try: + tools.get_subtitle_from_srt(file) + except Exception: + self._unlink(file) + return False + return True # 翻译字幕 def trans(self): self.precent += 3 @@ -431,7 +429,8 @@ def trans(self): config.task_countdown = 0 if self.app_mode == 'biaozhun_jd' else config.settings['countdown_sec'] # 如果存在目标语言字幕,前台直接使用该字幕替换 - if tools.vail_file(self.targetdir_target_sub): + if self._srt_vail(self.targetdir_target_sub): + # 判断已存在的字幕文件中是否存在有效字幕纪录 # 通知前端替换字幕 with open(self.targetdir_target_sub, 'r', encoding="utf-8", errors="ignore") as f: tools.set_process(f.read().strip(), 'replace_subtitle', btnkey=self.btnkey) @@ -439,6 +438,7 @@ def trans(self): if self.obj and self.obj['output'] != self.obj['linshi_output']: shutil.copy2(self.targetdir_target_sub, f'{self.obj["output"]}/{Path(self.targetdir_target_sub).name}') + self.trans_end = True return True # 批量不允许修改字幕 @@ -455,8 +455,9 @@ def trans(self): # 禁止修改字幕 tools.set_process('translate_start', 'timeout_djs', btnkey=self.btnkey) time.sleep(2) + # 如果不存在原字幕,或已存在目标语言字幕则跳过,比如使用已有字幕,无需翻译时 - if not tools.vail_file(self.targetdir_source_sub) or tools.vail_file(self.targetdir_target_sub): + if self._srt_vail(self.targetdir_target_sub): self.trans_end = True if self.app_mode == 'tiqu': self.compose_end = True @@ -481,14 +482,15 @@ def trans(self): except Exception as e: self.trans_end = True raise Exception(e) - self._save_srt_target(target_srt, self.targetdir_target_sub) - self.trans_end = True - if self.obj and self.obj['output'] != self.obj['linshi_output']: - shutil.copy2(self.targetdir_target_sub, f'{self.obj["output"]}/{Path(self.targetdir_target_sub).name}') - # 仅提取,该名字删原 - if self.app_mode == 'tiqu': - shutil.copy2(self.targetdir_target_sub,f'{self.obj["output"]}/{self.obj["raw_noextname"]}-{self.target_language_code}.srt') - self.compose_end = True + else: + self._save_srt_target(target_srt, self.targetdir_target_sub) + self.trans_end = True + if self.obj and self.obj['output'] != self.obj['linshi_output']: + shutil.copy2(self.targetdir_target_sub, f'{self.obj["output"]}/{Path(self.targetdir_target_sub).name}') + # 仅提取,该名字删原 + if self.app_mode == 'tiqu': + shutil.copy2(self.targetdir_target_sub,f'{self.obj["output"]}/{self.obj["raw_noextname"]}-{self.target_language_code}.srt') + self.compose_end = True return True # 配音处理 diff --git a/videotrans/translator/azure.py b/videotrans/translator/azure.py index fc68008b..048e0b38 100644 --- a/videotrans/translator/azure.py +++ b/videotrans/translator/azure.py @@ -13,16 +13,18 @@ def get_content(d,*,model=None,prompt=None): {'role': 'user', 'content': prompt.replace('[TEXT]',"\n".join(d))}, ] - config.logger.info(f"\n[Azure start]待翻译:{message=}") + config.logger.info(f"\n[AzureGPT]请求数据:{message=}") try: response = model.chat.completions.create( model=config.params["azure_model"], messages=message ) - config.logger.info(f'Azure 返回响应:{response}') + config.logger.info(f'[AzureGPT]返回响应:{response=}') except APIError as e: + config.logger.error(f'[AzureGPT]请求失败:{str(e)}') raise Exception(f'{e.message=}') except Exception as e: + config.logger.error(f'[AzureGPT]请求失败:{str(e)}') raise Exception(e) if response.choices: @@ -30,11 +32,12 @@ def get_content(d,*,model=None,prompt=None): elif response.data and response.data['choices']: result = response.data['choices'][0]['message']['content'].strip() else: - raise Exception(f"[error]:Azure {response}") + config.logger.error(f'[AzureGPT]请求失败:{response=}') + raise Exception(f"{response}") result = result.replace('##', '').strip().replace(''', '"').replace('"', "'") return result, response -def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,source_code=None,is_test=False): +def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,source_code="",is_test=False): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -59,13 +62,12 @@ def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,s is_srt=False if isinstance(text_list, str) else True # 切割为每次翻译多少行,值在 set.ini中设定,默认10 split_size = int(config.settings['trans_thread']) - #if is_srt and split_size>1: + prompt = config.params['azure_template'].replace('{lang}', target_language) with open(config.rootdir+"/videotrans/azure.txt",'r',encoding="utf-8") as f: prompt=f.read() prompt=prompt.replace('{lang}', target_language) - #else: - # prompt=prompt_line + end_point="。" if config.defaulelang=='zh' else '. ' # 整理待翻译的文字为 List[str] if not is_srt: @@ -79,20 +81,17 @@ def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,s response=None while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing' and not is_test: - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing' and not is_test): + return if iter_num >= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err=f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break iter_num += 1 - if iter_num > 1: if set_p: tools.set_process( f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + time.sleep(10) client = AzureOpenAI( api_key=config.params["azure_key"], @@ -103,8 +102,8 @@ def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,s for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing' and not is_test: - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing' and not is_test): + return if i0: @@ -138,20 +137,27 @@ def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,s if len(sep_res)-1 or error.lower().find('ConnectTimeoutError')>-1: - raise Exception(f'无法连接到Azure,请正确填写代理地址:{error}') - err = error - index = i + err = str(e) break + else: + # 未出错 + err='' + iter_num=0 + index=0 if i<=1 else i else: break + if err: + config.logger.error(f'[AzureGPT]翻译请求失败:{err=}') + raise Exception(f'AzureGPT:{err}') + if not is_srt: return "\n".join(target_text["0"]) + if len(target_text['srts']) < len(text_list) / 2: + raise Exception(f'AzureGPT:{config.transobj["fanyicuowu2"]}') for i, it in enumerate(text_list): line=str(it["line"]) diff --git a/videotrans/translator/baidu.py b/videotrans/translator/baidu.py index 4087a7c6..88897fd1 100644 --- a/videotrans/translator/baidu.py +++ b/videotrans/translator/baidu.py @@ -5,7 +5,7 @@ from videotrans.configure import config from videotrans.util import tools -def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=None): +def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=""): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -21,19 +21,17 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source iter_num = 0 # 当前循环次数,如果 大于 config.settings.retries 出错 err = "" while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing': - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing'): + return if iter_num >= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err=f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break iter_num += 1 if iter_num > 1: if set_p: tools.set_process( f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + time.sleep(10) # 整理待翻译的文字为 List[str] if isinstance(text_list, str): source_text = text_list.strip().split("\n") @@ -45,8 +43,8 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source split_source_text = [source_text[i:i + split_size] for i in range(0, len(source_text), split_size)] for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing': - break + if config.exit_soft or ( config.current_status != 'ing' and config.box_trans != 'ing'): + return if i0: @@ -60,20 +58,29 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source md5.update(strtext.encode('utf-8')) sign = md5.hexdigest() - config.logger.info(f'Baidu 发送给:{text=}') - res = requests.get( - f"http://api.fanyi.baidu.com/api/trans/vip/translate?q={text}&from=auto&to={target_language}&appid={config.params['baidu_appid']}&salt={salt}&sign={sign}") - res = res.json() - config.logger.info(f'Baidu 返回响应:{res=}') + requrl= f"http://api.fanyi.baidu.com/api/trans/vip/translate?q={text}&from=auto&to={target_language}&appid={config.params['baidu_appid']}&salt={salt}&sign={sign}" + + config.logger.info(f'[Baidu]请求数据:{requrl=}') + resraw = requests.get(requrl) + config.logger.info(f'[Baidu]返回响应:{resraw=}') + try: + res = resraw.json() + except Exception: + err=config.transobj['notjson']+resraw + break + if "error_code" in res or "trans_result" not in res or len(res['trans_result'])<1: - config.logger.info(f'Baidu 返回响应:{res}') + config.logger.info(f'Baidu 返回响应:{resraw}') if res['error_msg'].find('Access Limit')>-1: - raise Exception("Access Limit") - raise Exception("[error]百度翻译失败:" + res['error_msg']) + time.sleep(10) + break + err= res['error_msg'] + break result = [tres['dst'].strip().replace(''','"').replace('"',"'") for tres in res['trans_result']] if not result or len(result)<1: - raise Exception(f'百度翻译失败:{res}') + err=f'{resraw}' + break if inst and inst.precent < 75: inst.precent += round((i + 1) * 5 / len(split_source_text), 2) @@ -89,20 +96,27 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source result_length += 1 result = result[:source_length] target_text.extend(result) - iter_num=0 + except Exception as e: - error = str(e) - err=error - index=i - time.sleep(10) + err = str(e) break + else: + # 未出错 + err='' + iter_num=0 + index=0 if i<=1 else i else: break - + if err: + config.logger.error(f'[Baidu]翻译请求失败:{err=}') + raise Exception(f'百度翻译:{err}') if isinstance(text_list, str): return "\n".join(target_text) max_i = len(target_text) + if max_i < len(text_list) / 2: + raise Exception(f'百度翻译:出错数量超过一半,请检查') + for i, it in enumerate(text_list): if i < max_i : text_list[i]['text'] = target_text[i] diff --git a/videotrans/translator/chatgpt.py b/videotrans/translator/chatgpt.py index c30e84ce..41cb2a7d 100644 --- a/videotrans/translator/chatgpt.py +++ b/videotrans/translator/chatgpt.py @@ -35,7 +35,7 @@ def create_openai_client(): try: client = OpenAI(base_url=api_url,http_client=httpx.Client(proxies=proxies)) except Exception as e: - raise Exception(f'chatGPT API={api_url},{str(e)}') + raise Exception(f'API={api_url},{str(e)}') return client,api_url def get_content(d,*,model=None,prompt=None): @@ -43,16 +43,18 @@ def get_content(d,*,model=None,prompt=None): {'role': 'system', 'content': "You are a professional, authentic translation engine, only returns translations."}, {'role': 'user', 'content': prompt.replace('[TEXT]',"\n".join(d))}, ] - config.logger.info(f"\n[chatGPT start]待翻译:{message=}") + config.logger.info(f"\n[chatGPT]发送请求数据:{message=}") try: response = model.chat.completions.create( model=config.params['chatgpt_model'], messages=message ) - config.logger.info(f'chatGPT 返回响应:{response}') + config.logger.info(f'[chatGPT]响应:{response=}') except APIError as e: + config.logger.error(f'[chatGPT]请求失败:{str(e)}') raise Exception(f'{e.message=}') except Exception as e: + config.logger.error(f'[chatGPT]请求失败:{str(e)}') raise Exception(e) if response.choices: @@ -60,13 +62,14 @@ def get_content(d,*,model=None,prompt=None): elif response.data and response.data['choices']: result = response.data['choices'][0]['message']['content'].strip() else: - raise Exception(f"chatGPT {response}") + config.logger.error(f'[chatGPT]请求失败:{response=}') + raise Exception(f"{response}") result = result.replace('##', '').strip().replace(''', '"').replace('"', "'") return result,response -def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,source_code=None,is_test=False): +def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,source_code="",is_test=False): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -91,8 +94,7 @@ def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,s prompt=f.read() prompt=prompt.replace('{lang}', target_language) - #else: - # prompt=prompt_line + end_point="。" if config.defaulelang=='zh' else '. ' # 整理待翻译的文字为 List[str] if not is_srt: @@ -106,25 +108,25 @@ def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,s response=None while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing' and not is_test: - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing' and not is_test): + return if iter_num >= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err=f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break iter_num += 1 if iter_num > 1: if set_p: tools.set_process( f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + time.sleep(10) + client,api_url = create_openai_client() + config.logger.info(f'[chatGPT],{api_url=}') for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing' and not is_test: - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing' and not is_test): + return if i < index: continue if stop>0: @@ -161,23 +163,28 @@ def trans(text_list, target_language="English", *, set_p=True,inst=None,stop=0,s if len(sep_res)-1 or error.lower().find('ConnectTimeoutError')>-1: - raise Exception(f'无法连接到 {api_url},请正确填写代理地址:{error}') - if source_code is not None: - err =error+f'目标文件夹下{source_code}.srt文件第{(i*split_size)+1}条开始的{split_size}条字幕' - else: - err=error+f", {api_url=}" - index = i + err=str(e) break + else: + # 未出错 + err='' + iter_num=0 + index=0 if i<=1 else i else: break + if err: + config.logger.error(f'[ChatGPT]翻译请求失败:{err=}') + raise Exception(f'ChatGPT:{err}') if not is_srt: return "\n".join(target_text["0"]) + + if len(target_text['srts']) < len(text_list)/2: + raise Exception(f'ChatGPT:{config.transobj["fanyicuowu2"]},{config.params["chatgpt_api"]}') + for i, it in enumerate(text_list): if i< len(target_text['srts']): text_list[i]['text'] = target_text['srts'][i] diff --git a/videotrans/translator/deepl.py b/videotrans/translator/deepl.py index 4f958bd3..68d96c7a 100644 --- a/videotrans/translator/deepl.py +++ b/videotrans/translator/deepl.py @@ -7,7 +7,7 @@ from videotrans.util import tools -def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=None): +def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=""): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -23,19 +23,17 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source iter_num = 0 # 当前循环次数,如果 大于 config.settings.retries 出错 err = "" while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing': - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing'): + return if iter_num >= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err= f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break iter_num += 1 if iter_num > 1: if set_p: tools.set_process( f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + time.sleep(10) # 整理待翻译的文字为 List[str] if isinstance(text_list, str): source_text = text_list.strip().split("\n") @@ -49,15 +47,17 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source deepltranslator = deepl.Translator(config.params['deepl_authkey'],server_url=None if not config.params['deepl_api'] else config.params['deepl_api'].rstrip('/')) for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing': - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing'): + return if i < index: continue if stop>0: time.sleep(stop) try: source_length = len(it) + config.logger.info(f'[DeepL]请求数据:{it=}') result = deepltranslator.translate_text("\n".join(it), target_lang=target_language if not re.match(r'^zh',target_language,re.I) else "ZH" ) + config.logger.info(f'[DeepL]返回:{result=}') result=result.text.strip().replace(''','"').replace('"',"'").split("\n") if inst and inst.precent < 75: inst.precent += round((i + 1) * 5 / len(split_source_text), 2) @@ -73,18 +73,26 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source result_length += 1 result = result[:source_length] target_text.extend(result) - iter_num=0 except Exception as e: - error = str(e) - err=error - index=i + err = str(e) break + else: + # 未出错 + err='' + iter_num=0 + index=0 if i<=1 else i else: break + if err: + config.logger.error(f'[DeepL]翻译请求失败:{err=}') + raise Exception(f'DeepL:{err}') if isinstance(text_list, str): return "\n".join(target_text) max_i = len(target_text) + if max_i < len(text_list) / 2: + raise Exception(f'DeepL:{config.transobj["fanyicuowu2"]}') + for i, it in enumerate(text_list): if i < max_i: text_list[i]['text'] = target_text[i] diff --git a/videotrans/translator/deeplx.py b/videotrans/translator/deeplx.py index 92303762..ce2f5c5d 100644 --- a/videotrans/translator/deeplx.py +++ b/videotrans/translator/deeplx.py @@ -6,7 +6,7 @@ from videotrans.util import tools -def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=None): +def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=""): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -33,19 +33,17 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source iter_num = 0 # 当前循环次数,如果 大于 config.settings.retries 出错 err = "" while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing': - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing'): + return if iter_num >= config.settings['retries']: - raise Exception( - f'DeepLx:{iter_num}{"次重试后依然出错,请更换翻译渠道" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err=f'{iter_num}{"次重试后依然出错,请更换翻译渠道" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break iter_num += 1 if iter_num > 1: if set_p: tools.set_process( f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + time.sleep(10) # 整理待翻译的文字为 List[str] if isinstance(text_list, str): source_text = text_list.strip().split("\n") @@ -57,8 +55,8 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source split_source_text = [source_text[i:i + split_size] for i in range(0, len(source_text), split_size)] response=None for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing': - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing'): + return if i < index: continue if stop>0: @@ -70,16 +68,19 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source "source_lang": "auto", "target_lang": 'zh' if target_language.startswith('zh') else target_language } - config.logger.info(f'data,{i=}, {data}') + config.logger.info(f'[DeepLX]发送请求数据,{data=}') response = requests.post(url=url, json=data, proxies=proxies) + config.logger.info(f'[DeepLX]返回响应,{response.text=}') try: result = response.json() except Exception as e: - raise Exception(f'DeepLx请更换翻译渠道:{response.text=}') + err=config.transobj['notjson']+response.text + break result=result['data'].strip().replace(''','"').replace('"',"'") if not result: - raise Exception(f'DeepLx请更换翻译渠道:{response.text=}') + err=f'无有效返回,{response.text=}' + break result=result.split("\n") config.logger.info(f'result,{i=}, {result=}') if inst and inst.precent < 75: @@ -95,20 +96,27 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source result_length += 1 result = result[:source_length] target_text.extend(result) - iter_num=0 except Exception as e: - error = str(e) - config.logger.error(f'DeepLx {error}') - err=error - index=i + err = str(e) break + else: + # 未出错 + err='' + iter_num=0 + index=0 if i<=1 else i else: break + if err: + config.logger.error(f'[DeepLX]翻译请求失败:{err=}') + raise Exception(f'DeepLX:{err}') if isinstance(text_list, str): return "\n".join(target_text) max_i = len(target_text) + if max_i < len(text_list) / 2: + raise Exception(f'DeepLX:{config.transobj["fanyicuowu2"]}') + for i, it in enumerate(text_list): if i < max_i: text_list[i]['text'] = target_text[i] diff --git a/videotrans/translator/freegoogle.py b/videotrans/translator/freegoogle.py index 5198a323..47b10da1 100644 --- a/videotrans/translator/freegoogle.py +++ b/videotrans/translator/freegoogle.py @@ -21,7 +21,7 @@ -def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=None): +def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=""): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -45,20 +45,19 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source err = "" google_url=random.choice(urls) while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing': - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing'): + return if iter_num >= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err=f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break + iter_num += 1 if iter_num > 1: if set_p: tools.set_process( f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + time.sleep(10) # 整理待翻译的文字为 List[str] if isinstance(text_list, str): @@ -72,65 +71,73 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source split_source_text = [source_text[i:i + split_size] for i in range(0, len(source_text), split_size)] for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing': - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing'): + return if i0: time.sleep(stop) try: - source_length=len(it) text = "\n".join(it) url = f"{google_url}/m?sl=auto&tl={urllib.parse.quote(target_language)}&hl={urllib.parse.quote(target_language)}&q={urllib.parse.quote(text)}" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } + config.logger.info(f'[FreeGoole] 发送请求:{url=}') response = requests.get(url, proxies=proxies, headers=headers, timeout=300) + config.logger.info(f'[FreeGoole] 返回:{response.text=}') if response.status_code != 200: config.logger.error(f'{response.text=}') - raise Exception(f'FreeGoogle {google_url} error_code={response.status_code}') + err=f'{google_url} error_code={response.status_code}' + break re_result = re.findall( r'(?s)class="(?:t0|result-container)">(.*?)<', response.text) - if len(re_result) < 1: - raise Exception('len(re_result)<1') - if re_result[0]: - result=re_result[0].strip().replace(''','"').replace('"',"'").split("\n") - if inst and inst.precent < 75: - inst.precent += round((i + 1) * 5 / len(split_source_text), 2) - if set_p: - tools.set_process( f'{result[0]}\n\n' if split_size==1 else "\n\n".join(result), 'subtitle') - tools.set_process(config.transobj['starttrans']+f' {i*split_size+1} ',btnkey=inst.btnkey if inst else "") - else: - tools.set_process("\n\n".join(result), func_name="set_fanyi") - result_length=len(result) - config.logger.info(f'{result_length=},{source_length=}') - while result_length= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err=f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break iter_num += 1 - # print(f'第{iter_num}次') + if iter_num > 1: if set_p: tools.set_process( f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + time.sleep(10) response = None for i, it in enumerate(split_source_text): - - if config.current_status != 'ing' and config.box_trans != 'ing' and not is_test: - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing' and not is_test): + return if i < index: continue if stop > 0: time.sleep(stop) - try: result,response=get_content(it,model=model,prompt=prompt) if inst and inst.precent < 75: @@ -179,7 +178,7 @@ def trans(text_list, target_language="English", *, set_p=True, inst=None, stop=0 t,response=get_content([it_n.strip()],model=model,prompt=prompt) except Exception as e: config.logger.error(f'触发安全限制,{t=},{it_n=}') - t="-" + t="--" sep_res.append(t) for x, result_item in enumerate(sep_res): @@ -194,21 +193,28 @@ def trans(text_list, target_language="English", *, set_p=True, inst=None, stop=0 if len(sep_res) < len(it): tmp = ["" for x in range(len(it) - len(sep_res))] target_text["srts"] += tmp - iter_num = 0 + except Exception as e: - error = str(e) - if error.lower().find('timeout')>-1 or err.lower().find('timed out')>-1 or error.lower().find('ConnectTimeoutError')>-1: - raise Exception(f'无法连接到Google,请正确填写代理地址:{error}') - index = i - err = error + err = str(e) break + else: + # 未出错 + err = '' + iter_num = 0 + index = 0 if i <= 1 else i else: - break + + if err: + config.logger.error(f'[Gemini]翻译请求失败:{err=}') + raise Exception(f'Gemini:{err}') + if not is_srt: return "\n".join(target_text["0"]) - #print(f'{target_text=}') + if len(target_text['srts']) < len(text_list) / 2: + raise Exception(f'Gemini:{config.transobj["fanyicuowu2"]}') + for i, it in enumerate(text_list): if i < len(target_text['srts']): text_list[i]['text'] = target_text['srts'][i] diff --git a/videotrans/translator/google.py b/videotrans/translator/google.py index 712eeb7e..6f8a4e43 100644 --- a/videotrans/translator/google.py +++ b/videotrans/translator/google.py @@ -10,7 +10,7 @@ from videotrans.util import tools -def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=None): +def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=""): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -31,23 +31,22 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source index = 0 # 当前循环需要开始的 i 数字,小于index的则跳过 iter_num = 0 # 当前循环次数,如果 大于 config.settings.retries 出错 + # 记录最后一次错误 err = "" google_url=tools.get_google_url() while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing': - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing'): + return if iter_num >= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') - iter_num += 1 + err=f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break + iter_num += 1 if iter_num > 1: if set_p: tools.set_process( - f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + f"出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") + time.sleep(10) # 整理待翻译的文字为 List[str] if isinstance(text_list, str): @@ -61,67 +60,73 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source split_source_text = [source_text[i:i + split_size] for i in range(0, len(source_text), split_size)] for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing': - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing'): + return if i0: time.sleep(stop) try: - source_length=len(it) text = "\n".join(it) url = f"{google_url}/m?sl=auto&tl={urllib.parse.quote(target_language)}&hl={urllib.parse.quote(target_language)}&q={urllib.parse.quote(text)}" + config.logger.info(f'[Google]请求数据:{url=}') headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } response = requests.get(url, proxies=proxies, headers=headers, timeout=300) + config.logger.info(f'[Google]返回数据:{response.text=}') if response.status_code != 200: config.logger.error(f'{response.text=}') - raise Exception(f'Google {response.status_code},{response.reason}') - - re_result = re.findall( - r'(?s)class="(?:t0|result-container)">(.*?)<', response.text) - if len(re_result) < 1: - raise Exception('len(re_result)<1') - if re_result[0]: - result=re_result[0].strip().replace(''','"').replace('"',"'").split("\n") - if inst and inst.precent < 75: - inst.precent += round((i + 1) * 5 / len(split_source_text), 2) - if set_p: - tools.set_process( f'{result[0]}\n\n' if split_size==1 else "\n\n".join(result), 'subtitle') - tools.set_process(config.transobj['starttrans']+f' {i*split_size+1} ',btnkey=inst.btnkey if inst else "") - else: - tools.set_process("\n\n".join(result), func_name="set_fanyi") - result_length=len(result) - config.logger.info(f'{result_length=},{source_length=}') - while result_length(.*?)<', response.text) + if len(re_result) < 1 or not re_result[0]: + err=f'无有效结果,{response.text}' + break + + result=re_result[0].strip().replace(''','"').replace('"',"'").split("\n") + if inst and inst.precent < 75: + inst.precent += round((i + 1) * 5 / len(split_source_text), 2) + if set_p: + tools.set_process( f'{result[0]}\n\n' if split_size==1 else "\n\n".join(result), 'subtitle') + tools.set_process(config.transobj['starttrans']+f' {i*split_size+1} ',btnkey=inst.btnkey if inst else "") else: - raise Exception(f'Google no result:{re_result}') + tools.set_process("\n\n".join(result), func_name="set_fanyi") + result_length=len(result) + config.logger.info(f'{result_length=},{source_length=}') + while result_length-1 or error.lower().find('ConnectTimeoutError')>-1: - raise Exception(f'无法连接到Google,请正确填写代理地址:{error}') - config.logger.error(f'Google error:{google_url} {str(error)}') - err=error - index=i + err = f'Google:{str(e)}' break + else: + # 未出错 + err='' + iter_num=0 + index=0 if i<=1 else i else: break + if err: + config.logger.error(f'[Google]翻译请求失败:{err=}') + raise Exception(f'Google:{err}') if isinstance(text_list, str): return "\n".join(target_text) max_i = len(target_text) + if max_i < len(text_list)/2: + raise Exception(f'Google:{config.transobj["fanyicuowu2"]}') + for i, it in enumerate(text_list): if i < max_i: text_list[i]['text'] = target_text[i] diff --git a/videotrans/translator/microsoft.py b/videotrans/translator/microsoft.py index f6317e0c..f032840d 100644 --- a/videotrans/translator/microsoft.py +++ b/videotrans/translator/microsoft.py @@ -4,7 +4,7 @@ from videotrans.configure import config from videotrans.util import tools -def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=None): +def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=""): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -27,14 +27,11 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source 'https': serv } while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing': - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing'): + return if iter_num >= config.settings['retries']: - if err.find("timeout")>-1 and config.defaulelang == "zh": - err=f'{iter_num}次重试后依然出错,请尝试挂代理并填写代理地址,或者更换其他翻译渠道' - raise Exception(f'{err}') + err=f'{err}' + break iter_num += 1 if iter_num > 1: if set_p: @@ -58,9 +55,11 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source try: auth=requests.get('https://edge.microsoft.com/translate/auth',headers=headers,proxies=proxies) except: - raise Exception('连接微软翻译失败,请更换其他翻译渠道' if config.defaulelang=='zh' else 'Failed to connect to Microsoft Translate, please change to another translation channel') + err='连接微软翻译失败,请更换其他翻译渠道' if config.defaulelang=='zh' else 'Failed to connect to Microsoft Translate, please change to another translation channel' + continue + for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing': + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing'): break if i < index: continue @@ -71,44 +70,58 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source text = "\n".join(it) url = f"https://api-edge.cognitive.microsofttranslator.com/translate?from=&to={target_language}&api-version=3.0&includeSentenceLength=true" headers['Authorization']=f"Bearer {auth.text}" + config.logger.info(f'[Mircosoft]请求数据:{url=},{auth.text=}') response = requests.post(url, json=[{"Text":text}],headers=headers, timeout=300,proxies=proxies) + config.logger.info(f'[Mircosoft]返回:{response.text=}') if response.status_code != 200: - config.logger.info(f'Microsoft 返回响应:{response.text}\nurl={url}') - raise Exception(f'{response.status_code=}') + err=f'{response.status_code=}' + break + try: + re_result=response.json() + except Exception: + err=config.transobj['notjson']+response.text + break - re_result=response.json() - if len(re_result)>0 and len(re_result[0]['translations'])>0: - result=re_result[0]['translations'][0]['text'].strip().replace(''','"').replace('"',"'").split("\n") - if inst and inst.precent < 75: - inst.precent += round((i + 1) * 5 / len(split_source_text), 2) - if set_p: - tools.set_process( f'{result[0]}\n\n' if split_size==1 else "\n\n".join(result), 'subtitle') - tools.set_process(config.transobj['starttrans']+f' {i*split_size+1} ',btnkey=inst.btnkey if inst else "") - else: - tools.set_process("\n\n".join(result), func_name="set_fanyi") - result_length=len(result) - config.logger.info(f'{result_length=},{source_length=}') - while result_length= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err=f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break iter_num += 1 if iter_num > 1: if set_p: tools.set_process( f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + time.sleep(10) # 整理待翻译的文字为 List[str] if isinstance(text_list, str): source_text = text_list.strip().split("\n") @@ -58,8 +56,8 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source split_source_text = [source_text[i:i + split_size] for i in range(0, len(source_text), split_size)] for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing': - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing'): + return if i < index: continue if stop>0: @@ -75,16 +73,22 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source try: response = requests.post(url=url,json=data,proxies=proxies) - result = response.json() except Exception as e: - msg = f"OTT出错了,请检查部署和地址: {str(e)}" - raise Exception(msg) + err=str(e) + break if response.status_code != 200: - msg=f"OTT出错了,请检查部署和地址:{response=}" - raise Exception(msg) + err=response.text + break + try: + result = response.json() + except Exception: + err=config.transobj['notjson']+result.text + break + if "error" in result: - raise Exception(result['error']) + err=result['error'] + break result=result['translatedText'].strip().replace(''','"').replace('"',"'").split("\n") if inst and inst.precent < 75: inst.precent += round((i + 1) * 5 / len(split_source_text), 2) @@ -99,19 +103,26 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source result_length += 1 result = result[:source_length] target_text.extend(result) - iter_num=0 except Exception as e: - error = f'[error]OTT出错了,请检查部署和地址:{str(error)}' - err=error - index=i + err = f'请检查部署和地址:{str(e)}' break + else: + err='' + index=0 if i<=1 else i + iter_num=0 else: break + if err: + config.logger.error(f'[OTT]翻译请求失败:{err=}') + raise Exception(f'OTT:{err}') + if isinstance(text_list, str): return "\n".join(target_text) max_i = len(target_text) + if max_i < len(text_list) / 2: + raise Exception(f'OTT:{config.transobj["fanyicuowu2"]}') for i, it in enumerate(text_list): if i < max_i: text_list[i]['text'] = target_text[i] diff --git a/videotrans/translator/tencent.py b/videotrans/translator/tencent.py index e58c4bba..8a0a3db1 100644 --- a/videotrans/translator/tencent.py +++ b/videotrans/translator/tencent.py @@ -7,7 +7,7 @@ from videotrans.configure import config from videotrans.util import tools -def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=None): +def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=""): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -23,19 +23,17 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source iter_num = 0 # 当前循环次数,如果 大于 config.settings.retries 出错 err = "" while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing': - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing'): + return if iter_num >= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err = f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break iter_num += 1 if iter_num > 1: if set_p: tools.set_process( f"第{iter_num}次出错重试" if config.defaulelang == 'zh' else f'{iter_num} retries after error',btnkey=inst.btnkey if inst else "") - time.sleep(5) + time.sleep(10) # 整理待翻译的文字为 List[str] if isinstance(text_list, str): source_text = text_list.strip().split("\n") @@ -58,8 +56,8 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source client = tmt_client.TmtClient(cred, "ap-beijing", clientProfile) for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing': - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing'): + return if i < index: continue if stop>0: @@ -74,10 +72,12 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source "Target": target_language, "ProjectId": 0 } + config.logger.info(f'[腾讯]请求数据:{params=}') req.from_json_string(json.dumps(params)) # 返回的resp是一个TextTranslateResponse的实例,与请求对象对应 resp = client.TextTranslate(req) - result = resp.TargetText.strip().replace(''','"').replace('"',"'").split("\n")#json.loads(resp.TargetText) + config.logger.info(f'[腾讯]返回:{resp.TargetText=}') + result = resp.TargetText.strip().replace(''','"').replace('"',"'").split("\n") if inst and inst.precent < 75: inst.precent += round((i + 1) * 5 / len(split_source_text), 2) if set_p: @@ -91,20 +91,27 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source result_length += 1 result = result[:source_length] target_text.extend(result) - iter_num=0 + except Exception as e: - error = str(e) - config.logger.error(f"tencent api error:{error}" ) - err=error - index=i + err = str(e) break + else: + # 未出错 + err='' + iter_num=0 + index=0 if i<=1 else i else: break + if err: + config.logger.error(f'[腾讯翻译]翻译请求失败:{err=}') + raise Exception(f'腾讯翻译:{err}') if isinstance(text_list, str): return "\n".join(target_text) max_i = len(target_text) + if max_i < len(text_list) / 2: + raise Exception(f'腾讯翻译:翻译出错数量超过一半,请检查') for i, it in enumerate(text_list): if i < max_i: text_list[i]['text'] = target_text[i] diff --git a/videotrans/translator/transapi.py b/videotrans/translator/transapi.py index 7c6252d8..ef52b961 100644 --- a/videotrans/translator/transapi.py +++ b/videotrans/translator/transapi.py @@ -8,7 +8,7 @@ from videotrans.util import tools -def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code=None,is_test=False): +def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source_code="",is_test=False): """ text_list: 可能是多行字符串,也可能是格式化后的字幕对象数组 @@ -19,6 +19,8 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source """ # 翻译后的文本 url=config.params['trans_api_url'].strip().rstrip('/').lower() + if not url: + raise Exception(f'Please input your api') if not url.startswith('http'): url=f"http://{url}" if url.find('?')>0: @@ -39,13 +41,11 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source iter_num = 0 # 当前循环次数,如果 大于 config.settings.retries 出错 err = "" while 1: - if config.exit_soft: - return False - if config.current_status!='ing' and config.box_trans!='ing' and not is_test: - break + if config.exit_soft or (config.current_status!='ing' and config.box_trans!='ing' and not is_test): + return if iter_num >= config.settings['retries']: - raise Exception( - f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}') + err =f'{iter_num}{"次重试后依然出错" if config.defaulelang == "zh" else " retries after error persists "}:{err}' + break iter_num += 1 if iter_num > 1: if set_p: @@ -63,8 +63,8 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source split_source_text = [source_text[i:i + split_size] for i in range(0, len(source_text), split_size)] response=None for i,it in enumerate(split_source_text): - if config.current_status != 'ing' and config.box_trans != 'ing' and not is_test: - break + if config.exit_soft or (config.current_status != 'ing' and config.box_trans != 'ing' and not is_test): + return if i < index: continue if stop>0: @@ -77,20 +77,26 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source "source_language": 'zh' if source_code.startswith('zh') else source_code, "target_language": 'zh' if target_language.startswith('zh') else target_language } - config.logger.info(f'data,{i=}, {data}') + requrl=f"{url}target_language={data['target_language']}&source_language={data['source_language']}&text={data['text']}&secret={data['secret']}" + config.logger.info(f'[TransAPI]请求数据:{requrl=}') - response = requests.get(url=f"{url}target_language={data['target_language']}&source_language={data['source_language']}&text={data['text']}&secret={data['secret']}",proxies=proxies) + response = requests.get(url=requrl,proxies=proxies) + config.logger.info(f'[TransAPI]返回:{response.text=}') if response.status_code!=200: - raise Exception(f'code={response.status_code},{response.text}') + err=f'code={response.status_code=},{response.text}' + break try: result = response.json() - if result["code"]!=0: - raise result['msg'] except Exception as e: - raise Exception(f'{str(e)}') + err=config.transobj['notjson']+response.text + break + if result["code"]!=0: + err=result['msg'] + break result=result['text'].strip().replace(''','"').replace('"',"'") if not result: - raise Exception(f'{response.text=}') + err=f'{response.text=}' + break config.logger.info(f'result,{i=}, {result=}') if inst and inst.precent < 75: @@ -102,20 +108,29 @@ def trans(text_list, target_language="en", *, set_p=True,inst=None,stop=0,source tools.set_process(result+"\n\n", func_name="set_fanyi") target_text.append(result) - iter_num=0 + except Exception as e: - error = str(e) - config.logger.info(f'Transapi {error}') - err=error - index=i + err = str(e) break + else: + # 未出错 + err='' + iter_num=0 + index=0 if i<=1 else i else: break + if err: + config.logger.error(f'[TransAPI]翻译请求失败:{err=}') + raise Exception(f'Trans_API:{err}') + if isinstance(text_list, str): return "\n".join(target_text) max_i = len(target_text) + if max_i < len(text_list) / 2: + raise Exception(f'Trans_API:{config.transobj["fanyicuowu2"]}') + for i, it in enumerate(text_list): if i < max_i: text_list[i]['text'] = target_text[i] diff --git a/videotrans/util/tools.py b/videotrans/util/tools.py index 7867e127..92733975 100644 --- a/videotrans/util/tools.py +++ b/videotrans/util/tools.py @@ -368,7 +368,7 @@ def split_novoice_byraw(source_mp4, novoice_mp4, noextname, lib="copy"): # 从原始视频中分离出音频 cuda + h264_cuvid -def split_audio_byraw(source_mp4, targe_audio, is_separate=False): +def split_audio_byraw(source_mp4, targe_audio, is_separate=False,btnkey=None): cmd = [ "-y", "-i", @@ -405,7 +405,7 @@ def split_audio_byraw(source_mp4, targe_audio, is_separate=False): if not vail_file(vocal_file): set_process(config.transobj['Separating vocals and background music, which may take a longer time']) try: - st.start(audio=tmpfile, path=path) + st.start(audio=tmpfile, path=path,btnkey=btnkey) except Exception as e: msg = f"separate vocal and background music:{str(e)}" set_process(msg) @@ -702,6 +702,8 @@ def get_subtitle_from_srt(srtfile, *, is_file=True): it['end_time'] = end_time new_result.append(it) line += 1 + if len(new_result)<1: + raise Exception(config.transobj['zimuwenjianbuzhengque']) return new_result