Compare commits

..

No commits in common. "b706008101e90da5d3318a86f3fa0d1dc0d02b91" and "df265ead69c77da36a35fb3b255cb85d89a9e344" have entirely different histories.

9 changed files with 18672 additions and 18673 deletions

1
.envrc
View File

@ -4,7 +4,6 @@ export MAIL_PORT=587
export MAIL_SERVER="smtp.fastmail.com" export MAIL_SERVER="smtp.fastmail.com"
export MAIL_USERNAME="kae@midnighthax.com" export MAIL_USERNAME="kae@midnighthax.com"
export MAIL_USE_TLS=True export MAIL_USE_TLS=True
export PYGAME_HIDE_SUPPORT_PROMPT=1
branch=$(git branch --show-current) branch=$(git branch --show-current)
# Always treat running from /home/kae/mm as production # Always treat running from /home/kae/mm as production
if [ $(pwd) == /home/kae/mm ]; then if [ $(pwd) == /home/kae/mm ]; then

View File

@ -48,9 +48,6 @@ class Config(object):
DISPLAY_SQL = False DISPLAY_SQL = False
ERRORS_FROM = ['noreply@midnighthax.com'] ERRORS_FROM = ['noreply@midnighthax.com']
ERRORS_TO = ['kae@midnighthax.com'] ERRORS_TO = ['kae@midnighthax.com']
FADE_CURVE_BACKGROUND = "lightyellow"
FADE_CURVE_FOREGROUND = "blue"
FADE_CURVE_MS_BEFORE_FADE = 5000
FADE_STEPS = 20 FADE_STEPS = 20
FADE_TIME = 3000 FADE_TIME = 3000
HIDE_AFTER_PLAYING_OFFSET = 5000 HIDE_AFTER_PLAYING_OFFSET = 5000
@ -80,7 +77,7 @@ class Config(object):
SCROLL_TOP_MARGIN = 3 SCROLL_TOP_MARGIN = 3
TEXT_NO_TRACK_NO_NOTE = "[Section header]" TEXT_NO_TRACK_NO_NOTE = "[Section header]"
TOD_TIME_FORMAT = "%H:%M:%S" TOD_TIME_FORMAT = "%H:%M:%S"
TIMER_MS = 10 TIMER_MS = 500
TRACK_TIME_FORMAT = "%H:%M:%S" TRACK_TIME_FORMAT = "%H:%M:%S"
VOLUME_VLC_DEFAULT = 75 VOLUME_VLC_DEFAULT = 75
VOLUME_VLC_DROP3db = 65 VOLUME_VLC_DROP3db = 65

View File

@ -1,4 +1,3 @@
import numpy as np
import os import os
import psutil import psutil
import shutil import shutil

View File

