forked from mvarhola/comfy-channel
-
Notifications
You must be signed in to change notification settings - Fork 1
/
ComfyChannel.py
executable file
·147 lines (126 loc) · 5.57 KB
/
ComfyChannel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python3
import signal
import sys
import argparse
import random
import psutil
import Config as c
import Logger
import Generator
from datetime import datetime
from os import listdir,getpid
from Client import Client
from MediaItem import MediaItem
from Scheduler import Scheduler
from Server import Server
# Define and explain the arguments that can be passed to the program
def init_args():
parser = argparse.ArgumentParser()
parser.add_argument("-o", "--output", help="output location (stream url)",
action="store")
parser.add_argument("-ua", "--upnext_audio_dir", help="dir for upnext audio files",
action="store")
parser.add_argument("-uv", "--upnext_video_dir", help="dir for upnext video files",
action="store")
parser.add_argument("-uw", "--upnext_wisdom_file", help="file for wisdom text",
action="store")
parser.add_argument("-b", "--bumper_dir", help="dir for bumpers",
action="store")
parser.add_argument("-of", "--overlay_file", help="image to be displayed on the top right of the stream",
action="store")
parser.add_argument("-f", "--font_file", help="font file for overlay text",
action="store")
parser.add_argument("-p", "--playout_file", help="playout config file",
action="store")
parser.add_argument("-1", "--once", help="only run through playout once",
action="store_true")
args = vars(parser.parse_args())
if args['output']:
c.OUTPUT_LOCATION = args['output']
if args['upnext_audio_dir']:
c.SCHEDULER_UPNEXT_AUDIO_FOLDER = args['upnext_audio_dir']
if args['upnext_video_dir']:
c.SCHEDULER_UPNEXT_VIDEO_FOLDER = args['upnext_video_dir']
if args['upnext_wisdom_file']:
c.SCHEDULER_UPNEXT_WISDOM_FILE = args['upnext_wisdom_file']
if args['bumper_dir']:
c.BUMPER_FOLDER = args['bumper_dir']
if args['overlay_file']:
c.OVERLAY_FILE = args['overlay_file']
if args['font_file']:
c.CLIENT_DRAWTEXT_FONT_FILE = args['font_file']
c.SERVER_DRAWTEXT_FONT_FILE = args['font_file']
if args['playout_file']:
c.PLAYOUT_FILE = args['playout_file']
if args['once']:
c.LOOP = False
return args
# Exit program if signal received
def signal_handler(signal, frame):
Logger.LOGGER.log(Logger.TYPE_CRIT,
"{} received, exiting program!".format(signal))
kill_children()
sys.exit(0)
# Kill all processes child to this one
def kill_children():
parent = psutil.Process(getpid())
for child in parent.children(recursive=True):
print("{} pid:{} killed!".format(child.name(), child.pid))
child.kill()
# Play an item to the Server
def play_item(item, index, server):
retries = 0
client = Client(item, index, server)
while True:
ret = client.play()
if ret != 0:
Logger.LOGGER.log(
Logger.TYPE_ERROR, "FFMPEG Return Code {}, trying again".format(ret))
retries += 1
# (if a file fails to play several times consecutively, shut down)
if retries >= c.MAX_SAME_FILE_RETRIES:
Logger.LOGGER.log(
Logger.TYPE_ERROR, "Retry limit reached, giving up!")
return 1
else :
client.stop()
return 0
# Main program
def main():
init_args() # initialize and parse the passed arguments
signal.signal(signal.SIGINT, signal_handler) # Handle CTRL+C
server = Server(c.OUTPUT_LOCATION).start() # Start the server
bumplist = Generator.gen_playlist(c.BUMPER_FOLDER) # Playlist of bumps
consecutive_retries = 0
# Main loop
while True:
c.TIME_INDEX = datetime.now()
scheduler = Scheduler(c.PLAYOUT_FILE) # Create a schedule using full playout file
Logger.LOGGER.log(Logger.TYPE_INFO,
'Scheduler Created, PLAYOUT_FILE: {}'.format(c.PLAYOUT_FILE))
Logger.LOGGER.log(Logger.TYPE_INFO,
'Schedule will end at: {}'.format(c.TIME_INDEX.strftime("%H:%M")))
i = 0
for block in scheduler.blocklist: # Play each block in the schedule
for x in range(len(block.playlist)): # Play each file in the block
ret = play_item(block.playlist[x], i, server)
if ret == 0: # If item played successfully, roll bump chance
# Only attempt bump chance on regular items, and not the last item
if len(bumplist) > 0 and block.playlist[x].media_type == "regular" and x < len(block.playlist) - 1 and random.SystemRandom().random() > 1-block.bump_chance:
Logger.LOGGER.log(Logger.TYPE_INFO,"Bump chance succeeded, playing bump.")
play_item(random.SystemRandom().choice(bumplist), i, server)
else: # else, increment consecutive retries
consecutive_retries += 1
if consecutive_retries >= c.MAX_CONSECUTIVE_RETRIES:
Logger.LOGGER.log(Logger.TYPE_CRIT, "{} Retries consecutive reached, shutting down!".format(consecutive_retries))
kill_children()
sys.exit(0)
i += 1
if not c.LOOP:
Logger.LOGGER.log(Logger.TYPE_INFO,'Schedule Finished, shutting down.')
break
else: Logger.LOGGER.log(Logger.TYPE_INFO,'Schedule Finished, looping.')
server.terminate()
sys.exit(0)
if __name__ == "__main__":
main()