Created
December 23, 2021 18:02
-
-
Save dotcomboom/8797996d23515c502d4aac5f1e99d14d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# IMPORTS | |
from mpd import (MPDClient, CommandError) | |
from random import choice | |
from socket import error as SocketError | |
import sys | |
from sys import exit | |
import time | |
import os | |
## SETTINGS | |
## | |
HOST = 'localhost' | |
PORT = '6600' | |
PASSWORD = False | |
Schedule = [ | |
{ | |
'start': '00:00', # 12am Early Morning 12:00am - 7:00am | |
'end': '07:00', # 7am | |
'folder': 'radio_one_night' | |
}, | |
{ | |
'start': '07:00', # 7am Daytime 7:00am - 12:00pm | |
'end': '19:00', # 7pm | |
'folder': 'radio_one_day' | |
}, | |
{ | |
'start': '19:00', # 7pm Late Evening 7:00pm - 11:59pm | |
'end': '23:59', # 11:59pm | |
'folder': 'radio_one_night' | |
} | |
] | |
queue_max = 4 # max amount of songs in the playlist after the current song | |
# (the higher the number, the further ahead it'll plan) | |
### | |
client = MPDClient() | |
def connect(): | |
print('Trying to connect to MPD...') | |
client.disconnect() | |
while True: | |
try: | |
client.connect(host=HOST, port=PORT) | |
break | |
except Exception as e: | |
print('Could not connect to MPD:', e) | |
time.sleep(5) | |
print("> Prompting MPD database update") | |
client.update() | |
connect() | |
def get_block(ctime: time.struct_time, add_interstitial: bool = False): | |
for block in Schedule: | |
# convert start and end from hh:mm string to struct_time | |
start = time.strptime(block['start'], '%H:%M') | |
end = time.strptime(block['end'], '%H:%M') | |
# convert start and end from struct_time to seconds | |
start = start.tm_hour * 3600 + start.tm_min * 60 | |
end = end.tm_hour * 3600 + end.tm_min * 60 | |
ntime = ctime.tm_hour * 3600 + ctime.tm_min * 60 | |
#print(start, ntime, end) | |
if start <= ntime <= end: | |
#print('Block found:', block['folder']) | |
#if add_interstitial and 'interstitial' in block: | |
# print('Adding interstitial:', block['interstitial']) | |
# client.add(block['interstitial']) | |
return block['folder'] | |
if PASSWORD: | |
try: | |
client.password(PASSWORD) | |
except CommandError: | |
exit(1) | |
def reset(): | |
print('Resetting...') | |
os.execv(sys.executable, ['python'] + sys.argv) | |
exit(0) | |
# # check if volume is lower than 100% | |
# if int(client.status()['volume']) < 100: | |
# change = input('! The current volume is %s%%. Enter a number to change it to, or strike enter to proceed. ' % client.status()['volume']) | |
# if change: | |
# client.setvol(int(change)) | |
prevblock = get_block(time.localtime()) # to hold the block of the previously scheduled song | |
while True: | |
# get what time it is | |
now = time.localtime() | |
# | |
print("Current time: %s:%s:%s (%s)" % (now.tm_hour, now.tm_min, now.tm_sec, get_block(now))) | |
# print the current playlist length | |
# print playing song uri | |
#print(client.currentsong()) | |
# check position in play queue | |
# make sure the playing song is always the first song in the queue | |
# if position is over 0, remove the song at position 0 until position is 0 | |
try: | |
while int(client.status()['song']) > 0: | |
client.delete(0) | |
except KeyError: | |
print('No song playing!') | |
# start playback | |
client.play() | |
pass | |
except ConnectionError: | |
reset() | |
except ConnectionAbortedError: | |
reset() | |
except ConnectionResetError: | |
reset() | |
except ConnectionRefusedError: | |
reset() | |
except Exception as e: | |
print(e) | |
reset() | |
if int(client.status()['playlistlength']) > queue_max: | |
# get current playback time | |
# playback time is in the form cur:length | |
# split the string into two parts | |
# subtract the current position from the length of the song to get the time left | |
c = client.status()['time'] | |
position = int(c.split(':')[0]) | |
duration = int(c.split(':')[1]) | |
left = abs(duration - position) | |
if (left > 0): | |
print("> Playlist max (%s + NP) reached, waiting for song to finish to add another" % queue_max) | |
print(" New song will be added in %s seconds" % left) | |
# add now + time left to get the time when the song ends | |
time.sleep(left) | |
continue | |
duration = 0 | |
# loop through each file in the playlist | |
for f in client.playlistinfo(): | |
#print(f['duration']) | |
duration += float(f['duration']) | |
# get and subtract the current playback elapsed time from the duration | |
print("Remaining queue time:", duration) | |
# Add the duration amount of seconds to the current time to get the projected finish time | |
finish = time.localtime(time.mktime(now) + duration) | |
print("Projected playlist endtime: %s:%s:%s" % (finish.tm_hour, finish.tm_min, finish.tm_sec)) | |
folder = get_block(finish) | |
# check if none | |
if not folder: | |
print("! There is no scheduled programming for the time %s:%s:%s" % (finish.tm_hour, finish.tm_min, finish.tm_sec)) | |
# wait half of the duration of the playlist | |
print(' Waiting %s seconds' % (duration / 2)) | |
time.sleep(duration / 2) | |
continue | |
#if not prevblock == folder: | |
#get_block(finish, add_interstitial=True) # add interstitial | |
prevblock = folder | |
print("Block at endtime: %s" % folder) | |
# add a random song from the folder | |
song = choice(client.listall(folder)) # they really don't recommend using listall but there'd have to be a lot of songs in the folder | |
while (song in client.playlist()) or ('directory' in song.keys()): # if the song is already in the playlist (i think repeats can still happen tho) or is a directory, get a new song | |
song = choice(client.listall(folder)) | |
client.add(song['file']) | |
print('> %s' % song['file']) | |
print(' added to playlist, scheduled to play at %s:%s:%s' % (finish.tm_hour, finish.tm_min, finish.tm_sec)) | |
print() | |
client.disconnect() | |
# VIM MODLINE | |
# vim: ai ts=4 sw=4 sts=4 expandtab |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment