Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
nang-dev committed Jan 12, 2021
0 parents commit fa87f66
Show file tree
Hide file tree
Showing 12 changed files with 455 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
45 changes: 45 additions & 0 deletions Google.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import pickle
import os
from google_auth_oauthlib.flow import Flow, InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload
from google.auth.transport.requests import Request

def Create_Service(client_secret_file, api_name, api_version, *scopes):
CLIENT_SECRET_FILE = client_secret_file
API_SERVICE_NAME = api_name
API_VERSION = api_version
SCOPES = [scope for scope in scopes[0]]
print(SCOPES)

cred = None

pickle_file = f'token_{API_SERVICE_NAME}_{API_VERSION}.pickle'
# print(pickle_file)

if os.path.exists(pickle_file):
with open(pickle_file, 'rb') as token:
cred = pickle.load(token)

if not cred or not cred.valid:
if cred and cred.expired and cred.refresh_token:
cred.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
cred = flow.run_local_server()

with open(pickle_file, 'wb') as token:
pickle.dump(cred, token)

try:
service = build(API_SERVICE_NAME, API_VERSION, credentials=cred)
print(API_SERVICE_NAME, 'service created successfully')
return service
except Exception as e:
print('Unable to connect.')
print(e)
return None

def convert_to_RFC_datetime(year=1900, month=1, day=1, hour=0, minute=0):
dt = datetime.datetime(year, month, day, hour, minute, 0).isoformat() + 'Z'
return dt
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Fully Automated Youtube Channel

Code to run a fully automated youtube that can scrape content, edit a compilation, and upload to youtube daily.

# Instructions