@ -4,14 +4,11 @@ from log import log
from os.path import basename from os.path import basename
import argparse import argparse
import os import os
import numpy as np
import pyqtgraph as pg # type: ignore
import stackprinter # type: ignore import stackprinter # type: ignore
import subprocess import subprocess
import sys import sys
import threading import threading
import icons_rc
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pygame import mixer from pygame import mixer
from time import sleep from time import sleep
@ -143,63 +140,78 @@ class CartButton(QPushButton):
self.pgb.setGeometry(0, 0, self.width(), 10) self.pgb.setGeometry(0, 0, self.width(), 10)
class FadeCurve: class PlaylistTrack:
GraphWidget = None """
Used to provide a single reference point for specific playlist tracks,
typically the previous, current and next track.
"""
def __init__(self, track): def __init__(self) -> None:
""" """
Set up fade graph array Only initialises data structure. Call set_plr to populate.
Do NOT store row_number here - that changes if tracks are reordered
in playlist (add, remove, drag/drop) and we shouldn't care about row
number: that's the playlist's problem.
""" """
audio = helpers.get_audio_segment(track.path) self.artist: Optional[str] = None
if not audio: self.duration: Optional[int] = None
return None self.end_time: Optional[datetime] = None
self.fade_at: Optional[int] = None
self.fade_length: Optional[int] = None
self.path: Optional[str] = None
self.playlist_id: Optional[int] = None
self.playlist_tab: Optional[PlaylistTab] = None
self.plr_id: Optional[int] = None
self.silence_at: Optional[int] = None
self.start_gap: Optional[int] = None
self.start_time: Optional[datetime] = None
self.title: Optional[str] = None
self.track_id: Optional[int] = None
# Start point of curve is Config.FADE_CURVE_MS_BEFORE_FADE def __repr__(self) -> str:
# milliseconds before fade starts to silence return (
self.start_ms = max( f"<PlaylistTrack(title={self.title}, artist={self.artist}, "
0, track.fade_at - Config.FADE_CURVE_MS_BEFORE_FADE - 1) f"playlist_id={self.playlist_id}>"
self.end_ms = track.silence_at
self.audio_segment = audio[self.start_ms:self.end_ms]
self.graph_array = np.array(self.audio_segment.get_array_of_samples())
# Calculate the factor to map milliseconds of track to array
self.ms_to_array_factor = (
len(self.graph_array) / (self.end_ms - self.start_ms)
) )
self.region = None def set_plr(self, session: scoped_session, plr: PlaylistRows,
tab: PlaylistTab) -> None:
"""
Update with new plr information
"""
def clear(self) -> None: self.playlist_tab = tab
"""Clear the current graph"""
if self.GraphWidget: session.add(plr)
self.GraphWidget.clear() track = plr.track
def plot(self): self.artist = track.artist
self.curve = self.GraphWidget.plot(self.graph_array) self.duration = track.duration
self.curve.setPen(Config.FADE_CURVE_FOREGROUND) self.end_time = None
self.fade_at = track.fade_at
self.path = track.path
self.playlist_id = plr.playlist_id
self.plr_id = plr.id
self.silence_at = track.silence_at
self.start_gap = track.start_gap
self.start_time = None
self.title = track.title
self.track_id = track.id
def tick(self, play_time) -> None: if track.silence_at and track.fade_at:
"""Update volume fade curve""" self.fade_length = track.silence_at - track.fade_at
if not self.GraphWidget: def start(self) -> None:
return """
Called when track starts playing
"""
ms_of_graph = play_time - self.start_ms self.start_time = datetime.now()
if ms_of_graph < 0: if self.duration:
return self.end_time = (
self.start_time + timedelta(milliseconds=self.duration))
if self.region is None:
# Create the region now that we're into fade
self.region = pg.LinearRegionItem(
[0, 0],
bounds=[0, len(self.graph_array)]
)
self.GraphWidget.addItem(self.region)
# Update region position
self.region.setRegion([0, ms_of_graph * self.ms_to_array_factor])
class ImportTrack(QObject): class ImportTrack(QObject):
@ -249,91 +261,13 @@ class MusicMusterSignals(QObject):
set_next_track_signal = pyqtSignal(int, int) set_next_track_signal = pyqtSignal(int, int)
class PlaylistTrack:
"""
Used to provide a single reference point for specific playlist tracks,
typically the previous, current and next track.
"""
def __init__(self) -> None:
"""
Only initialises data structure. Call set_plr to populate.
Do NOT store row_number here - that changes if tracks are reordered
in playlist (add, remove, drag/drop) and we shouldn't care about row
number: that's the playlist's problem.
"""
self.artist: Optional[str] = None
self.duration: Optional[int] = None
self.end_time: Optional[datetime] = None
self.fade_at: Optional[int] = None
self.fade_curve: Optional[FadeCurve] = None
self.fade_length: Optional[int] = None
self.path: Optional[str] = None
self.playlist_id: Optional[int] = None
self.playlist_tab: Optional[PlaylistTab] = None
self.plr_id: Optional[int] = None
self.silence_at: Optional[int] = None
self.start_gap: Optional[int] = None
self.start_time: Optional[datetime] = None
self.title: Optional[str] = None
self.track_id: Optional[int] = None
def __repr__(self) -> str:
return (
f"<PlaylistTrack(title={self.title}, artist={self.artist}, "
f"playlist_id={self.playlist_id}>"
)
def set_plr(self, session: scoped_session, plr: PlaylistRows,
tab: PlaylistTab) -> None:
"""
Update with new plr information
"""
if not plr.track:
return
self.playlist_tab = tab
session.add(plr)
track = plr.track
self.artist = track.artist
self.duration = track.duration
self.end_time = None
self.fade_at = track.fade_at
self.fade_graph = FadeCurve(track)
self.path = track.path
self.playlist_id = plr.playlist_id
self.plr_id = plr.id
self.silence_at = track.silence_at
self.start_gap = track.start_gap
self.start_time = None
self.title = track.title
self.track_id = track.id
if track.silence_at and track.fade_at:
self.fade_length = track.silence_at - track.fade_at
def start(self) -> None:
"""
Called when track starts playing
"""
self.start_time = datetime.now()
if self.duration:
self.end_time = (
self.start_time + timedelta(milliseconds=self.duration))
class Window(QMainWindow, Ui_MainWindow): class Window(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None, *args, **kwargs) -> None: def __init__(self, parent=None, *args, **kwargs) -> None:
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.setupUi(self) self.setupUi(self)
self.timer: QTimer = QTimer() self.timer: QTimer = QTimer()
self.clock_counter: int = 0 self.even_tick: bool = True
self.music: music.Music = music.Music() self.music: music.Music = music.Music()
self.playing: bool = False self.playing: bool = False
@ -355,10 +289,6 @@ class Window(QMainWindow, Ui_MainWindow):
self.txtSearch.setHidden(True) self.txtSearch.setHidden(True)
self.hide_played_tracks = False self.hide_played_tracks = False
mixer.init() mixer.init()
self.widgetFadeVolume.hideAxis('bottom')
self.widgetFadeVolume.hideAxis('left')
self.widgetFadeVolume.setBackground(Config.FADE_CURVE_BACKGROUND)
FadeCurve.GraphWidget = self.widgetFadeVolume
self.visible_playlist_tab: Callable[[], PlaylistTab] = \ self.visible_playlist_tab: Callable[[], PlaylistTab] = \
self.tabPlaylist.currentWidget self.tabPlaylist.currentWidget
@ -370,7 +300,6 @@ class Window(QMainWindow, Ui_MainWindow):
else: else:
self.carts_init() self.carts_init()
self.enable_play_next_controls() self.enable_play_next_controls()
self.clock_counter = 0
self.timer.start(Config.TIMER_MS) self.timer.start(Config.TIMER_MS)
self.connect_signals_slots() self.connect_signals_slots()
@ -822,7 +751,6 @@ class Window(QMainWindow, Ui_MainWindow):
- Tell playlist_tab track has finished - Tell playlist_tab track has finished
- Reset PlaylistTrack objects - Reset PlaylistTrack objects
- Reset clocks - Reset clocks
- Reset fade graph
- Update headers - Update headers
- Enable controls - Enable controls
""" """
@ -835,9 +763,6 @@ class Window(QMainWindow, Ui_MainWindow):
if self.current_track.playlist_tab: if self.current_track.playlist_tab:
self.current_track.playlist_tab.play_ended() self.current_track.playlist_tab.play_ended()
# Reset fade graph
self.current_track.fade_graph.clear()
# Reset PlaylistTrack objects # Reset PlaylistTrack objects
if self.current_track.track_id: if self.current_track.track_id:
self.previous_track = self.current_track self.previous_track = self.current_track
@ -850,6 +775,21 @@ class Window(QMainWindow, Ui_MainWindow):
self.label_end_timer.setText("00:00") self.label_end_timer.setText("00:00")
self.label_fade_timer.setText("00:00") self.label_fade_timer.setText("00:00")
self.label_silent_timer.setText("00:00") self.label_silent_timer.setText("00:00")
self.label_start_time.setText("00:00:00")
self.label_end_time.setText("00:00:00")
if self.next_track.track_id:
self.label_track_length.setText(
helpers.ms_to_mmss(self.next_track.duration)
)
if self.next_track.silence_at and self.next_track.fade_at:
self.label_fade_length.setText(helpers.ms_to_mmss(
self.next_track.silence_at - self.next_track.fade_at))
else:
self.label_fade_length.setText("0:00")
else:
self.label_track_length.setText("0:00")
self.label_fade_length.setText("0:00")
# Update headers # Update headers
self.update_headers() self.update_headers()
@ -1309,9 +1249,6 @@ class Window(QMainWindow, Ui_MainWindow):
break break
sleep(0.1) sleep(0.1)
# Show closing volume graph
self.current_track.fade_graph.plot()
# Tell database to record it as played # Tell database to record it as played
Playdates(session, self.current_track.track_id) Playdates(session, self.current_track.track_id)
@ -1328,6 +1265,21 @@ class Window(QMainWindow, Ui_MainWindow):
# Update headers # Update headers
self.update_headers() self.update_headers()
# Update clocks
self.label_track_length.setText(
helpers.ms_to_mmss(self.current_track.duration)
)
self.label_fade_length.setText(
helpers.ms_to_mmss(self.current_track.fade_length))
if self.current_track.start_time:
self.label_start_time.setText(
self.current_track.start_time.strftime(
Config.TRACK_TIME_FORMAT))
if self.current_track.end_time:
self.label_end_time.setText(
self.current_track.end_time.strftime(
Config.TRACK_TIME_FORMAT))
def preview(self) -> None: def preview(self) -> None:
""" """
Preview selected or next track. We use a different mechanism to Preview selected or next track. We use a different mechanism to
@ -1596,7 +1548,7 @@ class Window(QMainWindow, Ui_MainWindow):
def set_next_plr_id(self, next_plr_id: Optional[int], def set_next_plr_id(self, next_plr_id: Optional[int],
playlist_tab: PlaylistTab) -> None: playlist_tab: PlaylistTab) -> None:
""" """
Set passed plr_id as next track to play, or clear next track if None Set passed plr_id as next track to play, or clear next track if None
Actions required: Actions required:
- Update self.next_track PlaylistTrack structure - Update self.next_track PlaylistTrack structure
@ -1673,13 +1625,8 @@ class Window(QMainWindow, Ui_MainWindow):
""" """
Carry out clock tick actions. Carry out clock tick actions.
self.clock_counter is incrememted at each tick (100ms), and this
value is used to determine the actions to take.
The Fade Volume graph is updated every 10ms.
The Time of Day clock and any cart progress bars are updated The Time of Day clock and any cart progress bars are updated
every 500ms. every tick (500ms).
All other timers are updated every second. As the timer displays All other timers are updated every second. As the timer displays
have a one-second resolution, updating every 500ms can result in have a one-second resolution, updating every 500ms can result in
@ -1687,7 +1634,6 @@ class Window(QMainWindow, Ui_MainWindow):
updating. That looks odd. updating. That looks odd.
Actions required: Actions required:
- Update Fade Volume graph
- Update TOD clock - Update TOD clock
- Call cart_tick - Call cart_tick
- If track is playing: - If track is playing:
@ -1696,85 +1642,74 @@ class Window(QMainWindow, Ui_MainWindow):
run stop_track run stop_track
""" """
# Update volume fade curve # Update TOD clock
if ( self.lblTOD.setText(datetime.now().strftime(Config.TOD_TIME_FORMAT))
self.current_track.track_id and # Update carts
self.current_track.fade_graph and self.cart_tick()
self.current_track.start_time
):
play_time = (
datetime.now() - self.current_track.start_time
).total_seconds() * 1000
self.current_track.fade_graph.tick(play_time)
if self.clock_counter % 20 == 0: self.even_tick = not self.even_tick
# Update TOD clock if not self.even_tick:
self.lblTOD.setText(datetime.now().strftime( return
Config.TOD_TIME_FORMAT)) if not self.playing:
# Update carts return
self.cart_tick()
if self.clock_counter % 50 == 0: # If track is playing, update track clocks time and colours
if not self.playing: # There is a discrete time between starting playing a track and
return # player.is_playing() returning True, so assume playing if less
# than Config.PLAY_SETTLE microseconds have passed since
# starting play.
if self.music.player and self.current_track.start_time and (
self.music.player.is_playing() or
(datetime.now() - self.current_track.start_time)
< timedelta(microseconds=Config.PLAY_SETTLE)):
playtime = self.music.get_playtime()
time_to_fade = (self.current_track.fade_at - playtime)
time_to_silence = (
self.current_track.silence_at - playtime)
time_to_end = (self.current_track.duration - playtime)
# If track is playing, update track clocks time and colours # Elapsed time
# There is a discrete time between starting playing a track and self.label_elapsed_timer.setText(helpers.ms_to_mmss(playtime))
# player.is_playing() returning True, so assume playing if less
# than Config.PLAY_SETTLE microseconds have passed since
# starting play.
if self.music.player and self.current_track.start_time and (
self.music.player.is_playing() or
(datetime.now() - self.current_track.start_time)
< timedelta(microseconds=Config.PLAY_SETTLE)):
playtime = self.music.get_playtime()
time_to_fade = (self.current_track.fade_at - playtime)
time_to_silence = (
self.current_track.silence_at - playtime)
time_to_end = (self.current_track.duration - playtime)
# Elapsed time # Time to fade
self.label_elapsed_timer.setText(helpers.ms_to_mmss(playtime)) self.label_fade_timer.setText(helpers.ms_to_mmss(time_to_fade))
# Time to fade # If silent in the next 5 seconds, put warning colour on
self.label_fade_timer.setText(helpers.ms_to_mmss(time_to_fade)) # time to silence box and enable play controls
if time_to_silence <= 5500:
# If silent in the next 5 seconds, put warning colour on self.frame_silent.setStyleSheet(
# time to silence box and enable play controls f"background: {Config.COLOUR_ENDING_TIMER}"
if time_to_silence <= 5500:
self.frame_silent.setStyleSheet(
f"background: {Config.COLOUR_ENDING_TIMER}"
)
self.enable_play_next_controls()
# Set warning colour on time to silence box when fade starts
elif time_to_fade <= 500:
self.frame_silent.setStyleSheet(
f"background: {Config.COLOUR_WARNING_TIMER}"
)
# Five seconds before fade starts, set warning colour on
# time to silence box and enable play controls
elif time_to_fade <= 5500:
self.frame_fade.setStyleSheet(
f"background: {Config.COLOUR_WARNING_TIMER}"
)
self.enable_play_next_controls()
else:
self.frame_silent.setStyleSheet("")
self.frame_fade.setStyleSheet("")
self.label_silent_timer.setText(
helpers.ms_to_mmss(time_to_silence)
) )
self.enable_play_next_controls()
# Time to end # Set warning colour on time to silence box when fade starts
self.label_end_timer.setText(helpers.ms_to_mmss(time_to_end)) elif time_to_fade <= 500:
self.frame_silent.setStyleSheet(
# Autoplay next track f"background: {Config.COLOUR_WARNING_TIMER}"
# if time_to_silence <= 1500: )
# self.play_next() # Five seconds before fade starts, set warning colour on
# time to silence box and enable play controls
elif time_to_fade <= 5500:
self.frame_fade.setStyleSheet(
f"background: {Config.COLOUR_WARNING_TIMER}"
)
self.enable_play_next_controls()
else: else:
if self.playing: self.frame_silent.setStyleSheet("")
self.stop_playing() self.frame_fade.setStyleSheet("")
self.label_silent_timer.setText(
helpers.ms_to_mmss(time_to_silence)
)
# Time to end
self.label_end_timer.setText(helpers.ms_to_mmss(time_to_end))
# Autoplay next track
# if time_to_silence <= 1500:
# self.play_next()
else:
if self.playing:
self.stop_playing()
def update_headers(self) -> None: def update_headers(self) -> None:
""" """

File diff suppressed because it is too large Load Diff

View File

@ -349,12 +349,6 @@ padding-left: 8px;</string>
</item> </item>
<item row="5" column="0"> <item row="5" column="0">
<widget class="QFrame" name="InfoFooterFrame"> <widget class="QFrame" name="InfoFooterFrame">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">background-color: rgb(192, 191, 188)</string> <string notr="true">background-color: rgb(192, 191, 188)</string>
</property> </property>
@ -371,14 +365,8 @@ padding-left: 8px;</string>
<widget class="QFrame" name="FadeStopInfoFrame"> <widget class="QFrame" name="FadeStopInfoFrame">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>152</width> <width>321</width>
<height>112</height> <height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>184</width>
<height>16777215</height>
</size> </size>
</property> </property>
<property name="frameShape"> <property name="frameShape">
@ -388,20 +376,28 @@ padding-left: 8px;</string>
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2"> <item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Fade length:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_x_2">
<property name="text">
<string>Start:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="btnFade"> <widget class="QPushButton" name="btnFade">
<property name="minimumSize">
<size>
<width>132</width>
<height>36</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>164</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string> Fade</string> <string> Fade</string>
</property> </property>
@ -417,14 +413,92 @@ padding-left: 8px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="2"> <item row="0" column="3">
<widget class="QPushButton" name="btnPreview"> <widget class="QLabel" name="label_start_time">
<property name="minimumSize"> <property name="font">
<size> <font>
<width>132</width> <family>FreeSans</family>
<height>36</height> <pointsize>16</pointsize>
</size> </font>
</property> </property>
<property name="text">
<string>00:00:00</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_end_time">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>00:00:00</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_x">
<property name="text">
<string>Track length:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_fade_length">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>0:00</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_8">
<property name="text">
<string>End:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_track_length">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>0:00</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QPushButton" name="btnPreview">
<property name="text"> <property name="text">
<string> Preview</string> <string> Preview</string>
</property> </property>
@ -450,7 +524,7 @@ padding-left: 8px;</string>
<widget class="QFrame" name="frame_elapsed"> <widget class="QFrame" name="frame_elapsed">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>152</width> <width>0</width>
<height>112</height> <height>112</height>
</size> </size>
</property> </property>
@ -502,7 +576,7 @@ padding-left: 8px;</string>
<widget class="QFrame" name="frame_fade"> <widget class="QFrame" name="frame_fade">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>152</width> <width>0</width>
<height>112</height> <height>112</height>
</size> </size>
</property> </property>
@ -547,27 +621,11 @@ padding-left: 8px;</string>
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="PlotWidget" name="widgetFadeVolume" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item> <item>
<widget class="QFrame" name="frame_silent"> <widget class="QFrame" name="frame_silent">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>152</width> <width>0</width>
<height>112</height> <height>112</height>
</size> </size>
</property> </property>
@ -616,7 +674,7 @@ padding-left: 8px;</string>
<widget class="QFrame" name="frame_end"> <widget class="QFrame" name="frame_end">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>152</width> <width>0</width>
<height>112</height> <height>112</height>
</size> </size>
</property> </property>
@ -1170,12 +1228,6 @@ padding-left: 8px;</string>
<header>infotabs</header> <header>infotabs</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>PlotWidget</class>
<extends>QWidget</extends>
<header>pyqtgraph</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="icons.qrc"/> <include location="icons.qrc"/>

View File

@ -179,7 +179,6 @@ class Ui_MainWindow(object):
self.tabInfolist.setObjectName("tabInfolist") self.tabInfolist.setObjectName("tabInfolist")
self.gridLayout_4.addWidget(self.splitter, 4, 0, 1, 1) self.gridLayout_4.addWidget(self.splitter, 4, 0, 1, 1)
self.InfoFooterFrame = QtWidgets.QFrame(parent=self.centralwidget) self.InfoFooterFrame = QtWidgets.QFrame(parent=self.centralwidget)
self.InfoFooterFrame.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.InfoFooterFrame.setStyleSheet("background-color: rgb(192, 191, 188)") self.InfoFooterFrame.setStyleSheet("background-color: rgb(192, 191, 188)")
self.InfoFooterFrame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.InfoFooterFrame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.InfoFooterFrame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) self.InfoFooterFrame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
@ -189,34 +188,78 @@ class Ui_MainWindow(object):
self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout") self.horizontalLayout.setObjectName("horizontalLayout")
self.FadeStopInfoFrame = QtWidgets.QFrame(parent=self.InfoFooterFrame) self.FadeStopInfoFrame = QtWidgets.QFrame(parent=self.InfoFooterFrame)
self.FadeStopInfoFrame.setMinimumSize(QtCore.QSize(152, 112)) self.FadeStopInfoFrame.setMinimumSize(QtCore.QSize(321, 0))
self.FadeStopInfoFrame.setMaximumSize(QtCore.QSize(184, 16777215))
self.FadeStopInfoFrame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.FadeStopInfoFrame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.FadeStopInfoFrame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) self.FadeStopInfoFrame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
self.FadeStopInfoFrame.setObjectName("FadeStopInfoFrame") self.FadeStopInfoFrame.setObjectName("FadeStopInfoFrame")
self.gridLayout = QtWidgets.QGridLayout(self.FadeStopInfoFrame) self.gridLayout = QtWidgets.QGridLayout(self.FadeStopInfoFrame)
self.gridLayout.setObjectName("gridLayout") self.gridLayout.setObjectName("gridLayout")
self.label_7 = QtWidgets.QLabel(parent=self.FadeStopInfoFrame)
self.label_7.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter)
self.label_7.setObjectName("label_7")
self.gridLayout.addWidget(self.label_7, 1, 0, 1, 1)
self.label_x_2 = QtWidgets.QLabel(parent=self.FadeStopInfoFrame)
self.label_x_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter)
self.label_x_2.setObjectName("label_x_2")
self.gridLayout.addWidget(self.label_x_2, 0, 2, 1, 1)
self.btnFade = QtWidgets.QPushButton(parent=self.FadeStopInfoFrame) self.btnFade = QtWidgets.QPushButton(parent=self.FadeStopInfoFrame)
self.btnFade.setMinimumSize(QtCore.QSize(132, 36))
self.btnFade.setMaximumSize(QtCore.QSize(164, 16777215))
icon1 = QtGui.QIcon() icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/icons/fade"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon1.addPixmap(QtGui.QPixmap(":/icons/fade"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
self.btnFade.setIcon(icon1) self.btnFade.setIcon(icon1)
self.btnFade.setIconSize(QtCore.QSize(30, 30)) self.btnFade.setIconSize(QtCore.QSize(30, 30))
self.btnFade.setObjectName("btnFade") self.btnFade.setObjectName("btnFade")
self.gridLayout.addWidget(self.btnFade, 0, 0, 1, 2) self.gridLayout.addWidget(self.btnFade, 2, 0, 1, 2)
self.label_start_time = QtWidgets.QLabel(parent=self.FadeStopInfoFrame)
font = QtGui.QFont()
font.setFamily("FreeSans")
font.setPointSize(16)
self.label_start_time.setFont(font)
self.label_start_time.setScaledContents(False)
self.label_start_time.setObjectName("label_start_time")
self.gridLayout.addWidget(self.label_start_time, 0, 3, 1, 1)
self.label_end_time = QtWidgets.QLabel(parent=self.FadeStopInfoFrame)
font = QtGui.QFont()
font.setFamily("FreeSans")
font.setPointSize(16)
self.label_end_time.setFont(font)
self.label_end_time.setScaledContents(False)
self.label_end_time.setObjectName("label_end_time")
self.gridLayout.addWidget(self.label_end_time, 1, 3, 1, 1)
self.label_x = QtWidgets.QLabel(parent=self.FadeStopInfoFrame)
self.label_x.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter)
self.label_x.setObjectName("label_x")
self.gridLayout.addWidget(self.label_x, 0, 0, 1, 1)
self.label_fade_length = QtWidgets.QLabel(parent=self.FadeStopInfoFrame)
font = QtGui.QFont()
font.setFamily("FreeSans")
font.setPointSize(16)
self.label_fade_length.setFont(font)
self.label_fade_length.setScaledContents(False)
self.label_fade_length.setObjectName("label_fade_length")
self.gridLayout.addWidget(self.label_fade_length, 1, 1, 1, 1)
self.label_8 = QtWidgets.QLabel(parent=self.FadeStopInfoFrame)
self.label_8.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter)
self.label_8.setObjectName("label_8")
self.gridLayout.addWidget(self.label_8, 1, 2, 1, 1)
self.label_track_length = QtWidgets.QLabel(parent=self.FadeStopInfoFrame)
font = QtGui.QFont()
font.setFamily("FreeSans")
font.setPointSize(16)
self.label_track_length.setFont(font)
self.label_track_length.setScaledContents(False)
self.label_track_length.setObjectName("label_track_length")
self.gridLayout.addWidget(self.label_track_length, 0, 1, 1, 1)
self.btnPreview = QtWidgets.QPushButton(parent=self.FadeStopInfoFrame) self.btnPreview = QtWidgets.QPushButton(parent=self.FadeStopInfoFrame)
self.btnPreview.setMinimumSize(QtCore.QSize(132, 36))
icon2 = QtGui.QIcon() icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(":/icons/headphones"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon2.addPixmap(QtGui.QPixmap(":/icons/headphones"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
self.btnPreview.setIcon(icon2) self.btnPreview.setIcon(icon2)
self.btnPreview.setIconSize(QtCore.QSize(30, 30)) self.btnPreview.setIconSize(QtCore.QSize(30, 30))
self.btnPreview.setCheckable(True) self.btnPreview.setCheckable(True)
self.btnPreview.setObjectName("btnPreview") self.btnPreview.setObjectName("btnPreview")
self.gridLayout.addWidget(self.btnPreview, 1, 0, 1, 2) self.gridLayout.addWidget(self.btnPreview, 2, 2, 1, 2)
self.horizontalLayout.addWidget(self.FadeStopInfoFrame) self.horizontalLayout.addWidget(self.FadeStopInfoFrame)
self.frame_elapsed = QtWidgets.QFrame(parent=self.InfoFooterFrame) self.frame_elapsed = QtWidgets.QFrame(parent=self.InfoFooterFrame)
self.frame_elapsed.setMinimumSize(QtCore.QSize(152, 112)) self.frame_elapsed.setMinimumSize(QtCore.QSize(0, 112))
self.frame_elapsed.setStyleSheet("") self.frame_elapsed.setStyleSheet("")
self.frame_elapsed.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.frame_elapsed.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.frame_elapsed.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) self.frame_elapsed.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
@ -240,7 +283,7 @@ class Ui_MainWindow(object):
self.verticalLayout_4.addWidget(self.label_elapsed_timer) self.verticalLayout_4.addWidget(self.label_elapsed_timer)
self.horizontalLayout.addWidget(self.frame_elapsed) self.horizontalLayout.addWidget(self.frame_elapsed)
self.frame_fade = QtWidgets.QFrame(parent=self.InfoFooterFrame) self.frame_fade = QtWidgets.QFrame(parent=self.InfoFooterFrame)
self.frame_fade.setMinimumSize(QtCore.QSize(152, 112)) self.frame_fade.setMinimumSize(QtCore.QSize(0, 112))
self.frame_fade.setStyleSheet("") self.frame_fade.setStyleSheet("")
self.frame_fade.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.frame_fade.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.frame_fade.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) self.frame_fade.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
@ -262,17 +305,8 @@ class Ui_MainWindow(object):
self.label_fade_timer.setObjectName("label_fade_timer") self.label_fade_timer.setObjectName("label_fade_timer")
self.verticalLayout_2.addWidget(self.label_fade_timer) self.verticalLayout_2.addWidget(self.label_fade_timer)
self.horizontalLayout.addWidget(self.frame_fade) self.horizontalLayout.addWidget(self.frame_fade)
self.widgetFadeVolume = PlotWidget(parent=self.InfoFooterFrame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widgetFadeVolume.sizePolicy().hasHeightForWidth())
self.widgetFadeVolume.setSizePolicy(sizePolicy)
self.widgetFadeVolume.setMinimumSize(QtCore.QSize(0, 0))
self.widgetFadeVolume.setObjectName("widgetFadeVolume")
self.horizontalLayout.addWidget(self.widgetFadeVolume)
self.frame_silent = QtWidgets.QFrame(parent=self.InfoFooterFrame) self.frame_silent = QtWidgets.QFrame(parent=self.InfoFooterFrame)
self.frame_silent.setMinimumSize(QtCore.QSize(152, 112)) self.frame_silent.setMinimumSize(QtCore.QSize(0, 112))
self.frame_silent.setStyleSheet("") self.frame_silent.setStyleSheet("")
self.frame_silent.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.frame_silent.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.frame_silent.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) self.frame_silent.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
@ -295,7 +329,7 @@ class Ui_MainWindow(object):
self.verticalLayout_5.addWidget(self.label_silent_timer) self.verticalLayout_5.addWidget(self.label_silent_timer)
self.horizontalLayout.addWidget(self.frame_silent) self.horizontalLayout.addWidget(self.frame_silent)
self.frame_end = QtWidgets.QFrame(parent=self.InfoFooterFrame) self.frame_end = QtWidgets.QFrame(parent=self.InfoFooterFrame)
self.frame_end.setMinimumSize(QtCore.QSize(152, 112)) self.frame_end.setMinimumSize(QtCore.QSize(0, 112))
self.frame_end.setStyleSheet("") self.frame_end.setStyleSheet("")
self.frame_end.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) self.frame_end.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.frame_end.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) self.frame_end.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
@ -540,7 +574,15 @@ class Ui_MainWindow(object):
self.current_track_2.setText(_translate("MainWindow", "Current track:")) self.current_track_2.setText(_translate("MainWindow", "Current track:"))
self.next_track_2.setText(_translate("MainWindow", "Next track:")) self.next_track_2.setText(_translate("MainWindow", "Next track:"))
self.lblTOD.setText(_translate("MainWindow", "00:00:00")) self.lblTOD.setText(_translate("MainWindow", "00:00:00"))
self.label_7.setText(_translate("MainWindow", "Fade length:"))
self.label_x_2.setText(_translate("MainWindow", "Start:"))
self.btnFade.setText(_translate("MainWindow", " Fade")) self.btnFade.setText(_translate("MainWindow", " Fade"))
self.label_start_time.setText(_translate("MainWindow", "00:00:00"))
self.label_end_time.setText(_translate("MainWindow", "00:00:00"))
self.label_x.setText(_translate("MainWindow", "Track length:"))
self.label_fade_length.setText(_translate("MainWindow", "0:00"))
self.label_8.setText(_translate("MainWindow", "End:"))
self.label_track_length.setText(_translate("MainWindow", "0:00"))
self.btnPreview.setText(_translate("MainWindow", " Preview")) self.btnPreview.setText(_translate("MainWindow", " Preview"))
self.label.setText(_translate("MainWindow", "Elapsed time")) self.label.setText(_translate("MainWindow", "Elapsed time"))
self.label_elapsed_timer.setText(_translate("MainWindow", "00:00")) self.label_elapsed_timer.setText(_translate("MainWindow", "00:00"))
@ -622,4 +664,3 @@ class Ui_MainWindow(object):
self.actionSearch_title_in_Songfacts.setText(_translate("MainWindow", "Search title in Songfacts")) self.actionSearch_title_in_Songfacts.setText(_translate("MainWindow", "Search title in Songfacts"))
self.actionSearch_title_in_Songfacts.setShortcut(_translate("MainWindow", "Ctrl+S")) self.actionSearch_title_in_Songfacts.setShortcut(_translate("MainWindow", "Ctrl+S"))
from infotabs import InfoTabs from infotabs import InfoTabs
from pyqtgraph import PlotWidget

