added some media keys

This commit is contained in:
JISAUAY committed 2025-10-02 14:54:35 -05:00
1 parent 14ac9b197d
commit 6d37093b26
2 files changed
+82 -10

No files matched your search

+81 -10
View File
@@ -1,3 +1,4 @@
import multiprocessing
import configparser
import logging
import asyncio
@@ -11,10 +12,6 @@ LOG_FILE = 'textual.log'
LOGGING_LEVEL = logging.DEBUG
LOG_FORMAT = '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
# Clear Log File
if os.path.exists(LOG_FILE):
os.remove(LOG_FILE)
# Read config file
config = configparser.ConfigParser()
config.read('config.ini')
@@ -25,16 +22,11 @@ BITRATE = re.findall(r'[0-9]+', BITRATE)[0]
BITRATE = int(BITRATE) if BITRATE else BITRATE
IMAGE_MODE = config.getboolean('GENERAL', 'GUI')
os.makedirs(".cache/art/", exist_ok=True)
os.makedirs(".cache/audio/", exist_ok=True)
os.makedirs(".cache/art/artists/", exist_ok=True)
logging.basicConfig(filename=LOG_FILE, level=LOGGING_LEVEL, format=LOG_FORMAT)
import SubSonic
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame
import pynput
from rich.text import Text
@@ -967,6 +959,45 @@ class MainView(Screen):
queue_table.update_queue()
app.update_now_playing()
# Startup keyboard listener for media keys
def listen_media_keys(queue: multiprocessing.Queue):
media_log_file = 'media_keys.log'
logger = logging.getLogger('media_keys')
logger.setLevel(LOGGING_LEVEL)
formatter = logging.Formatter('[%(asctime)s] %(levelname)s in %(module)s: %(message)s')
handler = logging.FileHandler(media_log_file)
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info('media_key logger initialized')
try:
def on_press(key: pynput.keyboard.Key | pynput.keyboard.KeyCode | None) -> None:
logger.debug(f'Process Key: {key}')
match key:
case pynput.keyboard.Key.media_play_pause:
logger.info('Media play/pause key pressed')
queue.put('play_pause')
case pynput.keyboard.Key.media_next:
logger.info('Media next key pressed')
queue.put('next')
case pynput.keyboard.Key.media_previous:
logger.info('Media rewind pressed')
queue.put('prev')
case pynput.keyboard.Key.media_volume_down:
logger.info('Media volume down')
queue.put('vdown')
case pynput.keyboard.Key.media_volume_up:
logger.info('Media volume up')
queue.put('udown')
with pynput.keyboard.Listener(on_press=on_press) as listener:
logger.info('Media key listener started')
listener.join()
except Exception as e:
pass
logger.error(f'Media key listener failed: {e}')
class TextualSubpyPlayer(App):
BINDINGS = [
("r", "rewind()", "⏪"),
@@ -998,12 +1029,17 @@ class TextualSubpyPlayer(App):
is_paused: bool = False
place: int = 0
music_command_queue: multiprocessing.Queue
check_playing_timer: Timer | None = None
check_music_commands: Timer
def on_mount(self) -> None:
self.title = "SubPy"
self.switch_mode('main')
self.check_music_commands = self.set_interval(2/3, self._music_player_loop, pause=False)
@work(exclusive=True)
async def play_song(self, song: SubSonic.Song) -> None:
self.currently_playing = song
@@ -1051,6 +1087,24 @@ class TextualSubpyPlayer(App):
# Set callback loop for progress bar
# self.progress_timer = self.set_interval(1 / 10, self.update_progress, pause=False)
def _music_player_loop(self) -> None:
if self.music_command_queue.empty():
return
command = self.music_command_queue.get_nowait()
match command:
case "play_pause":
self.action_play_pause_song()
case "next":
self.action_skip()
case "prev":
self.action_rewind()
case "vdown":
self.action_volume_down()
case "udown":
self.action_volume_up()
def _cache_audio(self, path: str, content: bytes) -> None:
"""Helper method to write audio to cache."""
with open(path, "wb") as file:
@@ -1168,5 +1222,22 @@ class TextualSubpyPlayer(App):
logging.debug(event.key)
if __name__ == '__main__':
os.makedirs(".cache/art/", exist_ok=True)
os.makedirs(".cache/audio/", exist_ok=True)
os.makedirs(".cache/art/artists/", exist_ok=True)
# Clear Log File
if os.path.exists(LOG_FILE):
os.remove(LOG_FILE)
logging.basicConfig(filename=LOG_FILE, level=LOGGING_LEVEL, format=LOG_FORMAT)
q = multiprocessing.Queue(-1)
p = multiprocessing.Process(target=listen_media_keys, args=(q,))
p.start()
app = TextualSubpyPlayer()
app.music_command_queue = q
app.run()
p.terminate()