Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/vicwomg/pikaraoke
Browse files Browse the repository at this point in the history
  • Loading branch information
vicwomg committed Jan 8, 2021
2 parents a3d6c04 + e848967 commit 69697f3
Show file tree
Hide file tree
Showing 47 changed files with 2,718 additions and 401 deletions.
233 changes: 176 additions & 57 deletions app.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion constants.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "1.0.0"
VERSION = "1.1.0"
118 changes: 74 additions & 44 deletions karaoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
import qrcode
from unidecode import unidecode

import omxclient
import vlcclient
from get_platform import get_platform
from lib import omxclient, vlcclient
from lib.get_platform import get_platform

if get_platform() != "windows":
from signal import SIGALRM, alarm, signal
Expand All @@ -33,6 +32,7 @@ class Karaoke:
available_songs = []
now_playing = None
now_playing_filename = None
now_playing_user = None
now_playing_transpose = 0
is_paused = True
process = None
Expand All @@ -55,12 +55,13 @@ def __init__(
log_level=logging.DEBUG,
splash_delay=2,
youtubedl_path="/usr/local/bin/youtube-dl",
omxplayer_path="/usr/bin/omxplayer",
omxplayer_path=None,
use_omxplayer=False,
use_vlc=True,
vlc_path=None,
vlc_port=None,
logo_path=None,
show_overlay=False
):