1. [Download](https://github.com/nathan-149/automated_youtube_channel/archive/main.zip) the Github Repository

2. Download and install [Python](https://www.python.org/downloads/) and [pip](https://pip.pypa.io/en/stable/installing/)

3. Run `pip install -r requirements.txt`

4. Get setup and create a Project with the Youtube API: https://developers.google.com/youtube/v3/quickstart/python
Be sure to follow it carefully, as it won't work if you don't do this part right.
Download your OATH file as "secret.json" in your folder.

5. Run `python3 setup_google.py` and follow the web page that opens up.

6. Create an instagram account and follow accounts you want to scrape from

7. Open main.py in a text editor and fill in necessary information

8. Run `python3 main.py`

9. Enjoy your fully automated youtube channel! :) Note that for uploading public videos, you have to complete an audit for the Youtube API. See the note in the [Google Documentation](https://developers.google.com/youtube/v3/docs/videos/insert)
Binary file added example_vid.mp4
Binary file not shown.
31 changes: 31 additions & 0 deletions instaloader_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from datetime import datetime
import instaloader

# insta loader downloads some posts under the hashtag urbanphotography

L = instaloader.Instaloader()

posts = instaloader.Hashtag.from_name(L.context, "urbanphotography").get_posts()

SINCE = datetime(2020, 5, 10) # further from today, inclusive
UNTIL = datetime(2020, 5, 11) # closer to today, not inclusive

k = 0 # initiate k
#k_list = [] # uncomment this to tune k

for post in posts:
postdate = post.date

if postdate > UNTIL:
continue
elif postdate <= SINCE:
k += 1
if k == 50:
break
else:
continue
else:
L.download_post(post, "#urbanphotography")
# if you want to tune k, uncomment below to get your k max
#k_list.append(k)
k = 0 # set k to 0
14 changes: 14 additions & 0 deletions instalooter_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from instalooter.looters import ProfileLooter
import datetime
import dateutil.relativedelta

# instalooter_test downloads videos posted by postleg__ in the last month

# Instanciate
looter = ProfileLooter("postleg__", videos_only=True, template="{id}-{username}-{width}-{height}")
looter.login("bigshaq6bih", "mmm12345")

today = datetime.date.today()
thismonth = (today, today - dateutil.relativedelta.relativedelta(days=28))

looter.download('./Memes_December_4', media_count=50, timeframe=thismonth)
113 changes: 113 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
from scrape_videos import scrapeVideos
from make_compilation import makeCompilation
from upload_ytvid import uploadYtvid
import schedule
import time
import datetime
import os
import shutil

# FILL THESE OUT
IG_USERNAME = "chewymemes_v3"
IG_PASSWORD = "mmm12345"

INTRO_VID = 'intro_vid.mp4' # SET AS '' IF YOU DONT HAVE ONE
OUTRO_VID = ''
TOTAL_VID_LENGTH = 13*60
MAX_CLIP_LENGTH = 18
MIN_CLIP_LENGTH = 4

num_to_month = {
1: "Jan",
2: "Feb",
3: "Mar",
4: "Apr",
5: "May",
6: "June",
7: "July",
8: "Aug",
9: "Sept",
10: "Oct",
11: "Nov",
12: "Dec"
}

def routine():
now = datetime.datetime.now()
print(now.year, now.month, now.day, now.hour, now.minute, now.second)
title = "BEST DANK MEMES COMPILATION V" + str(now.month) + "." + str(now.day) + " (VIDEOS)"
videoDirectory = "/tmp/Memes_" + num_to_month[now.month].upper() + "_" + str(now.year) + "_V" + str(now.day) + "/"
outputFile = "./" + num_to_month[now.month].upper() + "_" + str(now.year) + "_v" + str(now.day) + ".mp4"
metadataFile = "./metadata-" + num_to_month[now.month].upper() + "_" + str(now.year) + "_v" + str(now.day) + ".txt"
description = ""
print(outputFile)

if not os.path.exists(videoDirectory):
os.makedirs(videoDirectory)
"""
# Step 1: Scrape Videos
print("Scraping Videos...")
scrapeVideos(username = IG_USERNAME,
password = IG_PASSWORD,
output_folder = videoDirectory,
days=1)
print("Scraped Videos!")
"""
f = open(metadataFile, "w")
f.write(title + "\n\n")
description = "Enjoy the memes :) \n\n" \
"like and subscribe to @Chewy for more \n\n" \
"The memes in the compilation are reposts from various private instagram meme accounts.\n" \
"this episode's were from: \n"
f.write(description)

# Step 2: Make Compilation
print("Making Compilation...")
description += makeCompilation(path = videoDirectory,
introName = INTRO_VID,
outroName = OUTRO_VID,
totalVidLength = TOTAL_VID_LENGTH,
maxClipLength = MAX_CLIP_LENGTH,
minClipLength = MIN_CLIP_LENGTH,
outputFile = outputFile)
print("Made Compilation!")

description += "\n\nCopyright Disclaimer, Under Section 107 of the Copyright Act 1976, allowance is made for 'fair use' for purposes such as criticism, comment, news reporting, teaching, scholarship, and research. Fair use is a use permitted by copyright statute that might otherwise be infringing. Non-profit, educational or personal use tips the balance in favor of fair use.\n\n"
description += "#memes #dankmemes #compilation #funny #funnyvideos \n\n"
f.write(description + "\n\n")
f.close()

# Step 3: Upload to Youtube
print("Uploading to Youtube...")
uploadYtvid(VIDEO_FILE_NAME=outputFile,
title=title,
description=description)
print("Uploaded To Youtube!")

# Step 4: Cleanup
print("Removing temp files!")
# Delete all files made:
# Folder videoDirectory
shutil.rmtree(videoDirectory, ignore_errors=True)
# File outputFile
try:
os.remove(outputFile)
except OSError as e: ## if faile,d, report it back to the user ##
print ("Error: %s - %s." % (e.filename, e.strerror))
print("Removed temp files!")

def attemptRoutine():
try:
routine()
except OSError as err:
print("Routine Failed on " + "OS error: {0}".format(err))
time.sleep(60*60)
routine()

attemptRoutine()
schedule.every().day.at("19:05").do(attemptRoutine)

while True:
schedule.run_pending()
time.sleep(60) # wait one min

114 changes: 114 additions & 0 deletions make_compilation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from moviepy.editor import VideoFileClip, concatenate_videoclips
from moviepy.video.fx.resize import resize
import os
from os.path import isfile, join
import random
import shutil
from collections import defaultdict

VideoFileClip.resize = resize

def extractAcc(filepath):
try:
s = filepath.split("/")[-1].split("-")
acc = "-".join(s[1:(2+(len(s) - 4))])
return acc
except:
return ""

# generateTimeRange converts float seconds to a range of form @MM:SS
def generateTimeRange(duration, clipDuration):
preHour = int(duration / 60)
preMin = int(duration % 60)
preTime = str(preHour // 10) + str(preHour % 10) + ":" + str(preMin // 10) + str(preMin % 10)

duration += clipDuration
postHour = int(duration / 60)
postMin = int(duration % 60)
postTime = str(postHour // 10) + str(postHour % 10) + ":" + str(postMin // 10) + str(postMin % 10)

#return "@" + preTime + " - " + "@" + postTime
return "@" + preTime

# makeCompilation takes videos in a folder and creates a compilation with max length totalVidLength
def makeCompilation(path = "./",
introName = '',
outroName = '',
totalVidLength = 10*60,
maxClipLength = 20,
minClipLength = 5,
outputFile = "output.mp4"):

allVideos = []
seenLengths = defaultdict(list)
totalLength = 0
for fileName in os.listdir(path):
if isfile(join(path, fileName)) and fileName.endswith(".mp4"):
print(fileName)
filePath = os.path.join(path, fileName)
# Destination path
destination = os.path.join("./Duplicates/", fileName)
clip = VideoFileClip(filePath)
clip = clip.resize(width=1920)
clip = clip.resize(height=1080)
duration = clip.duration
print(duration)
if duration <= maxClipLength and duration >= minClipLength:
allVideos.append(clip)
seenLengths[duration].append(fileName)
totalLength += duration

print("Total Length: " + str(totalLength))
for length in seenLengths:
lst = seenLengths[length]
if len(lst) > 1:
for fileName in lst:
filePath = os.path.join(path, fileName)
# Destination path
destination = os.path.join("./Duplicates/", fileName)
shutil.copy(filePath, destination)
random.shuffle(allVideos)

duration = 0
# Add intro vid
videos = []
if introName != '':
introVid = VideoFileClip("./" + introName)
videos.append(introVid)
duration += introVid.duration

description = ""
# Create videos
for clip in allVideos:
timeRange = generateTimeRange(duration, clip.duration)
acc = extractAcc(clip.filename)
description += timeRange + " : @" + acc + "\n"
duration += clip.duration
videos.append(clip)
print(duration)
if duration >= totalVidLength:
# Just make one video
break

# Add outro vid
if outroName != '':
outroVid = VideoFileClip("./" + outroName)
videos.append(outroVid)

finalClip = concatenate_videoclips(videos, method="compose")

audio_path = "/tmp/temoaudiofile.m4a"

#print(description)
# Create compilation
finalClip.write_videofile(outputFile, threads=8, temp_audiofile=audio_path, remove_temp=True, codec="libx264", audio_codec="aac")

return description

if __name__ == "__main__":
makeCompilation(path = "/Users/nathanan/Documents/YOUTUBE/AutomatedChannel/Videos/Memes/",
introName = "intro_vid.mp4",
outroName = '',
totalVidLength = 10*60,
maxClipLength = 20,
outputFile = "outputseq.mp4")
8 changes: 8 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
google_api_python_client==1.12.8
google_auth_oauthlib==0.4.2
instaloader==4.5.5
instalooter==2.4.4
moviepy==1.0.3
protobuf==3.14.0
python_dateutil==2.8.1
schedule==0.6.0
Loading

0 comments on commit fa87f66

Please sign in to comment.