latest updates

This commit is contained in:
Karl 2021-11-14 19:29:35 +00:00
parent 8b433e77f4
commit 7643af19a8
12 changed files with 357 additions and 231 deletions

21
.vscode/launch.json vendored
View File

@ -4,6 +4,13 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{ {
"name": "Screen", "name": "Screen",
"type": "python", "type": "python",
@ -11,6 +18,13 @@
"program": "./screen_output.py", "program": "./screen_output.py",
"console": "integratedTerminal" "console": "integratedTerminal"
}, },
{
"name": "sync-Screen",
"type": "python",
"request": "launch",
"program": "./sync_screen.py",
"console": "integratedTerminal"
},
{ {
"name": "yt diskLoad", "name": "yt diskLoad",
"type": "python", "type": "python",
@ -18,7 +32,10 @@
"program": "./player.py", "program": "./player.py",
"console": "integratedTerminal", "console": "integratedTerminal",
"args": [ "args": [
"Daft Punk RAM - ytmusic:album:MPREb_K8qWMWVqXGi" // "Daft Punk RAM - ytmusic:album:MPREb_K8qWMWVqXGi"
// "-",
// "my likes - ytmusic:playlist:LM"
"Capital Xtra Reloaded - tunein:station:s306339"
// " Xtra Reloaded - http://media-ice.musicradio.com/CapitalXTRAReloadedMP3.m3u" // " Xtra Reloaded - http://media-ice.musicradio.com/CapitalXTRAReloadedMP3.m3u"
] ]
}, },
@ -29,7 +46,7 @@
"program": "./player.py", "program": "./player.py",
"console": "integratedTerminal", "console": "integratedTerminal",
"args": [ "args": [
"stop" "shuffle"
] ]
} }
] ]

View File

@ -1,4 +1,4 @@
Chris Brown Indigo - ytmusic:album:MPREb_jlY9mqAHYjR Chris Brown Indigo - ytmusic:album:MPREb_2UBRpewr9ad
Daft Punk RAM - Daft Punk RAM -
ytmusic:album:MPREb_K8qWMWVqXGi ytmusic:album:MPREb_K8qWMWVqXGi
@ -7,4 +7,4 @@ My Likes -
ytmusic:playlist:LM ytmusic:playlist:LM
Radio Radio
http://media-ice.musicradio.com/CapitalXTRAReloadedMP3.m3u Capital Xtra Reloaded - tunein:station:s306339

70
buttons.py Normal file → Executable file
View File

