Skip to content

Commit

Permalink
Feat: add Claude AI & LibreTranslate
Browse files Browse the repository at this point in the history
  • Loading branch information
jianchang512 committed Nov 3, 2024
1 parent d33f4a8 commit 71fa657
Show file tree
Hide file tree
Showing 25 changed files with 750 additions and 35 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ deepgram-sdk
deepgram-captions
funasr
modelscope
anthropic
samplerate
4 changes: 2 additions & 2 deletions videotrans/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-

VERSION = "v2.98"
VERSION_NUM = 120098
VERSION = "v3.00"
VERSION_NUM = 120300
22 changes: 22 additions & 0 deletions videotrans/claude-en.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Please translate the original text in <source> literally to {lang}, and then output only the translated text without adding any notes or leading words.

**Format Requirements:**
- Translate the original text line by line and generate the translation corresponding to that line, making sure that each word in the original line and the translated line corresponds to each other.
- If there are several lines of original text, several lines of translation must be generated.

**Content requirements:**
- Translations must be concise and short, avoiding long sentences.
- If the original text cannot be translated, please return it as it is, without adding any hints such as “meaningless statement or untranslatable”.
- Only the translated text should be output, not the original.

**Execution details:**
- If a line is very short in the original text, it should be retained after translation and not merged with the previous or next line.
- The characters corresponding to the characters in the translation at the line breaks in the original text must also be line breaks.
- Translate strictly literally, without interpreting or answering the content of the original text.

**End goal:**
- Provide high-quality translations that are formatted exactly like the original.

<source>[TEXT]</source>

Translation:
23 changes: 23 additions & 0 deletions videotrans/claude.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
请将<source>中的原文内容按字面意思翻译到{lang},然后只输出译文,不要添加任何说明或引导词。

**格式要求:**
- 按行翻译原文,并生成该行对应的译文,确保原文行和译文行中的每个单词相互对应。
- 有几行原文,必须生成几行译文。

**内容要求:**
- 翻译必须精简短小,避免长句。
- 如果原文无法翻译,请返回空行,不得添加“无意义语句或不可翻译”等任何提示语。
- 只输出译文即可,禁止输出任何原文。

**执行细节:**
- 如果某行原文很短,在翻译后也仍然要保留该行,不得与上一行或下一行合并。
- 原文换行处字符相对应的译文字符也必须换行。
- 严格按照字面意思翻译,不要解释或回答原文内容。

**最终目标:**
- 提供格式与原文完全一致的高质量翻译结果。

<source>[TEXT]</source>

译文:

6 changes: 4 additions & 2 deletions videotrans/component/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
HebingsrtForm, DoubaoForm, FishTTSForm, CosyVoiceForm, AI302Form, AI302TTSForm, SetINIForm, WatermarkForm, \
GetaudioForm, HunliuForm, VASForm, Fanyisrt, Recognform, Peiyinform, Videoandaudioform, Videoandsrtform, \
OpenAITTSForm, RecognAPIForm, OpenaiRecognAPIForm, DownloadModelForm, FormatcoverForm, SubtitlescoverForm, \
SubtitleEditer,SttAPIForm,VolcEngineTTSForm,F5TTSForm,DeepgramForm
SubtitleEditer,SttAPIForm,VolcEngineTTSForm,F5TTSForm,DeepgramForm,ClaudeForm,LibreForm

__all__ = [
"BaiduForm",
Expand Down Expand Up @@ -55,5 +55,7 @@
"SttAPIForm",
"VolcEngineTTSForm",
"F5TTSForm",
"DeepgramForm"
"DeepgramForm",
"ClaudeForm",
"LibreForm"
]
13 changes: 13 additions & 0 deletions videotrans/component/set_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from videotrans.ui.baidu import Ui_baiduform
from videotrans.ui.chatgpt import Ui_chatgptform
from videotrans.ui.chattts import Ui_chatttsform
from videotrans.ui.claude import Ui_claudeform
from videotrans.ui.clone import Ui_cloneform
from videotrans.ui.cosyvoice import Ui_cosyvoiceform
from videotrans.ui.deepgram import Ui_deepgramform
Expand All @@ -28,6 +29,7 @@
from videotrans.ui.gptsovits import Ui_gptsovitsform
from videotrans.ui.hunliu import Ui_hunliu
from videotrans.ui.info import Ui_infoform
from videotrans.ui.libretranslate import Ui_libretranslateform
from videotrans.ui.localllm import Ui_localllmform
from videotrans.ui.openairecognapi import Ui_openairecognapiform
from videotrans.ui.openaitts import Ui_openaittsform
Expand Down Expand Up @@ -142,6 +144,17 @@ def __init__(self, parent=None):
self.setupUi(self)
self.setWindowIcon(QIcon(f"{config.ROOT_DIR}/videotrans/styles/icon.ico"))