# override with supplied constructor args if provided
Expand All @@ -80,6 +81,7 @@ def __init__(
self.vlc_path = vlc_path
self.vlc_port = vlc_port
self.logo_path = self.default_logo_path if logo_path == None else logo_path
self.show_overlay = show_overlay

# other initializations
self.platform = get_platform()
Expand Down Expand Up @@ -111,7 +113,8 @@ def __init__(
Use VLC: %s
VLC path: %s
VLC port: %s
log_level: %s"""
log_level: %s
show overlay: %s"""
% (
self.port,
self.hide_ip,
Expand All @@ -130,6 +133,7 @@ def __init__(
self.vlc_path,
self.vlc_port,
log_level,
self.show_overlay
)
)

Expand Down Expand Up @@ -161,16 +165,20 @@ def __init__(
# clean up old sessions
self.kill_player()

self.generate_qr_code()
if self.use_vlc:
self.vlcclient = vlcclient.VLCClient(port=self.vlc_port, path=self.vlc_path)
if (self.show_overlay):
self.vlcclient = vlcclient.VLCClient(port=self.vlc_port, path=self.vlc_path, qrcode=self.qr_code_path, url=self.url)
else:
self.vlcclient = vlcclient.VLCClient(port=self.vlc_port, path=self.vlc_path)
else:
self.omxclient = omxclient.OMXClient(path=self.omxplayer_path, adev=self.omxplayer_adev, dual_screen=self.dual_screen, volume_offset=self.volume_offset)

if not self.hide_splash_screen:
self.generate_qr_code()
self.initialize_screen()
self.render_splash_screen()


# Other ip-getting methods are unreliable and sometimes return 127.0.0.1
# https://stackoverflow.com/a/28950776
def get_ip(self):
Expand Down Expand Up @@ -224,7 +232,14 @@ def is_network_connected(self):

def generate_qr_code(self):
logging.debug("Generating URL QR code")
img = qrcode.make(self.url)
qr = qrcode.QRCode(
version=1,
box_size=1,
border=4,
)
qr.add_data(self.url)
qr.make()
img = qr.make_image()
self.qr_code_path = os.path.join(self.base_path, "qrcode.png")
img.save(self.qr_code_path)

Expand Down Expand Up @@ -302,26 +317,29 @@ def render_splash_screen(self):
logo_rect = logo.get_rect(center=self.screen.get_rect().center)
self.screen.blit(logo, logo_rect)

blitY = self.screen.get_rect().bottomleft[1] - 40

if not self.hide_ip:
p_image = pygame.image.load(self.qr_code_path)
p_image = pygame.transform.scale(p_image, (150, 150))
self.screen.blit(p_image, (20, 20))
self.screen.blit(p_image, (20, blitY - 125))
if not self.is_network_connected():
text = self.font.render(
"Wifi/Network not connected. Shutting down in 10s...",
True,
(255, 255, 255),
)
self.screen.blit(text, (p_image.get_width() + 35, 20))
self.screen.blit(text, (p_image.get_width() + 35, blitY))
time.sleep(10)
sys.exit(
logging.info(
"No IP found. Network/Wifi configuration required. For wifi config, try: sudo raspi-config or the desktop GUI: startx"
)
self.stop()
else:
text = self.font.render(
"Connect at: " + self.url, True, (255, 255, 255)
)
self.screen.blit(text, (p_image.get_width() + 35, 20))
self.screen.blit(text, (p_image.get_width() + 35, blitY))

if (
self.raspi_wifi_config_installed
Expand All @@ -342,28 +360,32 @@ def render_splash_screen(self):
True,
(255, 255, 255),
)
y1 = self.height - text1.get_height() - 80
y2 = self.height - text2.get_height() - 40
y3 = self.height - text2.get_height() - 5
self.screen.blit(text1, (10, y1))
self.screen.blit(text2, (10, y2))
self.screen.blit(text3, (10, y3))
self.screen.blit(text1, (10, 10))
self.screen.blit(text2, (10, 50))
self.screen.blit(text3, (10, 90))

def render_next_song_to_splash_screen(self):
if not self.hide_splash_screen:
self.render_splash_screen()
if len(self.queue) >= 1:
logging.debug("Rendering next song to splash screen")
next_song = self.filename_from_path(self.queue[0])
next_song = self.queue[0]["title"]
max_length = 60
if (len(next_song) > max_length):
next_song = next_song[0:max_length] + "..."
next_user = self.queue[0]["user"]
font_next_song = pygame.font.SysFont(pygame.font.get_default_font(), 60)
text = font_next_song.render(
"Up next: %s" % unidecode(next_song), True, (0, 128, 0)
"Up next: %s" % (unidecode(next_song)), True, (0, 128, 0)
)
up_next = font_next_song.render("Up next: ", True, (255, 255, 0))
up_next = font_next_song.render("Up next: " , True, (255, 255, 0))
font_user_name = pygame.font.SysFont(pygame.font.get_default_font(), 50)
user_name = font_user_name.render("Added by: %s " % next_user, True, (255, 120, 0))
x = self.width - text.get_width() - 10
y = self.height - text.get_height() - 5
y = 5
self.screen.blit(text, (x, y))
self.screen.blit(up_next, (x, y))
self.screen.blit(user_name, (self.width - user_name.get_width() - 10, y + 50))
return True
else:
logging.debug("Could not render next song to splash. No song in queue")
Expand Down Expand Up @@ -394,7 +416,7 @@ def get_search_results(self, textToSearch):
def get_karaoke_search_results(self, songTitle):
return self.get_search_results(songTitle + " karaoke")

def download_video(self, video_url, enqueue=False):
def download_video(self, video_url, enqueue=False, user="Pikaraoke"):
logging.info("Downloading video: " + video_url)
dl_path = self.download_path + "%(title)s---%(id)s.%(ext)s"
file_quality = (
Expand All @@ -415,7 +437,7 @@ def download_video(self, video_url, enqueue=False):
y = self.get_youtube_id_from_url(video_url)
s = self.find_song_by_youtube_id(y)
if s:
self.enqueue(s)
self.enqueue(s, user)
else:
logging.error("Error queueing song: " + video_url)
else:
Expand Down Expand Up @@ -522,13 +544,19 @@ def is_file_playing(self):
self.now_playing = None
return False

def enqueue(self, song_path):
if song_path in self.queue:
logging.warn("Song already in queue, will not add: " + song_path)
def is_song_in_queue(self, song_path):
for each in self.queue:
if each["file"] == song_path:
return True
return False

def enqueue(self, song_path, user="Pikaraoke"):
if (self.is_song_in_queue(song_path)):
logging.warn("Song is already in queue, will not add: " + song_path)
return False
else:
logging.info("Adding video to queue: " + song_path)
self.queue.append(song_path)
logging.info("'%s' is adding song to queue: %s" % (user, song_path))
self.queue.append({"user": user, "file": song_path, "title": self.filename_from_path(song_path)})
return True

def queue_add_random(self, amount):
Expand All @@ -540,10 +568,10 @@ def queue_add_random(self, amount):
i = 0
while i < amount:
r = random.randint(0, len(songs) - 1)
if songs[r] in self.queue:
if self.is_song_in_queue(songs[r]):
logging.warn("Song already in queue, trying another... " + songs[r])
else:
self.queue.append(songs[r])
self.queue.append({"user": "Randomizer", "file": songs[r], "title": self.filename_from_path(songs[r])})
i += 1
songs.pop(r)
if len(songs) == 0:
Expand All @@ -558,38 +586,38 @@ def queue_clear(self):

def queue_edit(self, song_name, action):
index = 0
song_path = None
song = None
for each in self.queue:
if song_name in each:
song_path = each
if song_name in each["file"]:
song = each
break
else:
index += 1
if song_path == None:
logging.error("Song not found in queue: " + song_name)
if song == None:
logging.error("Song not found in queue: " + song["file"])
return False
if action == "up":
if index < 1:
logging.warn("Song is up next, can't bump up in queue: " + song_path)
logging.warn("Song is up next, can't bump up in queue: " + song["file"])
return False
else:
logging.info("Bumping song up in queue: " + song_path)
logging.info("Bumping song up in queue: " + song["file"])
del self.queue[index]
self.queue.insert(index - 1, song_path)
self.queue.insert(index - 1, song)
return True
elif action == "down":
if index == len(self.queue) - 1:
logging.warn(
"Song is already last, can't bump down in queue: " + song_path
"Song is already last, can't bump down in queue: " + song["file"]
)
return False
else:
logging.info("Bumping song down in queue: " + song_path)
logging.info("Bumping song down in queue: " + song["file"])
del self.queue[index]
self.queue.insert(index + 1, song_path)
self.queue.insert(index + 1, song)
return True
elif action == "delete":
logging.info("Deleting song from queue: " + song_path)
logging.info("Deleting song from queue: " + song["file"])
del self.queue[index]
return True
else:
Expand Down Expand Up @@ -696,6 +724,7 @@ def pygame_reset_screen(self):
def reset_now_playing(self):
self.now_playing = None
self.now_playing_filename = None
self.now_playing_user = None
self.is_paused = True
self.now_playing_transpose = 0

Expand All @@ -716,7 +745,8 @@ def run(self):
while i < (self.splash_delay * 1000):
self.handle_run_loop()
i += self.loop_interval
self.play_file(self.queue[0])
self.play_file(self.queue[0]["file"])
self.now_playing_user=self.queue[0]["user"]
self.queue.pop(0)
elif not pygame.display.get_active() and not self.is_file_playing():
self.pygame_reset_screen()
Expand Down
Empty file added lib/__init__.py
Empty file.
File renamed without changes.
File renamed without changes.
12 changes: 10 additions & 2 deletions vlcclient.py → lib/vlcclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import requests

from get_platform import get_platform
from lib.get_platform import get_platform


def get_default_vlc_path(platform):
Expand All @@ -28,7 +28,7 @@ def get_default_vlc_path(platform):
return "/usr/bin/vlc"

class VLCClient:
def __init__(self, port=5002, path=None):
def __init__(self, port=5002, path=None, qrcode=None, url=None):

# HTTP remote control server
self.http_password = "".join(
Expand All @@ -39,6 +39,9 @@ def __init__(self, port=5002, path=None):
self.http_command_endpoint = self.http_endpoint + "?command="
self.is_transposing = False

self.qrcode = qrcode
self.url = url

# Handle vlc paths
self.platform = get_platform()
if path == None:
Expand Down Expand Up @@ -82,11 +85,16 @@ def __init__(self, port=5002, path=None):
"--macosx-continue-playback",
"0",
]
if self.qrcode and self.url:
self.cmd_base += self.get_marquee_cmd()

logging.info("VLC command base: " + " ".join(self.cmd_base))

self.volume_offset = 10
self.process = None

def get_marquee_cmd(self):
return ["--sub-source", 'logo{file=%s,position=9,x=2,opacity=200}:marq{marquee="Pikaraoke - connect at: \n%s",position=9,x=38,color=0xFFFFFF,size=11,opacity=200}' % (self.qrcode, self.url)]

def handle_zipped_cdg(self, file_path):
extracted_dir = os.path.join(self.tmp_dir, "extracted")
Expand Down
8 changes: 3 additions & 5 deletions scripts/prepare_pi_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,24 @@ cd ~/pikaraoke
git checkout master
git pull

echo
echo "*** Clearing the songs dir ***"
sudo rm -rf /usr/lib/pikaraoke

echo
echo "*** Removing WPA supplicant saved wifi settings ***"
sudo rm -rf /etc/wpa_supplicant/wpa_supplicant.conf

echo
echo "*** Double-checking /usr/share/alsa/alsa.conf"
cat /usr/share/alsa/alsa.conf | grep "defaults.ctl.card "
cat /usr/share/alsa/alsa.conf | grep "defaults.pcm.card "
echo "^ the above values should be set to 0, not 1"

echo
echo "*** Double-checking /etc/rc.local expecting to see a line about launching pikaraoke:"
cat /etc/rc.local | grep pikaraoke

echo
echo "*** Double-checking we have a wpa_supplicant example file in /boot"
ls -la /boot/wpa_supplicant.conf.example

echo "*** Expecting hostname to be 'pikaraoke'"
hostname

fi
Loading

2 comments on commit 69697f3

@Hartebee5t
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WOW!
I love the new look-and-feel and the feature upgrades in 1.1.0.

Great work!

@vicwomg
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'm quite happy with this one!

Thank you for being an active contributor and offering feedback for so long now. Honestly, if it weren't for that, I would have gotten bored of making improvements a long time ago.

Please sign in to comment.