1. Installing the OS on the raspberry pi
b. Plugin a usb keyboard, connect via HDMI, and use a wired ethernet cable for initial setup
c. Login to the pi locally (pi/raspberry)
d. Set advanced settings by using sudo raspi-config
i. Increase GPU memory to (at least) 256 (Advanced Options -> Memory Split)
ii. Enable ssh (Advanced Options -> Interfacing options).
e. Now, you can do the following operations on the pi remotely using ssh (you can get the IP address of the pi from the hdmi screen and login is still the same, i.e. pi/raspberry)
2. Software installation and basic configuration
a. PS : I have followed the basic steps from this link, and customized them for my own use. It might be useful reference, so now you have it
chmod +x ./install.sh
source ./install.sh
3. Music and skin configuration
a. Configure /home/pi/rpi-fruitbox-master/Music to point to your mp3 source folder (I have chosen to point this to an smb share on my home nas, but you could point it to a local usb stick as well)
b. Test it first by manual commands, e.g.
mkdir /home/pi/Music
sudo mount -t cifs -o vers=1.0,_netdev,username=****,password=****,uid=1000,gid=1000 //192.168.1.8/public/Media/fruitbox/Music /home/pi/Music
c. Now, make the change persistent across reboots by adding the following entry to /etc/fstab as follows :
//192.168.1.8/public/Media/fruitbox/Music /home/pi/Music cifs defaults,vers=1.0,_netdev,username=****,password=****,uid=1000,gid=1000 0 0
4. Controller configuration
a. Plugin the controller and verify operation
I bought this generic xbox controller from amazon for $16.99, but you can use other ones too.
b. Configure fruitbox to accept and map the controller buttons
i. First install the xboxdrv package (sudo apt install xboxdrv)
ii. Run the following command to monitor inputs (sudo xboxdrv)
iii. Press a button (e.g. A) and see the registered change as noted below (the output scrolls by fast, but you can see it in terminal history)
X1: 0 Y1: -256 X2: 0 Y2: -256 du:0 dd:0 dl:0 dr:0 back:0 guide:0 start:0 TL:0 TR:0 A:0 B:0 X:0 Y:0 LB:0 RB:0 LT: 0 RT: 0
X1: 0 Y1: -256 X2: 0 Y2: -256 du:0 dd:0 dl:0 dr:0 back:0 guide:0 start:0 TL:0 TR:0 A:1 B:0 X:0 Y:0 LB:0 RB:0 LT: 0 RT: 0
iv. Now, you are ready to map the buttons in fruitbox to your newly recognized controller (see how have chosen the button configuration for my xbox controller)
cd rpi-fruitbox-master/
sudo ./fruitbox --config-buttons
Follow instructions on screen and press the controller keys for the controls. Press the ESC key for the buttons you want to skip.
v. Now edit the fruitbox.btn (sudo vi /home/pi/rpi-fruitbox-master/fruitbox.btn) and remove the duplicates for the buttons you have skipped (you will see the escape key repeated multiple times, just comment the duplicates out and only keep the one for ButtonQuit)
Here is how my fruitbox.btn file looks like
# fruitbox v1.16 button mapping file
# Missing buttons will assume their default values (see user guide)
ButtonQuit = JoyButton 0 316
#ButtonCoin1 = JoyButton 0 316
#ButtonCoin2 = JoyButton 0 316
#ButtonCoin3 = JoyButton 0 316
#ButtonCoin4 = JoyButton 0 316
#ButtonVol+ = JoyButton 0 316
#ButtonVol- = JoyButton 0 316
#ButtonRandom = JoyButton 0 316
ButtonSelect = JoyButton 0 314
ButtonSkip = JoyButton 0 315
#ButtonPause = JoyButton 0 316
ButtonUp = JoyStick 0 4 1
ButtonDown = JoyStick 0 4 0
ButtonLeft = JoyButton 0 310
ButtonRight = JoyButton 0 311
#ButtonLeftJump = JoyButton 0 316
#ButtonRightJump = JoyButton 0 316
#ButtonLeftAlpha = JoyButton 0 316
#ButtonRightAlpha = JoyButton 0 316
#ButtonAuto = JoyButton 0 316
#ButtonLoop = JoyButton 0 316
#ButtonFree = JoyButton 0 316
#ButtonClear = JoyButton 0 316
#ButtonMute = JoyButton 0 316
ButtonPowerOff = JoyStick 0 2 0
#Button0 = JoyButton 0 316
Button1 = JoyStick 0 17 0
Button2 = JoyStick 0 16 0
Button3 = JoyStick 0 17 1
Button4 = JoyStick 0 16 1
#Button5 = JoyButton 0 316
#Button6 = JoyButton 0 316
#Button7 = JoyButton 0 316
#Button8 = JoyButton 0 316
#Button9 = JoyButton 0 316
ButtonA = JoyButton 0 304
ButtonB = JoyButton 0 305
ButtonC = JoyButton 0 308
ButtonD = JoyButton 0 307
#ButtonF = JoyButton 0 316
#ButtonG = JoyButton 0 316
#ButtonH = JoyButton 0 316
#ButtonI = JoyButton 0 316
#ButtonJ = JoyButton 0 316
#ButtonK = JoyButton 0 316
#ButtonFlag1 = JoyButton 0 316
#ButtonFlag2 = JoyButton 0 316
#ButtonFlag3 = JoyButton 0 316
#ButtonFlag4 = JoyButton 0 316
5. Test out the jukebox with your skin real quick
cd rpi-fruitbox-master/
sudo ./fruitbox --cfg skins/WallJuke/fruitbox.cfg
You will see a database building message for the files in your Music folder that we configured earlier
If all was done correctly, you should be able to select tracks using the A-D, 1-4 buttons, skip them, and then exit as well
6. Some final changes to the raspbian OS to start things just right on bootup
a. First we need to set the automatic login to the user pi
sudo raspi-config
· select: 3 Boot Options Configure options for start-up
· Then: B1 Desktop/CLI Choose whether to boot into the desktop environment or the command line
And finally:
· B2 Console Autologin Text console, automatically logged in as 'pi' user
· Exit by selecting <Finish>
And to the question: Would you like to reboot now?
· Reply<Yes>
Go ahead and change the password for the user pi as well.
Here are some screenshots of the steps mentioned above to guide you
At this point we verify that when Raspbian restarts, the password is not required to log in as user pi
b. Now we have to automate the start and stop of the fruitbox program
i. Create the run script (/home/pi/runjb.sh)
#!/bin/bash
. /home/pi/jukebox.conf
ISRUNNING=`ps -ef | grep fruitbox | grep -v grep|wc -l`
TY=`ps ax | grep $$ | tail -n 1 | awk '{ print $2 }'`
if [ $ISRUNNING -lt 1 ] && [ "$TY" = "tty1" ]
then
cd /home/pi/rpi-fruitbox-master
sudo ./fruitbox --cfg ./skins/$THEME/$CONFFILE
echo "Found $TY. Should initiate a shutdown, as fruitbox has exited..."
#sudo halt
#sudo /sbin/init 0
else
echo "Not the main console, nothing to do..."
fi
ii. Create the default config file and uncomment your skin (/home/pi/jukebox.conf)
#!/bin/bash
USER="pi"
HD="/home/"$USER
CONFFILE="fruitbox.cfg"
THEME=WallJuke
#THEME=Modern
#THEME=Granite
#THEME=MikeTV
#THEME=NumberOne
#THEME=Splat
#THEME=TouchOne
#THEME=WallSmall
#THEME=Wurly
iii. Set the correct permissions and add the run script to run automatically when pi starts and automatically logs you in
sudo chmod 770 /home/pi/runjb.sh
sudo chmod 770 /home/pi/jukebox.conf
sudo echo "sudo /home/pi/runjb.sh" >> /home/pi/.bashrc
iv. Now reboot (sudo reboot) and verify auto launch and proper operation
7. Final end product !
8. Other miscellaneous tips
a. Audio configuration
Use sudo alsamixer to tune the audio. If you wanted to output to the audio out jack instead of hdmi, you can use sudo raspi-config to change that selection as well
b. Using a local USB stick for audio
Here are basic instructions on how to mount a USB stick (e.g. I am using an FAT32 Cruze USB stick )
sudo lsblk -o UUID,NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,MODEL
UUID NAME FSTYPE SIZE MOUNTPOINT LABEL MODEL
sda 29.8G Cruze
5E62-D6E5 └─sda1 exfat 29.8G USB
mmcblk0 7.6G
00D2-4212 ├─mmcblk0p1
│ vfat 63M RECOVERY
│
├─mmcblk0p2
│ 1K
06604c8a-3da2-49e8-8007-3f14c26b363b ├─mmcblk0p5
│ ext4 32M SETTINGS
│
5CB0-16FE ├─mmcblk0p6
│ vfat 256M /boot boot
6077dab4-00f2-4bf9-9e70-818da9fb1fed └─mmcblk0p7
ext4 7.2G / root
sudo apt install exfat-fuse
sudo blkid
/dev/mmcblk0: PTUUID="64e82d74" PTTYPE="dos"
/dev/mmcblk0p1: SEC_TYPE="msdos" LABEL_FATBOOT="RECOVERY" LABEL="RECOVERY" UUID="00D2-4212" TYPE="vfat" PARTUUID="64e82d74-01"
/dev/mmcblk0p5: LABEL="SETTINGS" UUID="06604c8a-3da2-49e8-8007-3f14c26b363b" TYPE="ext4" PARTUUID="64e82d74-05"
/dev/mmcblk0p6: LABEL_FATBOOT="boot" LABEL="boot" UUID="5CB0-16FE" TYPE="vfat" PARTUUID="64e82d74-06"
/dev/mmcblk0p7: LABEL="root" UUID="6077dab4-00f2-4bf9-9e70-818da9fb1fed" TYPE="ext4" PARTUUID="64e82d74-07"
/dev/sda1: LABEL="USB" UUID="5E62-D6E5" TYPE="exfat"
Add the following line to /etc/fstab
UUID=5E62-D6E5 /mnt/usb exfat defaults,auto,users,rw,nofail 0 0
ls -l /mnt/usb/Music/
total 160
drwxrwxrwx 1 root root 32768 Apr 2 2016 'Led Zeppelin Remasters [Disc 1]'
drwxrwxrwx 1 root root 32768 Feb 27 2016 'Led Zeppelin Remasters [Disc 2]'
drwxrwxrwx 1 root root 32768 Apr 2 2016 'Led Zeppelin Remasters [Disc 3]'
drwxrwxrwx 1 root root 32768 Mar 7 04:12 'Ozzy Osbourne'
drwxrwxrwx 1 root root 32768 Apr 2 2016 'Peter Frampton'
Of course, change the above instructions to point to /home/pi/Music
c. Wifi configuration
sudo raspi-config (Network options, Wifi, Follow instructions to set country, SSID, password)
Reboot and check if both connections are active
ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.211 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::24e3:a7a5:5e0e:5156 prefixlen 64 scopeid 0x20<link>
ether b8:27:eb:df:72:56 txqueuelen 1000 (Ethernet)
RX packets 652 bytes 205280 (200.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 150 bytes 23053 (22.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.212 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::46c:c76c:16ad:26b prefixlen 64 scopeid 0x20<link>
ether 00:13:ef:50:0e:f7 txqueuelen 1000 (Ethernet)
RX packets 421 bytes 143549 (140.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 28 bytes 4449 (4.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
d. How to use itunes to convert your owned music CDs to MP3s
ii. Couple of pointers though… Make sure you select mp3 encoder in the import settings, and the itunes folder as organized, select import CD and eject.
iii. With the right settings above, you could just start inserting your CDs and let itunes convert it to mp3, and store it in a nicely organized folder and then eject the cd, so that you could just make a weekend project of converting your music CDs to mp3s.
e. MP3 tagging
i. Fruitbox looks for the mp3 tags in the file and creates a database in /home/pi/fruitbox.db
ii. /home/pi/fuitbox.db is a text file, and you could manually edit it make corrections.
iii. However, you should use some mp3 tagging software to make the corrections.
iv. If you make mp3 tag changes, just remove the fruitbox.db file, and it will get recreated on next launch of fruitbox
9. Made some more changes to skin and buttons and final configuration to look as follows
- After converting all my CDs to mp3's , I realized that I prefer the CD album style layout, so I started with the Granite skin and made the following minor tweaks
- Added a picture of my dogs on top left and top right :)
- Tweaked the "now playing" to show the album art of the CD thats playing
- Moved the "coming up next to next tile"
- Re did my button selections to just have the following key things
- 0 , 1, 2, 3 , Quit, Skip, Up, Down, Left, Right , Clear, Pause, Select, Random
- Providing my skins/Granite/fruitbox.cfg below
- Providing my fruitbox.btn below
- Also, as you might be aware, MacOS creates the ._ files on NAS drives, so I was getting hidden mp3 files etc. which was causing havoc in the media library, so anytime I copy / update the files on my NAS drive now, I use the following two commands on the mac to find and clean the ._ files
- find . -type f -name "._*" -exec ls "{}" \;
- find . -type f -name "._*" -exec rm "{}" \;
skins/Granite/fruitbox.cfg
[general]
SkinName = Granite
SkinDescription = An Albums based 70s skin
SkinSize = 1920 1080
Database = ../fruitbox.db
MusicPath = ../Music/
PageMode = Albums
SortSongsBy Album
SelectButtons = 0
SelectButtons = 0123
#SelectButtons = A
#SelectButtons = 1234
AutoSelect = Yes
SelectTimeout = 150
SelectHoldTimeout = 150
AutoPageTurnTime = 3000
MaxPlaylistLength = 100
AlbumPageMissingArtwork = xgiphy11.jpg
NowPlayingMissingArtwork = splat.png
AlbumPageArtworkMode = Folder
NowPlayingArtworkMode = Folder
AutoPlay = yes
AutoPlayGap = 3000
PlaysPerCoin1 = 0
SongsPerPage = 25
PageSize = 380 720
PairSongs = no
#PageMoveStyle = 20 4 no
PageMoveStyle = 0 4 no
#PageMoveStyle = 12 4 yes
AlbumText = 0 255 255 255 255 centre false true false 0 4 360
ArtistText = 1 128 32 32 255 centre true true false 0 44 360
SongText = 2 0 0 0 255 centre false true false 0 264 260
#SongText = 2 0 0 0 255 centre false true false 0 264 140
PairedSongDescription = AlbumTitle
AlbumArtSize = 160 160
AlbumArtOffset = 120 84
AlbumArtAngle = 0
AlbumPageLineSpacing = 0
[sounds]
LoadSong = 100 recpop.wav
UnloadSong = 100 recpop.wav
InsertCoin = 70 coindrop.wav
PageMove = 70 pagemove.wav
[font]
#File = bauh93.ttf
File = TravellingFixed.ttf
Height = 40
[font]
#File = bauh93.ttf
#File = atwriter.ttf
#Height = 26
#File = hatten.ttf
#Height = 25
File = typewriter.ttf
Height = 36
[font]
#File = bauh93.ttf
#File = dotmatrx.ttf
File = atwriter.ttf
Height = 28
[font]
File = typewriter.ttf
Height = 26
[status]
Contents background_mix.txt
Bitmap = mesh01.jpg
Bitmap = mesh02.jpg
Bitmap = mesh03.jpg
Bitmap = mesh04.jpg
Bitmap = mesh05.jpg
Bitmap = mesh06.jpg
Bitmap = mesh07.jpg
Bitmap = mesh08.jpg
Bitmap = mesh09.jpg
Bitmap = mesh10.jpg
Bitmap = mesh11.jpg
Bitmap = mesh12.jpg
Bitmap = mesh13.jpg
Bitmap = mesh14.jpg
Bitmap = mesh15.jpg
Bitmap = mesh16.jpg
Bitmap = mesh17.jpg
Bitmap = mesh18.jpg
Bitmap = mesh19.jpg
Bitmap = mesh20.jpg
Bitmap = mesh21.jpg
Bitmap = mesh22.jpg
Bitmap = mesh23.jpg
Bitmap = mesh24.jpg
Bitmap = mesh25.jpg
Bitmap = mesh26.jpg
Bitmap = mesh27.jpg
Bitmap = mesh28.jpg
Bitmap = mesh29.jpg
Bitmap = mesh30.jpg
Bitmap = mesh31.jpg
Bitmap = mesh32.jpg
Bitmap = mesh33.jpg
Bitmap = mesh34.jpg
Bitmap = mesh35.jpg
Bitmap = mesh36.jpg
Bitmap = mesh37.jpg
Bitmap = mesh38.jpg
Bitmap = mesh39.jpg
Bitmap = mesh40.jpg
Bitmap = mesh41.jpg
Bitmap = mesh42.jpg
Bitmap = mesh43.jpg
Bitmap = mesh44.jpg
Bitmap = mesh45.jpg
Bitmap = mesh46.jpg
Bitmap = mesh47.jpg
Bitmap = mesh48.jpg
Bitmap = mesh49.jpg
Bitmap = mesh50.jpg
#SkinSize = 1920 1080
#Size width height (in pixels)
#Position x y (in pixels)
#Size = 1904 320
#Position = 8 8
Size = 400 320
Position = 1450 8
TimerTickPeriod = 2
[page]
Background = glass-red.png
Position = 80 320
[page]
Background = glass-green.png
Position = 540 320
[page]
Background = glass-blue.png
Position = 1000 320
[page]
Background = glass-yellow.png
Position = 1460 320
[bitmap]
File = foreground.png
Position = 0 0
Size = 1920 1080
#[status]
#Contents background_mix.txt
#Bitmap = ozzy-01.jpg
#Bitmap = mojo-01.jpg
##Bitmap = ozzy-01.png
##Bitmap = mojo-01.png
##Bitmap = hmv-logo-01.png
##Position = 920 130
#Position = 0 0
#Size = 75 75
#TimerTickPeriod = 40
[status]
Position = 80 80
Size = 840 160
Contents = now_playing.txt
Text = 3 255 255 255 255 left false false false 0 0
TimerTickPeriod = 100
[status]
Position = 790 90
Size = 120 120
Contents = now_playing_artwork.txt
[status]
Position = 1000 80
Size = 840 160
Contents = coming_up.txt
Text = 3 255 255 255 255 left false false false 0 0
[bitmap]
File = elapsed_bar.png
Position = 160 220
#Position = 80 220
Size = 680 8
HorzScale = NowPlayingElapsedTime
HorzScaleMode = Stretched
#[joystick]
#Bitmap = arrow.png
#Offset = -60 140
#Size 240 400
[bitmap]
File = mojo-01.jpg
Position = 0 0
Size = 75 75
[bitmap]
File = ozzy-01.jpg
Position = 1845 0
Size = 75 75
fruitbox.btn
# fruitbox v1.16 button mapping file
# Missing buttons will assume their default values (see user guide)
ButtonQuit = JoyStick 0 5 0
#ButtonCoin1 = JoyStick 0 5 0
#ButtonCoin2 = JoyStick 0 5 0
#ButtonCoin3 = JoyStick 0 5 0
#ButtonCoin4 = JoyStick 0 5 0
#ButtonVol+ = JoyStick 0 5 0
#ButtonVol- = JoyStick 0 5 0
ButtonRandom = JoyButton 0 307
ButtonSelect = JoyButton 0 314
ButtonSkip = JoyButton 0 305
ButtonPause = JoyButton 0 304
ButtonUp = JoyStick 0 4 1
ButtonDown = JoyStick 0 4 0
ButtonLeft = JoyButton 0 310
ButtonRight = JoyButton 0 311
#ButtonLeftJump = JoyStick 0 5 0
#ButtonRightJump = JoyStick 0 5 0
#ButtonLeftAlpha = JoyStick 0 5 1
#ButtonRightAlpha = JoyStick 0 5 1
#ButtonAuto = JoyStick 0 5 1
#ButtonLoop = JoyStick 0 5 1
#ButtonFree = JoyStick 0 5 1
ButtonClear = JoyButton 0 308
#ButtonMute = JoyStick 0 5 1
#ButtonPowerOff = JoyStick 0 5 1
Button0 = JoyStick 0 17 0
Button1 = JoyStick 0 16 0
Button2 = JoyStick 0 17 1
Button3 = JoyStick 0 16 1
#Button4 = JoyStick 0 5 1
#Button5 = JoyStick 0 5 1
#Button6 = JoyStick 0 5 1
#Button7 = JoyStick 0 5 1
#Button8 = JoyStick 0 5 1
#Button9 = JoyStick 0 5 1
#ButtonA = JoyStick 0 5 1
#ButtonB = JoyStick 0 5 1
#ButtonC = JoyStick 0 5 1
#ButtonD = JoyStick 0 5 1
#ButtonE = JoyStick 0 5 1
#ButtonF = JoyStick 0 5 1
#ButtonG = JoyStick 0 5 1
#ButtonH = JoyStick 0 5 1
#ButtonI = JoyStick 0 5 1
#ButtonJ = JoyStick 0 5 1
#ButtonK = JoyStick 0 5 1
#ButtonFlag1 = JoyStick 0 5 1
#ButtonFlag2 = JoyStick 0 5 1
#ButtonFlag3 = JoyStick 0 5 1
#ButtonFlag4 = JoyStick 0 5 1