55
poetry.lock generated
View File

@ -631,44 +631,6 @@ files = [
{file = "mysqlclient-2.1.1.tar.gz", hash = "sha256:828757e419fb11dd6c5ed2576ec92c3efaa93a0f7c39e263586d1ee779c3d782"}, {file = "mysqlclient-2.1.1.tar.gz", hash = "sha256:828757e419fb11dd6c5ed2576ec92c3efaa93a0f7c39e263586d1ee779c3d782"},
] ]
[[package]]
name = "numpy"
version = "1.24.3"
description = "Fundamental package for array computing in Python"
category = "main"
optional = false
python-versions = ">=3.8"
files = [
{file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"},
{file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"},
{file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"},
{file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"},
{file = "numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"},
{file = "numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"},
{file = "numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"},
{file = "numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"},
{file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"},
{file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"},
{file = "numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"},
{file = "numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"},
{file = "numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"},
{file = "numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"},
{file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"},
{file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"},
{file = "numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"},
{file = "numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"},
{file = "numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"},
{file = "numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"},
{file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"},
{file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"},
{file = "numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"},
{file = "numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"},
{file = "numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"},
{file = "numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"},
{file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"},
{file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"},
]
[[package]] [[package]]
name = "obsws-python" name = "obsws-python"
version = "1.4.2" version = "1.4.2"
@ -1172,21 +1134,6 @@ files = [
{file = "PyQt6_WebEngine_Qt6-6.5.0-py3-none-win_amd64.whl", hash = "sha256:5acadcc6608df8d9eba385e04ced2fc88e7eb92e366556ee4ac3c57a02c00088"}, {file = "PyQt6_WebEngine_Qt6-6.5.0-py3-none-win_amd64.whl", hash = "sha256:5acadcc6608df8d9eba385e04ced2fc88e7eb92e366556ee4ac3c57a02c00088"},
] ]
[[package]]
name = "pyqtgraph"
version = "0.13.3"
description = "Scientific Graphics and GUI Library for Python"
category = "main"
optional = false
python-versions = ">=3.8"
files = [
{file = "pyqtgraph-0.13.3-py3-none-any.whl", hash = "sha256:fdcc04ac4b32a7bedf1bf3cf74cbb93ab3ba5687791712bbfa8d0712377d2f2b"},
{file = "pyqtgraph-0.13.3.tar.gz", hash = "sha256:58108d8411c7054e0841d8b791ee85e101fc296b9b359c0e01dde38a98ff2ace"},
]
[package.dependencies]
numpy = ">=1.20.0"
[[package]] [[package]]
name = "pyqtwebengine" name = "pyqtwebengine"
version = "5.15.6" version = "5.15.6"
@ -1659,4 +1606,4 @@ test = ["websockets"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "e195143fc7756994b10a3c4472a17f2288829ebd6a75ef75f6b683905cb8a543" content-hash = "5b335197cebe3355472e3d0024a978e4853efce33802008987351b5196d8746d"

View File

@ -26,7 +26,6 @@ obsws-python = "^1.4.2"
pyqt6 = "^6.5.0" pyqt6 = "^6.5.0"
pyqt6-webengine = "^6.5.0" pyqt6-webengine = "^6.5.0"
pygame = "^2.4.0" pygame = "^2.4.0"
pyqtgraph = "^0.13.3"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
ipdb = "^0.13.9" ipdb = "^0.13.9"