PDA

View Full Version : Using webcam based RasPi and QR-Codes to remote control Squeezebox - But how? PyLMS?



de_ramon
2018-09-20, 04:57
Hi folks,

I want to build a system similar to [1] in order to let my 3 year old child control his Squeezebox Radio.

Steps:

Holding the Cover of a CD including the QR-Code with album and artist under the webcam
Search the lms Library for artist and album
Stop playlist and clear playlist
Add found album to playlist and start playing


I started using PyLMS [2], but was only able to start / stop, etc. I'm not able to search for albums using PyLMS.

Maybe there are other tools?

Any hints?

Thanks,

Ralf

Sorry, not yet able to post URLs
[1] w w w.tilman.de/projekte/audiosphere
[2] github.com/jinglemansweep/PyLMS

mherger
2018-09-20, 06:45
Unless you do this for the fun of doing it, I'd suggest you get a 7" screen, the HDGrid skin, and let your kid select album art from the display, rather than a physical CD cover. Use LMS' custom browse menus to create a section just for your kid. My kids were able to use this system (actually on a Radio with much smaller icons) well before their fourth birthday.

bpa
2018-09-20, 07:07
My german is not good but is this similar
http://www.raspberry-pi-geek.de/Magazin/2014/03/Kindgerechter-Audioplayer-mit-dem-Raspberry-Pi

de_ramon
2018-09-20, 21:42
Hi,

@mherger:
It's not only for fun: at home I want to use this station for controlling the Squeezebox Radio in his room, but outside I can use it as complete stand-alone mp3-player... ok, I could also run a complete LMS on it, but IMHO this is oversized for a mobile jukebox based on raspi with batterypack. Beside that, I like the kids to use paper und not starting to early / to often swiping on displays ;)

@bpa:
This is the solution I already use to play songs outside / offline :)

My problem:

I just need a solution to search on CLI (shell / python / ...) for Albums and add them, if they match, to a playlist....

Start, stop, louder, etc. can be already controlled using PyLMS...

Maybe I did not get the proper handling of PyLMS, it should be able to search... but I didn't get the point....

How can I do this?

DJanGo
2018-09-20, 23:53
I dont know nothing about webcams ;-)
I would buy a cheap barcode scanner cause they work as a keyboard...


Steps:


add each album into a own playlist and name that playlist like the output from the barcodescanner
Holding the Cover of a CD including the QR-Code with album and artist under the webcam


instead your steps i would just make a very simple script like

#! /bin/sh


###vars:
## the mac from your player
playerID="wh:at:ev:er"

## The Path must be the exact path where your lms finds the playlist!
my_playlistpath="/media/music/[playlist]"

## The IP from your LMS System
server=192.168.1.2

## The CLI Port from your LMS
port=9090

read -p "what album to play : " album
if [ -n "$album" ]
then
echo "playing $album"
my_album=$my_playlistpath/$album.m3u
printf "$playerID playlist play $my_album\nexit\n"|nc $server $port
fi

Using this way you have much more freedom and less issues.
You can even make your own artwork with volume up /stop /stop whatever.

Paul Webster
2018-09-21, 01:25
I started using PyLMS [2], but was only able to start / stop, etc. I'm not able to search for albums using PyLMS.

Maybe share your code ... assuming you have tried

playlist_add(item)
Add Item To Playlist

playlist_addalbum(genre=None, artist=None, album=None)
Add an album to the Playlist

playlist_clear()
Clear the entire playlist. Will stop the player.


UPDATE:
Looks like the version of pylms that includes loadalbum is not in PIP.
But - it is only a wrapper for the matching LMS command ... so something like
player.request('playlist loadalbum * A%20Flat%20Man Ivor%20Cutler')

Note - URL encoding of parameters - and * means "all genres".
I think loadalbum is case sensitive

de_ramon
2018-09-21, 01:36
Hi DJanGo,

thanks for your post...

Barcode-Scanners do not look that good :)

Take a look:

http://www.raspberry-pi-geek.de/var/rpg/storage/images/magazin/2014/03/kindgerechter-audioplayer-mit-dem-raspberry-pi/abbildung-42/11183-1-ger-DE/Abbildung-4_lightbox.png
http://www.tilman.de/projekte/musikrakete/
http://tilman.de/projekte/audiosphere/
https://forum-raspberrypi.de/forum/thread/13144-projekt-jukebox4kids-jukebox-fuer-kinder/?pageNo=32


