【已提供解决方案】有个功能漏写了,实时转录的时候热词替换会起作用,但是将音视频文件拖动到客户端打开转录时,热词无效
Issue: 批量转录功能缺少热词替换
问题描述
在使用 CapsWriter-Offline 时发现,热词替换功能在实时转录时正常工作,但在批量转录音视频文件时不起作用。
原因分析
通过代码分析发现:
- 实时转录时,
core_client.py中的main_mic()函数会调用update_hot_all()来加载热词词典 - 而批量转录时,
main_file()函数没有加载热词词典的步骤 - 虽然
client_transcribe.py中调用了hot_sub()函数,但由于热词词典为空,所以没有任何替换效果
解决方案
有两种修复方案:
- 修改源码(推荐):
在
core_client.py的main_file()函数开头添加热词加载:
async def main_file(files: List[Path]):
show_file_tips()
# 添加这行来加载热词
update_hot_all()
for file in files:
# ...其他代码不变
- 使用外置程序: 对于无法修改 core_client.exe 的用户,可以编写一个独立的脚本,在转录完成后手动应用热词替换。将以下代码保存到capswriter软件目录下
import sys
from pathlib import Path
import re
from util.client_hot_update import update_hot_all
from util.client_hot_sub import hot_sub
from util.client_cosmic import console
import srt_from_txt
def apply_hot_sub(file: Path):
"""对已转录的文件应用热词替换"""
# 检查文件是否存在
if not file.exists():
console.print(f'文件不存在:{file}')
return
# 更新热词词典
update_hot_all()
# 读取原始文件
merge_file = file.with_suffix('.merge.txt')
if not merge_file.exists():
console.print(f'找不到合并文本文件:{merge_file}')
return
with open(merge_file, 'r', encoding='utf-8') as f:
text = f.read()
# 应用热词替换
text_new = hot_sub(text)
# 生成分行版本
text_split = re.sub('[,。?]', '\n', text_new)
# 保存结果
with open(merge_file, 'w', encoding='utf-8') as f:
f.write(text_new)
txt_file = file.with_suffix('.txt')
with open(txt_file, 'w', encoding='utf-8') as f:
f.write(text_split)
# 重新生成srt
srt_from_txt.one_task(txt_file)
console.print(f'已完成热词替换并更新文件:\n{merge_file}\n{txt_file}\n{file.with_suffix(".srt")}')
if __name__ == '__main__':
if len(sys.argv) < 2:
print('用法: python apply_hot_sub.py <文件路径>')
sys.exit(1)
file = Path(sys.argv[1])
apply_hot_sub(file)
建议
- 在下一版本更新中添加热词加载步骤
- 在文档中说明这个限制
- 可以考虑将热词加载功能模块化,确保两种转录模式都能正确初始化
因为无法正常运行源码的客户端(老是莫名其妙显示有库缺失),自行重新打包的exe也无法正常运行,只好出此下策,贵在简单可行
谢谢大佬,但方法1无效啊,热词列表是成功导入了,但热词替换仍然没有生效
同楼上@hehe854 ,我也发现拖音频视频文件到client端无法使用热词替换功能 我一开始也以为方法1就够了,实际上还是无效的,update_hot_all()的功能仅为更新热词, 真正起到替换热词的代码是
# 热词替换
text = hot_sub(text)
可以在recv_result看到这一串。
问题就是把它加在哪里了。 因为txt、srt字幕都要替换热词才是, 所以我修改的位置在转录的py脚本处理这一部分,也就是这个路径的文件 util\client_transcribe.py 开头添加
from util.client_hot_sub import hot_sub
如果要实时更新热词,再加
from util.client_hot_update import update_hot_all, observe_hot
然后就是
async def transcribe_recv(file: Path):
# 获取连接
websocket = Cosmic.websocket
# 接收结果
async for message in websocket:
message = json.loads(message)
console.print(f' 转录进度: {message["duration"]:.2f}s', end='\r')
if message['is_final']:
break
update_hot_all() # 更新热词 ←加进去
observer = observe_hot() # 实时更新热词 ←加进去
# 解析结果
text_merge = message['text']
text_merge = hot_sub(text_merge) # 热词替换 ←加进去
text_split = re.sub('[,。?]', '\n', text_merge)
timestamps = message['timestamps']
tokens = message['tokens']
然后就可以看到替换过的文稿了!!!
@HaujetZhao 希望作者大大能把热词替换方案发扬广大!强无敌!专业术语密集的音频、视频真的很需要这个东西 而且用大模型做文本纠错根本既贵又臃肿又慢啊()
同楼上@hehe854 ,我也发现拖音频视频文件到client端无法使用热词替换功能 我一开始也以为方法1就够了,实际上还是无效的,update_hot_all()的功能仅为更新热词, 真正起到替换热词的代码是
> # 热词替换
> text = hot_sub(text)
可以在recv_result看到这一串。
问题就是把它加在哪里了。 因为txt、srt字幕都要替换热词才是, 所以我修改的位置在转录的py脚本处理这一部分,也就是这个路径的文件 util\client_transcribe.py 开头添加
from util.client_hot_sub import hot_sub 如果要实时更新热词,再加
from util.client_hot_update import update_hot_all, observe_hot 然后就是
> async def transcribe_recv(file: Path):
>
> # 获取连接
> websocket = Cosmic.websocket
> # 接收结果
> async for message in websocket:
> message = json.loads(message)
> console.print(f' 转录进度: {message["duration"]:.2f}s', end='\r')
> if message['is_final']:
> break
> update_hot_all() # 更新热词 ←加进去
> observer = observe_hot() # 实时更新热词 ←加进去
> # 解析结果
> text_merge = message['text']
> text_merge = hot_sub(text_merge) # 热词替换 ←加进去
> text_split = re.sub('[,。?]', '\n', text_merge)
> timestamps = message['timestamps']
> tokens = message['tokens']
然后就可以看到替换过的文稿了!!!
@HaujetZhao 希望作者大大能把热词替换方案发扬广大!强无敌!专业术语密集的音频、视频真的很需要这个东西 而且用大模型做文本纠错根本既贵又臃肿又慢啊()
成功了!非常感谢!@naruhodo-cc
发现一个新问题,在config.py中,无论是“声调 = False”还是“声调 = True”,都会忽略声调的区别,导致在这两种情况下,「黄章」都会匹配「慌张」,也就是声调区别是不生效的。
不知道大佬有没有遇到? @naruhodo-cc