1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonで音楽を流し、ライトの色を変える。

Last updated at Posted at 2022-01-21

音楽に合わせてライトの色を変えたら面白そうって思ったので、作ってみました。

#1. フローチャート
簡単に作りたいイメージをフローチャートにしてみた。
音楽をGUIで選んで、音楽を再生、ライトアップして、音楽が終わったら、ライトがフェードアウトして、終了するように作ります。
Untitled Diagram.drawio.png

#2. codeの説明
コードについて分割して説明していきます。

##2-1 mp3ファイルの選択。
mp3ファイルは、PySimpleGUIを使って選択します。下記のようなGUIを作成しました。ライトの色の変更を3,5,10秒間隔で変更できるようにラジオボタンも入れています。
キャプチャ.PNG

##2-2 音楽の再生
音楽を再生できるライブラリはいくつあったのですが、再生、停止ができるのが分かりやすかったのでpygame.mixerを使うことにしました。pygameのドキュメントがまとまっていてわかりやすかったので、リンク入れておきます。

また、音楽が終わったらライトをフェードアウトしたかったので、mutagen.mp3を使って、音楽の長さを取得しています。取得する方法については、下記を参考にさせていただいています。

##2-3 ライトの色の選択
ライトの色は、16進数のカラーコードをcsvファイルに入力し、その中からランダムで1つ色を選ぶようにしました。カラーコードをまとめているサイトがいくつかあり、ジャンルごとに色合いが違うので、曲に合わせてカラーを選択しやすいかなと思い、そうしています。私は、やわらかい音楽をよく聞くのでパステルカラーコードを入力しています。カラーコードのcsvは、下記のように記述しています。色が選択できたらyeelightを光らせるために、RGBごと色を分ける操作をしています。

キャプチャ2.PNG

##2-4 ライトのフェードアウト
yeelightにフェードアウトの構文がなかったので作りました。brightの量をfor分を使って、徐々に下げて暗くし、最後にoffにするようにしています。wait timeは、何度か試してみて自然に消えるかなっていうところで、時間を決めています。

##2-5 code
コードは、下記のようになっています。不明点あれば、コメントいただけると幸いです。

main.py
import yeelight
import time
#user module
import light_action
import work

#Set up 
#GUI
gui_class   = work.gui_operation() #instance

#sound
sound_class = work.sound() #instance

#Yeelight
ye_address = "IPアドレス"
light_action_class = light_action.light_up_rgb_color() #instance
light_action_class.address_set(ye_address) # light address set

# 1.music start 
file,action_term = gui_class.read_mp3_file()
music_time = sound_class.music_length(file)
sound_class.sound_play(file)

#2.Turn on light up
light_action_class.light_turn_on()

#3 Change the color
event_term = music_time // action_term
for i in range(int(event_term)):
    yee_R, yee_G,yee_B = light_action_class.rgb_select()
    light_action_class.rgb_random(yee_R,yee_G,yee_B)
    time.sleep(action_term)

#Turn off 
time.sleep(3)
sound_class.sound_stop()
light_action_class.fade_out()
light_action_class.light_turn_off()

light_action.py
import yeelight
import csv 
from random import randint
import pandas as pd
import time

class light_up_rgb_color :
    # 初期処理
    def __init__(self) : 
        bulb_def = ""
        print("initilize")

    def address_set(self, ac_address) :
        self.bulb_def  = yeelight.Bulb(ac_address)        

    def light_turn_on(self) :
        self.bulb_def.turn_on()
        self.bulb_def.set_brightness(50)

    def light_turn_off(self) :
        self.bulb_def.turn_off()

    def rgb_random(self, r, g, b):
        self.bulb_def.set_rgb(r,g,b)
    
    def rgb_select (self):
        df = pd.read_csv('16進数で表示したcsvファイル', header=None)
        color_select = randint(0,df.size-1) # get ramdon number 
        color_row    = color_select // len(df.columns)
        color_column = color_select %  len(df.columns)
        color_code   = (df.iloc[color_row, color_column]) # select color code cell.
        
        # Extract RGB
        R_Hexa = color_code[1:3]
        G_Hexa = color_code[3:5]
        B_Hexa = color_code[5:7]
        # x16  => 10
        R_int = int(R_Hexa, 16)
        G_int = int(G_Hexa, 16)
        B_int = int(B_Hexa, 16)
        return R_int,G_int,B_int

    def fade_out (self):
        for i in range (50):
            bright_term = 50 // 50
            bright      = 50 - bright_term * i
            self.bulb_def.set_brightness(bright)
            time.sleep(0.05)
      
work.py
import PySimpleGUI as sg
from mutagen.mp3 import MP3
import pygame.mixer

class gui_operation :
    def read_mp3_file(self):
        
        # GUI color select
        sg.change_look_and_feel('Light Blue 2')
        radio_dic = {
            '3': '3sec',
            '5': '5sec',
            '10': '10sec',
        }
        layout = [[sg.Text('Data'),
                sg.InputText(' file path',key='-file-'),
                sg.FilesBrowse('Read file', target='-file-', file_types=(('mp3 file', '.mp3'),))],
                [sg.Text('term')],
                [sg.Radio(item[1], key=item[0], group_id='0') for item in radio_dic.items()],
                [sg.Submit(), sg.Cancel()]
        ]
  
        # Make a window
        window = sg.Window('Charting', layout)#window title

        # Event operation
        while True:
            event, values = window.read() # Event read 
            if event in 'Submit': 
                Get_file = values['-file-'] # Get file path
                if values['3']  == True: sec = 3
                if values['5']  == True: sec = 5 
                if values['10'] == True: sec = 10
                if  Get_file == ' file path':
                    Get_file = 'NULL'
                break
            else:
                Get_file = 'NULL' # Get file path
                break
        window.close()
        return Get_file,sec

class sound :

    def music_length(self,path):
        try:
            audio = MP3(path)
            length = audio.info.length
            return length
        except:
            return None
            
    def sound_play(self,f):
        pygame.mixer.init()
        pygame.mixer.music.stop() 
        pygame.mixer.music.load(f) 
        pygame.mixer.music.play() 
    
    def sound_stop(self):
        pygame.mixer.music.stop() 


1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?