Skip to content

Instantly share code, notes, and snippets.

@dotcomboom
Created December 23, 2021 18:02
Show Gist options
  • Save dotcomboom/8797996d23515c502d4aac5f1e99d14d to your computer and use it in GitHub Desktop.
Save dotcomboom/8797996d23515c502d4aac5f1e99d14d to your computer and use it in GitHub Desktop.
#!/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