diff --git a/assets/Shiny Channel Art/VNNLogo.png b/assets/Shiny Channel Art/VNNLogo.png new file mode 100644 index 0000000..183b370 Binary files /dev/null and b/assets/Shiny Channel Art/VNNLogo.png differ diff --git a/assets/Shiny Channel Art/VNNLogo.xcf b/assets/Shiny Channel Art/VNNLogo.xcf new file mode 100644 index 0000000..df00161 Binary files /dev/null and b/assets/Shiny Channel Art/VNNLogo.xcf differ diff --git a/assets/tvchannelnotes.txt b/assets/tvchannelnotes.txt index 780fdd5..0b142e1 100644 --- a/assets/tvchannelnotes.txt +++ b/assets/tvchannelnotes.txt @@ -6,13 +6,15 @@ apt update & upgrade edit /boot/config.txt comment out all hdmi lines -uncomment default overscan lines ??? -add "sdtv_mode=1" and "sdtv_aspect=1" +uncomment default overscan lines ??? (no) +add "sdtv_mode=0" and "sdtv_aspect=1" raspi-config Advanced -> Compositor -> No Display Options->Composite->Yes->Reboot Now +Python3-> sudo pip install moviepy && sudo pip install yt-dlp + ancient abandoned esoteric animations or AAEA for short FansubTV @@ -35,7 +37,7 @@ use NTP to determine when hour is up. station ID fills remaining time. timeToTopOfHour = $((60 - $(date +%M))) -DISPLAY=:0 cvlc --fullscreen --play-and-exit --video-filter "logo{file='/media/aaeachannelbug.png',logo-position=10,opacity=128}" --no-osd '/media/anime/' - +DISPLAY=:0 cvlc --fullscreen --play-and-exit --sub-source logo --logo-position 10 --logo-opacity=128 --logo-file /media/aaeachannelbug.png --no-osd /media/anime/' +yt-dlp -o - "https://www.youtube.com/watch?v=GMef9cY4EAA" | DISPLAY=:0 cvlc --fullscreen --play-and-exit --sub-source logo --logo-position 10 --logo-opacity=128 --logo-file /media/aaeachannelbug.png --no-osd - diff --git a/fakeTV.sh b/fakeTV.sh index 9bd8861..70ccdca 100644 --- a/fakeTV.sh +++ b/fakeTV.sh @@ -1,31 +1,19 @@ -#!/bin/bash - -#HELP: Usage-> fakeTV.sh logo[path to transparent background png] stationIdVideo[path to video file] commericals[path to m3u file] episodes[path to m3u file] - -#ancient abandoned esoteric animations or AAEA for short -#FansubTV - -#Hour by Hour loop script: - -#schedule: -#-Station ID video plays -#-episode (~25 minutes) -#-random commercial block (2.5 minutes) -#-Station ID video plays -#-random commercial block (2.5 minutes) -#-episode (~25 minutes) -#-random commercial block (2.5 minutes) -#-Station ID video plays -#-random commercial block (2.5 minutes) - - -while(true); do - -#station Id video call - - - - - - -done +#!/bin/bash + +#vars + +#The channel bug that displays while the channel is playing episodes +buglocation="/media/zella/anime/aaeachannelbug.png" +#The playlist location +playlist="/media/zella/anime/playlist.m3u" +#the python script location +pyscript="/media/zella/anime/fakeTV.py" + +while(true); do + +python $pyscript + +DISPLAY=:0 cvlc --fullscreen --play-and-exit --sub-source logo --logo-position 10 --logo-opacity=128 --logo-file $buglocation --no-osd $playlist + +done + diff --git a/faketv.py b/faketv.py new file mode 100644 index 0000000..b7330fe --- /dev/null +++ b/faketv.py @@ -0,0 +1,157 @@ +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" + +secondsInHour = 3600 +episodeBlockTime = 1560 +minimumTime = 30 + +def get_next_show_episode(showNumber): + if lineupStack[showNumber].empty(): + return None + else: + return lineupStack[showNumber].pop() + +def get_next_commercial(): + if commercialStack.empty(): + 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_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): + showEpisodes.append(os.path.abspath(file)) + lineupStack.append(showEpisodes) + print("\n Added " + str(len(lineupStack[showNumber])) + " episodes from " + folder + "\n") + showNumberList.append(showNumber) + showNumber += 1 + + + +#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 + + +#time = get_video_length_in_seconds(stationID) + +#print("\n The station ID video length in seconds is: " + str(time) + "\n") + + +print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") +print(" Building Playlist ") +print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") + + +episodesEmptyFlag = False +firstLoop = True +while not episodesEmptyFlag: + if firstLoop: + timeLeft = get_remaining_seconds_in_hour() + else: + timeLeft = secondsInHour + random.shuffle(showNumberList) + showNumberListCount = 0 + while timeLeft > miniumTime: + if timeLeft >= episodeBlockTime: + print("Enough time for an episode block") + #add station id + timeLeft -= get_video_length_in_seconds(stationID) + playlist.write(stationID) + + #add commercial. Maybe add a while loop here to add multiple commercials if one is too short + nextAd = get_next_commercial() + timeLeft -= get_video_length_in_seconds(nextAd) + playlist.write(nextAd) + + #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) + + break + if nextEpisode is None: + episodesEmptyFlag = True + break + #add commercial + else: + + diff --git a/videos/stationid/AAEAStationID.mp4 b/videos/stationid/AAEAStationID.mp4 new file mode 100644 index 0000000..9d6cb23 Binary files /dev/null and b/videos/stationid/AAEAStationID.mp4 differ