def __init__(self): super(Main, self).__init__() # File Picker self.video_pick = Picker("Open video", filters="Videos (*.mp4 *.mpg *.avi);;All files (*.*)") self.subtitle_pick = Picker("Open subtitle", filters="SubRip Subtitles (*.srt);;All files (*.*)") self.save_pick = Picker("Save as", check_exists=False, check_writable=True) # Times self.start = MinuteSecondEdit(self) self.stop = MinuteSecondEdit(self) self.alt_audio = QtWidgets.QCheckBox("Alternate audio track", self) icon_ok = self.style().standardIcon(QtWidgets.QStyle.SP_DialogOkButton) self.ok_btn = QPushButton(icon_ok, "Do it !", self) self.init()
def __init__(self): super(Main, self).__init__() # File Picker self.video_pick = Picker( 'Open video', filters='Videos (*.mp4 *.mpg *.avi);;All files (*.*)') self.subtitle_pick = Picker( 'Open subtitle', filters='SubRip Subtitles (*.srt);;All files (*.*)') self.save_pick = Picker('Save as', check_exists=False, check_writable=True) # Times self.start = MinuteSecondEdit(self) self.stop = MinuteSecondEdit(self) self.alt_audio = QtWidgets.QCheckBox('Alternate audio track', self) icon_ok = self.style().standardIcon(QtWidgets.QStyle.SP_DialogOkButton) self.ok_btn = QPushButton(icon_ok, 'Do it !', self) self.init()
class Main(QtWidgets.QWidget): def __init__(self): super(Main, self).__init__() # File Picker self.video_pick = Picker("Open video", filters="Videos (*.mp4 *.mpg *.avi);;All files (*.*)") self.subtitle_pick = Picker("Open subtitle", filters="SubRip Subtitles (*.srt);;All files (*.*)") self.save_pick = Picker("Save as", check_exists=False, check_writable=True) # Times self.start = MinuteSecondEdit(self) self.stop = MinuteSecondEdit(self) self.alt_audio = QtWidgets.QCheckBox("Alternate audio track", self) icon_ok = self.style().standardIcon(QtWidgets.QStyle.SP_DialogOkButton) self.ok_btn = QPushButton(icon_ok, "Do it !", self) self.init() def init(self): # events self.video_pick.textChanged.connect(self.video_changed) for w in (self.video_pick, self.subtitle_pick, self.start, self.stop, self.save_pick): w.textChanged.connect(self.doit_controller) # times times = QtWidgets.QHBoxLayout() times.addWidget(self.start) times.addWidget(self.stop) times.addStretch(1) # Buttons self.ok_btn.setEnabled(False) self.ok_btn.clicked.connect(self.do_it) icon_quit = self.style().standardIcon(QtWidgets.QStyle.SP_DialogCancelButton) quit_btn = QPushButton(icon_quit, "Quit", self) quit_btn.clicked.connect(exit) hbox = QtWidgets.QHBoxLayout() hbox.addWidget(self.alt_audio) hbox.addStretch(1) hbox.addWidget(self.ok_btn) hbox.addWidget(quit_btn) # Stitch it # vbox = QtWidgets.QVBoxLayout() grid = QtWidgets.QGridLayout() grid.setSpacing(10) grid.addWidget(QLabel("Video:"), 1, 0) grid.addWidget(self.video_pick, 1, 1) grid.addWidget(QLabel("Subtitles:"), 2, 0) grid.addWidget(self.subtitle_pick, 2, 1) grid.addWidget(QLabel("Start / Stop (HHMMSS):"), 3, 0) grid.addLayout(times, 3, 1) grid.addWidget(QLabel("Output:"), 4, 0) grid.addWidget(self.save_pick, 4, 1) # grid.addStretch(1) grid.addLayout(hbox, 5, 1) self.setLayout(grid) # noinspection PyUnusedLocal @QtCore.pyqtSlot() def video_changed(self, *args, **kw): p = self.video_pick.get_text() if p: self.subtitle_pick.set_text(str(Path(p).with_suffix(".srt"))) # noinspection PyUnusedLocal @QtCore.pyqtSlot() def doit_controller(self, *args, **kw): ok = lambda w: w.hasAcceptableInput() self.ok_btn.setEnabled( (ok(self.video_pick) or ok(self.subtitle_pick)) and ok(self.start) and ok(self.stop) and ok(self.save_pick) ) def do_it(self): vid_in = self.video_pick.get_text() vid_out = self.save_pick.get_text() + os.path.splitext(vid_in)[1] ss = self.start.get_time() to = self.stop.get_time() d = duration_str(self.start.get_h_m_s(), self.stop.get_h_m_s()) alt_audio = self.alt_audio.isChecked() video_ret = video_cut(vid_in, vid_out, ss, to, d, alt_audio, self) if video_ret == 0: sbt_out = self.cut_subtitle() opn = shutil.which("xdg-open") if vid_out and os.path.isfile(vid_out): f = vid_out elif sbt_out and os.path.isfile(sbt_out): f = sbt_out else: # This should not happen as button is greyed out msg = "" QMessageBox.warning(self, "no file was generated", msg, defaultButton=QMessageBox.NoButton) return if opn: subprocess.Popen([opn, f]) def cut_subtitle(self): sbt_in = self.subtitle_pick.get_text() if os.path.isfile(sbt_in): sbt_out = self.save_pick.get_text() + os.path.splitext(sbt_in)[1] h1, m1, s1 = self.start.get_h_m_s() h2, m2, s2 = self.stop.get_h_m_s() import chardet detected = chardet.detect(open(sbt_in, "rb").read(1024 * 1024)) enc = detected["encoding"] cnf = detected["confidence"] e = None encs = OrderedSet([enc, "utf-8", "latin1"]) for encoding in encs: try: logger.info("Trying to open subtitle with encoding %s" % encoding) subs = pysrt.open(sbt_in, error_handling=pysrt.ERROR_LOG, encoding=encoding) subtitle_cut(h1, m1, s1, h2, m2, s2, subs, sbt_out) return except Exception as ae: e = e or ae logger.warning("encoding %s failed", encoding, exc_info=1) msg = ( "Could not open {} with any of the following encodings:\n {}\n\n" "Confidence on {} was {}.\nFirst error was: {}" ) msg = msg.format(os.path.basename(sbt_in), ", ".join(encs), enc, cnf, str(e)) QMessageBox.warning(self, "Opening subtitle failed", msg, defaultButton=QMessageBox.NoButton) return sbt_out
class Main(QtWidgets.QWidget): def __init__(self): super(Main, self).__init__() # File Picker self.video_pick = Picker( 'Open video', filters='Videos (*.mp4 *.mpg *.avi);;All files (*.*)') self.subtitle_pick = Picker( 'Open subtitle', filters='SubRip Subtitles (*.srt);;All files (*.*)') self.save_pick = Picker('Save as', check_exists=False, check_writable=True) # Times self.start = MinuteSecondEdit(self) self.stop = MinuteSecondEdit(self) self.alt_audio = QtWidgets.QCheckBox('Alternate audio track', self) icon_ok = self.style().standardIcon(QtWidgets.QStyle.SP_DialogOkButton) self.ok_btn = QPushButton(icon_ok, 'Do it !', self) self.init() def init(self): # events self.video_pick.textChanged.connect(self.video_changed) for w in (self.video_pick, self.subtitle_pick, self.start, self.stop, self.save_pick): w.textChanged.connect(self.doit_controller) # times times = QtWidgets.QHBoxLayout() times.addWidget(self.start) times.addWidget(self.stop) times.addStretch(1) # Buttons self.ok_btn.setEnabled(False) self.ok_btn.clicked.connect(self.do_it) icon_quit = self.style().standardIcon( QtWidgets.QStyle.SP_DialogCancelButton) quit_btn = QPushButton(icon_quit, 'Quit', self) quit_btn.clicked.connect(exit) hbox = QtWidgets.QHBoxLayout() hbox.addWidget(self.alt_audio) hbox.addStretch(1) hbox.addWidget(self.ok_btn) hbox.addWidget(quit_btn) # Stitch it # vbox = QtWidgets.QVBoxLayout() grid = QtWidgets.QGridLayout() grid.setSpacing(10) grid.addWidget(QLabel('Video:'), 1, 0) grid.addWidget(self.video_pick, 1, 1) grid.addWidget(QLabel('Subtitles:'), 2, 0) grid.addWidget(self.subtitle_pick, 2, 1) grid.addWidget(QLabel('Start / Stop (HHMMSS):'), 3, 0) grid.addLayout(times, 3, 1) grid.addWidget(QLabel('Output:'), 4, 0) grid.addWidget(self.save_pick, 4, 1) # grid.addStretch(1) grid.addLayout(hbox, 5, 1) self.setLayout(grid) # noinspection PyUnusedLocal @QtCore.pyqtSlot() def video_changed(self, *args, **kw): p = self.video_pick.get_text() if p: self.subtitle_pick.set_text(str(Path(p).with_suffix('.srt'))) # noinspection PyUnusedLocal @QtCore.pyqtSlot() def doit_controller(self, *args, **kw): ok = lambda w: w.hasAcceptableInput() self.ok_btn.setEnabled((ok(self.video_pick) or ok(self.subtitle_pick)) and ok(self.start) and ok(self.stop) and ok(self.save_pick)) def do_it(self): vid_in = self.video_pick.get_text() vid_out = self.save_pick.get_text() + os.path.splitext(vid_in)[1] ss = self.start.get_time() to = self.stop.get_time() d = duration_str(self.start.get_h_m_s(), self.stop.get_h_m_s()) alt_audio = self.alt_audio.isChecked() video_ret = video_cut(vid_in, vid_out, ss, to, d, alt_audio, self) if video_ret == 0: sbt_out = self.cut_subtitle() opn = shutil.which('xdg-open') if vid_out and os.path.isfile(vid_out): f = vid_out elif sbt_out and os.path.isfile(sbt_out): f = sbt_out else: # This should not happen as button is greyed out msg = '' QMessageBox.warning(self, 'no file was generated', msg, defaultButton=QMessageBox.NoButton) return if opn: subprocess.Popen([opn, f]) def cut_subtitle(self): sbt_in = self.subtitle_pick.get_text() if os.path.isfile(sbt_in): sbt_out = self.save_pick.get_text() + os.path.splitext(sbt_in)[1] h1, m1, s1 = self.start.get_h_m_s() h2, m2, s2 = self.stop.get_h_m_s() import chardet detected = chardet.detect(open(sbt_in, 'rb').read(1024 * 1024)) enc = detected['encoding'] cnf = detected['confidence'] e = None encs = OrderedSet([enc, 'utf-8', 'latin1']) for encoding in encs: try: logger.info('Trying to open subtitle with encoding %s' % encoding) subs = pysrt.open(sbt_in, error_handling=pysrt.ERROR_LOG, encoding=encoding) subtitle_cut(h1, m1, s1, h2, m2, s2, subs, sbt_out) return except Exception as ae: e = e or ae logger.warning('encoding %s failed', encoding, exc_info=1) msg = "Could not open {} with any of the following encodings:\n {}\n\n" \ "Confidence on {} was {}.\nFirst error was: {}" msg = msg.format(os.path.basename(sbt_in), ', '.join(encs), enc, cnf, str(e)) QMessageBox.warning(self, 'Opening subtitle failed', msg, defaultButton=QMessageBox.NoButton) return sbt_out