class ClaudeForm(QDialog, Ui_claudeform): # <===
def __init__(self, parent=None):
super(ClaudeForm, self).__init__(parent)
self.setupUi(self)
self.setWindowIcon(QIcon(f"{config.ROOT_DIR}/videotrans/styles/icon.ico"))
class LibreForm(QDialog, Ui_libretranslateform): # <===
def __init__(self, parent=None):
super(LibreForm, self).__init__(parent)
self.setupUi(self)
self.setWindowIcon(QIcon(f"{config.ROOT_DIR}/videotrans/styles/icon.ico"))


class TransapiForm(QDialog, Ui_transapiform): # <===
def __init__(self, parent=None):
Expand Down
11 changes: 11 additions & 0 deletions videotrans/configure/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ def parse_init():
"openaitts_model": "tts-1,tts-1-hd",
"openairecognapi_model": "whisper-1",
"chatgpt_model": "gpt-4o-mini,gpt-4o,gpt-4,gpt-4-turbo,gpt-4-turbo-preview,qwen,moonshot-v1-8k,deepseek-chat",
"claude_model":"claude-3-5-sonnet-latest,claude-3-5-sonnet-20241022,claude-3-opus-latest,claude-3-sonnet-20240229,claude-3-haiku-20240307",
"azure_model": "gpt-4o,gpt-4,gpt-35-turbo",
"localllm_model": "qwen:7b,qwen:1.8b-chat-v1.5-q2_k,moonshot-v1-8k,deepseek-chat",
"zijiehuoshan_model": "",
Expand Down Expand Up @@ -425,11 +426,14 @@ def parse_init():

ChatTTS_voicelist = re.split(r'[,,]', settings['chattts_voice'])
_chatgpt_model_list = [it.strip() for it in settings['chatgpt_model'].split(',') if it.strip()]
_claude_model_list = [it.strip() for it in settings['claude_model'].split(',') if it.strip()]
_azure_model_list = [it.strip() for it in settings['azure_model'].split(',') if it.strip()]
_localllm_model_list = [it.strip() for it in settings['localllm_model'].split(',') if it.strip()]
_zijiehuoshan_model_list = [it.strip() for it in settings['zijiehuoshan_model'].split(',') if it.strip()]
if len(_chatgpt_model_list) < 1:
_chatgpt_model_list = ['']
if len(_claude_model_list) < 1:
_claude_model_list = ['']
if len(_localllm_model_list) < 1:
_localllm_model_list = ['']
if len(_zijiehuoshan_model_list) < 1:
Expand Down Expand Up @@ -582,6 +586,8 @@ def getset_params(obj=None):

"deeplx_address": "",
"deeplx_key": "",
"libre_address": "",
"libre_key": "",

"ott_address": "",

Expand All @@ -597,6 +603,11 @@ def getset_params(obj=None):
"chatgpt_model": _chatgpt_model_list[0],
"chatgpt_template": "",

"claude_api": "",
"claude_key": "",
"claude_model": _claude_model_list[0],
"claude_template": "",

"azure_api": "",
"azure_key": "",
"azure_version": "2024-06-01",
Expand Down
5 changes: 2 additions & 3 deletions videotrans/mainwin/_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,6 @@ def set_translate_type(self, idx):
def recogn_type_change(self):
recogn_type= self.main.recogn_type.currentIndex()

lang = translator.get_code(show_text=self.main.source_language.currentText())
is_allow_lang = recognition.is_allow_lang(langcode=lang, recogn_type=recogn_type,model_name=self.main.model_name.currentText())

