Commit 464b8e26 authored by smile2019's avatar smile2019

Merge remote-tracking branch 'refs/remotes/origin/feat_1' into feat_1

parents 72383c7f 7db705f9
...@@ -9,4 +9,8 @@ dist ...@@ -9,4 +9,8 @@ dist
build build
log log
product_test product_test
res/ffmpeg-4.3.1/bin/output.mp4
res/ffmpeg-4.3.1/bin/qiji_local.mp4
venv/
venv37/
shenming_test shenming_test
\ No newline at end of file
...@@ -78,7 +78,8 @@ def predict_long_audio_with_paddle(wav_path, pre_time, book_name, sheet_name, st ...@@ -78,7 +78,8 @@ def predict_long_audio_with_paddle(wav_path, pre_time, book_name, sheet_name, st
(time_stamps[i][0] + pre_time) * normal_speed) (time_stamps[i][0] + pre_time) * normal_speed)
print("插入旁白,推荐字数为%d" % recommend_lens) print("插入旁白,推荐字数为%d" % recommend_lens)
# narratages.append(["", "", "", "插入旁白,推荐字数为%d" % recommend_lens]) # narratages.append(["", "", "", "插入旁白,推荐字数为%d" % recommend_lens])
write_to_sheet(book_name, sheet_name, ["", "", "", "插入旁白,推荐字数为%d" % recommend_lens]) # write_to_sheet(book_name, sheet_name, ["", "", "", "插入旁白,推荐字数为%d" % recommend_lens])
write_to_sheet(book_name, sheet_name, ["", "", "", "%d" % recommend_lens])
# narratages.append([round(time_stamps[i][0] + pre_time, 2), round(time_stamps[i][1] + pre_time, 2), # narratages.append([round(time_stamps[i][0] + pre_time, 2), round(time_stamps[i][1] + pre_time, 2),
# text, '']) # text, ''])
write_to_sheet(book_name, sheet_name, write_to_sheet(book_name, sheet_name,
......
This diff is collapsed.
...@@ -16,14 +16,23 @@ from prompt_dialog import Prompt_Dialog ...@@ -16,14 +16,23 @@ from prompt_dialog import Prompt_Dialog
class Create_Dialog(QDialog, Ui_Dialog): class Create_Dialog(QDialog, Ui_Dialog):
init_project_signal = pyqtSignal(str) init_project_signal = pyqtSignal(str)
def __init__(self): def __init__(self, mainWindow):
super(Create_Dialog, self).__init__() super(Create_Dialog, self).__init__()
self.mainWindow = mainWindow
self.setupUi(self) self.setupUi(self)
self.setWindowTitle("新建工程") self.setWindowTitle("新建工程")
self.get_dir.clicked.connect(self.choose_root) self.get_dir.clicked.connect(self.choose_root)
self.confirm.clicked.connect(self.create_project) self.confirm.clicked.connect(self.create_project)
self.get_video_dir.clicked.connect(self.choose_video)
self.prompt_dialog = Prompt_Dialog() self.prompt_dialog = Prompt_Dialog()
self.cancel.clicked.connect(self.close_dialog) self.cancel.clicked.connect(self.close_dialog)
self.video_path = None
def choose_video(self):
path = QFileDialog.getOpenFileUrl(self, "选择待导入视频", QUrl(
os.getcwd()), "Video Files(*.mp4 *.rmvb *mkv *avi *.);; 所有文件(*.*)")[0]
self.video_input.setText(path.path()[1:])
self.video_path = path
def choose_root(self): def choose_root(self):
"""选择存放新工程的文件夹 """选择存放新工程的文件夹
...@@ -54,6 +63,7 @@ class Create_Dialog(QDialog, Ui_Dialog): ...@@ -54,6 +63,7 @@ class Create_Dialog(QDialog, Ui_Dialog):
self.prompt_dialog.show_with_msg("请输入工程名称") self.prompt_dialog.show_with_msg("请输入工程名称")
else: else:
self.prompt_dialog.show_with_msg("请输入合法文件夹路径") self.prompt_dialog.show_with_msg("请输入合法文件夹路径")
self.mainWindow.play_video(self.video_path)
def close_dialog(self): def close_dialog(self):
"""关闭窗口 """关闭窗口
......
...@@ -29,6 +29,13 @@ class Ui_Dialog(object): ...@@ -29,6 +29,13 @@ class Ui_Dialog(object):
self.get_dir.setObjectName("get_dir") self.get_dir.setObjectName("get_dir")
self.gridLayout.addWidget(self.get_dir, 0, 2, 1, 1) self.gridLayout.addWidget(self.get_dir, 0, 2, 1, 1)
self.video_input = QtWidgets.QLineEdit(Dialog)
self.video_input.setObjectName("video_input")
self.gridLayout.addWidget(self.video_input, 2, 1, 1, 1)
self.get_video_dir = QtWidgets.QPushButton(Dialog)
self.get_video_dir.setObjectName("get_video_dir")
self.gridLayout.addWidget(self.get_video_dir, 2, 2, 1, 1)
self.rootLabel = QtWidgets.QLabel(Dialog) self.rootLabel = QtWidgets.QLabel(Dialog)
self.rootLabel.setObjectName("rootLabel") self.rootLabel.setObjectName("rootLabel")
self.gridLayout.addWidget(self.rootLabel, 0, 0, 1, 1) self.gridLayout.addWidget(self.rootLabel, 0, 0, 1, 1)
...@@ -37,6 +44,10 @@ class Ui_Dialog(object): ...@@ -37,6 +44,10 @@ class Ui_Dialog(object):
self.nameLabel.setObjectName("nameLabel") self.nameLabel.setObjectName("nameLabel")
self.gridLayout.addWidget(self.nameLabel, 1, 0, 1, 1) self.gridLayout.addWidget(self.nameLabel, 1, 0, 1, 1)
self.videoPath = QtWidgets.QLabel(Dialog)
self.videoPath.setObjectName("videoPath")
self.gridLayout.addWidget(self.videoPath, 2, 0, 1, 1)
self.gridLayout.addWidget(self.name_input, 1, 1, 1, 1) self.gridLayout.addWidget(self.name_input, 1, 1, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1) self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout = QtWidgets.QHBoxLayout()
...@@ -68,6 +79,8 @@ class Ui_Dialog(object): ...@@ -68,6 +79,8 @@ class Ui_Dialog(object):
Dialog.setWindowTitle(_translate("Dialog", "Dialog")) Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.nameLabel.setText(_translate("Dialog", "工程名称")) self.nameLabel.setText(_translate("Dialog", "工程名称"))
self.rootLabel.setText(_translate("Dialog", "目标路径")) self.rootLabel.setText(_translate("Dialog", "目标路径"))
self.videoPath.setText(_translate("Dialog", "视频路径"))
self.get_dir.setText(_translate("Dialog", "打开文件夹")) self.get_dir.setText(_translate("Dialog", "打开文件夹"))
self.get_video_dir.setText(_translate("Dialog", "导入视频"))
self.confirm.setText(_translate("Dialog", "确认")) self.confirm.setText(_translate("Dialog", "确认"))
self.cancel.setText(_translate("Dialog", "取消")) self.cancel.setText(_translate("Dialog", "取消"))
@echo on @REM @echo on
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close) && exit @REM %1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close) && exit
cd /d %~dp0 cd /d %~dp0
IF EXIST "%PROGRAMFILES(X86)%" (GOTO 64BIT) ELSE (GOTO 32BIT) IF EXIST "%PROGRAMFILES(X86)%" (GOTO 64BIT) ELSE (GOTO 32BIT)
...@@ -16,6 +16,7 @@ GOTO END ...@@ -16,6 +16,7 @@ GOTO END
:END :END
c:
cd C:\LavFilters\ cd C:\LavFilters\
call install_audio.bat call install_audio.bat
call install_splitter.bat call install_splitter.bat
......
...@@ -98,7 +98,7 @@ def detect_with_asr(video_path: str, book_path: str, start_time=0, end_time=-1, ...@@ -98,7 +98,7 @@ def detect_with_asr(video_path: str, book_path: str, start_time=0, end_time=-1,
os.remove(book_path) os.remove(book_path)
book_name_xlsx = book_path book_name_xlsx = book_path
sheet_name_xlsx = "旁白插入位置建议" sheet_name_xlsx = "旁白插入位置建议"
table_head = [["起始时间", "终止时间", "字幕", '建议', '解说脚本']] table_head = [["起始时间", "终止时间", "字幕", '建议旁白字数', '解说脚本']]
create_sheet(book_name_xlsx, sheet_name_xlsx, table_head) create_sheet(book_name_xlsx, sheet_name_xlsx, table_head)
sys.path.append("PaddlePaddle_DeepSpeech2") sys.path.append("PaddlePaddle_DeepSpeech2")
......
This diff is collapsed.
{
"user_name":"盲文出版社",
"dd_url_prefix":"https://oapi.dingtalk.com/robot/send?access_token=a7e6b223bc0a6e4b5e3f64b1570d0c884db0d833592f5e84b020c2896130d659",
"secret":"SEC252452789bc17cfb1e6c973f837426fa0f9fd50c8793239c070e9d3c021d8109"
}
\ No newline at end of file
...@@ -9,13 +9,19 @@ import base64 ...@@ -9,13 +9,19 @@ import base64
import hashlib import hashlib
import urllib.parse import urllib.parse
user_name = "盲文出版社" with open("./ding_notify.conf", "r", encoding="utf-8") as f:
dd_url_prefix = "https://oapi.dingtalk.com/robot/send?access_token=a7e6b223bc0a6e4b5e3f64b1570d0c884db0d833592f5e84b020c2896130d659" json_obj = json.load(f)
# dd_url_prefix = "https://oapi.dingtalk.com/robot/send?access_token=12a5e64b24e7345fed2415c5c2f9101180763e327b21727cd35fdaa3fb274e74" # user_name = "盲文出版社"
secret = 'SEC252452789bc17cfb1e6c973f837426fa0f9fd50c8793239c070e9d3c021d8109' # dd_url_prefix = "https://oapi.dingtalk.com/robot/send?access_token=a7e6b223bc0a6e4b5e3f64b1570d0c884db0d833592f5e84b020c2896130d659"
# secret = "SECb5d68b27bd2e4694667d36c0f91336f3641b3287b945906a83997353f961d415" # # dd_url_prefix = "https://oapi.dingtalk.com/robot/send?access_token=12a5e64b24e7345fed2415c5c2f9101180763e327b21727cd35fdaa3fb274e74"
# secret = 'SEC252452789bc17cfb1e6c973f837426fa0f9fd50c8793239c070e9d3c021d8109'
# # secret = "SECb5d68b27bd2e4694667d36c0f91336f3641b3287b945906a83997353f961d415"
user_name = json_obj["user_name"]
dd_url_prefix = json_obj["dd_url_prefix"]
secret = json_obj["secret"]
def notify(err): def notify(err):
try:
timestamp = str(round(time.time() * 1000)) timestamp = str(round(time.time() * 1000))
secret_enc = secret.encode('utf-8') secret_enc = secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret) string_to_sign = '{}\n{}'.format(timestamp, secret)
...@@ -41,3 +47,6 @@ def notify(err): ...@@ -41,3 +47,6 @@ def notify(err):
r = requests.post(dd_url, json.dumps(d), headers=h) r = requests.post(dd_url, json.dumps(d), headers=h)
print(r.status_code) print(r.status_code)
print(r.text) print(r.text)
except Exception as e:
print("ding notify err")
print(e)
\ No newline at end of file
...@@ -4,6 +4,8 @@ import openpyxl ...@@ -4,6 +4,8 @@ import openpyxl
from management import Element from management import Element
from utils import reverse_time_to_seconds, get_seconds
def read_xls(file_path): def read_xls(file_path):
print("read_xls") print("read_xls")
elements = [] elements = []
...@@ -26,20 +28,20 @@ def read_xls(file_path): ...@@ -26,20 +28,20 @@ def read_xls(file_path):
cell_value = str(cell_value) if cell_value != None else "" cell_value = str(cell_value) if cell_value != None else ""
# print(cell_value) # print(cell_value)
if col_index == 0: if col_index == 0:
start_time = cell_value if cell_value != None else "" start_time = get_seconds(cell_value) if cell_value != None else ""
if col_index == 1:
end_time = get_seconds(cell_value) if cell_value != None else ""
if col_index == 2: if col_index == 2:
end_time = cell_value if cell_value != None else ""
if col_index == 4:
subtitle = cell_value if cell_value != None else "" subtitle = cell_value if cell_value != None else ""
if col_index == 5: if col_index == 3:
if cell_value == None or cell_value == "": if cell_value == None or cell_value == "":
break break
suggest = cell_value if cell_value != None else "" suggest = cell_value if cell_value != None else ""
if col_index == 6: if col_index == 4:
if cell_value == None or cell_value == "": if cell_value == None or cell_value == "":
break break
aside = cell_value if cell_value != None else "" aside = cell_value if cell_value != None else ""
if col_index == 7: if col_index == 5:
speed = cell_value if cell_value != None else "" speed = cell_value if cell_value != None else ""
col_index = col_index + 1 col_index = col_index + 1
if suggest != "" and aside != "": if suggest != "" and aside != "":
...@@ -71,33 +73,39 @@ def read_xlsx(file_path): ...@@ -71,33 +73,39 @@ def read_xlsx(file_path):
cell_value = str(cell_value) if cell_value != None else "" cell_value = str(cell_value) if cell_value != None else ""
# print(cell_value) # print(cell_value)
if col_index == 0: if col_index == 0:
start_time = cell_value if cell_value != None else "" start_time = get_seconds(cell_value) if cell_value != None else ""
if col_index == 1:
end_time = get_seconds(cell_value) if cell_value != None else ""
if col_index == 2: if col_index == 2:
end_time = cell_value if cell_value != None else ""
if col_index == 4:
subtitle = cell_value if cell_value != None else "" subtitle = cell_value if cell_value != None else ""
if col_index == 5: if col_index == 3:
if cell_value == None or cell_value == "": if cell_value == None or cell_value == "":
break break
suggest = cell_value if cell_value != None else "" suggest = cell_value if cell_value != None else ""
if col_index == 6: if col_index == 4:
if cell_value == None or cell_value == "": if cell_value == None or cell_value == "":
break break
aside = cell_value if cell_value != None else "" aside = cell_value if cell_value != None else ""
if col_index == 7: if col_index == 5:
speed = cell_value if cell_value != None else "" speed = cell_value if cell_value != None else ""
col_index = col_index + 1 col_index = col_index + 1
if suggest != "" and aside != "": if suggest != None and suggest != "" and aside != None and aside != "":
new_element = Element(start_time, end_time, subtitle, suggest, aside, speed) new_element = Element(start_time, end_time, subtitle, suggest, aside, speed)
# new_element.print_self() new_element.print_self()
elements.append(new_element) elements.append(new_element)
checkLength(elements) checkLength(elements)
print("element size:")
print(len(elements))
return elements return elements
def checkLength(elements): def checkLength(elements):
for element in elements: for element in elements:
if int("".join(filter(str.isdigit, element.suggest))) < len(element.aside): # if int("".join(filter(str.isdigit, element.suggest))) < len(element.aside):
# raise Exception("旁白字数没有按照推荐要求")
if int(element.suggest.split("/")[1]) < len(element.aside):
raise Exception("旁白字数没有按照推荐要求") raise Exception("旁白字数没有按照推荐要求")
else:
element.suggest = str(len(element.aside)) + "/" + element.suggest.split("/")[1]
# elements = read_xlsx("C:/Users/AIA/Desktop/1/121/1.xlsx") # elements = read_xlsx("C:/Users/AIA/Desktop/1/121/1.xlsx")
# print(len(elements)) # print(len(elements))
......
import subprocess
import os
import subprocess
import math
import time
import shutil
def calculate_audio_volume(file_path):
# 使用FFmpeg获取音频分贝值
command = [
'res/ffmpeg-4.3.1/bin/ffmpeg', '-i', file_path,
'-af', 'volumedetect', '-f', 'null', '-'
]
print(command)
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
output = result.stderr
# 从输出中解析分贝值
for line in output.split('\n'):
if 'mean_volume' in line:
print(line)
a = float(line.split(':')[1].strip().split("d")[0].strip())
print(a)
# mean_volume = float((line.split(':')[1].strip()).split(" ")[0])
return a
return None
# def adjust_audio_volume(input_file, output_file, multiplier):
# # 使用FFmpeg将音频音量设置为给定倍数
# command = [
# 'ffmpeg', '-i', input_file,
# '-af', f'volume={multiplier}*', output_file
# ]
# subprocess.run(command)
def adjust_audio_volume(input_file, volume_adjustment):
temp_path = "./temp.wav"
command = [
"res/ffmpeg-4.3.1/bin/ffmpeg",
"-i", input_file,
"-af", f"volume={volume_adjustment}",
"-y", # 覆盖输出文件,加上此选项
temp_path # 输出文件与输入文件相同
]
subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
os.remove(input_file)
# os.rename(temp_path, input_file)
shutil.move(temp_path, input_file)
def cg_wav(first_file_path, second_file_path, rate):
try:
print(first_file_path, second_file_path, str(rate))
# 计算第一个文件的音量
first_file_volume = calculate_audio_volume(first_file_path)
if first_file_volume is not None:
# 计算第二个文件的音量并计算倍数
second_file_volume = calculate_audio_volume(second_file_path)
if second_file_volume is not None:
# volume_multiplier = 10 ** ((first_file_volume - second_file_volume) / 20) # 转换为幅度倍数
# # 调整第二个文件的音量
# adjusted_output_file = 'path/to/output/adjusted_file.wav'
# 计算第二个文件应改为自身的大小的倍数
volume_difference_db = first_file_volume - second_file_volume
volume_difference_linear = 10 ** (volume_difference_db / 20) # 转换为线性倍数
adjusted_multiplier = volume_difference_linear * rate
adjust_audio_volume(second_file_path, adjusted_multiplier)
else:
print("无法计算第二个文件的音量")
else:
print("无法计算第一个文件的音量")
except Exception as e:
print("cg_wav err")
print(e)
# cg_wav("C:/Users/Administrator/Desktop/无障碍电影/fuiii0000/output/0.01.wav","C:/Users/Administrator/Desktop/无障碍电影/fuiii0000\output\0.01.wav",0.26)
# calculate_audio_volume("./0.01.wav")
# adjust_audio_volume("./0.01.wav",1.335)
# calculate_audio_volume("./0.01.wav")
# def test(projectContext):
# from split_wav import extract_audio
# video_path = projectContext.video_path
# output_dir = os.path.join(projectContext.project_base_dir, "output")
# extract_audio(video_path, output_dir, 0, -1)
# self.projectContext.video_path
# output_dir = os.path.join(self.projectContext.project_base_dir, "output")
# files = os.listdir(output_dir):
# for i, f in enumerate(files):
# fname = '.'.join(f.split('.')[:-1])
# try:
# st_time = float(fname)
# cur_audio, _ = soundfile.read(os.path.join(output_dir, f))
# # print(len(cur_audio))
# st_index = int(st_time * freq)
# audio_len = len(cur_audio)
# blank_audio[st_index: st_index + audio_len] = cur_audio
# origin_wav[st_index: st_index + audio_len] *= origin_audio_rate
# state[0] = float((i + 1) / len(files)) * 0.6 + 0.2
# except:
# continue
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
...@@ -9,7 +9,7 @@ import openpyxl ...@@ -9,7 +9,7 @@ import openpyxl
import constant import constant
from openpyxl.styles import PatternFill, Alignment from openpyxl.styles import PatternFill, Alignment
from utils import replace_path_suffix, transfer_second_to_time from utils import replace_path_suffix, transfer_second_to_time, reverse_time_to_seconds, get_seconds, transfer_second_to_all_time
from speech_synthesis import Speaker from speech_synthesis import Speaker
class RunThread(threading.Thread): class RunThread(threading.Thread):
"""复写线程类,用于解决主线程无法捕捉子线程中异常的问题 """复写线程类,用于解决主线程无法捕捉子线程中异常的问题
...@@ -125,8 +125,9 @@ class ProjectContext: ...@@ -125,8 +125,9 @@ class ProjectContext:
self.speaker_speed = None self.speaker_speed = None
self.duration = 0 self.duration = 0
# 一些常量 # 一些常量
self.header = ["起始时间", "终止时间", "字幕", '建议', '解说脚本', "语速"] self.header = ["起始时间", "终止时间", "字幕", '建议旁白字数', '解说脚本', "语速"]
self.write_header = ["起始时间", "起始时间(转换后)", "终止时间", "终止时间(转换后)", "字幕", '建议', '解说脚本', "语速"] # self.write_header = ["起始时间", "起始时间(转换后)", "终止时间", "终止时间(转换后)", "字幕", '建议', '解说脚本', "语速"]
self.write_header = ["起始时间", "终止时间", "字幕", '建议旁白字数', '解说脚本', "语速"]
self.aside_header = ['起始时间', '推荐字数', '解说脚本',"语速", "预览音频"] self.aside_header = ['起始时间', '推荐字数', '解说脚本',"语速", "预览音频"]
self.subtitle_header = ["起始时间", "终止时间", "字幕"] self.subtitle_header = ["起始时间", "终止时间", "字幕"]
...@@ -185,7 +186,7 @@ class ProjectContext: ...@@ -185,7 +186,7 @@ class ProjectContext:
self.excel_path = info["excel_path"] self.excel_path = info["excel_path"]
self.speaker_info = info["speaker_info"]["speaker_id"] self.speaker_info = info["speaker_info"]["speaker_id"]
self.speaker_speed = info["speaker_info"]["speaker_speed"] self.speaker_speed = info["speaker_info"]["speaker_speed"]
self.speaker_type = info["speaker_info"]["speaker_type"] if "speaker_type" in info["speaker_info"] else "科大讯飞" self.speaker_type = info["speaker_info"]["speaker_type"] if "speaker_type" in info["speaker_info"] else "浙大内部tts"
self.detected = info["detection_info"]["detected"] self.detected = info["detection_info"]["detected"]
self.nd_process = info["detection_info"]["nd_process"] self.nd_process = info["detection_info"]["nd_process"]
self.last_time = info["detection_info"]["last_time"] self.last_time = info["detection_info"]["last_time"]
...@@ -231,7 +232,6 @@ class ProjectContext: ...@@ -231,7 +232,6 @@ class ProjectContext:
# 先备份文件,再覆盖主文件,可选是否需要备份,默认需要备份 # 先备份文件,再覆盖主文件,可选是否需要备份,默认需要备份
# 20221030:添加旁白检测的进度 # 20221030:添加旁白检测的进度
def save_project(self, need_save_new: bool=False) -> str: def save_project(self, need_save_new: bool=False) -> str:
print("22222sava")
self.save_conf() self.save_conf()
# all_element = sorted(all_element, key=lambda x: float(x.st_time_sec)) # all_element = sorted(all_element, key=lambda x: float(x.st_time_sec))
print("current excel_path:", self.excel_path) print("current excel_path:", self.excel_path)
...@@ -279,8 +279,16 @@ class ProjectContext: ...@@ -279,8 +279,16 @@ class ProjectContext:
# todo:现在是只用None判断是否是字幕,后续是否也需要用""来? # todo:现在是只用None判断是否是字幕,后续是否也需要用""来?
for i in range(len(d["字幕"])): for i in range(len(d["字幕"])):
st_time_sec, ed_time_sec, subtitle, suggest, aside, speed = [d[x][i] for x in self.header] st_time_sec, ed_time_sec, subtitle, suggest, aside, speed = [d[x][i] for x in self.header]
print(">>>>>>>>>>>>>>load ed time")
print(st_time_sec)
print(ed_time_sec)
if ed_time_sec == None or ed_time_sec == "":
print(">>>>into load")
ed_time_sec = st_time_sec
# 当前条目是字幕 # 当前条目是字幕
if d["字幕"][i] != None: if d["字幕"][i] != None:
st_time_sec = reverse_time_to_seconds(str(st_time_sec))
ed_time_sec = reverse_time_to_seconds(str(ed_time_sec))
self.subtitle_list.append(Element(st_time_sec, ed_time_sec, subtitle, suggest, aside, speed)) self.subtitle_list.append(Element(st_time_sec, ed_time_sec, subtitle, suggest, aside, speed))
self.all_elements.append(self.subtitle_list[-1]) self.all_elements.append(self.subtitle_list[-1])
else: else:
...@@ -299,12 +307,22 @@ class ProjectContext: ...@@ -299,12 +307,22 @@ class ProjectContext:
if d["终止时间"][i] is None: if d["终止时间"][i] is None:
# 如果是最后一条 # 如果是最后一条
if i == len(d["字幕"]) - 1: if i == len(d["字幕"]) - 1:
ed_time_sec = "360000" if self.duration == 0 else self.duration # todo 默认最大时长是100h print(1)
# ed_time_sec = "360000" if self.duration == 0 else self.duration # todo 默认最大时长是100h
else: else:
ed_time_sec = "%.2f"%(float(d["起始时间"][i + 1]) - 0.01) ed_time_sec = "%.2f"%(float(d["起始时间"][i + 1]) - 0.01)
else: else:
ed_time_sec = d["终止时间"][i] ed_time_sec = d["终止时间"][i]
st_time_sec = reverse_time_to_seconds(str(st_time_sec))
ed_time_sec = reverse_time_to_seconds(str(ed_time_sec))
if aside == None:
aside = ""
if suggest != None and suggest != "":
arrays = suggest.split("/")
if len(arrays) == 2:
suggest = str(len(aside)) + "/" + arrays[1]
else:
suggest = str(len(aside)) + "/" + arrays[0]
self.aside_list.append(Element(st_time_sec, ed_time_sec, subtitle, suggest, aside, speed)) self.aside_list.append(Element(st_time_sec, ed_time_sec, subtitle, suggest, aside, speed))
self.all_elements.append(self.aside_list[-1]) self.all_elements.append(self.aside_list[-1])
# print("[load_excel_from_path] ", end='') # print("[load_excel_from_path] ", end='')
...@@ -370,8 +388,9 @@ class ProjectContext: ...@@ -370,8 +388,9 @@ class ProjectContext:
for speaker in content["speaker_zju_details"]: for speaker in content["speaker_zju_details"]:
speaker_name.append( speaker_name.append(
",".join([speaker["name"], speaker["gender"], speaker["age_group"]])) ",".join([speaker["name"], speaker["gender"], speaker["age_group"]]))
if self.speaker_info is None: if self.speaker_info is None or self.speaker_info == "":
self.speaker_info = speaker_name[0] self.speaker_info = speaker_name[0]
print(">>>>>>>>>>>>>>>>>get all info :" + self.speaker_info)
return tuple(speaker_name) return tuple(speaker_name)
def init_speakers(self): def init_speakers(self):
...@@ -450,17 +469,31 @@ def write_to_sheet(path: str, sheet_name: str, valuelist: list): ...@@ -450,17 +469,31 @@ def write_to_sheet(path: str, sheet_name: str, valuelist: list):
value = value_element.to_list() value = value_element.to_list()
# 把None换成空串 # 把None换成空串
value = ["" if x == None else x for x in value] value = ["" if x == None else x for x in value]
value.insert(1, transfer_second_to_time(value[0])) if value[0] != "" else value.insert(1, "") # value.insert(1, transfer_second_to_time(value[0])) if value[0] != "" else value.insert(1, "")
value.insert(3, transfer_second_to_time(value[2])) if value[2] != "" else value.insert(3, "") # value.insert(3, transfer_second_to_time(value[2])) if value[2] != "" else value.insert(3, "")
# value[0] = get_seconds(value[0]) if value[0] != "" else ""
# value[1] = get_seconds(value[1]) if value[1] != "" else ""
value[0] = transfer_second_to_all_time(value[0]) if value[0] != "" else ""
value[1] = transfer_second_to_all_time(value[1]) if value[1] != "" else ""
suggest = value[3]
if suggest != None and suggest != "":
arrays = suggest.split("/")
if len(arrays) == 2:
value[3] = str(len(value[4])) + "/" + arrays[1]
else:
value[3] = str(len(value[4])) + "/" + arrays[0]
index = len(value) index = len(value)
cur_row = sheet.max_row cur_row = sheet.max_row
for j in range(0, index): for j in range(0, index):
sheet.cell(row=cur_row + 1, column=j + 1, value=str(value[j])) cell = sheet.cell(row=cur_row + 1, column=j + 1, value=str(value[j]))
if value[j] == '' or '插入旁白' in str(value[j]): if value[j] == '' or '插入旁白' in str(value[j]):
sheet.cell(row=cur_row + 1, column=j + 1).fill = PatternFill(fill_type='solid', fgColor='ffff00') cell = sheet.cell(row=cur_row + 1, column=j + 1).fill = PatternFill(fill_type='solid', fgColor='ffff00')
if j == 4: if j == 4:
sheet.cell(row=cur_row + 1, column=j + 1).alignment = Alignment(wrapText=True) cell = sheet.cell(row=cur_row + 1, column=j + 1).alignment = Alignment(wrapText=True)
cell.number_format = '@'
workbook.save(path) workbook.save(path)
......
...@@ -13,3 +13,4 @@ class myVideoSlider(QSlider): ...@@ -13,3 +13,4 @@ class myVideoSlider(QSlider):
# self.setValue(int(value)/9) # self.setValue(int(value)/9)
value = round(value/self.width()*self.maximum()) # 根据鼠标点击的位置和slider的长度算出百分比 value = round(value/self.width()*self.maximum()) # 根据鼠标点击的位置和slider的长度算出百分比
self.ClickedValue.emit(value) self.ClickedValue.emit(value)
self.setFocus()
\ No newline at end of file
import re
import csv
import argparse
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from difflib import SequenceMatcher
title = ['起始时间(转换后)', '终止时间(转换后)', '字幕']
def init():
# 获取中文停用词列表
global stop_words
with open('chinese_stopwords.txt', 'r', encoding='utf-8') as file:
stop_words = set(line.strip() for line in file)
# 将保存的时间戳转化为秒
def change_to_second(time_str):
from datetime import datetime
time_obj = datetime.strptime(time_str, "%H:%M:%S,%f")
seconds = time_obj.hour * 3600 + time_obj.minute * 60 + \
time_obj.second + time_obj.microsecond / 1000000
return seconds
# 计算字幕的相似度
def calculate_similarity(str1, str2, method='cosine'):
if method == 'cosine':
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform([str1, str2])
similarity_matrix = cosine_similarity(tfidf_matrix)
return similarity_matrix[0][1]
else :
return SequenceMatcher(None, str1, str2).ratio()
# 计算两个时间戳的时间差(单位:秒)
def calculate_time_difference(time1, time2):
return abs(time2 - time1)
def calculate_weight(x, y):
# weight = e^(-alpha * time_diff)
# 相差1s的系数为0.9
alpha = 0.11
return 1 / (alpha * (x + y) + 1)
# 检查句子中的每个单词是否都是停用词
def is_all_stopwords(sentence):
return all(word in stop_words for word in sentence)
### 如果其中有-符号,可能在用excel打开时自动添加=变成公式,读取的时候没问题
def read_srt_to_csv(path_srt, path_output):
with open(path_srt, 'r', encoding='utf-8-sig') as f:
srt_content = f.read() # str
# 使用正则表达式匹配时间码和字幕内容
pattern = re.compile(r'(\d+)\n([\d:,]+) --> ([\d:,]+)\n(.+?)(?=\n\d+\n|$)', re.DOTALL)
matches = pattern.findall(srt_content)
# 写入 csv 文件
with open(path_output, 'w', newline='', encoding='utf-8') as f:
csv_writer = csv.writer(f)
csv_writer.writerow(title)
for _, start, end, subtitle in matches: # 都是str格式
subtitle = re.sub(r'\{[^}]*\}', '', subtitle) # 将srt文件前的加粗等格式去掉
csv_writer.writerow([start, end, subtitle.strip()])
def read_from_xlsx(path_xlsx='output.xlsx', path_output='deal.csv'):
data = pd.read_excel(path_xlsx)
with open(path_output, 'w', newline='', encoding='utf-8') as f:
csv_writer = csv.writer(f)
csv_writer.writerow(title)
for _, data1 in data.iterrows():
start, end, subtitle = data1[1], data1[3], data1[4]
if isinstance(subtitle, float) and np.isnan(subtitle):
continue
# 与srt文件格式同步
start = start.replace('.', ',')
end = end.replace('.', ',')
# print(start, end, subtitle,)
# print(type(start), type(end), type(subtitle))
csv_writer.writerow([start, end, subtitle.strip()])
### 对于srt中的字幕计算相似性度。从ocr中找到时间戳满足<=time_t的字幕,
### 然后计算字幕间的相似度,取一个最大的。字幕从start和end都匹配一遍
# time_threshold设置阈值,用于判断时间差是否可接受
def measure_score(path_srt, path_ocr, time_threshold=5.0, method='cosine'):
data_srt, data_ocr = [], []
with open(path_srt, 'r', encoding='utf-8') as file:
csv_reader = csv.reader(file)
data_srt = [i for i in csv_reader]
data_srt.pop(0)
for i in range(len(data_srt)):
data_srt[i][0] = change_to_second(data_srt[i][0])
data_srt[i][1] = change_to_second(data_srt[i][1])
with open(path_ocr, 'r', encoding='utf-8') as file:
csv_reader = csv.reader(file)
data_ocr = [i for i in csv_reader]
data_ocr.pop(0)
for i in range(len(data_ocr)):
data_ocr[i][0] = change_to_second(data_ocr[i][0])
data_ocr[i][1] = change_to_second(data_ocr[i][1])
# 计算相似度
total_similarity = 0.0
total_weight = 0.0
for sub in data_srt:
max_similarity = 0.0
# 去除srt中的停用词
if is_all_stopwords(sub[2]):
continue
for sub1 in data_ocr:
x, y = abs(sub[0] - sub1[0]), abs(sub[1] - sub1[1])
if min(x, y) <= time_threshold:
# print(sub[2], sub1[2])
score = calculate_similarity(sub[2], sub1[2], 'cosine')
max_similarity = max(max_similarity, score * calculate_weight(x, y))
total_similarity += max_similarity
total_weight += 1
# print(total_similarity, total_similarity / len(data_srt), total_similarity / total_weight)
return total_similarity / len(data_srt), total_similarity / total_weight
if __name__ == '__main__':
init()
parser = argparse.ArgumentParser(description="benchmark")
# 添加命令行参数
parser.add_argument("--path_srt", required=True, type=str, help="Path of srt file, format is srt")
parser.add_argument("--path_ocr", required=True, type=str, help="Path of ocr file, format is xlsx")
parser.add_argument("--method", type=str, default='cosine', help="Select evaluation method")
parser.add_argument("--time_threshold", type=float,default=5.0, help="Allowable time frame")
args = parser.parse_args()
output_file_srt = 'deal_srt.csv'
output_file_ocr = 'deal_ocr.csv'
read_srt_to_csv(args.path_srt, output_file_srt)
read_from_xlsx(args.path_ocr, output_file_ocr)
score = measure_score(output_file_srt, output_file_ocr, args.time_threshold, args.method)
print(f'该评估算法得分: {score[1]:.5f}')
\ No newline at end of file
...@@ -260,9 +260,12 @@ class Operation_Dialog(QDialog, Ui_Dialog): ...@@ -260,9 +260,12 @@ class Operation_Dialog(QDialog, Ui_Dialog):
else: # 如果是旁白 else: # 如果是旁白
end_time = "" end_time = ""
subtitle = "" subtitle = ""
suggest = "插入旁白,推荐字数为" + suggest # suggest = "插入旁白,推荐字数为" + suggest
# if self.comboBox_2.currentText() == "增加一行":
# suggest = "插入旁白,推荐字数为0"
suggest = suggest
if self.comboBox_2.currentText() == "增加一行": if self.comboBox_2.currentText() == "增加一行":
suggest = "插入旁白,推荐字数为0" suggest = "0/100"
# 别忘复原 # 别忘复原
self.buttonBox.setEnabled(False) self.buttonBox.setEnabled(False)
self.zmpb_change_slot() self.zmpb_change_slot()
......
...@@ -14,6 +14,7 @@ from PyQt5.QtWidgets import *; ...@@ -14,6 +14,7 @@ from PyQt5.QtWidgets import *;
from management import RunThread from management import RunThread
from speech_synthesis import ffmpeg_path from speech_synthesis import ffmpeg_path
from ffmpeg_util import cg_wav
class ExportProcessor(QWidget): class ExportProcessor(QWidget):
show_warning_signal = pyqtSignal(str) show_warning_signal = pyqtSignal(str)
...@@ -23,27 +24,30 @@ class ExportProcessor(QWidget): ...@@ -23,27 +24,30 @@ class ExportProcessor(QWidget):
self.state = [0] self.state = [0]
self.threads = [] self.threads = []
def export_slot(self, video_path, output_dir): def export_slot(self, video_path, output_dir, pb_cg_rate):
t = RunThread(funcName=self.start_export, t = RunThread(funcName=self.start_export,
args=(video_path, output_dir), args=(video_path, output_dir, pb_cg_rate),
name="export") name="export")
t.setDaemon(True) t.setDaemon(True)
self.threads.append(t) self.threads.append(t)
for t in self.threads: for t in self.threads:
try:
t.start() t.start()
except Exception as e:
print(e)
print("===子线程已经开启 in export===") print("===子线程已经开启 in export===")
self.export_callback_signal.emit(self.threads, self.state) self.export_callback_signal.emit(self.threads, self.state)
def start_export(self, video_path, output_dir): def start_export(self, video_path, output_dir, pb_cg_rate):
mixed_audio_path = aggrevate_audios(video_path, output_dir, self.state) mixed_audio_path = aggrevate_audios(video_path, output_dir, self.state, pb_cg_rate)
export_video(video_path, mixed_audio_path, output_dir, self.state) export_video(video_path, mixed_audio_path, output_dir, self.state)
# 生成一条无声的音频,然后把旁白音频逐个按照时间位置放进去,得到仅含旁白的音频和旁白+原声的音频 # 生成一条无声的音频,然后把旁白音频逐个按照时间位置放进去,得到仅含旁白的音频和旁白+原声的音频
def aggrevate_audios(video_path: str, output_dir: str, state=None): def aggrevate_audios(video_path: str, output_dir: str, state=None,pb_cg_rate = 1.00):
# 这个模块最多只有80%的进度 # 这个模块最多只有80%的进度
if state is None: if state is None:
state = [0] state = [0]
...@@ -56,6 +60,18 @@ def aggrevate_audios(video_path: str, output_dir: str, state=None): ...@@ -56,6 +60,18 @@ def aggrevate_audios(video_path: str, output_dir: str, state=None):
# 将生成的旁白音频放入空白音频中,并将原音频的对应位置音量降低为原来的30% # 将生成的旁白音频放入空白音频中,并将原音频的对应位置音量降低为原来的30%
files = os.listdir(output_dir) files = os.listdir(output_dir)
if pb_cg_rate != 1.00:
audio_path = os.path.join(output_dir, os.path.basename(video_path).split('.')[0] + ".wav")
for i, f in enumerate(files):
fname = '.'.join(f.split('.')[:-1])
try:
if fname.find(".") != -1:
cg_wav(audio_path, os.path.join(output_dir, f), pb_cg_rate)
except Exception as e:
print(e)
continue
for i, f in enumerate(files): for i, f in enumerate(files):
fname = '.'.join(f.split('.')[:-1]) fname = '.'.join(f.split('.')[:-1])
try: try:
......
{"video_path": null, "excel_path": null, "detection_info": {"detected": false, "nd_process": 0.0, "last_time": 0.0, "caption_boundings": [], "has_subtitle": true}, "speaker_info": {"speaker_type": "\u6d59\u5927\u5185\u90e8tts", "speaker_id": "test\uff0c\u5973\uff0c\u5e74\u8f7b\u4eba", "speaker_speed": "1.00(4\u5b57/\u79d2)"}} {"video_path": null, "excel_path": null, "detection_info": {"detected": false, "nd_process": 0.0, "last_time": 0.0, "caption_boundings": [], "has_subtitle": true}, "speaker_info": {"speaker_type": "", "speaker_id": "eagle\uff0c\u5973\uff0c\u5e74\u8f7b\u4eba", "speaker_speed": "1.00(4\u5b57/\u79d2)"}}
\ No newline at end of file \ No newline at end of file
{ {
"speaker_details": [{ "speaker_details": [
"id": 0,
"name": "晓辰",
"language": "中文(普通话,简体)",
"age_group": "年轻人",
"gender": "女",
"description": "休闲、放松的语音,用于自发性对话和会议听录。",
"audio_path": "./res/speaker_audio/Xiaochen.wav",
"speaker_code": "zh-CN-XiaochenNeural"
},
{
"id": 1,
"name": "晓涵",
"language": "中文(普通话,简体)",
"age_group": "年轻人",
"gender": "女",
"description": "温暖、甜美、富有感情的声音,可用于许多对话场景。",
"audio_path": "./res/speaker_audio/Xiaohan.wav",
"speaker_code": "zh-CN-XiaohanNeural"
},
{
"id": 2,
"name": "晓墨",
"language": "中文(普通话,简体)",
"age_group": "年轻人",
"gender": "女",
"description": "清晰、放松的声音,具有丰富的角色扮演和情感,适合音频书籍。",
"audio_path": "./res/speaker_audio/Xiaomo.wav",
"speaker_code": "zh-CN-XiaomoNeural"
},
{
"id": 7,
"name": "晓晓",
"language": "中文(普通话,简体)",
"age_group": "年轻人",
"gender": "女",
"description": "活泼、温暖的声音,具有多种场景风格和情感。",
"audio_path": "./res/speaker_audio/Xiaoxiao.wav",
"speaker_code": "zh-CN-XiaoxiaoNeural"
},
{
"id": 8,
"name": "晓萱",
"language": "中文(普通话,简体)",
"age_group": "年轻人",
"gender": "女",
"description": "自信、有能力的声音,具有丰富的角色扮演和情感,适合音频书籍。",
"audio_path": "./res/speaker_audio/Xiaoxuan.wav",
"speaker_code": "zh-CN-XiaoxuanNeural"
},
{
"id": 9,
"name": "晓颜",
"language": "中文(普通话,简体)",
"age_group": "年轻人",
"gender": "女",
"description": "训练有素、舒适的语音,用于客户服务和对话场景。",
"audio_path": "./res/speaker_audio/Xiaoyan.wav",
"speaker_code": "zh-CN-XiaoyanNeural"
},
{
"id": 3,
"name": "晓秋",
"language": "中文(普通话,简体)",
"age_group": "中年人",
"gender": "女",
"description": "智能、舒适的语音,适合阅读长内容。",
"audio_path": "./res/speaker_audio/Xiaoqiu.wav",
"speaker_code": "zh-CN-XiaoqiuNeural"
},
{
"id": 4,
"name": "晓秋",
"language": "中文(普通话,简体)",
"age_group": "中年人",
"gender": "女",
"description": "智能、舒适的语音,适合阅读长内容。",
"audio_path": "./res/speaker_audio/Xiaoqiu.wav",
"speaker_code": "zh-CN-XiaoqiuNeural"
},
{
"id": 5,
"name": "晓睿",
"language": "中文(普通话,简体)",
"age_group": "老年",
"gender": "女",
"description": "成熟、睿智的声音,具有丰富的情感,适合音频书籍。",
"audio_path": "./res/speaker_audio/Xiaorui.wav",
"speaker_code": "zh-CN-XiaoruiNeural"
},
{
"id": 6,
"name": "晓双",
"language": "中文(普通话,简体)",
"age_group": "儿童",
"gender": "女",
"description": "可爱、愉悦的语音,可应用于许多儿童相关场景。",
"audio_path": "./res/speaker_audio/Xiaoshuang.wav",
"speaker_code": "zh-CN-XiaoshuangNeural"
},
{
"id": 10,
"name": "晓悠",
"language": "中文(普通话,简体)",
"age_group": "儿童",
"gender": "女",
"description": "天使般的清晰声音,可以应用于许多儿童相关场景。",
"audio_path": "./res/speaker_audio/Xiaoyou.wav",
"speaker_code": "zh-CN-XiaoyouNeural"
},
{
"id": 11,
"name": "云希",
"language": "中文(普通话,简体)",
"age_group": "年轻人",
"gender": "男",
"description": "活泼、阳光的声音,具有丰富的情感,可用于许多对话场景。",
"audio_path": "./res/speaker_audio/Yunxi.wav",
"speaker_code": "zh-CN-YunxiNeural"
},
{
"id": 12,
"name": "云扬",
"language": "中文(普通话,简体)",
"age_group": "年轻人",
"gender": "男",
"description": "专业、流利的声音,具有多种场景风格。",
"audio_path": "./res/speaker_audio/Yunyang.wav",
"speaker_code": "zh-CN-YunyangNeural"
},
{
"id": 13,
"name": "云野",
"language": "中文(普通话,简体)",
"age_group": "中年人",
"gender": "男",
"description": "成熟、放松的声音,具有多种情感,适合音频书籍。",
"audio_path": "./res/speaker_audio/Yunye.wav",
"speaker_code": "zh-CN-YunyeNeural"
}
], ],
"speaker_zju_details": [{ "speaker_zju_details": [{
"id": 0, "id": 0,
"name": "test", "name": "eagle",
"language": "中文(普通话,简体)", "language": "中文(普通话,简体)",
"age_group": "年轻人", "age_group": "年轻人",
"gender": "女", "gender": "女",
......
...@@ -39,6 +39,7 @@ class Setting_Dialog(QDialog, Ui_Dialog): ...@@ -39,6 +39,7 @@ class Setting_Dialog(QDialog, Ui_Dialog):
self.comboBox_2.clear() self.comboBox_2.clear()
# todo 把所有说话人都加上来 # todo 把所有说话人都加上来
self.speaker_li = projectContext.get_all_speaker_info() self.speaker_li = projectContext.get_all_speaker_info()
# self.speaker_li = []
self.speaker_zju_li = projectContext.get_all_speaker_zju_info() #本地tts self.speaker_zju_li = projectContext.get_all_speaker_zju_info() #本地tts
self.speed_list_zju = ["1.00(4字/秒)", "1.10(4.5字/秒)", "1.25(5字/秒)", "1.50(6字/秒)", "1.75(7字/秒)", "2.00(8字/秒)", "2.50(10字/秒)"] #本地tts self.speed_list_zju = ["1.00(4字/秒)", "1.10(4.5字/秒)", "1.25(5字/秒)", "1.50(6字/秒)", "1.75(7字/秒)", "2.00(8字/秒)", "2.50(10字/秒)"] #本地tts
...@@ -46,7 +47,8 @@ class Setting_Dialog(QDialog, Ui_Dialog): ...@@ -46,7 +47,8 @@ class Setting_Dialog(QDialog, Ui_Dialog):
# self.comboBox.addItem(i) # self.comboBox.addItem(i)
self.speed_li_2 = ["1.00(4字/秒)", "1.10(4.5字/秒)", "1.25(5字/秒)", "1.50(6字/秒)", "1.75(7字/秒)", "2.00(8字/秒)", "2.50(10字/秒)"] self.speed_li_2 = ["1.00(4字/秒)", "1.10(4.5字/秒)", "1.25(5字/秒)", "1.50(6字/秒)", "1.75(7字/秒)", "2.00(8字/秒)", "2.50(10字/秒)"]
# self.comboBox_2.addItems(self.speed_li_2) # self.comboBox_2.addItems(self.speed_li_2)
self.speaker_types = ["科大讯飞", "浙大内部tts"] # self.speaker_types = ["科大讯飞", "浙大内部tts"]
self.speaker_types = ["浙大内部tts"]
self.comboBox_0.addItems(self.speaker_types) self.comboBox_0.addItems(self.speaker_types)
print(projectContext.speaker_type) print(projectContext.speaker_type)
if projectContext.speaker_type is None or projectContext.speaker_type == "": if projectContext.speaker_type is None or projectContext.speaker_type == "":
...@@ -54,7 +56,7 @@ class Setting_Dialog(QDialog, Ui_Dialog): ...@@ -54,7 +56,7 @@ class Setting_Dialog(QDialog, Ui_Dialog):
else: else:
self.comboBox_0.setCurrentIndex(self.speaker_types.index(projectContext.speaker_type)) self.comboBox_0.setCurrentIndex(self.speaker_types.index(projectContext.speaker_type))
if self.comboBox_0.currentIndex() ==0: #讯飞 if self.comboBox_0.currentIndex() !=0: #讯飞
self.comboBox.addItems(self.speaker_li) self.comboBox.addItems(self.speaker_li)
self.comboBox_2.addItems(self.speed_li_2) self.comboBox_2.addItems(self.speed_li_2)
else: else:
...@@ -67,13 +69,13 @@ class Setting_Dialog(QDialog, Ui_Dialog): ...@@ -67,13 +69,13 @@ class Setting_Dialog(QDialog, Ui_Dialog):
self.comboBox.setCurrentIndex(0) self.comboBox.setCurrentIndex(0)
else: else:
print(projectContext.speaker_info) print(projectContext.speaker_info)
self.comboBox.setCurrentIndex(self.speaker_li.index(projectContext.speaker_info) if self.comboBox_0.currentIndex() ==0 else self.speaker_zju_li.index(projectContext.speaker_info)) self.comboBox.setCurrentIndex(self.speaker_li.index(projectContext.speaker_info) if self.comboBox_0.currentIndex() !=0 else self.speaker_zju_li.index(projectContext.speaker_info))
print(projectContext.speaker_speed) print(projectContext.speaker_speed)
if projectContext.speaker_speed is None or projectContext.speaker_speed == "": if projectContext.speaker_speed is None or projectContext.speaker_speed == "":
self.comboBox_2.setCurrentIndex(0) self.comboBox_2.setCurrentIndex(0)
else: else:
self.comboBox_2.setCurrentIndex(self.speed_li_2.index(projectContext.speaker_speed) if self.comboBox_0.currentIndex() ==0 else self.speed_list_zju.index(projectContext.speaker_speed)) self.comboBox_2.setCurrentIndex(self.speed_li_2.index(projectContext.speaker_speed) if self.comboBox_0.currentIndex() !=0 else self.speed_list_zju.index(projectContext.speaker_speed))
finally: finally:
self.refresh_flag = False self.refresh_flag = False
...@@ -84,7 +86,8 @@ class Setting_Dialog(QDialog, Ui_Dialog): ...@@ -84,7 +86,8 @@ class Setting_Dialog(QDialog, Ui_Dialog):
self.comboBox.clear() self.comboBox.clear()
self.comboBox_2.clear() self.comboBox_2.clear()
self.projectContext.speaker_type = self.comboBox_0.currentText() self.projectContext.speaker_type = self.comboBox_0.currentText()
if self.comboBox_0.currentIndex() ==0: # if self.comboBox_0.currentIndex() ==0:
if self.comboBox_0.currentIndex() !=0:
print("讯飞") print("讯飞")
self.comboBox.addItems(self.speaker_li) self.comboBox.addItems(self.speaker_li)
self.comboBox_2.addItems(self.speed_li_2) self.comboBox_2.addItems(self.speed_li_2)
...@@ -106,12 +109,12 @@ class Setting_Dialog(QDialog, Ui_Dialog): ...@@ -106,12 +109,12 @@ class Setting_Dialog(QDialog, Ui_Dialog):
if self.projectContext.speaker_info is None or self.projectContext.speaker_info == "" : if self.projectContext.speaker_info is None or self.projectContext.speaker_info == "" :
self.comboBox.setCurrentIndex(0) self.comboBox.setCurrentIndex(0)
else: else:
self.comboBox.setCurrentIndex(self.speaker_li.index(self.projectContext.speaker_info) if self.comboBox_0.currentIndex() ==0 else self.speaker_zju_li.index(self.projectContext.speaker_info)) self.comboBox.setCurrentIndex(self.speaker_li.index(self.projectContext.speaker_info) if self.comboBox_0.currentIndex() !=0 else self.speaker_zju_li.index(self.projectContext.speaker_info))
if self.projectContext.speaker_speed is None or self.projectContext.speaker_speed == "": if self.projectContext.speaker_speed is None or self.projectContext.speaker_speed == "":
self.comboBox_2.setCurrentIndex(0) self.comboBox_2.setCurrentIndex(0)
else: else:
self.comboBox_2.setCurrentIndex(self.speed_li_2.index(self.projectContext.speaker_speed) if self.comboBox_0.currentIndex() ==0 else self.speed_list_zju.index(self.projectContext.speaker_speed)) self.comboBox_2.setCurrentIndex(self.speed_li_2.index(self.projectContext.speaker_speed) if self.comboBox_0.currentIndex() !=0 else self.speed_list_zju.index(self.projectContext.speaker_speed))
def speaker_change_slot(self): def speaker_change_slot(self):
"""切换说话人 """切换说话人
......
...@@ -23,11 +23,12 @@ from typing import Tuple ...@@ -23,11 +23,12 @@ from typing import Tuple
import datetime import datetime
import numpy as np import numpy as np
from azure.cognitiveservices.speech import SpeechConfig, SpeechSynthesizer, ResultReason, AudioDataStream # from azure.cognitiveservices.speech import SpeechConfig, SpeechSynthesizer, ResultReason, AudioDataStream
from azure.cognitiveservices.speech.audio import AudioOutputConfig # from azure.cognitiveservices.speech.audio import AudioOutputConfig
import openpyxl import openpyxl
import shutil import shutil
from vits_chinese import tts from vits_chinese import tts
from utils import reverse_time_to_seconds
tmp_file = 'tmp.wav' tmp_file = 'tmp.wav'
adjusted_wav_path = "adjusted.wav" adjusted_wav_path = "adjusted.wav"
...@@ -81,8 +82,11 @@ def choose_speaker(speaker_name: str) -> Speaker: ...@@ -81,8 +82,11 @@ def choose_speaker(speaker_name: str) -> Speaker:
Returns: Returns:
Speaker: 返回对应说话人,如果没有这个说话人则报错 Speaker: 返回对应说话人,如果没有这个说话人则报错
""" """
print(">>>>>>>>>>>>>speakerName:" + speaker_name)
for speaker in speakers: for speaker in speakers:
print(">>>>>>>>>>>>>speaker:" + speaker.name)
if speaker.name == speaker_name: if speaker.name == speaker_name:
return speaker return speaker
raise ValueError raise ValueError
...@@ -105,41 +109,42 @@ def speech_synthesis(text: str, output_file: str, speaker: Speaker, speed: float ...@@ -105,41 +109,42 @@ def speech_synthesis(text: str, output_file: str, speaker: Speaker, speed: float
if speaker.speaker_type != None and speaker.speaker_type == "1": if speaker.speaker_type != None and speaker.speaker_type == "1":
tts(text, speed, output_file) tts(text, speed, output_file)
else: else:
speech_config = SpeechConfig( print("1")
subscription="db34d38d2d3447d482e0f977c66bd624", # speech_config = SpeechConfig(
region="eastus" # subscription="db34d38d2d3447d482e0f977c66bd624",
) # region="eastus"
# )
speech_config.speech_synthesis_language = "zh-CN"
speech_config.speech_synthesis_voice_name = speaker.speaker_code # speech_config.speech_synthesis_language = "zh-CN"
# speech_config.speech_synthesis_voice_name = speaker.speaker_code
# 先把合成的语音文件输出得到tmp.wav中,便于可能的调速需求
# # 先把合成的语音文件输出得到tmp.wav中,便于可能的调速需求
synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None)
ssml_string = f""" # synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None)
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="{speech_config.speech_synthesis_language}"> # ssml_string = f"""
<voice name="{speaker.speaker_code}"> # <speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="{speech_config.speech_synthesis_language}">
<prosody rate="{round((speed - 1.0) * 100, 2)}%"> # <voice name="{speaker.speaker_code}">
{text} # <prosody rate="{round((speed - 1.0) * 100, 2)}%">
</prosody> # {text}
</voice> # </prosody>
</speak>""" # </voice>
result = synthesizer.speak_ssml_async(ssml_string).get() # </speak>"""
stream = AudioDataStream(result) # result = synthesizer.speak_ssml_async(ssml_string).get()
stream.save_to_wav_file(output_file) # stream = AudioDataStream(result)
print(result.reason) # stream.save_to_wav_file(output_file)
# print(result.reason)
while result.reason == ResultReason.Canceled:
cancellation_details = result.cancellation_details # while result.reason == ResultReason.Canceled:
print("取消的原因", cancellation_details.reason, cancellation_details.error_details) # cancellation_details = result.cancellation_details
time.sleep(1) # print("取消的原因", cancellation_details.reason, cancellation_details.error_details)
synthesizer.stop_speaking() # time.sleep(1)
del synthesizer # synthesizer.stop_speaking()
synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None) # del synthesizer
result = synthesizer.speak_ssml_async(ssml_string).get() # synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None)
stream = AudioDataStream(result) # result = synthesizer.speak_ssml_async(ssml_string).get()
stream.save_to_wav_file(output_file) # stream = AudioDataStream(result)
print(result.reason) # stream.save_to_wav_file(output_file)
# print(result.reason)
# detached # detached
def change_speed_and_volume(wav_path: str, speed: float = 1.0): def change_speed_and_volume(wav_path: str, speed: float = 1.0):
...@@ -205,7 +210,7 @@ def get_narratage_text(sheet_content: dict) -> Tuple[list, list, list]: ...@@ -205,7 +210,7 @@ def get_narratage_text(sheet_content: dict) -> Tuple[list, list, list]:
for i, text in enumerate(narratage): for i, text in enumerate(narratage):
# 这里的speed是x.x倍速 # 这里的speed是x.x倍速
speed = float(speeds[i].split('(')[0]) speed = float(speeds[i].split('(')[0])
if text is not None: if text is not None and text != "":
if text == '翻译': if text == '翻译':
narratage_text.append(subtitle[i]) narratage_text.append(subtitle[i])
else: else:
...@@ -236,8 +241,10 @@ def get_narratage_text(sheet_content: dict) -> Tuple[list, list, list]: ...@@ -236,8 +241,10 @@ def get_narratage_text(sheet_content: dict) -> Tuple[list, list, list]:
# narratage_start_time.append(cur_start) # narratage_start_time.append(cur_start)
# narratage_end_time.append(cur_end) # narratage_end_time.append(cur_end)
# cur_start = cur_start + (len(x) / normal_speed + normal_interval) / speed # cur_start = cur_start + (len(x) / normal_speed + normal_interval) / speed
narratage_start_time.append(float(start_time[i])) # narratage_start_time.append(float(start_time[i]))
narratage_end_time.append(float(end_time[i])) if end_time[i] is not None else narratage_end_time.append(-1) # narratage_end_time.append(float(end_time[i])) if end_time[i] is not None else narratage_end_time.append(-1)
narratage_start_time.append(float(reverse_time_to_seconds(start_time[i])))
narratage_end_time.append(float(reverse_time_to_seconds(end_time[i]))) if end_time[i] is not None and end_time[i] != "" else narratage_end_time.append(-1)
narratage_speed.append(speed) narratage_speed.append(speed)
return narratage_text, narratage_start_time, narratage_end_time, narratage_speed return narratage_text, narratage_start_time, narratage_end_time, narratage_speed
...@@ -251,6 +258,7 @@ def second_to_str(seconds: float) -> str: ...@@ -251,6 +258,7 @@ def second_to_str(seconds: float) -> str:
Returns: Returns:
str: “时:分:秒”格式的时间字符串 str: “时:分:秒”格式的时间字符串
""" """
try:
seconds = float(seconds) seconds = float(seconds)
hour = int(seconds / 3600) hour = int(seconds / 3600)
minute = int((seconds - hour * 3600) / 60) minute = int((seconds - hour * 3600) / 60)
...@@ -258,6 +266,8 @@ def second_to_str(seconds: float) -> str: ...@@ -258,6 +266,8 @@ def second_to_str(seconds: float) -> str:
ms = int((seconds - second - minute * 60 - hour * 3600) * 1000) ms = int((seconds - second - minute * 60 - hour * 3600) * 1000)
time_str = "%02d:%02d:%02d,%03d" % (hour, minute, second, ms) time_str = "%02d:%02d:%02d,%03d" % (hour, minute, second, ms)
return time_str return time_str
except:
return str(seconds)
def export_caption(sheet_content: dict, caption_file: str): def export_caption(sheet_content: dict, caption_file: str):
......
...@@ -56,19 +56,34 @@ def change_project_path(path): ...@@ -56,19 +56,34 @@ def change_project_path(path):
if __name__ == '__main__': if __name__ == '__main__':
try: try:
# subprocess.call(['deploy.bat']) # subprocess.call(['deploy.bat'])
if not is_lav_filters_installed() or not is_file_copyed(): # if not is_lav_filters_installed() or not is_file_copyed():
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) # QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) # QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv) # app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./res/images/eagle_2.ico")) # app.setWindowIcon(QIcon("./res/images/eagle_2.ico"))
apply_stylesheet(app, theme='dark_amber.xml') # apply_stylesheet(app, theme='dark_amber.xml')
mainWindow = MainWindow(project_path) # mainWindow = MainWindow(project_path)
QtWidgets.QMessageBox.critical(mainWindow,'警告','视频解码器未正常安装',QtWidgets.QMessageBox.Yes) # QtWidgets.QMessageBox.critical(mainWindow,'警告','视频解码器未正常安装',QtWidgets.QMessageBox.Yes)
else: # else:
# QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
# QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
# currentExitCode = MainWindow.EXIT_CODE_REBOOT
# if not os.path.exists("C:\LavFilters") and not os.path.exists("C:\Program Files (x86)\LAV Filters"):
# QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
# QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
# app = QApplication(sys.argv)
# app.setWindowIcon(QIcon("./res/images/eagle_2.ico"))
# apply_stylesheet(app, theme='dark_amber.xml')
# mainWindow = MainWindow(project_path)
# QtWidgets.QMessageBox.critical(mainWindow,'警告','视频解码器未正常安装',QtWidgets.QMessageBox.Yes)
# else:
# QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
# QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
# currentExitCode = MainWindow.EXIT_CODE_REBOOT
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
currentExitCode = MainWindow.EXIT_CODE_REBOOT currentExitCode = MainWindow.EXIT_CODE_REBOOT
while currentExitCode == MainWindow.EXIT_CODE_REBOOT: while currentExitCode == MainWindow.EXIT_CODE_REBOOT:
app = QApplication(sys.argv) app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./res/images/eagle_2.ico")) app.setWindowIcon(QIcon("./res/images/eagle_2.ico"))
...@@ -82,6 +97,8 @@ if __name__ == '__main__': ...@@ -82,6 +97,8 @@ if __name__ == '__main__':
apply_stylesheet(app, theme='dark_amber.xml') apply_stylesheet(app, theme='dark_amber.xml')
# mainWindow.show() # mainWindow.show()
mainWindow.showMaximized() mainWindow.showMaximized()
if not os.path.exists("C:\LavFilters") and not os.path.exists("C:\Program Files (x86)\LAV Filters"):
mainWindow.import_excel_dialog.show_with_msg("视频解码器未正常安装")
currentExitCode = app.exec_() currentExitCode = app.exec_()
app = None app = None
except Exception as e: except Exception as e:
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
block_cipher = None block_cipher = None
env_dir = 'C:/Users/AIA/.conda/envs/testmovie/Lib/site-packages/' env_dir = 'C:/Users/AIA/.conda/envs/testmovie/Lib/site-packages/'
missingPkgs = ['Microsoft.CognitiveServices.Speech.core.dll', 'decorator.py', 'google', 'paddle', 'paddleocr', 'PIL', 'requests', 'urllib3', 'http', 'idna', 'certifi', 'setuptools', 'astor', 'charset_normalizer'] missingPkgs = ['Microsoft.CognitiveServices.Speech.core.dll', 'decorator.py', 'google', 'paddleocr', 'PIL', 'requests', 'urllib3', 'http', 'idna', 'certifi', 'setuptools', 'astor', 'charset_normalizer']
def add_missing_packages(lst): def add_missing_packages(lst):
pkgs = [] pkgs = []
...@@ -20,8 +20,8 @@ a = Analysis( ...@@ -20,8 +20,8 @@ a = Analysis(
['start.py'], ['start.py'],
pathex=[], pathex=[],
binaries=[], binaries=[],
datas=[('res','res')] + pkgPaths, datas=[('vits_chinese','vits_chinese')] + [('res','res'),('./deploy.bat','.'),('./ding_notify.conf','.'),('LAVFilters64','LAVFilters64'),('LAVFilters32','LAVFilters32')] + pkgPaths,
hiddenimports=[], hiddenimports=['filecmp'],
hookspath=[], hookspath=[],
hooksconfig={}, hooksconfig={},
runtime_hooks=[], runtime_hooks=[],
...@@ -38,7 +38,7 @@ exe = EXE( ...@@ -38,7 +38,7 @@ exe = EXE(
a.scripts, a.scripts,
[], [],
exclude_binaries=True, exclude_binaries=True,
name='start', name='无障碍电影制作系统',
debug=False, debug=False,
bootloader_ignore_signals=False, bootloader_ignore_signals=False,
strip=False, strip=False,
...@@ -49,6 +49,7 @@ exe = EXE( ...@@ -49,6 +49,7 @@ exe = EXE(
target_arch=None, target_arch=None,
codesign_identity=None, codesign_identity=None,
entitlements_file=None, entitlements_file=None,
icon=['res\\images\\eagle_2.ico'],
) )
coll = COLLECT( coll = COLLECT(
exe, exe,
...@@ -58,5 +59,5 @@ coll = COLLECT( ...@@ -58,5 +59,5 @@ coll = COLLECT(
strip=False, strip=False,
upx=True, upx=True,
upx_exclude=[], upx_exclude=[],
name='start', name='无障碍电影制作系统',
) )
...@@ -38,6 +38,29 @@ def validate_and_get_filepath(file_info) -> Tuple[str, bool]: ...@@ -38,6 +38,29 @@ def validate_and_get_filepath(file_info) -> Tuple[str, bool]:
return "", False return "", False
return file_info[0][0], True return file_info[0][0], True
def get_seconds(time_str: str):
try:
# print(">>>>>>>>>>reverse time")
# print(time_str)
if time_str is None or time_str == "":
return time_str
parts = time_str.split(":")
if len(parts) != 3:
return time_str
hour = int(parts[0])
minutes = int(parts[1])
seconds_parts = parts[2].split(".")
if len(seconds_parts) != 2:
return time_str
seconds = int(seconds_parts[0])
milliseconds = int(seconds_parts[1])
total_seconds = hour * 3600 + minutes * 60 + seconds + milliseconds / 1000
return str(total_seconds)
except Exception as e:
print(e)
return time_str
def trans_to_seconds(timePoint: str) -> float: def trans_to_seconds(timePoint: str) -> float:
"""将用户输入的时间字符串转换为秒数 """将用户输入的时间字符串转换为秒数
...@@ -47,13 +70,17 @@ def trans_to_seconds(timePoint: str) -> float: ...@@ -47,13 +70,17 @@ def trans_to_seconds(timePoint: str) -> float:
Returns: Returns:
float: 时间字符串对应秒数 float: 时间字符串对应秒数
""" """
time_in_seconds = 0 # time_in_seconds = 0
timePoints = timePoint.split(':') # timePoints = timePoint.split(':')
units = 1 # units = 1
for i in range(len(timePoints) - 1, -1, -1): # for i in range(len(timePoints) - 1, -1, -1):
time_in_seconds += units * float(timePoints[i]) # time_in_seconds += units * float(timePoints[i])
units *= 60 # units *= 60
return time_in_seconds # return time_in_seconds
try:
return float(reverse_time_to_seconds(timePoint))
except Exception as e:
return None
def transfer_second_to_time(sec: str) -> str: def transfer_second_to_time(sec: str) -> str:
"""将秒数转换为"hh:mm:ss.xxx"格式的时间字符串 """将秒数转换为"hh:mm:ss.xxx"格式的时间字符串
...@@ -64,13 +91,75 @@ def transfer_second_to_time(sec: str) -> str: ...@@ -64,13 +91,75 @@ def transfer_second_to_time(sec: str) -> str:
Returns: Returns:
str: "hh:mm:ss.xxx"格式的时间字符串 str: "hh:mm:ss.xxx"格式的时间字符串
""" """
try:
duration = int(float(sec))
hour = int(duration/3600)
minutes = int((duration % 3600)/60)
seconds = int(duration%60)
# msec = round((float(sec) - hour * 3600 - minutes * 60 - seconds) * 1000)
# time = "%02d:%02d:%02d.%03d" % (hour, minutes, seconds, msec)
time = "%02d:%02d:%02d" % (hour, minutes, seconds)
return time
except Exception as e:
print(e)
return sec
def transfer_second_to_all_time(sec: str) -> str:
"""将秒数转换为"hh:mm:ss.xxx"格式的时间字符串
Args:
sec (str): 待转换的描述
Returns:
str: "hh:mm:ss.xxx"格式的时间字符串
"""
try:
duration = int(float(sec)) duration = int(float(sec))
hour = int(duration/3600) hour = int(duration/3600)
minutes = int((duration % 3600)/60) minutes = int((duration % 3600)/60)
seconds = int(duration%60) seconds = int(duration%60)
msec = round((float(sec) - hour * 3600 - minutes * 60 - seconds) * 1000) msec = round((float(sec) - hour * 3600 - minutes * 60 - seconds) * 1000)
time = "%02d:%02d:%02d.%03d" % (hour, minutes, seconds, msec) time = "%02d:%02d:%02d.%03d" % (hour, minutes, seconds, msec)
# time = "%02d:%02d:%02d" % (hour, minutes, seconds)
return time return time
except Exception as e:
print(e)
return sec
def reverse_time_to_seconds(time_str: str) -> str:
"""将"hh:mm:ss.xxx"格式的时间字符串转换为秒数
Args:
time_str (str): 时间字符串,格式为"hh:mm:ss.xxx"
Returns:
float: 对应的秒数
"""
try:
# print(">>>>>>>>>>reverse time")
# print(time_str)
if time_str is None or time_str == "":
return time_str
parts = time_str.split(":")
if len(parts) != 3:
return time_str
hour = int(parts[0])
minutes = int(parts[1])
seconds_parts = parts[2].split(".")
# if len(seconds_parts) != 2:
# return time_str
seconds = int(seconds_parts[0])
# milliseconds = int(seconds_parts[1])
# total_seconds = hour * 3600 + minutes * 60 + seconds + milliseconds / 1000
total_seconds = hour * 3600 + minutes * 60 + seconds
print(str(total_seconds))
return str(total_seconds)
except Exception as e:
print(">>>>>>>>>>reverse time err" + time_str)
print(e)
return time_str
def replace_path_suffix(path: str, new_suffix: str) -> str: def replace_path_suffix(path: str, new_suffix: str) -> str:
"""替换文件路径后缀 """替换文件路径后缀
...@@ -93,7 +182,7 @@ def check_sheet_content(book_path: str) -> bool: ...@@ -93,7 +182,7 @@ def check_sheet_content(book_path: str) -> bool:
bool: True(用户输入的表符合预期) or False(用户输入的表格式不正确,很可能输入错误) bool: True(用户输入的表符合预期) or False(用户输入的表格式不正确,很可能输入错误)
""" """
sheet_heads = get_sheetHead(book_path) sheet_heads = get_sheetHead(book_path)
need_heads = ['起始时间', '终止时间', '字幕', '建议', '解说脚本'] need_heads = ['起始时间', '终止时间', '字幕', '建议旁白字数', '解说脚本']
if len(sheet_heads) == 0: if len(sheet_heads) == 0:
return False return False
...@@ -150,7 +239,8 @@ def get_progress_with_cmd(cmd: str, state=None): ...@@ -150,7 +239,8 @@ def get_progress_with_cmd(cmd: str, state=None):
if result is not None: if result is not None:
elapsed_time = result.groupdict()['time'] elapsed_time = result.groupdict()['time']
# 此处可能会出现进度超过100%,未对数值进行纠正 # 此处可能会出现进度超过100%,未对数值进行纠正
progress = trans_to_seconds(elapsed_time) / trans_to_seconds(duration) # progress = trans_to_seconds(elapsed_time) / trans_to_seconds(duration)
progress = float(get_seconds(elapsed_time)) / float(get_seconds(duration))
state[0] = pre + progress * 0.2 state[0] = pre + progress * 0.2
print(elapsed_time) print(elapsed_time)
print(progress) print(progress)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment