def VideoFormatter(target): targetPath = fullPath("data/rawClips/{}.mp4".format(target)) outputPath = fullPath("data/sync_data/{}.mp4".format(target)) prettyPrint(bcolors.OKBLUE, "Formatting data/rawClips/{}.mp4".format(target)) # This is a really long command so here are a bunch of comments explaining it # Step #1: FFMPEG makes two copies, [original] and [copy] # Step #2: Take [copy] and scale it to 16/9 so all videos are the same size, and apply a blur effect to it # Step #3: Append [original] on top of [copy] and output the finished video to data/sync_data prettyPrint( bcolors.ENDC, os.popen( "ffmpeg -i {} -vf 'split[original][copy];[copy]scale=ih*16/9:-1,crop=h=iw*9/16,gblur=sigma=20[blurred];[blurred][original]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2' -video_track_timescale 29971 -ac 1 {}" .format(targetPath, outputPath)).read()) # Checks to make sure the video are valid files try: float( os.popen( "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {}" .format(outputPath)).read()) except Exception as e: prettyPrint( bcolors.WARNING, "Non-viable file, file will be removed. Error code {}".format(e)) os.remove(outputPath) # Cleans up the files and exist the thread os.remove(targetPath) sys.exit("Exiting the thread")
def youtube_detector(timestamp): # Downloading all the YouTube Sources for vid in ytSources: prettyPrint( bcolors.ENDC, os.popen("youtube-dl -o \"{}\" -f mp4 {}".format( fullPath("data/rawVideos/%(id)s.mp4"), fullPath(vid))).read()) # Editing each of the videos for targetVid in os.listdir("data/rawVideos"): cut_video(targetVid)
def reddit_detector(timestamp, source): # Gets the creds from disk with open(fullPath("data/auth.json")) as jsonfile: auth = json.load(jsonfile) # Configures PRAW creds prettyPrint(bcolors.OKBLUE, "Authenticating provided credentials") redditAuth = praw.Reddit(client_id=auth['reddit']['client_id'], client_secret=auth['reddit']['client_secret'], user_agent=auth['reddit']['user_agent'], username=auth['reddit']['username'], password=auth['reddit']['password']) prettyPrint(bcolors.OKBLUE, "Checking and downloading content from {}".format(source)) # Generates a list of moderators, this allows us to filter out their posts mods = [] for moderator in redditAuth.subreddit(source).moderator(): mods.append(str(moderator)) # Downloads all of the videos for targetSubmission in redditAuth.subreddit(source).hot(): if not (os.path.exists( fullPath("data/rawClips/{}.mp4".format( targetSubmission.id)))) and not (os.path.exists( fullPath("data/rawClips/{}.mp4".format( targetSubmission.id)))): if not (str(targetSubmission.author) in mods): prettyPrint( bcolors.OKBLUE, "Thread {} is now downloading {} from {} on Reddit.". format(threading.currentThread().ident, targetSubmission.id, source)) prettyPrint( bcolors.ENDC, os.popen("youtube-dl --no-continue -o \"{}\" {}".format( fullPath("data/rawClips/{}.mp4".format( targetSubmission.id)), targetSubmission.url)).read()) fT = threading.Thread(target=VideoFormatter, args=(targetSubmission.id, )) fT.start()
def newUpload(): with open(fullPath("data/auth.json")) as jsonfile: auth = json.load(jsonfile) opts = webdriver.ChromeOptions() opts.binary_location = "/usr/bin/google-chrome" opts.accept_untrusted_certs = True opts.assume_untrusted_cert_issuer = True for arg in arguments: opts.add_argument(arg) driver = webdriver.Chrome(executable_path="data/browser/chromedriver", options=opts) # Authenticate into Youtube Studio driver.get( "https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&prompt=consent&response_type=code&client_id=407408718192.apps.googleusercontent.com&scope=email&access_type=offline&flowName=GeneralOAuthFlow" ) # Get to upload screen CREATE = driver.find_element_by_id("create-icon").click() UPLOAD = driver.find_element_by_id("text-item-0").click() content = os.listdir(fullPath("data/output"))[0] selectFiles = driver.find_element_by_id("select-files-button").click() selectFiles.send_keys(content) # Publish video to youtube title = "{} memes for {}".format(random.choice(titles), names.get_first_name()) titleBox = driver.find_element_by_id("textbox").send_keys(title) nextButon = driver.find_element_by_id("next-button") nextButon.click() nextButon.click() # Finally uploads the video doneButton = driver.find_element_by_id("done-button").click() driver.close() prettyPrint(bcolors.OKGREEN, "Video finished uploading, closing connection")
import json import os, sys import names import random from selenium import webdriver from selenium.webdriver.chrome.options import Options from webdriver_manager.chrome import ChromeDriver from selenium.webdriver.common.keys import Keys from tooling import prettyPrint, bcolors, fullPath titles = [] # load list from a file (capitalize and remove trailing \n characters) with open(fullPath('data/adjectives.txt')) as f: titles = [line.capitalize().rstrip() for line in f] arguments = [ "--disable-web-security", "--allow-running-insecure-content", "--allow-automation", "--disable-extensions", "--disable-popup-blocking", "--ignore-certificate-errors", "--disable-plugins-discovery", "--user-data-dir=data/browser/secondStump", "--incognito" "user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36'" ] def newUpload(): with open(fullPath("data/auth.json")) as jsonfile: auth = json.load(jsonfile) opts = webdriver.ChromeOptions() opts.binary_location = "/usr/bin/google-chrome"
def GenerateVideo(): # Gets minimum length of video (between 11 and 14 minutes) videoLength = random.randint(660, 841) prettyPrint( bcolors.OKBLUE, "Expected video length is {}".format( datetime.timedelta(seconds=videoLength))) # A list of which clips to use and how long the video is currently clipPaths = [] totalLength = 0 # Randomly selecting clips to add until the video is long enough while (totalLength < videoLength): newChoice = fullPath("data/sync_data/{}".format( random.choice(os.listdir(fullPath("data/sync_data"))))) if newChoice not in clipPaths: try: totalLength += float( os.popen( "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {}" .format(newChoice)).read()) clipPaths.append(newChoice) except Exception as e: prettyPrint( bcolors.WARNING, "Exception thrown, continuing with process. Exception: {}". format(e)) # Just some output for the user prettyPrint( bcolors.OKBLUE, "Actual video length is {} and contains {} videos. All file paths are listed below" .format(datetime.timedelta(seconds=int(totalLength)), len(clipPaths))) # Logs the video files for future reference logString = "" spacing = len(str(datetime.datetime.now())) + 4 for path in clipPaths: logString += "{} || ".format(path) logString += "\n" for x in range(spacing): logString += " " prettyPrint(bcolors.ENDC, logString) # Edits the video together startTime = time.perf_counter() # Creates a list of the input files for FFMPEG with open(fullPath("inputPaths.txt"), "a") as inputPathFile: ouputString = "" for inputPath in clipPaths: ouputString += "file '{}' \n".format(inputPath) inputPathFile.write(ouputString) # Finally edits the clips togeather vidIndex = len(os.listdir(fullPath("/data/output"))) + 1 prettyPrint( bcolors.ENDC, os.popen("ffmpeg -f concat -safe 0 -i {} -c copy {}".format( fullPath("inputPaths.txt"), fullPath("data/output/video_{}.mp4".format(vidIndex)))).read()) os.remove(fullPath("inputPaths.txt")) # A little alert to let the user know the function is over and how long it took endTime = time.perf_counter() prettyPrint( bcolors.OKGREEN, f"Collected clips and edited video. Process took {endTime - startTime:0.4f} seconds" )