Play Music

efore attempting to play your first song, make sure you have successfully installed LightShow Pi and verified your hardware configuration.

Playing your first Song

You can play a single song with the following command from your install directory (replacing the path with that of another music file you’ve uploaded to your Raspberry Pi if desired):

sudo python py/synchronized_lights.py --file=/home/pi/lightshowpi/music/sample/ovenrake_deck-the-halls.mp3

Before the song is played all the lights are turned on for 30 seconds, then off for 1 second before playback begins. You can modify this behavior by overriding the preshow_configuration setting.

Playing back music from a playlist

You can create a playlist of songs to play. The playlist is simply a file with one song per line in the following format (replacing <tab> with the actual <tab> character):

My Cool Song<tab>/home/pi/lightshowpi/music/cool_song.mp3
An Amazing Tune<tab>/home/pi/lightshowpi/music/amazing_tune.mp3

A sample playlist and sample songs are provided in the lightshowpi/music/sample directory.

You can play one song at a time from your playlist by running the following command (replacing /home/pi/lightshowpi/music/sample/.playlist with the path to your playlist):

sudo python py/synchronized_lights.py --playlist=/home/pi/lightshowpi/music/sample/.playlist

Each time the above command is run, a single file from your playlist will be played. To play one song after another from your playlist you’ll want to override the playlist_path configuration setting to point to your playlist, and then run the following script to continuously play songs from your playlist:

start_music_and_lights

To stop the continuous playback, you can issue to following command:

stop_music_and_lights

