feat(subtitles): add support for loading and displaying subtitles in the application feat(video): implement video capture and frame navigation functionality feat(ui): create main window UI for subtitle and video management test: add unit tests for utility functions related to subtitle processing chore: set up project structure with necessary files and directories for functionality feat(ui_hardsubripper.py): add UI implementation for HardSubRipper application to provide a graphical interface for subtitle extraction and translation functionalities
135 lines
5.0 KiB
Python
135 lines
5.0 KiB
Python
from windows.ui_hardsubripper import Ui_HardSubRipper
|
|
from utils.utils import milliseconds_to_framenumber
|
|
from PyQt6 import QtWidgets, QtGui, QtCore
|
|
import cv2
|
|
from utils.Subtitles import Subtitles
|
|
|
|
class MainWindow(QtWidgets.QMainWindow, Ui_HardSubRipper):
|
|
|
|
def __init__(self,parent=None):
|
|
super(MainWindow,self).__init__(parent)
|
|
#
|
|
self.video= None
|
|
self.subtitles = None
|
|
self.cap = None
|
|
self.current_subtitle = 0
|
|
self.current_frame = 0
|
|
self.current_frame_img = None
|
|
|
|
self.new_subtitles = None
|
|
|
|
#
|
|
self.video_height = 720
|
|
self.video_width = 1280
|
|
self.setupUi(self)
|
|
self.setupPixmap()
|
|
|
|
self.opensub.clicked.connect(self.load_subtitles)
|
|
self.openvid.clicked.connect(self.open_video)
|
|
self.next.clicked.connect(self.go_to_next_line)
|
|
self.previous.clicked.connect(self.go_to_previous_line)
|
|
|
|
self.translate.clicked.connect(self.extract_useful_frames)
|
|
|
|
|
|
def translate_all(self):
|
|
|
|
|
|
def setupPixmap(self):
|
|
placeholder = QtGui.QPixmap(self.video_width,self.video_height)
|
|
placeholder.fill(QtGui.QColor(255,0,0))
|
|
self.frame_pixmap.setPixmap(placeholder)
|
|
|
|
def goToFrame(self,int):
|
|
self.cap.set(cv2.CAP_PROP_POS_FRAMES,int)
|
|
ret, cv_img = self.cap.read()
|
|
self.current_frame_img = cv_img
|
|
self.current_frame = int
|
|
self.crop_frame()
|
|
|
|
def crop_frame(self):
|
|
x = self.xmin.value()
|
|
y = self.ymin.value()
|
|
w = self.xmax.value() - x
|
|
h = self.ymax.value() - y
|
|
cropped = self.current_frame_img[y:y+h, x:x+w]
|
|
self.frame_pixmap.setScaledContents(True)
|
|
self.frame_pixmap.setPixmap(self.convert_cv_qt(cropped))
|
|
|
|
def extract_useful_frames(self):
|
|
pass
|
|
|
|
def open_video(self):
|
|
self.new_subtitles = {}
|
|
path = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', '.', "Video files (*.mp4 *.avi), All files (*.*)")
|
|
if path[0] == '':
|
|
return
|
|
path = path[0]
|
|
self.video = path
|
|
self.cap = cv2.VideoCapture(path)
|
|
self.video_height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
|
self.video_width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
self.current_frame = int(self.cap.get(cv2.CAP_PROP_POS_FRAMES))
|
|
|
|
self.xmin.setMaximum(self.video_width)
|
|
self.xmax.setMaximum(self.video_width)
|
|
self.ymin.setMaximum(self.video_height)
|
|
self.ymax.setMaximum(self.video_height)
|
|
|
|
self.xmax.setValue(self.video_width)
|
|
self.ymax.setValue(self.video_height)
|
|
|
|
ret, cv_img = self.cap.read()
|
|
self.frame_pixmap.setPixmap(self.convert_cv_qt(cv_img))
|
|
|
|
self.xmin.valueChanged.connect(self.crop_frame)
|
|
self.ymin.valueChanged.connect(self.crop_frame)
|
|
self.xmax.valueChanged.connect(self.crop_frame)
|
|
self.ymax.valueChanged.connect(self.crop_frame)
|
|
|
|
def go_to_previous_line(self):
|
|
if self.subtitles is None: return
|
|
if self.current_subtitle > 1:
|
|
self.current_subtitle -= 1
|
|
self.translated.document().setPlainText(self.subtitles.getLine(self.current_subtitle))
|
|
|
|
if self.video is not None:
|
|
frame = milliseconds_to_framenumber(self.subtitles.timestamps[self.current_subtitle].getStartInMilliseconds(), self.cap.get(cv2.CAP_PROP_FPS))
|
|
self.goToFrame(frame)
|
|
|
|
|
|
def go_to_next_line(self):
|
|
if self.subtitles is None: return
|
|
if self.current_subtitle < self.subtitles.number_of_lines:
|
|
self.current_subtitle += 1
|
|
self.translated.document().setPlainText(self.subtitles.getLine(self.current_subtitle))
|
|
|
|
if self.video is not None:
|
|
frame = milliseconds_to_framenumber(self.subtitles.timestamps[self.current_subtitle].getStartInMilliseconds(), self.cap.get(cv2.CAP_PROP_FPS))
|
|
self.goToFrame(frame)
|
|
|
|
def load_subtitles(self):
|
|
path = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', '.', "SubRip files (*.srt), All files (*.*)")
|
|
print(path)
|
|
if path[0] == '':
|
|
return
|
|
path = path[0]
|
|
#create a widget to ask for the language
|
|
lang = QtWidgets.QInputDialog.getText(self, 'Language', 'Enter the language of the subtitles')
|
|
if lang[1] == False:
|
|
return
|
|
self.subtitles = Subtitles()
|
|
self.subtitles.load(lang, path)
|
|
self.current_subtitle = 1
|
|
self.translated.document().setPlainText(self.subtitles.getLine(1))
|
|
|
|
|
|
def convert_cv_qt(self, cv_img):
|
|
"""Convert from an opencv image to QPixmap"""
|
|
rgb_image = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
|
h, w, ch = rgb_image.shape
|
|
bytes_per_line = ch * w
|
|
convert_to_qt_format = QtGui.QImage(rgb_image.data, w, h, bytes_per_line, QtGui.QImage.Format.Format_RGB888)
|
|
p = convert_to_qt_format.scaled(self.video_width, self.video_height, QtCore.Qt.AspectRatioMode.KeepAspectRatio)
|
|
return QtGui.QPixmap.fromImage(p)
|