mt_clockwheel/mt_clockwheel.py

155 lines
5.4 KiB
Python
Raw Normal View History

2023-08-25 11:36:58 -04:00
import argparse
import datetime
from glob import glob
2023-08-25 11:36:58 -04:00
import json
from listdict import ListDict
2023-08-25 11:36:58 -04:00
import os
# globals
mediadir = "/var/lib/ffplayout/tv-media"
playlistdir = "/var/lib/ffplayout/playlists"
channel = "newellijaytelevision"
verbose = False
from_date = datetime.date.today()
to_date = datetime.date.today()
playlist_duration = 6 * 60 * 60 # six hours, in seconds
mediadirs = ListDict()
2023-08-25 11:36:58 -04:00
def main():
parse_config()
get_media_dirs(mediadir)
2023-08-25 11:49:39 -04:00
for single_date in daterange(from_date, to_date):
if verbose:
print("Processing date", single_date)
daylist = build_day(single_date)
daylist_path = playlistdir + "/" + channel + "/" + single_date.strftime("%Y") + "/" + single_date.strftime("%m") + "/" + single_date.strftime("%d") + "/"
if not os.path.isdir(daylist_path):
os.makedirs(daylist_path)
daylist_file = single_date.strftime("%Y") + "-" + single_date.strftime("%m") + "-" + single_date.strftime("%d") + ".json"
with open(daylist_path + daylist_file, "w") as file:
file.write(daylist)
if verbose:
print('wrote playlist file', daylist_path + daylist_file)
2023-08-25 11:36:58 -04:00
def parse_config():
global mediadir, playlistdir, channel, verbose, from_date, to_date, playlist_duration
2023-08-25 11:36:58 -04:00
parser = argparse.ArgumentParser(
prog="mt_clockwheel",
description="a simple clockwheel playlist generator for ffplayout",
epilog="brought to you by your friends at Mountain Town Technology and Community Media Network"
)
parser.add_argument('-d', '--directory', dest='mediadir', help='root directory for media library')
parser.add_argument('-p', '--playlists', dest='playlistdir', help='root directory for playlists')
parser.add_argument('-c', '--channel', dest='channel', help='channel name to generate playlists for')
parser.add_argument('-v', '--verbose', action='store_true', help='provide verbose output logging')
parser.add_argument('-f', '--from', dest='from_date', help='first date to generate playlist for')
parser.add_argument('-t', '--to', dest='to_date', help='last date to generate playlist for')
parser.add_argument('-l', '--length', dest='playlist_duration', help='duration (in seconds) for each playlist - if a factor of 24 * 60 * 60 then playlist will be duplicated to fill 24 hours')
2023-08-25 11:36:58 -04:00
args = parser.parse_args()
if args.verbose:
verbose = True
if args.mediadir:
mediadir = args.mediadir
if args.playlistdir:
playlistdir = args.playlistdir
if args.channel:
channel = args.channel
if args.from_date:
2023-08-25 11:49:39 -04:00
from_date = datetime.datetime.strptime(args.from_date, "%Y-%m-%d").date()
2023-08-25 11:36:58 -04:00
if args.to_date:
2023-08-25 11:49:39 -04:00
to_date = datetime.datetime.strptime(args.to_date, "%Y-%m-%d").date()
if args.playlist_duration:
playlist_duration = args.playlist_duration
2023-08-25 11:36:58 -04:00
if verbose:
print("Arguments parsed, config:")
print("mediadir:", mediadir)
print("playlistdir:", playlistdir)
print("channel:", channel)
print("from_date:", from_date)
print("to_date:", to_date)
def get_media_dirs(rootdir):
for file in os.listdir(rootdir):
if file == "Commercials":
pass
elif file == "Television":
get_media_dirs(os.path.join(rootdir, file))
else:
d = os.path.join(rootdir, file)
if os.path.isdir(d):
if verbose:
print("adding " + d + " to media dirs")
mediadirs.add_item(d)
2023-08-25 11:49:39 -04:00
def build_day(this_date):
d = {} # empty dict that will become our JSON output
d["channel"] = channel
d["date"] = this_date.strftime("%Y-%m-%d")
d["program"] = [] # empty list to populate with programs
total_time = 0
get_commercial = False
while total_time < playlist_duration:
entry, length = get_playlist_entry(get_commercial)
d["program"].append(entry)
total_time += length
if length > 0:
get_commercial = not get_commercial
if verbose:
print(' added program:', json.dumps(entry), length)
# TODO: see if playlist_duration is a factor of 24 * 60 * 60 and, if so, duplicate it to fill 24 hours
playlist = json.dumps(d)
if verbose:
print("playlist json:", playlist)
return playlist
def get_playlist_entry(get_commercial):
exts = ['*.mp4', '*.webm', '*.mov']
entry_dir = mediadir + '/Commercials' if get_commercial else mediadirs.choose_random_item()
media_files = ListDict()
found_media = [f for ext in exts
for f in glob(os.path.join(entry_dir, '**', ext), recursive=True)]
for d in found_media:
media_files.add_item(d)
this_file = media_files.choose_random_item() if media_files.length() > 0 else ""
if this_file == "":
return "", 0 # get out of this oopsie situation and try again
# TODO: ffprobe file for duration
entry = {
"in": 0,
"out": 300,
"duration": 300,
"source": this_file
}
if get_commercial:
entry["category"] = "advertisement"
length = entry["duration"]
return entry, length
2023-08-25 11:49:39 -04:00
# generator function to yield single dates from a date range
def daterange(start_date, end_date):
for n in range(int((end_date - start_date).days) + 1): # adding 1 to make the range inclusive
yield start_date + datetime.timedelta(n)
2023-08-25 11:36:58 -04:00
if __name__ == "__main__":
main()