cleaning up, preparing for windows tests
This commit is contained in:
parent
e7b895888b
commit
55bedf7aa3
8 changed files with 35 additions and 140 deletions
|
@ -42,8 +42,8 @@ pymediainfo = { version = "^6.1.0", optional = true }
|
|||
pyyaml = { version = "^6.0.1", optional = true }
|
||||
alt-profanity-check = {version = "^1.4.1", optional = true}
|
||||
pyqt6 = {version="^6.7.1", optional = true}
|
||||
mpv = "^1.0.7"
|
||||
qasync = "^0.27.1"
|
||||
mpv = {version = "^1.0.7", optional = true}
|
||||
qasync = {version = "^0.27.1", optional = true}
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
types-pyyaml = "^6.0.12.12"
|
||||
|
|
|
@ -5,10 +5,13 @@ mkdir -p requirements
|
|||
cd requirements
|
||||
|
||||
# download mpv
|
||||
wget https://nightly.link/mpv-player/mpv/workflows/build/master/mpv-x86_64-windows-msvc.zip
|
||||
unzip mpv-x86_64-windows-msvc.zip
|
||||
cp mpv.exe ../src
|
||||
cp vulkan-1.dll ../src
|
||||
# wget https://nightly.link/mpv-player/mpv/workflows/build/master/mpv-x86_64-windows-msvc.zip
|
||||
# unzip mpv-x86_64-windows-msvc.zip
|
||||
# cp mpv.exe ../src
|
||||
# cp vulkan-1.dll ../src
|
||||
wget https://github.com/shinchiro/mpv-winbuild-cmake/releases/download/20241118/mpv-dev-x86_64-20241118-git-e8fd7b8.7z
|
||||
7z x mpv-dev-x86_64-20241118-git-e8fd7b8.7z
|
||||
cp libmpv-2.dll ../src
|
||||
|
||||
# download ffmpeg
|
||||
wget https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z
|
||||
|
@ -27,7 +30,7 @@ cp ../icons/syng.ico src/
|
|||
# rm -rf src/build
|
||||
# rm -rf src/dist
|
||||
# docker run --volume "$(pwd)/src:/src/" batonogov/pyinstaller-windows:latest "pyinstaller --onefile -w -i'.\syng.ico' --add-data='.\syng\static\syng.png;.\static' --add-binary '.\mpv.exe;.' --add-binary '.\vulkan-1.dll;.' --add-binary '.\ffmpeg.exe;.' syng/main.py"
|
||||
docker run --volume "$(pwd)/src:/src/" batonogov/pyinstaller-windows:latest "pyinstaller -F -w -i'.\syng.ico' --add-data='.\syng.ico;.' --add-binary '.\mpv.exe;.' --add-binary '.\vulkan-1.dll;.' --add-binary '.\ffmpeg.exe;.' syng/main.py"
|
||||
docker run --volume "$(pwd)/src:/src/" batonogov/pyinstaller-windows:latest "pyinstaller -w -i'.\syng.ico' --add-data='.\syng.ico;.' --add-binary '.\libmpv-2.dll;.' --add-binary '.\ffmpeg.exe;.' syng/main.py"
|
||||
|
||||
# cd syng-2.0.1
|
||||
# wine python -m poetry install -E client
|
||||
|
|
|
@ -21,7 +21,6 @@ from logging.handlers import QueueHandler
|
|||
from multiprocessing import Queue
|
||||
import secrets
|
||||
import string
|
||||
import tempfile
|
||||
import signal
|
||||
from argparse import Namespace
|
||||
from dataclasses import dataclass
|
||||
|
@ -35,7 +34,6 @@ from qrcode.main import QRCode
|
|||
import socketio
|
||||
from socketio.exceptions import ConnectionError
|
||||
import engineio
|
||||
from PIL import Image
|
||||
from yaml import load, Loader
|
||||
|
||||
from syng.player_libmpv import Player
|
||||
|
|
69
syng/gui.py
69
syng/gui.py
|
@ -5,7 +5,6 @@ import logging
|
|||
from logging.handlers import QueueListener
|
||||
from logging.handlers import QueueHandler
|
||||
|
||||
# from multiprocessing import Process, Queue
|
||||
from queue import Queue
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime
|
||||
|
@ -13,7 +12,6 @@ import os
|
|||
from functools import partial
|
||||
import random
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
import threading
|
||||
import secrets
|
||||
import string
|
||||
import signal
|
||||
|
@ -32,7 +30,6 @@ from qasync import QEventLoop, QApplication
|
|||
from PyQt6.QtCore import QTimer, Qt
|
||||
from PyQt6.QtGui import QCloseEvent, QIcon, QPixmap
|
||||
from PyQt6.QtWidgets import (
|
||||
# QApplication,
|
||||
QCheckBox,
|
||||
QComboBox,
|
||||
QDateTimeEdit,
|
||||
|
@ -58,7 +55,7 @@ from qrcode.main import QRCode
|
|||
import platformdirs
|
||||
|
||||
from . import resources # noqa
|
||||
from .client import Client, create_async_and_start_client, default_config
|
||||
from .client import Client, default_config
|
||||
from .log import logger
|
||||
|
||||
from .sources import available_sources
|
||||
|
@ -73,16 +70,6 @@ from .config import (
|
|||
StrOption,
|
||||
)
|
||||
|
||||
# try:
|
||||
# from .server import run_server
|
||||
#
|
||||
# SERVER_AVAILABLE = True
|
||||
# except ImportError:
|
||||
# if TYPE_CHECKING:
|
||||
# from .server import run_server
|
||||
#
|
||||
# SERVER_AVAILABLE = False
|
||||
|
||||
|
||||
# TODO: ScrollableFrame
|
||||
class OptionFrame(QWidget):
|
||||
|
@ -482,14 +469,8 @@ class GeneralConfig(OptionFrame):
|
|||
|
||||
class SyngGui(QMainWindow):
|
||||
def closeEvent(self, a0: Optional[QCloseEvent]) -> None:
|
||||
# if self.syng_server is not None:
|
||||
# self.syng_server.kill()
|
||||
# self.syng_server.join()
|
||||
|
||||
# if self.syng_client is not None:
|
||||
# self.syng_client.terminate()
|
||||
# self.syng_client.join(1.0)
|
||||
# self.syng_client.kill()
|
||||
if self.client is not None:
|
||||
self.client.quit_callback()
|
||||
|
||||
self.destroy()
|
||||
|
||||
|
@ -497,10 +478,6 @@ class SyngGui(QMainWindow):
|
|||
self.buttons_layout = QHBoxLayout()
|
||||
self.central_layout.addLayout(self.buttons_layout)
|
||||
|
||||
# self.startsyng_serverbutton = QPushButton("Start Local Server")
|
||||
# self.startsyng_serverbutton.clicked.connect(self.start_syng_server)
|
||||
# self.buttons_layout.addWidget(self.startsyng_serverbutton)
|
||||
|
||||
self.resetbutton = QPushButton("Set Config to Default")
|
||||
self.exportbutton = QPushButton("Export Config")
|
||||
self.importbutton = QPushButton("Import Config")
|
||||
|
@ -521,11 +498,7 @@ class SyngGui(QMainWindow):
|
|||
self.buttons_layout.addWidget(self.show_advanced_toggle)
|
||||
|
||||
spacer_item = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
||||
# self.notification_label = QLabel("", self)
|
||||
# spacer_item2 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
||||
self.buttons_layout.addItem(spacer_item)
|
||||
# self.buttons_layout.addWidget(self.notification_label)
|
||||
# self.buttons_layout.addItem(spacer_item2)
|
||||
|
||||
self.savebutton = QPushButton("Save")
|
||||
self.savebutton.clicked.connect(self.save_config)
|
||||
|
@ -632,8 +605,6 @@ class SyngGui(QMainWindow):
|
|||
self.setWindowIcon(QIcon(":/icons/syng.ico"))
|
||||
|
||||
self.loop = asyncio.get_event_loop()
|
||||
# self.syng_server: Optional[threading.Thread] = None
|
||||
# self.syng_client: Optional[threading.Thread] = None
|
||||
self.client: Optional[Client] = None
|
||||
self.syng_client_logging_listener: Optional[QueueListener] = None
|
||||
|
||||
|
@ -658,7 +629,6 @@ class SyngGui(QMainWindow):
|
|||
|
||||
self.setCentralWidget(self.central_widget)
|
||||
|
||||
# check every 500 ms if client is running
|
||||
self.timer = QTimer()
|
||||
self.timer.timeout.connect(self.check_if_client_is_running)
|
||||
|
||||
|
@ -781,48 +751,16 @@ class SyngGui(QMainWindow):
|
|||
)
|
||||
self.syng_client_logging_listener.start()
|
||||
|
||||
# self.syng_client = multiprocessing.Process(
|
||||
# target=create_async_and_start_client, args=[config, queue]
|
||||
# )
|
||||
logger.addHandler(QueueHandler(queue))
|
||||
self.client = Client(config)
|
||||
asyncio.run_coroutine_threadsafe(self.client.start_client(config), self.loop)
|
||||
# self.syng_client = threading.Thread(
|
||||
# target=create_async_and_start_client, args=[config, queue, self.client]
|
||||
# )
|
||||
# self.syng_client.start()
|
||||
self.notification_label.setText("")
|
||||
self.timer.start(500)
|
||||
self.set_client_button_stop()
|
||||
else:
|
||||
self.client.quit_callback()
|
||||
# self.syng_client.join(1.0)
|
||||
self.set_client_button_start()
|
||||
|
||||
# def start_syng_server(self) -> None:
|
||||
# if self.syng_server is None:
|
||||
# root_path = os.path.join(os.path.dirname(__file__), "static")
|
||||
# self.syng_server = multiprocessing.Process(
|
||||
# target=run_server,
|
||||
# args=[
|
||||
# Namespace(
|
||||
# host="0.0.0.0",
|
||||
# port=8080,
|
||||
# registration_keyfile=None,
|
||||
# root_folder=root_path,
|
||||
# private=False,
|
||||
# restricted=False,
|
||||
# )
|
||||
# ],
|
||||
# )
|
||||
# self.syng_server.start()
|
||||
# self.startsyng_serverbutton.setText("Stop Local Server")
|
||||
# else:
|
||||
# self.syng_server.terminate()
|
||||
# self.syng_server.join()
|
||||
# self.syng_server = None
|
||||
# self.startsyng_serverbutton.setText("Start Local Server")
|
||||
|
||||
def change_qr(self, data: str) -> None:
|
||||
qr = QRCode(box_size=10, border=2)
|
||||
qr.add_data(data)
|
||||
|
@ -876,7 +814,6 @@ def run_gui() -> None:
|
|||
app.setDesktopFileName("rocks.syng.Syng")
|
||||
window = SyngGui()
|
||||
window.show()
|
||||
# app.exec()
|
||||
with event_loop:
|
||||
event_loop.run_forever()
|
||||
|
||||
|
|
|
@ -477,8 +477,8 @@ class Server:
|
|||
"source": data["source"],
|
||||
"performer": data["performer"],
|
||||
"ident": data["ident"],
|
||||
"artist": data["artist"],
|
||||
"title": data["title"],
|
||||
"artist": data.get("artist", None),
|
||||
"title": data.get("title", None),
|
||||
},
|
||||
"old_entry": {
|
||||
"artist": old_entry.artist,
|
||||
|
@ -493,7 +493,10 @@ class Server:
|
|||
source_obj = state.client.sources[data["source"]]
|
||||
|
||||
entry = await source_obj.get_entry(
|
||||
data["performer"], data["ident"], artist=data["artist"], title=data["title"]
|
||||
data["performer"],
|
||||
data["ident"],
|
||||
artist=data.get("artist", None),
|
||||
title=data.get("title", None),
|
||||
)
|
||||
|
||||
if entry is None:
|
||||
|
|
|
@ -127,40 +127,11 @@ class Source(ABC):
|
|||
"""
|
||||
self.downloaded_files: defaultdict[str, DLFilesEntry] = defaultdict(DLFilesEntry)
|
||||
self._masterlock: asyncio.Lock = asyncio.Lock()
|
||||
# self.player: Optional[asyncio.subprocess.Process] = None
|
||||
self._index: list[str] = config["index"] if "index" in config else []
|
||||
self.extra_mpv_arguments: list[str] = []
|
||||
self.extra_mpv_options: dict[str, str] = {}
|
||||
self._skip_next = False
|
||||
|
||||
@staticmethod
|
||||
async def play_mpv(
|
||||
video: str, audio: Optional[str], /, *options: str
|
||||
) -> asyncio.subprocess.Process:
|
||||
"""
|
||||
Create a mpv process to play a song in full screen.
|
||||
|
||||
:param video: Location of the video part.
|
||||
:type video: str
|
||||
:param audio: Location of the audio part, if it exists.
|
||||
:type audio: Optional[str]
|
||||
:param options: Extra arguments forwarded to the mpv player
|
||||
:type options: str
|
||||
:returns: An async reference to the process
|
||||
:rtype: asyncio.subprocess.Process
|
||||
"""
|
||||
args = ["--fullscreen", *options, video] + ([f"--audio-file={audio}"] if audio else [])
|
||||
|
||||
# print(f"File is {video=} and {audio=}")
|
||||
|
||||
mpv_process = asyncio.create_subprocess_exec(
|
||||
"mpv",
|
||||
*args,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
return await mpv_process
|
||||
|
||||
async def get_entry(
|
||||
self,
|
||||
performer: str,
|
||||
|
@ -299,22 +270,10 @@ class Source(ABC):
|
|||
entry.skip = True
|
||||
return
|
||||
|
||||
extra_options = (
|
||||
(self.extra_mpv_arguments + [mpv_options])
|
||||
if mpv_options
|
||||
else self.extra_mpv_arguments
|
||||
)
|
||||
|
||||
# self.player = await self.play_mpv(
|
||||
# self.downloaded_files[entry.ident].video,
|
||||
# self.downloaded_files[entry.ident].audio,
|
||||
# *extra_options,
|
||||
# )
|
||||
await player.play(
|
||||
self.downloaded_files[entry.ident].video, self.downloaded_files[entry.ident].audio
|
||||
)
|
||||
# await self.player.wait()
|
||||
# self.player = None
|
||||
|
||||
if self._skip_next:
|
||||
self._skip_next = False
|
||||
entry.skip = True
|
||||
|
@ -339,9 +298,6 @@ class Source(ABC):
|
|||
buffer_task.cancel()
|
||||
self.downloaded_files[entry.ident].ready.set()
|
||||
|
||||
# if self.player is not None:
|
||||
# self.player.kill()
|
||||
|
||||
async def ensure_playable(self, entry: Entry) -> tuple[str, Optional[str]]:
|
||||
"""
|
||||
Guaranties that the given entry can be played.
|
||||
|
|
|
@ -103,12 +103,6 @@ class YouTube:
|
|||
:type search_result: dict[str, Any]
|
||||
"""
|
||||
url = search_result["url"]
|
||||
# cls.__cache__[url] = {
|
||||
# "duration": int(search_result["duration"]),
|
||||
# "title": search_result["title"],
|
||||
# "channel": search_result["channel"],
|
||||
# "url": url,
|
||||
# }
|
||||
return cls(url, info=search_result)
|
||||
|
||||
|
||||
|
@ -255,15 +249,6 @@ class YoutubeSource(Source):
|
|||
:rtype: None
|
||||
"""
|
||||
if self.start_streaming and not self.downloaded_files[entry.ident].complete:
|
||||
# self.player = await self.play_mpv(
|
||||
# entry.ident,
|
||||
# None,
|
||||
# "--script-opts=ytdl_hook-ytdl_path=yt-dlp,ytdl_hook-exclude='%.pls$'",
|
||||
# f"--ytdl-format={self.formatstring}",
|
||||
# "--fullscreen",
|
||||
# mpv_options,
|
||||
# )
|
||||
# await self.player.wait()
|
||||
await player.play(entry.ident)
|
||||
else:
|
||||
await super().play(entry, player, mpv_options)
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
from asyncio import AbstractEventLoop
|
||||
from types import TracebackType
|
||||
from typing import Optional
|
||||
import PyQt6.QtWidgets
|
||||
from asyncio import BaseEventLoop
|
||||
|
||||
class QApplication:
|
||||
class QApplication(PyQt6.QtWidgets.QApplication):
|
||||
def __init__(self, argv: list[str]) -> None: ...
|
||||
|
||||
class QEventLoop(BaseEventLoop):
|
||||
def __init__(self, app: QApplication) -> None: ...
|
||||
def __enter__(self) -> None: ...
|
||||
def __exit__(
|
||||
self,
|
||||
exc_type: Optional[type[BaseException]],
|
||||
exc_value: Optional[BaseException],
|
||||
traceback: Optional[TracebackType],
|
||||
) -> None: ...
|
||||
|
|
Loading…
Add table
Reference in a new issue