continue fixing
This commit is contained in:
@@ -8,7 +8,8 @@ pip 安装依赖后即可直接播放视频。
|
||||
## 功能特性
|
||||
|
||||
- 播放 / 暂停 / 停止、上一首 / 下一首
|
||||
- 前进 / 后退(10 秒或 60 秒)与进度条点击拖动定位
|
||||
- 前进 / 后退(步长可自定义)与进度条点击拖动定位
|
||||
- 快进步长可在界面底部直接填写(1-600 秒),自动保存、下次启动自动加载
|
||||
- 音量调节、静音,0.5x - 2.0x 变速播放
|
||||
- 三种循环模式:关 / 单曲循环 / 列表循环
|
||||
- 播放列表管理(打开文件、打开文件夹、删除条目、双击播放)
|
||||
@@ -85,6 +86,10 @@ pip install -r requirements.txt
|
||||
播放列表保存在用户主目录的 `.mediaplayer_playlist.json` 中,删除该文件即可
|
||||
清除记忆。
|
||||
|
||||
界面底部的“快进步长”用于设置 `←` / `→` 每次跳转的秒数(`Shift+← / →` 固定为
|
||||
60 秒),输入后按回车或点击其他位置即生效并自动保存(配置文件:用户主目录下的
|
||||
`.mediaplayer_settings.json`)。
|
||||
|
||||
## 常见问题
|
||||
|
||||
- **状态栏显示“纯 Python 解码内核”**:说明未检测到 VLC,程序正在使用内置的
|
||||
|
||||
@@ -830,6 +830,7 @@ class MediaPlayerApp(tk.Tk):
|
||||
self.current_index = -1
|
||||
self.volume = 80
|
||||
self.rate = 1.0
|
||||
self.seek_step = self._load_settings()
|
||||
self.loop_mode = "list"
|
||||
self._seeking = False
|
||||
self._switching_until = 0.0
|
||||
@@ -951,19 +952,39 @@ class MediaPlayerApp(tk.Tk):
|
||||
self._playlist_menu.add_separator()
|
||||
self._playlist_menu.add_command(label="删除选中曲目", command=self.remove_selected)
|
||||
self._playlist_menu.add_command(label="清空播放列表", command=self.clear_playlist)
|
||||
self.listbox.bind("<Button-3>", self._show_playlist_menu)
|
||||
if IS_MAC:
|
||||
self.listbox.bind("<Button-2>", self._show_playlist_menu)
|
||||
self.listbox.bind("<Button-3>", self._show_playlist_menu)
|
||||
self.listbox.bind("<Control-Button-1>", self._show_playlist_menu)
|
||||
else:
|
||||
self.listbox.bind("<Button-3>", self._show_playlist_menu)
|
||||
|
||||
bottom = ttk.Frame(self, padding=(8, 6))
|
||||
bottom.pack(fill="x")
|
||||
self.seekbar = SeekBar(bottom, command=self._on_seek_command)
|
||||
self.seekbar.pack(fill="x")
|
||||
|
||||
controls = ttk.Frame(bottom)
|
||||
controls.pack(fill="x", pady=(4, 0))
|
||||
self.time_var = tk.StringVar(value="00:00 / --:--")
|
||||
self.status_var = tk.StringVar(value="就绪 — 打开文件或按 Ctrl+O")
|
||||
ttk.Label(bottom, textvariable=self.time_var).pack(side="left", anchor="w")
|
||||
ttk.Label(bottom, textvariable=self.status_var, anchor="e").pack(side="right", fill="x", expand=True)
|
||||
self.seek_step_var = tk.StringVar(value=str(self.seek_step))
|
||||
ttk.Label(controls, textvariable=self.time_var).pack(side="left", anchor="w")
|
||||
ttk.Label(controls, text="快进步长:").pack(side="left", padx=(16, 4))
|
||||
self.seek_step_spin = ttk.Spinbox(
|
||||
controls,
|
||||
from_=1,
|
||||
to=600,
|
||||
increment=1,
|
||||
width=5,
|
||||
textvariable=self.seek_step_var,
|
||||
command=self._commit_seek_step,
|
||||
)
|
||||
self.seek_step_spin.pack(side="left")
|
||||
ttk.Label(controls, text="秒").pack(side="left", padx=(4, 0))
|
||||
self.seek_step_spin.bind("<Return>", self._on_seek_step_return)
|
||||
self.seek_step_spin.bind("<FocusOut>", lambda _e: self._commit_seek_step())
|
||||
ttk.Label(controls, textvariable=self.status_var, anchor="e").pack(side="right", fill="x", expand=True)
|
||||
|
||||
def _bind_shortcuts(self):
|
||||
shortcuts = [
|
||||
@@ -1012,11 +1033,11 @@ class MediaPlayerApp(tk.Tk):
|
||||
return "break"
|
||||
|
||||
def _on_left(self, _event):
|
||||
self.seek_relative(-SEEK_STEP)
|
||||
self.seek_relative(-self.seek_step)
|
||||
return "break"
|
||||
|
||||
def _on_right(self, _event):
|
||||
self.seek_relative(SEEK_STEP)
|
||||
self.seek_relative(self.seek_step)
|
||||
return "break"
|
||||
|
||||
def _on_up(self, _event):
|
||||
@@ -1115,6 +1136,26 @@ class MediaPlayerApp(tk.Tk):
|
||||
def _playlist_path(self):
|
||||
return Path.home() / ".mediaplayer_playlist.json"
|
||||
|
||||
def _settings_path(self):
|
||||
return Path.home() / ".mediaplayer_settings.json"
|
||||
|
||||
def _load_settings(self):
|
||||
try:
|
||||
data = json.loads(self._settings_path().read_text(encoding="utf-8"))
|
||||
value = int(data.get("seek_step", SEEK_STEP))
|
||||
except Exception:
|
||||
value = SEEK_STEP
|
||||
return value if 1 <= value <= 600 else SEEK_STEP
|
||||
|
||||
def _save_settings(self):
|
||||
try:
|
||||
self._settings_path().write_text(
|
||||
json.dumps({"seek_step": self.seek_step}, ensure_ascii=False, indent=2),
|
||||
encoding="utf-8",
|
||||
)
|
||||
except Exception as exc:
|
||||
print("保存设置失败:", exc)
|
||||
|
||||
def _save_playlist(self):
|
||||
try:
|
||||
data = {"playlist": list(self.playlist), "current_index": self.current_index}
|
||||
@@ -1225,6 +1266,26 @@ class MediaPlayerApp(tk.Tk):
|
||||
return
|
||||
self.seek_to(pos + seconds * 1000)
|
||||
|
||||
def _commit_seek_step(self):
|
||||
raw = self.seek_step_var.get().strip()
|
||||
try:
|
||||
value = int(float(raw))
|
||||
except ValueError:
|
||||
value = 0
|
||||
if not 1 <= value <= 600:
|
||||
self.seek_step_var.set(str(self.seek_step))
|
||||
self.status_var.set("快进步长需为 1-600 之间的整数")
|
||||
return
|
||||
if value != self.seek_step:
|
||||
self.seek_step = value
|
||||
self._save_settings()
|
||||
self.status_var.set(f"快进步长已设为 {value} 秒(已保存)")
|
||||
|
||||
def _on_seek_step_return(self, _event):
|
||||
self._commit_seek_step()
|
||||
self.focus_set()
|
||||
return "break"
|
||||
|
||||
def seek_to(self, ms):
|
||||
ms = max(0, int(ms))
|
||||
if not self.engine.seek(ms):
|
||||
|
||||
Reference in New Issue
Block a user