# 判断不是 faster,禁用分割模式、隐藏vad参数和均等分割设置
if recogn_type!=recognition.FASTER_WHISPER:
self.main.split_type.setDisabled(True)
Expand Down Expand Up @@ -152,6 +149,8 @@ def recogn_type_change(self):
self.main.model_name.addItems(config.DEEPGRAM_MODEL)
else:
self.main.model_name.addItems(config.FUNASR_MODEL)
lang = translator.get_code(show_text=self.main.source_language.currentText())
is_allow_lang = recognition.is_allow_lang(langcode=lang, recogn_type=recogn_type,model_name=self.main.model_name.currentText())
if is_allow_lang is not True:
QMessageBox.critical(self.main, config.transobj['anerror'], is_allow_lang)
return
Expand Down
2 changes: 2 additions & 0 deletions videotrans/mainwin/_main_win.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ def start_subform(self):
self.actiongemini_key.triggered.connect(winform.gemini.openwin)
self.actiontencent_key.triggered.connect(winform.tencent.openwin)
self.actionchatgpt_key.triggered.connect(winform.chatgpt.openwin)
self.actionclaude_key.triggered.connect(winform.claude.openwin)
self.actionlibretranslate_key.triggered.connect(winform.libre.openwin)

self.actionai302_key.triggered.connect(winform.ai302.openwin)
self.actionlocalllm_key.triggered.connect(winform.localllm.openwin)
Expand Down
13 changes: 13 additions & 0 deletions videotrans/prompts/srt/claude-en.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Please translate the content of srt subtitle format in <source> to {lang}, and then output only the translated text without adding any description or guide words:

**Note the following requirements:**
1. **Translate **subtitle text content only, do not translate subtitle line numbers and timestamps.
2. **Must ensure that **the translated translation format is a valid srt subtitle.
3. **Must ensure that the number of **translated subtitles is exactly the same as the original subtitles, and that each subtitle corresponds to one of the original subtitles.
4. **Keep the timestamps as they are** and translate only the content of the subtitles.
5. If you can't translate the subtitle, you can return the original text directly without reporting any error.


<source>[TEXT]</source>

Translation:
13 changes: 13 additions & 0 deletions videotrans/prompts/srt/claude.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
请将<source>中的srt字幕格式内容翻译到{lang},然后只输出译文,不要添加任何说明或引导词:

**注意以下要求:**
1. **只翻译**字幕文本内容,不翻译字幕的行号和时间戳。
2. **必须保证**翻译后的译文格式为有效的 srt字幕。
3. **确保**翻译后的字幕数量和原始字幕完全一致,每一条字幕对应原始字幕中的一条。
4. **保持时间戳的原样**,只翻译字幕文本内容。
5. 如果遇到无法翻译的情况,直接将原文本内容返回,不要报错,不要道歉。


<source>[TEXT]</source>

译文:
10 changes: 6 additions & 4 deletions videotrans/recognition/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@
def is_allow_lang(langcode: str = None, recogn_type: int = None,model_name=None):
if langcode=='auto' and recogn_type not in [FASTER_WHISPER,OPENAI_WHISPER]:
return '仅在 faster-whisper和 openai-whisper模式下允许检测语言' if config.defaulelang=='zh' else 'Recognition language is only supported in faster-whisper and openai-whisper modes.'
if recogn_type == FUNASR_CN and langcode[:2] !='zh':
return 'FunASR 下 paraformer-zh 和 SenseVoiceSmall 模型仅支持中文语音识别' if config.defaulelang == 'zh' else 'paraformer-zh and SenseVoiceSmall models only support Chinese speech recognition'
if recogn_type == FUNASR_CN:
if model_name=='paraformer-zh' and langcode[:2] !='zh':
return 'FunASR 下 paraformer-zh 模型仅支持中文语音识别' if config.defaulelang == 'zh' else 'paraformer-zh models only support Chinese speech recognition'
if model_name =='SenseVoiceSmall' and langcode[:2] not in ['zh','en','ja','ko']:
return 'FunASR 下 SenseVoiceSmall 模型仅支持中英日韩语音识别' if config.defaulelang == 'zh' else 'SenseVoiceSmall models only support Chinese,Ja,ko,English speech recognition'
return True