@ -1,9 +1,9 @@
from gpiozero import Button from gpiozero import Button
from signal import pause from signal import pause
import time import time
import subprocess import subprocess
import beepy as beep import pathlib
Button.was_held = False Button.was_held = False
@ -12,34 +12,44 @@ Button.was_held = False
def vol_up(btn): def vol_up(btn):
btn.was_held = True btn.was_held = True
while btn.was_held: while btn.was_held:
# print("Vol Up") print("Vol Up")
result = subprocess.run( result = subprocess.run(
[f"mpc volume +10"], [f"mpc volume +10"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
shell=True, shell=True,
).stdout.decode("utf-8") ).stdout.decode("utf-8")
# beep(sound=1) time.sleep(0.3)
time.sleep(0.5)
def vol_down(btn): def vol_down(btn):
btn.was_held = True btn.was_held = True
while btn.was_held: while btn.was_held:
# print("Vol Down") print("Vol Down")
result = subprocess.run( result = subprocess.run(
[f"mpc volume -10"], [f"mpc volume -10"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
shell=True, shell=True,
).stdout.decode("utf-8") ).stdout.decode("utf-8")
# beep(sound=1) time.sleep(0.3)
time.sleep(0.5)
def mute(btn):
btn.was_held = True
while btn.was_held:
print("Mute")
result = subprocess.run(
[f"mpc volume -10"],
stdout=subprocess.PIPE,
shell=True,
).stdout.decode("utf-8")
time.sleep(0.3)
def playpause_down(btn): def playpause_down(btn):
btn.was_held = True btn.was_held = True
while btn.was_held: while btn.was_held:
print("playpause") print("playpause")
time.sleep(1) time.sleep(0.3)
def released(btn): def released(btn):
@ -49,47 +59,51 @@ def released(btn):
def pressed(btn): def pressed(btn):
if btn._pin.number == 15: if btn._pin.number == up_pin:
# print("next") print("next")
result = subprocess.run( result = subprocess.run(
[f"python ./player.py next"], [f"{pathlib.Path().resolve()}/venv/bin/python3 ./player.py next"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
shell=True, shell=True,
).stdout.decode("utf-8") ).stdout.decode("utf-8")
elif btn._pin.number == 24: elif btn._pin.number == down_pin:
# print("back") print("back")
result = subprocess.run( result = subprocess.run(
[f"python ./player.py previous"], [f"{pathlib.Path().resolve()}/venv/bin/python3 ./player.py previous"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
shell=True, shell=True,
).stdout.decode("utf-8") ).stdout.decode("utf-8")
elif btn._pin.number == 14: elif btn._pin.number == playpause_pin:
# print("playpause") print("playpause")
result = subprocess.run( result = subprocess.run(
[f"python ./player.py playpause"], [f"{pathlib.Path().resolve()}/venv/bin/python3 ./player.py playpause"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
shell=True, shell=True,
).stdout.decode("utf-8") ).stdout.decode("utf-8")
elif btn._pin.number == 23: elif btn._pin.number == shuffle_pin:
# print("shuffle") print("shuffle")
result = subprocess.run( result = subprocess.run(
[f"python ./player.py shuffle"], [f"{pathlib.Path().resolve()}/venv/bin/python3 ./player.py shuffle"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
shell=True, shell=True,
).stdout.decode("utf-8") ).stdout.decode("utf-8")
up_btn = Button(15) up_pin = 24
down_button = Button(24) down_pin = 15
playpause_button = Button(14) playpause_pin = 14
shuffle_button = Button(23) shuffle_pin = 23
down_button.when_held = vol_down up_btn = Button(up_pin)
down_button.when_released = released down_button = Button(down_pin)
playpause_button = Button(playpause_pin)
shuffle_button = Button(shuffle_pin)
up_btn.when_held = vol_up up_btn.when_held = vol_up
up_btn.when_released = released up_btn.when_released = released
down_button.when_held = vol_down
down_button.when_released = released
playpause_button.when_held = mute
playpause_button.when_released = released playpause_button.when_released = released
shuffle_button.when_released = released shuffle_button.when_released = released
pause() pause()

85
intro.py Normal file
View File

@ -0,0 +1,85 @@
import math
import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
RST = 24
# 128x64 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
# Initialize library.
disp.begin()
# Get display width and height.
width = disp.width
height = disp.height
# Clear display.
disp.clear()
disp.display()
# Create image buffer.
# Make sure to create image with mode '1' for 1-bit color.
image = Image.new('1', (width, height))
# Load default font.
font = ImageFont.load_default()
# Alternatively load a TTF font. Make sure the .ttf font file is in the same directory as this python script!
# Some nice fonts to try: http://www.dafont.com/bitmap.php
# font = ImageFont.truetype('Minecraftia.ttf', 8)
# Create drawing object.
draw = ImageDraw.Draw(image)
# Define text and get total width.
text = 'Floppy Player'
maxwidth, unused = draw.textsize(text, font=font)
# Set animation and sine wave parameters.
amplitude = height/4-10
offset = height/2 - 4
velocity = -2
startpos = width
# Animate text moving in sine wave.
# print('Press Ctrl-C to quit.')
pos = startpos
while True:
# Clear image buffer by drawing a black filled box.
draw.rectangle((0,0,width,height), outline=0, fill=0)
# Enumerate characters and draw them offset vertically based on a sine wave.
x = pos
for i, c in enumerate(text):
# Stop drawing if off the right side of screen.
if x > width:
break
# Calculate width but skip drawing if off the left side of screen.
if x < -10:
char_width, char_height = draw.textsize(c, font=font)
x += char_width
continue
# Calculate offset from sine wave.
y = offset+math.floor(amplitude*math.sin(x/float(width)*2.0*math.pi))
# Draw text.
draw.text((x, y), c, font=font, fill=255)
# Increment x position based on chacacter width.
char_width, char_height = draw.textsize(c, font=font)
x += char_width
# Draw the image buffer.
disp.image(image)
disp.display()
# Move position for next frame.
pos += velocity
# Start over if text has scrolled completely off left side of screen.
if pos < -maxwidth:
break
# Pause briefly before drawing next frame.
time.sleep(0.1)

View File

@ -19,10 +19,10 @@ if [ $? -eq 0 ]; then
echo "$(date) Floppy mounted" echo "$(date) Floppy mounted"
var=$(cat /mnt/floppy/diskplayer.contents) var=$(cat /mnt/floppy/diskplayer.contents)
echo python3 /home/pi/pythonDiskPlayer/player.py \"$var\" echo python3 /home/pi/pythonDiskPlayer/player.py \"$var\"
runuser -l pi -c "python3 /home/pi/pythonDiskPlayer/player.py \"$var\"" runuser -l pi -c "/home/pi/pythonDiskPlayer/venv/bin/python3 /home/pi/pythonDiskPlayer/player.py \"$var\""
else else
echo "$(date) Device does not exist on machine." echo "$(date) Device does not exist on machine."
runuser -l pi -c "python3 /home/pi/pythonDiskPlayer/player.py stop" runuser -l pi -c "/home/pi/pythonDiskPlayer/venv/bin/python3 /home/pi/pythonDiskPlayer/player.py stop"
echo "$(date) Forcing unmount of floppy" echo "$(date) Forcing unmount of floppy"
/usr/bin/systemd-mount --umount /mnt/floppy /usr/bin/systemd-mount --umount /mnt/floppy
fi fi

64
player.py Normal file → Executable file
View File

@ -1,60 +1,64 @@
import asyncio
import argparse import argparse
import pathlib
from mopidy_async_client import MopidyClient from mopidy_json_client import MopidyClient
parser = argparse.ArgumentParser(description="Mopdiy FloppyPlayer") parser = argparse.ArgumentParser(description="Mopdiy FloppyPlayer")
parser.add_argument("URI_string", help="Mopdiy URI to Album/Playlist.") parser.add_argument("URI_string", help="Mopdiy URI to Album/Playlist.")
args = parser.parse_args() args = parser.parse_args()
inputURI = args.URI_string inputURI = args.URI_string
disk_file = f"{pathlib.Path().resolve()}/last_disk.txt"
async def selector(action): mopidy = MopidyClient()
last_disk_read = open("/home/pi/pythonDiskPlayer/last_disk.txt", "r+").read()
def selector(action):
last_disk_read = open(disk_file, "r+").read()
if action is not "" and last_disk_read != action: if action is not "" and last_disk_read != action:
mopidy = await MopidyClient().connect()
if action == "stop": if action == "stop":
await mopidy.playback.stop() mopidy.playback.stop()
await mopidy.tracklist.clear() mopidy.tracklist.clear()
elif action == "next": elif action == "next":
await mopidy.playback.next() mopidy.playback.next()
elif action == "previous": elif action == "previous":
await mopidy.playback.previous() mopidy.playback.previous()
elif action == "shuffle": elif action == "shuffle":
await mopidy.tracklist.shuffle() mopidy.tracklist.shuffle()
await mopidy.tracklist.move( mopidy.tracklist.move(
start=await mopidy.tracklist.index(), start=mopidy.tracklist.index(),
end=await mopidy.tracklist.index(), end=mopidy.tracklist.index(),
to_position=0, to_position=0,
) )
elif action == "playpause": elif action == "playpause":
if await mopidy.playback.get_state() == "playing": if mopidy.playback.get_state() == "playing":
await mopidy.playback.pause() mopidy.playback.pause()
else: else:
await mopidy.playback.resume() mopidy.playback.resume()
elif action == "": elif action == "":
return return
else: else:
last_disk = open("/home/pi/pythonDiskPlayer/last_disk.txt", "w") last_disk = open(disk_file, "w")
last_disk.write(action) last_disk.write(action)
await run_floppy(action) run_floppy(action)
await mopidy.disconnect() mopidy.disconnect()
elif action == "":
pass
else: else:
mopidy = await MopidyClient().connect() if mopidy.playback.get_state() == "playing":
if await mopidy.playback.get_state() == "playing":
return return
else: else:
await run_floppy(action) run_floppy(action)
mopidy.disconnect()
async def run_floppy(input): def run_floppy(input):
link = input.split(" - ")[1] link = input.split(" - ")[1]
mopidy = await MopidyClient().connect() mopidy.playback.stop()
await mopidy.playback.stop() mopidy.tracklist.clear()
await mopidy.tracklist.clear() mopidy.tracklist.add(uris=[link])
await mopidy.tracklist.add(uris=[link]) mopidy.playback.play()
await mopidy.playback.play() mopidy.disconnect()
await mopidy.disconnect()
asyncio.run(selector(inputURI)) selector(inputURI)

View File

@ -5,7 +5,7 @@ black==21.10b0
click==8.0.3 click==8.0.3
future==0.18.2 future==0.18.2
importlib-metadata==4.8.1 importlib-metadata==4.8.1
mopidy-async-client==0.6.4 Mopidy-JSON-Client==0.6.0
mypy-extensions==0.4.3 mypy-extensions==0.4.3
pathspec==0.9.0 pathspec==0.9.0
pkg-resources==0.0.0 pkg-resources==0.0.0

168
screen.py Normal file
View File

@ -0,0 +1,168 @@
from signal import pause
import time
import board
import adafruit_ssd1306
from mopidy_json_client import MopidyClient
from datetime import datetime
def print_oled(data):
oled.fill(0)
oled.text("Floppy Player", 26, 0, 1)
oled.text(data["line1"]["text"], data["line1"]["line"], data["line1"]["row"], 1)
oled.text(data["line2"]["text"], data["line2"]["line"], data["line2"]["row"], 1)
oled.text(data["line3"]["text"], data["line3"]["line"], data["line3"]["row"], 1)
oled.text(data["line4"]["text"], data["line4"]["line"], data["line4"]["row"], 1)
oled.show()
def clear_old():
oled.fill(0)
oled.text("Floppy Player", 26, 0, 1)
oled.text("", 0, 0, 1)
oled.text("", 0, 0, 1)
oled.text("", 0, 0, 1)
oled.text("", 0, 0, 1)
oled.show()
def print_track_info(tl_track, title=False):
track = tl_track.get("track") if tl_track else None
if not track:
print("No Track")
return
if title != False:
print_oled(
{
"line1": {"text": track.get("album").get("name"), "line": 0, "row": 16},
"line2": {
"text": track.get("name"),
"line": 0,
"row": 26,
},
"line3": {"text": title[1], "line": 0, "row": 36},
"line4": {"text": title[0], "line": 0, "row": 46},
}
)
else:
print_oled(
{
"line1": {"text": track.get("name"), "line": 0, "row": 16},
"line2": {
"text": track.get("artists")[0].get("name"),
"line": 0,
"row": 26,
},
"line3": {"text": track.get("album").get("name"), "line": 0, "row": 36},
"line4": {"text": "", "line": 0, "row": 46},
}
)
def stream_title_changed(title):
data = title.split(" - ")
print_track_info(mopidy.playback.get_current_tl_track(), data)
def playback_state_changed(old_state, new_state):
state = new_state
if state == "paused":
print_oled(
{
"line1": {"text": "", "line": 0, "row": 16},
"line2": {"text": "", "line": 0, "row": 26},
"line3": {"text": "Paused", "line": 32, "row": 36},
"line4": {"text": "", "line": 0, "row": 46},
}
)
elif state == "stopped":
print_oled(
{
"line1": {"text": "", "line": 0, "row": 16},
"line2": {"text": "Nothing", "line": 40, "row": 26},
"line3": {"text": "Playing", "line": 40, "row": 36},
"line4": {"text": "Insert a Disk", "line": 25, "row": 46},
}
)
elif state == "playing":
print_track_info(mopidy.playback.get_current_tl_track())
def volume_changed(volume):
global old_vol
if old_vol != volume:
old_vol = volume
print_oled(
{
"line1": {"text": "", "line": 0, "row": 16},
"line2": {"text": "Current Volume", "line": 32, "row": 26},
"line3": {"text": str(volume), "line": 32, "row": 36},
"line4": {"text": "", "line": 0, "row": 46},
}
)
time.sleep(1)
get_state()
def mute_changed(mute):
if mute == True:
print_oled(
{
"line1": {"text": "", "line": 0, "row": 16},
"line2": {"text": "Muted", "line": 32, "row": 26},
"line3": {"text": "", "line": 32, "row": 36},
"line4": {"text": "", "line": 0, "row": 46},
}
)
else:
get_state()
# def options_changed():
# options = {
# "random": mopidy.tracklist.get_random(timeout=10),
# "single": mopidy.tracklist.get_single(timeout=10),
# "consume": mopidy.tracklist.get_consume(timeout=10),
# "repeat": mopidy.tracklist.get_repeat(timeout=10),
# }
# print("Tracklist Options:", options, format="expand")
def seeked(time_position):
print(f" Current Position is {time_position}")
mopidy = MopidyClient()
mopidy.bind_event("track_playback_started", print_track_info)
mopidy.bind_event("playback_state_changed", playback_state_changed)
mopidy.bind_event("stream_title_changed", stream_title_changed)
mopidy.bind_event("volume_changed", volume_changed)
mopidy.bind_event("mute_changed", mute_changed)
mopidy.bind_event("seeked", seeked)
WIDTH = 128
HEIGHT = 64
# Use for I2C.
i2c = board.I2C()
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C)
def get_state():
state = mopidy.playback.get_state()
if state == "playing":
print_track_info(mopidy.playback.get_current_tl_track())
elif state == "paused":
playback_state_changed("running", "paused")
elif state == "stopped":
playback_state_changed("running", "stopped")
old_vol = mopidy.mixer.get_volume()
import intro
clear_old()
get_state()
pause()

View File

@ -1,81 +0,0 @@
import asyncio
import time
import board
import adafruit_ssd1306
from mopidy_async_client import MopidyClient
from datetime import datetime
async def current_track():
mopidy = await MopidyClient().connect()
if await mopidy.playback.get_state() == "stopped":
oled.text("Nothing", 32, 26, 1)
oled.text("Playing", 32, 36, 1)
return
current_track_data = await mopidy.playback.get_current_track()
time_position = datetime.fromtimestamp(
await mopidy.playback.get_time_position() / 1000.0
).strftime("%M:%S")
if "ytmusic" in current_track_data["uri"]:
if "album" in current_track_data:
totalTime = current_track_data["length"]
track_total_length = datetime.fromtimestamp(totalTime / 1000.0).strftime(
"%M:%S"
)
current_data = {
"Artist": current_track_data["artists"][0]["name"],
"Album": current_track_data["album"]["name"],
"Song": current_track_data["name"],
"TrackTime": time_position + "/" + track_total_length,
}
elif "ytmusic:track" in current_track_data["uri"]:
totalTime = current_track_data["length"]
track_total_length = datetime.fromtimestamp(totalTime / 1000.0).strftime(
"%M:%S"
)
current_data = {
"Artist": "-",
"Album": current_track_data["artists"][0]["name"],
"Song": current_track_data["name"],
"TrackTime": time_position + "/" + track_total_length,
}
else:
try:
stream_title = await mopidy.playback.get_stream_title()
artist_and_song = stream_title.split(" - ")
except:
stream_title = "None"
artist_and_song = ['None','None']
current_data = {
"Artist": current_track_data["name"],
"Album": artist_and_song[0],
"Song": artist_and_song[1],
"TrackTime": "",
}
await mopidy.disconnect()
oled.text(current_data["Artist"], 0, 16, 1)
oled.text(current_data["Album"], 0, 26, 1)
oled.text(current_data["Song"], 0, 36, 1)
oled.text(current_data["TrackTime"], 0, 46, 1)
return
WIDTH = 128
HEIGHT = 64
# Use for I2C.
i2c = board.I2C()
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C)
async def main():
while True:
oled.fill(0)
oled.text("Floppy Player", 26, 0, 1)
await current_track()
oled.show()
time.sleep(5)
asyncio.run(main())

3
startupScript Executable file
View File

@ -0,0 +1,3 @@
sudo rm -rf /home/pi/pythonDiskPlayer/mount.log &
screen -S buttons -dm /home/pi/pythonDiskPlayer/venv/bin/python3 /home/pi/pythonDiskPlayer/buttons.py &
screen -S screen -dm /home/pi/pythonDiskPlayer/venv/bin/python3 /home/pi/pythonDiskPlayer/screen.py

View File

@ -1,84 +0,0 @@
import time
import board
import adafruit_ssd1306
from tenacity import retry, stop_after_attempt
from mopidy_json_client import MopidyClient
from datetime import datetime
@retry(stop=stop_after_attempt(5))
def current_track():
mopidy = MopidyClient()
if mopidy.playback.get_state(timeout=5) == "stopped":
oled.text("Nothing", 32, 26, 1)
oled.text("Playing", 32, 36, 1)
return
if mopidy.playback.get_state(timeout=5) == "paused":
oled.text("Paused", 32, 36, 1)
return
current_track_data = mopidy.playback.get_current_track(timeout=5)
time_position = datetime.fromtimestamp(
mopidy.playback.get_time_position(timeout=5) / 1000.0
).strftime("%M:%S")
if "ytmusic" in current_track_data["uri"]:
if "album" in current_track_data:
totalTime = current_track_data["length"]
track_total_length = datetime.fromtimestamp(totalTime / 1000.0).strftime(
"%M:%S"
)
current_data = {
"Artist": current_track_data["artists"][0]["name"],
"Album": current_track_data["album"]["name"],
"Song": current_track_data["name"],
"TrackTime": time_position + "/" + track_total_length,
}
elif "ytmusic:track" in current_track_data["uri"]:
totalTime = current_track_data["length"]
track_total_length = datetime.fromtimestamp(totalTime / 1000.0).strftime(
"%M:%S"
)
current_data = {
"Artist": "-",
"Album": current_track_data["artists"][0]["name"],
"Song": current_track_data["name"],
"TrackTime": time_position + "/" + track_total_length,
}
else:
try:
stream_title = mopidy.playback.get_stream_title(timeout=5)
artist_and_song = stream_title.split(" - ")
except:
stream_title = "None"
artist_and_song = ["None", "None"]
current_data = {
"Artist": current_track_data["album"]["name"],
"Album": artist_and_song[0],
"Song": artist_and_song[1],
"TrackTime": time_position,
}
mopidy.disconnect()
oled.text(current_data["Artist"], 0, 16, 1)
oled.text(current_data["Album"], 0, 26, 1)
oled.text(current_data["Song"], 0, 36, 1)
oled.text(current_data["TrackTime"], 0, 46, 1)
return
WIDTH = 128
HEIGHT = 64
# Use for I2C.
i2c = board.I2C()
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C)
while True:
oled.fill(0)
oled.text("Floppy Player", 26, 0, 1)
current_track()
oled.show()
time.sleep(3)