Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
accessibility_movie_2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
赵心治
accessibility_movie_2
Commits
69305eb1
Commit
69305eb1
authored
Jul 31, 2022
by
xuanweiace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
upd 新增对字幕和旁白表格的支持 并支持毫秒级视频运行时间的展示
parent
23b4ef50
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
468 additions
and
56 deletions
+468
-56
README.md
README.md
+4
-2
detect_with_asr.py
detect_with_asr.py
+3
-0
main_window.py
main_window.py
+71
-10
main_window.ui
main_window.ui
+20
-10
main_window_ui.py
main_window_ui.py
+33
-20
management.py
management.py
+155
-2
myTableWidget.py
myTableWidget.py
+69
-0
other_test.py
other_test.py
+13
-2
speech_synthesis.py
speech_synthesis.py
+11
-7
testTableWidget.py
testTableWidget.py
+74
-0
utils.py
utils.py
+15
-3
No files found.
README.md
View file @
69305eb1
# accessibility_movie_2
二期的无障碍电影制作工具,主要包含旁白区间检测和旁白及字幕导出两个功能; 二期主要提升用户体验、产品功能与易用性,设计成熟的操作界面进行人机交互,另外为了方便用户使用,使用pyinstaller进行打包。
\ No newline at end of file
二期的无障碍电影制作工具,主要包含旁白区间检测和旁白及字幕导出两个功能; 二期主要提升用户体验、产品功能与易用性,设计成熟的操作界面进行人机交互,另外为了方便用户使用,使用pyinstaller进行打包。
注意要自行下载mp4的解码器,不然无法播放视频
\ No newline at end of file
detect_with_asr.py
View file @
69305eb1
...
...
@@ -34,6 +34,7 @@ def create_sheet(path: str, sheet_name: str, value: list):
"""
index
=
len
(
value
)
workbook
=
openpyxl
.
Workbook
()
sheet
=
workbook
.
active
sheet
.
title
=
sheet_name
# 将字幕对应的那一列扩宽一些
...
...
@@ -109,6 +110,8 @@ 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()
# # 给定待处理的视频路径
...
...
main_window.py
View file @
69305eb1
...
...
@@ -2,10 +2,11 @@ import time
import
os
import
cv2
from
PyQt5.QtWidgets
import
QMainWindow
,
QFileDialog
from
PyQt5.QtWidgets
import
QMainWindow
,
QFileDialog
,
QTableWidget
,
QTableWidgetItem
import
utils
from
management
import
RunThread
from
utils
import
validate_and_get_filepath
from
management
import
RunThread
,
ProjectContext
,
Element
from
detect_dialog
import
Detect_Dialog
from
assemble_dialog
import
Assemble_Dialog
from
synthesis
import
SynthesisProcessor
...
...
@@ -20,6 +21,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
super
(
MainWindow
,
self
)
.
__init__
()
self
.
setupUi
(
self
)
self
.
statusbar
.
showMessage
(
"hello"
,
5000
)
self
.
projectContext
=
ProjectContext
()
# 语音合成相关组件
# todo:后续改成QThread的组件
...
...
@@ -30,21 +32,24 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self
.
detect_dialog
.
start_detect_signal
.
connect
(
self
.
start_detect
)
#合成对话框
self
.
assemble_dialog
=
Assemble_Dialog
()
self
.
assemble_dialog
.
start_assemble_signal
.
connect
(
self
.
synthesis
.
synthesis_slot
)
# 菜单栏的动作
self
.
actiona_3
.
triggered
.
connect
(
self
.
show_detect_dialog
)
self
.
actiona_4
.
triggered
.
connect
(
self
.
show_assemble_dialog
)
self
.
action_save
.
triggered
.
connect
(
self
.
save_project
)
self
.
import_movie
.
triggered
.
connect
(
self
.
import_slot
)
#视频时长,全局变量
self
.
video_duration
=
None
self
.
sld_video_pressed
=
False
#判断当前进度条识别否被鼠标点击
self
.
videoFullScreen
=
False
# 判断当前widget是否全屏
self
.
videoFullScreenWidget
=
myVideoWidget
()
# 创建一个全屏的widget
self
.
player
=
QMediaPlayer
()
self
.
player
.
setVideoOutput
(
self
.
wgt_video
)
# 视频播放输出的widget,就是上面定义的
self
.
btn_open
.
clicked
.
connect
(
self
.
open
VideoFile
)
# 打开视频文件按钮
self
.
btn_open
.
clicked
.
connect
(
self
.
open
_excel
)
# 打开视频文件按钮
self
.
btn_play
.
clicked
.
connect
(
self
.
playVideo
)
# play
self
.
btn_stop
.
clicked
.
connect
(
self
.
pauseVideo
)
# pause
self
.
player
.
positionChanged
.
connect
(
self
.
changeSlide
)
# change Slide
...
...
@@ -75,6 +80,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
replp
=
QtWidgets
.
QMessageBox
.
question
(
self
,
u'警告'
,
msg
,
QtWidgets
.
QMessageBox
.
Yes
)
def
import_slot
(
self
):
video_path
=
self
.
openVideoFile
()
self
.
init_ProjectContext_VideoPath
(
video_path
)
def
start_detect
(
self
,
video_path
,
book_path
):
...
...
@@ -108,7 +116,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# self.show_warning_msg_box("请确认结束时间是否正确")
# return
print
(
"daozhele"
)
# 获取视频的时长等信息,初始化开始结束时间
startTime
=
"00:00:00"
...
...
@@ -128,7 +135,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self
.
show_warning_msg_box
(
"开始时间不得大于等于结束时间,请重新填写"
)
return
print
(
"daozhele11111"
)
video_fps
=
cv2
.
VideoCapture
(
video_path
)
.
get
(
cv2
.
CAP_PROP_FPS
)
if
(
end_time
-
start_time
)
*
video_fps
<
150
:
self
.
show_warning_msg_box
(
"您想要检测的片段太短,请重新输入开始时间和结束时间!"
)
...
...
@@ -217,20 +223,25 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self
.
player
.
setVolume
(
volume
)
self
.
lab_audio
.
setText
(
"volume:"
+
str
(
volume
)
+
"
%
"
)
# postion 取值[0,100]
def
clickedSlider
(
self
,
position
):
if
self
.
player
.
duration
()
>
0
:
# 开始播放后才允许进行跳转
video_position
=
int
((
position
/
100
)
*
self
.
player
.
duration
())
self
.
player
.
setPosition
(
video_position
)
self
.
lab_video
.
setText
(
"
%.2
f
%%
"
%
position
)
# print("pos:", position, "总时长:", self.player.duration())
# self.lab_video.setText("%.2f%%" % position)
self
.
lab_video
.
setText
(
utils
.
transfer_second_to_time
(
str
(
video_position
)))
else
:
self
.
sld_video
.
setValue
(
0
)
# position 取值[0,100]
def
moveSlider
(
self
,
position
):
self
.
sld_video_pressed
=
True
if
self
.
player
.
duration
()
>
0
:
# 开始播放后才允许进行跳转
video_position
=
int
((
position
/
100
)
*
self
.
player
.
duration
())
self
.
player
.
setPosition
(
video_position
)
self
.
lab_video
.
setText
(
"
%.2
f
%%
"
%
position
)
# self.lab_video.setText("%.2f%%" % position)
self
.
lab_video
.
setText
(
utils
.
transfer_second_to_time
(
str
(
video_position
)))
def
pressSlider
(
self
):
self
.
sld_video_pressed
=
True
...
...
@@ -239,16 +250,28 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def
releaseSlider
(
self
):
self
.
sld_video_pressed
=
False
# position 取值[0,总时长]
def
changeSlide
(
self
,
position
):
if
not
self
.
sld_video_pressed
:
# 进度条被鼠标点击时不更新
self
.
vidoeLength
=
self
.
player
.
duration
()
+
0.1
self
.
sld_video
.
setValue
(
round
((
position
/
self
.
vidoeLength
)
*
100
))
self
.
lab_video
.
setText
(
"
%.2
f
%%
"
%
((
position
/
self
.
vidoeLength
)
*
100
))
self
.
lab_video
.
setText
(
utils
.
transfer_second_to_time
(
str
(
position
/
1000
)))
# self.lab_video.setText("%.2f%%" % ((position/self.vidoeLength)*100))
def
openVideoFile
(
self
):
self
.
player
.
setMedia
(
QMediaContent
(
QFileDialog
.
getOpenFileUrl
()[
0
]))
# 选取视频文件
path
=
QFileDialog
.
getOpenFileUrl
()[
0
]
self
.
player
.
setMedia
(
QMediaContent
(
path
))
# 选取视频文件
self
.
player
.
play
()
# 播放视频
print
(
self
.
player
.
availableMetaData
())
return
path
# 在初始化工程时
def
init_ProjectContext_VideoPath
(
self
,
path
):
# video_dir = os.path.dirname(path)
# video_name = os.path.basename(path)
# self.projectContext.Init(video_dir, video_name)
self
.
projectContext
.
setVideoPath
(
path
)
def
playVideo
(
self
):
self
.
player
.
play
()
...
...
@@ -268,3 +291,41 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self
.
player
.
setVideoOutput
(
self
.
videoFullScreenWidget
)
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
.
set_table_to_window
()
def
set_table_to_window
(
self
):
header
=
self
.
projectContext
.
header
subtitle_list
=
self
.
projectContext
.
subtitle_list
aside_list
=
self
.
projectContext
.
aside_list
self
.
zm_tableWidget
.
setRowCount
(
len
(
subtitle_list
))
self
.
zm_tableWidget
.
setColumnCount
(
len
(
header
))
self
.
zm_tableWidget
.
setHorizontalHeaderLabels
(
header
)
for
i
in
range
(
len
(
subtitle_list
)):
self
.
setElememtToTable
(
self
.
zm_tableWidget
,
subtitle_list
[
i
],
i
)
self
.
pb_tableWidget
.
setRowCount
(
len
(
aside_list
))
self
.
pb_tableWidget
.
setColumnCount
(
len
(
header
))
self
.
pb_tableWidget
.
setHorizontalHeaderLabels
(
header
)
for
i
in
range
(
len
(
aside_list
)):
self
.
setElememtToTable
(
self
.
pb_tableWidget
,
aside_list
[
i
],
i
)
def
setElememtToTable
(
self
,
table
:
QTableWidget
,
elem
:
Element
,
idx
:
int
):
elem_list
=
elem
.
to_list
()
for
j
in
range
(
len
(
elem_list
)):
table
.
setItem
(
idx
,
j
,
QTableWidgetItem
(
elem_list
[
j
]))
def
save_project
(
self
):
self
.
projectContext
.
save_project
()
main_window.ui
View file @
69305eb1
...
...
@@ -7,7 +7,7 @@
<x>
0
</x>
<y>
0
</y>
<width>
939
</width>
<height>
7
55
</height>
<height>
7
63
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
...
...
@@ -30,7 +30,7 @@
<layout
class=
"QHBoxLayout"
name=
"shuiping"
stretch=
"3,1"
>
<item>
<widget
class=
"QWidget"
name=
"verticalWidget_3"
native=
"true"
>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout_3"
stretch=
"8,
1
"
>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout_3"
stretch=
"8,
0
"
>
<item>
<widget
class=
"myVideoWidget"
name=
"wgt_video"
native=
"true"
>
<property
name=
"minimumSize"
>
...
...
@@ -127,7 +127,7 @@
</size>
</property>
<property
name=
"text"
>
<string>
打开
视频
文件
</string>
<string>
打开
表格
文件
</string>
</property>
</widget>
<widget
class=
"QPushButton"
name=
"btn_play"
>
...
...
@@ -276,7 +276,7 @@ QPushButton:pressed {
<enum>
QTabWidget::Triangular
</enum>
</property>
<property
name=
"currentIndex"
>
<number>
1
</number>
<number>
0
</number>
</property>
<property
name=
"iconSize"
>
<size>
...
...
@@ -293,15 +293,25 @@ QPushButton:pressed {
<property
name=
"tabBarAutoHide"
>
<bool>
false
</bool>
</property>
<widget
class=
"QWidget"
name=
"tab"
>
<widget
class=
"QWidget"
name=
"
zm_
tab"
>
<attribute
name=
"title"
>
<string>
字幕
</string>
</attribute>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_2"
>
<item>
<widget
class=
"QTableWidget"
name=
"zm_tableWidget"
/>
</item>
</layout>
</widget>
<widget
class=
"QWidget"
name=
"
tab_2
"
>
<widget
class=
"QWidget"
name=
"
pb_tab
"
>
<attribute
name=
"title"
>
<string>
旁白
</string>
</attribute>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_3"
>
<item>
<widget
class=
"QTableWidget"
name=
"pb_tableWidget"
/>
</item>
</layout>
</widget>
</widget>
</item>
...
...
@@ -455,10 +465,10 @@ QPushButton:pressed {
<addaction
name=
"actionxinjian"
/>
<addaction
name=
"actiona"
/>
<addaction
name=
"separator"
/>
<addaction
name=
"
actiona_2
"
/>
<addaction
name=
"
import_movie
"
/>
<addaction
name=
"actions"
/>
<addaction
name=
"separator"
/>
<addaction
name=
"action
s_2
"
/>
<addaction
name=
"action
_save
"
/>
</widget>
<widget
class=
"QMenu"
name=
"menu_2"
>
<property
name=
"title"
>
...
...
@@ -489,7 +499,7 @@ QPushButton:pressed {
<string>
打开
</string>
</property>
</action>
<action
name=
"
actiona_2
"
>
<action
name=
"
import_movie
"
>
<property
name=
"text"
>
<string>
视频导入
</string>
</property>
...
...
@@ -499,7 +509,7 @@ QPushButton:pressed {
<string>
内容导出
</string>
</property>
</action>
<action
name=
"action
s_2
"
>
<action
name=
"action
_save
"
>
<property
name=
"text"
>
<string>
工程保存
</string>
</property>
...
...
main_window_ui.py
View file @
69305eb1
...
...
@@ -12,7 +12,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class
Ui_MainWindow
(
object
):
def
setupUi
(
self
,
MainWindow
):
MainWindow
.
setObjectName
(
"MainWindow"
)
MainWindow
.
resize
(
939
,
7
55
)
MainWindow
.
resize
(
939
,
7
63
)
MainWindow
.
setStyleSheet
(
"QMainWindow:{
\n
"
" border: 2px groove gray;
\n
"
" border-radius: 25px;
\n
"
...
...
@@ -141,7 +141,6 @@ class Ui_MainWindow(object):
self
.
label_2
.
setObjectName
(
"label_2"
)
self
.
verticalLayout_3
.
addWidget
(
self
.
splitter
)
self
.
verticalLayout_3
.
setStretch
(
0
,
8
)
self
.
verticalLayout_3
.
setStretch
(
1
,
1
)
self
.
shuiping
.
addWidget
(
self
.
verticalWidget_3
)
self
.
tabWidget
=
QtWidgets
.
QTabWidget
(
self
.
centralwidget
)
self
.
tabWidget
.
setContextMenuPolicy
(
QtCore
.
Qt
.
DefaultContextMenu
)
...
...
@@ -153,12 +152,26 @@ class Ui_MainWindow(object):
self
.
tabWidget
.
setMovable
(
False
)
self
.
tabWidget
.
setTabBarAutoHide
(
False
)
self
.
tabWidget
.
setObjectName
(
"tabWidget"
)
self
.
tab
=
QtWidgets
.
QWidget
()
self
.
tab
.
setObjectName
(
"tab"
)
self
.
tabWidget
.
addTab
(
self
.
tab
,
""
)
self
.
tab_2
=
QtWidgets
.
QWidget
()
self
.
tab_2
.
setObjectName
(
"tab_2"
)
self
.
tabWidget
.
addTab
(
self
.
tab_2
,
""
)
self
.
zm_tab
=
QtWidgets
.
QWidget
()
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
,
3
)
self
.
shuiping
.
setStretch
(
1
,
1
)
...
...
@@ -248,12 +261,12 @@ class Ui_MainWindow(object):
self
.
actionxinjian
.
setObjectName
(
"actionxinjian"
)
self
.
actiona
=
QtWidgets
.
QAction
(
MainWindow
)
self
.
actiona
.
setObjectName
(
"actiona"
)
self
.
actiona_2
=
QtWidgets
.
QAction
(
MainWindow
)
self
.
actiona_2
.
setObjectName
(
"actiona_2
"
)
self
.
import_movie
=
QtWidgets
.
QAction
(
MainWindow
)
self
.
import_movie
.
setObjectName
(
"import_movie
"
)
self
.
actions
=
QtWidgets
.
QAction
(
MainWindow
)
self
.
actions
.
setObjectName
(
"actions"
)
self
.
action
s_2
=
QtWidgets
.
QAction
(
MainWindow
)
self
.
action
s_2
.
setObjectName
(
"actions_2
"
)
self
.
action
_save
=
QtWidgets
.
QAction
(
MainWindow
)
self
.
action
_save
.
setObjectName
(
"action_save
"
)
self
.
actionchexiao
=
QtWidgets
.
QAction
(
MainWindow
)
self
.
actionchexiao
.
setObjectName
(
"actionchexiao"
)
self
.
actionchongzuo
=
QtWidgets
.
QAction
(
MainWindow
)
...
...
@@ -265,10 +278,10 @@ class Ui_MainWindow(object):
self
.
menu
.
addAction
(
self
.
actionxinjian
)
self
.
menu
.
addAction
(
self
.
actiona
)
self
.
menu
.
addSeparator
()
self
.
menu
.
addAction
(
self
.
actiona_2
)
self
.
menu
.
addAction
(
self
.
import_movie
)
self
.
menu
.
addAction
(
self
.
actions
)
self
.
menu
.
addSeparator
()
self
.
menu
.
addAction
(
self
.
action
s_2
)
self
.
menu
.
addAction
(
self
.
action
_save
)
self
.
menu_2
.
addAction
(
self
.
actionchexiao
)
self
.
menu_2
.
addAction
(
self
.
actionchongzuo
)
self
.
menu_3
.
addAction
(
self
.
actiona_3
)
...
...
@@ -278,19 +291,19 @@ class Ui_MainWindow(object):
self
.
menubar
.
addAction
(
self
.
menu_3
.
menuAction
())
self
.
retranslateUi
(
MainWindow
)
self
.
tabWidget
.
setCurrentIndex
(
1
)
self
.
tabWidget
.
setCurrentIndex
(
0
)
QtCore
.
QMetaObject
.
connectSlotsByName
(
MainWindow
)
def
retranslateUi
(
self
,
MainWindow
):
_translate
=
QtCore
.
QCoreApplication
.
translate
MainWindow
.
setWindowTitle
(
_translate
(
"MainWindow"
,
"MainWindow"
))
self
.
btn_open
.
setText
(
_translate
(
"MainWindow"
,
"打开
视频
文件"
))
self
.
btn_open
.
setText
(
_translate
(
"MainWindow"
,
"打开
表格
文件"
))
self
.
btn_play
.
setText
(
_translate
(
"MainWindow"
,
"播放"
))
self
.
btn_stop
.
setText
(
_translate
(
"MainWindow"
,
"暂停"
))
self
.
lab_audio
.
setText
(
_translate
(
"MainWindow"
,
"volume:100
%
"
))
self
.
label_2
.
setText
(
_translate
(
"MainWindow"
,
"00:00/12:34"
))
self
.
tabWidget
.
setTabText
(
self
.
tabWidget
.
indexOf
(
self
.
tab
),
_translate
(
"MainWindow"
,
"字幕"
))
self
.
tabWidget
.
setTabText
(
self
.
tabWidget
.
indexOf
(
self
.
tab_2
),
_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"
,
"0
%
"
))
self
.
pb_label
.
setText
(
_translate
(
"MainWindow"
,
"旁白时间轴"
))
...
...
@@ -299,9 +312,9 @@ class Ui_MainWindow(object):
self
.
menu_3
.
setTitle
(
_translate
(
"MainWindow"
,
"功能按键"
))
self
.
actionxinjian
.
setText
(
_translate
(
"MainWindow"
,
"新建"
))
self
.
actiona
.
setText
(
_translate
(
"MainWindow"
,
"打开"
))
self
.
actiona_2
.
setText
(
_translate
(
"MainWindow"
,
"视频导入"
))
self
.
import_movie
.
setText
(
_translate
(
"MainWindow"
,
"视频导入"
))
self
.
actions
.
setText
(
_translate
(
"MainWindow"
,
"内容导出"
))
self
.
action
s_2
.
setText
(
_translate
(
"MainWindow"
,
"工程保存"
))
self
.
action
_save
.
setText
(
_translate
(
"MainWindow"
,
"工程保存"
))
self
.
actionchexiao
.
setText
(
_translate
(
"MainWindow"
,
"撤销"
))
self
.
actionchongzuo
.
setText
(
_translate
(
"MainWindow"
,
"重做"
))
self
.
actiona_3
.
setText
(
_translate
(
"MainWindow"
,
"旁白区间检测"
))
...
...
management.py
View file @
69305eb1
import
os.path
import
threading
import
traceback
import
sys
from
enum
import
Enum
import
openpyxl
from
openpyxl.styles
import
PatternFill
,
Alignment
from
utils
import
replace_path_suffix
class
RunThread
(
threading
.
Thread
):
"""复写线程类,用于解决主线程无法捕捉子线程中异常的问题
"""
...
...
@@ -42,4 +51,148 @@ class RunThread(threading.Thread):
try
:
self
.
_funcName
(
*
self
.
_args
)
except
Exception
as
e
:
raise
e
\ No newline at end of file
raise
e
# 计划支持两种操作符,修改和删除(目前还是仅支持修改)
# todo:删除是指对字幕Element的删除(比如重复的进行合并)
class
Operation
(
Enum
):
Modify
=
0
# Delete = 1
# 维护一条历史记录
# 目前仅支持对旁白做修改
class
OperateRecord
:
def
__init__
(
self
,
operation
:
Operation
,
old
:
str
,
new
:
str
):
self
.
operation
=
operation
self
.
old_str
=
old
self
.
new_str
=
new
# 每一行的具体信息,"起始时间", "终止时间", "字幕", '建议', '解说脚本'
class
Element
:
def
__init__
(
self
,
st_time_sec
:
float
,
ed_time_sec
:
float
,
subtitle
,
suggest
,
aside
):
self
.
st_time_sec
=
st_time_sec
self
.
ed_time_sec
=
ed_time_sec
self
.
subtitle
=
subtitle
self
.
suggest
=
suggest
self
.
aside
=
aside
self
.
history_records
=
[]
# 判断当前元素是否是字幕
def
is_subtitle
(
self
):
return
self
.
subtitle
!=
None
and
self
.
subtitle
!=
""
# 判断当前元素是否是旁白
def
is_aside
(
self
):
return
not
self
.
is_subtitle
()
def
to_list
(
self
):
return
[
self
.
st_time_sec
,
self
.
ed_time_sec
,
self
.
subtitle
,
self
.
suggest
,
self
.
aside
]
class
ProjectContext
:
def
__init__
(
self
):
self
.
project_base_dir
=
None
self
.
video_path
=
None
self
.
excel_path
=
None
self
.
subtitle_list
=
[]
self
.
aside_list
=
[]
# 一些常量
self
.
header
=
[
"起始时间"
,
"终止时间"
,
"字幕"
,
'建议'
,
'解说脚本'
]
self
.
excel_sheet_name
=
"旁白插入位置建议"
def
Init
(
self
,
project_dir
,
video_name
):
self
.
project_base_dir
=
project_dir
self
.
video_path
=
os
.
path
.
join
(
project_dir
,
video_name
)
self
.
excel_path
=
replace_path_suffix
(
self
.
video_path
,
".xlsx"
)
def
Init
(
self
,
project_dir
,
video_path
,
excel_path
):
self
.
project_base_dir
=
project_dir
self
.
video_path
=
video_path
self
.
excel_path
=
excel_path
def
setVideoPath
(
self
,
video_path
):
self
.
video_path
=
video_path
def
setExcelPath
(
self
,
excel_path
):
self
.
excel_path
=
excel_path
# 目前只是把excel保存到文件中
def
save_project
(
self
):
all_element
=
self
.
subtitle_list
+
self
.
aside_list
all_element
.
sort
(
lambda
x
,
y
:
(
x
.
st_time_sec
<
y
.
st_time_sec
))
for
element
in
all_element
:
write_to_sheet
(
self
.
excel_path
,
self
.
excel_sheet_name
,
element
.
to_list
)
# 加载整个工程,填充到ProjectContext上下文中
def
load_project
(
self
):
pass
def
load_excel_from_path
(
self
):
d
=
read_sheet
(
self
.
excel_path
)
# todo:现在是只用None判断是否是字幕,后续是否也需要用""来?
for
i
in
range
(
len
(
d
[
"字幕"
])):
st_time_sec
,
ed_time_sec
,
subtitle
,
suggest
,
aside
=
[
d
[
x
][
i
]
for
x
in
self
.
header
]
if
d
[
"字幕"
][
i
]
!=
None
:
self
.
subtitle_list
.
append
(
Element
(
st_time_sec
,
ed_time_sec
,
subtitle
,
suggest
,
aside
))
else
:
self
.
aside_list
.
append
(
Element
(
st_time_sec
,
ed_time_sec
,
subtitle
,
suggest
,
aside
))
def
write_to_sheet
(
path
:
str
,
sheet_name
:
str
,
value
:
list
):
"""向已存在的表格中写入一行数据
Args:
path (str): 表格(book)的存储位置
sheet_name (str): excel表内的表(sheet)的名字
value (list): 要插入表内的一行数据
"""
index
=
len
(
value
)
workbook
=
openpyxl
.
load_workbook
(
path
)
sheet
=
workbook
.
get_sheet_by_name
(
sheet_name
)
cur_row
=
sheet
.
max_row
for
j
in
range
(
0
,
index
):
sheet
.
cell
(
row
=
cur_row
+
1
,
column
=
j
+
1
,
value
=
str
(
value
[
j
]))
if
value
[
j
]
==
''
or
'插入旁白'
in
str
(
value
[
j
]):
sheet
.
cell
(
row
=
cur_row
+
1
,
column
=
j
+
1
)
.
fill
=
PatternFill
(
fill_type
=
'solid'
,
fgColor
=
'ffff00'
)
if
j
==
2
:
sheet
.
cell
(
row
=
cur_row
+
1
,
column
=
j
+
1
)
.
alignment
=
Alignment
(
wrapText
=
True
)
workbook
.
save
(
path
)
def
read_sheet
(
book_path
:
str
,
sheet_name
:
str
=
""
)
->
dict
:
"""读表
从表格中读出所有的内容,用dict保存(表格的格式固定,第一行为表头(起始时间|终止时间|字幕|建议|解说脚本))
Args:
book_path (str): 表格的存储路径
sheet_name (str, optional): 想要读取的表在excel表格中的名字. Defaults to "".
Returns:
dict: 表格中的所有内容,key为该列表头,value为列中的数据
"""
workbook
=
openpyxl
.
load_workbook
(
book_path
)
sheet
=
workbook
.
active
rows
=
sheet
.
max_row
cols
=
sheet
.
max_column
sheet_content
=
{}
# 读取xlsx中每列的内容,默认第一行是各列的列名
for
i
in
range
(
1
,
rows
+
1
):
for
j
in
range
(
1
,
cols
+
1
):
if
i
==
1
:
sheet_content
[
sheet
.
cell
(
1
,
j
)
.
value
]
=
[]
else
:
sheet_content
[
sheet
.
cell
(
1
,
j
)
.
value
]
.
append
(
sheet
.
cell
(
i
,
j
)
.
value
)
return
sheet_content
if
__name__
==
'__main__'
:
# d = read_sheet("test37second.xlsx")
# print(d["字幕"])
# print(d.keys())
ctx
=
ProjectContext
()
ctx
.
setExcelPath
(
"d:/123"
)
print
(
ctx
.
excel_path
)
\ No newline at end of file
myTableWidget.py
0 → 100644
View file @
69305eb1
import
sys
from
PyQt5.QtWidgets
import
(
QWidget
,
QTableWidget
,
QHBoxLayout
,
QApplication
,
QTableWidgetItem
,
QAbstractItemView
)
class
myTableWidget
(
QWidget
):
def
__init__
(
self
):
super
(
myTableWidget
,
self
)
.
__init__
()
self
.
initUI
()
def
initUI
(
self
):
self
.
setWindowTitle
(
"QTableWidget演示"
)
self
.
resize
(
430
,
230
);
layout
=
QHBoxLayout
()
tablewidget
=
QTableWidget
()
tablewidget
.
setRowCount
(
4
)
tablewidget
.
setColumnCount
(
6
)
layout
.
addWidget
(
tablewidget
)
tablewidget
.
setHorizontalHeaderLabels
([
'时间'
,
'文字'
])
nameItem
=
QTableWidgetItem
(
"0:00"
)
tablewidget
.
setItem
(
0
,
0
,
nameItem
)
ageItem
=
QTableWidgetItem
(
"24"
)
tablewidget
.
setItem
(
0
,
1
,
ageItem
)
jgItem
=
QTableWidgetItem
(
"北京"
)
tablewidget
.
setItem
(
0
,
2
,
jgItem
)
# 禁止编辑
# tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
# 整行选择
tablewidget
.
setSelectionBehavior
(
QAbstractItemView
.
SelectRows
)
# 调整列和行
tablewidget
.
resizeColumnsToContents
()
tablewidget
.
resizeRowsToContents
()
# tablewidget.horizontalHeader().setVisible(False)
# tablewidget.verticalHeader().setVisible(False)
tablewidget
.
setVerticalHeaderLabels
([
"a"
,
"b"
])
# 隐藏表格线
tablewidget
.
setShowGrid
(
False
)
self
.
setLayout
(
layout
)
tablewidget
.
itemClicked
.
connect
(
self
.
show_data
)
def
show_data
(
self
,
Item
):
# 如果单元格对象为空
if
Item
is
None
:
return
else
:
row
=
Item
.
row
()
# 获取行数
col
=
Item
.
column
()
# 获取列数 注意是column而不是col哦
text
=
Item
.
text
()
# 获取内容
# 输出测试
print
(
'row = '
,
row
)
print
(
'col ='
,
col
)
print
(
'text = '
,
text
)
if
__name__
==
'__main__'
:
app
=
QApplication
(
sys
.
argv
)
example
=
myTableWidget
()
example
.
show
()
sys
.
exit
(
app
.
exec_
())
other_test.py
View file @
69305eb1
...
...
@@ -7,4 +7,15 @@ def f(a,b,c,d):
data
=
[
'ACME'
,
50
,
91.1
,
(
2012
,
12
,
21
)
]
name
,
shares
,
price
,
date
=
data
print
(
name
)
\ No newline at end of file
print
(
name
)
from
enum
import
Enum
class
Operation
(
Enum
):
Modify
=
0
Delete
=
1
# print(Operation.Delete)
print
(
Operation
((
'修改'
,
"xiugai"
)))
\ No newline at end of file
speech_synthesis.py
View file @
69305eb1
...
...
@@ -403,10 +403,13 @@ def ss_and_export(video_path: str, sheet_path: str, output_dir: str, speed: floa
if
__name__
==
'__main__'
:
video_path
=
r'D:/Downloads/zhanlang.rmvb'
sheet_path
=
r'D:/Downloads/战狼.xlsx'
output_dir
=
r'D:/AddCaption/last_version/accessibility_movie/zhanlang'
speed
=
1.25
caption_file
=
'./zhanlang/zhanlang.srt'
speaker_name
=
'晓秋'
ss_and_export
(
video_path
,
sheet_path
,
output_dir
,
speed
,
caption_file
,
speaker_name
)
# video_path = r'D:/Downloads/zhanlang.rmvb'
# sheet_path = r'D:/Downloads/战狼.xlsx'
# output_dir = r'D:/AddCaption/last_version/accessibility_movie/zhanlang'
# speed = 1.25
# caption_file = './zhanlang/zhanlang.srt'
# speaker_name = '晓秋'
# ss_and_export(video_path, sheet_path, output_dir, speed, caption_file, speaker_name)
import
pprint
d
=
read_sheet
(
"./test37second.xlsx"
)
pprint
.
pprint
(
d
)
\ No newline at end of file
testTableWidget.py
0 → 100644
View file @
69305eb1
import
sys
from
PyQt5.QtWidgets
import
(
QWidget
,
QTableWidget
,
QHBoxLayout
,
QApplication
,
QTableWidgetItem
,
QAbstractItemView
)
from
PyQt5.QtCore
import
Qt
class
TableWidget
(
QWidget
):
def
__init__
(
self
):
super
(
TableWidget
,
self
)
.
__init__
()
self
.
initUI
()
def
initUI
(
self
):
self
.
setWindowTitle
(
"QTableWidget演示"
)
self
.
resize
(
430
,
230
);
layout
=
QHBoxLayout
()
tablewidget
=
QTableWidget
()
tablewidget
.
setRowCount
(
4
)
tablewidget
.
setColumnCount
(
6
)
layout
.
addWidget
(
tablewidget
)
tablewidget
.
setHorizontalHeaderLabels
([
'时间'
,
'文字'
])
nameItem
=
QTableWidgetItem
(
"0:00"
)
# nameItem.setFlags()
tablewidget
.
setItem
(
0
,
0
,
nameItem
)
ageItem
=
QTableWidgetItem
(
"24"
)
tablewidget
.
setItem
(
0
,
1
,
ageItem
)
jgItem
=
QTableWidgetItem
(
"北京"
)
# jgItem.setFlags(Qt.ItemIsEnabled)
jgItem
.
setFlags
(
Qt
.
ItemFlags
(
32
))
# jgItem.checkState()
tablewidget
.
setItem
(
0
,
2
,
jgItem
)
# 禁止编辑
# tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
# 整行选择
tablewidget
.
setSelectionBehavior
(
QAbstractItemView
.
SelectRows
)
# 调整列和行
tablewidget
.
resizeColumnsToContents
()
tablewidget
.
resizeRowsToContents
()
# tablewidget.horizontalHeader().setVisible(False)
# tablewidget.verticalHeader().setVisible(False)
tablewidget
.
setVerticalHeaderLabels
([
"a"
,
"b"
])
# 隐藏表格线
tablewidget
.
setShowGrid
(
False
)
self
.
setLayout
(
layout
)
tablewidget
.
itemClicked
.
connect
(
self
.
show_data
)
def
show_data
(
self
,
Item
):
# 如果单元格对象为空
if
Item
is
None
:
return
else
:
print
(
Item
.
checkState
())
row
=
Item
.
row
()
# 获取行数
col
=
Item
.
column
()
# 获取列数 注意是column而不是col哦
text
=
Item
.
text
()
# 获取内容
# 输出测试
print
(
'row = '
,
row
)
print
(
'col ='
,
col
)
print
(
'text = '
,
text
)
if
__name__
==
'__main__'
:
app
=
QApplication
(
sys
.
argv
)
example
=
TableWidget
()
example
.
show
()
sys
.
exit
(
app
.
exec_
())
utils.py
View file @
69305eb1
...
...
@@ -25,7 +25,15 @@ def trans_to_seconds(timePoint: str) -> float:
units
*=
60
return
time_in_seconds
def
transfer_second_to_time
(
sec
:
str
)
->
str
:
duration
=
int
(
float
(
sec
))
minutes
=
int
(
duration
/
60
)
seconds
=
int
(
duration
-
60
*
minutes
)
idx
=
sec
.
find
(
'.'
)
if
(
idx
==
-
1
):
idx
=
len
(
sec
)
time
=
"
%02
d:
%02
d
%
s"
%
(
minutes
,
seconds
,
sec
[
idx
:])
return
time
def
replace_path_suffix
(
path
,
new_suffix
):
return
path
.
replace
(
os
.
path
.
splitext
(
path
)[
-
1
],
new_suffix
)
...
...
@@ -66,4 +74,9 @@ def get_sheetHead(book_path: str) -> list:
if
rows
>
1
:
for
j
in
range
(
1
,
cols
+
1
):
sheet_head
.
append
(
sheet
.
cell
(
1
,
j
)
.
value
)
return
sheet_head
\ No newline at end of file
return
sheet_head
if
__name__
==
'__main__'
:
x
=
transfer_second_to_time
(
"12000.923"
)
print
(
x
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment