Commit 262fe4ee authored by 翟艳秋(20软)'s avatar 翟艳秋(20软)

feat: change the definition of project, fix some bugs and optimize the progress of export

parent 146a444a
__pycache__
.vscode
.idea
from PyQt5.QtCore import Qt, QRect, QPointF
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QSlider, QWidget, QVBoxLayout, QProxyStyle, QStyle, QStyleOptionSlider
class SliderStyle(QProxyStyle):
def subControlRect(self, control, option, subControl, widget=None):
rect = super(SliderStyle, self).subControlRect(
control, option, subControl, widget)
if subControl == QStyle.SC_SliderHandle:
if option.orientation == Qt.Horizontal:
# 高度1/3
radius = int(widget.height() / 3)
offset = int(radius / 3)
if option.state & QStyle.State_MouseOver:
x = min(rect.x() - offset, widget.width() - radius)
x = x if x >= 0 else 0
else:
radius = offset
x = min(rect.x(), widget.width() - radius)
rect = QRect(x, int((rect.height() - radius) / 2),
radius, radius)
else:
# 宽度1/3
radius = int(widget.width() / 3)
offset = int(radius / 3)
if option.state & QStyle.State_MouseOver:
y = min(rect.y() - offset, widget.height() - radius)
y = y if y >= 0 else 0
else:
radius = offset
y = min(rect.y(), widget.height() - radius)
rect = QRect(int((rect.width() - radius) / 2),
y, radius, radius)
return rect
return rect
class PaintQSlider(QSlider):
def __init__(self, *args, **kwargs):
super(PaintQSlider, self).__init__(*args, **kwargs)
# 设置代理样式,主要用于计算和解决鼠标点击区域
self.setStyle(SliderStyle())
def paintEvent(self, _):
option = QStyleOptionSlider()
self.initStyleOption(option)
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
# 中间圆圈的位置
rect = self.style().subControlRect(
QStyle.CC_Slider, option, QStyle.SC_SliderHandle, self)
# 画中间白色线条
painter.setPen(Qt.white)
painter.setBrush(Qt.white)
if self.orientation() == Qt.Horizontal:
y = self.height() / 2
painter.drawLine(QPointF(0, y), QPointF(self.width(), y))
else:
x = self.width() / 2
painter.drawLine(QPointF(x, 0), QPointF(x, self.height()))
# 画圆
painter.setPen(Qt.NoPen)
if option.state & QStyle.State_MouseOver: # 双重圆
# 半透明大圆
r = rect.height() / 2
painter.setBrush(QColor(255, 255, 255, 100))
painter.drawRoundedRect(rect, r, r)
# 实心小圆(上下左右偏移4)
rect = rect.adjusted(4, 4, -4, -4)
r = rect.height() / 2
painter.setBrush(QColor(255, 255, 255, 255))
painter.drawRoundedRect(rect, r, r)
# 绘制文字
painter.setPen(Qt.white)
if self.orientation() == Qt.Horizontal: # 在上方绘制文字
x, y = rect.x(), rect.y() - rect.height() - 2
else: # 在左侧绘制文字
x, y = rect.x() - rect.width() - 2, rect.y()
painter.drawText(
x, y, rect.width(), rect.height(),
Qt.AlignCenter, str(self.value())
)
else: # 实心圆
r = rect.height() / 2
painter.setBrush(Qt.white)
painter.drawRoundedRect(rect, r, r)
# class Window(QWidget):
# def __init__(self, *args, **kwargs):
# super(Window, self).__init__(*args, **kwargs)
# self.setAttribute(Qt.WA_StyledBackground, True)
# layout = QVBoxLayout(self)
# layout.addWidget(PaintQSlider(Qt.Vertical, self, minimumWidth=90))
# layout.addWidget(PaintQSlider(Qt.Horizontal, self, minimumHeight=90))
# if __name__ == '__main__':
# import sys
# from PyQt5.QtWidgets import QApplication
# app = QApplication(sys.argv)
# w = Window()
# w.setStyleSheet('QWidget {background: gray;}')
# w.show()
# sys.exit(app.exec_())
\ No newline at end of file
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'd:\AddCaption\cur_version\accessibility_movie_2\create_dialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(408, 238)
self.gridLayoutWidget = QtWidgets.QWidget(Dialog)
self.gridLayoutWidget.setGeometry(QtCore.QRect(20, 50, 361, 91))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.root_input = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.root_input.setObjectName("root_input")
self.gridLayout.addWidget(self.root_input, 1, 1, 1, 1)
self.get_dir = QtWidgets.QPushButton(self.gridLayoutWidget)
self.get_dir.setObjectName("get_dir")
self.gridLayout.addWidget(self.get_dir, 1, 2, 1, 1)
self.rootLabel = QtWidgets.QLabel(self.gridLayoutWidget)
self.rootLabel.setObjectName("rootLabel")
self.gridLayout.addWidget(self.rootLabel, 1, 0, 1, 1)
self.nameLabel = QtWidgets.QLabel(self.gridLayoutWidget)
self.nameLabel.setObjectName("nameLabel")
self.gridLayout.addWidget(self.nameLabel, 0, 0, 1, 1)
self.name_input = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.name_input.setObjectName("name_input")
self.gridLayout.addWidget(self.name_input, 0, 1, 1, 1)
self.widget = QtWidgets.QWidget(Dialog)
self.widget.setGeometry(QtCore.QRect(90, 180, 201, 25))
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.confirm = QtWidgets.QPushButton(self.widget)
self.confirm.setObjectName("confirm")
self.horizontalLayout.addWidget(self.confirm)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.cancel = QtWidgets.QPushButton(self.widget)
self.cancel.setObjectName("cancel")
self.horizontalLayout.addWidget(self.cancel)
self.horizontalLayout.setStretch(0, 1)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.get_dir.setText(_translate("Dialog", "打开文件夹"))
self.rootLabel.setText(_translate("Dialog", "工程文件夹"))
self.nameLabel.setText(_translate("Dialog", "工程名称"))
self.confirm.setText(_translate("Dialog", "确认"))
self.cancel.setText(_translate("Dialog", "取消"))
......@@ -35,6 +35,7 @@ class Assemble_Dialog(QDialog, Ui_Dialog):
self.lineEdit_3.setText(projectContext.speaker_info)
self.lineEdit_4.setText(projectContext.speaker_speed)
# self.show.connect(self.init_self_slot)
def init_self(self):
# print("self.projectContext.speaker_info", self.projectContext.speaker_info)
self.lineEdit.setText(self.projectContext.video_path)
......
......@@ -68,5 +68,3 @@ class Ui_Dialog(object):
self.pushButton_2.setText(_translate("Dialog", "表格路径"))
self.label_3.setText(_translate("Dialog", "旁白说话人:"))
self.label_4.setText(_translate("Dialog", "旁白语速:"))
\ No newline at end of file
{"video_path": "F:/mystudy/Eagle/test2/\u4f55\u4ee5\u7b19\u7bab\u9ed8.mp4", "excel_path": "F:/mystudy/Eagle/test2/\u4f55\u4ee5\u7b19\u7bab\u9ed8.xlsx", "detection_info": {"detected": false, "nd_process": 0.12199690880989182, "last_time": 789.32, "caption_boundings": [], "has_subtitle": true}, "speaker_info": {"speaker_id": "\u6653\u6653\uff0c\u5973\uff0c\u5e74\u8f7b\u4eba", "speaker_speed": "1.00(4\u5b57/\u79d2)"}}
\ 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_id": "\u6653\u6653\uff0c\u5973\uff0c\u5e74\u8f7b\u4eba", "speaker_speed": "1.10(4.5\u5b57/\u79d2)"}}
\ No newline at end of file
import os
from PyQt5.QtCore import *;
from PyQt5.QtGui import *;
from PyQt5.QtWidgets import *;
from create_dialog_ui import Ui_Dialog
from prompt_dialog import Prompt_Dialog
class Create_Dialog(QDialog, Ui_Dialog):
def __init__(self, projectContext):
super(Create_Dialog, self).__init__()
self.projectConext = projectContext
self.setupUi(self)
self.setWindowTitle("新建工程")
self.get_dir.clicked.connect(self.choose_root)
self.confirm.clicked.connect(self.create_project)
self.prompt_dialog = Prompt_Dialog()
self.cancel.clicked.connect(self.close_dialog)
def choose_root(self):
root_info = QFileDialog.getExistingDirectory(self, "选择工程文件夹", os.getcwd())
self.root_input.setText(root_info)
def create_project(self):
self.project_name = self.name_input.text()
self.dir_path = self.root_input.text()
if os.path.exists(self.dir_path) and len(self.project_name) > 0:
self.project_path = os.path.join(self.dir_path, self.project_name)
if os.path.exists(self.project_path):
self.prompt_dialog.show_with_msg("已存在同名文件夹")
return
os.mkdir(self.project_path)
self.projectConext.project_base_dir = self.project_path
self.close()
elif len(self.project_name) == 0:
self.prompt_dialog.show_with_msg("请输入工程名称")
else:
self.prompt_dialog.show_with_msg("请输入合法文件夹路径")
def close_dialog(self):
self.close()
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>408</width>
<height>238</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>50</y>
<width>361</width>
<height>91</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="topMargin">
<number>0</number>
</property>
<item row="1" column="1">
<widget class="QLineEdit" name="root_input"/>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="get_dir">
<property name="text">
<string>打开文件夹</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="rootLabel">
<property name="text">
<string>工程文件夹</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>工程名称</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="name_input"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>90</x>
<y>180</y>
<width>201</width>
<height>25</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0">
<item>
<widget class="QPushButton" name="confirm">
<property name="text">
<string>确认</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancel">
<property name="text">
<string>取消</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'd:\AddCaption\cur_version\accessibility_movie_2\create_dialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(408, 238)
self.gridLayoutWidget = QtWidgets.QWidget(Dialog)
self.gridLayoutWidget.setGeometry(QtCore.QRect(20, 50, 361, 91))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.root_input = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.root_input.setObjectName("root_input")
self.gridLayout.addWidget(self.root_input, 1, 1, 1, 1)
self.get_dir = QtWidgets.QPushButton(self.gridLayoutWidget)
self.get_dir.setObjectName("get_dir")
self.gridLayout.addWidget(self.get_dir, 1, 2, 1, 1)
self.rootLabel = QtWidgets.QLabel(self.gridLayoutWidget)
self.rootLabel.setObjectName("rootLabel")
self.gridLayout.addWidget(self.rootLabel, 1, 0, 1, 1)
self.nameLabel = QtWidgets.QLabel(self.gridLayoutWidget)
self.nameLabel.setObjectName("nameLabel")
self.gridLayout.addWidget(self.nameLabel, 0, 0, 1, 1)
self.name_input = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.name_input.setObjectName("name_input")
self.gridLayout.addWidget(self.name_input, 0, 1, 1, 1)
self.widget = QtWidgets.QWidget(Dialog)
self.widget.setGeometry(QtCore.QRect(90, 180, 201, 25))
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.confirm = QtWidgets.QPushButton(self.widget)
self.confirm.setObjectName("confirm")
self.horizontalLayout.addWidget(self.confirm)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.cancel = QtWidgets.QPushButton(self.widget)
self.cancel.setObjectName("cancel")
self.horizontalLayout.addWidget(self.cancel)
self.horizontalLayout.setStretch(0, 1)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.get_dir.setText(_translate("Dialog", "打开文件夹"))
self.rootLabel.setText(_translate("Dialog", "工程文件夹"))
self.nameLabel.setText(_translate("Dialog", "工程名称"))
self.confirm.setText(_translate("Dialog", "确认"))
self.cancel.setText(_translate("Dialog", "取消"))
......@@ -12,8 +12,9 @@ class Detect_Dialog(QDialog, Ui_Dialog):
#开始检测信号,传参分别是movie路径和输出表格路径
start_detect_signal = pyqtSignal(str, str)
def __init__(self):
def __init__(self, projectContext):
super(Detect_Dialog, self).__init__()
self.projectContext = projectContext
self.setupUi(self)
self.setWindowTitle("检测")
self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText("开始检测")
......@@ -21,12 +22,19 @@ class Detect_Dialog(QDialog, Ui_Dialog):
self.pushButton.clicked.connect(self.openFile)
self.pushButton_2.clicked.connect(self.openTableFile)
self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).clicked.connect(self.start_detect)
def init_self(self):
self.lineEdit.setText(self.projectContext.video_path)
self.lineEdit_2.setText(self.projectContext.excel_path)
def openFile(self):
file_info = QFileDialog.getOpenFileNames(self, '选择视频', os.getcwd(), "Video Files(*.mp4 *.rmvb *mkv *avi)")
root_dir = os.getcwd() if self.projectContext.video_path is None else os.path.dirname(self.projectContext.video_path)
file_info = QFileDialog.getOpenFileNames(self, '选择视频', root_dir, "Video Files(*.mp4 *.rmvb *mkv *avi)")
file_name, ok = validate_and_get_filepath(file_info)
if ok:
self.lineEdit.setText(file_name)
self.lineEdit_2.setText(replace_path_suffix(file_info[0][0], ".xlsx"))
def openTableFile(self):
now_path = os.path.join(os.getcwd(), self.lineEdit.text())
now_path = now_path.replace(os.path.splitext(now_path)[-1], ".xlsx")
......@@ -37,6 +45,7 @@ class Detect_Dialog(QDialog, Ui_Dialog):
print(file_name, ok)
if ok:
self.lineEdit_2.setText(file_name)
def start_detect(self):
# 发出一个信号,开始检测了
# 版本1.0:(当前版本)
......
......@@ -44,7 +44,7 @@
<x>20</x>
<y>70</y>
<width>72</width>
<height>15</height>
<height>16</height>
</rect>
</property>
<property name="text">
......@@ -55,9 +55,9 @@
<property name="geometry">
<rect>
<x>100</x>
<y>70</y>
<y>68</y>
<width>211</width>
<height>21</height>
<height>20</height>
</rect>
</property>
</widget>
......@@ -65,9 +65,9 @@
<property name="geometry">
<rect>
<x>390</x>
<y>60</y>
<width>93</width>
<height>28</height>
<y>63</y>
<width>110</width>
<height>30</height>
</rect>
</property>
<property name="text">
......@@ -80,7 +80,7 @@
<x>20</x>
<y>130</y>
<width>72</width>
<height>15</height>
<height>16</height>
</rect>
</property>
<property name="text">
......@@ -91,9 +91,9 @@
<property name="geometry">
<rect>
<x>100</x>
<y>130</y>
<y>128</y>
<width>211</width>
<height>21</height>
<height>20</height>
</rect>
</property>
</widget>
......@@ -101,9 +101,9 @@
<property name="geometry">
<rect>
<x>390</x>
<y>130</y>
<width>101</width>
<height>31</height>
<y>123</y>
<width>110</width>
<height>30</height>
</rect>
</property>
<property name="text">
......
......@@ -110,12 +110,12 @@ def detect_with_asr(video_path: str, book_path: str, start_time=0, end_time=-1,
if __name__ == '__main__':
create_sheet("./xxxxxx.xlsx", "abc", [["起始时间", "终止时间", "字幕", '建议', '解说脚本']])
# write_to_sheet("./xxx.xlsx", "abc", ["qssj", "zzsj", "zm", 'jy', 'pb'])
pass
# start_time = time.time()
# # 给定待处理的视频路径
# video_path = 'D:/Downloads/芳H.[更多请关注公众号:吃瓜族].mp4'
#
# detect_with_asr(video_path, "fanghua.xlsx", 0, 8122, [None])
# print("处理视频 {} 需要时长为{} ".format(os.path.basename(video_path), time.time() - start_time))
# create_sheet("./xxxxxx.xlsx", "abc", [["起始时间", "终止时间", "字幕", '建议', '解说脚本']])
# # write_to_sheet("./xxx.xlsx", "abc", ["qssj", "zzsj", "zm", 'jy', 'pb'])
# pass
start_time = time.time()
# 给定待处理的视频路径
video_path = 'D:\software\WPF_JJDown_v1.229.1\[WPF]JJDown\Download\大闹天宫.mp4'
detect_with_asr(video_path, "大闹天宫.xlsx", 0, 6754)
print("处理视频 {} 需要时长为{} ".format(os.path.basename(video_path), time.time() - start_time))
......@@ -227,6 +227,15 @@ def process_video(video_path: str, begin: float, end: float, book_path: str, she
sheet_name (str): 输出表格中的表名
state (optional): 用于通信的状态关键字. Defaults to None.
"""
global normal_speed
if mainWindow.projectContext.speaker_speed is not None:
normal_speed = float(mainWindow.projectContext.speaker_speed.split('(')[1].split('字')[0])
sz = len(mainWindow.projectContext.all_elements)
if sz == 0:
last_time = begin
else:
last_time = float(mainWindow.projectContext.all_elements[sz - 1].ed_time_sec) + 0.01
print("当前使用的语速为", normal_speed)
if state is None:
state = [None]
video = cv2.VideoCapture(video_path)
......@@ -262,9 +271,9 @@ def process_video(video_path: str, begin: float, end: float, book_path: str, she
if cnt % int(fps / 4) == 0:
# 更新当前工程的检测进度
if pre_state is None:
state[0] = float((cur_time - begin) / (end - begin))
state[0] = float(cur_time/ end)
else:
state[0] = min(0.9999, pre_state + float((cur_time - begin) / (end - begin)))
state[0] = min(0.9999, float(cur_time / end))
mainWindow.projectContext.nd_process = state[0]
mainWindow.projectContext.last_time = cur_time
......@@ -278,9 +287,9 @@ def process_video(video_path: str, begin: float, end: float, book_path: str, she
elif lastSubTitle is not None and subTitle is None:
end_time = cur_time
res.append([start_time, end_time, lastSubTitle])
if len(res) == 1 or res[-1][0] - res[-2][1] >= 1:
if (len(res) == 1 and res[-1][0] - last_time >= 1) or (len(res) > 1 and res[-1][0] - res[-2][1]) >= 1:
print('--------------------------------------------------')
recommend_lens = int(res[-1][0] * normal_speed) if len(res) == 1 else int(
recommend_lens = int((res[-1][0] - last_time) * normal_speed) if len(res) == 1 else int(
(res[-1][0] - res[-2][1]) * normal_speed)
# write_to_sheet(book_path, sheet_name, ['', '', '', '插入旁白,推荐字数为%d' % recommend_lens])
add_to_list(mainWindow, "旁白", ['', '', '', '插入旁白,推荐字数为%d' % recommend_lens])
......@@ -293,9 +302,9 @@ def process_video(video_path: str, begin: float, end: float, book_path: str, she
if string_similar(lastSubTitle, subTitle) < 0.7:
end_time = cur_time
res.append([start_time, end_time, lastSubTitle])
if len(res) == 1 or res[-1][0] - res[-2][1] >= 1:
if (len(res) == 1 and res[-1][0] - last_time >= 1) or (len(res) > 1 and res[-1][0] - res[-2][1]) >= 1:
print('--------------------------------------------------')
recommend_lens = int(res[-1][0] * normal_speed) if len(res) == 1 else int(
recommend_lens = int((res[-1][0] - last_time) * normal_speed) if len(res) == 1 else int(
(res[-1][0] - res[-2][1]) * normal_speed)
# write_to_sheet(book_path, sheet_name, ['', '', '', '插入旁白,推荐字数为%d' % recommend_lens])
add_to_list(mainWindow, "旁白", ['', '', '', '插入旁白,推荐字数为%d' % recommend_lens])
......
def generate():
""""""
icon_path = r'D:\AddCaption\cur_version\accessibility_movie_2\images\slider.svg'
with open(icon_path, 'r') as file_input:
content_original = file_input.read()
color = "#ffd740"
secondary = "#232629"
new_content = replace_color(content_original, color)
new_content = replace_color(
new_content, secondary, '#ff0000')
file_to_write = r'D:\AddCaption\cur_version\accessibility_movie_2\images\slider_new.svg'
with open(file_to_write, 'w') as file_output:
file_output.write(new_content)
# ----------------------------------------------------------------------
def replace_color(content, replace, color='#0000ff'):
""""""
colors = [color] + [''.join(list(color)[:i] +
['\\\n'] + list(color)[i:]) for i in range(1, 7)]
for c in colors:
content = content.replace(c, replace)
replace = '#ffffff00'
color = '#000000'
colors = [color] + [''.join(list(color)[:i] +
['\\\n'] + list(color)[i:]) for i in range(1, 7)]
for c in colors:
content = content.replace(c, replace)
return content
generate()
\ No newline at end of file
......@@ -99,7 +99,7 @@
transform="matrix(1.9986219,0,0,1.9986185,17.324484,-313.52314)">
<path
inkscape:transform-center-y="3.175"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#000000;stroke-width:0.07000433;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#ffffff00;stroke-width:0.07000433;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
d="M 25.399999,271.60002 -8.0000008e-7,246.20002 H 50.799999 Z"
id="path883"
inkscape:connector-curvature="0"
......@@ -110,7 +110,7 @@
id="path880"
d="m 25.399999,271.60002 25.399999,25.4 H 0 Z"
inkscape:transform-center-y="-3.1749995"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#000000;stroke-width:0.07000433;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#ffffff00;stroke-width:0.07000433;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
<rect
ry="5.0534658"
y="253.84885"
......@@ -118,30 +118,30 @@
height="35.528759"
width="35.528786"
id="rect870"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#000000;stroke-width:0.06184419;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#ffffff00;stroke-width:0.06184419;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
<circle
r="25.396828"
cy="271.60001"
cx="25.4"
id="path872"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#000000;stroke-width:0.07635882;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#ffffff00;stroke-width:0.07635882;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
<circle
transform="rotate(-45)"
cx="-174.08969"
cy="210.01071"
r="12.656071"
id="path876"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#000000;stroke-width:0.07399406;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#ffffff00;stroke-width:0.07399406;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
<path
inkscape:transform-center-x="-3.1749999"
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path904"
d="m 25.4,271.60002 -25.40000040000004,25.4 v -50.8 z"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#000000;stroke-width:0.07000433;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#ffffff00;stroke-width:0.07000433;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
<path
inkscape:transform-center-x="3.175"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#000000;stroke-width:0.07000433;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#ffffff00;stroke-width:0.07000433;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
d="m 25.399999,271.60002 25.4,-25.4 v 50.8 z"
id="path906"
inkscape:connector-curvature="0"
......@@ -153,9 +153,9 @@
height="30.440479"
width="45.693634"
id="rect837"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#000000;stroke-width:0.0657438;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#ffffff00;stroke-width:0.0657438;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
<rect
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#000000;stroke-width:0.0657438;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
style="opacity:1;fill:none;fill-opacity:0.49382719;stroke:#ffffff00;stroke-width:0.0657438;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
id="rect831"
width="45.693588"
height="30.44051"
......@@ -172,7 +172,7 @@
id="rect997"
inkscape:connector-curvature="0" />
<path
style="opacity:1;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
style="opacity:1;fill:#ffd740;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
d="M 10,0.01367188 C 4.4846749,0.01360343 0.01360343,4.4846749 0.01367188,10 0.0136035,15.515325 4.484675,19.986396 10,19.986328 15.515325,19.986396 19.986396,15.515325 19.986328,10 19.986396,4.484675 15.515325,0.0136035 10,0.01367188 Z"
transform="matrix(0.26458332,0,0,0.26458332,0,291.70835)"
id="path826"
......
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1667704438494" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3707" width="200" height="200" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M512.01598 0C229.68971 0 0 229.68971 0 512.01598s229.68971 511.98402 512.01598 511.98402c282.29431 0 511.98402-229.68971 511.98402-511.98402S794.31029 0 512.01598 0zM512.01598 960.081895C264.940545 960.081895 63.918105 759.059455 63.918105 512.01598S264.940545 63.918105 512.01598 63.918105c247.043476 0 448.065916 201.02244 448.065916 448.097875S759.059455 960.081895 512.01598 960.081895zM743.079929 472.195l-279.833463-171.172685-4.122718-2.141257c-2.36497-1.02269-23.969289-9.939265-46.947848-9.939265-39.757061 0-65.484098 26.430136-65.484098 67.273805l0 324.895727 1.725789 5.017571c6.008302 17.673356 26.174464 47.55507 63.374801 47.55507l0 0c11.824849 0 24.065167-3.195905 37.551887-10.099061l276.637558-156.791111 2.716519-1.757748c19.047595-13.48672 39.629225-47.363316 18.440373-85.522424L743.079929 472.195zM419.047096 667.368934c-4.026841 2.045379-6.295933 2.36497-7.030992 2.428888-0.383509-0.319591-0.862894-0.862894-1.374239-1.534035l0-312.048188c0-1.374239 0.063918-2.492806 0.191754-3.323741 5.912425-0.319591 16.970257 2.460847 21.508442 4.122718l256.918823 157.142661L419.047096 667.368934z" p-id="3708" fill="#2c2c2c"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1667704464266" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4034" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512.862059 1023.999349A511.999674 511.999674 0 0 1 313.472753 40.078252a511.999674 511.999674 0 0 1 398.778611 942.840888 508.993805 508.993805 0 0 1-199.389305 41.080209z m0-943.842844C274.396457 80.156505 81.018889 273.534073 81.018889 511.999674s193.377568 431.84317 431.84317 431.84317 431.84317-194.379524 431.843169-431.84317S750.325704 80.156505 512.862059 80.156505z" fill="#2c2c2c" p-id="4035"></path><path d="M395.63317 754.473101a40.078252 40.078252 0 0 1-40.078252-40.078252V332.649495a40.078252 40.078252 0 0 1 80.156505 0v381.745354a40.078252 40.078252 0 0 1-40.078253 40.078252zM634.098772 754.473101a40.078252 40.078252 0 0 1-40.078252-40.078252V332.649495a40.078252 40.078252 0 0 1 80.156505 0v381.745354a40.078252 40.078252 0 0 1-40.078253 40.078252z" fill="#2c2c2c" p-id="4036"></path></svg>
\ No newline at end of file
......@@ -8,6 +8,7 @@ from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QTableWidget, QTableWidgetItem, QAbstractItemView, QProgressBar, QLabel
from PyQt5.QtCore import QUrl, Qt, QTimer, QRect
from PyQt5.QtMultimedia import *
from PyQt5.QtGui import QIcon
import utils
from utils import validate_and_get_filepath
from management import RunThread, ProjectContext, Element
......@@ -16,6 +17,7 @@ from assemble_dialog import Assemble_Dialog
from prompt_dialog import Prompt_Dialog
from setting_dialog import Setting_Dialog
from operation_dialog import Operation_Dialog
from create_dialog import Create_Dialog
from synthesis import SynthesisProcessor
from render import ExportProcessor
from myVideoWidget import myVideoWidget
......@@ -39,7 +41,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.synthesis.show_warning_signal.connect(self.show_warning_msg_box)
self.synthesis.synthesis_callback_signal.connect(self.deal_synthesis_callback_slot)
# 检测对话框
self.detect_dialog = Detect_Dialog()
self.detect_dialog = Detect_Dialog(self.projectContext)
self.detect_dialog.start_detect_signal.connect(self.start_detect)
# 合成对话框
......@@ -47,6 +49,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.assemble_dialog.start_assemble_signal.connect(
self.synthesis.synthesis_slot)
self.create_dialog = Create_Dialog(self.projectContext)
# 工程导出相关组件
self.export = ExportProcessor()
......@@ -103,13 +106,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.progressBar.setRange(0, 100)
# 设置进度条的初始值
self.progressBar.setValue(0)
# 进度条的进度
self.progressLabel = QLabel("0.00%")
# 菜单栏的动作
self.actionxinjian.triggered.connect(self.show_setting_dialog) # 设置
self.setting.triggered.connect(self.show_setting_dialog) # 设置
self.actiona_3.triggered.connect(self.show_detect_dialog)
self.actiona_4.triggered.connect(self.show_assemble_dialog)
self.action_create.triggered.connect(self.show_create_dialog) # 新建工程
self.action_save.triggered.connect(self.save_project)
self.import_movie.triggered.connect(self.import_slot)
self.import_movie.setEnabled(False)
self.action_open_project.triggered.connect(self.open_project_slot)
self.action_refresh_tab.triggered.connect(self.refresh_tab_slot)
self.action_export.triggered.connect(self.export_all)
......@@ -125,8 +132,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# 状态栏的动作
# self.statusbar.addPermanentWidget(self.statusbarButton, stretch=0)
self.statusbar.addPermanentWidget(self.statusbarLabel, stretch=2)
self.statusbar.addPermanentWidget(self.progressBar, stretch=10)
self.statusbar.addPermanentWidget(self.statusbarLabel, stretch=1)
self.statusbar.addPermanentWidget(self.progressBar, stretch=9)
self.statusbar.addPermanentWidget(self.progressLabel, stretch=1)
# 视频时长,全局变量
self.video_duration = None
......@@ -136,7 +144,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.player = QMediaPlayer()
self.player.setVideoOutput(self.wgt_video) # 视频播放输出的widget,就是上面定义的
self.player.durationChanged.connect(self.player_change_slot)
# self.btn_open.clicked.connect(self.open_excel) # 打开视频文件按钮
# self.btn_open.clicked.connect(self.open_excel) # 打开excel文件按钮
self.btn_play.clicked.connect(self.playVideo) # play
# self.btn_stop.clicked.connect(self.pauseVideo) # pause
self.player.positionChanged.connect(
......@@ -153,6 +161,37 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.sld_audio.valueChanged.connect(self.volumeChange) # 控制声音播放
self.kd_slider.valueChanged.connect(self.scale_change_slot)
# 设置表格每一列的宽度
subtitle_header = self.projectContext.subtitle_header
self.zm_tableWidget.setColumnCount(len(subtitle_header))
self.zm_tableWidget.setHorizontalHeaderLabels(subtitle_header)
zm_tableHeader = self.zm_tableWidget.horizontalHeader()
zm_tableHeader.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
zm_tableHeader.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
zm_tableHeader.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
content_header = self.projectContext.contentHeader
self.all_tableWidget.setColumnCount(len(content_header))
self.all_tableWidget.setHorizontalHeaderLabels(content_header)
all_tableHead = self.all_tableWidget.horizontalHeader()
all_tableHead.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
all_tableHead.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch)
all_tableHead.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
all_tableHead.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents)
aside_header = self.projectContext.aside_header
self.pb_tableWidget.setColumnCount(len(aside_header))
self.pb_tableWidget.setHorizontalHeaderLabels(aside_header)
pb_tableHead = self.pb_tableWidget.horizontalHeader()
pb_tableHead.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
pb_tableHead.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
pb_tableHead.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
pb_tableHead.setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)
pb_tableHead.setSectionResizeMode(4, QtWidgets.QHeaderView.ResizeToContents)
self.all_tableWidget.resizeRowsToContents()
self.pb_tableWidget.resizeRowsToContents()
self.zm_tableWidget.resizeRowsToContents()
# 表格中的起始位置
self.all_tableWidget_idx = 0
self.pb_tableWidget_idx = 0
......@@ -183,8 +222,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.can_write_history = True
self.previewed_audio = {}
self.is_video_playing = True
self.excel_content_changed = False
self.is_video_playing = False
# 表格中的内容是否被更改,需要刷新
self.need_fresh = False
......@@ -203,23 +241,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# btn_save_and_close = buttonBox.addButton("保存并退出", QtWidgets.QMessageBox.YesRole)
# btn_not_save_and_close = buttonBox.addButton("不保存并退出", QtWidgets.QMessageBox.YesRole)
# buttonBox.exec_()
# 如果没有进行任何修改就退出了的话,确认退出?
if not self.excel_content_changed:
# 如果没有进行任何修改就退出了的话,确认退出?在退出前,先保存一下
replp = QtWidgets.QMessageBox.question(self, u'警告', u'确认退出?',
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
if replp == QtWidgets.QMessageBox.Yes:
self.projectContext.save_project(False)
event.accept()
print("emit close Event")
else:
event.ignore()
# 如果进行了修改,就要问是否需要保存修改
else:
replp = QtWidgets.QMessageBox().question(self, u'警告', u'是否保存新的修改到Excel?',
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
if replp == QtWidgets.QMessageBox.Yes:
self.projectContext.save_project(False)
event.accept()
print("emit close Event")
# 重写改变窗口大小事件
def resizeEvent(self, *args, **kwargs):
......@@ -228,6 +258,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.scale_change_slot(position)
def show_detect_dialog(self):
self.detect_dialog.init_self()
self.detect_dialog.show()
def show_assemble_dialog(self):
......@@ -237,33 +268,45 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def show_setting_dialog(self):
self.setting_dialog.showDialog()
def show_create_dialog(self):
self.create_dialog.show()
if self.projectContext.project_base_dir is not None:
self.import_movie.setEnabled(True)
def show_warning_msg_box(self, msg: str):
replp = QtWidgets.QMessageBox.question(self, u'警告', msg,
QtWidgets.QMessageBox.Yes)
# 导入视频
def import_slot(self):
video_path = self.openVideoFile().path()
print("[import_slot] video_path=" + video_path)
if video_path == "" or video_path == None:
return
self.projectContext.Init(os.path.dirname(video_path), os.path.basename(video_path))
self.statusbar.showMessage("工程路径为:" + video_path)
if video_path[0] == '/':
video_path = video_path[1:]
self.projectContext.video_path = video_path
excel_name = os.path.splitext(os.path.basename(video_path))[0]
self.projectContext.excel_path = os.path.join(self.projectContext.project_base_dir, excel_name + ".xlsx")
self.action_export.setEnabled(True)
# todo: 后续这段代码公共的可以抽出来
def open_project_slot(self):
video_path = self.openVideoFile().path()
print("[import_slot] video_path=" + video_path)
if video_path == "" or video_path == None:
project_path = QFileDialog.getExistingDirectory(self, "选择工程文件夹", os.getcwd())
print("[import_slot] project_path=" + project_path)
if project_path == "" or project_path == None:
return
print(os.path.dirname(video_path))
print(os.path.basename(video_path))
self.projectContext.Init(os.path.dirname(
video_path), os.path.basename(video_path))
self.statusbar.showMessage("工程路径为:" + os.path.dirname(video_path))
self.projectContext.Init(project_path)
self.action_export.setEnabled(True)
if self.projectContext.excel_path is not None:
self.open_excel_with_project_path()
if self.projectContext.video_path is None:
self.import_movie.setEnabled(True)
else:
self.player.setMedia(QMediaContent(path)) # 选取视频文件
self.playVideo() # 播放视频
def start_detect(self, video_path, book_path):
"""检测旁白
......@@ -294,8 +337,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# self.show_warning_msg_box("请确认结束时间是否正确")
# return
self.projectContext.Init(os.path.dirname(
book_path), os.path.basename(video_path))
# self.projectContext.Init(os.path.dirname(
# book_path), os.path.basename(video_path))
# 获取视频的时长等信息,初始化开始结束时间
startTime = "00:00:00"
......@@ -346,7 +389,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
print("===子线程已经开启 in detect ===")
self.statusbarLabel.setText(" 准备检测:")
self.progressBar.setValue(0)
self.detect_timer.start(5000)
def check_if_detect_over_slot(self):
......@@ -366,6 +409,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.statusbarLabel.setText(" 正在%s:" % (type))
print("当前进度条进度", self.state[-1])
self.progressBar.setValue(int(self.state[-1]*100))
self.progressLabel.setText(f"{round(self.state[-1] * 100, 2)}%")
for t in self.threads:
alive = alive and t.is_alive()
if not alive:
......@@ -380,23 +424,27 @@ class MainWindow(QMainWindow, Ui_MainWindow):
print("===已有线程结束了 in %s ===" % (type))
self.statusbarLabel.setText(" %s完成" % (type))
self.progressBar.setValue(100)
self.progressLabel.setText(f"100%")
for t in self.threads:
if t.exitcode != 0:
print("Exception in", t.getName())
self.show_warning_msg_box("运行出错,请联系开发者处理")
print("当前已有的检测结果", self.projectContext.all_elements)
return
def deal_synthesis_callback_slot(self, threads, state):
self.statusbarLabel.setText(" 准备合成:")
self.progressBar.setValue(0)
self.state = self.synthesis.state
self.threads = self.synthesis.threads
self.synthesis_timer.start(5000)
def deal_export_callback_slot(self, threads, state):
self.statusbarLabel.setText(" 准备导出:")
self.progressBar.setValue(0)
self.state = self.export.state
self.threads = self.export.threads
self.export_timer.start(5000)
self.export_timer.start(1000)
"""
刻度相关
......@@ -449,7 +497,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
volume = round(position/self.sld_audio.maximum()*100)
print("vlume %f" % volume)
self.player.setVolume(volume)
self.lab_audio.setText("volume:"+str(volume)+"%")
self.lab_audio.setText("音量:"+str(volume)+"%")
# postion 取值[0,self.sld_video.maximum()]
def clickedSlider(self, position):
......@@ -519,7 +567,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
time.sleep(10)
def openVideoFile(self):
path = QFileDialog.getOpenFileUrl()[0]
path = QFileDialog.getOpenFileUrl(self, "选择待导入视频", QUrl(os.getcwd()), "Video Files(*.mp4 *.rmvb *mkv *avi)")[0]
print(path.url()[8:])
if len(path.url()) == 0 or not os.path.exists(path.url()[8:]):
return path
self.player.setMedia(QMediaContent(path)) # 选取视频文件
self.playVideo() # 播放视频
......@@ -537,52 +588,47 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.previewed_audio = {}
def playVideo(self):
self.player.play()
self.is_video_playing = True
self.btn_play.setIcon(qtawesome.icon(
'fa.pause-circle', color='#FFFFFF', font=18))
self.btn_play.clicked.connect(self.pauseVideo)
self.init_previewed_audio()
def pauseVideo(self):
if not self.player.media().isNull():
# 正在播放中,那就是暂停
if self.is_video_playing is True:
self.player.pause()
self.is_video_playing = False
self.btn_play.setIcon(qtawesome.icon(
'fa.play-circle', color='#FFFFFF', font=18))
self.btn_play.clicked.connect(self.playVideo)
self.btn_play.setIcon(QIcon('images\播放.svg'))
self.init_previewed_audio()
else:
self.player.play()
self.is_video_playing = True
self.btn_play.setIcon(QIcon("images\暂停.svg"))
self.init_previewed_audio()
def videoDoubleClicked(self, text):
if self.player.duration() > 0: # 开始播放后才允许进行全屏操作
if self.videoFullScreen:
self.player.setVideoOutput(self.wgt_video)
if not self.is_video_playing:
self.pauseVideo()
self.playVideo()
self.videoFullScreenWidget.hide()
self.videoFullScreen = False
else:
self.videoFullScreenWidget.show()
self.player.setVideoOutput(self.videoFullScreenWidget)
if not self.is_video_playing:
self.pauseVideo()
self.playVideo()
self.videoFullScreenWidget.setFullScreen(1)
self.videoFullScreen = True
def open_excel(self):
file_info = QFileDialog.getOpenFileNames(
self, '选择表格路径', os.getcwd(), "All Files(*);;Text Files(*.txt)")
file_path, ok = validate_and_get_filepath(file_info)
# path = QFileDialog.getOpenFileUrl()
print("表格路径:", file_path)
if ok == False:
return
self.projectContext.setExcelPath(file_path)
self.projectContext.load_excel_from_path()
self.all_tableWidget_idx = 0
self.pb_tableWidget_idx = 0
self.zm_tableWidget_idx = 0
self.set_table_to_window()
# def open_excel(self):
# file_info = QFileDialog.getOpenFileNames(
# self, '选择表格路径', os.getcwd(), "All Files(*);;Text Files(*.txt)")
# file_path, ok = validate_and_get_filepath(file_info)
# # path = QFileDialog.getOpenFileUrl()
# print("表格路径:", file_path)
# if ok == False:
# return
# self.projectContext.setExcelPath(file_path)
# self.projectContext.load_excel_from_path()
# self.all_tableWidget_idx = 0
# self.pb_tableWidget_idx = 0
# self.zm_tableWidget_idx = 0
# self.set_table_to_window()
def open_excel_with_project_path(self):
self.projectContext.load_excel_from_path()
......@@ -602,35 +648,24 @@ class MainWindow(QMainWindow, Ui_MainWindow):
"""
if not user_operation:
self.projectContext.initial_ing = True
header = self.projectContext.header
subtitle_list = self.projectContext.subtitle_list
aside_list = self.projectContext.aside_list
all_elements = self.projectContext.all_elements
contentHeader = self.projectContext.contentHeader
aside_header = self.projectContext.aside_header
subtitle_header = self.projectContext.subtitle_header
# self.zm_tableWidget.clear()
# self.pb_tableWidget.clear()
self.zm_tableWidget.setRowCount(len(subtitle_list))
self.zm_tableWidget.setColumnCount(len(subtitle_header))
self.zm_tableWidget.setHorizontalHeaderLabels(subtitle_header)
st_idx = 0 if need_refresh_all else self.zm_tableWidget_idx
for i in range(st_idx, len(subtitle_list)):
self.setElememtToTable(self.zm_tableWidget, subtitle_list[i], i)
self.pb_tableWidget.setRowCount(len(aside_list))
self.pb_tableWidget.setColumnCount(len(aside_header))
self.pb_tableWidget.setHorizontalHeaderLabels(aside_header)
st_idx = 0 if need_refresh_all else self.pb_tableWidget_idx
for i in range(st_idx, len(aside_list)):
self.setElememtToTable(self.pb_tableWidget, aside_list[i], i)
# self.all_tableWidget.clear()
self.all_tableWidget.setRowCount(len(all_elements))
self.all_tableWidget.setColumnCount(len(contentHeader))
self.all_tableWidget.setHorizontalHeaderLabels(contentHeader)
st_idx = 0 if need_refresh_all else self.all_tableWidget_idx
for i in range(st_idx, len(all_elements)):
self.setElememtToTable(self.all_tableWidget, all_elements[i], i)
......@@ -638,6 +673,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.all_tableWidget_idx = len(all_elements)
self.pb_tableWidget_idx = len(aside_list)
self.zm_tableWidget_idx = len(subtitle_list)
self.all_tableWidget.resizeRowsToContents()
self.pb_tableWidget.resizeRowsToContents()
self.zm_tableWidget.resizeRowsToContents()
if not user_operation:
self.projectContext.initial_ing = False
......@@ -755,7 +793,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# 只有更新语速或者更新旁白,才需要重新生成音频
if col not in constant.Aside.ActivateColumns:
return
self.excel_content_changed = True
# 合成这一段语音
self.do_generate_audio_by_aside_row(int(row))
......@@ -778,6 +815,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
speaker = self.projectContext.choose_speaker(speaker_name)
text = self.pb_tableWidget.item(int(row), constant.Aside.AsideColumnNumber).text()
# 如果目前wav_path存在,且旁白字数清空了,那就把已生成wav删掉
if len(text) == 0:
if os.path.exists(wav_path):
os.remove(wav_path)
return
t = RunThread(funcName=speech_synthesis,
args=(text, wav_path, speaker, speed),
name="speech_synthesis")
......@@ -952,9 +994,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.label_2.setText(cur_time + "/" + duration_time)
def change_table_select_rows(self):
cur_time = self.player.position()/1000
cur_time = self.player.position() / 1000
all_elements = self.projectContext.all_elements
for i in range(len(all_elements)-1, -1, -1):
aside_list = self.projectContext.aside_list
for i in range(len(all_elements) - 1, -1, -1):
if utils.trans_to_seconds(all_elements[i].st_time_sec) <= cur_time:
self.all_tableWidget.selectRow(i)
break
......@@ -969,9 +1012,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
"""
刷新整个表格
"""
self.set_table_to_window()
self.set_table_to_window(need_refresh_all=False)
# 不需要加这个,因为只要itemchange,就会触发保存的
# self.projectContext.save_project(False)
self.projectContext.save_project(False)
def export_all(self):
# 暂时存放音频的文件夹被命名为tmp
......@@ -1027,17 +1070,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.projectContext.subtitle_list.insert(idx, new_element)
self.zm_tableWidget_idx =idx
self.refresh_tab_slot()
self.projectContext.save_project()
self.prompt_dialog.show_with_msg("操作成功!!请查看变化")
# 只需要改all_elements就可以了,因为是同一对象
def mod_line_operation_slot(self, row, start_time, end_time, subtitle, suggest, aside):
def mod_line_operation_slot(self, row, start_time, end_time, subtitle, suggest, aside, speed):
elem = self.projectContext.all_elements[int(row)-1]
elem.st_time_sec = start_time
elem.ed_time_sec = end_time
elem.subtitle = subtitle
elem.suggest = suggest
elem.aside = aside
elem.speed = speed
to_be_modify_element = self.projectContext.all_elements[int(row) - 1]
if suggest is not None and "插入旁白,推荐字数为" in suggest:
......@@ -1068,9 +1111,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.pb_tableWidget_idx = i
self.projectContext.aside_list.pop(i)
break
else:
for i in range(len(self.projectContext.subtitle_header)):
for i in range(len(self.projectContext.subtitle_list)):
if to_be_delete_element.equalTo(self.projectContext.subtitle_list[i]):
self.zm_tableWidget_idx = i
self.projectContext.subtitle_list.pop(i)
......@@ -1078,7 +1120,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.all_tableWidget_idx = int(row)-1
self.projectContext.all_elements.pop(int(row)-1)
self.projectContext.save_project()
self.refresh_tab_slot()
self.prompt_dialog.show_with_msg("操作成功!!请查看变化")
def pb_item_changed_by_double_clicked_slot(self, item):
......
......@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>939</width>
<width>924</width>
<height>763</height>
</rect>
</property>
......@@ -27,10 +27,9 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout" stretch="5,1">
<item>
<layout class="QHBoxLayout" name="shuiping" stretch="2,1">
<layout class="QHBoxLayout" name="shuiping" stretch="3,5">
<item>
<widget class="QWidget" name="verticalWidget_3" native="true">
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="8,0">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="8,1,1">
<item>
<widget class="myVideoWidget" name="wgt_video" native="true">
<property name="minimumSize">
......@@ -48,12 +47,21 @@
<property name="palette">
<palette>
<active>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
......@@ -68,12 +76,21 @@
</colorrole>
</active>
<inactive>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
......@@ -88,6 +105,15 @@
</colorrole>
</inactive>
<disabled>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
......@@ -110,55 +136,66 @@
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<widget class="QSlider" name="verticalSlider">
<property name="geometry">
<rect>
<x>560</x>
<y>310</y>
<width>16</width>
<height>161</height>
</rect>
</property>
<property name="maximum">
<number>100</number>
<bool>false</bool>
</property>
<property name="singleStep">
<number>5</number>
<property name="styleSheet">
<string notr="true">background-color: #000</string>
</property>
<property name="value">
<number>100</number>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="2,1,2,1,1,1">
<item>
<widget class="QLabel" name="label_2">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
<property name="text">
<string>00:00/00:00</string>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QSplitter" name="splitter">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>25</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btn_play">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>50</height>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>50</height>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
color: #333;
color: #fff;
border: 2px groove gray;
border-radius: 25px;
border-radius: 15px;
border-style: outset;
background: qradialgradient(
cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,
......@@ -167,14 +204,14 @@
padding: 5px;
}
QPushButton:hover {
QPushButton:hover {
background: qradialgradient(
cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,
radius: 1.35, stop: 0 #fff, stop: 1 #bbb
);
}
QPushButton:pressed {
QPushButton:pressed {
border-style: inset;
background: qradialgradient(
cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1,
......@@ -183,30 +220,129 @@ QPushButton:pressed {
}</string>
</property>
<property name="text">
<string>播放</string>
<string/>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="text">
<string>00:00/00:00</string>
<property name="icon">
<iconset>
<normaloff>images/播放.svg</normaloff>
<selectedon>images/暂停.svg</selectedon>images/播放.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="sld_audio">
<property name="minimumSize">
<size>
<width>0</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
<width>80</width>
<height>24</height>
</size>
</property>
<property name="text">
<string>音量</string>
<property name="styleSheet">
<string notr="true">QSlider:horizontal {
min-height: 24px;
max-height: 24px;
}
QSlider:vertical {
min-width: 24px;
max-width: 24px;
}
QSlider::groove:horizontal {
height: 4px;
background: #393939;
margin: 0 12px;
}
QSlider::groove:vertical {
width: 4px;
background: #393939;
margin: 12px 0;
border-radius: 24px;
}
QSlider::handle:horizontal {
image: url(images/slider.svg);
width: 12px;
height: 12px;
margin: -24px -12px;
}
QSlider::handle:vertical {
image: url(images/slider.svg);
border-radius: 24px;
width: 12px;
height: 12px;
margin: -12px -24px;
}
QSlider::add-page {
background: #232629;
}
QSlider::sub-page {
background: #ffd740;
}</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lab_audio">
<property name="text">
<string>音量:100%</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="0,0">
<item>
<widget class="QPushButton" name="pickStart">
<property name="text">
<string>选择开始时间</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pickEnd">
<property name="text">
<string>选择终止时间</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="enabled">
......@@ -225,7 +361,7 @@ QPushButton:pressed {
<enum>QTabWidget::Triangular</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<property name="iconSize">
<size>
......@@ -448,7 +584,7 @@ QPushButton:pressed {
<rect>
<x>0</x>
<y>0</y>
<width>939</width>
<width>924</width>
<height>22</height>
</rect>
</property>
......@@ -456,13 +592,14 @@ QPushButton:pressed {
<property name="title">
<string>文件</string>
</property>
<addaction name="actionxinjian"/>
<addaction name="action_create"/>
<addaction name="action_open_project"/>
<addaction name="separator"/>
<addaction name="import_movie"/>
<addaction name="action_export"/>
<addaction name="separator"/>
<addaction name="action_save"/>
<addaction name="setting"/>
</widget>
<widget class="QMenu" name="menu_2">
<property name="title">
......@@ -490,7 +627,7 @@ QPushButton:pressed {
<addaction name="menu_3"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionxinjian">
<action name="setting">
<property name="text">
<string>设置</string>
</property>
......@@ -565,6 +702,11 @@ QPushButton:pressed {
<string>当前位置插入字幕</string>
</property>
</action>
<action name="action_create">
<property name="text">
<string>新建</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
......
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'main_window.ui'
# Form implementation generated from reading ui file 'd:\AddCaption\cur_version\accessibility_movie_2\main_window_modified.ui'
#
# Created by: PyQt5 UI code generator 5.12
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING! All changes made in this file will be lost!
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
import qtawesome
from myVideoWidget import myVideoWidget
from myvideoslider import myVideoSlider
from mywidgetcontents import myWidgetContents
class Ui_MainWindow(object):
......@@ -29,13 +33,12 @@ class Ui_MainWindow(object):
self.verticalLayout.setObjectName("verticalLayout")
self.shuiping = QtWidgets.QHBoxLayout()
self.shuiping.setObjectName("shuiping")
self.verticalWidget_3 = QtWidgets.QWidget(self.centralwidget)
self.verticalWidget_3.setObjectName("verticalWidget_3")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.verticalWidget_3)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.wgt_video = myVideoWidget(self.verticalWidget_3)
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.wgt_video = myVideoWidget(self.centralwidget)
self.wgt_video.setMinimumSize(QtCore.QSize(410, 200))
self.wgt_video.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.wgt_video.setStyleSheet("background-color: #000")
palette = QtGui.QPalette()
brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
......@@ -58,21 +61,25 @@ class Ui_MainWindow(object):
self.wgt_video.setPalette(palette)
self.wgt_video.setAutoFillBackground(True)
self.wgt_video.setObjectName("wgt_video")
self.verticalLayout_3.addWidget(self.wgt_video)
self.splitter = QtWidgets.QSplitter(self.verticalWidget_3)
self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter")
self.label_2 = QtWidgets.QLabel(self.splitter)
self.verticalLayout_2.addWidget(self.wgt_video)
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setMaximumSize(QtCore.QSize(150, 16777215))
self.label_2.setObjectName("label_2")
# self.btn_open = QtWidgets.QPushButton(self.splitter)
# self.btn_open.setMaximumSize(QtCore.QSize(100, 25))
# self.btn_open.setObjectName("btn_open")
self.btn_play = QtWidgets.QPushButton(qtawesome.icon('fa.play-circle', color='#FFFFFF', font=50), "", self.splitter)
self.btn_play.setIconSize(QtCore.QSize(30, 30))
self.horizontalLayout_5.addWidget(self.label_2)
spacerItem = QtWidgets.QSpacerItem(25, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem)
self.btn_play = QtWidgets.QPushButton(self.centralwidget)
# sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
# sizePolicy.setHorizontalStretch(0)
# sizePolicy.setVerticalStretch(0)
# sizePolicy.setHeightForWidth(self.btn_play.sizePolicy().hasHeightForWidth())
# self.btn_play.setSizePolicy(sizePolicy)
self.btn_play.setMinimumSize(QtCore.QSize(30, 30))
self.btn_play.setMaximumSize(QtCore.QSize(30, 30))
self.btn_play.setStyleSheet("QPushButton {\n"
" color: #333;\n"
" color: #fff;\n"
" border: 2px groove gray;\n"
" border-radius: 15px;\n"
" border-style: outset;\n"
......@@ -97,73 +104,92 @@ class Ui_MainWindow(object):
" radius: 1.35, stop: 0 #fff, stop: 1 #ddd\n"
" );\n"
" }")
self.btn_play.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("images/播放.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon.addPixmap(QtGui.QPixmap("images/暂停.svg"), QtGui.QIcon.Selected, QtGui.QIcon.On)
self.btn_play.setIcon(icon)
self.btn_play.setIconSize(QtCore.QSize(30, 30))
self.btn_play.setObjectName("btn_play")
self.sld_audio = QtWidgets.QSlider(self.splitter)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.sld_audio.sizePolicy().hasHeightForWidth())
self.sld_audio.setSizePolicy(sizePolicy)
self.sld_audio.setMinimumSize(QtCore.QSize(50, 25))
self.sld_audio.setMaximumSize(QtCore.QSize(150, 25))
self.horizontalLayout_5.addWidget(self.btn_play)
spacerItem1 = QtWidgets.QSpacerItem(30, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem1)
self.sld_audio = QtWidgets.QSlider(self.centralwidget)
self.sld_audio.setMinimumSize(QtCore.QSize(0, 24))
self.sld_audio.setMaximumSize(QtCore.QSize(80, 24))
self.sld_audio.setSingleStep(5)
# self.sld_audio.setTickPosition(QtWidgets.QSlider.TicksBelow)
# self.sld_audio.setTickInterval(5)
self.sld_audio.setProperty("value", 100)
self.sld_audio.setStyleSheet("QSlider:horizontal {\n"
" min-height: 24px;\n"
" max-height: 24px;\n"
"}\n"
"\n"
"QSlider:vertical {\n"
" min-width: 24px;\n"
" max-width: 24px;\n"
"}\n"
"\n"
"QSlider::groove:horizontal {\n"
" height: 4px;\n"
" background: #393939;\n"
" margin: 0 12px;\n"
"}\n"
"\n"
"QSlider::groove:vertical {\n"
" width: 4px;\n"
" background: #393939;\n"
" margin: 12px 0;\n"
" border-radius: 24px;\n"
"}\n"
"\n"
"QSlider::handle:horizontal {\n"
" image: url(images/slider.svg);\n"
" width: 12px;\n"
" height: 12px;\n"
" margin: -24px -12px;\n"
"}\n"
"\n"
"QSlider::handle:vertical {\n"
" image: url(images/slider.svg);\n"
" border-radius: 24px;\n"
" width: 12px;\n"
" height: 12px;\n"
" margin: -12px -24px;\n"
"}\n"
"\n"
"QSlider::add-page {\n"
"background: #232629;\n"
"}\n"
"\n"
"QSlider::sub-page {\n"
"background: #ffd740;\n"
"}")
self.sld_audio.setOrientation(QtCore.Qt.Horizontal)
self.sld_audio.setObjectName("sld_audio")
self.sld_audio.setStyleSheet('''
QSlider:horizontal {
min-height: 24px;
max-height: 24px;
}
QSlider:vertical {
min-width: 24px;
max-width: 24px;
}
QSlider::groove:horizontal {
height: 4px;
background: #393939;
margin: 0 12px;
}
QSlider::groove:vertical {
width: 4px;
background: #393939;
margin: 12px 0;
border-radius: 24px;
}
QSlider::handle:horizontal {
image: url(images/slider.svg);
width: 12px;
height: 12px;
margin: -24px -12px;
}
QSlider::handle:vertical {
image: url(images/slider.svg);
border-radius: 24px;
width: 12px;
height: 12px;
margin: -12px -24px;
}
QSlider::add-page {
background: #232629;
}
QSlider::sub-page {
background: #ffd740;
}
''')
self.lab_audio = QtWidgets.QLabel(self.splitter)
self.horizontalLayout_5.addWidget(self.sld_audio)
self.lab_audio = QtWidgets.QLabel(self.centralwidget)
self.lab_audio.setObjectName("lab_audio")
self.verticalLayout_3.addWidget(self.splitter)
self.verticalLayout_3.setStretch(0, 8)
self.shuiping.addWidget(self.verticalWidget_3)
self.horizontalLayout_5.addWidget(self.lab_audio)
self.horizontalLayout_5.setStretch(0, 2)
self.horizontalLayout_5.setStretch(1, 1)
self.horizontalLayout_5.setStretch(2, 2)
self.horizontalLayout_5.setStretch(3, 1)
self.horizontalLayout_5.setStretch(4, 1)
self.horizontalLayout_5.setStretch(5, 1)
self.verticalLayout_2.addLayout(self.horizontalLayout_5)
self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
self.horizontalLayout_6.setObjectName("horizontalLayout_6")
self.pickStart = QtWidgets.QPushButton(self.centralwidget)
self.pickStart.setObjectName("pickStart")
self.horizontalLayout_6.addWidget(self.pickStart)
self.pickEnd = QtWidgets.QPushButton(self.centralwidget)
self.pickEnd.setObjectName("pickEnd")
self.horizontalLayout_6.addWidget(self.pickEnd)
self.verticalLayout_2.addLayout(self.horizontalLayout_6)
self.verticalLayout_2.setStretch(0, 8)
self.verticalLayout_2.setStretch(1, 1)
self.verticalLayout_2.setStretch(2, 1)
self.shuiping.addLayout(self.verticalLayout_2)
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setEnabled(True)
self.tabWidget.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
......@@ -208,8 +234,8 @@ background: #ffd740;
self.horizontalLayout_3.addWidget(self.pb_tableWidget)
self.tabWidget.addTab(self.pb_tab, "")
self.shuiping.addWidget(self.tabWidget)
self.shuiping.setStretch(0, 2)
self.shuiping.setStretch(1, 1)
self.shuiping.setStretch(0, 3)
self.shuiping.setStretch(1, 5)
self.verticalLayout.addLayout(self.shuiping)
self.verticalWidget_2 = QtWidgets.QWidget(self.centralwidget)
self.verticalWidget_2.setObjectName("verticalWidget_2")
......@@ -250,8 +276,8 @@ background: #ffd740;
self.zm_slider_layout.setStretch(0, 15)
self.zm_slider_layout.setStretch(1, 1)
self.chuizhi.addLayout(self.zm_slider_layout)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.chuizhi.addItem(spacerItem)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.chuizhi.addItem(spacerItem2)
self.pb_label = QtWidgets.QLabel(self.verticalWidget_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
......@@ -298,8 +324,8 @@ background: #ffd740;
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionxinjian = QtWidgets.QAction(MainWindow)
self.actionxinjian.setObjectName("actionxinjian")
self.setting = QtWidgets.QAction(MainWindow)
self.setting.setObjectName("setting")
self.action_open_project = QtWidgets.QAction(MainWindow)
self.action_open_project.setObjectName("action_open_project")
self.import_movie = QtWidgets.QAction(MainWindow)
......@@ -326,19 +352,25 @@ background: #ffd740;
self.action_export.setObjectName("action_export")
self.action_insert_aside_from_now = QtWidgets.QAction(MainWindow)
self.action_insert_aside_from_now.setObjectName("action_insert_aside_from_now")
self.menu.addAction(self.actionxinjian)
self.action_insert_subtitle_from_now = QtWidgets.QAction(MainWindow)
self.action_insert_subtitle_from_now.setObjectName("action_insert_subtitle_from_now")
self.action_create = QtWidgets.QAction(MainWindow)
self.action_create.setObjectName("action_create")
self.menu.addAction(self.action_create)
self.menu.addAction(self.action_open_project)
self.menu.addSeparator()
self.menu.addAction(self.import_movie)
self.menu.addAction(self.action_export)
self.menu.addSeparator()
self.menu.addAction(self.action_save)
self.menu.addAction(self.setting)
self.menu_2.addAction(self.action_undo)
self.menu_2.addAction(self.action_redo)
# self.menu_2.addAction(self.action_view_history)
self.menu_2.addSeparator()
self.menu_2.addAction(self.action_insert_aside_from_now)
self.menu_2.addAction(self.action_operate)
# self.menu_2.addAction(self.action_insert_subtitle_from_now)
self.menu_3.addAction(self.actiona_3)
self.menu_3.addAction(self.actiona_4)
self.menu_3.addSeparator()
......@@ -354,8 +386,10 @@ background: #ffd740;
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.lab_audio.setText(_translate("MainWindow", "volume:100%"))
self.label_2.setText(_translate("MainWindow", "00:00/00:00"))
self.lab_audio.setText(_translate("MainWindow", "音量:100%"))
self.pickStart.setText(_translate("MainWindow", "选择开始时间"))
self.pickEnd.setText(_translate("MainWindow", "选择终止时间"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.all_tab), _translate("MainWindow", "字幕旁白"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.zm_tab), _translate("MainWindow", "字幕"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.pb_tab), _translate("MainWindow", "旁白"))
......@@ -365,7 +399,7 @@ background: #ffd740;
self.menu.setTitle(_translate("MainWindow", "文件"))
self.menu_2.setTitle(_translate("MainWindow", "编辑"))
self.menu_3.setTitle(_translate("MainWindow", "功能按键"))
self.actionxinjian.setText(_translate("MainWindow", "设置"))
self.setting.setText(_translate("MainWindow", "设置"))
self.action_open_project.setText(_translate("MainWindow", "打开"))
self.import_movie.setText(_translate("MainWindow", "视频导入"))
self.actions.setText(_translate("MainWindow", "内容导出"))
......@@ -379,8 +413,6 @@ background: #ffd740;
self.action_operate.setText(_translate("MainWindow", "操作表格"))
self.action_export.setText(_translate("MainWindow", "导出"))
self.action_insert_aside_from_now.setText(_translate("MainWindow", "当前位置插入旁白"))
# self.action_insert_subtitle_from_now.setText(_translate("MainWindow", "当前位置插入字幕"))
self.action_create.setText(_translate("MainWindow", "新建"))
from myVideoWidget import myVideoWidget
from myvideoslider import myVideoSlider
from mywidgetcontents import myWidgetContents
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'main_window.ui'
#
# Created by: PyQt5 UI code generator 5.12
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
from myVideoWidget import myVideoWidget
from myvideoslider import myVideoSlider
from mywidgetcontents import myWidgetContents
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(939, 763)
MainWindow.setStyleSheet("QMainWindow:{\n"
" border: 2px groove gray;\n"
" border-radius: 25px;\n"
" border-style: outset;\n"
" background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));\n"
" padding: 5px;\n"
"}")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.shuiping = QtWidgets.QHBoxLayout()
self.shuiping.setObjectName("shuiping")
self.verticalWidget_3 = QtWidgets.QWidget(self.centralwidget)
self.verticalWidget_3.setObjectName("verticalWidget_3")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.verticalWidget_3)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.wgt_video = myVideoWidget(self.verticalWidget_3)
self.wgt_video.setMinimumSize(QtCore.QSize(410, 200))
self.wgt_video.setMaximumSize(QtCore.QSize(16777215, 16777215))
palette = QtGui.QPalette()
brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
self.wgt_video.setPalette(palette)
self.wgt_video.setAutoFillBackground(True)
self.wgt_video.setObjectName("wgt_video")
self.verticalLayout_3.addWidget(self.wgt_video)
self.splitter = QtWidgets.QSplitter(self.verticalWidget_3)
self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter")
self.label_2 = QtWidgets.QLabel(self.splitter)
self.label_2.setObjectName("label_2")
# self.btn_open = QtWidgets.QPushButton(self.splitter)
# self.btn_open.setMaximumSize(QtCore.QSize(100, 25))
# self.btn_open.setObjectName("btn_open")
self.btn_play = QtWidgets.QPushButton("", self.splitter)
self.btn_play.setIcon(QtGui.QIcon("images\播放.svg"))
self.btn_play.setIconSize(QtCore.QSize(30, 30))
self.btn_play.setMinimumSize(QtCore.QSize(30, 30))
self.btn_play.setMaximumSize(QtCore.QSize(30, 30))
self.btn_play.setStyleSheet("QPushButton {\n"
" color: #fff;\n"
" border: 2px groove gray;\n"
" border-radius: 15px;\n"
" border-style: outset;\n"
" background: qradialgradient(\n"
" cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,\n"
" radius: 1.35, stop: 0 #fff, stop: 1 #888\n"
" );\n"
" padding: 5px;\n"
" }\n"
"\n"
"QPushButton:hover {\n"
" background: qradialgradient(\n"
" cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,\n"
" radius: 1.35, stop: 0 #fff, stop: 1 #bbb\n"
" );\n"
" }\n"
"\n"
"QPushButton:pressed {\n"
" border-style: inset;\n"
" background: qradialgradient(\n"
" cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1,\n"
" radius: 1.35, stop: 0 #fff, stop: 1 #ddd\n"
" );\n"
" }")
self.btn_play.setObjectName("btn_play")
self.sld_audio = QtWidgets.QSlider(self.splitter)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.sld_audio.sizePolicy().hasHeightForWidth())
self.sld_audio.setSizePolicy(sizePolicy)
self.sld_audio.setMinimumSize(QtCore.QSize(50, 25))
self.sld_audio.setMaximumSize(QtCore.QSize(150, 25))
self.sld_audio.setSingleStep(5)
# self.sld_audio.setTickPosition(QtWidgets.QSlider.TicksBelow)
# self.sld_audio.setTickInterval(5)
self.sld_audio.setProperty("value", 100)
self.sld_audio.setOrientation(QtCore.Qt.Horizontal)
self.sld_audio.setObjectName("sld_audio")
self.sld_audio.setStyleSheet('''
QSlider:horizontal {
min-height: 24px;
max-height: 24px;
}
QSlider:vertical {
min-width: 24px;
max-width: 24px;
}
QSlider::groove:horizontal {
height: 4px;
background: #393939;
margin: 0 12px;
}
QSlider::groove:vertical {
width: 4px;
background: #393939;
margin: 12px 0;
border-radius: 24px;
}
QSlider::handle:horizontal {
image: url(images/slider.svg);
width: 12px;
height: 12px;
margin: -24px -12px;
}
QSlider::handle:vertical {
image: url(images/slider.svg);
border-radius: 24px;
width: 12px;
height: 12px;
margin: -12px -24px;
}
QSlider::add-page {
background: #232629;
}
QSlider::sub-page {
background: #ffd740;
}
''')
self.lab_audio = QtWidgets.QLabel(self.splitter)
self.lab_audio.setObjectName("lab_audio")
self.verticalLayout_3.addWidget(self.splitter)
self.verticalLayout_3.setStretch(0, 8)
self.shuiping.addWidget(self.verticalWidget_3)
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setEnabled(True)
self.tabWidget.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
self.tabWidget.setStyleSheet("")
self.tabWidget.setTabPosition(QtWidgets.QTabWidget.North)
self.tabWidget.setTabShape(QtWidgets.QTabWidget.Triangular)
self.tabWidget.setIconSize(QtCore.QSize(20, 20))
self.tabWidget.setElideMode(QtCore.Qt.ElideNone)
self.tabWidget.setMovable(False)
self.tabWidget.setTabBarAutoHide(False)
self.tabWidget.setObjectName("tabWidget")
self.all_tab = QtWidgets.QWidget()
self.all_tab.setEnabled(True)
self.all_tab.setObjectName("all_tab")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.all_tab)
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.all_tableWidget = QtWidgets.QTableWidget(self.all_tab)
self.all_tableWidget.setObjectName("all_tableWidget")
self.all_tableWidget.setColumnCount(0)
self.all_tableWidget.setRowCount(0)
self.horizontalLayout_4.addWidget(self.all_tableWidget)
self.tabWidget.addTab(self.all_tab, "")
self.zm_tab = QtWidgets.QWidget()
self.zm_tab.setEnabled(True)
self.zm_tab.setObjectName("zm_tab")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.zm_tab)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.zm_tableWidget = QtWidgets.QTableWidget(self.zm_tab)
self.zm_tableWidget.setObjectName("zm_tableWidget")
self.zm_tableWidget.setColumnCount(0)
self.zm_tableWidget.setRowCount(0)
self.horizontalLayout_2.addWidget(self.zm_tableWidget)
self.tabWidget.addTab(self.zm_tab, "")
self.pb_tab = QtWidgets.QWidget()
self.pb_tab.setObjectName("pb_tab")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.pb_tab)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.pb_tableWidget = QtWidgets.QTableWidget(self.pb_tab)
self.pb_tableWidget.setObjectName("pb_tableWidget")
self.pb_tableWidget.setColumnCount(0)
self.pb_tableWidget.setRowCount(0)
self.horizontalLayout_3.addWidget(self.pb_tableWidget)
self.tabWidget.addTab(self.pb_tab, "")
self.shuiping.addWidget(self.tabWidget)
self.shuiping.setStretch(0, 2)
self.shuiping.setStretch(1, 1)
self.verticalLayout.addLayout(self.shuiping)
self.verticalWidget_2 = QtWidgets.QWidget(self.centralwidget)
self.verticalWidget_2.setObjectName("verticalWidget_2")
self.chuizhi = QtWidgets.QVBoxLayout(self.verticalWidget_2)
self.chuizhi.setObjectName("chuizhi")
self.zm_label = QtWidgets.QLabel(self.verticalWidget_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.zm_label.sizePolicy().hasHeightForWidth())
self.zm_label.setSizePolicy(sizePolicy)
self.zm_label.setObjectName("zm_label")
self.chuizhi.addWidget(self.zm_label)
self.zm_slider_layout = QtWidgets.QHBoxLayout()
self.zm_slider_layout.setObjectName("zm_slider_layout")
self.scrollArea = QtWidgets.QScrollArea(self.verticalWidget_2)
self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.scrollArea.setWidgetResizable(False)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = myWidgetContents()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 800, 40))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.sld_video = myVideoSlider(self.scrollAreaWidgetContents)
self.sld_video.setGeometry(QtCore.QRect(10, 20, 790, 30))
self.sld_video.setMinimumSize(QtCore.QSize(410, 0))
self.sld_video.setMaximumSize(QtCore.QSize(16777215, 20))
self.sld_video.setMaximum(100)
self.sld_video.setOrientation(QtCore.Qt.Horizontal)
self.sld_video.setTickPosition(QtWidgets.QSlider.TicksAbove)
self.sld_video.setTickInterval(1)
self.sld_video.setObjectName("sld_video")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.zm_slider_layout.addWidget(self.scrollArea)
self.lab_video = QtWidgets.QLabel(self.verticalWidget_2)
self.lab_video.setMaximumSize(QtCore.QSize(16777215, 50))
self.lab_video.setObjectName("lab_video")
self.zm_slider_layout.addWidget(self.lab_video)
self.zm_slider_layout.setStretch(0, 15)
self.zm_slider_layout.setStretch(1, 1)
self.chuizhi.addLayout(self.zm_slider_layout)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.chuizhi.addItem(spacerItem)
self.pb_label = QtWidgets.QLabel(self.verticalWidget_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pb_label.sizePolicy().hasHeightForWidth())
self.pb_label.setSizePolicy(sizePolicy)
self.pb_label.setObjectName("pb_label")
self.chuizhi.addWidget(self.pb_label)
self.kd_slider_layout = QtWidgets.QHBoxLayout()
self.kd_slider_layout.setObjectName("kd_slider_layout")
self.kd_slider = QtWidgets.QSlider(self.verticalWidget_2)
self.kd_slider.setEnabled(True)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.kd_slider.sizePolicy().hasHeightForWidth())
self.kd_slider.setSizePolicy(sizePolicy)
self.kd_slider.setCursor(QtGui.QCursor(QtCore.Qt.SizeHorCursor))
self.kd_slider.setMouseTracking(False)
self.kd_slider.setFocusPolicy(QtCore.Qt.NoFocus)
self.kd_slider.setMinimum(1)
self.kd_slider.setMaximum(100)
self.kd_slider.setOrientation(QtCore.Qt.Horizontal)
self.kd_slider.setTickPosition(QtWidgets.QSlider.TicksAbove)
self.kd_slider.setTickInterval(1)
self.kd_slider.setObjectName("kd_slider")
self.kd_slider_layout.addWidget(self.kd_slider)
self.chuizhi.addLayout(self.kd_slider_layout)
self.verticalLayout.addWidget(self.verticalWidget_2)
self.verticalLayout.setStretch(0, 5)
self.verticalLayout.setStretch(1, 1)
self.horizontalLayout.addLayout(self.verticalLayout)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 939, 26))
self.menubar.setObjectName("menubar")
self.menu = QtWidgets.QMenu(self.menubar)
self.menu.setObjectName("menu")
self.menu_2 = QtWidgets.QMenu(self.menubar)
self.menu_2.setObjectName("menu_2")
self.menu_3 = QtWidgets.QMenu(self.menubar)
self.menu_3.setObjectName("menu_3")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionxinjian = QtWidgets.QAction(MainWindow)
self.actionxinjian.setObjectName("actionxinjian")
self.action_open_project = QtWidgets.QAction(MainWindow)
self.action_open_project.setObjectName("action_open_project")
self.import_movie = QtWidgets.QAction(MainWindow)
self.import_movie.setObjectName("import_movie")
self.actions = QtWidgets.QAction(MainWindow)
self.actions.setObjectName("actions")
self.action_save = QtWidgets.QAction(MainWindow)
self.action_save.setObjectName("action_save")
self.action_undo = QtWidgets.QAction(MainWindow)
self.action_undo.setObjectName("action_undo")
self.action_redo = QtWidgets.QAction(MainWindow)
self.action_redo.setObjectName("action_redo")
self.actiona_3 = QtWidgets.QAction(MainWindow)
self.actiona_3.setObjectName("actiona_3")
self.actiona_4 = QtWidgets.QAction(MainWindow)
self.actiona_4.setObjectName("actiona_4")
self.action_view_history = QtWidgets.QAction(MainWindow)
self.action_view_history.setObjectName("action_view_history")
self.action_refresh_tab = QtWidgets.QAction(MainWindow)
self.action_refresh_tab.setObjectName("action_refresh_tab")
self.action_operate = QtWidgets.QAction(MainWindow)
self.action_operate.setObjectName("action_operate")
self.action_export = QtWidgets.QAction(MainWindow)
self.action_export.setObjectName("action_export")
self.action_insert_aside_from_now = QtWidgets.QAction(MainWindow)
self.action_insert_aside_from_now.setObjectName("action_insert_aside_from_now")
self.menu.addAction(self.actionxinjian)
self.menu.addAction(self.action_open_project)
self.menu.addSeparator()
self.menu.addAction(self.import_movie)
self.menu.addAction(self.action_export)
self.menu.addSeparator()
self.menu.addAction(self.action_save)
self.menu_2.addAction(self.action_undo)
self.menu_2.addAction(self.action_redo)
# self.menu_2.addAction(self.action_view_history)
self.menu_2.addSeparator()
self.menu_2.addAction(self.action_insert_aside_from_now)
self.menu_2.addAction(self.action_operate)
self.menu_3.addAction(self.actiona_3)
self.menu_3.addAction(self.actiona_4)
self.menu_3.addSeparator()
self.menu_3.addAction(self.action_refresh_tab)
self.menubar.addAction(self.menu.menuAction())
self.menubar.addAction(self.menu_2.menuAction())
self.menubar.addAction(self.menu_3.menuAction())
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.lab_audio.setText(_translate("MainWindow", "音量:100%"))
self.label_2.setText(_translate("MainWindow", "00:00/00:00"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.all_tab), _translate("MainWindow", "字幕旁白"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.zm_tab), _translate("MainWindow", "字幕"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.pb_tab), _translate("MainWindow", "旁白"))
self.zm_label.setText(_translate("MainWindow", "时间轴"))
self.lab_video.setText(_translate("MainWindow", "00:00"))
self.pb_label.setText(_translate("MainWindow", "刻度"))
self.menu.setTitle(_translate("MainWindow", "文件"))
self.menu_2.setTitle(_translate("MainWindow", "编辑"))
self.menu_3.setTitle(_translate("MainWindow", "功能按键"))
self.actionxinjian.setText(_translate("MainWindow", "设置"))
self.action_open_project.setText(_translate("MainWindow", "打开"))
self.import_movie.setText(_translate("MainWindow", "视频导入"))
self.actions.setText(_translate("MainWindow", "内容导出"))
self.action_save.setText(_translate("MainWindow", "保存并备份"))
self.action_undo.setText(_translate("MainWindow", "撤销"))
self.action_redo.setText(_translate("MainWindow", "重做"))
self.actiona_3.setText(_translate("MainWindow", "旁白区间检测"))
self.actiona_4.setText(_translate("MainWindow", "旁白音频合成"))
self.action_view_history.setText(_translate("MainWindow", "----"))
self.action_refresh_tab.setText(_translate("MainWindow", "刷新且保存表格"))
self.action_operate.setText(_translate("MainWindow", "操作表格"))
self.action_export.setText(_translate("MainWindow", "导出"))
self.action_insert_aside_from_now.setText(_translate("MainWindow", "当前位置插入旁白"))
......@@ -74,10 +74,6 @@ class OperateRecord:
s = "{row=%d, opt=%s, oldStr=%s, newStr=%s}"%(self.row, str(self.operation), self.old_str, self.new_str)
return s
# 每一行的具体信息,"起始时间", "终止时间", "字幕", '建议', '解说脚本'
class Element:
def __init__(self, st_time_sec: str, ed_time_sec: str, subtitle, suggest, aside, speed = "1.00(4字/秒)"):
......@@ -88,7 +84,6 @@ class Element:
self.aside = aside
self.speed = speed
# 判断当前元素是否是字幕
def is_subtitle(self):
return self.subtitle != None and self.subtitle != ""
......@@ -126,10 +121,10 @@ class ProjectContext:
self.speaker_speed = None
# 一些常量
self.header = ["起始时间", "终止时间", "字幕", '建议', '解说脚本', "语速"]
self.aside_header = ["起始时间", "终止时间", '建议', '解说脚本',"语速"]
self.subtitle_header = ["起始时间", "终止时间", "字幕"]
self.aside_header = ["起始时间", "终止时间", '推荐插入字数', '解说脚本',"语速", ""]
self.subtitle_header = ["起始时间", "终止时间", "字幕", ""]
self.contentHeader = ["起始时间", "字幕", "旁白", "语速"]
self.contentHeader = ["起始时间", "字幕", "解说脚本", "语速", ""]
self.excel_sheet_name = "旁白插入位置建议"
self.history_records = []
self.records_pos = 0
......@@ -156,17 +151,13 @@ class ProjectContext:
self.history_records = []
self.records_pos = 0
def Init(self, project_dir, video_name):
def Init(self, project_dir):
if len(project_dir) == 0 or project_dir is None:
return
# 有的时候路径是 '/F:/out1/test.xlsx',有的时候是'F:/out1/test.xlsx'
if project_dir[0] == '/':
project_dir = project_dir[1:]
self.project_base_dir = project_dir
# self.video_path = os.path.join(project_dir, video_name)
self.video_path = project_dir + "/" + video_name
print("video_path", self.video_path)
self.excel_path = replace_path_suffix(self.video_path, ".xlsx")
self.load_conf()
def load_conf(self):
......@@ -174,6 +165,9 @@ class ProjectContext:
# 如果当前工程里还没有对应的配置文件,那么选择使用全局的配置文件进行初始化,否则就使用当前工程的配置文件
if os.path.exists(this_conf_path):
self.conf_path = this_conf_path
if not os.path.exists(self.conf_path):
print("conf file does not exist, 找管理员要")
return
with open(self.conf_path, 'r', encoding='utf8') as f:
info = json.load(f)
video_path = info["video_path"]
......@@ -186,6 +180,10 @@ class ProjectContext:
self.last_time = info["detection_info"]["last_time"]
self.caption_boundings = info["detection_info"]["caption_boundings"]
self.has_subtitle = info["detection_info"]["has_subtitle"]
# 当前工程下没有配置文件,就初始化一份
if self.conf_path != this_conf_path:
self.conf_path = this_conf_path
self.save_conf()
def save_conf(self):
with open(self.conf_path, 'w', encoding='utf-8') as f:
......
......@@ -12,10 +12,11 @@ from operation_dialog_ui import Ui_Dialog
class Operation_Dialog(QDialog, Ui_Dialog):
#开始检测信号,传参分别是movie路径和输出表格路径
# 开始检测信号,传参分别是movie路径和输出表格路径
start_add_signal = pyqtSignal(str, str, str, str, str, str, str)
start_mod_signal = pyqtSignal(str, str, str, str, str, str, str)
start_del_signal = pyqtSignal(str, str, str, str, str, str, str)
def __init__(self, mainWindow):
super(Operation_Dialog, self).__init__()
self.setupUi(self)
......@@ -24,7 +25,7 @@ class Operation_Dialog(QDialog, Ui_Dialog):
self.pushButton.clicked.connect(self.check_validate_slot)
self.pushButton_2.clicked.connect(self.remake_slot)
#如果是【修改一行】,选择行的时候要瞬间更新成目前行的内容
# 如果是【修改一行】,选择行的时候要瞬间更新成目前行的内容
self.pushButton_3.clicked.connect(self.fill_row_info_slot)
self.buttonBox.setEnabled(False)
......@@ -34,9 +35,11 @@ class Operation_Dialog(QDialog, Ui_Dialog):
self.comboBox.currentIndexChanged.connect(self.zmpb_change_slot)
# 增加一行/删除一行 选择框
self.comboBox_2.currentIndexChanged.connect(self.adddel_change_slot)
self.speed_list = ["1.00(4字/秒)", "1.10(4.5字/秒)", "1.25(5字/秒)", "1.50(6字/秒)", "1.75(7字/秒)", "2.00(8字/秒)", "2.50(10字/秒)"]
self.speed_list = ["1.00(4字/秒)", "1.10(4.5字/秒)", "1.25(5字/秒)",
"1.50(6字/秒)", "1.75(7字/秒)", "2.00(8字/秒)", "2.50(10字/秒)"]
self.comboBox_3.addItems(self.speed_list)
self.lineEdits = [self.lineEdit, self.lineEdit_2, self.lineEdit_3, self.lineEdit_4, self.lineEdit_5, self.lineEdit_6]
self.lineEdits = [self.lineEdit, self.lineEdit_2, self.lineEdit_3,
self.lineEdit_4, self.lineEdit_5, self.lineEdit_6]
self.zmpb_change_slot()
self.adddel_change_slot()
......@@ -81,27 +84,31 @@ class Operation_Dialog(QDialog, Ui_Dialog):
# 校验时间填写是否是hh:mm:ss格式的
try:
import re
if type(self.lineEdit_2.text())==str and len(self.lineEdit_2.text()) > 0:
x = re.match("^(([0-1]\d)|(2[0-4])):[0-5]\d:[0-5]\d(.\d{1,2})?$", self.lineEdit_2.text())
if type(self.lineEdit_2.text()) == str and len(self.lineEdit_2.text()) > 0:
x = re.match(
"^(([0-1]\d)|(2[0-4])):[0-5]\d:[0-5]\d(.\d{1,2})?$", self.lineEdit_2.text())
assert x != None
if type(self.lineEdit_3.text()) == str and len(self.lineEdit_3.text()) > 0:
x = re.match("^(([0-1]\d)|(2[0-4])):[0-5]\d:[0-5]\d(.\d{1,2})?$", self.lineEdit_3.text())
x = re.match(
"^(([0-1]\d)|(2[0-4])):[0-5]\d:[0-5]\d(.\d{1,2})?$", self.lineEdit_3.text())
assert x != None
except Exception as e:
self.mainWindow.prompt_dialog.show_with_msg("校验失败!起始或结束时间输入的格式有误!应该为hh:mm:ss!!"%(rowCount, self.lineEdit.text()))
self.mainWindow.prompt_dialog.show_with_msg(
"校验失败!起始或结束时间输入的格式有误!应该为hh:mm:ss!!" % (rowCount, self.lineEdit.text()))
return False
# 这些是只有【add】才需要检测的
if self.comboBox_2.currentText() == "增加一行":
# 校验起始时间、结束时间
start_time_f, end_time_f = 0.0, 0.0
try:
start_time_f = float(utils.trans_to_seconds(self.lineEdit_2.text()))
start_time_f = float(
utils.trans_to_seconds(self.lineEdit_2.text()))
if self.comboBox.currentText() == "字幕":
end_time_f = float(utils.trans_to_seconds(self.lineEdit_3.text()))
end_time_f = float(
utils.trans_to_seconds(self.lineEdit_3.text()))
assert start_time_f < end_time_f
except Exception as e:
self.mainWindow.prompt_dialog.show_with_msg(
......@@ -145,12 +152,13 @@ class Operation_Dialog(QDialog, Ui_Dialog):
def start_operation_slot(self):
row, start_time, end_time, subtitle, suggest, aside = [x.text() for x in self.lineEdits]
row, start_time, end_time, subtitle, suggest, aside = [
x.text() for x in self.lineEdits]
speed = self.comboBox_3.currentText()
# 将hh:mm:ss转成秒的形式传给mainWindow
if type(start_time)==str and len(start_time)>0:
if type(start_time) == str and len(start_time) > 0:
start_time = str(utils.trans_to_seconds(start_time))
if type(end_time)==str and len(end_time)>0:
if type(end_time) == str and len(end_time) > 0:
end_time = str(utils.trans_to_seconds(end_time))
if self.comboBox.currentText() == "字幕":
......@@ -168,11 +176,14 @@ class Operation_Dialog(QDialog, Ui_Dialog):
# 根据增删两种操作,分别触发不同信号。
if self.comboBox_2.currentText() == "增加一行":
self.start_add_signal.emit(row, start_time, end_time, subtitle, suggest, aside, speed)
self.start_add_signal.emit(
row, start_time, end_time, subtitle, suggest, aside, speed)
elif self.comboBox_2.currentText() == "修改一行":
self.start_mod_signal.emit(row, start_time, end_time, subtitle, suggest, aside, speed)
self.start_mod_signal.emit(
row, start_time, end_time, subtitle, suggest, aside, speed)
else:
self.start_del_signal.emit(row, start_time, end_time, subtitle, suggest, aside, speed)
self.start_del_signal.emit(
row, start_time, end_time, subtitle, suggest, aside, speed)
def fill_row_info_slot(self):
text = self.lineEdit.text()
......@@ -182,18 +193,21 @@ class Operation_Dialog(QDialog, Ui_Dialog):
rowCount = self.mainWindow.all_tableWidget.rowCount()
row_number = int(self.lineEdit.text())
assert 1 <= row_number <= rowCount
elem = self.mainWindow.projectContext.all_elements[int(row_number)-1]
self.lineEdit_2.setText(str(utils.transfer_second_to_time(elem.st_time_sec)))
self.lineEdit_3.setText(str(utils.transfer_second_to_time(elem.ed_time_sec)))
elem = self.mainWindow.projectContext.all_elements[int(
row_number)-1]
self.lineEdit_2.setText(
str(utils.transfer_second_to_time(elem.st_time_sec)))
self.lineEdit_3.setText(str(utils.transfer_second_to_time(elem.ed_time_sec))) if len(
elem.ed_time_sec) > 0 else self.lineEdit_3.setText("")
self.lineEdit_4.setText(elem.subtitle)
self.lineEdit_5.setText(
elem.suggest[elem.suggest.index("推荐字数为") + 5:])
self.lineEdit_6.setText(elem.aside)
self.comboBox_3.setCurrentIndex(
self.speed_list.index(elem.speed))
# 如果是旁白的话
if elem.suggest is not None and "推荐字数为" in elem.suggest:
self.lineEdit_5.setText(elem.suggest[elem.suggest.index("推荐字数为")+5:])
self.comboBox_3.setCurrentIndex(self.speed_list.index(elem.speed))
self.lineEdit_5.setText(
elem.suggest[elem.suggest.index("推荐字数为")+5:])
except Exception as e:
print("exception:", e)
pass
......
......@@ -24,6 +24,8 @@ class Prompt_Dialog(QDialog, Ui_Dialog):
super(Prompt_Dialog, self).__init__()
self.setupUi(self)
self.setWindowTitle("提示框")
self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText("确认")
self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText("取消")
self.show_dialog_signal.connect(self.show_with_msg)
def show_with_msg(self, msg):
......
......@@ -2,7 +2,6 @@
用于渲染最终成果,将之前临时生成的音频插入到原音频中|生成一条纯旁白的音频|插入到原视频中
'''
import librosa
import numpy as np
import os
import soundfile
......@@ -21,7 +20,7 @@ class ExportProcessor(QWidget):
export_callback_signal = pyqtSignal(list, list)
def __init__(self):
super(ExportProcessor, self).__init__()
self.state = [None]
self.state = [0]
self.threads = []
def export_slot(self, video_path, output_dir):
......@@ -47,11 +46,12 @@ class ExportProcessor(QWidget):
def aggrevate_audios(video_path: str, output_dir: str, state=None):
# 这个模块最多只有80%的进度
if state is None:
state = [None]
state = [0]
# 生成等长的空白音频
from split_wav import extract_audio
origin_wav_path = extract_audio(video_path, output_dir, 0, -1)
origin_wav, freq = librosa.load(origin_wav_path)
# 提取音频的进度最多20%
origin_wav_path = extract_audio(video_path, output_dir, 0, -1, state)
origin_wav, freq = soundfile.read(origin_wav_path)
blank_audio = np.zeros_like(origin_wav)
# 将生成的旁白音频放入空白音频中,并将原音频的对应位置音量降低为原来的30%
......@@ -60,13 +60,13 @@ def aggrevate_audios(video_path: str, output_dir: str, state=None):
fname = '.'.join(f.split('.')[:-1])
try:
st_time = float(fname)
cur_audio, _ = librosa.load(os.path.join(output_dir, f))
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] *= 0.3
state[0] = float((i + 1) / len(files)) * 0.7
state[0] = float((i + 1) / len(files)) * 0.6 + 0.2
except:
continue
......@@ -85,7 +85,7 @@ def aggrevate_audios(video_path: str, output_dir: str, state=None):
def export_video(video_path: str, mixed_audio_path: str, output_dir: str, state=None):
if state is None:
state = [None]
state = [0]
# 生成合成音频+原视频的新视频
if os.path.basename(video_path).split('.')[-1] == 'rmvb':
video_name = os.path.basename(video_path).split('.')[0]
......@@ -94,7 +94,8 @@ def export_video(video_path: str, mixed_audio_path: str, output_dir: str, state=
else:
mixed_movie_path = os.path.join(output_dir, "new_" + os.path.basename(video_path))
command_line = f'{ffmpeg_path} -i {video_path} -i {mixed_audio_path} -map 0:v:0 -map 1:a:0 -vcodec copy {mixed_movie_path} -y'
subprocess.call(command_line)
from utils import get_progress_with_cmd
get_progress_with_cmd(command_line, state)
state[0] = 1.00
......
......@@ -8,17 +8,16 @@
"""
# 最简单的是音轨分离,直接将背景音乐的轨道剥离,只剩下人声道后即可根据空白片段进行切割
# 只有一个音轨时,使用音乐检索系统,分割人声和背景音乐声
# from pydub import AudioSegment
# from moviepy.editor import *
# import numpy as np
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
import numpy as np
from moviepy.editor import *
from pydub import AudioSegment
ffmpeg_path = r'.\ffmpeg-4.3.1\bin\ffmpeg'
def extract_audio(video_path: str, root: str, start_time: float, end_time: float) -> str:
def extract_audio(video_path: str, root: str, start_time: float, end_time: float, state=None) -> str:
"""从视频中读取音频
Args:
......@@ -36,7 +35,8 @@ def extract_audio(video_path: str, root: str, start_time: float, end_time: float
else:
command = "{} -i {} -ar 16000 -ac 1 -ss {} -to {} -y {}".format(ffmpeg_path, video_path, start_time, end_time,
audio_path)
os.system(command)
from utils import get_progress_with_cmd
get_progress_with_cmd(command, state)
return audio_path
......
......@@ -6,16 +6,20 @@ from PyQt5.QtGui import *;
from PyQt5.QtWidgets import *;
from main_window import MainWindow
from qt_material import apply_stylesheet
import qdarkstyle
import os
os.environ['PYQTGRAPH_QT_LIB'] = 'PyQt5'
if __name__ == '__main__':
try:
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./images/eagle_2.ico"))
mainWindow = MainWindow()
# apply_stylesheet(app, theme='dark_amber.xml')
mainWindow.setWindowTitle("无障碍电影制作软件")
apply_stylesheet(app, theme='dark_amber.xml')
# app.setStyleSheet(qdarkstyle.load_stylesheet(qt_api=os.environ['PYQTGRAPH_QT_LIB']))
mainWindow.show()
......
import os, sys
import openpyxl
import subprocess
import re
def validate_and_get_filepath(file_info):
if type(file_info[0]) == str:
return file_info[0], True
......@@ -80,6 +83,29 @@ def get_sheetHead(book_path: str) -> list:
sheet_head.append(sheet.cell(1, j).value)
return sheet_head
def get_progress_with_cmd(cmd: str, state=None):
if state is None:
state = [0]
pre = state[0]
process = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, encoding='utf-8', text=True)
for line in process.stdout:
print(line)
duration_res = re.search(r'\sDuration: (?P<duration>\S+)', line)
if duration_res is not None:
print("----------------------------------")
duration = duration_res.groupdict()['duration']
duration = re.sub(r',', '', duration)
print(duration)
result = re.search(r'\stime=(?P<time>\S+)', line)
if result is not None:
elapsed_time = result.groupdict()['time']
# 此处可能会出现进度超过100%,未对数值进行纠正
progress = trans_to_seconds(elapsed_time) / trans_to_seconds(duration)
state[0] = pre + progress * 0.2
print(elapsed_time)
print(progress)
print("进度:%3.2f" % (progress * 100) + "%")
if __name__ == '__main__':
x = transfer_second_to_time("12000.923")
......
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