mirror of
https://github.com/metafy-social/python-scripts.git
synced 2025-01-31 05:33:44 +00:00
Automated Youtube Short Maker And Uploader
This commit is contained in:
parent
2d95dcb8a3
commit
2009079f31
BIN
scripts/python_ytshorts/__temp__.mp4
Normal file
BIN
scripts/python_ytshorts/__temp__.mp4
Normal file
Binary file not shown.
295
scripts/python_ytshorts/main.ipynb
Normal file
295
scripts/python_ytshorts/main.ipynb
Normal file
File diff suppressed because one or more lines are too long
9
scripts/python_ytshorts/readme.md
Normal file
9
scripts/python_ytshorts/readme.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
**Problem Statement**
|
||||||
|
To make a Youtube Short using a Random Facts API and upload it to youtube with one click of a button on a Python Notebook.
|
||||||
|
|
||||||
|
**To Run It**
|
||||||
|
|
||||||
|
1. Download all the the installs required for the notebook given on the requirements file.
|
||||||
|
2. Add the API Key required by following the information on the notebook (Just the API Key from Api Ninja)
|
||||||
|
3. Run The notebook if you have done everything correctly it should all work although the rendering process
|
||||||
|
4. Then it will prompt you for a Youtube login OAUTH. After which video should be uploaded.
|
16
scripts/python_ytshorts/requirements.txt
Normal file
16
scripts/python_ytshorts/requirements.txt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
API Keys Required
|
||||||
|
|
||||||
|
https://api.api-ninjas.com/v1/facts
|
||||||
|
|
||||||
|
|
||||||
|
Installation Files
|
||||||
|
|
||||||
|
moviepy.editor
|
||||||
|
IPython.display
|
||||||
|
pyttsx3
|
||||||
|
wave
|
||||||
|
contextlib
|
||||||
|
random
|
||||||
|
requests
|
||||||
|
spacy
|
||||||
|
json
|
126
scripts/python_ytshorts/scripter.py
Normal file
126
scripts/python_ytshorts/scripter.py
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
# %%
|
||||||
|
from moviepy.editor import *
|
||||||
|
from IPython.display import Image
|
||||||
|
import pyttsx3
|
||||||
|
import wave
|
||||||
|
import contextlib
|
||||||
|
from random import randint
|
||||||
|
import requests
|
||||||
|
import spacy
|
||||||
|
import json
|
||||||
|
|
||||||
|
# %%
|
||||||
|
limit = 1
|
||||||
|
nlp=spacy.load("en_core_web_sm")
|
||||||
|
api_url = 'https://api.api-ninjas.com/v1/facts?limit={}'.format(limit)
|
||||||
|
|
||||||
|
def get_fact():
|
||||||
|
response = requests.get(api_url, headers={'X-Api-Key': 'dY3dPGjWV0eJYJDe0s58fQ==h38UzNvlCb4SjqOO'})
|
||||||
|
if response.status_code == requests.codes.ok:
|
||||||
|
print(response.text)
|
||||||
|
return response.text
|
||||||
|
else:
|
||||||
|
print("Error:", response.status_code, response.text)
|
||||||
|
|
||||||
|
flag=0
|
||||||
|
while(flag==0):
|
||||||
|
fact= get_fact()
|
||||||
|
# print(len(fact))
|
||||||
|
doc=nlp(fact)
|
||||||
|
# print (doc.ents)
|
||||||
|
for X in doc.ents:
|
||||||
|
#CAN ALSO DO IF X.label_=="GPE"
|
||||||
|
if (len(fact)>=100):
|
||||||
|
flag=1
|
||||||
|
name=X.text
|
||||||
|
break
|
||||||
|
print("\n"+name+"\n")
|
||||||
|
fact=json.loads(fact)[0]["fact"]
|
||||||
|
print(fact)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
questiontext= "Did you know?"
|
||||||
|
answersay= fact
|
||||||
|
|
||||||
|
answertext= fact
|
||||||
|
answerlist=list(answertext)
|
||||||
|
i=30
|
||||||
|
while(i<len(answerlist)):
|
||||||
|
if(answerlist[i]==" "):
|
||||||
|
answerlist[i]="\n"
|
||||||
|
if(i+30>=len(answerlist)):
|
||||||
|
break
|
||||||
|
i+=30
|
||||||
|
else:
|
||||||
|
i+=1
|
||||||
|
|
||||||
|
def convert(s):
|
||||||
|
new = ""
|
||||||
|
for x in s:
|
||||||
|
new += x
|
||||||
|
return new
|
||||||
|
answertext= convert(answerlist)
|
||||||
|
|
||||||
|
# %%
|
||||||
|
engine = pyttsx3.init()
|
||||||
|
engine.save_to_file(answersay, 'static/test2.mp3' )
|
||||||
|
engine.runAndWait()
|
||||||
|
|
||||||
|
with contextlib.closing(wave.open("static/test2.mp3",'r')) as f:
|
||||||
|
frames = f.getnframes()
|
||||||
|
rate = f.getframerate()
|
||||||
|
duration = frames / float(rate)
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
knowaudio = AudioFileClip("static/test1.mp3")
|
||||||
|
knowaudioclip = CompositeAudioClip([knowaudio])
|
||||||
|
answeraudio = AudioFileClip("static/test2.mp3")
|
||||||
|
answeraudioclip = CompositeAudioClip([answeraudio])
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
x=randint(0,2)
|
||||||
|
y=randint(0,2)
|
||||||
|
z=randint(0,2)
|
||||||
|
|
||||||
|
def randomize_color(image):
|
||||||
|
return image[:,:,[x,y,z]]
|
||||||
|
|
||||||
|
BackgroundClip= VideoFileClip("static/background.mp4").fl_image( randomize_color )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
knowback= BackgroundClip.subclip(0,3)
|
||||||
|
knowtext= TextClip(questiontext, fontsize=80, color="white" , font="Microsoft-Uighur-Bold", bg_color="black").set_position("center").set_duration(3)
|
||||||
|
knowclip= CompositeVideoClip([knowback,knowtext])
|
||||||
|
knowclip.audio= knowaudioclip
|
||||||
|
|
||||||
|
# %%
|
||||||
|
answerback= BackgroundClip.subclip(3,3+duration)
|
||||||
|
answertext= TextClip(answertext, fontsize=50, color="white" , font="Microsoft-Uighur", bg_color="black").set_position("center").set_duration(duration)
|
||||||
|
answerclip= CompositeVideoClip([answerback,answertext])
|
||||||
|
answerclip.audio= answeraudioclip
|
||||||
|
|
||||||
|
# %%
|
||||||
|
subscribeclip= VideoFileClip("static/Subscribe.mp4").fx(vfx.fadein, 1).fx(vfx.speedx, 2)
|
||||||
|
|
||||||
|
# %%
|
||||||
|
compile=concatenate_videoclips([knowclip, answerclip, subscribeclip], method="compose")
|
||||||
|
video = compile.resize(height=1920)
|
||||||
|
video = video.crop(x1=1166.6,y1=0,x2=2246.6,y2=1920)
|
||||||
|
video.save_frame("static/frame.png", 6)
|
||||||
|
Image(filename="static/frame.png")
|
||||||
|
|
||||||
|
# %%
|
||||||
|
video.write_videofile("static/temp.mp4", fps=60)
|
||||||
|
|
||||||
|
# %%
|
||||||
|
from test import *
|
||||||
|
upload(name.upper())
|
||||||
|
|
||||||
|
|
1
scripts/python_ytshorts/tempCodeRunnerFile.ipynb
Normal file
1
scripts/python_ytshorts/tempCodeRunnerFile.ipynb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
https://api.api-ninjas.com/v1/facts?limit={}
|
121
scripts/python_ytshorts/tempCodeRunnerFile.python
Normal file
121
scripts/python_ytshorts/tempCodeRunnerFile.python
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
# %%
|
||||||
|
from moviepy.editor import *
|
||||||
|
from IPython.display import Image
|
||||||
|
import pyttsx3
|
||||||
|
import wave
|
||||||
|
import contextlib
|
||||||
|
from random import randint
|
||||||
|
import requests
|
||||||
|
import spacy
|
||||||
|
import json
|
||||||
|
|
||||||
|
# %%
|
||||||
|
limit = 1
|
||||||
|
nlp=spacy.load("en_core_web_sm")
|
||||||
|
api_url = 'https://api.api-ninjas.com/v1/facts?limit={}'.format(limit)
|
||||||
|
|
||||||
|
def get_fact():
|
||||||
|
response = requests.get(api_url, headers={'X-Api-Key': 'dY3dPGjWV0eJYJDe0s58fQ==h38UzNvlCb4SjqOO'})
|
||||||
|
if response.status_code == requests.codes.ok:
|
||||||
|
print(response.text)
|
||||||
|
return response.text
|
||||||
|
else:
|
||||||
|
print("Error:", response.status_code, response.text)
|
||||||
|
|
||||||
|
flag=0
|
||||||
|
while(flag==0):
|
||||||
|
fact= get_fact()
|
||||||
|
doc=nlp(fact)
|
||||||
|
for X in doc.ents:
|
||||||
|
if (X.label_=="GPE" ):
|
||||||
|
flag=1
|
||||||
|
name=X.text
|
||||||
|
break
|
||||||
|
print("\n"+name+"\n")
|
||||||
|
fact=json.loads(fact)[0]["fact"]
|
||||||
|
print(fact)
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
questiontext= "Did you know?"
|
||||||
|
answersay= fact
|
||||||
|
|
||||||
|
answertext= fact
|
||||||
|
answerlist=list(answertext)
|
||||||
|
i=30
|
||||||
|
while(i<len(answerlist)):
|
||||||
|
if(answerlist[i]==" "):
|
||||||
|
answerlist[i]="\n"
|
||||||
|
if(i+30>=len(answerlist)):
|
||||||
|
break
|
||||||
|
i+=30
|
||||||
|
else:
|
||||||
|
i+=1
|
||||||
|
|
||||||
|
def convert(s):
|
||||||
|
new = ""
|
||||||
|
for x in s:
|
||||||
|
new += x
|
||||||
|
return new
|
||||||
|
answertext= convert(answerlist)
|
||||||
|
|
||||||
|
# %%
|
||||||
|
engine = pyttsx3.init()
|
||||||
|
engine.save_to_file(answersay, 'static/test2.mp3' )
|
||||||
|
engine.runAndWait()
|
||||||
|
|
||||||
|
with contextlib.closing(wave.open("static/test2.mp3",'r')) as f:
|
||||||
|
frames = f.getnframes()
|
||||||
|
rate = f.getframerate()
|
||||||
|
duration = frames / float(rate)
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
knowaudio = AudioFileClip("static/test1.mp3")
|
||||||
|
knowaudioclip = CompositeAudioClip([knowaudio])
|
||||||
|
answeraudio = AudioFileClip("static/test2.mp3")
|
||||||
|
answeraudioclip = CompositeAudioClip([answeraudio])
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
x=randint(0,2)
|
||||||
|
y=randint(0,2)
|
||||||
|
z=randint(0,2)
|
||||||
|
|
||||||
|
def randomize_color(image):
|
||||||
|
return image[:,:,[x,y,z]]
|
||||||
|
|
||||||
|
BackgroundClip= VideoFileClip("static/background.mp4").fl_image( randomize_color )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# %%
|
||||||
|
knowback= BackgroundClip.subclip(0,3)
|
||||||
|
knowtext= TextClip(questiontext, fontsize=80, color="white" , font="Microsoft-Uighur-Bold", bg_color="black").set_position("center").set_duration(3)
|
||||||
|
knowclip= CompositeVideoClip([knowback,knowtext])
|
||||||
|
knowclip.audio= knowaudioclip
|
||||||
|
|
||||||
|
# %%
|
||||||
|
answerback= BackgroundClip.subclip(3,3+duration)
|
||||||
|
answertext= TextClip(answertext, fontsize=50, color="white" , font="Microsoft-Uighur", bg_color="black").set_position("center").set_duration(duration)
|
||||||
|
answerclip= CompositeVideoClip([answerback,answertext])
|
||||||
|
answerclip.audio= answeraudioclip
|
||||||
|
|
||||||
|
# %%
|
||||||
|
subscribeclip= VideoFileClip("static/Subscribe.mp4").fx(vfx.fadein, 1).fx(vfx.speedx, 2)
|
||||||
|
|
||||||
|
# %%
|
||||||
|
compile=concatenate_videoclips([knowclip, answerclip, subscribeclip], method="compose")
|
||||||
|
video = compile.resize(height=1920)
|
||||||
|
video = video.crop(x1=1166.6,y1=0,x2=2246.6,y2=1920)
|
||||||
|
video.save_frame("static/frame.png", 6)
|
||||||
|
Image(filename="static/frame.png")
|
||||||
|
|
||||||
|
# %%
|
||||||
|
video.write_videofile("static/temp.mp4", fps=60)
|
||||||
|
|
||||||
|
# %%
|
||||||
|
from test import *
|
||||||
|
upload(name.upper())
|
||||||
|
|
||||||
|
|
17
scripts/python_ytshorts/test.py
Normal file
17
scripts/python_ytshorts/test.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import os
|
||||||
|
def upload(country):
|
||||||
|
country=country.upper()
|
||||||
|
filepath="C:\\python_ytshorts\\static\\temp.mp4"
|
||||||
|
title=str("\"AMAZING LIFE FACT about {} #shorts\"").format(country)
|
||||||
|
description="\"ABOUT OUR CHANNEL Our channel is about Facts. We cover lots of cool stuff such as Facts Check out our channel here:https://www.youtube.com/channel/UCeT_1wHgBWVfNZUM4tCWWmADon’t forget to subscribe!\""
|
||||||
|
keywords=str("\"facts about the {},facts about,facts about {},amazing facts about {},surprising facts about the {},5 random facts about the {},about,interesting facts about {},random facts about the {},the worst things about {},facts about beer,facts about skoda,facts about czech,facts about czechs,facts about the world,facts about countries,facts about ice hockey\"").format(country.lower(),country.lower(),country.lower(),country.lower(),country.lower(),country.lower(),country.lower(),country.lower())
|
||||||
|
status= "\"public\""
|
||||||
|
category= "\"1\""
|
||||||
|
|
||||||
|
cmd="python upload.py --file={} --title={} --description={} --category={} --keywords={} --privacyStatus={} ".format(filepath,title,description,category,keywords,status)
|
||||||
|
print(cmd)
|
||||||
|
os.system(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
9
scripts/python_ytshorts/texttospeech.py
Normal file
9
scripts/python_ytshorts/texttospeech.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import pyttsx3
|
||||||
|
|
||||||
|
questiontext= "Did you know?"
|
||||||
|
answertext= "Australia is wider than the moon. The moon sits at 3400km in diameter, while Australia’s diameter from east to west is almost 4000km."
|
||||||
|
|
||||||
|
engine = pyttsx3.init()
|
||||||
|
engine.save_to_file(questiontext, 'test1.mp3')
|
||||||
|
engine.save_to_file(answertext, 'test2.mp3' )
|
||||||
|
engine.runAndWait()
|
181
scripts/python_ytshorts/upload.py
Normal file
181
scripts/python_ytshorts/upload.py
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
import httplib2
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
# from apiclient.discovery import build
|
||||||
|
from googleapiclient.errors import HttpError
|
||||||
|
from googleapiclient.http import MediaFileUpload
|
||||||
|
from googleapiclient.discovery import build
|
||||||
|
from oauth2client.client import flow_from_clientsecrets
|
||||||
|
from oauth2client.file import Storage
|
||||||
|
from oauth2client.tools import argparser, run_flow
|
||||||
|
|
||||||
|
|
||||||
|
# Explicitly tell the underlying HTTP transport library not to retry, since
|
||||||
|
# we are handling retry logic ourselves.
|
||||||
|
httplib2.RETRIES = 1
|
||||||
|
|
||||||
|
# Maximum number of times to retry before giving up.
|
||||||
|
MAX_RETRIES = 10
|
||||||
|
|
||||||
|
# Always retry when these exceptions are raised.
|
||||||
|
RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError)
|
||||||
|
|
||||||
|
# Always retry when an apiclient.errors.HttpError with one of these status
|
||||||
|
# codes is raised.
|
||||||
|
RETRIABLE_STATUS_CODES = [500, 502, 503, 504]
|
||||||
|
|
||||||
|
# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
|
||||||
|
# the OAuth 2.0 information for this application, including its client_id and
|
||||||
|
# client_secret. You can acquire an OAuth 2.0 client ID and client secret from
|
||||||
|
# the Google API Console at
|
||||||
|
# https://console.developers.google.com/.
|
||||||
|
# Please ensure that you have enabled the YouTube Data API for your project.
|
||||||
|
# For more information about using OAuth2 to access the YouTube Data API, see:
|
||||||
|
# https://developers.google.com/youtube/v3/guides/authentication
|
||||||
|
# For more information about the client_secrets.json file format, see:
|
||||||
|
# https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
|
||||||
|
CLIENT_SECRETS_FILE = "client_secret_804209683373-ndq0m9ecmm41bq18o7m67i96lcqmtld6.apps.googleusercontent.com.json"
|
||||||
|
|
||||||
|
# This OAuth 2.0 access scope allows an application to upload files to the
|
||||||
|
# authenticated user's YouTube channel, but doesn't allow other types of access.
|
||||||
|
YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload"
|
||||||
|
YOUTUBE_API_SERVICE_NAME = "youtube"
|
||||||
|
YOUTUBE_API_VERSION = "v3"
|
||||||
|
|
||||||
|
# This variable defines a message to display if the CLIENT_SECRETS_FILE is
|
||||||
|
# missing.
|
||||||
|
MISSING_CLIENT_SECRETS_MESSAGE = """
|
||||||
|
WARNING: Please configure OAuth 2.0
|
||||||
|
|
||||||
|
To make this sample run you will need to populate the client_secrets.json file
|
||||||
|
found at:
|
||||||
|
|
||||||
|
%s
|
||||||
|
|
||||||
|
with information from the API Console
|
||||||
|
https://console.developers.google.com/
|
||||||
|
|
||||||
|
For more information about the client_secrets.json file format, please visit:
|
||||||
|
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
|
||||||
|
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),
|
||||||
|
CLIENT_SECRETS_FILE))
|
||||||
|
|
||||||
|
VALID_PRIVACY_STATUSES = ("public", "private", "unlisted")
|
||||||
|
|
||||||
|
|
||||||
|
def get_authenticated_service(args):
|
||||||
|
flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE,
|
||||||
|
scope=YOUTUBE_UPLOAD_SCOPE,
|
||||||
|
message=MISSING_CLIENT_SECRETS_MESSAGE)
|
||||||
|
|
||||||
|
storage = Storage("%s-oauth2.json" % sys.argv[0])
|
||||||
|
credentials = storage.get()
|
||||||
|
|
||||||
|
if credentials is None or credentials.invalid:
|
||||||
|
credentials = run_flow(flow, storage, args)
|
||||||
|
|
||||||
|
return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
|
||||||
|
http=credentials.authorize(httplib2.Http()))
|
||||||
|
|
||||||
|
def initialize_upload(youtube, options):
|
||||||
|
tags = None
|
||||||
|
if options.keywords:
|
||||||
|
tags = options.keywords.split(",")
|
||||||
|
|
||||||
|
body=dict(
|
||||||
|
snippet=dict(
|
||||||
|
title=options.title,
|
||||||
|
description=options.description,
|
||||||
|
tags=tags,
|
||||||
|
categoryId=options.category
|
||||||
|
),
|
||||||
|
status=dict(
|
||||||
|
privacyStatus = options.privacyStatus,
|
||||||
|
kidsStatus= options.kidsStatus,
|
||||||
|
selfDeclaredkidsStatus = options.selfDeclaredMadeForKids
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Call the API's videos.insert method to create and upload the video.
|
||||||
|
insert_request = youtube.videos().insert(
|
||||||
|
part=",".join(body.keys()),
|
||||||
|
body=body,
|
||||||
|
# The chunksize parameter specifies the size of each chunk of data, in
|
||||||
|
# bytes, that will be uploaded at a time. Set a higher value for
|
||||||
|
# reliable connections as fewer chunks lead to faster uploads. Set a lower
|
||||||
|
# value for better recovery on less reliable connections.
|
||||||
|
#
|
||||||
|
# Setting "chunksize" equal to -1 in the code below means that the entire
|
||||||
|
# file will be uploaded in a single HTTP request. (If the upload fails,
|
||||||
|
# it will still be retried where it left off.) This is usually a best
|
||||||
|
# practice, but if you're using Python older than 2.6 or if you're
|
||||||
|
# running on App Engine, you should set the chunksize to something like
|
||||||
|
# 1024 * 1024 (1 megabyte).
|
||||||
|
media_body= MediaFileUpload(options.file, chunksize=-1, resumable=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
resumable_upload(insert_request)
|
||||||
|
|
||||||
|
# This method implements an exponential backoff strategy to resume a
|
||||||
|
# failed upload.
|
||||||
|
def resumable_upload(insert_request):
|
||||||
|
response = None
|
||||||
|
error = None
|
||||||
|
retry = 0
|
||||||
|
while response is None:
|
||||||
|
try:
|
||||||
|
print ("Uploading file...")
|
||||||
|
status, response = insert_request.next_chunk()
|
||||||
|
if response is not None:
|
||||||
|
if 'id' in response:
|
||||||
|
print ("Video id '%s' was successfully uploaded." % response['id'])
|
||||||
|
else:
|
||||||
|
exit("The upload failed with an unexpected response: %s" % response)
|
||||||
|
except HttpError as e:
|
||||||
|
if e.resp.status in RETRIABLE_STATUS_CODES:
|
||||||
|
error = "A retriable HTTP error %d occurred:\n%s" % (e.resp.status,
|
||||||
|
e.content)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
except RETRIABLE_EXCEPTIONS as e:
|
||||||
|
error = "A retriable error occurred: %s" % e
|
||||||
|
|
||||||
|
if error is not None:
|
||||||
|
print (error)
|
||||||
|
retry += 1
|
||||||
|
if retry > MAX_RETRIES:
|
||||||
|
exit("No longer attempting to retry.")
|
||||||
|
|
||||||
|
max_sleep = 2 ** retry
|
||||||
|
sleep_seconds = random.random() * max_sleep
|
||||||
|
print ("Sleeping %f seconds and then retrying..." % sleep_seconds)
|
||||||
|
time.sleep(sleep_seconds)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
argparser.add_argument("--file", required=True, help="Video file to upload")
|
||||||
|
argparser.add_argument("--title", help="Video title", default="Test Title")
|
||||||
|
argparser.add_argument("--description", help="Video description",
|
||||||
|
default="Test Description")
|
||||||
|
argparser.add_argument("--category", default="22",
|
||||||
|
help="Numeric video category. " +
|
||||||
|
"See https://developers.google.com/youtube/v3/docs/videoCategories/list")
|
||||||
|
argparser.add_argument("--keywords", help="Video keywords, comma separated",
|
||||||
|
default="")
|
||||||
|
argparser.add_argument("--privacyStatus", choices=VALID_PRIVACY_STATUSES,
|
||||||
|
default=VALID_PRIVACY_STATUSES[0], help="Video privacy status.")
|
||||||
|
argparser.add_argument("--kidsStatus", default="1", help="Video kids status")
|
||||||
|
argparser.add_argument("--selfDeclaredMadeForKids", default="1", help="Video self declared made for kids status")
|
||||||
|
args = argparser.parse_args()
|
||||||
|
|
||||||
|
if not os.path.exists(args.file):
|
||||||
|
exit("Please specify a valid file using the --file= parameter.")
|
||||||
|
|
||||||
|
youtube = get_authenticated_service(args)
|
||||||
|
try:
|
||||||
|
initialize_upload(youtube, args)
|
||||||
|
except HttpError as e:
|
||||||
|
print ("An HTTP error %d occurred:\n%s" % (e.resp.status, e.content))
|
Loading…
Reference in New Issue
Block a user