dev

parent 4733180f
@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)
......
...@@ -27,7 +27,7 @@ import difflib ...@@ -27,7 +27,7 @@ import difflib
import re import re
from typing import Tuple, Union from typing import Tuple, Union
from utils import reverse_time_to_seconds
from detect_with_asr import create_sheet, write_to_sheet from detect_with_asr import create_sheet, write_to_sheet
from main_window import MainWindow, Element from main_window import MainWindow, Element
# 字幕的上下边界 # 字幕的上下边界
...@@ -381,11 +381,26 @@ def process_video(video_path: str, begin: float, end: float, book_path: str, she ...@@ -381,11 +381,26 @@ def process_video(video_path: str, begin: float, end: float, book_path: str, she
lastConf = conf lastConf = conf
def add_to_list(mainWindow: MainWindow, element_type: str, li: list): def add_to_list(mainWindow: MainWindow, element_type: str, li: list):
# 默认使用配置文件中的语速
speed = mainWindow.projectContext.speaker_speed
aside_head_time = float(reverse_time_to_seconds(mainWindow.aside_head_time)) if mainWindow.aside_head_time != None else float(0)
st_time_sec, ed_time_sec, subtitle, suggest = li st_time_sec, ed_time_sec, subtitle, suggest = li
print(">>>>>>>>start time:")
print(st_time_sec)
if (st_time_sec != None and st_time_sec != "" and aside_head_time > float(st_time_sec)):
print(">>>>>>need del")
print(st_time_sec)
if not mainWindow.add_head_aside:
new_element = Element('0.00', "", "", "0/100", "",speed)
mainWindow.projectContext.aside_list.append(new_element)
mainWindow.projectContext.all_elements.append(mainWindow.projectContext.aside_list[-1])
mainWindow.last_aside_index = len(mainWindow.projectContext.all_elements) - 1
mainWindow.add_head_aside = True
return
st_time_sec, ed_time_sec = str(st_time_sec), str(ed_time_sec) st_time_sec, ed_time_sec = str(st_time_sec), str(ed_time_sec)
# 默认使用配置文件中的语速
speed = mainWindow.projectContext.speaker_speed
aside = "" aside = ""
i = len(mainWindow.projectContext.all_elements) i = len(mainWindow.projectContext.all_elements)
if element_type == "字幕": if element_type == "字幕":
...@@ -393,12 +408,19 @@ def add_to_list(mainWindow: MainWindow, element_type: str, li: list): ...@@ -393,12 +408,19 @@ def add_to_list(mainWindow: MainWindow, element_type: str, li: list):
new_element.print_self() new_element.print_self()
if mainWindow.last_aside_index != None and mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec == "" and new_element.ed_time_sec != "": if mainWindow.last_aside_index != None and mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec == "" and new_element.ed_time_sec != "":
mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec = new_element.st_time_sec mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec = new_element.st_time_sec
if float(mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec) - float(mainWindow.projectContext.all_elements[mainWindow.last_aside_index].st_time_sec) < 2:
# print(">>>>>>>>>>>remove short aside")
mainWindow.projectContext.aside_list.remove(mainWindow.projectContext.all_elements[mainWindow.last_aside_index])
mainWindow.projectContext.all_elements.remove(mainWindow.projectContext.all_elements[mainWindow.last_aside_index])
mainWindow.last_aside_index = None
mainWindow.projectContext.subtitle_list.append(new_element) mainWindow.projectContext.subtitle_list.append(new_element)
mainWindow.projectContext.all_elements.append(mainWindow.projectContext.subtitle_list[-1]) mainWindow.projectContext.all_elements.append(mainWindow.projectContext.subtitle_list[-1])
else: else:
if i == 0: if i == 0:
st_time_sec = "0.01" st_time_sec = "0.01"
else: else:
if mainWindow.projectContext.all_elements[i - 1].ed_time_sec == "":
return
st_time_sec = "%.2f" % (float(mainWindow.projectContext.all_elements[i - 1].ed_time_sec) + 0.01) st_time_sec = "%.2f" % (float(mainWindow.projectContext.all_elements[i - 1].ed_time_sec) + 0.01)
# 因为暂时没有用到ed_time_sec,所以直接赋值空吧 # 因为暂时没有用到ed_time_sec,所以直接赋值空吧
...@@ -407,6 +429,14 @@ def add_to_list(mainWindow: MainWindow, element_type: str, li: list): ...@@ -407,6 +429,14 @@ def add_to_list(mainWindow: MainWindow, element_type: str, li: list):
new_element.print_self() new_element.print_self()
if mainWindow.last_aside_index != None and mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec == "" and new_element.ed_time_sec != "": if mainWindow.last_aside_index != None and mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec == "" and new_element.ed_time_sec != "":
mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec = new_element.st_time_sec mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec = new_element.st_time_sec
if float(mainWindow.projectContext.all_elements[mainWindow.last_aside_index].ed_time_sec) - float(mainWindow.projectContext.all_elements[mainWindow.last_aside_index].st_time_sec) < 2:
# print(">>>>>>>>>>>remove short aside")
mainWindow.projectContext.aside_list.remove(mainWindow.projectContext.all_elements[mainWindow.last_aside_index])
mainWindow.projectContext.all_elements.remove(mainWindow.projectContext.all_elements[mainWindow.last_aside_index])
mainWindow.last_aside_index = None
new_element.suggest = "0/" + new_element.suggest
if (st_time_sec != None and st_time_sec != "" and aside_head_time > float(st_time_sec)):
return
mainWindow.projectContext.aside_list.append(new_element) mainWindow.projectContext.aside_list.append(new_element)
mainWindow.projectContext.all_elements.append(mainWindow.projectContext.aside_list[-1]) mainWindow.projectContext.all_elements.append(mainWindow.projectContext.aside_list[-1])
mainWindow.last_aside_index = len(mainWindow.projectContext.all_elements) - 1 mainWindow.last_aside_index = len(mainWindow.projectContext.all_elements) - 1
......
...@@ -4,7 +4,7 @@ import openpyxl ...@@ -4,7 +4,7 @@ import openpyxl
from management import Element from management import Element
from utils import reverse_time_to_seconds 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")
...@@ -28,9 +28,9 @@ def read_xls(file_path): ...@@ -28,9 +28,9 @@ 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 = reverse_time_to_seconds(cell_value) if cell_value != None else "" start_time = get_seconds(cell_value) if cell_value != None else ""
if col_index == 1: if col_index == 1:
end_time = reverse_time_to_seconds(cell_value) if cell_value != None else "" end_time = get_seconds(cell_value) if cell_value != None else ""
if col_index == 2: if col_index == 2:
subtitle = cell_value if cell_value != None else "" subtitle = cell_value if cell_value != None else ""
if col_index == 3: if col_index == 3:
...@@ -73,9 +73,9 @@ def read_xlsx(file_path): ...@@ -73,9 +73,9 @@ 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 = reverse_time_to_seconds(cell_value) if cell_value != None else "" start_time = get_seconds(cell_value) if cell_value != None else ""
if col_index == 1: if col_index == 1:
end_time = reverse_time_to_seconds(cell_value) if cell_value != None else "" end_time = get_seconds(cell_value) if cell_value != None else ""
if col_index == 2: if col_index == 2:
subtitle = cell_value if cell_value != None else "" subtitle = cell_value if cell_value != None else ""
if col_index == 3: if col_index == 3:
...@@ -102,8 +102,10 @@ def checkLength(elements): ...@@ -102,8 +102,10 @@ 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("旁白字数没有按照推荐要求") # raise Exception("旁白字数没有按照推荐要求")
if int(element.suggest) < len(element.aside): 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))
......
...@@ -78,6 +78,15 @@ class WorkerThread(QThread): ...@@ -78,6 +78,15 @@ class WorkerThread(QThread):
def refresh(self): def refresh(self):
self.main_window.import_process_sign.emit(self.elements) self.main_window.import_process_sign.emit(self.elements)
class CustomDelegate(QtWidgets.QStyledItemDelegate):
def paint(self, painter, option, index):
# Customize the painting behavior for the specific column
if index.column() == 0: # Replace with the desired column index
option.state |= QtWidgets.QStyle.State_Selected
# option.state |= QtWidgets.QStyle.State_HasFocus
super().paint(painter, option, index)
class MainWindow(QMainWindow, Ui_MainWindow): class MainWindow(QMainWindow, Ui_MainWindow):
EXIT_CODE_REBOOT = -12345678 EXIT_CODE_REBOOT = -12345678
renew_signal = pyqtSignal(str) renew_signal = pyqtSignal(str)
...@@ -268,13 +277,33 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -268,13 +277,33 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.generateMenu) self.generateMenu)
all_tableHead = self.all_tableWidget.horizontalHeader() all_tableHead = self.all_tableWidget.horizontalHeader()
all_tableHead.setSectionResizeMode(QtWidgets.QHeaderView.Fixed)
# all_tableHead.setStyleSheet("QHeaderView::section { padding: 1px;endent: 1px; margin: 1px}")
# all_tableHead.setSectionResizeMode(
# 0, QtWidgets.QHeaderView.Fixed)
# all_tableHead.resizeSection(0,100)
# all_tableHead.setSectionResizeMode(
# 1, QtWidgets.QHeaderView.Fixed)
# all_tableHead.resizeSection(1,100)
all_tableHead.setSectionResizeMode( all_tableHead.setSectionResizeMode(
0, QtWidgets.QHeaderView.ResizeToContents) 2, QtWidgets.QHeaderView.Fixed)
all_tableHead.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) all_tableHead.resizeSection(2,180)
all_tableHead.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch) # all_tableHead.setSectionResizeMode(
# 3, QtWidgets.QHeaderView.Fixed)
# all_tableHead.resizeSection(3,100)
all_tableHead.setSectionResizeMode( all_tableHead.setSectionResizeMode(
3, QtWidgets.QHeaderView.ResizeToContents) 4, QtWidgets.QHeaderView.Fixed)
all_tableHead.resizeSection(4,400)
# all_tableHead.setSectionResizeMode(
# 6, QtWidgets.QHeaderView.Fixed)
# all_tableHead.resizeSection(6,50)
# all_tableHead.setSectionResizeMode(
# 0, QtWidgets.QHeaderView.ResizeToContents)
all_tableHead.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
all_tableHead.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch)
# all_tableHead.setSectionResizeMode(
# 3, QtWidgets.QHeaderView.ResizeToContents)
# all_tableHead.setSectionResizeMode(4, QtWidgets.QHeaderView.Stretch)
aside_header = self.projectContext.aside_header aside_header = self.projectContext.aside_header
self.pb_tableWidget.setColumnCount(len(aside_header)) self.pb_tableWidget.setColumnCount(len(aside_header))
self.pb_tableWidget.setHorizontalHeaderLabels(aside_header) self.pb_tableWidget.setHorizontalHeaderLabels(aside_header)
...@@ -301,6 +330,10 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -301,6 +330,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.zm_tableWidget.itemDoubleClicked.connect(self.change_video_time) self.zm_tableWidget.itemDoubleClicked.connect(self.change_video_time)
# self.all_tableWidget.itemDoubleClicked.connect(self.change_video_time) # self.all_tableWidget.itemDoubleClicked.connect(self.change_video_time)
# self.all_tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) # self.all_tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
# self.all_tableWidget.setItemDelegateForColumn(0, CustomDelegate())
# self.all_tableWidget.setItemDelegate(CustomDelegate())
self.all_tableWidget.itemDoubleClicked.connect(self.writeHistory) self.all_tableWidget.itemDoubleClicked.connect(self.writeHistory)
self.all_tableWidget.itemChanged.connect(self.rewriteHistory) self.all_tableWidget.itemChanged.connect(self.rewriteHistory)
self.all_tableWidget.itemChanged.connect(self.write2ProjectFromContent) self.all_tableWidget.itemChanged.connect(self.write2ProjectFromContent)
...@@ -349,11 +382,35 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -349,11 +382,35 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.origin_rate = 100.00 self.origin_rate = 100.00
self.pb_rate = 100.00 self.pb_rate = 100.00
self.pb_cg_rate = 1.00 self.pb_cg_rate = 1.00
self.sld_video.setFocus()
self.aside_head_time = None
self.add_head_aside = False
# 打印到log文件中 # 打印到log文件中
t = RunThread(funcName=make_print_to_file, args=os.path.join(os.getcwd(), 'log'), name="logging") t = RunThread(funcName=make_print_to_file, args=os.path.join(os.getcwd(), 'log'), name="logging")
print(t) print(t)
make_print_to_file(os.path.join(os.getcwd(), 'log')) make_print_to_file(os.path.join(os.getcwd(), 'log'))
get_focus_thread = RunThread(funcName=self.getFocus, name="get_focus_thread")
get_focus_thread.setDaemon(True)
get_focus_thread.start()
def getFocus(self):
while(True):
if(not self.is_user_editing()):
self.setFocus()
time.sleep(1)
def keyPressEvent(self, event):
if event.key()==Qt.Key_Left:
self.sld_video.setValue(self.sld_video.value() - 5 if self.sld_video.value() >=5 else 0)
self.clickedSlider(self.sld_video.value())
# print(">>>>>>press Left")
if event.key()==Qt.Key_Right:
print(self.sld_video.maximum())
self.sld_video.setValue(self.sld_video.value() + 5 if self.sld_video.value() < self.sld_video.maximum() - 5 else self.sld_video.maximum() -1)
self.clickedSlider(self.sld_video.value())
# print(">>>>>>press Right")
def generateMenu(self, pos): def generateMenu(self, pos):
"""当用户右击字幕旁白表格时,弹出菜单项 """当用户右击字幕旁白表格时,弹出菜单项
...@@ -951,6 +1008,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -951,6 +1008,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
根据当前浮标在时间轴上的位置对应切换视频的播放进度,并更新视频播放进度标签 根据当前浮标在时间轴上的位置对应切换视频的播放进度,并更新视频播放进度标签
""" """
print(">>>>>>>>>>click slider:" + str(position))
if self.player.duration() > 0: # 开始播放后才允许进行跳转 if self.player.duration() > 0: # 开始播放后才允许进行跳转
video_position = int( video_position = int(
(position / self.sld_video.maximum()) * self.player.duration()) (position / self.sld_video.maximum()) * self.player.duration())
...@@ -1139,6 +1197,13 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1139,6 +1197,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.all_tableWidget.clearContents() self.all_tableWidget.clearContents()
st_idx = 0 if need_refresh_all else self.all_tableWidget_idx st_idx = 0 if need_refresh_all else self.all_tableWidget_idx
for i in range(st_idx, len(all_elements)): for i in range(st_idx, len(all_elements)):
# suggest = all_elements[i].suggest
# if suggest != None and suggest != "":
# arrays = suggest.split("/")
# if len(arrays) == 2:
# all_elements[i].suggest = (str(len(all_elements[i].aside)) if all_elements[i].aside != None and all_elements[i].aside != "" else "0") + "/" + arrays[1]
# else:
# all_elements[i].suggest = (str(len(all_elements[i].aside)) if all_elements[i].aside != None and all_elements[i].aside != "" else "0") + "/" + arrays[0]
self.setElememtToTable(self.all_tableWidget, all_elements[i], i) self.setElememtToTable(self.all_tableWidget, all_elements[i], i)
self.all_tableWidget_idx = self.all_tableWidget_idx + 1 self.all_tableWidget_idx = self.all_tableWidget_idx + 1
...@@ -1167,7 +1232,8 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1167,7 +1232,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
elem_list = elem.to_short_list() elem_list = elem.to_short_list()
time_format_col_list = constant.Content.TimeFormatColumns time_format_col_list = constant.Content.TimeFormatColumns
btn = QPushButton() btn = QPushButton()
btn.setText(f"预览{idx}") # btn.setText(f"预览{idx}")
btn.setText(f"预览")
col = len(elem_list) col = len(elem_list)
btn.clicked.connect(self.audio_preview_slot_all) btn.clicked.connect(self.audio_preview_slot_all)
table.setCellWidget(idx, col, btn) table.setCellWidget(idx, col, btn)
...@@ -1178,7 +1244,8 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1178,7 +1244,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
elem_list = elem.to_aside_list() elem_list = elem.to_aside_list()
time_format_col_list = constant.Aside.TimeFormatColumns time_format_col_list = constant.Aside.TimeFormatColumns
btn = QPushButton() btn = QPushButton()
btn.setText(f"预览{idx}") # btn.setText(f"预览{idx}")
btn.setText(f"预览")
col = len(elem_list) col = len(elem_list)
btn.clicked.connect(self.audio_preview_slot) btn.clicked.connect(self.audio_preview_slot)
table.setCellWidget(idx, col, btn) table.setCellWidget(idx, col, btn)
...@@ -1209,9 +1276,11 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1209,9 +1276,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
table.setCellWidget(idx, j, qcombo) table.setCellWidget(idx, j, qcombo)
else: else:
item = QTableWidgetItem(text) item = QTableWidgetItem(text)
item.setTextAlignment(Qt.AlignCenter)
# 设置为不可编辑 # 设置为不可编辑
if self.checkIfTableItemCanChange(table, idx, j) == False: if self.checkIfTableItemCanChange(table, idx, j) == False:
item.setFlags(Qt.ItemIsEnabled) # item.setFlags(Qt.ItemIsEnabled)
print(1)
table.setItem(idx, j, item) table.setItem(idx, j, item)
# 只有Content页的字幕列和 Aside页的字幕列 可编辑 # 只有Content页的字幕列和 Aside页的字幕列 可编辑
...@@ -1264,7 +1333,8 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1264,7 +1333,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# 获取时间 # 获取时间
item = self.all_tableWidget.item(idx.row(), 0) item = self.all_tableWidget.item(idx.row(), 0)
audio_path = None audio_path = None
pos_sec = utils.trans_to_seconds(item.text()) pos_sec = float(utils.get_seconds(self.projectContext.all_elements[int(idx.row())].st_time_sec))
# pos_sec = utils.trans_to_seconds(item.text())
audio_path = os.path.dirname(self.projectContext.excel_path) + ( audio_path = os.path.dirname(self.projectContext.excel_path) + (
"/tmp/%.3f.wav" % pos_sec) "/tmp/%.3f.wav" % pos_sec)
print("待播放的音频文件为", audio_path) print("待播放的音频文件为", audio_path)
...@@ -1332,11 +1402,13 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1332,11 +1402,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
row = item.row() # 获取行数 row = item.row() # 获取行数
col = item.column() # 获取列数 col = item.column() # 获取列数
print("row, col = %s, %s" % (row, col)) print("row, col = %s, %s" % (row, col))
text = item.text() # 获取内容 # text = item.text() # 获取内容
pre_item = self.all_tableWidget.item(row, 0)
text = pre_item.text() # 获取内容
# 停下旁白预览 # 停下旁白预览
self.audio_player.setMedia(QMediaContent()) self.audio_player.setMedia(QMediaContent())
if self.checkIfVideoTimeCanChange(col): # if self.checkIfVideoTimeCanChange(col):
self.video_timer.stop() self.video_timer.stop()
# 双击的时候,就重启计时器,避免他跳转回video.position的地方去。 # 双击的时候,就重启计时器,避免他跳转回video.position的地方去。
self.video_timer.start(1000) self.video_timer.start(1000)
...@@ -1421,7 +1493,15 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1421,7 +1493,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
在set表格的时候(初始化),不会触发。只有双击修改或切换语速时才会触发 在set表格的时候(初始化),不会触发。只有双击修改或切换语速时才会触发
""" """
try: try:
# 不需要set为False
row = item.row() # 获取行数
col = item.column() # 获取列数 注意是column而不是col
# 只有更新语速或者更新旁白,才需要重新生成音频
if col not in constant.Content.ActivateColumns:
return
print(">>>>>>>>>>>into audio")
if self.projectContext.initial_ing == True: if self.projectContext.initial_ing == True:
print(">>>>>>>>>>>>aa11")
return return
if item is None: if item is None:
print("WRONG!!!! item Is None") print("WRONG!!!! item Is None")
...@@ -1431,17 +1511,13 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1431,17 +1511,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
return return
self.set_user_edit(False) self.set_user_edit(False)
# 不需要set为False
row = item.row() # 获取行数
col = item.column() # 获取列数 注意是column而不是col
# 只有更新语速或者更新旁白,才需要重新生成音频
if col not in constant.Content.ActivateColumns:
return
# 停止预览,释放当前占用的音频文件 # 停止预览,释放当前占用的音频文件
self.audio_player.setMedia(QMediaContent()) self.audio_player.setMedia(QMediaContent())
# 合成这一段语音 # 合成这一段语音
print(">>>>>>>>start audio")
self.do_generate_audio_by_aside_row_all(int(row)) self.do_generate_audio_by_aside_row_all(int(row))
except Exception as e: except Exception as e:
print(e) print(e)
...@@ -1457,8 +1533,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1457,8 +1533,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
from speech_synthesis import speech_synthesis, Speaker, choose_speaker from speech_synthesis import speech_synthesis, Speaker, choose_speaker
audio_dir = os.path.dirname(self.projectContext.excel_path) audio_dir = os.path.dirname(self.projectContext.excel_path)
wav_path = audio_dir + \ wav_path = audio_dir + \
'/tmp/%.3f.wav' % float( '/tmp/%.3f.wav' % float(utils.reverse_time_to_seconds(self.projectContext.all_elements[int(row)].st_time_sec))
self.projectContext.all_elements[int(row)].st_time_sec)
print("wav_path:", wav_path) print("wav_path:", wav_path)
try: try:
# speed_info = self.projectContext.speaker_speed # speed_info = self.projectContext.speaker_speed
...@@ -1675,6 +1750,22 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1675,6 +1750,22 @@ class MainWindow(QMainWindow, Ui_MainWindow):
col = item.column() # 获取列数 注意是column而不是col哦 col = item.column() # 获取列数 注意是column而不是col哦
text = item.text() # 获取内容 text = item.text() # 获取内容
pre_item = self.all_tableWidget.item(row, col - 1)
suggest = pre_item.text()
if suggest != None and suggest != "":
arrays = suggest.split("/")
if len(arrays) == 2:
suggest = str(len(text)) + "/" + arrays[1]
if len(text) > int(arrays[1]):
self.import_excel_dialog.show_with_msg("旁白字数不能超过推荐字数")
return
else:
suggest = str(len(text)) + "/" + arrays[0]
if len(text) > int(arrays[0]):
self.import_excel_dialog.show_with_msg("旁白字数不能超过推荐字数")
return
if col not in constant.Content.ActivateColumns: if col not in constant.Content.ActivateColumns:
return return
# 更新【字幕旁白】这个tab里的字,如果是语速,那就更新语速这一列,如果是旁白,那就更新旁白这一列 # 更新【字幕旁白】这个tab里的字,如果是语速,那就更新语速这一列,如果是旁白,那就更新旁白这一列
...@@ -1692,6 +1783,12 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1692,6 +1783,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# self.all_tableWidget.setItem( # self.all_tableWidget.setItem(
# int(idx), constant.Content.SpeedColumnNumber, QTableWidgetItem(text)) # int(idx), constant.Content.SpeedColumnNumber, QTableWidgetItem(text))
self.projectContext.refresh_speed(row, text) self.projectContext.refresh_speed(row, text)
# self.all_tableWidget_idx = int(row)
# self.set_table_to_window(False)
pre_item.setText(suggest)
except Exception as e: except Exception as e:
print(e) print(e)
...@@ -1784,8 +1881,11 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1784,8 +1881,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
if not self.is_user_editing() and self.curTab == 0: if not self.is_user_editing() and self.curTab == 0:
all_elements = self.projectContext.all_elements all_elements = self.projectContext.all_elements
for i in range(len(all_elements) - 1, -1, -1): for i in range(len(all_elements) - 1, -1, -1):
if utils.trans_to_seconds(all_elements[i].st_time_sec) <= cur_time: # if utils.trans_to_seconds(all_elements[i].st_time_sec) <= cur_time:
if float(utils.get_seconds(all_elements[i].st_time_sec)) <= cur_time:
self.all_tableWidget.selectRow(i) self.all_tableWidget.selectRow(i)
# self.all_tableWidget.setCurrentCell(i, 0) # 选中整行
# self.all_tableWidget.setStyleSheet("QTableView::item:selected { background-color: yellow; }") # 应用高亮样式
break break
# elif self.curTab == 1: # elif self.curTab == 1:
# subtitle_list = self.projectContext.subtitle_list # subtitle_list = self.projectContext.subtitle_list
...@@ -1869,9 +1969,9 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1869,9 +1969,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# else: # else:
# self.add_line_operation_slot(idx, str(cur_time), str(cur_time+1), "", "插入旁白,推荐字数为0", "", self.projectContext.speaker_speed) # self.add_line_operation_slot(idx, str(cur_time), str(cur_time+1), "", "插入旁白,推荐字数为0", "", self.projectContext.speaker_speed)
if idx < len(self.projectContext.all_elements) - 1: if idx < len(self.projectContext.all_elements) - 1:
self.add_line_operation_slot(idx, str(cur_time), self.projectContext.all_elements[idx+1].st_time_sec, "", "0", "", self.projectContext.speaker_speed) self.add_line_operation_slot(idx, str(cur_time), self.projectContext.all_elements[idx+1].st_time_sec, "", "0/100", "", self.projectContext.speaker_speed)
else: else:
self.add_line_operation_slot(idx, str(cur_time), str(cur_time+1), "", "0", "", self.projectContext.speaker_speed) self.add_line_operation_slot(idx, str(cur_time), str(cur_time+1), "", "0/100", "", self.projectContext.speaker_speed)
def insert_aside_from_cur_time(self,cur_time:float): def insert_aside_from_cur_time(self,cur_time:float):
...@@ -1909,7 +2009,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -1909,7 +2009,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
""" """
idx = 0 idx = 0
while idx < len(self.projectContext.all_elements): while idx < len(self.projectContext.all_elements):
if float(cur_time) < float(self.projectContext.all_elements[idx].st_time_sec): if float(cur_time) < float(utils.reverse_time_to_seconds(self.projectContext.all_elements[idx].st_time_sec)):
break break
idx += 1 idx += 1
return idx return idx
...@@ -2008,8 +2108,9 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -2008,8 +2108,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
aside = new_element.aside aside = new_element.aside
subtitle = new_element.subtitle subtitle = new_element.subtitle
print(">>>>>>aside: " + aside) print(">>>>>>aside: " + aside)
insert_time = self.getSeconds(start_time) print(start_time)
cur_time = round(insert_time/1000, 3) # insert_time = self.getSeconds(start_time)
# cur_time = round(insert_time/1000, 3)
row, same_flag = self.removeByCurTime(start_time, aside) row, same_flag = self.removeByCurTime(start_time, aside)
# #该旁白没有被改动 # #该旁白没有被改动
if same_flag: if same_flag:
...@@ -2273,3 +2374,12 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -2273,3 +2374,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.projectContext.all_elements[int(all_idx)].speed = combo.currentText() self.projectContext.all_elements[int(all_idx)].speed = combo.currentText()
self.all_tableWidget.setItem(int(all_idx), constant.Content.SpeedColumnNumber, QTableWidgetItem(combo.currentText())) self.all_tableWidget.setItem(int(all_idx), constant.Content.SpeedColumnNumber, QTableWidgetItem(combo.currentText()))
self.do_generate_audio_by_aside_row_all(int(row)) self.do_generate_audio_by_aside_row_all(int(row))
def confirm_head_aside(self):
print(">>>>>>>>>>>>>confirm_head_aside")
position = self.sld_video.value()
video_position = int(
(position / self.sld_video.maximum()) * self.player.duration())
self.aside_head_time = utils.transfer_second_to_time(
str(round(video_position/1000, 2)))
self.import_excel_dialog.show_with_msg("定位成功:" + self.aside_head_time)
\ No newline at end of file
...@@ -334,6 +334,7 @@ class Ui_MainWindow(object): ...@@ -334,6 +334,7 @@ class Ui_MainWindow(object):
self.all_tableWidget.setObjectName("all_tableWidget") self.all_tableWidget.setObjectName("all_tableWidget")
self.all_tableWidget.setColumnCount(0) self.all_tableWidget.setColumnCount(0)
self.all_tableWidget.setRowCount(0) self.all_tableWidget.setRowCount(0)
# self.all_tableWidget.setStyleSheet(f"QTableWidget::item:selected:enabled {{ background-color: blue; color: white; }}")
self.all_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.all_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.horizontalLayout_4.addWidget(self.all_tableWidget) self.horizontalLayout_4.addWidget(self.all_tableWidget)
self.tabWidget.addTab(self.all_tab, "") self.tabWidget.addTab(self.all_tab, "")
...@@ -459,6 +460,8 @@ class Ui_MainWindow(object): ...@@ -459,6 +460,8 @@ class Ui_MainWindow(object):
self.menu.setObjectName("menu") self.menu.setObjectName("menu")
self.menu_2 = QtWidgets.QMenu(self.menubar) self.menu_2 = QtWidgets.QMenu(self.menubar)
self.menu_2.setObjectName("menu_2") self.menu_2.setObjectName("menu_2")
self.menu_7 = QtWidgets.QMenu(self.menubar)
self.menu_7.setObjectName("menu_7")
# self.menu_3 = QtWidgets.QMenu(self.menubar) # self.menu_3 = QtWidgets.QMenu(self.menubar)
# self.menu_3.setObjectName("menu_3") # self.menu_3.setObjectName("menu_3")
self.menu_4 = QtWidgets.QMenu(self.menubar) self.menu_4 = QtWidgets.QMenu(self.menubar)
...@@ -499,14 +502,16 @@ class Ui_MainWindow(object): ...@@ -499,14 +502,16 @@ class Ui_MainWindow(object):
self.action_4.setEnabled(False) self.action_4.setEnabled(False)
self.action_5 = QtWidgets.QAction("旁白导入",self,triggered=self.import_excel) self.action_5 = QtWidgets.QAction("旁白导入",self,triggered=self.import_excel)
self.action_5.setEnabled(False) self.action_5.setEnabled(False)
self.action_6 = QtWidgets.QAction("字幕上边界++",self,triggered=self.up_ocr) self.action_6 = QtWidgets.QAction("字幕上边界上移",self,triggered=self.up_ocr)
self.action_6.setEnabled(True) self.action_6.setEnabled(True)
self.action_7 = QtWidgets.QAction("字幕上边界--",self,triggered=self.down_ocr) self.action_7 = QtWidgets.QAction("字幕上边界下移",self,triggered=self.down_ocr)
self.action_7.setEnabled(True) self.action_7.setEnabled(True)
self.action_8 = QtWidgets.QAction("字幕下边界++",self,triggered=self.up_ocr_bottom) self.action_8 = QtWidgets.QAction("字幕下边界上移",self,triggered=self.up_ocr_bottom)
self.action_8.setEnabled(True) self.action_8.setEnabled(True)
self.action_9 = QtWidgets.QAction("字幕下边界--",self,triggered=self.down_ocr_bottom) self.action_9 = QtWidgets.QAction("字幕下边界下移",self,triggered=self.down_ocr_bottom)
self.action_9.setEnabled(True) self.action_9.setEnabled(True)
self.action_10 = QtWidgets.QAction("片头旁白定位",self,triggered=self.confirm_head_aside)
self.action_10.setEnabled(True)
# self.action_3.setObjectName("action_3") # self.action_3.setObjectName("action_3")
# self.action_4 = QtWidgets.QAction(MainWindow) # self.action_4 = QtWidgets.QAction(MainWindow)
...@@ -542,13 +547,16 @@ class Ui_MainWindow(object): ...@@ -542,13 +547,16 @@ class Ui_MainWindow(object):
# self.menu_3.addSeparator() # self.menu_3.addSeparator()
self.menubar.addAction(self.menu.menuAction()) self.menubar.addAction(self.menu.menuAction())
self.menubar.addAction(self.menu_2.menuAction()) self.menubar.addAction(self.menu_2.menuAction())
self.menubar.addAction(self.menu_7.menuAction())
self.menubar.addAction(self.action_3) self.menubar.addAction(self.action_3)
self.menubar.addAction(self.action_4) self.menubar.addAction(self.action_4)
self.menubar.addAction(self.action_5) self.menubar.addAction(self.action_5)
self.menubar.addAction(self.action_6)
self.menubar.addAction(self.action_7) self.menu_7.addAction(self.action_6)
self.menubar.addAction(self.action_8) self.menu_7.addAction(self.action_7)
self.menubar.addAction(self.action_9) self.menu_7.addAction(self.action_8)
self.menu_7.addAction(self.action_9)
self.menu_7.addAction(self.action_10)
# self.menubar.addAction(self.menu_5.menuAction()) # self.menubar.addAction(self.menu_5.menuAction())
# self.menubar.addAction(self.menu_6.menuAction()) # self.menubar.addAction(self.menu_6.menuAction())
# self.menubar.addAction(self.menu_3.menuAction()) # self.menubar.addAction(self.menu_3.menuAction())
...@@ -572,6 +580,7 @@ class Ui_MainWindow(object): ...@@ -572,6 +580,7 @@ class Ui_MainWindow(object):
self.pb_label.setText(_translate("MainWindow", "刻度")) self.pb_label.setText(_translate("MainWindow", "刻度"))
self.menu.setTitle(_translate("MainWindow", "文件")) self.menu.setTitle(_translate("MainWindow", "文件"))
self.menu_2.setTitle(_translate("MainWindow", "编辑")) self.menu_2.setTitle(_translate("MainWindow", "编辑"))
self.menu_7.setTitle(_translate("MainWindow", "旁白检测准备"))
# self.menu_3.setTitle(_translate("MainWindow", "功能按键")) # self.menu_3.setTitle(_translate("MainWindow", "功能按键"))
self.menu_4.setTitle(_translate("MainWindow", "旁白区间检测")) self.menu_4.setTitle(_translate("MainWindow", "旁白区间检测"))
self.menu_5.setTitle(_translate("MainWindow", "旁白音频合成")) self.menu_5.setTitle(_translate("MainWindow", "旁白音频合成"))
......
...@@ -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, reverse_time_to_seconds 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):
"""复写线程类,用于解决主线程无法捕捉子线程中异常的问题 """复写线程类,用于解决主线程无法捕捉子线程中异常的问题
...@@ -186,7 +186,7 @@ class ProjectContext: ...@@ -186,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"]
...@@ -232,7 +232,6 @@ class ProjectContext: ...@@ -232,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)
...@@ -375,8 +374,9 @@ class ProjectContext: ...@@ -375,8 +374,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):
...@@ -457,8 +457,22 @@ def write_to_sheet(path: str, sheet_name: str, valuelist: list): ...@@ -457,8 +457,22 @@ def write_to_sheet(path: str, sheet_name: str, valuelist: list):
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] = transfer_second_to_time(value[0]) if value[0] != "" else "" # value[0] = get_seconds(value[0]) if value[0] != "" else ""
value[1] = transfer_second_to_time(value[1]) if value[1] != "" 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]
print(">>>>>>>>>>>>>>>>>>>suggest:"+suggest)
if suggest != None and suggest != "":
arrays = suggest.split("/")
if len(arrays) == 2:
value[3] = str(len(value[4])) + "/" + arrays[1]
print(">>>>>>>>>>>>v3:" + value[3])
else:
value[3] = str(len(value[4])) + "/" + arrays[0]
print(">>>>>>>>>>>>v3:" + value[3])
index = len(value) index = len(value)
cur_row = sheet.max_row cur_row = sheet.max_row
......
...@@ -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
{"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": "eagle\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,
......
...@@ -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,8 +23,8 @@ from typing import Tuple ...@@ -23,8 +23,8 @@ 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
...@@ -82,8 +82,11 @@ def choose_speaker(speaker_name: str) -> Speaker: ...@@ -82,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
...@@ -106,41 +109,42 @@ def speech_synthesis(text: str, output_file: str, speaker: Speaker, speed: float ...@@ -106,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):
......
...@@ -56,7 +56,20 @@ def change_project_path(path): ...@@ -56,7 +56,20 @@ 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_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
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_EnableHighDpiScaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv) app = QApplication(sys.argv)
......
...@@ -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 = []
......
...@@ -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,17 +70,43 @@ def trans_to_seconds(timePoint: str) -> float: ...@@ -47,17 +70,43 @@ 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"格式的时间字符串
Args:
sec (str): 待转换的描述
Returns:
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: Args:
sec (str): 待转换的描述 sec (str): 待转换的描述
...@@ -71,6 +120,7 @@ def transfer_second_to_time(sec: str) -> str: ...@@ -71,6 +120,7 @@ def transfer_second_to_time(sec: str) -> str:
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: except Exception as e:
print(e) print(e)
...@@ -97,13 +147,13 @@ def reverse_time_to_seconds(time_str: str) -> str: ...@@ -97,13 +147,13 @@ def reverse_time_to_seconds(time_str: str) -> str:
hour = int(parts[0]) hour = int(parts[0])
minutes = int(parts[1]) minutes = int(parts[1])
seconds_parts = parts[2].split(".") seconds_parts = parts[2].split(".")
if len(seconds_parts) != 2: # if len(seconds_parts) != 2:
return time_str # return time_str
seconds = int(seconds_parts[0]) seconds = int(seconds_parts[0])
milliseconds = int(seconds_parts[1]) # milliseconds = int(seconds_parts[1])
total_seconds = hour * 3600 + minutes * 60 + seconds + milliseconds / 1000 # total_seconds = hour * 3600 + minutes * 60 + seconds + milliseconds / 1000
total_seconds = hour * 3600 + minutes * 60 + seconds
print(str(total_seconds)) print(str(total_seconds))
return str(total_seconds) return str(total_seconds)
except Exception as e: except Exception as e:
...@@ -189,7 +239,8 @@ def get_progress_with_cmd(cmd: str, state=None): ...@@ -189,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