mytunes-pro 2.1.4__py3-none-any.whl → 2.1.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mytunes/app.py +47 -5
- {mytunes_pro-2.1.4.dist-info → mytunes_pro-2.1.5.dist-info}/METADATA +9 -4
- mytunes_pro-2.1.5.dist-info/RECORD +8 -0
- mytunes_pro-2.1.4.dist-info/RECORD +0 -8
- {mytunes_pro-2.1.4.dist-info → mytunes_pro-2.1.5.dist-info}/WHEEL +0 -0
- {mytunes_pro-2.1.4.dist-info → mytunes_pro-2.1.5.dist-info}/entry_points.txt +0 -0
- {mytunes_pro-2.1.4.dist-info → mytunes_pro-2.1.5.dist-info}/licenses/LICENSE +0 -0
- {mytunes_pro-2.1.4.dist-info → mytunes_pro-2.1.5.dist-info}/top_level.txt +0 -0
mytunes/app.py
CHANGED
|
@@ -44,7 +44,7 @@ MPV_SOCKET = "/tmp/mpv_socket"
|
|
|
44
44
|
LOG_FILE = "/tmp/mytunes_mpv.log"
|
|
45
45
|
PID_FILE = "/tmp/mytunes_mpv.pid"
|
|
46
46
|
APP_NAME = "MyTunes Pro"
|
|
47
|
-
APP_VERSION = "2.1.
|
|
47
|
+
APP_VERSION = "2.1.5"
|
|
48
48
|
|
|
49
49
|
# Initial Locale Setup for WSL/Windows Multibyte/Emoji Harmony
|
|
50
50
|
try:
|
|
@@ -336,7 +336,7 @@ class Player:
|
|
|
336
336
|
subprocess.run(["pkill", "-f", "mpv --video=no"], stderr=subprocess.DEVNULL)
|
|
337
337
|
except: pass
|
|
338
338
|
|
|
339
|
-
def play(self, url, start_pos=0, initial_eq_preset="Flat"):
|
|
339
|
+
def play(self, url, start_pos=0, initial_eq_preset="Flat", initial_volume=100):
|
|
340
340
|
# 1. Try to reuse existing instance via IPC (Graceful)
|
|
341
341
|
if os.path.exists(MPV_SOCKET):
|
|
342
342
|
try:
|
|
@@ -349,6 +349,9 @@ class Player:
|
|
|
349
349
|
# Apply EQ immediately for reused instance
|
|
350
350
|
if initial_eq_preset and initial_eq_preset != "Flat":
|
|
351
351
|
self.set_equalizer(initial_eq_preset)
|
|
352
|
+
|
|
353
|
+
# Apply Volume for reused instance
|
|
354
|
+
self.send_cmd(["set_property", "volume", initial_volume])
|
|
352
355
|
|
|
353
356
|
self.loading = True
|
|
354
357
|
self.loading_ts = time.time()
|
|
@@ -374,6 +377,7 @@ class Player:
|
|
|
374
377
|
"mpv", "--video=no", "--vo=null", "--force-window=no",
|
|
375
378
|
"--audio-display=no", "--no-config",
|
|
376
379
|
f"--input-ipc-server={MPV_SOCKET}",
|
|
380
|
+
f"--volume={initial_volume}",
|
|
377
381
|
"--idle=yes"
|
|
378
382
|
]
|
|
379
383
|
|
|
@@ -444,6 +448,7 @@ class Player:
|
|
|
444
448
|
|
|
445
449
|
def change_volume(self, delta):
|
|
446
450
|
self.send_cmd(["add", "volume", delta])
|
|
451
|
+
return self.get_property("volume")
|
|
447
452
|
|
|
448
453
|
def send_cmd(self, command):
|
|
449
454
|
"""Send raw command list to MPV via JSON IPC with resilience."""
|
|
@@ -609,6 +614,10 @@ class MyTunesApp:
|
|
|
609
614
|
|
|
610
615
|
|
|
611
616
|
self.sent_history = {}
|
|
617
|
+
|
|
618
|
+
# Volume Control (Persisted)
|
|
619
|
+
self.volume = self.dm.data.get("volume", 100)
|
|
620
|
+
|
|
612
621
|
|
|
613
622
|
|
|
614
623
|
def show_feedback(self, msg, duration=2.5):
|
|
@@ -731,6 +740,12 @@ class MyTunesApp:
|
|
|
731
740
|
|
|
732
741
|
# Periodic Save (Throttle 10s)
|
|
733
742
|
if time.time() - getattr(self, 'last_save_time', 0) > 10:
|
|
743
|
+
# Sync volume if playing (in case changed externally/via scripts)
|
|
744
|
+
v = self.player.get_property("volume")
|
|
745
|
+
if v is not None:
|
|
746
|
+
self.volume = int(float(v))
|
|
747
|
+
self.dm.data["volume"] = self.volume
|
|
748
|
+
|
|
734
749
|
self.dm.save_data()
|
|
735
750
|
self.last_save_time = time.time()
|
|
736
751
|
|
|
@@ -864,8 +879,35 @@ class MyTunesApp:
|
|
|
864
879
|
self.forward_stack = []; self.view_stack = ["main"]; self.selection_idx = 0; self.scroll_offset = 0; self.set_view_status("")
|
|
865
880
|
|
|
866
881
|
elif cmd == "TOGGLE_PAUSE": self.player.toggle_pause()
|
|
867
|
-
elif cmd == "VOL_DOWN":
|
|
868
|
-
|
|
882
|
+
elif cmd == "VOL_DOWN":
|
|
883
|
+
if self.player.socket_ok and self.player.current_proc:
|
|
884
|
+
vol = self.player.change_volume(-5)
|
|
885
|
+
if vol is not None: self.volume = int(vol)
|
|
886
|
+
else:
|
|
887
|
+
self.volume = max(0, self.volume - 5)
|
|
888
|
+
|
|
889
|
+
# Persist
|
|
890
|
+
self.dm.data["volume"] = self.volume
|
|
891
|
+
self.dm.save_data()
|
|
892
|
+
|
|
893
|
+
msg = self.t("vol_fmt", self.volume)
|
|
894
|
+
if self.volume > 100: msg += " (Boost)"
|
|
895
|
+
self.show_feedback(msg)
|
|
896
|
+
|
|
897
|
+
elif cmd == "VOL_UP":
|
|
898
|
+
if self.player.socket_ok and self.player.current_proc:
|
|
899
|
+
vol = self.player.change_volume(5)
|
|
900
|
+
if vol is not None: self.volume = int(vol)
|
|
901
|
+
else:
|
|
902
|
+
self.volume = min(130, self.volume + 5)
|
|
903
|
+
|
|
904
|
+
# Persist
|
|
905
|
+
self.dm.data["volume"] = self.volume
|
|
906
|
+
self.dm.save_data()
|
|
907
|
+
|
|
908
|
+
msg = self.t("vol_fmt", self.volume)
|
|
909
|
+
if self.volume > 100: msg += " (Boost)"
|
|
910
|
+
self.show_feedback(msg)
|
|
869
911
|
elif cmd == "SEEK_BACK_10": self.player.seek(-10)
|
|
870
912
|
elif cmd == "SEEK_FWD_10": self.player.seek(10)
|
|
871
913
|
elif cmd == "SEEK_BACK_30": self.player.seek(-30); self.show_feedback("Rewind 30s")
|
|
@@ -1193,7 +1235,7 @@ class MyTunesApp:
|
|
|
1193
1235
|
else:
|
|
1194
1236
|
start_pos = 0
|
|
1195
1237
|
|
|
1196
|
-
self.player.play(item['url'], start_pos, initial_eq_preset=target_eq_preset)
|
|
1238
|
+
self.player.play(item['url'], start_pos, initial_eq_preset=target_eq_preset, initial_volume=self.volume)
|
|
1197
1239
|
|
|
1198
1240
|
# Re-apply EQ logic (double check: mpv restart wipes af property?)
|
|
1199
1241
|
# Yes, play() might restart mpv if socket fails.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mytunes-pro
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.5
|
|
4
4
|
Summary: A lightweight, keyboard-centric terminal player for streaming YouTube music.
|
|
5
5
|
Author-email: loxo <loxo5432@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/postgresql-co-kr/mytunes
|
|
@@ -18,9 +18,9 @@ Requires-Dist: yt-dlp
|
|
|
18
18
|
Requires-Dist: pusher
|
|
19
19
|
Dynamic: license-file
|
|
20
20
|
|
|
21
|
-
# 🎵 MyTunes Pro - Professional TUI Edition v2.1.
|
|
21
|
+
# 🎵 MyTunes Pro - Professional TUI Edition v2.1.5
|
|
22
22
|
|
|
23
|
-
## 🚀 Terminal-based Media Workflow Experiment v2.1.
|
|
23
|
+
## 🚀 Terminal-based Media Workflow Experiment v2.1.5
|
|
24
24
|
|
|
25
25
|
> [!IMPORTANT]
|
|
26
26
|
> **Legal Disclaimer:** This project is a personal, non-commercial research experiment for developer education.
|
|
@@ -216,7 +216,7 @@ Executes immediately without worrying about input language status.
|
|
|
216
216
|
|
|
217
217
|
# 🎵 MyTunes Pro (Experimental Media Tool - KR)
|
|
218
218
|
|
|
219
|
-
## 🚀 터미널 기반 미디어 워크플로우 실험 v2.1.
|
|
219
|
+
## 🚀 터미널 기반 미디어 워크플로우 실험 v2.1.5
|
|
220
220
|
|
|
221
221
|
> [!IMPORTANT]
|
|
222
222
|
> **법적 면책 고지:** 본 프로젝트는 개발자 교육 및 연구를 목적으로 하는 개인적, 비상업적 실험입니다.
|
|
@@ -390,6 +390,11 @@ Windows 환경에서 한글 검색이 안 되거나 설치가 어려운 분들
|
|
|
390
390
|
|
|
391
391
|
## 🔄 Changelog
|
|
392
392
|
|
|
393
|
+
### v2.1.5 (2026-02-04)
|
|
394
|
+
- **Absolute Volume Display**: Now displays volume as a precise percentage (0-100%) with a "(Boost)" indicator for levels above 100%.
|
|
395
|
+
- **Volume Persistence**: Volume level is now permanently saved and restored across app restarts.
|
|
396
|
+
- **Offline Control**: Adjust volume levels globally even when the player is stopped; changes apply immediately upon next playback.
|
|
397
|
+
|
|
393
398
|
### v2.1.4 (2026-02-03)
|
|
394
399
|
- **Mouse Support Removed**: Reverted to pure keyboard interface for cleaner experience.
|
|
395
400
|
- **Bug Fixes**: Resolved IndentationError and key loop crashes.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
mytunes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
mytunes/app.py,sha256=FqN582fRha0aEnRgT9MOkWp98RC7Jf34kJRqYG4doII,85298
|
|
3
|
+
mytunes_pro-2.1.5.dist-info/licenses/LICENSE,sha256=lOrP0EIjxcgJia__W3f3PVDZkRd2oRzFkyH2g3LRRCg,1063
|
|
4
|
+
mytunes_pro-2.1.5.dist-info/METADATA,sha256=L7lAo7YVBmrrKP8NT-s7rd0qfxknCisRqxQdOVSoYCs,31378
|
|
5
|
+
mytunes_pro-2.1.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
6
|
+
mytunes_pro-2.1.5.dist-info/entry_points.txt,sha256=6-MsC13nIgzLvrREaGotc32FgxHx_Iuu1z2qCzJs1_4,65
|
|
7
|
+
mytunes_pro-2.1.5.dist-info/top_level.txt,sha256=KWzdFyNNG_sO7GT83-sN5fYArP4_DL5I8HYIwgazXyY,8
|
|
8
|
+
mytunes_pro-2.1.5.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
mytunes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
mytunes/app.py,sha256=2EAFeMB4j-7EZAe3vaRGbkjZd5qzcYvFxlyDzKzI8FM,83690
|
|
3
|
-
mytunes_pro-2.1.4.dist-info/licenses/LICENSE,sha256=lOrP0EIjxcgJia__W3f3PVDZkRd2oRzFkyH2g3LRRCg,1063
|
|
4
|
-
mytunes_pro-2.1.4.dist-info/METADATA,sha256=kUyvNfHdHKX7_mrkme6WQ33D4oUKXX6-SOqZlEv7nEE,30989
|
|
5
|
-
mytunes_pro-2.1.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
6
|
-
mytunes_pro-2.1.4.dist-info/entry_points.txt,sha256=6-MsC13nIgzLvrREaGotc32FgxHx_Iuu1z2qCzJs1_4,65
|
|
7
|
-
mytunes_pro-2.1.4.dist-info/top_level.txt,sha256=KWzdFyNNG_sO7GT83-sN5fYArP4_DL5I8HYIwgazXyY,8
|
|
8
|
-
mytunes_pro-2.1.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|