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): ...@@ -35,6 +35,7 @@ class Assemble_Dialog(QDialog, Ui_Dialog):
self.lineEdit_3.setText(projectContext.speaker_info) self.lineEdit_3.setText(projectContext.speaker_info)
self.lineEdit_4.setText(projectContext.speaker_speed) self.lineEdit_4.setText(projectContext.speaker_speed)
# self.show.connect(self.init_self_slot) # self.show.connect(self.init_self_slot)
def init_self(self): def init_self(self):
# print("self.projectContext.speaker_info", self.projectContext.speaker_info) # print("self.projectContext.speaker_info", self.projectContext.speaker_info)
self.lineEdit.setText(self.projectContext.video_path) self.lineEdit.setText(self.projectContext.video_path)
......
...@@ -67,6 +67,4 @@ class Ui_Dialog(object): ...@@ -67,6 +67,4 @@ class Ui_Dialog(object):
self.label_2.setText(_translate("Dialog", "旁白脚本表格:")) self.label_2.setText(_translate("Dialog", "旁白脚本表格:"))
self.pushButton_2.setText(_translate("Dialog", "表格路径")) self.pushButton_2.setText(_translate("Dialog", "表格路径"))
self.label_3.setText(_translate("Dialog", "旁白说话人:")) self.label_3.setText(_translate("Dialog", "旁白说话人:"))
self.label_4.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)"}} {"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 \ 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): ...@@ -12,8 +12,9 @@ class Detect_Dialog(QDialog, Ui_Dialog):
#开始检测信号,传参分别是movie路径和输出表格路径 #开始检测信号,传参分别是movie路径和输出表格路径
start_detect_signal = pyqtSignal(str, str) start_detect_signal = pyqtSignal(str, str)
def __init__(self): def __init__(self, projectContext):
super(Detect_Dialog, self).__init__() super(Detect_Dialog, self).__init__()
self.projectContext = projectContext
self.setupUi(self) self.setupUi(self)
self.setWindowTitle("检测") self.setWindowTitle("检测")
self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText("开始检测") self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText("开始检测")
...@@ -21,12 +22,19 @@ class Detect_Dialog(QDialog, Ui_Dialog): ...@@ -21,12 +22,19 @@ class Detect_Dialog(QDialog, Ui_Dialog):
self.pushButton.clicked.connect(self.openFile) self.pushButton.clicked.connect(self.openFile)
self.pushButton_2.clicked.connect(self.openTableFile) self.pushButton_2.clicked.connect(self.openTableFile)
self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).clicked.connect(self.start_detect) 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): 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) file_name, ok = validate_and_get_filepath(file_info)
if ok: if ok:
self.lineEdit.setText(file_name) self.lineEdit.setText(file_name)
self.lineEdit_2.setText(replace_path_suffix(file_info[0][0], ".xlsx")) self.lineEdit_2.setText(replace_path_suffix(file_info[0][0], ".xlsx"))
def openTableFile(self): def openTableFile(self):
now_path = os.path.join(os.getcwd(), self.lineEdit.text()) now_path = os.path.join(os.getcwd(), self.lineEdit.text())
now_path = now_path.replace(os.path.splitext(now_path)[-1], ".xlsx") now_path = now_path.replace(os.path.splitext(now_path)[-1], ".xlsx")
...@@ -37,6 +45,7 @@ class Detect_Dialog(QDialog, Ui_Dialog): ...@@ -37,6 +45,7 @@ class Detect_Dialog(QDialog, Ui_Dialog):
print(file_name, ok) print(file_name, ok)
if ok: if ok:
self.lineEdit_2.setText(file_name) self.lineEdit_2.setText(file_name)
def start_detect(self): def start_detect(self):
# 发出一个信号,开始检测了 # 发出一个信号,开始检测了
# 版本1.0:(当前版本) # 版本1.0:(当前版本)
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
<x>20</x> <x>20</x>
<y>70</y> <y>70</y>
<width>72</width> <width>72</width>
<height>15</height> <height>16</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
...@@ -55,9 +55,9 @@ ...@@ -55,9 +55,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>100</x> <x>100</x>
<y>70</y> <y>68</y>
<width>211</width> <width>211</width>
<height>21</height> <height>20</height>
</rect> </rect>
</property> </property>
</widget> </widget>
...@@ -65,9 +65,9 @@ ...@@ -65,9 +65,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>390</x> <x>390</x>
<y>60</y> <y>63</y>
<width>93</width> <width>110</width>
<height>28</height> <height>30</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
<x>20</x> <x>20</x>
<y>130</y> <y>130</y>
<width>72</width> <width>72</width>
<height>15</height> <height>16</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
...@@ -91,9 +91,9 @@ ...@@ -91,9 +91,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>100</x> <x>100</x>
<y>130</y> <y>128</y>
<width>211</width> <width>211</width>
<height>21</height> <height>20</height>
</rect> </rect>
</property> </property>
</widget> </widget>
...@@ -101,9 +101,9 @@ ...@@ -101,9 +101,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>390</x> <x>390</x>
<y>130</y> <y>123</y>
<width>101</width> <width>110</width>
<height>31</height> <height>30</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
......
...@@ -110,12 +110,12 @@ def detect_with_asr(video_path: str, book_path: str, start_time=0, end_time=-1, ...@@ -110,12 +110,12 @@ def detect_with_asr(video_path: str, book_path: str, start_time=0, end_time=-1,
if __name__ == '__main__': if __name__ == '__main__':
create_sheet("./xxxxxx.xlsx", "abc", [["起始时间", "终止时间", "字幕", '建议', '解说脚本']]) # create_sheet("./xxxxxx.xlsx", "abc", [["起始时间", "终止时间", "字幕", '建议', '解说脚本']])
# write_to_sheet("./xxx.xlsx", "abc", ["qssj", "zzsj", "zm", 'jy', 'pb']) # # write_to_sheet("./xxx.xlsx", "abc", ["qssj", "zzsj", "zm", 'jy', 'pb'])
pass # pass
# start_time = time.time() start_time = time.time()
# # 给定待处理的视频路径 # 给定待处理的视频路径
# video_path = 'D:/Downloads/芳H.[更多请关注公众号:吃瓜族].mp4' video_path = 'D:\software\WPF_JJDown_v1.229.1\[WPF]JJDown\Download\大闹天宫.mp4'
#
# detect_with_asr(video_path, "fanghua.xlsx", 0, 8122, [None]) detect_with_asr(video_path, "大闹天宫.xlsx", 0, 6754)
# print("处理视频 {} 需要时长为{} ".format(os.path.basename(video_path), time.time() - start_time)) 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 ...@@ -227,6 +227,15 @@ def process_video(video_path: str, begin: float, end: float, book_path: str, she
sheet_name (str): 输出表格中的表名 sheet_name (str): 输出表格中的表名
state (optional): 用于通信的状态关键字. Defaults to None. 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: if state is None:
state = [None] state = [None]
video = cv2.VideoCapture(video_path) video = cv2.VideoCapture(video_path)
...@@ -262,9 +271,9 @@ def process_video(video_path: str, begin: float, end: float, book_path: str, she ...@@ -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 cnt % int(fps / 4) == 0:
# 更新当前工程的检测进度 # 更新当前工程的检测进度
if pre_state is None: if pre_state is None:
state[0] = float((cur_time - begin) / (end - begin)) state[0] = float(cur_time/ end)
else: 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.nd_process = state[0]
mainWindow.projectContext.last_time = cur_time mainWindow.projectContext.last_time = cur_time
...@@ -278,9 +287,9 @@ def process_video(video_path: str, begin: float, end: float, book_path: str, she ...@@ -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: elif lastSubTitle is not None and subTitle is None:
end_time = cur_time end_time = cur_time
res.append([start_time, end_time, lastSubTitle]) 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('--------------------------------------------------') 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) (res[-1][0] - res[-2][1]) * normal_speed)
# write_to_sheet(book_path, sheet_name, ['', '', '', '插入旁白,推荐字数为%d' % recommend_lens]) # write_to_sheet(book_path, sheet_name, ['', '', '', '插入旁白,推荐字数为%d' % recommend_lens])
add_to_list(mainWindow, "旁白", ['', '', '', '插入旁白,推荐字数为%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 ...@@ -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: if string_similar(lastSubTitle, subTitle) < 0.7:
end_time = cur_time end_time = cur_time
res.append([start_time, end_time, lastSubTitle]) 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('--------------------------------------------------') 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) (res[-1][0] - res[-2][1]) * normal_speed)
# write_to_sheet(book_path, sheet_name, ['', '', '', '插入旁白,推荐字数为%d' % recommend_lens]) # write_to_sheet(book_path, sheet_name, ['', '', '', '插入旁白,推荐字数为%d' % recommend_lens])
add_to_list(mainWindow, "旁白", ['', '', '', '插入旁白,推荐字数为%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
This diff is collapsed.
<?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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -74,10 +74,6 @@ class OperateRecord: ...@@ -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) s = "{row=%d, opt=%s, oldStr=%s, newStr=%s}"%(self.row, str(self.operation), self.old_str, self.new_str)
return s return s
# 每一行的具体信息,"起始时间", "终止时间", "字幕", '建议', '解说脚本' # 每一行的具体信息,"起始时间", "终止时间", "字幕", '建议', '解说脚本'
class Element: class Element:
def __init__(self, st_time_sec: str, ed_time_sec: str, subtitle, suggest, aside, speed = "1.00(4字/秒)"): def __init__(self, st_time_sec: str, ed_time_sec: str, subtitle, suggest, aside, speed = "1.00(4字/秒)"):
...@@ -88,7 +84,6 @@ class Element: ...@@ -88,7 +84,6 @@ class Element:
self.aside = aside self.aside = aside
self.speed = speed self.speed = speed
# 判断当前元素是否是字幕 # 判断当前元素是否是字幕
def is_subtitle(self): def is_subtitle(self):
return self.subtitle != None and self.subtitle != "" return self.subtitle != None and self.subtitle != ""
...@@ -126,10 +121,10 @@ class ProjectContext: ...@@ -126,10 +121,10 @@ class ProjectContext:
self.speaker_speed = None self.speaker_speed = None
# 一些常量 # 一些常量
self.header = ["起始时间", "终止时间", "字幕", '建议', '解说脚本', "语速"] self.header = ["起始时间", "终止时间", "字幕", '建议', '解说脚本', "语速"]
self.aside_header = ["起始时间", "终止时间", '建议', '解说脚本',"语速"] self.aside_header = ["起始时间", "终止时间", '推荐插入字数', '解说脚本',"语速", ""]
self.subtitle_header = ["起始时间", "终止时间", "字幕"] self.subtitle_header = ["起始时间", "终止时间", "字幕", ""]
self.contentHeader = ["起始时间", "字幕", "旁白", "语速"] self.contentHeader = ["起始时间", "字幕", "解说脚本", "语速", ""]
self.excel_sheet_name = "旁白插入位置建议" self.excel_sheet_name = "旁白插入位置建议"
self.history_records = [] self.history_records = []
self.records_pos = 0 self.records_pos = 0
...@@ -156,17 +151,13 @@ class ProjectContext: ...@@ -156,17 +151,13 @@ class ProjectContext:
self.history_records = [] self.history_records = []
self.records_pos = 0 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: if len(project_dir) == 0 or project_dir is None:
return return
# 有的时候路径是 '/F:/out1/test.xlsx',有的时候是'F:/out1/test.xlsx' # 有的时候路径是 '/F:/out1/test.xlsx',有的时候是'F:/out1/test.xlsx'
if project_dir[0] == '/': if project_dir[0] == '/':
project_dir = project_dir[1:] project_dir = project_dir[1:]
self.project_base_dir = project_dir 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() self.load_conf()
def load_conf(self): def load_conf(self):
...@@ -174,6 +165,9 @@ class ProjectContext: ...@@ -174,6 +165,9 @@ class ProjectContext:
# 如果当前工程里还没有对应的配置文件,那么选择使用全局的配置文件进行初始化,否则就使用当前工程的配置文件 # 如果当前工程里还没有对应的配置文件,那么选择使用全局的配置文件进行初始化,否则就使用当前工程的配置文件
if os.path.exists(this_conf_path): if os.path.exists(this_conf_path):
self.conf_path = 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: with open(self.conf_path, 'r', encoding='utf8') as f:
info = json.load(f) info = json.load(f)
video_path = info["video_path"] video_path = info["video_path"]
...@@ -186,6 +180,10 @@ class ProjectContext: ...@@ -186,6 +180,10 @@ class ProjectContext:
self.last_time = info["detection_info"]["last_time"] self.last_time = info["detection_info"]["last_time"]
self.caption_boundings = info["detection_info"]["caption_boundings"] self.caption_boundings = info["detection_info"]["caption_boundings"]
self.has_subtitle = info["detection_info"]["has_subtitle"] 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): def save_conf(self):
with open(self.conf_path, 'w', encoding='utf-8') as f: with open(self.conf_path, 'w', encoding='utf-8') as f:
......
...@@ -12,10 +12,11 @@ from operation_dialog_ui import Ui_Dialog ...@@ -12,10 +12,11 @@ from operation_dialog_ui import Ui_Dialog
class Operation_Dialog(QDialog, Ui_Dialog): class Operation_Dialog(QDialog, Ui_Dialog):
#开始检测信号,传参分别是movie路径和输出表格路径 # 开始检测信号,传参分别是movie路径和输出表格路径
start_add_signal = pyqtSignal(str, str, str, str, str, str, str) start_add_signal = pyqtSignal(str, str, str, str, str, str, str)
start_mod_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) start_del_signal = pyqtSignal(str, str, str, str, str, str, str)
def __init__(self, mainWindow): def __init__(self, mainWindow):
super(Operation_Dialog, self).__init__() super(Operation_Dialog, self).__init__()
self.setupUi(self) self.setupUi(self)
...@@ -24,7 +25,7 @@ class Operation_Dialog(QDialog, Ui_Dialog): ...@@ -24,7 +25,7 @@ class Operation_Dialog(QDialog, Ui_Dialog):
self.pushButton.clicked.connect(self.check_validate_slot) self.pushButton.clicked.connect(self.check_validate_slot)
self.pushButton_2.clicked.connect(self.remake_slot) self.pushButton_2.clicked.connect(self.remake_slot)
#如果是【修改一行】,选择行的时候要瞬间更新成目前行的内容 # 如果是【修改一行】,选择行的时候要瞬间更新成目前行的内容
self.pushButton_3.clicked.connect(self.fill_row_info_slot) self.pushButton_3.clicked.connect(self.fill_row_info_slot)
self.buttonBox.setEnabled(False) self.buttonBox.setEnabled(False)
...@@ -34,9 +35,11 @@ class Operation_Dialog(QDialog, Ui_Dialog): ...@@ -34,9 +35,11 @@ class Operation_Dialog(QDialog, Ui_Dialog):
self.comboBox.currentIndexChanged.connect(self.zmpb_change_slot) self.comboBox.currentIndexChanged.connect(self.zmpb_change_slot)
# 增加一行/删除一行 选择框 # 增加一行/删除一行 选择框
self.comboBox_2.currentIndexChanged.connect(self.adddel_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.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.zmpb_change_slot()
self.adddel_change_slot() self.adddel_change_slot()
...@@ -81,27 +84,31 @@ class Operation_Dialog(QDialog, Ui_Dialog): ...@@ -81,27 +84,31 @@ class Operation_Dialog(QDialog, Ui_Dialog):
# 校验时间填写是否是hh:mm:ss格式的 # 校验时间填写是否是hh:mm:ss格式的
try: try:
import re import re
if type(self.lineEdit_2.text())==str and len(self.lineEdit_2.text()) > 0: 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()) 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 assert x != None
if type(self.lineEdit_3.text()) == str and len(self.lineEdit_3.text()) > 0: 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 assert x != None
except Exception as e: 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 return False
# 这些是只有【add】才需要检测的 # 这些是只有【add】才需要检测的
if self.comboBox_2.currentText() == "增加一行": if self.comboBox_2.currentText() == "增加一行":
# 校验起始时间、结束时间 # 校验起始时间、结束时间
start_time_f, end_time_f = 0.0, 0.0 start_time_f, end_time_f = 0.0, 0.0
try: 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() == "字幕": 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 assert start_time_f < end_time_f
except Exception as e: except Exception as e:
self.mainWindow.prompt_dialog.show_with_msg( self.mainWindow.prompt_dialog.show_with_msg(
...@@ -145,12 +152,13 @@ class Operation_Dialog(QDialog, Ui_Dialog): ...@@ -145,12 +152,13 @@ class Operation_Dialog(QDialog, Ui_Dialog):
def start_operation_slot(self): 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() speed = self.comboBox_3.currentText()
# 将hh:mm:ss转成秒的形式传给mainWindow # 将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)) 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)) end_time = str(utils.trans_to_seconds(end_time))
if self.comboBox.currentText() == "字幕": if self.comboBox.currentText() == "字幕":
...@@ -168,11 +176,14 @@ class Operation_Dialog(QDialog, Ui_Dialog): ...@@ -168,11 +176,14 @@ class Operation_Dialog(QDialog, Ui_Dialog):
# 根据增删两种操作,分别触发不同信号。 # 根据增删两种操作,分别触发不同信号。
if self.comboBox_2.currentText() == "增加一行": 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() == "修改一行": 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: 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): def fill_row_info_slot(self):
text = self.lineEdit.text() text = self.lineEdit.text()
...@@ -182,18 +193,21 @@ class Operation_Dialog(QDialog, Ui_Dialog): ...@@ -182,18 +193,21 @@ class Operation_Dialog(QDialog, Ui_Dialog):
rowCount = self.mainWindow.all_tableWidget.rowCount() rowCount = self.mainWindow.all_tableWidget.rowCount()
row_number = int(self.lineEdit.text()) row_number = int(self.lineEdit.text())
assert 1 <= row_number <= rowCount assert 1 <= row_number <= rowCount
elem = self.mainWindow.projectContext.all_elements[int(row_number)-1] elem = self.mainWindow.projectContext.all_elements[int(
self.lineEdit_2.setText(str(utils.transfer_second_to_time(elem.st_time_sec))) row_number)-1]
self.lineEdit_3.setText(str(utils.transfer_second_to_time(elem.ed_time_sec))) 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_4.setText(elem.subtitle)
self.lineEdit_5.setText(
elem.suggest[elem.suggest.index("推荐字数为") + 5:])
self.lineEdit_6.setText(elem.aside) 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: if elem.suggest is not None and "推荐字数为" in elem.suggest:
self.lineEdit_5.setText(elem.suggest[elem.suggest.index("推荐字数为")+5:]) self.lineEdit_5.setText(
self.comboBox_3.setCurrentIndex(self.speed_list.index(elem.speed)) elem.suggest[elem.suggest.index("推荐字数为")+5:])
except Exception as e: except Exception as e:
print("exception:", e) print("exception:", e)
pass pass
......
...@@ -24,6 +24,8 @@ class Prompt_Dialog(QDialog, Ui_Dialog): ...@@ -24,6 +24,8 @@ class Prompt_Dialog(QDialog, Ui_Dialog):
super(Prompt_Dialog, self).__init__() super(Prompt_Dialog, self).__init__()
self.setupUi(self) self.setupUi(self)
self.setWindowTitle("提示框") 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) self.show_dialog_signal.connect(self.show_with_msg)
def show_with_msg(self, msg): def show_with_msg(self, msg):
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
用于渲染最终成果,将之前临时生成的音频插入到原音频中|生成一条纯旁白的音频|插入到原视频中 用于渲染最终成果,将之前临时生成的音频插入到原音频中|生成一条纯旁白的音频|插入到原视频中
''' '''
import librosa
import numpy as np import numpy as np
import os import os
import soundfile import soundfile
...@@ -21,7 +20,7 @@ class ExportProcessor(QWidget): ...@@ -21,7 +20,7 @@ class ExportProcessor(QWidget):
export_callback_signal = pyqtSignal(list, list) export_callback_signal = pyqtSignal(list, list)
def __init__(self): def __init__(self):
super(ExportProcessor, self).__init__() super(ExportProcessor, self).__init__()
self.state = [None] self.state = [0]
self.threads = [] self.threads = []
def export_slot(self, video_path, output_dir): def export_slot(self, video_path, output_dir):
...@@ -47,11 +46,12 @@ class ExportProcessor(QWidget): ...@@ -47,11 +46,12 @@ class ExportProcessor(QWidget):
def aggrevate_audios(video_path: str, output_dir: str, state=None): def aggrevate_audios(video_path: str, output_dir: str, state=None):
# 这个模块最多只有80%的进度 # 这个模块最多只有80%的进度
if state is None: if state is None:
state = [None] state = [0]
# 生成等长的空白音频 # 生成等长的空白音频
from split_wav import extract_audio from split_wav import extract_audio
origin_wav_path = extract_audio(video_path, output_dir, 0, -1) # 提取音频的进度最多20%
origin_wav, freq = librosa.load(origin_wav_path) 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) blank_audio = np.zeros_like(origin_wav)
# 将生成的旁白音频放入空白音频中,并将原音频的对应位置音量降低为原来的30% # 将生成的旁白音频放入空白音频中,并将原音频的对应位置音量降低为原来的30%
...@@ -60,13 +60,13 @@ def aggrevate_audios(video_path: str, output_dir: str, state=None): ...@@ -60,13 +60,13 @@ def aggrevate_audios(video_path: str, output_dir: str, state=None):
fname = '.'.join(f.split('.')[:-1]) fname = '.'.join(f.split('.')[:-1])
try: try:
st_time = float(fname) 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)) # print(len(cur_audio))
st_index = int(st_time * freq) st_index = int(st_time * freq)
audio_len = len(cur_audio) audio_len = len(cur_audio)
blank_audio[st_index: st_index + audio_len] = cur_audio blank_audio[st_index: st_index + audio_len] = cur_audio
origin_wav[st_index: st_index + audio_len] *= 0.3 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: except:
continue continue
...@@ -85,7 +85,7 @@ def aggrevate_audios(video_path: str, output_dir: str, state=None): ...@@ -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): def export_video(video_path: str, mixed_audio_path: str, output_dir: str, state=None):
if state is None: if state is None:
state = [None] state = [0]
# 生成合成音频+原视频的新视频 # 生成合成音频+原视频的新视频
if os.path.basename(video_path).split('.')[-1] == 'rmvb': if os.path.basename(video_path).split('.')[-1] == 'rmvb':
video_name = os.path.basename(video_path).split('.')[0] 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= ...@@ -94,7 +94,8 @@ def export_video(video_path: str, mixed_audio_path: str, output_dir: str, state=
else: else:
mixed_movie_path = os.path.join(output_dir, "new_" + os.path.basename(video_path)) 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' 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 state[0] = 1.00
......
...@@ -8,17 +8,16 @@ ...@@ -8,17 +8,16 @@
""" """
# 最简单的是音轨分离,直接将背景音乐的轨道剥离,只剩下人声道后即可根据空白片段进行切割 # 最简单的是音轨分离,直接将背景音乐的轨道剥离,只剩下人声道后即可根据空白片段进行切割
# 只有一个音轨时,使用音乐检索系统,分割人声和背景音乐声 # 只有一个音轨时,使用音乐检索系统,分割人声和背景音乐声
# from pydub import AudioSegment
# from moviepy.editor import *
# import numpy as np
import os import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1" 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' 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: Args:
...@@ -36,7 +35,8 @@ def extract_audio(video_path: str, root: str, start_time: float, end_time: float ...@@ -36,7 +35,8 @@ def extract_audio(video_path: str, root: str, start_time: float, end_time: float
else: else:
command = "{} -i {} -ar 16000 -ac 1 -ss {} -to {} -y {}".format(ffmpeg_path, video_path, start_time, end_time, command = "{} -i {} -ar 16000 -ac 1 -ss {} -to {} -y {}".format(ffmpeg_path, video_path, start_time, end_time,
audio_path) audio_path)
os.system(command) from utils import get_progress_with_cmd
get_progress_with_cmd(command, state)
return audio_path return audio_path
......
...@@ -6,16 +6,20 @@ from PyQt5.QtGui import *; ...@@ -6,16 +6,20 @@ from PyQt5.QtGui import *;
from PyQt5.QtWidgets import *; from PyQt5.QtWidgets import *;
from main_window import MainWindow from main_window import MainWindow
from qt_material import apply_stylesheet
import qdarkstyle
import os import os
os.environ['PYQTGRAPH_QT_LIB'] = 'PyQt5' os.environ['PYQTGRAPH_QT_LIB'] = 'PyQt5'
if __name__ == '__main__': if __name__ == '__main__':
try: try:
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv) app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./images/eagle_2.ico")) app.setWindowIcon(QIcon("./images/eagle_2.ico"))
mainWindow = MainWindow() 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'])) # app.setStyleSheet(qdarkstyle.load_stylesheet(qt_api=os.environ['PYQTGRAPH_QT_LIB']))
mainWindow.show() mainWindow.show()
......
import os, sys import os, sys
import openpyxl import openpyxl
import subprocess
import re
def validate_and_get_filepath(file_info): def validate_and_get_filepath(file_info):
if type(file_info[0]) == str: if type(file_info[0]) == str:
return file_info[0], True return file_info[0], True
...@@ -80,6 +83,29 @@ def get_sheetHead(book_path: str) -> list: ...@@ -80,6 +83,29 @@ def get_sheetHead(book_path: str) -> list:
sheet_head.append(sheet.cell(1, j).value) sheet_head.append(sheet.cell(1, j).value)
return sheet_head 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__': if __name__ == '__main__':
x = transfer_second_to_time("12000.923") 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