【備忘録】TkinterとPygameで簡素な音楽プレイヤーを作る

初めまして、Zaforiaと申します。

新社会人だったりします

独学&プログラミング歴数か月のガチ初心者です

 

諸事情で二ヶ月のネット断食を強いられて自分で作ったプログラムを忘れそうだったのでここに残していこうと思います。

 

ついでにはじめてgithubにも入れたので公開しておきます

 

Python 3.8環境です

3.8で追加されたformat構文 f'{var}' を使ってるのでこれ以下のバージョンだと動かない可能性があります

 

今日は書ききれなかったのでブログはぼちぼち更新していきます...

 

github.com

 

 

 

    1.使ったライブラリとか

タイトル通りPygameTkinterがメインです

選定理由はGUI入門でTkinterが作りやすそうだったのとPygameは再生と一時停止の関数があるから

 

pydubは再生時間の取得のために使いました

 

import os
import sys
import tkinter as tk
import tkinter.filedialog
from tkinter import Text
import itertools
import threading
import pickle
import glob
import pygame
from pydub import AudioSegment
import random
#__line__
import re
import tempfile
import shutil
#/__line__
import subprocess
from subprocess import PIPE

  

 

    2.再生時間の処理とか

結構苦戦しました。Tkinterのroot.afterの機能を使って125ms間隔で関数を無限に実行、別のスレッドで再生状態の監視をやってリセットしたりの処理をやってます。

 

class clock:
    def __init__(self, root):
        self.root = root

        self.time_start = 0
        self.min = 0
        self.flag = 0
        self.pause_flag = 0
        self.zeroflag = 0



    def time_counter(self):
        #self.a = threading.Thread(target=self.update)
        #self.a.start()
        if self.zeroflag == 0 and self.pause_flag == 0:
            self.time_start = 0
            self.zeroflag = 1


        if self.pause_flag == 0 and self.zeroflag == 1:
            self.msintimer += 1
            
        if self.pause_flag == 0 and self.zeroflag == 1 and self.msintimer >= 8:
            self.msintimer = 0
            self.time_start += 1
            
        if self.time_start >= 60 and self.pause_flag == 0:
            self.min += 1
            self.time_start = 0
            
        elif self.pause_flag == 1:
            self.stop()
            self.pause_flag = 0

        if pygame.mixer.get_busy:
            self.id = self.root.after(125, self.time_counter)

        self.update()

    def update(self):
        if self.flag == 1:
            sound =    AudioSegment.from_file(self.entries[self.boxes])
            rate = sound.frame_rate
            pygame.mixer.init(frequency = rate)
            z = pygame.mixer.Sound(self.entries[self.boxes])
            self.z = z.get_length()
            #if self.time_start + self.min * 60 > self.z + 1:
                 #if var.get() >= 1 :
                    #self.reset(self.mes, self.listbox, self.entries, self.boxes)
                 #else:
                      #self.root.after_cancel(self.id)
                #self.reset(self.mes, self.listbox, self.entries, self.boxes)
            self.mes.configure(text=f'{str(self.min).zfill(2)}:{str(self.time_start).zfill(2)}')


    def reset(self, mes, listbox, entries, boxes):
        self.zeroflag = 0
        self.time_start = 0
        self.min = 0
        self.msintimer = 0

        self.mes = mes
        self.listbox = listbox
        self.entries = entries
        self.boxes = boxes
        if self.flag == 0:
            self.flag = 1
        else:
            self.root.after_cancel(self.id)
        self.time_counter()


    def pause(self):
        self.nowmin = self.min
        self.nowtime = self.time_start
        self.nowmsintimer = self.msintimer
        self.root.after_cancel(self.id)
     

    def unpause(self):
        self.pause_flag = 1
        self.min = self.nowmin
        self.time_start = self.nowtime
        self.msintimer = self.nowmsintimer
        self.time_counter()

    def stop(self):
        self.root.after_cancel(self.id)