Merge branch 'develop'
2
.gitignore
vendored
@ -54,7 +54,7 @@ cover/
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
demuxer.txt
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
|
3
.idea/dictionaries/afar.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="afar" />
|
||||
</component>
|
2
Pipfile
@ -10,6 +10,8 @@ pipfile-requirements = "*"
|
||||
pylama = "*"
|
||||
ffmpeg = "*"
|
||||
pip = "*"
|
||||
ffmpeg-python = "*"
|
||||
pydub = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
25
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "a59428c79a266fc1237cdd4e74b0803bb5f39803495f1fc6c134df7333cdc2bc"
|
||||
"sha256": "b9153460b4a961fc9063b87ddac6e4c7bf8748bfaefcefc26f2401e340ae7b1e"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@ -31,6 +31,14 @@
|
||||
"index": "pypi",
|
||||
"version": "==1.4"
|
||||
},
|
||||
"ffmpeg-python": {
|
||||
"hashes": [
|
||||
"sha256:65225db34627c578ef0e11c8b1eb528bb35e024752f6f10b78c011f6f64c4127",
|
||||
"sha256:ac441a0404e053f8b6a1113a77c0f452f1cfc62f6344a769475ffdc0f56c23c5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.2.0"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060",
|
||||
@ -39,6 +47,13 @@
|
||||
"index": "pypi",
|
||||
"version": "==1.1.2"
|
||||
},
|
||||
"future": {
|
||||
"hashes": [
|
||||
"sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.18.2"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19",
|
||||
@ -133,6 +148,14 @@
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==5.1.1"
|
||||
},
|
||||
"pydub": {
|
||||
"hashes": [
|
||||
"sha256:25fdfbbfd4c69363006a27c7bd2346c4b886a0dd3da264c14d858b71a9593284",
|
||||
"sha256:630c68bfff9bb27cbc5e1f02923f717c3bc5f4d73fd685fda08b6ce90f76dc69"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.24.1"
|
||||
},
|
||||
"pyflakes": {
|
||||
"hashes": [
|
||||
"sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92",
|
||||
|
5
bash_commands/connect_sound.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
tmp_dir=$1
|
||||
audio=$2
|
||||
|
||||
ffmpeg -i $tmp_dir/video/video.mp4 -i $audio -ac 1 -tune stillimage ./out/video-and-audio.mp4 -y
|
8
bash_commands/create_raw_files.sh
Normal file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
tmp_dir=$1
|
||||
aresample=$2
|
||||
|
||||
ffmpeg -i $tmp_dir/left.wav -ac 1 -filter:a aresample=$aresample -map 0:a -c:a pcm_u8 -f data - > $tmp_dir/leftraw &
|
||||
ffmpeg -i $tmp_dir/right.wav -ac 1 -filter:a aresample=$aresample -map 0:a -c:a pcm_u8 -f data - > $tmp_dir/rightraw &
|
||||
|
||||
wait;
|
5
bash_commands/generate_video_by_demuxer.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
tmp_dir=$1
|
||||
tmp_video_dir=$2
|
||||
|
||||
ffmpeg -y -f concat -safe 0 -i demuxer.txt -r 30 -tune stillimage -vsync vfr -pix_fmt yuv420p $tmp_video_dir/video.mp4
|
5
bash_commands/split_channels_to_two_ways.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
tmp_dir=$1
|
||||
both_channels=$2
|
||||
|
||||
ffmpeg -i $both_channels -map_channel 0.0.0 $tmp_dir/left.wav -map_channel 0.0.1 $tmp_dir/right.wav
|
52
find_loudness.py
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
def createReadStream(file):
|
||||
"""Create Bytes Stream"""
|
||||
data = open(file, 'rb')
|
||||
return data
|
||||
|
||||
|
||||
def process_find_loudness(file_path: str, threshold_at_point: int, inertia_samples: float, label: str):
|
||||
|
||||
print("Start process to find loudness in:")
|
||||
print(
|
||||
F"\tfile_path: {file_path}\n"
|
||||
F"\tthreshold_at_point: {threshold_at_point}\n"
|
||||
F"\tinertia_samples: {inertia_samples}\n"
|
||||
F"\tlabel: {label}\n"
|
||||
)
|
||||
stream = createReadStream(file_path)
|
||||
position = 0
|
||||
results = []
|
||||
last_swap_position = 0
|
||||
keep_loud_until = 0
|
||||
was_loud_last_time = False
|
||||
print("Read chunks")
|
||||
chunks = stream.read()
|
||||
print(F"Length: {len(chunks)}")
|
||||
|
||||
try:
|
||||
for i, byte in enumerate(chunks):
|
||||
position += 1
|
||||
volume = abs(byte - 128)
|
||||
|
||||
if position >= keep_loud_until:
|
||||
is_loud = volume > threshold_at_point
|
||||
|
||||
if is_loud != was_loud_last_time:
|
||||
swap_point = {
|
||||
'position_start': last_swap_position,
|
||||
'duration': position - last_swap_position,
|
||||
'loud': was_loud_last_time,
|
||||
'label': label
|
||||
}
|
||||
results.append(swap_point)
|
||||
last_swap_position = position
|
||||
was_loud_last_time = is_loud
|
||||
|
||||
if volume > threshold_at_point:
|
||||
keep_loud_until = position + inertia_samples
|
||||
|
||||
return results
|
||||
|
||||
except Exception as err:
|
||||
print(err)
|
109
generate_demuxer.py
Normal file
@ -0,0 +1,109 @@
|
||||
import math
|
||||
|
||||
from find_loudness import process_find_loudness
|
||||
|
||||
graph_density = 8000
|
||||
threshold_at_point = 1
|
||||
inertia_s = 0.3
|
||||
inertia_samples = inertia_s * graph_density
|
||||
|
||||
|
||||
def set_up_threshold(new_value: int):
|
||||
"""Setup threshold value"""
|
||||
global threshold_at_point
|
||||
if new_value > 0 and isinstance(new_value, int):
|
||||
threshold_at_point = int(new_value)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def s(n: int):
|
||||
"""Frame conversions"""
|
||||
global graph_density
|
||||
return n / graph_density
|
||||
|
||||
|
||||
def seconds(units: int):
|
||||
"""Return seconds."""
|
||||
return math.floor(s(units) % 60)
|
||||
|
||||
|
||||
def minutes(units: int):
|
||||
"""Return minutes."""
|
||||
return math.floor(s(units) / 60)
|
||||
|
||||
|
||||
def hours(units: int):
|
||||
"""Return hours."""
|
||||
return math.floor(s(units) / 60 / 60)
|
||||
|
||||
|
||||
def formatTime(units: int):
|
||||
"""Format time HH:MM:SS."""
|
||||
return f"{hours(units)}:{minutes(units)}:{seconds(units)}"
|
||||
|
||||
|
||||
def new_mode(m, s):
|
||||
"""Set new node"""
|
||||
data = m
|
||||
data[s['label']] = s['loud']
|
||||
return data
|
||||
|
||||
|
||||
def mode_to_string(mode):
|
||||
"""Convert mode type to string"""
|
||||
if mode['left'] and mode['right']:
|
||||
return 'both'
|
||||
elif mode['left']:
|
||||
return 'left'
|
||||
elif mode['right']:
|
||||
return 'right'
|
||||
else:
|
||||
return "none"
|
||||
|
||||
|
||||
def run(tmp_dir):
|
||||
"""Main method to run generating demuxer.txt"""
|
||||
global inertia_samples
|
||||
out_demuxer = 'demuxer.txt'
|
||||
|
||||
with open(out_demuxer, 'w') as demuxer:
|
||||
# Execute process_find_loudness for left and right side
|
||||
left_loudness = process_find_loudness(
|
||||
tmp_dir + "/audio/leftraw",
|
||||
threshold_at_point=threshold_at_point,
|
||||
inertia_samples=inertia_samples,
|
||||
label="left")
|
||||
|
||||
right_loudness = process_find_loudness(
|
||||
tmp_dir + "/audio/rightraw",
|
||||
threshold_at_point=threshold_at_point,
|
||||
inertia_samples=inertia_samples,
|
||||
label="right")
|
||||
|
||||
merged = [*left_loudness, *right_loudness]
|
||||
sorted_list = sorted(merged, key=lambda x: x['position_start'])
|
||||
|
||||
demuxer.write(F"file {tmp_dir}/pics/none.png\n")
|
||||
|
||||
last_point = 0
|
||||
mode = {'left': False, 'right': False}
|
||||
last_file = ''
|
||||
total = 0
|
||||
|
||||
for i in range(2, len(sorted_list)):
|
||||
point = sorted_list[i]
|
||||
mode = new_mode(m=mode, s=point)
|
||||
|
||||
file = F"{tmp_dir}/pics/{mode_to_string(mode)}.png"
|
||||
duration = (point['position_start'] - last_point) / graph_density
|
||||
demuxer.write(F"duration {duration}\n")
|
||||
demuxer.write(F"file {file}\n")
|
||||
last_point = point['position_start']
|
||||
last_file = file
|
||||
total += duration * graph_density
|
||||
|
||||
demuxer.write(F"duration {sorted_list[len(sorted_list) - 1]['duration'] / graph_density}\n")
|
||||
demuxer.write(F"file {last_file}\n")
|
||||
print(F"{total} {formatTime(total)}\n")
|
@ -19,4 +19,23 @@
|
||||
<file>src/gui/dicts/magicpodcast.en.qm</file>
|
||||
<file>src/gui/dicts/magicpodcast.pl.qm</file>
|
||||
</qresource>
|
||||
|
||||
<qresource prefix="icons">
|
||||
<file>src/gui/images/icons/save.png</file>
|
||||
<file>src/gui/images/icons/save_as.png</file>
|
||||
<file>src/gui/images/icons/preview.png</file>
|
||||
<file>src/gui/images/icons/open.png</file>
|
||||
<file>src/gui/images/icons/generate.png</file>
|
||||
<file>src/gui/images/icons/info.png</file>
|
||||
<file>src/gui/images/icons/settings.png</file>
|
||||
<file>src/gui/images/icons/new.png</file>
|
||||
<file>src/gui/images/icons/exit.png</file>
|
||||
<file>src/gui/images/icons/import.png</file>
|
||||
</qresource>
|
||||
|
||||
<qresource prefix="favicon">
|
||||
<file>src/gui/images/icons/32x32.png</file>
|
||||
<file>src/gui/images/icons/45x45.png</file>
|
||||
<file>src/gui/images/icons/60x60.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
56813
resources_rc.py
BIN
src/gui/fonts/Raleway.zip
Normal file
BIN
src/gui/images/icons/32x32.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/gui/images/icons/45x45.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/gui/images/icons/60x60.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
src/gui/images/icons/exit.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
src/gui/images/icons/generate.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/gui/images/icons/import.png
Normal file
After Width: | Height: | Size: 853 B |
BIN
src/gui/images/icons/info.png
Normal file
After Width: | Height: | Size: 950 B |
BIN
src/gui/images/icons/new.png
Normal file
After Width: | Height: | Size: 780 B |
BIN
src/gui/images/icons/open.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/gui/images/icons/preview.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
src/gui/images/icons/save.png
Normal file
After Width: | Height: | Size: 780 B |
BIN
src/gui/images/icons/save_as.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/gui/images/icons/settings.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
@ -78,6 +78,10 @@
|
||||
<property name="text">
|
||||
<string>Dodaj audio 1</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/import.png</normaloff>:/icons/src/gui/images/icons/import.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -139,6 +143,10 @@
|
||||
<property name="text">
|
||||
<string>Dodaj audio 2</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/import.png</normaloff>:/icons/src/gui/images/icons/import.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -221,6 +229,10 @@
|
||||
<property name="text">
|
||||
<string>Rozmówcy - aktywni</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/import.png</normaloff>:/icons/src/gui/images/icons/import.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -303,6 +315,10 @@
|
||||
<property name="text">
|
||||
<string>Rozmówcy - nieaktywni</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/import.png</normaloff>:/icons/src/gui/images/icons/import.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -392,6 +408,10 @@
|
||||
<property name="text">
|
||||
<string>Pierwszy rozmówca - aktywny</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/import.png</normaloff>:/icons/src/gui/images/icons/import.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -474,6 +494,10 @@
|
||||
<property name="text">
|
||||
<string>Drugi rozmówca - aktywny</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/import.png</normaloff>:/icons/src/gui/images/icons/import.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -509,7 +533,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="lcd_number_of_threshold">
|
||||
<widget class="QLCDNumber" name="threshold_lcd">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
@ -538,14 +562,20 @@
|
||||
<enum>QLCDNumber::Filled</enum>
|
||||
</property>
|
||||
<property name="intValue" stdset="0">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="h_slider">
|
||||
<widget class="QSlider" name="threshold_slider">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>128</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@ -565,6 +595,10 @@
|
||||
<property name="text">
|
||||
<string>Podgląd</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/preview.png</normaloff>:/icons/src/gui/images/icons/preview.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@ -572,6 +606,10 @@
|
||||
<property name="text">
|
||||
<string>Wygeneruj podcast</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/generate.png</normaloff>:/icons/src/gui/images/icons/generate.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -579,7 +617,7 @@
|
||||
</layout>
|
||||
<zorder>h_line</zorder>
|
||||
<zorder>h_line_2</zorder>
|
||||
<zorder>h_slider</zorder>
|
||||
<zorder>threshold_slider</zorder>
|
||||
<zorder>h_line_3</zorder>
|
||||
<zorder>v_spacer_1</zorder>
|
||||
<zorder>check_box_connected_channels</zorder>
|
||||
@ -611,6 +649,10 @@
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="status_bar"/>
|
||||
<action name="action_new">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/new.png</normaloff>:/icons/src/gui/images/icons/new.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Nowy projekt</string>
|
||||
</property>
|
||||
@ -622,6 +664,10 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_open">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/open.png</normaloff>:/icons/src/gui/images/icons/open.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Otwórz projekt</string>
|
||||
</property>
|
||||
@ -633,6 +679,10 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_save">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/save.png</normaloff>:/icons/src/gui/images/icons/save.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Zapisz projekt</string>
|
||||
</property>
|
||||
@ -644,6 +694,10 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_save_as">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/save_as.png</normaloff>:/icons/src/gui/images/icons/save_as.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Zapisz projekt jako</string>
|
||||
</property>
|
||||
@ -655,6 +709,10 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_exit">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/exit.png</normaloff>:/icons/src/gui/images/icons/exit.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Zamknij program</string>
|
||||
</property>
|
||||
@ -666,6 +724,10 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_settings">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/settings.png</normaloff>:/icons/src/gui/images/icons/settings.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ustawienia</string>
|
||||
</property>
|
||||
@ -677,6 +739,10 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_about">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/icons/src/gui/images/icons/info.png</normaloff>:/icons/src/gui/images/icons/info.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>O programie MagicPodcast</string>
|
||||
</property>
|
||||
@ -688,7 +754,9 @@
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<resources>
|
||||
<include location="../../../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>action_exit</sender>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>dialog</class>
|
||||
<widget class="QDialog" name="dialog">
|
||||
<class>PreviewDialog</class>
|
||||
<widget class="QDialog" name="PreviewDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::NonModal</enum>
|
||||
</property>
|
||||
@ -18,85 +18,68 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="vertical_layout">
|
||||
<layout class="QVBoxLayout" name="v_layout_1"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="h_layout_range_values">
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="graphics_view"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<widget class="QLabel" name="left_label">
|
||||
<property name="text">
|
||||
<string>Czas rozpoczęcia:</string>
|
||||
</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>
|
||||
<widget class="QLineEdit" name="left_range"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="right_label">
|
||||
<property name="text">
|
||||
<string>Czas zakończenia:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<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>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="play_button">
|
||||
<property name="text">
|
||||
<string>start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontal_layout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Początek fragmentu</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="line_edit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Koniec fragemntu</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="line_edit_2"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontal_layout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="push_button">
|
||||
<property name="text">
|
||||
<string>start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="push_button_2">
|
||||
<property name="text">
|
||||
<string>stop</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="push_button_3">
|
||||
<property name="text">
|
||||
<string>zakończ</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QPushButton" name="stop_button">
|
||||
<property name="text">
|
||||
<string>stop</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
@ -2,16 +2,28 @@ import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import resources_rc
|
||||
from pathlib import Path
|
||||
from pydub.utils import mediainfo
|
||||
|
||||
# import resources_rc
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QPixmap
|
||||
from PyQt5.QtWidgets import QMainWindow, QLabel, QFileDialog, QDialog, QDialogButtonBox, QVBoxLayout, QApplication
|
||||
|
||||
from src.python.classes.settings_dialog import SettingsDialog
|
||||
from src.python.ui.mainwindow_ui import Ui_MainWindow
|
||||
|
||||
from src.python.classes.translate import Translator
|
||||
from src.python.classes.preview_dialog import PreviewDialog
|
||||
|
||||
import generate_demuxer
|
||||
|
||||
|
||||
class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
||||
"""
|
||||
MainWindow Class
|
||||
"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(MainWindow, self).__init__(parent=parent)
|
||||
self.translator = Translator()
|
||||
@ -22,12 +34,17 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
||||
self.setup_logic()
|
||||
self.setup_detail()
|
||||
self.retranslateUi(self.window())
|
||||
self.aresample = 8000
|
||||
self.aresample = "8000"
|
||||
self.test_data()
|
||||
|
||||
self.image_extensions = ['.jpg', '.png']
|
||||
self.audio_extensions = ['.mp3', '.wav']
|
||||
|
||||
def setup_logic(self):
|
||||
"""Connect ui elements with methods."""
|
||||
self.action_settings.triggered.connect(self.open_setting_dialog)
|
||||
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_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))
|
||||
@ -38,6 +55,7 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
||||
self.check_box_connected_channels.stateChanged.connect(self.channels_connected)
|
||||
|
||||
def change_language(self):
|
||||
"""Retranslate user interface."""
|
||||
self.translator.load_lang(self.lang)
|
||||
self.retranslateUi(self.window())
|
||||
|
||||
@ -45,25 +63,12 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
||||
self.test_data()
|
||||
|
||||
def setup_detail(self):
|
||||
"""TODO: add names to images"""
|
||||
self.line_edit_name_1.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):
|
||||
"""Test data."""
|
||||
self.line_edit_audio_1.setText('./src/sounds/oba_kanały.mp3')
|
||||
pixmap1 = QPixmap('./src/gui/images/both.png')
|
||||
scaled_pixmap1 = pixmap1.scaled(pixmap1.size(), Qt.KeepAspectRatio)
|
||||
@ -85,83 +90,128 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
||||
self.preview_label_avatar_4.setPixmap(scaled_pixmap4)
|
||||
self.preview_label_avatar_4.setProperty('path', './src/gui/images/right.png')
|
||||
|
||||
def open_setting_dialog(self):
|
||||
old_lang = self.lang
|
||||
settings = SettingsDialog(parent=self)
|
||||
settings.exec_()
|
||||
if old_lang != self.lang:
|
||||
print(old_lang, self.lang)
|
||||
self.change_language()
|
||||
self.threshold_slider.valueChanged.connect(self.update_lcd_threshold)
|
||||
|
||||
def open_image_import(self, image_number: int):
|
||||
dialog = QFileDialog()
|
||||
dialog.setOption(dialog.DontUseNativeDialog, True)
|
||||
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_()
|
||||
def update_lcd_threshold(self, event):
|
||||
"""Set threshold value from slider to lcd."""
|
||||
self.threshold_lcd.display(event)
|
||||
|
||||
if file and not file.lower().endswith('.jpg') and not file.lower().endswith('.png'):
|
||||
title = 'Błąd'
|
||||
msg = F"[!] Plik {file} nie jest plikiem jpg/png."
|
||||
dialog = self.create_custom_dialog(title=title, msg=msg)
|
||||
dialog.exec_()
|
||||
|
||||
else:
|
||||
if file:
|
||||
pixmap = QPixmap(file)
|
||||
|
||||
scaled_pixmap = pixmap.scaled(pixmap.size(), Qt.KeepAspectRatio)
|
||||
|
||||
if image_number == 1:
|
||||
self.preview_label_avatar_1.setProperty('path', file)
|
||||
self.preview_label_avatar_1.setPixmap(scaled_pixmap)
|
||||
|
||||
elif image_number == 2:
|
||||
self.preview_label_avatar_2.setProperty('path', file)
|
||||
self.preview_label_avatar_2.setPixmap(scaled_pixmap)
|
||||
|
||||
elif image_number == 3:
|
||||
self.preview_label_avatar_3.setProperty('path', file)
|
||||
self.preview_label_avatar_3.setPixmap(scaled_pixmap)
|
||||
|
||||
elif image_number == 4:
|
||||
self.preview_label_avatar_4.setProperty('path', file)
|
||||
self.preview_label_avatar_4.setPixmap(scaled_pixmap)
|
||||
|
||||
print(F"[*] Zaimportowano garfikę {image_number} z pliku: '{file}'.")
|
||||
print(F"[*] Rodzielczość grafiki: {pixmap.width()}x{pixmap.height()}")
|
||||
|
||||
def open_audio_import(self, audio_number: int):
|
||||
dialog = QFileDialog()
|
||||
dialog.setOption(dialog.DontUseNativeDialog, True)
|
||||
dialog.setFileMode(QFileDialog.ExistingFile)
|
||||
file_formats = "All Files (*);;mp3 (*.mp3);;wav (*.wav)"
|
||||
file, _ = dialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "", file_formats, options=dialog.options())
|
||||
def check_file(self, file, extensions):
|
||||
"""Check file exist and have good extension."""
|
||||
if not file:
|
||||
msg = "[!] Nie wybrano żadnego pliku."
|
||||
dialog = self.create_custom_dialog(title='Ostrzeżenie', msg=msg)
|
||||
dialog.exec_()
|
||||
return False
|
||||
|
||||
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)
|
||||
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):
|
||||
""""Import images."""
|
||||
dialog: QFileDialog = QFileDialog()
|
||||
dialog.setOption(dialog.DontUseNativeDialog, False)
|
||||
dialog.setFileMode(QFileDialog.ExistingFile)
|
||||
|
||||
title = f"Import image file {image_number}:"
|
||||
|
||||
# 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:
|
||||
pixmap = QPixmap(file)
|
||||
scaled_pixmap = pixmap.scaled(pixmap.size(), Qt.KeepAspectRatio)
|
||||
|
||||
if image_number == 1:
|
||||
self.preview_label_avatar_1.setProperty('path', file)
|
||||
self.preview_label_avatar_1.setPixmap(scaled_pixmap)
|
||||
|
||||
elif image_number == 2:
|
||||
self.preview_label_avatar_2.setProperty('path', file)
|
||||
self.preview_label_avatar_2.setPixmap(scaled_pixmap)
|
||||
|
||||
elif image_number == 3:
|
||||
self.preview_label_avatar_3.setProperty('path', file)
|
||||
self.preview_label_avatar_3.setPixmap(scaled_pixmap)
|
||||
|
||||
elif image_number == 4:
|
||||
self.preview_label_avatar_4.setProperty('path', file)
|
||||
self.preview_label_avatar_4.setPixmap(scaled_pixmap)
|
||||
|
||||
print(F"[*] Zaimportowano garfikę {image_number} z pliku: '{file}'.")
|
||||
print(F"[*] Rodzielczość grafiki: {pixmap.width()}x{pixmap.height()}")
|
||||
|
||||
def open_audio_import(self, audio_number: int):
|
||||
"""Method to import audio."""
|
||||
dialog = QFileDialog()
|
||||
dialog.setOption(dialog.DontUseNativeDialog, True)
|
||||
dialog.setFileMode(QFileDialog.ExistingFile)
|
||||
file_formats = "All Files (*);;mp3 (*.mp3);;wav (*.wav)"
|
||||
title = f"Import audio file {audio_number}:"
|
||||
file, _ = dialog.getOpenFileName(
|
||||
self, caption=title, filter=file_formats, options=dialog.options()
|
||||
)
|
||||
if not self.check_file(file, self.audio_extensions):
|
||||
return -1
|
||||
else:
|
||||
if audio_number == 1:
|
||||
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:
|
||||
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}'.")
|
||||
|
||||
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):
|
||||
"""Change information id channels connected."""
|
||||
print(checked)
|
||||
if checked:
|
||||
self.button_audio_2.setDisabled(True)
|
||||
@ -173,39 +223,117 @@ class MainWindow(QMainWindow, QApplication, Ui_MainWindow):
|
||||
self.line_edit_audio_2.setDisabled(False)
|
||||
self.line_edit_audio_1.setPlaceholderText("Plik audio 1 rozmówcy")
|
||||
|
||||
def generate_video_podcast(self):
|
||||
# TODO: Change to pure python
|
||||
"""Generate podcast based on values from UI."""
|
||||
audio_1 = self.line_edit_audio_1.text()
|
||||
audio_2 = self.line_edit_audio_2.text()
|
||||
def preview_video_podcast(self):
|
||||
"""Preview Video Podcast"""
|
||||
preview_dialog = PreviewDialog(parent=self)
|
||||
preview_dialog.exec_()
|
||||
|
||||
both_image = self.preview_label_avatar_1.property('path')
|
||||
none_image = self.preview_label_avatar_2.property('path')
|
||||
left_image = self.preview_label_avatar_3.property('path')
|
||||
right_image = self.preview_label_avatar_4.property('path')
|
||||
def generate_video_podcast(self, start=None, end=None):
|
||||
"""Generate podcast based on values from UI."""
|
||||
threshold_value = int(self.threshold_lcd.value())
|
||||
generate_demuxer.set_up_threshold(threshold_value)
|
||||
connected_channels = self.check_box_connected_channels.isChecked()
|
||||
|
||||
# Setup images
|
||||
image_files = {
|
||||
'both': self.preview_label_avatar_1.property('path'),
|
||||
'none': self.preview_label_avatar_2.property('path'),
|
||||
'left': self.preview_label_avatar_3.property('path'),
|
||||
'right': self.preview_label_avatar_4.property('path')
|
||||
}
|
||||
|
||||
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:
|
||||
audio_files.append({'file': self.line_edit_audio_1.text()})
|
||||
audio_files.append({'file': self.line_edit_audio_2.text()})
|
||||
|
||||
else:
|
||||
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
|
||||
for dictionary in audio_files:
|
||||
dictionary['ext'] = dictionary['file'].rsplit('.')[-1]
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp_dir_name:
|
||||
print('[*] Created temporary directory', tmp_dir_name)
|
||||
pics_dir = tmp_dir_name + "/pics/"
|
||||
print(tmp_dir_name)
|
||||
print(f'[*] Create temporary directory: {tmp_dir_name}')
|
||||
tmp_out_dir = tmp_dir_name + "/out"
|
||||
pics_dir = tmp_dir_name + "/pics"
|
||||
audio_dir = tmp_dir_name + "/audio"
|
||||
video_dir = tmp_dir_name + "/video"
|
||||
|
||||
print(f'[*] Created pics directory in {tmp_dir_name}')
|
||||
print(F"[!] Create tmp out dir: {tmp_out_dir}")
|
||||
os.mkdir(tmp_out_dir)
|
||||
|
||||
print(f'[*] Create pics dir: {pics_dir}')
|
||||
os.mkdir(pics_dir)
|
||||
|
||||
print(f'[*] Create audio dir: {audio_dir}')
|
||||
os.mkdir(audio_dir)
|
||||
|
||||
print(f'[*] Create video dir: {video_dir}\n')
|
||||
os.mkdir(video_dir)
|
||||
|
||||
print(f'[*] Copy images to {pics_dir}')
|
||||
shutil.copy(both_image, pics_dir + "both.png")
|
||||
shutil.copy(none_image, pics_dir + "none.png")
|
||||
shutil.copy(left_image, pics_dir + "left.png")
|
||||
shutil.copy(right_image, pics_dir + "right.png")
|
||||
shutil.copy(image_files['both'], pics_dir + "/both.png")
|
||||
shutil.copy(image_files['none'], pics_dir + "/none.png")
|
||||
shutil.copy(image_files['left'], pics_dir + "/left.png")
|
||||
shutil.copy(image_files['right'], pics_dir + "/right.png")
|
||||
|
||||
print(f'[*] Copy audio to {audio_dir}\n')
|
||||
if not self.check_box_connected_channels.isChecked():
|
||||
audio_files[0]['tmp'] = audio_dir + "/left_channel" + "." + audio_files[0]['ext']
|
||||
audio_files[1]['tmp'] = audio_dir + "/right_channel" + "." + audio_files[1]['ext']
|
||||
|
||||
shutil.copy(audio_files[0]['file'], audio_files[0]['tmp'])
|
||||
shutil.copy(audio_files[1]['file'], audio_files[1]['tmp'])
|
||||
|
||||
else:
|
||||
audio_files[0]['tmp'] = audio_dir + "/both_channel" + "." + audio_files[0]['ext']
|
||||
shutil.copy(audio_files[0]['file'], audio_files[0]['tmp'])
|
||||
|
||||
print(f'[*] Images in {pics_dir}: {os.listdir(pics_dir)}')
|
||||
echo_temp_dir_name = subprocess.check_output(["echo", tmp_dir_name]).decode('utf-8')
|
||||
print(f'[*] Audo files in {audio_dir}: {os.listdir(audio_dir)}')
|
||||
|
||||
ech = subprocess.check_output(["bash", "./generate.sh",
|
||||
tmp_dir_name,
|
||||
audio_1, audio_2,
|
||||
both_image, none_image,
|
||||
left_image, right_image,
|
||||
str(self.aresample)]).decode('utf-8')
|
||||
subprocess.check_output(["echo", tmp_dir_name]).decode('utf-8')
|
||||
|
||||
print(echo_temp_dir_name)
|
||||
print(ech)
|
||||
if connected_channels:
|
||||
# Split channels
|
||||
print("[-] Split channels - start:")
|
||||
subprocess.check_output(["bash",
|
||||
"bash_commands/split_channels_to_two_ways.sh",
|
||||
audio_dir,
|
||||
audio_files[0]['tmp']])
|
||||
print("[+] Split channels - done")
|
||||
|
||||
print("[-] Create raw files - start:")
|
||||
subprocess.check_output(['bash',
|
||||
'bash_commands/create_raw_files.sh',
|
||||
audio_dir, self.aresample])
|
||||
print("[+] Create raw files - done")
|
||||
|
||||
print("[-] Create demuxer - start:")
|
||||
generate_demuxer.run(tmp_dir=tmp_dir_name)
|
||||
print("[+] Create demuxer - done")
|
||||
|
||||
print('[-] Create video - start:')
|
||||
subprocess.check_output(
|
||||
['bash', 'bash_commands/generate_video_by_demuxer.sh', tmp_dir_name, video_dir])
|
||||
print('[+] Create video - done')
|
||||
|
||||
# while True: pass
|
||||
print('[-] Create final podcast - start:')
|
||||
subprocess.check_output(
|
||||
['bash', 'bash_commands/connect_sound.sh', tmp_dir_name, audio_files[0]['file']])
|
||||
print('[+] Create final podcast - done')
|
||||
|
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
@ -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())
|
||||
)
|
@ -44,6 +44,9 @@ class Ui_MainWindow(object):
|
||||
self.h_layout_select_audio_1.addWidget(self.line_edit_name_1)
|
||||
self.button_audio_1 = QtWidgets.QPushButton(self.central_widget)
|
||||
self.button_audio_1.setMinimumSize(QtCore.QSize(120, 0))
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/import.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.button_audio_1.setIcon(icon)
|
||||
self.button_audio_1.setObjectName("button_audio_1")
|
||||
self.h_layout_select_audio_1.addWidget(self.button_audio_1)
|
||||
self.verticalLayout.addLayout(self.h_layout_select_audio_1)
|
||||
@ -71,6 +74,7 @@ class Ui_MainWindow(object):
|
||||
self.h_layout_select_audio_2.addWidget(self.line_edit_name_2)
|
||||
self.button_audio_2 = QtWidgets.QPushButton(self.central_widget)
|
||||
self.button_audio_2.setMinimumSize(QtCore.QSize(120, 0))
|
||||
self.button_audio_2.setIcon(icon)
|
||||
self.button_audio_2.setObjectName("button_audio_2")
|
||||
self.h_layout_select_audio_2.addWidget(self.button_audio_2)
|
||||
self.verticalLayout.addLayout(self.h_layout_select_audio_2)
|
||||
@ -108,6 +112,7 @@ class Ui_MainWindow(object):
|
||||
self.button_select_avatar_1.setSizePolicy(sizePolicy)
|
||||
self.button_select_avatar_1.setMinimumSize(QtCore.QSize(200, 35))
|
||||
self.button_select_avatar_1.setMaximumSize(QtCore.QSize(16777215, 35))
|
||||
self.button_select_avatar_1.setIcon(icon)
|
||||
self.button_select_avatar_1.setObjectName("button_select_avatar_1")
|
||||
self.w_layout_avatar_1.addWidget(self.button_select_avatar_1)
|
||||
self.w_layout_avatars_1_and_2.addLayout(self.w_layout_avatar_1)
|
||||
@ -137,6 +142,7 @@ class Ui_MainWindow(object):
|
||||
self.button_select_avatar_2.setSizePolicy(sizePolicy)
|
||||
self.button_select_avatar_2.setMinimumSize(QtCore.QSize(200, 35))
|
||||
self.button_select_avatar_2.setMaximumSize(QtCore.QSize(16777215, 35))
|
||||
self.button_select_avatar_2.setIcon(icon)
|
||||
self.button_select_avatar_2.setObjectName("button_select_avatar_2")
|
||||
self.w_layout_avatar_2.addWidget(self.button_select_avatar_2)
|
||||
self.w_layout_avatars_1_and_2.addLayout(self.w_layout_avatar_2)
|
||||
@ -170,6 +176,7 @@ class Ui_MainWindow(object):
|
||||
self.button_select_avatar_3.setSizePolicy(sizePolicy)
|
||||
self.button_select_avatar_3.setMinimumSize(QtCore.QSize(200, 35))
|
||||
self.button_select_avatar_3.setMaximumSize(QtCore.QSize(16777215, 35))
|
||||
self.button_select_avatar_3.setIcon(icon)
|
||||
self.button_select_avatar_3.setObjectName("button_select_avatar_3")
|
||||
self.w_layout_avatar_3.addWidget(self.button_select_avatar_3)
|
||||
self.w_layout_avatars_3_and_4.addLayout(self.w_layout_avatar_3)
|
||||
@ -199,6 +206,7 @@ class Ui_MainWindow(object):
|
||||
self.button_select_avatar_4.setSizePolicy(sizePolicy)
|
||||
self.button_select_avatar_4.setMinimumSize(QtCore.QSize(200, 35))
|
||||
self.button_select_avatar_4.setMaximumSize(QtCore.QSize(16777215, 35))
|
||||
self.button_select_avatar_4.setIcon(icon)
|
||||
self.button_select_avatar_4.setObjectName("button_select_avatar_4")
|
||||
self.w_layout_avatar_4.addWidget(self.button_select_avatar_4)
|
||||
self.w_layout_avatars_3_and_4.addLayout(self.w_layout_avatar_4)
|
||||
@ -215,22 +223,24 @@ class Ui_MainWindow(object):
|
||||
self.label_threshold_description.setMaximumSize(QtCore.QSize(250, 50))
|
||||
self.label_threshold_description.setObjectName("label_threshold_description")
|
||||
self.h_layout_threshold.addWidget(self.label_threshold_description)
|
||||
self.lcd_number_of_threshold = QtWidgets.QLCDNumber(self.central_widget)
|
||||
self.lcd_number_of_threshold.setMinimumSize(QtCore.QSize(0, 30))
|
||||
self.lcd_number_of_threshold.setMaximumSize(QtCore.QSize(200, 50))
|
||||
self.lcd_number_of_threshold.setFrameShape(QtWidgets.QFrame.Box)
|
||||
self.lcd_number_of_threshold.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.lcd_number_of_threshold.setSmallDecimalPoint(False)
|
||||
self.lcd_number_of_threshold.setDigitCount(3)
|
||||
self.lcd_number_of_threshold.setSegmentStyle(QtWidgets.QLCDNumber.Filled)
|
||||
self.lcd_number_of_threshold.setProperty("intValue", 0)
|
||||
self.lcd_number_of_threshold.setObjectName("lcd_number_of_threshold")
|
||||
self.h_layout_threshold.addWidget(self.lcd_number_of_threshold)
|
||||
self.threshold_lcd = QtWidgets.QLCDNumber(self.central_widget)
|
||||
self.threshold_lcd.setMinimumSize(QtCore.QSize(0, 30))
|
||||
self.threshold_lcd.setMaximumSize(QtCore.QSize(200, 50))
|
||||
self.threshold_lcd.setFrameShape(QtWidgets.QFrame.Box)
|
||||
self.threshold_lcd.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.threshold_lcd.setSmallDecimalPoint(False)
|
||||
self.threshold_lcd.setDigitCount(3)
|
||||
self.threshold_lcd.setSegmentStyle(QtWidgets.QLCDNumber.Filled)
|
||||
self.threshold_lcd.setProperty("intValue", 1)
|
||||
self.threshold_lcd.setObjectName("threshold_lcd")
|
||||
self.h_layout_threshold.addWidget(self.threshold_lcd)
|
||||
self.verticalLayout.addLayout(self.h_layout_threshold)
|
||||
self.h_slider = QtWidgets.QSlider(self.central_widget)
|
||||
self.h_slider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.h_slider.setObjectName("h_slider")
|
||||
self.verticalLayout.addWidget(self.h_slider)
|
||||
self.threshold_slider = QtWidgets.QSlider(self.central_widget)
|
||||
self.threshold_slider.setMinimum(1)
|
||||
self.threshold_slider.setMaximum(128)
|
||||
self.threshold_slider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.threshold_slider.setObjectName("threshold_slider")
|
||||
self.verticalLayout.addWidget(self.threshold_slider)
|
||||
self.h_line_3 = QtWidgets.QFrame(self.central_widget)
|
||||
self.h_line_3.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
self.h_line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
@ -239,15 +249,21 @@ class Ui_MainWindow(object):
|
||||
self.h_layout_preview_or_generate = QtWidgets.QHBoxLayout()
|
||||
self.h_layout_preview_or_generate.setObjectName("h_layout_preview_or_generate")
|
||||
self.button_preview = QtWidgets.QPushButton(self.central_widget)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/preview.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.button_preview.setIcon(icon1)
|
||||
self.button_preview.setObjectName("button_preview")
|
||||
self.h_layout_preview_or_generate.addWidget(self.button_preview)
|
||||
self.button_generate = QtWidgets.QPushButton(self.central_widget)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/generate.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.button_generate.setIcon(icon2)
|
||||
self.button_generate.setObjectName("button_generate")
|
||||
self.h_layout_preview_or_generate.addWidget(self.button_generate)
|
||||
self.verticalLayout.addLayout(self.h_layout_preview_or_generate)
|
||||
self.h_line.raise_()
|
||||
self.h_line_2.raise_()
|
||||
self.h_slider.raise_()
|
||||
self.threshold_slider.raise_()
|
||||
self.h_line_3.raise_()
|
||||
self.check_box_connected_channels.raise_()
|
||||
MainWindow.setCentralWidget(self.central_widget)
|
||||
@ -261,18 +277,39 @@ class Ui_MainWindow(object):
|
||||
self.status_bar.setObjectName("status_bar")
|
||||
MainWindow.setStatusBar(self.status_bar)
|
||||
self.action_new = QtWidgets.QAction(MainWindow)
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.action_new.setIcon(icon3)
|
||||
self.action_new.setObjectName("action_new")
|
||||
self.action_open = QtWidgets.QAction(MainWindow)
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/open.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.action_open.setIcon(icon4)
|
||||
self.action_open.setObjectName("action_open")
|
||||
self.action_save = QtWidgets.QAction(MainWindow)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/save.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.action_save.setIcon(icon5)
|
||||
self.action_save.setObjectName("action_save")
|
||||
self.action_save_as = QtWidgets.QAction(MainWindow)
|
||||
icon6 = QtGui.QIcon()
|
||||
icon6.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/save_as.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.action_save_as.setIcon(icon6)
|
||||
self.action_save_as.setObjectName("action_save_as")
|
||||
self.action_exit = QtWidgets.QAction(MainWindow)
|
||||
icon7 = QtGui.QIcon()
|
||||
icon7.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/exit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.action_exit.setIcon(icon7)
|
||||
self.action_exit.setObjectName("action_exit")
|
||||
self.action_settings = QtWidgets.QAction(MainWindow)
|
||||
icon8 = QtGui.QIcon()
|
||||
icon8.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/settings.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.action_settings.setIcon(icon8)
|
||||
self.action_settings.setObjectName("action_settings")
|
||||
self.action_about = QtWidgets.QAction(MainWindow)
|
||||
icon9 = QtGui.QIcon()
|
||||
icon9.addPixmap(QtGui.QPixmap(":/icons/src/gui/images/icons/info.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.action_about.setIcon(icon9)
|
||||
self.action_about.setObjectName("action_about")
|
||||
self.menu_project.addAction(self.action_new)
|
||||
self.menu_project.addAction(self.action_open)
|
||||
@ -332,6 +369,7 @@ class Ui_MainWindow(object):
|
||||
self.action_about.setText(_translate("MainWindow", "O programie MagicPodcast"))
|
||||
self.action_about.setToolTip(_translate("MainWindow", "Kliknij, aby wyświetlić informacje dotyczące programu MagicPodcast"))
|
||||
self.action_about.setShortcut(_translate("MainWindow", "Ctrl+I"))
|
||||
import resources_rc
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -11,81 +11,72 @@
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_dialog(object):
|
||||
def setupUi(self, dialog):
|
||||
dialog.setObjectName("dialog")
|
||||
dialog.setWindowModality(QtCore.Qt.NonModal)
|
||||
dialog.resize(782, 356)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(dialog)
|
||||
class Ui_PreviewDialog(object):
|
||||
def setupUi(self, PreviewDialog):
|
||||
PreviewDialog.setObjectName("PreviewDialog")
|
||||
PreviewDialog.setWindowModality(QtCore.Qt.NonModal)
|
||||
PreviewDialog.resize(782, 356)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(PreviewDialog)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.vertical_layout = QtWidgets.QVBoxLayout()
|
||||
self.vertical_layout.setObjectName("vertical_layout")
|
||||
self.graphics_view = QtWidgets.QGraphicsView(dialog)
|
||||
self.graphics_view.setObjectName("graphics_view")
|
||||
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.v_layout_1 = QtWidgets.QVBoxLayout()
|
||||
self.v_layout_1.setObjectName("v_layout_1")
|
||||
self.verticalLayout.addLayout(self.v_layout_1)
|
||||
self.line_2 = QtWidgets.QFrame(PreviewDialog)
|
||||
self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.line_2.setObjectName("line_2")
|
||||
self.vertical_layout.addWidget(self.line_2)
|
||||
self.horizontal_layout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontal_layout_2.setObjectName("horizontal_layout_2")
|
||||
self.label = QtWidgets.QLabel(dialog)
|
||||
self.label.setObjectName("label")
|
||||
self.horizontal_layout_2.addWidget(self.label)
|
||||
self.line_edit = QtWidgets.QLineEdit(dialog)
|
||||
self.line_edit.setObjectName("line_edit")
|
||||
self.horizontal_layout_2.addWidget(self.line_edit)
|
||||
self.label_2 = QtWidgets.QLabel(dialog)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.horizontal_layout_2.addWidget(self.label_2)
|
||||
self.line_edit_2 = QtWidgets.QLineEdit(dialog)
|
||||
self.line_edit_2.setObjectName("line_edit_2")
|
||||
self.horizontal_layout_2.addWidget(self.line_edit_2)
|
||||
self.vertical_layout.addLayout(self.horizontal_layout_2)
|
||||
self.horizontal_layout_3 = QtWidgets.QHBoxLayout()
|
||||
self.horizontal_layout_3.setObjectName("horizontal_layout_3")
|
||||
self.push_button = QtWidgets.QPushButton(dialog)
|
||||
self.push_button.setObjectName("push_button")
|
||||
self.horizontal_layout_3.addWidget(self.push_button)
|
||||
self.push_button_2 = QtWidgets.QPushButton(dialog)
|
||||
self.push_button_2.setObjectName("push_button_2")
|
||||
self.horizontal_layout_3.addWidget(self.push_button_2)
|
||||
self.push_button_3 = QtWidgets.QPushButton(dialog)
|
||||
self.push_button_3.setObjectName("push_button_3")
|
||||
self.horizontal_layout_3.addWidget(self.push_button_3)
|
||||
self.vertical_layout.addLayout(self.horizontal_layout_3)
|
||||
self.verticalLayout.addLayout(self.vertical_layout)
|
||||
self.verticalLayout.addWidget(self.line_2)
|
||||
self.h_layout_range_values = QtWidgets.QHBoxLayout()
|
||||
self.h_layout_range_values.setObjectName("h_layout_range_values")
|
||||
self.left_label = QtWidgets.QLabel(PreviewDialog)
|
||||
self.left_label.setObjectName("left_label")
|
||||
self.h_layout_range_values.addWidget(self.left_label)
|
||||
self.left_range = QtWidgets.QLineEdit(PreviewDialog)
|
||||
self.left_range.setObjectName("left_range")
|
||||
self.h_layout_range_values.addWidget(self.left_range)
|
||||
self.right_label = QtWidgets.QLabel(PreviewDialog)
|
||||
self.right_label.setObjectName("right_label")
|
||||
self.h_layout_range_values.addWidget(self.right_label)
|
||||
self.right_range = QtWidgets.QLineEdit(PreviewDialog)
|
||||
self.right_range.setObjectName("right_range")
|
||||
self.h_layout_range_values.addWidget(self.right_range)
|
||||
self.create_preview_button = QtWidgets.QPushButton(PreviewDialog)
|
||||
self.create_preview_button.setObjectName("create_preview_button")
|
||||
self.h_layout_range_values.addWidget(self.create_preview_button)
|
||||
self.verticalLayout.addLayout(self.h_layout_range_values)
|
||||
self.line = QtWidgets.QFrame(PreviewDialog)
|
||||
self.line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.line.setObjectName("line")
|
||||
self.verticalLayout.addWidget(self.line)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.play_button = QtWidgets.QPushButton(PreviewDialog)
|
||||
self.play_button.setObjectName("play_button")
|
||||
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)
|
||||
QtCore.QMetaObject.connectSlotsByName(dialog)
|
||||
self.retranslateUi(PreviewDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(PreviewDialog)
|
||||
|
||||
def retranslateUi(self, dialog):
|
||||
def retranslateUi(self, PreviewDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
dialog.setWindowTitle(_translate("dialog", "Dialog"))
|
||||
self.label.setText(_translate("dialog", "Początek fragmentu"))
|
||||
self.label_2.setText(_translate("dialog", "Koniec fragemntu"))
|
||||
self.push_button.setText(_translate("dialog", "start"))
|
||||
self.push_button_2.setText(_translate("dialog", "stop"))
|
||||
self.push_button_3.setText(_translate("dialog", "zakończ"))
|
||||
PreviewDialog.setWindowTitle(_translate("PreviewDialog", "Dialog"))
|
||||
self.left_label.setText(_translate("PreviewDialog", "Czas rozpoczęcia:"))
|
||||
self.right_label.setText(_translate("PreviewDialog", "Czas zakończenia:"))
|
||||
self.create_preview_button.setText(_translate("PreviewDialog", "utwórz podgląd"))
|
||||
self.play_button.setText(_translate("PreviewDialog", "start"))
|
||||
self.stop_button.setText(_translate("PreviewDialog", "stop"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
dialog = QtWidgets.QDialog()
|
||||
ui = Ui_dialog()
|
||||
ui.setupUi(dialog)
|
||||
dialog.show()
|
||||
PreviewDialog = QtWidgets.QDialog()
|
||||
ui = Ui_PreviewDialog()
|
||||
ui.setupUi(PreviewDialog)
|
||||
PreviewDialog.show()
|
||||
sys.exit(app.exec_())
|
||||
|