音楽に合わせてライトの色を変えたら面白そうって思ったので、作ってみました。
#1. フローチャート
簡単に作りたいイメージをフローチャートにしてみた。
音楽をGUIで選んで、音楽を再生、ライトアップして、音楽が終わったら、ライトがフェードアウトして、終了するように作ります。
#2. codeの説明
コードについて分割して説明していきます。
##2-1 mp3ファイルの選択。
mp3ファイルは、PySimpleGUIを使って選択します。下記のようなGUIを作成しました。ライトの色の変更を3,5,10秒間隔で変更できるようにラジオボタンも入れています。
##2-2 音楽の再生
音楽を再生できるライブラリはいくつあったのですが、再生、停止ができるのが分かりやすかったのでpygame.mixerを使うことにしました。pygameのドキュメントがまとまっていてわかりやすかったので、リンク入れておきます。
また、音楽が終わったらライトをフェードアウトしたかったので、mutagen.mp3を使って、音楽の長さを取得しています。取得する方法については、下記を参考にさせていただいています。
##2-3 ライトの色の選択
ライトの色は、16進数のカラーコードをcsvファイルに入力し、その中からランダムで1つ色を選ぶようにしました。カラーコードをまとめているサイトがいくつかあり、ジャンルごとに色合いが違うので、曲に合わせてカラーを選択しやすいかなと思い、そうしています。私は、やわらかい音楽をよく聞くのでパステルカラーコードを入力しています。カラーコードのcsvは、下記のように記述しています。色が選択できたらyeelightを光らせるために、RGBごと色を分ける操作をしています。
##2-4 ライトのフェードアウト
yeelightにフェードアウトの構文がなかったので作りました。brightの量をfor分を使って、徐々に下げて暗くし、最後にoffにするようにしています。wait timeは、何度か試してみて自然に消えるかなっていうところで、時間を決めています。
##2-5 code
コードは、下記のようになっています。不明点あれば、コメントいただけると幸いです。
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()
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)
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()