32 Replies to “Play Music”

  1. Is there a way to convert this simple command line menu to a GUI interface

    #!/bin/bash
    trap ‘ ‘ 2
    while true
    do
    clear
    echo “=================================”
    echo ” Menu of Songs”
    echo “=================================”
    echo “Enter 1 Manheim Steamroller Deck the Halls”
    echo “Enter 2 Frozen”
    echo “Enter 3 Jingle Bells”
    echo “Enter 4 Joy to the World”
    echo “Enter 5 Mary, Did you Know”
    echo “Enter 6 Blue Christmas”
    echo “Enter 7 Main Street Electrical Parade”
    echo “Enter 8 Little Drummer Boy”
    echo “Enter 9 Eye of the Tiger”
    echo “Enter a Don’t want to miss a Thing”
    echo “Enter b Firework”
    echo “Enter q to quit”
    echo -e “n”
    echo -e “Enter your Selection here and hit ”
    read answer # create varible to retain the answer
    case “$answer” in
    1) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    2) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    3) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    4) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    5) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    6) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    7) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    8) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    9) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    a) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    b) sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi$
    q) exit ;;
    esac
    echo -e “/n”
    echo -e ” Hit the key to continue.. c”
    read input #This cause a pause so we can read the output of the selection be$
    done

    Thanks in advance.

    1. Hello, I am sharing the code that I made in python for a menu with interfaces that makes it more friendly, it makes some sequences with the 8 channels that you can modify, it is missing some improvements but I haven’t had time to do it, regards.

      from Tkinter import *
      import sys
      import RPi.GPIO as GPIO
      import time as time
      import os
      import threading
      from threading import Thread,Event
      from random import randint, uniform,random
      import ttk
      import tkMessageBox
      global status

      window=Tk()

      def num(s):
      try:
      return int(s)
      except ValueError:
      return float(s)

      def OnOff(Canal, OnOff):

      if Canal==1:
      if OnOff==1:
      GPIO.output(17, True)
      else:
      GPIO.output(17, False)
      if Canal==2:
      if OnOff==1:
      GPIO.output(18, True)
      else:
      GPIO.output(18, False)
      if Canal==3:
      if OnOff==1:
      GPIO.output(27, True)
      else:
      GPIO.output(27, False)
      if Canal==4:
      if OnOff==1:
      GPIO.output(22, True)
      else:
      GPIO.output(22, False)
      if Canal==5:
      if OnOff==1:
      GPIO.output(23, True)
      else:
      GPIO.output(23, False)
      if Canal==6:
      if OnOff==1:
      GPIO.output(24, True)
      else:
      GPIO.output(24, False)
      if Canal==7:
      if OnOff==1:
      GPIO.output(25, True)
      else:
      GPIO.output(25, False)
      if Canal==8:
      if OnOff==1:
      GPIO.output(4, True)
      else:
      GPIO.output(4, False)

      def CleanGPIOs(OnOff):
      if OnOff==0:
      GPIO.cleanup()
      GPIO.setmode(GPIO.BCM)
      GPIO.setup(17, GPIO.OUT)
      GPIO.setup(18, GPIO.OUT)
      GPIO.setup(27, GPIO.OUT)
      GPIO.setup(22, GPIO.OUT)
      GPIO.setup(23, GPIO.OUT)
      GPIO.setup(24, GPIO.OUT)
      GPIO.setup(25, GPIO.OUT)
      GPIO.setup(4, GPIO.OUT)
      GPIO.output(17, GPIO.LOW);GPIO.output(18, GPIO.LOW);GPIO.output(27, GPIO.LOW);GPIO.output(22, GPIO.LOW);
      GPIO.output(23, GPIO.LOW);GPIO.output(24, GPIO.LOW);GPIO.output(25, GPIO.LOW);GPIO.output(4, GPIO.LOW);
      if OnOff==1:
      GPIO.cleanup()
      GPIO.setmode(GPIO.BCM)
      GPIO.setup(17, GPIO.IN)
      GPIO.setup(18, GPIO.IN)
      GPIO.setup(27, GPIO.IN)
      GPIO.setup(22, GPIO.IN)
      GPIO.setup(23, GPIO.IN)
      GPIO.setup(24, GPIO.IN)
      GPIO.setup(25, GPIO.IN)
      GPIO.setup(4, GPIO.IN)
      #GPIO.output(17, GPIO.IN);GPIO.output(18, GPIO.IN);GPIO.output(27, GPIO.IN);GPIO.output(22, GPIO.IN);
      #GPIO.output(23, GPIO.IN);GPIO.output(24, GPIO.IN);GPIO.output(25, GPIO.IN);GPIO.output(4, GPIO.IN);

      def KnightRider(t):
      CleanGPIOs(0)
      while True:
      for x in range(1, 9):
      OnOff(x,1)
      time.sleep(t)
      OnOff(x,0)

      for x in range(8, 0, -1):
      OnOff(x,1)
      time.sleep(t)
      OnOff(x,0)
      if not stop_threads:
      break

      def KnightRiderWinDoor(t):
      CleanGPIOs(0)
      OnOff(1,1); OnOff(7,1); OnOff(8,1) #Solo cobertizo, tronco y ramas arbol encendido
      while True:
      for x in range(2, 6):
      OnOff(x,1)
      time.sleep(t)
      OnOff(x,0)

      for x in range(6, 2, -1):
      OnOff(x,1)
      time.sleep(t)
      OnOff(x,0)
      if not stop_threads:
      break

      def WindowAndDoorParty(t):
      CleanGPIOs(0)
      OnOff(1,1); OnOff(7,1); OnOff(8,1) #Solo cobertizo, tronco y ramas arbol encendido
      x=0
      while True:
      CanalAleatorio = randint(2,6)
      ApagoEnciendo = randint(0,1)
      OnOff(CanalAleatorio,ApagoEnciendo)
      time.sleep(t)
      if not stop_threads:
      break

      def AllParty(t):
      while True:
      CleanGPIOs(0)
      CanalAleatorio = randint(1,8)
      ApagoEnciendo = randint(0,1)
      OnOff(CanalAleatorio,ApagoEnciendo)
      time.sleep(t)
      if not stop_threads:
      break

      def TwisterWindowsDoor(t):
      CleanGPIOs(0)
      OnOff(1,1); OnOff(7,1); OnOff(8,1) #Solo cobertizo, tronco y ramas arbol encendido
      while True:
      for x in range(2, 7):
      OnOff(x,1)
      time.sleep(t)
      OnOff(x,0)
      if not stop_threads:
      break

      def DownUpWindowsDoor(t):
      CleanGPIOs(0)
      OnOff(1,1); OnOff(7,1); OnOff(8,1) #Solo cobertizo, tronco y ramas arbol encendido
      while True:
      OnOff(2,1);OnOff(3,1)
      time.sleep(t)
      OnOff(2,0);OnOff(3,0)
      OnOff(4,1);OnOff(5,1);OnOff(6,1)
      time.sleep(t)
      OnOff(4,0);OnOff(5,0);OnOff(6,0)
      if not stop_threads:
      break

      def QuitControlLuces():
      status.configure(text=’Adios.’)
      window.quit()
      window.destroy()
      sys.exit(0)

      def IntructionStop():
      status.configure(text=’Listo.’)
      global stop_threads
      stop_threads = False
      time.sleep(2)

      def IntructionStart():
      if comboExample.current()!=0 and v0.get() !=0:
      status.configure(text=’Procesando…’)
      global stop_threads
      global thread
      stop_threads=True
      print(v0.get())
      if v0.get()==1:
      print(‘Instruccion de inicio para la opcion 1’)
      thread = threading.Thread(target=CleanGPIOs, args=(0,))
      if v0.get()==2:
      print(‘Instruccion de inicio para la opcion 2’)
      thread = threading.Thread(target=KnightRider, args=(num(TimeComboBox),))
      if v0.get()==3:
      print(‘Instruccion de inicio para la opcion 3’)
      thread = threading.Thread(target=KnightRiderWinDoor, args=(num(TimeComboBox),))
      if v0.get()==4:
      print(‘Instruccion de inicio para la opcion 4’)
      thread = threading.Thread(target=WindowAndDoorParty, args=(num(TimeComboBox),))
      if v0.get()==5:
      print(‘Instruccion de inicio para la opcion 5’)
      thread = threading.Thread(target=AllParty, args=(num(TimeComboBox),))
      if v0.get()==6:
      print(‘Instruccion de inicio para la opcion 6’)
      thread = threading.Thread(target=TwisterWindowsDoor, args=(num(TimeComboBox),))
      if v0.get()==7:
      print(‘Instruccion de inicio para la opcion 7’)
      thread = threading.Thread(target=DownUpWindowsDoor, args=(num(TimeComboBox),))
      thread.daemon = True
      thread.start()
      else:
      tkMessageBox.showerror(‘Error’,’Debe seleccionar tiempo y una secuencia de luces.’)

      def prueba():
      CleanGPIOs(0)
      while True:
      time.sleep(0.5)
      print(‘enciende’)
      OnOff(2,0)
      time.sleep(0.5)
      OnOff(2,1)

      window.title(‘Control de Luces Casa’)

      lbl=Label(window, text=’Control De Luces Casa’, fg=’red’, font=(‘Helvetica’, 16))
      lbl.place(x=180, y=10)

      v0=IntVar()
      #v0.set(1)
      r1=Radiobutton(window, text=”Apagar todo”, variable=v0,value=1)
      r1.place(x=10,y=50)
      r2=Radiobutton(window, text=”Knight Rider Todo”, variable=v0,value=2)
      r2.place(x=10, y=70)
      r3=Radiobutton(window, text=”Knight Rider solo ventanas y puerta, arbol y cobertizo encendidos”, variable=v0,value=3)
      r3.place(x=10, y=90)
      r4=Radiobutton(window, text=”Party solo ventanas y puerta, arbol y cobertizo encendidos”, variable=v0,value=4)
      r4.place(x=10, y=110)
      r5=Radiobutton(window, text=”Party todo (aleatorio)”, variable=v0,value=5)
      r5.place(x=10, y=130)
      r6=Radiobutton(window, text=”Twister solo ventanas y puerta, arbol y cobertizo encendidos”, variable=v0,value=6)
      r6.place(x=10, y=150)
      r7=Radiobutton(window, text=”Arriba/Abajo solo ventanas y puerta, arbol y cobertizo encendidos”, variable=v0,value=7)
      r7.place(x=10, y=170)
      valor=v0.get()

      #COMBOBOX TIEMPO
      def callbackFunc(event):
      global TimeComboBox
      TimeComboBox = comboExample.get()
      print(“Se selecciono combo tiempo”,comboExample.current(), TimeComboBox)

      labelTop = ttk.Label(window,text = “Tiempo:”)
      #labelTop.grid(column=10, row=210)
      labelTop.place(x=20, y=212)

      comboExample = ttk.Combobox(window, state=”readonly”, values=[”, ‘0.1’, ‘0.2’, ‘0.3’, ‘0.4’, ‘0.5’, ‘0.6’,
      ‘0.7’, ‘0.8’, ‘0.9’, ‘1’, ‘1.1’, ‘1.2’, ‘1.3’, ‘1.4’, ‘1.5’, ‘1.6’, ‘1.7’, ‘1.8’, ‘1.9’, ‘2’])
      #print(dict(comboExample))
      comboExample.place(x=80, y=210)
      comboExample.current(0)
      comboExample.bind(“<>”, callbackFunc)
      #print(comboExample.current(), comboExample.get())

      btn=Button(window, text=’Iniciar’, fg=’blue’, width=8, height=1, anchor=”nw”, command=IntructionStart)
      btn.place(x=500, y=50)

      btn=Button(window, text=’Terminar’, fg=’blue’, width=8, height=1, anchor=”nw”, command=IntructionStop)
      btn.place(x=500, y=80)

      btn=Button(window, text=’Salir’, fg=’blue’, width=8, height=1, anchor=”nw”, command=QuitControlLuces)
      btn.place(x=500, y=250)

      status = Label(window, text = ‘Listo.’, relief=SUNKEN, anchor=W)
      status.pack(side=BOTTOM, fill=X)

      window.geometry(“600×300+10+20”)
      window.mainloop()

  2. ERROR in execute
    # sudo python py/synchronized_lights.py –playlist=/home/pi/lightshowpi/music/sample/.playlist
    /home/pi/lightshowpi/py/fft.py:61: RuntimeWarning: divide by zero encountered in log10
    :piff(frequency_limits[i][1], chunk_size, sample_rate):1]))

  3. Is there a way to make this work with with a bluetooth adapter with music coming from an external device? I am new to this, but really want to learn more.

  4. Hope you can help. I am getting the following error:

    “Unable to enable V3D. Please check your firmware is up to date.”

    When running [ sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi/music/sample/ovenrake_deck-the-halls.mp3 ]

  5. When I try to set what music I want to play I get an error that “Traceback (most recent call last):
    File ‘py/synchronized_lights.py’, line 465, in
    play_song()
    File ‘py/synchronized_lights.py’, line 290, in play_song
    for song in playlist:
    _csv.Error: line contains NULL byte”
    What does all that mean and how can I fix it?

  6. Is there a way to create 2 playlists and be able to chose between the 2. ie, Halloween and Christmas. So as they year changes, I do not need to use another SD card?

    1. I do this myself, just have two different playlists in two separate directories, then modify your overrides.cfg file to point to one or the other.

  7. just fyi for anyone trying to stream stuff with stream-in mode, don’t just stream the url to stdout with ffmpeg or something, i’ve had better results using these settings and commands:
    (i am streaming theradio.cc)

    1. Run: mkfifo /home/pi/lightshowpi.sock

    2. Change your config to:
    mode = stream-in
    stream_in_command = cat /home/pi/lightshowpi.sock

    3. Start synchronized_lights.py in one terminal (i use tmux)

    4. Run this in another terminal: ffmpeg -re -i http://mp3.theradio.cc -ar 48000 -f wav pipe:1 > /home/pi/lightshowpi.sock

    BOOM! A less resource intensive, less laggy, less delay stream-in mode

  8. Thanks a Ton. I was able to successfully put together the project and the final piece was the software. your code worked like a charm. I am interested to know is there any way to stream the FM as input instead of MP3.

    1. With the current code, you can stream music over the network as input, or from a usb soundcard … so in theory if you have an external FM radio you could pair it with a usb sound card in audio-in mode.

  9. I followed the steps as outlined. However, I receive the following error message when I attempt to utilise the .playlist

    pi@raspberrypi:~/lightshowpi $ sudo python py/synchronized_lights.py –file=/home/pi/lightshowpi/music/Christmas/.Playlist
    Traceback (most recent call last):
    File “py/synchronized_lights.py”, line 965, in
    lightshow.play_song()
    File “py/synchronized_lights.py”, line 805, in play_song
    self.setup_audio()
    File “py/synchronized_lights.py”, line 608, in setup_audio
    self.music_file = decoder.open(self.song_filename, force_header)
    File “/usr/local/lib/python2.7/dist-packages/decoder/__init__.py”, line 735, in open
    raise IOError, (2, “No such file or directory: ‘%s'” % name)
    IOError: [Errno 2] No such file or directory: ‘/home/pi/lightshowpi/music/Christmas/.Playlist’

    1. Verify the file exists there:

      ls -ahlrt /home/pi/lightshowpi/music
      ls -ahrlt /home/pi/lightshowpi/Christmas
      (or should it be christmas lowercase ‘c’)?
      ls -ahlrt /home/pi/lightshowpi/Christmas/.Playlist
      (or should it be .playlist lowercase ‘p’)?

    2. I am having the same issue but the line numbers are different on the message I get
      Did you get yours resolved as Todd has been helping it won’t play the songs I want.

  10. hi, does anyone know why im getting this error while trying to link a music file with lightshowpi as it works well with the sample music files?

    pi@raspberrypi:~/lightshowpi/py $ sudo python synchronized_lights.py –file=/home/pi/Music/Meat_Loaf/Bat_Out_of_Hell.mp3
    Traceback (most recent call last):
    File “synchronized_lights.py”, line 969, in
    lightshow.play_song()
    File “synchronized_lights.py”, line 803, in play_song
    self.setup_audio()
    File “synchronized_lights.py”, line 606, in setup_audio
    self.music_file = decoder.open(self.song_filename, force_header)
    File “/usr/local/lib/python2.7/dist-packages/decoder/__init__.py”, line 735, in open
    raise IOError, (2, “No such file or directory: ‘%s'” % name)
    IOError: [Errno 2] No such file or directory: ‘/home/pi/Music/Meat_Loaf/Bat_Out_of_Hell.mp3’

    The music files appear as,

    pi@raspberrypi:~/Music/Meat Loaf $ dir
    Meat\ Loaf\ -\ Bat\ Out\ of\ Hell.mp3

  11. i have this error when i try to run and no sound come out of it

    Traceback (most recent call last):
    File “py/synchronized_lights.py”, line 979, in
    lightshow.play_song()
    File “py/synchronized_lights.py”, line 810, in play_song
    self.setup_audio()
    File “py/synchronized_lights.py”, line 613, in setup_audio
    self.music_file = decoder.open(self.song_filename, force_header)
    File “/usr/local/lib/python2.7/dist-packages/decoder/__init__.py”, line 771, in open
    wf = fakewave(po, fh)
    File “/usr/local/lib/python2.7/dist-packages/decoder/__init__.py”, line 635, in __init__
    self.initfp()
    File “/usr/local/lib/python2.7/dist-packages/decoder/__init__.py”, line 665, in initfp
    self._nframes = int(self._framerate * info(self.obj.filename).info.length)
    File “/usr/local/lib/python2.7/dist-packages/decoder/fileinfo.py”, line 56, in info
    exec “r = “+mod+”.%s(\”%s\”)” % (func, filename)
    File “”, line 1, in
    AttributeError: ‘module’ object has no attribute ‘Open’

  12. Are there any preset shows? I built a 16 channel controller box and had a friend help me install Lightshow pi after months of asking and failed attempt to do being a 100% beginner and really wanted a show up and running for my 2 year old tomorrow but being told it can’t happen.

Leave a Reply to Todd Giles Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.