That's I like to build :)

QR-Codes are easy to create and read:
https://github.com/rheikvaneyck/QRMusic


BUT:
I do not use playlists on my LMS :-|

What for? I select albums in the player or via iPeng...

So my playlist-directory only has entries for radio-stations :eek:

SO:
I need to search / query the database for albums and add them to the playlist (as I'm doing it right now via iPeng on iPhone or on WebGUI).

Please help...

Thx,

Ralf

de_ramon
2018-09-21, 02:11
Hi Paul,

you are right :p

Here my code:


#!/usr/bin/env python

from pylms.server import Server
from pylms.player import Player

sc = Server(hostname="192.168.120.4", port=9090, username="", password="")
sc.connect()
sq = sc.get_player("10:dd:b1:d0:14:d3")

print "--== Server Info ==--"
print "Logged in: %s" % sc.logged_in
print "Version: %s" % sc.get_version()
print ""
print "--== Player Info ==--"
print "Name: %s | Mode: %s | Time: %s | Connected: %s | WiFi: %s" % (sq.get_name(), sq.get_mode(), sq.get_time_elapsed(), sq.is_connected, sq.get_wifi_signal_strength())
print ""
print "--== Song Info ==--"
print "Artist: ", sq.get_track_artist()
print "Album: ", sq.get_track_album()
print "Title: ", sq.get_track_title()
print "Restzeit: ", sq.get_time_remaining()
print ""
print "--== Test ==--"

## Pause (repeating pause does not start playing!)
#sq.pause()
#sq.unpause()
## Play
#sq.play()

sq.playlist_addalbum(genre=None, artist=Metallica, album=Load)
# Logged in: True
# Version: 7.7.6
# Name: SqueezeLite | Mode: stop | Time: 0.0 | Connected: True | WiFi: 0
#
# 0
# Traceback (most recent call last):
# File "./pylms_squeezelite_01.py", line 25, in <module>
# sq.playlist_addalbum(genre=None, artist=Metallica, album=Load)
# AttributeError: 'Player' object has no attribute 'playlist_addalbum'

# Clearing playlist works
# sq.playlist_clear()


and output


--== Server Info ==--
Logged in: True
Version: 7.9.1

--== Player Info ==--
Name: SqueezeLite | Mode: play | Time: 190.64260216 | Connected: True | WiFi: 0

--== Song Info ==--
Artist: Aimless
Album: Dark Comes To Light
Title: So We Are...
Restzeit: 177.387717928

--== Test ==--
Traceback (most recent call last):
File "./pylms_squeezelite_01.py", line 31, in <module>
sq.playlist_addalbum(genre=None, artist=Metallica, album=Load)
AttributeError: 'Player' object has no attribute 'playlist_addalbum'


So how to search and how to add the result to the actual playlist?

thx,

Ralf

Paul Webster
2018-09-21, 03:09
"AttributeError: 'Player' object has no attribute 'playlist_addalbum'"

See my edited answer above ... looks like the version of pyLMS with that in has not been pushed to PyPi ... so I have raised an issue for it in GitHub and suggested a work-around above.

DJanGo
2018-09-21, 04:14
Hi DJanGo,

thanks for your post...

Barcode-Scanners do not look that good :)
Thx,

Ralf

Well, these things can dismantled and put back together in every shape you like and where they fit ;-)

I've done plenty of such devices some with barcode, or rfid but everyone had to start with 90% of the steps already done before i started with hardware.

maybe it because of my bad english, maybe its not but i didnt understand what you want in the end.

Adding a album to a players playlist has nothing to do with searching if you hold something with any kind of information to a device that reads that information.
The searching process is already done before otherwise you cant show the code/information to that reading device.

de_ramon
2018-09-21, 04:19
Paul,

thank you! So now I'm on the way....

Here my Code that works to add Album "Load" from "Metallica"



#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, sys
from pylms.server import Server
from pylms.player import Player

sc = Server(hostname="192.168.120.4", port=9090, username="", password="")
sc.connect()
sq = sc.get_player("10:dd:b1:d0:14:d3")



print "--== Server Info ==--"
print "Logged in: %s" % sc.logged_in
print "Version: %s" % sc.get_version()
print ""
print "--== Player Info ==--"
print sq
print "Name: %s | Mode: %s | Time: %s | Connected: %s | WiFi: %s" % (sq.get_name(), sq.get_mode(), sq.get_time_elapsed(), sq.is_connected, sq.get_wifi_signal_strength())
print ""
print "--== Test ==--"