if recogn_type == DOUBAO_API and langcode[:2] not in ["zh", "en", "ja", "ko", "es", "fr", "ru"]:
return '豆包语音识别仅支持中英日韩法俄西班牙语言,其他不支持'


return True

# 判断 openai whisper和 faster whisper 模型是否存在
Expand Down
2 changes: 1 addition & 1 deletion videotrans/recognition/_funasr.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def _exec1(self) -> Union[List[Dict], None]:

model = AutoModel(
model="iic/SenseVoiceSmall",
punc_model="ct-punc-c",
punc_model="ct-punc",
disable_update=True,
device=self.device,
local_dir=config.ROOT_DIR + "/models",
Expand Down
28 changes: 25 additions & 3 deletions videotrans/translator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
GEMINI_INDEX = 12
TRANSAPI_INDEX = 13
FREEGOOGLE_INDEX = 14
CLAUDE_INDEX = 15
LIBRE_INDEX = 16
# 翻译通道名字列表,显示在界面
TRANSLASTE_NAME_LIST = [
"Google翻译" if config.defaulelang == 'zh' else 'Google',
Expand All @@ -39,7 +41,9 @@
"AzureAI GPT",
"Gemini",
"自定义翻译API" if config.defaulelang == 'zh' else 'Customized API',
"FreeGoogle翻译" if config.defaulelang == 'zh' else 'Free Google'
"FreeGoogle翻译" if config.defaulelang == 'zh' else 'Free Google',
"Claude API",
"LibreTranslate"
]
# subtitles language code https://zh.wikipedia.org/wiki/ISO_639-2 https://www.loc.gov/standards/iso639-2/php/code_list.php
# 腾讯翻译 https://cloud.tencent.com/document/api/551/15619
Expand Down Expand Up @@ -354,7 +358,7 @@ def get_source_target_code(*, show_source=None, show_target=None, translate_type
elif translate_type == TENCENT_INDEX:
return (source_list[4] if source_list else "-", target_list[4] if target_list else "-")
elif translate_type in [CHATGPT_INDEX, AZUREGPT_INDEX, GEMINI_INDEX,
LOCALLLM_INDEX, ZIJIE_INDEX, AI302_INDEX]:
LOCALLLM_INDEX, ZIJIE_INDEX, AI302_INDEX,CLAUDE_INDEX]:
return (source_list[7] if source_list else "-", target_list[7] if target_list else "-")
elif translate_type == OTT_INDEX:
return (source_list[5] if source_list else "-", target_list[5] if target_list else "-")
Expand Down Expand Up @@ -385,6 +389,12 @@ def is_allow_translate(*, translate_type=None, show_target=None, only_key=False,
from videotrans.winform import ai302
ai302.openwin()
return False
if translate_type == CLAUDE_INDEX and not config.params['claude_key']:
if return_str:
return "Please configure the api and key information of the Claude API channel first."
from videotrans.winform import claude
claude.openwin()
return False
if translate_type == TRANSAPI_INDEX and not config.params['trans_api_url']:
if return_str:
return "Please configure the api and key information of the Trans_API channel first."
Expand Down Expand Up @@ -446,6 +456,12 @@ def is_allow_translate(*, translate_type=None, show_target=None, only_key=False,
from videotrans.winform import deepLX
deepLX.openwin()
return False
if translate_type == LIBRE_INDEX and not config.params["libre_address"]:
if return_str:
return "Please configure the api and key information of the LibreTranslate channel first."
from videotrans.winform import libre
libre.openwin()
return False

if translate_type == TRANSAPI_INDEX and not config.params["trans_api_url"]:
if return_str:
Expand Down Expand Up @@ -518,7 +534,7 @@ def run(*, translate_type=None,
# 其他渠道下是语言代码
# source_code是原语言代码
target_language_name=target_code
if translate_type in [GEMINI_INDEX, AZUREGPT_INDEX,CHATGPT_INDEX,AI302_INDEX,LOCALLLM_INDEX,ZIJIE_INDEX]:
if translate_type in [GEMINI_INDEX, AZUREGPT_INDEX,CHATGPT_INDEX,AI302_INDEX,LOCALLLM_INDEX,ZIJIE_INDEX,CLAUDE_INDEX]:
_, target_language_name = get_source_target_code(show_target=target_code, translate_type=translate_type)
kwargs = {
"text_list": text_list,
Expand Down Expand Up @@ -588,5 +604,11 @@ def run(*, translate_type=None,
if translate_type == GEMINI_INDEX:
from videotrans.translator._gemini import Gemini
return Gemini(**kwargs).run()
if translate_type == CLAUDE_INDEX:
from videotrans.translator._claude import Claude
return Claude(**kwargs).run()
if translate_type == LIBRE_INDEX:
from videotrans.translator._libre import Libre
return Libre(**kwargs).run()

raise Exception('No translation channel')
36 changes: 27 additions & 9 deletions videotrans/translator/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def __init__(self,
self.is_test = is_test
#
self.error = ""
self.error_code=0
# 同时翻译字幕条数
self.trans_thread = int(config.settings.get('trans_thread', 5))
# 出错重试次数
Expand Down Expand Up @@ -95,10 +96,16 @@ def run(self) -> Union[List, str, None]:

self.iter_num += 1
if self.iter_num > 1:
self._signal(
text=f"第{self.iter_num}次出错,10s后重试," if config.defaulelang == 'zh' else f'{self.iter_num} retries occurs,10s later retry')
time.sleep(10)
continue
if self.error_code==429:
msg='429 超出api每分钟频率限制,暂停60s后重试' if config.defaulelang=='zh' else '429 Exceeded the frequency limit of the api per minute, pause for 60s and retry'
self._signal(text=msg)
if self.inst and self.inst.status_text:
self.inst.status_text=msg
time.sleep(60)
else:
self._signal(
text=f"第{self.iter_num}次出错,{self.wait_sec}s后重试," if config.defaulelang == 'zh' else f'{self.iter_num} retries occurs, {self.wait_sec}s later retry')
time.sleep(self.wait_sec)

try:
result = self._get_cache(it)
Expand Down Expand Up @@ -151,11 +158,13 @@ def run(self) -> Union[List, str, None]:
except Exception as e:
self.error = f'{e}'
config.logger.exception(e, exc_info=True)
time.sleep(self.wait_sec)
else:
# 成功 未出错
self.error = ''
self.error_code=0
self.iter_num = 0
if self.inst and self.inst.status_text:
self.inst.status_text='字幕翻译中' if config.defaulelang=='zh' else 'Translation of subtitles'
finally:
time.sleep(self.wait_sec)
if self.iter_num == 0:
Expand Down Expand Up @@ -197,10 +206,16 @@ def runsrt(self):

self.iter_num += 1
if self.iter_num > 1:
self._signal(
text=f"第{self.iter_num}次出错重试" if config.defaulelang == 'zh' else f'{self.iter_num} retries after error')
time.sleep(10)
continue
if self.error_code==429:
msg='429 超出api每分钟频率限制,暂停60s后重试' if config.defaulelang=='zh' else '429 Exceeded the frequency limit of the api per minute, pause for 60s and retry'
self._signal(text=msg)
if self.inst and self.inst.status_text:
self.inst.status_text=msg
time.sleep(60)
else:
self._signal(
text=f"第{self.iter_num}次出错,{self.wait_sec} s后重试," if config.defaulelang == 'zh' else f'{self.iter_num} retries occurs, {self.wait_sec}s later retry')
time.sleep(self.wait_sec)

try:
srt_str = "\n\n".join(
Expand Down Expand Up @@ -229,7 +244,10 @@ def runsrt(self):
else:
# 成功 未出错
self.error = ''
self.error_code=0
self.iter_num = 0
if self.inst and self.inst.status_text:
self.inst.status_text='字幕翻译中' if config.defaulelang=='zh' else 'Translation of subtitles'
finally:
time.sleep(self.wait_sec)
if self.iter_num == 0:
Expand Down
Loading

0 comments on commit 71fa657

Please sign in to comment.