Refactoring the project. Adding some improvements. Add QRangeSlider slider to set the scope of the podcast preview. Interface improvements to the podcast view. Update .gitignore.
This commit is contained in:
parent
0efb96fef6
commit
cce2fb47dc
2
.gitignore
vendored
2
.gitignore
vendored
@ -54,7 +54,7 @@ cover/
|
|||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
*.pot
|
*.pot
|
||||||
|
demuxer.txt
|
||||||
# Django stuff:
|
# Django stuff:
|
||||||
*.log
|
*.log
|
||||||
local_settings.py
|
local_settings.py
|
||||||
|
3
.idea/dictionaries/afar.xml
Normal file
3
.idea/dictionaries/afar.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="afar" />
|
||||||
|
</component>
|
1
Pipfile
1
Pipfile
@ -11,6 +11,7 @@ pylama = "*"
|
|||||||
ffmpeg = "*"
|
ffmpeg = "*"
|
||||||
pip = "*"
|
pip = "*"
|
||||||
ffmpeg-python = "*"
|
ffmpeg-python = "*"
|
||||||
|
pydub = "*"
|
||||||
|
|
||||||
[dev-packages]
|
[dev-packages]
|
||||||
|
|
||||||
|
10
Pipfile.lock
generated
10
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "6c12b28b456a859b8139dd5175876beeec58f47abcfbcb6d98dbfdc3a955320d"
|
"sha256": "b9153460b4a961fc9063b87ddac6e4c7bf8748bfaefcefc26f2401e340ae7b1e"
|
||||||
},
|
},
|
||||||
"pipfile-spec": 6,
|
"pipfile-spec": 6,
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -148,6 +148,14 @@
|
|||||||
"markers": "python_version >= '3.5'",
|
"markers": "python_version >= '3.5'",
|
||||||
"version": "==5.1.1"
|
"version": "==5.1.1"
|
||||||
},
|
},
|
||||||
|
"pydub": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:25fdfbbfd4c69363006a27c7bd2346c4b886a0dd3da264c14d858b71a9593284",
|
||||||
|
"sha256:630c68bfff9bb27cbc5e1f02923f717c3bc5f4d73fd685fda08b6ce90f76dc69"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.24.1"
|
||||||
|
},
|
||||||
"pyflakes": {
|
"pyflakes": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92",
|
"sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92",
|
||||||
|
BIN
src/gui/fonts/Raleway.zip
Normal file
BIN
src/gui/fonts/Raleway.zip
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 840 B After Width: | Height: | Size: 1.1 KiB |
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>dialog</class>
|
<class>PreviewDialog</class>
|
||||||
<widget class="QDialog" name="dialog">
|
<widget class="QDialog" name="PreviewDialog">
|
||||||
<property name="windowModality">
|
<property name="windowModality">
|
||||||
<enum>Qt::NonModal</enum>
|
<enum>Qt::NonModal</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -18,29 +18,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="vertical_layout">
|
<layout class="QVBoxLayout" name="v_layout_1"/>
|
||||||
<item>
|
|
||||||
<widget class="QGraphicsView" name="graphics_view"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="Line" name="line">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSlider" name="range_silder">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="tickPosition">
|
|
||||||
<enum>QSlider::TicksBothSides</enum>
|
|
||||||
</property>
|
|
||||||
<property name="tickInterval">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_2">
|
<widget class="Line" name="line_2">
|
||||||
@ -50,54 +28,59 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontal_layout_2">
|
<layout class="QHBoxLayout" name="h_layout_range_values">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="left_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Początek fragmentu</string>
|
<string>Czas rozpoczęcia:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="line_edit"/>
|
<widget class="QLineEdit" name="left_range"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="right_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Koniec fragemntu</string>
|
<string>Czas zakończenia:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="line_edit_2"/>
|
<widget class="QLineEdit" name="right_range"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="create_preview_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>utwórz podgląd</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontal_layout_3">
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="push_button">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="play_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>start</string>
|
<string>start</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="push_button_2">
|
<widget class="QPushButton" name="stop_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>stop</string>
|
<string>stop</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="push_button_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>zakończ</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -2,6 +2,8 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from pathlib import Path
|
||||||
|
from pydub.utils import mediainfo
|
||||||
|
|
||||||
# import resources_rc
|
# import resources_rc
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
@ -10,12 +12,18 @@ from PyQt5.QtWidgets import QMainWindow, QLabel, QFileDialog, QDialog, QDialogBu
|
|||||||
|
|
||||||
from src.python.classes.settings_dialog import SettingsDialog
|
from src.python.classes.settings_dialog import SettingsDialog
|
||||||
from src.python.ui.mainwindow_ui import Ui_MainWindow
|
from src.python.ui.mainwindow_ui import Ui_MainWindow
|
||||||
|
|
||||||
from src.python.classes.translate import Translator
|
from src.python.classes.translate import Translator
|
||||||
|
from src.python.classes.preview_dialog import PreviewDialog
|
||||||
|
|
||||||
import generate_demuxer
|
import generate_demuxer
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
||||||
|
"""
|
||||||
|
MainWindow Class
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(MainWindow, self).__init__(parent=parent)
|
super(MainWindow, self).__init__(parent=parent)
|
||||||
self.translator = Translator()
|
self.translator = Translator()
|
||||||
@ -29,9 +37,14 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
|||||||
self.aresample = "8000"
|
self.aresample = "8000"
|
||||||
self.test_data()
|
self.test_data()
|
||||||
|
|
||||||
|
self.image_extensions = ['.jpg', '.png']
|
||||||
|
self.audio_extensions = ['.mp3', '.wav']
|
||||||
|
|
||||||
def setup_logic(self):
|
def setup_logic(self):
|
||||||
|
"""Connect ui elements with methods."""
|
||||||
self.action_settings.triggered.connect(self.open_setting_dialog)
|
self.action_settings.triggered.connect(self.open_setting_dialog)
|
||||||
self.button_generate.clicked.connect(self.generate_video_podcast)
|
self.button_generate.clicked.connect(self.generate_video_podcast)
|
||||||
|
self.button_preview.clicked.connect(self.preview_video_podcast)
|
||||||
self.button_audio_1.clicked.connect(lambda: self.open_audio_import(audio_number=1))
|
self.button_audio_1.clicked.connect(lambda: self.open_audio_import(audio_number=1))
|
||||||
self.button_audio_2.clicked.connect(lambda: self.open_audio_import(audio_number=2))
|
self.button_audio_2.clicked.connect(lambda: self.open_audio_import(audio_number=2))
|
||||||
self.button_select_avatar_1.clicked.connect(lambda: self.open_image_import(image_number=1))
|
self.button_select_avatar_1.clicked.connect(lambda: self.open_image_import(image_number=1))
|
||||||
@ -42,6 +55,7 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
|||||||
self.check_box_connected_channels.stateChanged.connect(self.channels_connected)
|
self.check_box_connected_channels.stateChanged.connect(self.channels_connected)
|
||||||
|
|
||||||
def change_language(self):
|
def change_language(self):
|
||||||
|
"""Retranslate user interface."""
|
||||||
self.translator.load_lang(self.lang)
|
self.translator.load_lang(self.lang)
|
||||||
self.retranslateUi(self.window())
|
self.retranslateUi(self.window())
|
||||||
|
|
||||||
@ -49,25 +63,12 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
|||||||
self.test_data()
|
self.test_data()
|
||||||
|
|
||||||
def setup_detail(self):
|
def setup_detail(self):
|
||||||
|
"""TODO: add names to images"""
|
||||||
self.line_edit_name_1.setDisabled(True)
|
self.line_edit_name_1.setDisabled(True)
|
||||||
self.line_edit_name_2.setDisabled(True)
|
self.line_edit_name_2.setDisabled(True)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def create_custom_dialog(title: str, msg: str):
|
|
||||||
dialog = QDialog()
|
|
||||||
label = QLabel()
|
|
||||||
label.setText(msg)
|
|
||||||
label.setObjectName('message_box')
|
|
||||||
buttons = QDialogButtonBox.Ok
|
|
||||||
button_box = QDialogButtonBox(buttons)
|
|
||||||
button_box.accepted.connect(dialog.accept)
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
layout.addWidget(label)
|
|
||||||
layout.addWidget(button_box)
|
|
||||||
dialog.setLayout(layout)
|
|
||||||
return dialog
|
|
||||||
|
|
||||||
def test_data(self):
|
def test_data(self):
|
||||||
|
"""Test data."""
|
||||||
self.line_edit_audio_1.setText('./src/sounds/oba_kanały.mp3')
|
self.line_edit_audio_1.setText('./src/sounds/oba_kanały.mp3')
|
||||||
pixmap1 = QPixmap('./src/gui/images/both.png')
|
pixmap1 = QPixmap('./src/gui/images/both.png')
|
||||||
scaled_pixmap1 = pixmap1.scaled(pixmap1.size(), Qt.KeepAspectRatio)
|
scaled_pixmap1 = pixmap1.scaled(pixmap1.size(), Qt.KeepAspectRatio)
|
||||||
@ -89,36 +90,64 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
|||||||
self.preview_label_avatar_4.setPixmap(scaled_pixmap4)
|
self.preview_label_avatar_4.setPixmap(scaled_pixmap4)
|
||||||
self.preview_label_avatar_4.setProperty('path', './src/gui/images/right.png')
|
self.preview_label_avatar_4.setProperty('path', './src/gui/images/right.png')
|
||||||
|
|
||||||
def open_setting_dialog(self):
|
def check_file(self, file, extensions):
|
||||||
old_lang = self.lang
|
"""Check file exist and have good extension."""
|
||||||
settings = SettingsDialog(parent=self)
|
if not file:
|
||||||
settings.exec_()
|
msg = "[!] Nie wybrano żadnego pliku."
|
||||||
if old_lang != self.lang:
|
dialog = self.create_custom_dialog(title='Ostrzeżenie', msg=msg)
|
||||||
print(old_lang, self.lang)
|
dialog.exec_()
|
||||||
self.change_language()
|
return False
|
||||||
|
|
||||||
|
elif not Path(file).is_file():
|
||||||
|
msg = f"[!] Wybrany plik: {file} - nie istnieje."
|
||||||
|
dialog = self.create_custom_dialog(title='Ostrzeżenie', msg=msg)
|
||||||
|
dialog.exec_()
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif not any(file.lower().endswith(x) for x in extensions):
|
||||||
|
dialog = self.create_custom_dialog(
|
||||||
|
title='Błąd',
|
||||||
|
msg=F"[!] Wybrany plik: {file.rsplit('/')[-1]} - nie jest plikiem o rozszerzeniu {extensions}.")
|
||||||
|
dialog.exec_()
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def create_custom_dialog(self, title: str, msg: str):
|
||||||
|
"""Create custom dialog."""
|
||||||
|
dialog = QDialog(parent=self)
|
||||||
|
dialog.setWindowTitle(title)
|
||||||
|
label = QLabel()
|
||||||
|
label.setText(msg)
|
||||||
|
label.setObjectName('message_box')
|
||||||
|
buttons = QDialogButtonBox.Ok
|
||||||
|
button_box = QDialogButtonBox(buttons)
|
||||||
|
button_box.accepted.connect(dialog.accept)
|
||||||
|
layout = QVBoxLayout()
|
||||||
|
layout.addWidget(label)
|
||||||
|
layout.addWidget(button_box)
|
||||||
|
dialog.setLayout(layout)
|
||||||
|
return dialog
|
||||||
|
|
||||||
def open_image_import(self, image_number: int):
|
def open_image_import(self, image_number: int):
|
||||||
dialog = QFileDialog()
|
""""Import images."""
|
||||||
dialog.setOption(dialog.DontUseNativeDialog, True)
|
dialog: QFileDialog = QFileDialog()
|
||||||
|
dialog.setOption(dialog.DontUseNativeDialog, False)
|
||||||
dialog.setFileMode(QFileDialog.ExistingFile)
|
dialog.setFileMode(QFileDialog.ExistingFile)
|
||||||
file_formats = "All Files (*);;JPG (*.jpg);;PNG (*.png)"
|
|
||||||
file, _ = dialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "", file_formats, options=dialog.options())
|
|
||||||
if not file:
|
|
||||||
title = 'Ostrzeżenie'
|
|
||||||
msg = "[!] Nie wybrano żadnego pliku."
|
|
||||||
dialog = self.create_custom_dialog(title=title, msg=msg)
|
|
||||||
dialog.exec_()
|
|
||||||
|
|
||||||
if file and not file.lower().endswith('.jpg') and not file.lower().endswith('.png'):
|
title = f"Import image file {image_number}:"
|
||||||
title = 'Błąd'
|
|
||||||
msg = F"[!] Plik {file} nie jest plikiem jpg/png."
|
|
||||||
dialog = self.create_custom_dialog(title=title, msg=msg)
|
|
||||||
dialog.exec_()
|
|
||||||
|
|
||||||
|
# TODO: dynamic create formats filter based on list self.image_extensions
|
||||||
|
formats_filter = "All Files (*);;JPG (*.jpg);;PNG (*.png)"
|
||||||
|
|
||||||
|
file, _ = dialog.getOpenFileName(
|
||||||
|
self, caption=title, filter=formats_filter, options=dialog.options()
|
||||||
|
)
|
||||||
|
|
||||||
|
if not self.check_file(file, self.image_extensions):
|
||||||
|
return -1
|
||||||
else:
|
else:
|
||||||
if file:
|
|
||||||
pixmap = QPixmap(file)
|
pixmap = QPixmap(file)
|
||||||
|
|
||||||
scaled_pixmap = pixmap.scaled(pixmap.size(), Qt.KeepAspectRatio)
|
scaled_pixmap = pixmap.scaled(pixmap.size(), Qt.KeepAspectRatio)
|
||||||
|
|
||||||
if image_number == 1:
|
if image_number == 1:
|
||||||
@ -141,31 +170,42 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
|||||||
print(F"[*] Rodzielczość grafiki: {pixmap.width()}x{pixmap.height()}")
|
print(F"[*] Rodzielczość grafiki: {pixmap.width()}x{pixmap.height()}")
|
||||||
|
|
||||||
def open_audio_import(self, audio_number: int):
|
def open_audio_import(self, audio_number: int):
|
||||||
|
"""Method to import audio."""
|
||||||
dialog = QFileDialog()
|
dialog = QFileDialog()
|
||||||
dialog.setOption(dialog.DontUseNativeDialog, True)
|
dialog.setOption(dialog.DontUseNativeDialog, True)
|
||||||
dialog.setFileMode(QFileDialog.ExistingFile)
|
dialog.setFileMode(QFileDialog.ExistingFile)
|
||||||
file_formats = "All Files (*);;mp3 (*.mp3);;wav (*.wav)"
|
file_formats = "All Files (*);;mp3 (*.mp3);;wav (*.wav)"
|
||||||
file, _ = dialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "", file_formats, options=dialog.options())
|
title = f"Import audio file {audio_number}:"
|
||||||
if not file:
|
file, _ = dialog.getOpenFileName(
|
||||||
msg = "[!] Nie wybrano żadnego pliku."
|
self, caption=title, filter=file_formats, options=dialog.options()
|
||||||
dialog = self.create_custom_dialog(title='Ostrzeżenie', msg=msg)
|
)
|
||||||
dialog.exec_()
|
if not self.check_file(file, self.audio_extensions):
|
||||||
|
return -1
|
||||||
elif not file.lower().endswith('.mp3') and not file.lower().endswith('.wav'):
|
|
||||||
msg = F"[!] Plik {file} nie jest plikiem mp3/wav."
|
|
||||||
dialog = self.create_custom_dialog(title='Błąd', msg=msg)
|
|
||||||
dialog.exec_()
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if audio_number == 1:
|
if audio_number == 1:
|
||||||
self.line_edit_audio_1.setText(file)
|
self.line_edit_audio_1.setText(file)
|
||||||
|
self.line_edit_audio_1.setProperty('duration', mediainfo(file)['duration'])
|
||||||
|
print(f"[*] Audio 1: {file} duration: {mediainfo(file)['duration']}")
|
||||||
elif audio_number == 2:
|
elif audio_number == 2:
|
||||||
self.line_edit_audio_2.setText(file)
|
self.line_edit_audio_2.setText(file)
|
||||||
|
self.line_edit_audio_2.setProperty('duration', mediainfo(file)['duration'])
|
||||||
|
print(f"[*] Audio 2: {file} duration: {mediainfo(file)['duration']}")
|
||||||
|
|
||||||
print(F"[*] Zaimportowano ścieżkę {audio_number} pliku: '{file}'.")
|
print(F"[*] Zaimportowano ścieżkę {audio_number} pliku: '{file}'.")
|
||||||
|
|
||||||
|
def open_setting_dialog(self):
|
||||||
|
"""Open settings dialog."""
|
||||||
|
old_lang = self.lang
|
||||||
|
settings = SettingsDialog(parent=self)
|
||||||
|
settings.exec_()
|
||||||
|
|
||||||
|
if old_lang != self.lang:
|
||||||
|
print(old_lang, self.lang)
|
||||||
|
self.change_language()
|
||||||
|
return True
|
||||||
|
|
||||||
def channels_connected(self, checked):
|
def channels_connected(self, checked):
|
||||||
|
"""Change information id channels connected."""
|
||||||
print(checked)
|
print(checked)
|
||||||
if checked:
|
if checked:
|
||||||
self.button_audio_2.setDisabled(True)
|
self.button_audio_2.setDisabled(True)
|
||||||
@ -177,10 +217,15 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
|||||||
self.line_edit_audio_2.setDisabled(False)
|
self.line_edit_audio_2.setDisabled(False)
|
||||||
self.line_edit_audio_1.setPlaceholderText("Plik audio 1 rozmówcy")
|
self.line_edit_audio_1.setPlaceholderText("Plik audio 1 rozmówcy")
|
||||||
|
|
||||||
def generate_video_podcast(self):
|
def preview_video_podcast(self):
|
||||||
# TODO: Change to pure python
|
"""Preview Video Podcast"""
|
||||||
|
preview_dialog = PreviewDialog(parent=self)
|
||||||
|
preview_dialog.exec_()
|
||||||
|
|
||||||
|
def generate_video_podcast(self, start=None, end=None):
|
||||||
"""Generate podcast based on values from UI."""
|
"""Generate podcast based on values from UI."""
|
||||||
connected_channels = self.check_box_connected_channels.isChecked()
|
connected_channels = self.check_box_connected_channels.isChecked()
|
||||||
|
|
||||||
# Setup images
|
# Setup images
|
||||||
image_files = {
|
image_files = {
|
||||||
'both': self.preview_label_avatar_1.property('path'),
|
'both': self.preview_label_avatar_1.property('path'),
|
||||||
@ -188,7 +233,12 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
|||||||
'left': self.preview_label_avatar_3.property('path'),
|
'left': self.preview_label_avatar_3.property('path'),
|
||||||
'right': self.preview_label_avatar_4.property('path')
|
'right': self.preview_label_avatar_4.property('path')
|
||||||
}
|
}
|
||||||
|
|
||||||
audio_files = []
|
audio_files = []
|
||||||
|
for image_path in image_files.values():
|
||||||
|
if not self.check_file(image_path, self.image_extensions):
|
||||||
|
self.create_custom_dialog(title='Błąd!', msg=f"Tworzenie podcastu zostało przerwane.")
|
||||||
|
return -1
|
||||||
|
|
||||||
if not connected_channels:
|
if not connected_channels:
|
||||||
audio_files.append({'file': self.line_edit_audio_1.text()})
|
audio_files.append({'file': self.line_edit_audio_1.text()})
|
||||||
@ -197,6 +247,12 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
|||||||
else:
|
else:
|
||||||
audio_files.append({'file': self.line_edit_audio_1.text()})
|
audio_files.append({'file': self.line_edit_audio_1.text()})
|
||||||
|
|
||||||
|
for audio_path in audio_files:
|
||||||
|
if not Path(audio_path['file']).is_file():
|
||||||
|
if not self.check_file(audio_path['file'], self.audio_extensions):
|
||||||
|
self.create_custom_dialog(title='Błąd!', msg=f"Tworzenie podcastu zostało przerwane.")
|
||||||
|
return -1
|
||||||
|
|
||||||
# Split name and extension of the file
|
# Split name and extension of the file
|
||||||
for dictionary in audio_files:
|
for dictionary in audio_files:
|
||||||
dictionary['ext'] = dictionary['file'].rsplit('.')[-1]
|
dictionary['ext'] = dictionary['file'].rsplit('.')[-1]
|
||||||
|
72
src/python/classes/preview_dialog.py
Normal file
72
src/python/classes/preview_dialog.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
from PyQt5.QtMultimedia import QMediaPlayer
|
||||||
|
from PyQt5.QtMultimediaWidgets import QVideoWidget
|
||||||
|
|
||||||
|
|
||||||
|
from src.python.classes.range_slider import QRangeSlider
|
||||||
|
from src.python.ui.preview_dialog_ui import Ui_PreviewDialog
|
||||||
|
from PyQt5.QtWidgets import QDialog, QLabel, QStyle
|
||||||
|
|
||||||
|
|
||||||
|
class PreviewDialog(QDialog, Ui_PreviewDialog):
|
||||||
|
"""
|
||||||
|
Dialog to show preview of podcast.
|
||||||
|
"""
|
||||||
|
def __init__(self, parent=None, start_time=0, end_time=15):
|
||||||
|
super(PreviewDialog, self).__init__(parent=parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
self.mediaPlayer = QMediaPlayer(parent=self, flags=QMediaPlayer.VideoSurface)
|
||||||
|
|
||||||
|
self.video_widget = QVideoWidget()
|
||||||
|
self.range_slider = QRangeSlider()
|
||||||
|
self.v_layout_1.addWidget(self.video_widget)
|
||||||
|
self.v_layout_1.addWidget(self.range_slider)
|
||||||
|
|
||||||
|
self.range_slider.setRange(start=int(start_time), end=int(end_time))
|
||||||
|
|
||||||
|
def setup_video_logic(self):
|
||||||
|
"""
|
||||||
|
Setup connections to events
|
||||||
|
"""
|
||||||
|
self.mediaPlayer.setVideoOutput(self.video_widget)
|
||||||
|
self.mediaPlayer.stateChanged.connect(self.media_state_changed)
|
||||||
|
self.mediaPlayer.positionChanged.connect(self.position_changed)
|
||||||
|
self.mediaPlayer.durationChanged.connect(self.duration_changed)
|
||||||
|
self.create_preview_button.connect(self.generate_podcast_preview)
|
||||||
|
|
||||||
|
def media_state_changed(self, state):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param state:
|
||||||
|
"""
|
||||||
|
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
|
||||||
|
self.playButton.setIcon(
|
||||||
|
self.style().standardIcon(QStyle.SP_MediaPause))
|
||||||
|
else:
|
||||||
|
self.playButton.setIcon(
|
||||||
|
self.style().standardIcon(QStyle.SP_MediaPlay))
|
||||||
|
|
||||||
|
def position_changed(self):
|
||||||
|
"""
|
||||||
|
Position Changed
|
||||||
|
"""
|
||||||
|
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
|
||||||
|
self.mediaPlayer.pause()
|
||||||
|
else:
|
||||||
|
self.mediaPlayer.play()
|
||||||
|
|
||||||
|
def play(self):
|
||||||
|
"""
|
||||||
|
Play
|
||||||
|
"""
|
||||||
|
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
|
||||||
|
self.mediaPlayer.pause()
|
||||||
|
else:
|
||||||
|
self.mediaPlayer.play()
|
||||||
|
|
||||||
|
def duration_changed(self, duration):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param duration:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
self.positionSlider.setRange(0, duration)
|
150
src/python/classes/range_slider.py
Normal file
150
src/python/classes/range_slider.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
from PyQt5.QtWidgets import *
|
||||||
|
from PyQt5.QtCore import *
|
||||||
|
from PyQt5.QtGui import *
|
||||||
|
|
||||||
|
|
||||||
|
class QRangeSlider(QAbstractSlider):
|
||||||
|
"""
|
||||||
|
QRangeSlider
|
||||||
|
"""
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.first_position = 1
|
||||||
|
self.second_position = 8
|
||||||
|
|
||||||
|
self.opt = QStyleOptionSlider()
|
||||||
|
self.opt.minimum = 0
|
||||||
|
self.opt.maximum = 100
|
||||||
|
|
||||||
|
self.setTickPosition(QSlider.TicksAbove)
|
||||||
|
self.setTickInterval(1)
|
||||||
|
|
||||||
|
self.setSizePolicy(
|
||||||
|
QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed, QSizePolicy.Slider)
|
||||||
|
)
|
||||||
|
|
||||||
|
def setRangeLimit(self, minimum: int, maximum: int):
|
||||||
|
self.opt.minimum = minimum
|
||||||
|
self.opt.maximum = maximum
|
||||||
|
|
||||||
|
def setRange(self, start: int, end: int):
|
||||||
|
self.first_position = start
|
||||||
|
self.second_position = end
|
||||||
|
|
||||||
|
def getRange(self):
|
||||||
|
return self.first_position, self.second_position
|
||||||
|
|
||||||
|
def setTickPosition(self, position: QSlider.TickPosition):
|
||||||
|
self.opt.tickPosition = position
|
||||||
|
|
||||||
|
def setTickInterval(self, ti: int):
|
||||||
|
self.opt.tickInterval = ti
|
||||||
|
|
||||||
|
def paintEvent(self, event: QPaintEvent):
|
||||||
|
|
||||||
|
painter = QPainter(self)
|
||||||
|
|
||||||
|
# Draw rule
|
||||||
|
self.opt.initFrom(self)
|
||||||
|
self.opt.rect = self.rect()
|
||||||
|
self.opt.sliderPosition = 0
|
||||||
|
self.opt.subControls = QStyle.SC_SliderGroove | QStyle.SC_SliderTickmarks
|
||||||
|
|
||||||
|
# Draw GROOVE
|
||||||
|
self.style().drawComplexControl(QStyle.CC_Slider, self.opt, painter)
|
||||||
|
|
||||||
|
# Draw INTERVAL
|
||||||
|
|
||||||
|
color = self.palette().color(QPalette.Highlight)
|
||||||
|
color.setAlpha(160)
|
||||||
|
painter.setBrush(QBrush(color))
|
||||||
|
painter.setPen(Qt.NoPen)
|
||||||
|
|
||||||
|
self.opt.sliderPosition = self.first_position
|
||||||
|
x_left_handle = (
|
||||||
|
self.style()
|
||||||
|
.subControlRect(QStyle.CC_Slider, self.opt, QStyle.SC_SliderHandle)
|
||||||
|
.right()
|
||||||
|
)
|
||||||
|
|
||||||
|
self.opt.sliderPosition = self.second_position
|
||||||
|
x_right_handle = (
|
||||||
|
self.style()
|
||||||
|
.subControlRect(QStyle.CC_Slider, self.opt, QStyle.SC_SliderHandle)
|
||||||
|
.left()
|
||||||
|
)
|
||||||
|
|
||||||
|
groove_rect = self.style().subControlRect(
|
||||||
|
QStyle.CC_Slider, self.opt, QStyle.SC_SliderGroove
|
||||||
|
)
|
||||||
|
|
||||||
|
selection = QRect(
|
||||||
|
x_left_handle,
|
||||||
|
groove_rect.y(),
|
||||||
|
x_right_handle - x_left_handle,
|
||||||
|
groove_rect.height(),
|
||||||
|
).adjusted(-1, 1, 1, -1)
|
||||||
|
|
||||||
|
painter.drawRect(selection)
|
||||||
|
|
||||||
|
# Draw first handle
|
||||||
|
|
||||||
|
self.opt.subControls = QStyle.SC_SliderHandle
|
||||||
|
self.opt.sliderPosition = self.first_position
|
||||||
|
self.style().drawComplexControl(QStyle.CC_Slider, self.opt, painter)
|
||||||
|
|
||||||
|
# Draw second handle
|
||||||
|
self.opt.sliderPosition = self.second_position
|
||||||
|
self.style().drawComplexControl(QStyle.CC_Slider, self.opt, painter)
|
||||||
|
|
||||||
|
def mousePressEvent(self, event: QMouseEvent):
|
||||||
|
|
||||||
|
self.opt.sliderPosition = self.first_position
|
||||||
|
self._first_sc = self.style().hitTestComplexControl(
|
||||||
|
QStyle.CC_Slider, self.opt, event.pos(), self
|
||||||
|
)
|
||||||
|
|
||||||
|
self.opt.sliderPosition = self.second_position
|
||||||
|
self._second_sc = self.style().hitTestComplexControl(
|
||||||
|
QStyle.CC_Slider, self.opt, event.pos(), self
|
||||||
|
)
|
||||||
|
|
||||||
|
def mouseMoveEvent(self, event: QMouseEvent):
|
||||||
|
|
||||||
|
distance = self.opt.maximum - self.opt.minimum
|
||||||
|
|
||||||
|
pos = self.style().sliderValueFromPosition(
|
||||||
|
0, distance, event.pos().x(), self.rect().width()
|
||||||
|
)
|
||||||
|
|
||||||
|
if self._first_sc == QStyle.SC_SliderHandle:
|
||||||
|
if pos <= self.second_position:
|
||||||
|
self.first_position = pos
|
||||||
|
self.update()
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._second_sc == QStyle.SC_SliderHandle:
|
||||||
|
if pos >= self.first_position:
|
||||||
|
self.second_position = pos
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def sizeHint(self):
|
||||||
|
""" override """
|
||||||
|
SliderLength = 84
|
||||||
|
TickSpace = 5
|
||||||
|
|
||||||
|
w = SliderLength
|
||||||
|
h = self.style().pixelMetric(QStyle.PM_SliderThickness, self.opt, self)
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.opt.tickPosition & QSlider.TicksAbove
|
||||||
|
or self.opt.tickPosition & QSlider.TicksBelow
|
||||||
|
):
|
||||||
|
h += TickSpace
|
||||||
|
|
||||||
|
return (
|
||||||
|
self.style()
|
||||||
|
.sizeFromContents(QStyle.CT_Slider, self.opt, QSize(w, h), self)
|
||||||
|
.expandedTo(QApplication.globalStrut())
|
||||||
|
)
|
@ -11,81 +11,72 @@
|
|||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
class Ui_dialog(object):
|
class Ui_PreviewDialog(object):
|
||||||
def setupUi(self, dialog):
|
def setupUi(self, PreviewDialog):
|
||||||
dialog.setObjectName("dialog")
|
PreviewDialog.setObjectName("PreviewDialog")
|
||||||
dialog.setWindowModality(QtCore.Qt.NonModal)
|
PreviewDialog.setWindowModality(QtCore.Qt.NonModal)
|
||||||
dialog.resize(782, 356)
|
PreviewDialog.resize(782, 356)
|
||||||
self.verticalLayout = QtWidgets.QVBoxLayout(dialog)
|
self.verticalLayout = QtWidgets.QVBoxLayout(PreviewDialog)
|
||||||
self.verticalLayout.setObjectName("verticalLayout")
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
self.vertical_layout = QtWidgets.QVBoxLayout()
|
self.v_layout_1 = QtWidgets.QVBoxLayout()
|
||||||
self.vertical_layout.setObjectName("vertical_layout")
|
self.v_layout_1.setObjectName("v_layout_1")
|
||||||
self.graphics_view = QtWidgets.QGraphicsView(dialog)
|
self.verticalLayout.addLayout(self.v_layout_1)
|
||||||
self.graphics_view.setObjectName("graphics_view")
|
self.line_2 = QtWidgets.QFrame(PreviewDialog)
|
||||||
self.vertical_layout.addWidget(self.graphics_view)
|
|
||||||
self.line = QtWidgets.QFrame(dialog)
|
|
||||||
self.line.setFrameShape(QtWidgets.QFrame.HLine)
|
|
||||||
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
|
||||||
self.line.setObjectName("line")
|
|
||||||
self.vertical_layout.addWidget(self.line)
|
|
||||||
self.range_silder = QtWidgets.QSlider(dialog)
|
|
||||||
self.range_silder.setOrientation(QtCore.Qt.Horizontal)
|
|
||||||
self.range_silder.setTickPosition(QtWidgets.QSlider.TicksBothSides)
|
|
||||||
self.range_silder.setTickInterval(1)
|
|
||||||
self.range_silder.setObjectName("range_silder")
|
|
||||||
self.vertical_layout.addWidget(self.range_silder)
|
|
||||||
self.line_2 = QtWidgets.QFrame(dialog)
|
|
||||||
self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
|
self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
|
||||||
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
|
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||||
self.line_2.setObjectName("line_2")
|
self.line_2.setObjectName("line_2")
|
||||||
self.vertical_layout.addWidget(self.line_2)
|
self.verticalLayout.addWidget(self.line_2)
|
||||||
self.horizontal_layout_2 = QtWidgets.QHBoxLayout()
|
self.h_layout_range_values = QtWidgets.QHBoxLayout()
|
||||||
self.horizontal_layout_2.setObjectName("horizontal_layout_2")
|
self.h_layout_range_values.setObjectName("h_layout_range_values")
|
||||||
self.label = QtWidgets.QLabel(dialog)
|
self.left_label = QtWidgets.QLabel(PreviewDialog)
|
||||||
self.label.setObjectName("label")
|
self.left_label.setObjectName("left_label")
|
||||||
self.horizontal_layout_2.addWidget(self.label)
|
self.h_layout_range_values.addWidget(self.left_label)
|
||||||
self.line_edit = QtWidgets.QLineEdit(dialog)
|
self.left_range = QtWidgets.QLineEdit(PreviewDialog)
|
||||||
self.line_edit.setObjectName("line_edit")
|
self.left_range.setObjectName("left_range")
|
||||||
self.horizontal_layout_2.addWidget(self.line_edit)
|
self.h_layout_range_values.addWidget(self.left_range)
|
||||||
self.label_2 = QtWidgets.QLabel(dialog)
|
self.right_label = QtWidgets.QLabel(PreviewDialog)
|
||||||
self.label_2.setObjectName("label_2")
|
self.right_label.setObjectName("right_label")
|
||||||
self.horizontal_layout_2.addWidget(self.label_2)
|
self.h_layout_range_values.addWidget(self.right_label)
|
||||||
self.line_edit_2 = QtWidgets.QLineEdit(dialog)
|
self.right_range = QtWidgets.QLineEdit(PreviewDialog)
|
||||||
self.line_edit_2.setObjectName("line_edit_2")
|
self.right_range.setObjectName("right_range")
|
||||||
self.horizontal_layout_2.addWidget(self.line_edit_2)
|
self.h_layout_range_values.addWidget(self.right_range)
|
||||||
self.vertical_layout.addLayout(self.horizontal_layout_2)
|
self.create_preview_button = QtWidgets.QPushButton(PreviewDialog)
|
||||||
self.horizontal_layout_3 = QtWidgets.QHBoxLayout()
|
self.create_preview_button.setObjectName("create_preview_button")
|
||||||
self.horizontal_layout_3.setObjectName("horizontal_layout_3")
|
self.h_layout_range_values.addWidget(self.create_preview_button)
|
||||||
self.push_button = QtWidgets.QPushButton(dialog)
|
self.verticalLayout.addLayout(self.h_layout_range_values)
|
||||||
self.push_button.setObjectName("push_button")
|
self.line = QtWidgets.QFrame(PreviewDialog)
|
||||||
self.horizontal_layout_3.addWidget(self.push_button)
|
self.line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||||
self.push_button_2 = QtWidgets.QPushButton(dialog)
|
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||||
self.push_button_2.setObjectName("push_button_2")
|
self.line.setObjectName("line")
|
||||||
self.horizontal_layout_3.addWidget(self.push_button_2)
|
self.verticalLayout.addWidget(self.line)
|
||||||
self.push_button_3 = QtWidgets.QPushButton(dialog)
|
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||||
self.push_button_3.setObjectName("push_button_3")
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
self.horizontal_layout_3.addWidget(self.push_button_3)
|
self.play_button = QtWidgets.QPushButton(PreviewDialog)
|
||||||
self.vertical_layout.addLayout(self.horizontal_layout_3)
|
self.play_button.setObjectName("play_button")
|
||||||
self.verticalLayout.addLayout(self.vertical_layout)
|
self.horizontalLayout.addWidget(self.play_button)
|
||||||
|
self.stop_button = QtWidgets.QPushButton(PreviewDialog)
|
||||||
|
self.stop_button.setObjectName("stop_button")
|
||||||
|
self.horizontalLayout.addWidget(self.stop_button)
|
||||||
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||||
|
|
||||||
self.retranslateUi(dialog)
|
self.retranslateUi(PreviewDialog)
|
||||||
QtCore.QMetaObject.connectSlotsByName(dialog)
|
QtCore.QMetaObject.connectSlotsByName(PreviewDialog)
|
||||||
|
|
||||||
def retranslateUi(self, dialog):
|
def retranslateUi(self, PreviewDialog):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
dialog.setWindowTitle(_translate("dialog", "Dialog"))
|
PreviewDialog.setWindowTitle(_translate("PreviewDialog", "Dialog"))
|
||||||
self.label.setText(_translate("dialog", "Początek fragmentu"))
|
self.left_label.setText(_translate("PreviewDialog", "Czas rozpoczęcia:"))
|
||||||
self.label_2.setText(_translate("dialog", "Koniec fragemntu"))
|
self.right_label.setText(_translate("PreviewDialog", "Czas zakończenia:"))
|
||||||
self.push_button.setText(_translate("dialog", "start"))
|
self.create_preview_button.setText(_translate("PreviewDialog", "utwórz podgląd"))
|
||||||
self.push_button_2.setText(_translate("dialog", "stop"))
|
self.play_button.setText(_translate("PreviewDialog", "start"))
|
||||||
self.push_button_3.setText(_translate("dialog", "zakończ"))
|
self.stop_button.setText(_translate("PreviewDialog", "stop"))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import sys
|
import sys
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
dialog = QtWidgets.QDialog()
|
PreviewDialog = QtWidgets.QDialog()
|
||||||
ui = Ui_dialog()
|
ui = Ui_PreviewDialog()
|
||||||
ui.setupUi(dialog)
|
ui.setupUi(PreviewDialog)
|
||||||
dialog.show()
|
PreviewDialog.show()
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
||||||
|
Loading…
Reference in New Issue
Block a user