以下は『音律魔装《冥響輪舞》』のソースコード全文です:
import tkinter as tk
from tkinter import filedialog, messagebox
import pygame.mixer
import time
import threading
class MusicPlayer:
def __init__(self, root):
self.root = root
self.root.title("音楽プレイヤー - 音律魔装《冥響輪舞》")
pygame.mixer.init()
self.file_path = ""
self.play_count = 1
self.current_play = 0
self.is_playing = False
self.is_paused = False
self.pause_pos = 0 # 一時停止位置を記録
self.label = tk.Label(root, text="音楽ファイルを選択してください", font=("Arial", 12))
self.label.pack(pady=10)
self.select_button = tk.Button(root, text="ファイルを選択", command=self.load_file)
self.select_button.pack()
self.count_label = tk.Label(root, text="再生回数 (1-100):")
self.count_label.pack()
self.count_entry = tk.Entry(root)
self.count_entry.pack()
self.count_entry.insert(0, "1")
self.play_button = tk.Button(root, text="再生", command=self.start_playback)
self.play_button.pack()
self.pause_button = tk.Button(root, text="一時停止", command=self.pause_music, state=tk.DISABLED)
self.pause_button.pack()
self.stop_button = tk.Button(root, text="再生終了", command=self.stop_playback, state=tk.DISABLED)
self.stop_button.pack()
self.status_label = tk.Label(root, text="", font=("Arial", 12))
self.status_label.pack(pady=10)
# ウィンドウを閉じる処理を追加
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
def load_file(self):
self.file_path = filedialog.askopenfilename(filetypes=[("Audio Files", "*.mp3;*.aac")])
if self.file_path:
self.label.config(text=f"選択されたファイル: {self.file_path.split('/')[-1]}")
def start_playback(self):
if not self.file_path:
messagebox.showwarning("警告", "ファイルを選択してください")
return
try:
self.play_count = int(self.count_entry.get())
if self.play_count < 1 or self.play_count > 100:
raise ValueError
except ValueError:
messagebox.showerror("エラー", "再生回数は1から100の間で入力してください")
return
self.play_button.config(state=tk.DISABLED)
self.pause_button.config(state=tk.NORMAL)
self.stop_button.config(state=tk.NORMAL)
self.is_playing = True
self.is_paused = False
threading.Thread(target=self.play_loop, daemon=True).start()
def play_loop(self):
while self.is_playing and self.current_play < self.play_count:
if self.is_paused:
time.sleep(0.5)
continue
pygame.mixer.music.load(self.file_path)
pygame.mixer.music.play(start=self.pause_pos)
self.update_status()
while pygame.mixer.music.get_busy() and self.is_playing:
if self.is_paused:
pygame.mixer.music.pause()
while self.is_paused and self.is_playing:
time.sleep(0.5)
pygame.mixer.music.unpause()
time.sleep(0.5)
if not self.is_paused and self.is_playing:
self.current_play += 1
self.pause_pos = 0 # 曲の最後まで再生したらリセット
self.update_status()
if not self.is_playing:
break
self.play_button.config(state=tk.NORMAL)
self.pause_button.config(state=tk.DISABLED)
self.stop_button.config(state=tk.DISABLED)
self.is_playing = False
self.update_status()
def pause_music(self):
if self.is_paused:
self.is_paused = False
self.pause_button.config(text="一時停止")
else:
self.pause_pos = pygame.mixer.music.get_pos() / 1000.0 # ミリ秒単位を秒に変換
self.is_paused = True
self.pause_button.config(text="一時停止解除")
def stop_playback(self):
self.is_playing = False
pygame.mixer.music.stop()
self.pause_pos = 0 # 完全に停止したら位置をリセット
self.play_button.config(state=tk.NORMAL)
self.pause_button.config(state=tk.DISABLED)
self.stop_button.config(state=tk.DISABLED)
self.update_status()
def update_status(self):
remaining = max(self.play_count - self.current_play, 0)
self.status_label.config(text=f"再生中: {self.current_play}/{self.play_count} 回 残り: {remaining} 回")
def on_closing(self):
"""ウィンドウを閉じたときにプログラムを完全に終了"""
self.is_playing = False
pygame.mixer.music.stop()
self.root.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = MusicPlayer(root)
root.mainloop()