Raspberry Piで

超簡易オーディオプレイヤー 「梅」

「ボタンを押すと、楽曲ファイルが演奏され、もう一度ボタンを押すと演奏が止まる」という、誠に単純な機能を持つ装置

Raspberry PiにLEDをつけたただけの、これ以上ない簡単な構成のオーディオプレイヤー

OSのインストール

インストールしたOSイメージ

2018-11-13-raspbian-stretch-lite.img

ソフトウェアの設定は、共通のものを参照。

usbmountのインストール

$ sudo apt-get install usbmount

次に、/lib/systemd/system/systemd-udevd.serviceを書き換える。

(before)   MountFlags=slave
(after)    MountFlags=shared

回路図

オーディオプレイヤーのソフトウェア

Python3を使って、実装する。

(ソースコード:ファイル名 ledsimpleplayer.py)

#! /usr/bin/env python3
# coding:utf-8

# RapsberryPi Simple Music Player

import RPi.GPIO as GPIO
import subprocess
import vlc
import pathlib
import random

import time
import sys
import os

class SimplePlayer():
    def __init__(self):
        self.set_gpio()
        self.status = "STOP"

        self.vlcmlp = vlc.MediaListPlayer() #VLC Media List Player
        self.vlcmlp.set_playback_mode(vlc.PlaybackMode.loop) #vlc playback mode をloop(play listの繰り返しに)

        # VLC Volume 80%
        self.VLC_volume = 80
        self.vlc_media_player=self.vlcmlp.get_media_player() # get media player instance from media list palyer
        self.vlc_media_player.audio_set_volume(self.VLC_volume) # volume set to media player

        # Play Listの生成
        self.vlcmlp.set_media_list( self.get_media_list() ) #set media list

    def stop_and_clean(self):
        #停止時の後始末
        self.led_off()
        if self.status == "PLAY" :
            self.vlcmlp.stop() #曲の停止
            print("--STOP--")
        GPIO.cleanup(22) # Cleanup GPIO 22
        GPIO.cleanup(27) # Cleanup GPIO 27

    def on_closing(self):
        self.stop_and_clean()
        root.destroy()


    def get_media_list(self):
        #メディアリストを更新し、返す。
        print("--LIST--")
        p_temp_media_list = vlc.MediaList() # MediaListを生成
        #メディアファイルのpathのリストを取得
        #p_temp = pathlib.Path('/home/pi/music') #テスト用楽曲ファイルのパスを設定
        #p_temp = pathlib.Path('/media/usb') #USBメモリのパスを設定(Raspbian LITE + usbmount)
        p_temp = pathlib.Path('/media/pi/') #USBメモリのパスを設定(Raspbian Desktop)

        length_mrl_list = 0 #mrl_listの要素数を初期化
        while length_mrl_list <= 0 : #有効な要素数が得られなければ

            print ("LISTING")

            mrl_list = [] #mrl(楽曲ファイルのPATH)のリストの初期化
            extension_mrl_list = list(p_temp.glob('**/*.m[4p][3a]')) # 楽曲拡張子mp3,m4aのファイル名を取得
            mrl_list.extend(extension_mrl_list)
            length_mrl_list = len(mrl_list) #mrl_listの要素数を取得

        for i in range(length_mrl_list):
            mrl = random.choice(mrl_list)
            p_temp_media_list.add_media(str(mrl))#リストからランダムに取り出す
            #print(mrl) #DEBUG
        print("--LIST Done--")
        return p_temp_media_list


    def vlc_play(self):
        #DEBUG:print("DEBUG:status="+self.status)
        if self.status == "STOP" :
            self.led_on()

            self.status = "PLAY"
            print("--PLAY--")
            # Music media files in /media/pi directory
            self.vlcmlp.play() # 曲の再生

            #再生中にメディアリストを再構築する
            self.vlcmlp.set_media_list( self.get_media_list() ) #set media list
            print("--PLAYING--")

        else:
            self.led_off()

            self.status = "STOP"
            self.vlcmlp.stop() #曲の停止

            print("--STOP--")


    def play_sound_gpio(self):
        ## DEBUG:print("DEBUG:" + self.status)
        print("SW: PRESSED")
        waittimercounter = 0
        while True:
            time.sleep(0.5) # wait 0.5 seconds
            print("SW: PRESSED")
            if GPIO.input(22) == False:
                # ボタン(PORT22)が押されていないときは
                print("SW: RELEASED")
                break# Exit
            else:
                # ボタン(PORT22)が押されているときは
                waittimercounter += 1 # ボタンの押された回数のカウンタを1増やす
                #LED点滅
                if waittimercounter % 2 == 0:
                    self.led_on()
                else:
                    self.led_off()

                if waittimercounter >= 7: # ボタンのカウンタが規定数になったら終わり
                    print('SW: LONG PRESSED')
                    self.stop_and_clean() #終了時処理
                    os.system("sudo shutdown -h now") # System Shut down
        # VLC palyer control by GPIO
        self.vlc_play()


    def set_gpio(self):
        GPIO.setmode(GPIO.BCM)  #GPIO Access by BCM
        GPIO.setup(27,GPIO.OUT)   #BCM PIN-27 as Output
        GPIO.setup(22,GPIO.IN)
        GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)   #BCM PIN-22 as Input
#        GPIO.add_event_detect(22, GPIO.RISING,bouncetime=200)
        #GPIO.add_event_detect(22, GPIO.FALLING,bouncetime=200) #なぜか勝手に割り込みが入るのでダメ
        #GPIO.add_event_callback(22, self.play_sound_gpio) # Call back Trigger GPIO PIN-22
        self.led_off(); # LED OFF


    def led_on(self):
        GPIO.output(27, GPIO.HIGH)


    def led_off(self):
        GPIO.output(27, GPIO.LOW)


####################################################
app = SimplePlayer()
while True:
    GPIO.wait_for_edge(22, GPIO.RISING)
    app.play_sound_gpio()

ソースコードの保存

ソースコードを(Python3)をledsimpleplayer.pyという名前で保存

場所は/home/pi/simpleplayer/

ソースコードを実行可能に設定する。

$ chmod +x /home/pi/simpleplayer/ledsimpleplayer.py

OSの起動時に自動的に起動するように設定する。

編集するファイル: /home/pi/.config/lxsession/LXDE-pi/autostart

最後に下記のエントリを追加

@/home/pi/simpleplayer/ledsimpleplayer.py