├── .gitignore ├── README.MD ├── bot.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | howitsmadebot -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | #How it's made bot 2 | ##Created by /u/LewisTheScot 3 | 4 | ###**Use ffmpeg to grab random times of the video downloaded. Otherwise it won't work** 5 | 6 | This is a bot I am working on just to practice some stuff with python 7 | 8 | ENJOY :) 9 | 10 | -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | # Imports 2 | from urllib.request import urlopen 3 | from moviepy.video.io.VideoFileClip import VideoFileClip 4 | from pytube import YouTube 5 | from decimal import Decimal 6 | import imgurpython 7 | import re 8 | import praw 9 | import random 10 | import bs4 11 | import subprocess 12 | import os 13 | 14 | directoryFlag = False 15 | 16 | # link to the How it's made youtube video query 17 | linkQuery = "https://www.youtube.com/results?search_query=how+its+made" 18 | 19 | # pages is a list to hold all youtube links so we don't recieve any duplicates 20 | pages = set() 21 | 22 | # Easy naming scheme for the videos and gifs 23 | videoName = 0 24 | gifName = 0 25 | 26 | # imgur credentials 27 | imgurClientId = "b01297eb68376c7" 28 | imgurClientSecret = "0f7006ff650c755924a1cf531036c4820cfd8c72" 29 | 30 | # reddit credentials 31 | redditUsername = input("Please input Reddit Username: ") 32 | redditPassword = input("Please input Reddit Password: ") 33 | 34 | 35 | # function that will check to see if you have 'videos' and 'gifs' 36 | def createFolders(): 37 | global directoryFlag 38 | print("Creating directory for videos") 39 | os.makedirs("videos", exist_ok=True) 40 | print("Creating directory for gifs") 41 | os.makedirs("gifs", exist_ok=True) 42 | directoryFlag = True 43 | 44 | 45 | # function to grab the youtube video link 46 | def findYoutubeVideoLink(youtubeLinkQuery): 47 | global pages 48 | print("Finding Youtube video links...") 49 | html = urlopen(linkQuery) 50 | bsObj = bs4.BeautifulSoup(html, 'html.parser') 51 | # for every 'a' tag that has the '/watch' link... 52 | for link in bsObj.findAll("a", href=re.compile("^(/watch)")): 53 | if 'href' in link.attrs: 54 | if link.attrs['href'] not in pages: 55 | # We have encounted a new page 56 | newPage = link.attrs['href'] 57 | print("Found new video at: https://youtube.com" + newPage) 58 | pages.add(newPage) 59 | return "https://youtube.com" + str(newPage) 60 | 61 | 62 | # function that grabs the youtube video that has been grabbed by findYoutubeVideoLink 63 | def downloadYoutubeVideo(youtubeLink): 64 | global videoName 65 | videoName += 1 66 | yt = YouTube(youtubeLink) 67 | yt.set_filename(videoName) 68 | # Sadly low quality however it's usually the only one available (Seriously science channel...) 69 | video = yt.get('mp4', '360p') 70 | print("Downloading video... this may take a little bit...") 71 | video.download('videos/') 72 | print("Video downloaded at videos/" + str(videoName) + '.mp4!') 73 | return 'videos/' + str(videoName) + '.mp4' 74 | 75 | 76 | # function that grabs time of the video downloaded in order to grab a random time later on 77 | # Uses ffmpeg to grab time of the youtube video that has been downloaded 78 | def grabTimeOfDownloadedYoutubeVideo(youtubeVideo): 79 | process = subprocess.Popen(['/usr/local/bin/ffmpeg', '-i', youtubeVideo], stdout=subprocess.PIPE, 80 | stderr=subprocess.STDOUT) 81 | stdout, stderr = process.communicate() 82 | # matches does a regex scan and finds duration of video that has been downloaded 83 | matches = re.search(r"Duration:\s(?P\d+?):(?P\d+?):(?P\d+\.\d+?),", 84 | str(stdout)).groupdict() 85 | hours = int(matches['hours']) 86 | minutes = int(matches['minutes']) 87 | seconds = int(Decimal(matches['seconds'])) 88 | print("Length of video is: " + str(minutes) + " minutes. As well as " + str(Decimal(seconds)) + " seconds.") 89 | return matches['minutes'], matches['seconds'] 90 | 91 | 92 | # function that takes youtube video and turns it into a gif 93 | # Currently the gifs are set to be 3.5 seconds long. 94 | def turnYoutubeVideoIntoGif(youtubeVideo, minutes, seconds): 95 | global gifName 96 | # randomize points of the video 97 | randomLengthMinutes = random.randint(0, int(minutes)) 98 | randomLengthSeconds = random.randint(0, int(Decimal(seconds))) 99 | randomLengthSecondsEnd = int(randomLengthSeconds) + 3.5 100 | gifName += 1 101 | print("Converting video into gif...") 102 | clip = (VideoFileClip(youtubeVideo) 103 | .subclip((int(randomLengthMinutes), int(randomLengthSeconds)), 104 | (int(randomLengthMinutes), int(randomLengthSecondsEnd)))) 105 | clip.write_gif("gifs/how-its-made" + str(gifName) + ".gif", fps=15) 106 | print("Gif has been created!!!") 107 | return "gifs/how-its-made" + str(gifName) + ".gif" 108 | 109 | 110 | # Takes gif and uploads to imgur and returns upload link in order to upload to reddit 111 | def uploadGifToImgur(gif, clientId, clientSecret): 112 | # Uploading Gif to Imgur 113 | print("Uploading " + gif + " to imgur.") 114 | i = imgurpython.ImgurClient(clientId, clientSecret).upload_from_path(path=gif, config=None, anon=True) 115 | link = i.get('link') 116 | print("Gif can be found at: " + link) 117 | return link 118 | 119 | 120 | def uploadGifToReddit(imgurLink, username, password): 121 | global gifName 122 | r = praw.Reddit(user_agent="How its made!!") 123 | r.login(redditUsername, redditPassword) 124 | subreddit = r.get_subreddit("LewisTestsBots") 125 | print("Uploading link to reddit") 126 | subreddit.submit(title="How it's made " + str(gifName), url=imgurLink) 127 | 128 | # Main Loop 129 | while True: 130 | if directoryFlag is False: 131 | createFolders() 132 | youtube_link = findYoutubeVideoLink(linkQuery) 133 | youtubeVideo = downloadYoutubeVideo(youtube_link) 134 | (minutes, seconds) = grabTimeOfDownloadedYoutubeVideo(youtubeVideo) 135 | urlPath = turnYoutubeVideoIntoGif(youtubeVideo, minutes, seconds) 136 | imgurLink = uploadGifToImgur("gifs/" + "how-its-made" + str(gifName) + ".gif", imgurClientId, imgurClientSecret) 137 | uploadGifToReddit(imgurLink, redditUsername, redditPassword) 138 | 139 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.4.1 2 | decorator==4.0.4 3 | imageio==1.4 4 | imgurpython==1.1.6 5 | moviepy==0.2.2.11 6 | numpy==1.10.1 7 | praw==3.3.0 8 | pytube==6.1.3 9 | requests==2.8.1 10 | six==1.10.0 11 | tqdm==2.2.4 12 | update-checker==0.11 13 | --------------------------------------------------------------------------------