# Works :)
sq.request('playlist loadalbum * Metallica Load')


But now the next problem to be faced with :mad:

non ASCII characters:



./pylms_squeezelite_test.py
--== Server Info ==--
Logged in: True
Version: 7.9.1

--== Player Info ==--
Player: 10:dd:b1:d0:14:d3
Name: SqueezeLite | Mode: play | Time: 11.0323789711 | Connected: True | WiFi: 0

--== Test ==--
Traceback (most recent call last):
File "./pylms_squeezelite_test.py", line 27, in <module>
sq.request('playlist loadalbum * Der%20Grüffelo Der%20Grüffelo')
File "build/bdist.linux-x86_64/egg/pylms/player.py", line 75, in request
File "build/bdist.linux-x86_64/egg/pylms/server.py", line 80, in request
File "build/bdist.linux-x86_64/egg/pylms/server.py", line 222, in __encode
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 47: ordinal not in range(128)


Same problem, different part of code here: https://github.com/jinglemansweep/PyLMS/issues/6

Any hints? :-|

Thx,

Ralf

Paul Webster
2018-09-21, 05:43
I assume that you need to URLEncode the extended characters as well.

Probably use urllib.quote (Python2) or urllib.parse.quote (Python3) ... or work out how to write it using something that works with both Python versions.

de_ramon
2018-09-21, 07:04
Hi Paul,

thanks! You are my hero!!



#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import os, sys
from pylms.server import Server
from pylms.player import Player
import urllib
import urllib2

sc = Server(hostname="192.168.120.4", port=9090, username="", password="")
sc.connect()
sq = sc.get_player("10:dd:b1:d0:14:d3")

print "--== Server Info ==--"
print "Logged in: %s" % sc.logged_in
print "Version: %s" % sc.get_version()
print ""
print "--== Player Info ==--"
print sq
print "Name: %s | Mode: %s | Time: %s | Connected: %s | WiFi: %s" % (sq.get_name(), sq.get_mode(), sq.get_time_elapsed(), sq.is_connected, sq.get_wifi_signal_strength())
print ""
print "--== Adding Album to playlist ==--"

# Assuming QR import by zbarcam
artist_qr = 'Der Grüffelo'
album_qr = 'Der Grüffelo'


# 'URLling' the strings...
genre = '*'
#artist = '*'
artist = urllib.quote(artist_qr)
#album = '*'
album = urllib.quote(album_qr)
# Play album
print "Playing album -=",album_qr,"=- from -=",artist_qr,"=-"
sq.request("playlist loadalbum %s %s %s" % (genre, artist, album))
print ""
# Show info
print "--== Song Info ==--"
print "Artist: ", sq.get_track_artist()
print "Album: ", sq.get_track_album()
print "Title: ", sq.get_track_title()
print "Remaining: ", sq.get_time_remaining()


works for adding albums, only the output of get_track and get_album had to be fixed but are still ugly....



--== Server Info ==--
Logged in: True
Version: 7.9.1

--== Player Info ==--
Player: 10:dd:b1:d0:14:d3
Name: SqueezeLite | Mode: play | Time: 123.331089235 | Connected: True | WiFi: 0

--== Adding Album to playlist ==--
Playing album -= Der Grüffelo =- from -= Der Grüffelo =-

--== Song Info ==--
Artist: Der GrAffelo
Album: Der GrAffelo
Title: Der GrAffelo Track 1
Remaining: 282.946


I had to add


import unicodedata
....
result = result.strip()
# new line
result = unicodedata.normalize('NFD', result).encode('ascii','ignore')
return result


like mentioned here https://github.com/jinglemansweep/PyLMS/issues/6

So I've to get into github, clone that stuff and fix it next days....

Any hint for the result enconding stuff?

thx,

Ralf

Paul Webster
2018-09-21, 07:37
This should do it - and I think will work on Python2 and Python3
You will need to install Python module "future"



from future.standard_library import install_aliases
install_aliases()

from urllib.parse import quote, unquote


...



strencartist = quote('Biréli Lagrène')
strencalbum = quote('Move')
player.request('playlist loadalbum * '+strencartist+' '+strencalbum)


I have it playing right now using a version of that (in my case - activated by voice through a Google AIY VoiceKit)