import cv2 import datetime import math import os import random import subprocess #from moviepy.editor import VideoFileClip #The channel bug that displays while the channel is playing episodes buglocation = "/media/zella/anime/aaeachannelbug.png" #the shows you would like this channel to play in individual folders under this folder shows = "/media/zella/anime/shows" #the "commercials" to fill up extra time in the hour. no folders, just videos in this folder. commercials = "/media/zella/anime/commercials" #the "station id" video that calls out what the channel is. have fun with it. stationID = "/media/zella/anime/stationid/AAEAStationID.mp4" secondsInBlock = 1800 episodeBlockTime = 1560 minimumTime = 30 def get_next_show_episode(showNumber): if len(lineupStack[showNumber]) == 0: return None else: return lineupStack[showNumber].pop() def get_next_commercial(): if len(commercialStack) == 0: for file in os.listdir(commercials): commercialStack.append(os.path.join(commercials,file)) random.shuffle(commercialStack) print("\nCommercial Stack reshuffled.\n" + "\nCommercial returned from stack at size: " + str(len(commercialStack)) + "\n") return commercialStack.pop() else: print("\nCommercial returned from stack at size: " + str(len(commercialStack)) + "\n") return commercialStack.pop() #requires moviepy module. rounded up to nearest whole second, for simplicity. #def get_video_length_in_seconds(videoFile): # clip = VideoFileClip(videoFile) # return math.ceil(clip.duration) def get_video_length_in_seconds(video_path): cap = cv2.VideoCapture(video_path) total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) frame_rate = cap.get(cv2.CAP_PROP_FPS) video_length = total_frames / frame_rate return math.ceil(video_length) def get_remaining_seconds_in_hour(): now = datetime.datetime.now() seconds_left_in_hour = 3600 - now.minute * 60 - now.second return seconds_left_in_hour #Main Thread starts here if os.path.exists("playlist.m3u"): os.remove("playlist.m3u") else: print("\n playlist file does not exist.\n") #open file in append mode playlist = open('playlist.m3u',"a") #a list of stacks of episode paths lineupStack = [] #A list of commercials commercialStack = [] #A list of showNumbers, for use later in shuffling episodes in a round robin manner randomly showNumberList = [] #initialize show lists showNumber = 0 for direc in os.listdir(shows): folder = os.path.join(shows,direc) if os.path.isdir(folder): print("\nOpening show " + str(showNumber) + " folder: " + folder + "\n") showEpisodes = [] for file in os.listdir(folder): print(os.path.join(folder,file)) showEpisodes.append(os.path.join(folder,file)) lineupStack.append(showEpisodes) print("\n Added " + str(len(lineupStack[showNumber])) + " episodes from " + folder + "\n") showNumberList.append(showNumber) showNumber += 1 #reverse each show stack in the lineupStack list so we start from episode 1 for show in lineupStack: show.reverse() #build season lineup station playlist using schedule: #schedule: #for boot hour #get remaining seconds in hour #if more than 30, stationid, play episode and fill rest with commercials and stationid #if less, stationid and fill with commercials #if more than 55, skip and build normal hour #3600 seconds in an hour #timeLeft = 3600 #In each hour: #-Station ID video plays #-episode (~25 minutes) #-random commercial block (2 minutes) #-Station ID video plays #-random commercial block (2 minutes) #-episode (~25 minutes) #-random commercial block (2 minutes) #-Station ID video plays #-random commercial block (2 minutes) #repeat until out of episodes print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") print(" Building Playlist ") print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") episodesEmptyFlag = False firstLoop = True while not episodesEmptyFlag: #generate next episode block (station id + episode + fill in any extra time with commercial spots) if firstLoop: timeLeft = get_remaining_seconds_in_hour() if timeLeft > secondsInBlock: timeLeft -= secondsInBlock; # only use the extra time over the first half hour on the opening block firstLoop = False else: timeLeft = secondsInBlock random.shuffle(showNumberList) showNumberListCount = 0 if timeLeft >= episodeBlockTime: #while there is time left in the 30 minute block #add station id timeLeft -= get_video_length_in_seconds(stationID) playlist.write(stationID + "\n") #add tv episode nextEpisode = "" while showNumberListCount < len(showNumberList): nextEpisode = get_next_show_episode(showNumberList[showNumberListCount]) if nextEpisode is None: showNumberListCount += 1 continue else: showNumberListCount += 1 timeLeft -= get_video_length_in_seconds(nextEpisode) playlist.write(nextEpisode + "\n") print("\nEpisode " + nextEpisode + " added to playlist. " + str(len(lineupStack[showNumberList[showNumberListCount - 1]])) + " episodes left in stack\n") break if nextEpisode is None: print("Episodes exhausted! Completing Playlist!\n") episodesEmptyFlag = True break #add commercial. while timeLeft > minimumTime: nextAd = get_next_commercial() comLength = get_video_length_in_seconds(nextAd) if timeLeft > comLength: timeLeft -= comLength playlist.write(nextAd + "\n") print("\nCommercial " + nextAd + " added to playlist.\n") else: print("\nCommercial too long. retrying...\n") else: #no time for furtur episodes this hour print("Not enough time for another episode this hour. Padding") #add commercial. while timeLeft > minimumTime: nextAd = get_next_commercial() comLength = get_video_length_in_seconds(nextAd) if timeLeft > comLength: timeLeft -= comLength playlist.write(nextAd + "\n") print("\nCommercial " + nextAd + " added to playlist.\n") else: print("\nCommercial too long. retrying...\n") print("playlist file creation complete")