mirror of
https://github.com/Paillat-dev/FABLE.git
synced 2026-01-02 01:06:20 +00:00
refactor(video.py): remove unnecessary print statement
refactor(montage.py): use os.path.join instead of string concatenation refactor(thumbnail.py): use os.path.join instead of string concatenation refactor(uploader.py): use os.path.join instead of string concatenation refactor(uploader.py): add support for client_secret.json file with different names in credentials folder docs(readme.md): update instructions for openai and unsplash keys docs(readme.md): update instructions for google oauth client id json files docs(readme.md): add information about channel.yaml file in each channel's folder
This commit is contained in:
@@ -31,8 +31,7 @@ class Video:
|
||||
os.makedirs( self.path)
|
||||
script = None
|
||||
if os.path.exists(os.path.join( self.path, "script.json")):
|
||||
printm("Video script already exists. Do you want to overwrite it ?")
|
||||
if input("y/N") == "y":
|
||||
if input("Video script already exists. Do you want to overwrite it ? (y/N) : ") == "y":
|
||||
os.remove(os.path.join( self.path, "script.json"))
|
||||
|
||||
if not os.path.exists(os.path.join( self.path, "script.json")):
|
||||
@@ -51,7 +50,7 @@ class Video:
|
||||
"description": self.idea['description'] + "\n\n" + credits,
|
||||
}
|
||||
await generate_thumbnail( self.path, self.idea['title'], self.idea['description'])
|
||||
videoid = await upload_video( self.path, self.idea['title'], self.metadata['description'], 28, "", "private", self.path)
|
||||
videoid = await upload_video( self.path, self.idea['title'], self.metadata['description'], 28, "", "private", self.parent.path)
|
||||
printm(f"Your video is ready! You can find it in { self.path}")
|
||||
video_meta_file = {
|
||||
"title": self.idea['title'],
|
||||
|
||||
@@ -18,7 +18,7 @@ if not unsplash_access:
|
||||
unsplash_url = "https://api.unsplash.com/photos/random/?client_id=" + unsplash_access + "&query="
|
||||
|
||||
async def prepare(path):
|
||||
with open(path + "/script.json", 'r', encoding='utf-8') as f:
|
||||
with open(os.path.join(path, "script.json"), 'r', encoding='utf-8') as f:
|
||||
script = json.load(f)
|
||||
f.close()
|
||||
if not os.path.exists(path + "/slides"): os.mkdir(path + "/slides")
|
||||
@@ -70,7 +70,7 @@ async def prepare(path):
|
||||
with open(path + "/slides/slide" + str(i) + ".md", 'w', encoding='utf-8') as f:
|
||||
f.write(marp + "\n\n") # blank slide
|
||||
for i in range(len(script)):
|
||||
marrkdown_path = "./" + path + "/slides/slide" + str(i) + ".md"
|
||||
marrkdown_path = os.path.join(path, f"slides/slide{i}.md")
|
||||
if os.path.exists(f"./{path}/slides/slide{i}.png"):
|
||||
#skip this slide
|
||||
continue
|
||||
@@ -134,6 +134,6 @@ async def mount(path, script):
|
||||
with open (randpath.split(".")[0] + ".txt", 'r', encoding='utf-8') as f:
|
||||
music_credit = f.read()
|
||||
f.close()
|
||||
return music_credit
|
||||
return music_credit or ""
|
||||
else:
|
||||
return None
|
||||
@@ -5,6 +5,7 @@ from PIL import Image
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from utils.openaicaller import openai
|
||||
from utils.misc import open_explorer_here
|
||||
'''
|
||||
Putpose of this file is to generate a miniature of the video.
|
||||
It has a function that takes a path, title, and description and generates a miniature.
|
||||
@@ -47,7 +48,7 @@ async def rand_gradient(image):
|
||||
|
||||
async def generate_thumbnail(path, title, description):
|
||||
prmpt = prompt.replace("[TITLE]", title).replace("[DESCRIPTION]", description)
|
||||
response = openai.generate_response(
|
||||
response = await openai.generate_response(
|
||||
model="gpt-4",
|
||||
messages=[
|
||||
{"role":"user","content":prmpt},
|
||||
@@ -58,14 +59,18 @@ async def generate_thumbnail(path, title, description):
|
||||
await generate_image(path, text1, text2)
|
||||
|
||||
async def generate_image(path, text1, text2):
|
||||
path_to_bcg = path.split("/")[:-1]
|
||||
path_to_bcg = "/".join(path_to_bcg)
|
||||
# path_to_bcg = path.split("/")[:-1]
|
||||
# path_to_bcg = "/".join(path_to_bcg)
|
||||
#use os instead
|
||||
path_to_bcg = os.path.dirname(os.path.dirname(path))
|
||||
print(path_to_bcg)
|
||||
if not os.path.exists(f"{path_to_bcg}/bcg.png"):
|
||||
input("bcg.png not found. Please put bcg.png in the same folder as the video."+path_to_bcg)
|
||||
input("bcg.png not found. Please put bcg.png in the folder that will open. Press enter to open the folder.")
|
||||
open_explorer_here(path_to_bcg)
|
||||
input("Press enter when you have put bcg.png in the folder.")
|
||||
if not os.path.exists(f"{path_to_bcg}/bcg.png"):
|
||||
input("bcg.png still not found. Exiting.")
|
||||
exit()
|
||||
raise FileNotFoundError("bcg.png not found")
|
||||
bcg = Image.open(f"{path_to_bcg}/bcg.png")
|
||||
img = Image.new('RGBA', (1920, 1080))
|
||||
img, textcolor1, textcolor2 = await rand_gradient(img)
|
||||
|
||||
20
readme.md
20
readme.md
@@ -10,21 +10,11 @@ pip install -r requirements.txt
|
||||
```
|
||||
You will also need to install [FFmpeg](https://ffmpeg.org/download.html) in order for `moviepy` to work.
|
||||
|
||||
Now that you have installed the dependencies, you will need to add all the required values to the `.env` file like this:
|
||||
```
|
||||
OPENAI_API_KEY=
|
||||
UNSPLASH_ACCESS_KEY=
|
||||
DEEPL_ACCESS_KEY=
|
||||
```
|
||||
You should be able to find all the required keys with a quick Google search.
|
||||
You will need an `openai_api_key` and an `unsplash_access_key` in order to use the script. You can get them [here](https://beta.openai.com/), and [here](https://unsplash.com/developers). You will be told when to paste them. You can always change them later in the `env.yaml` file.
|
||||
|
||||
Now, open the blank text file called `subjects.txt` in the `env` folder and add the subjects you want to generate videos for, one per line. For example:
|
||||
```
|
||||
Educational and simple videos about physics
|
||||
Python tutorials for both beginners and advanced programmers
|
||||
```
|
||||
One per line.
|
||||
|
||||
You should also prepare google oauth client id json for the youtube api for each account youo want to automate. You can find a tutorial on how to do that [here](https://developers.google.com/youtube/v3/quickstart/python). You will be asked to add it to the corresponding folder when you run the script for the first time for each subject.
|
||||
You should also prepare google oauth client id json for the youtube api for each account you want to automate. You can find a tutorial on how to do that [here](https://developers.google.com/youtube/v3/quickstart/python). You will be asked to add it to the corresponding folder when you run the script for the first time for each channel.
|
||||
|
||||
Now, you can run the `main.py` script to generate the videos. If it is the first time you are running the script, it will ask you to log in to your Google account, as well as creating and moving or creating some files. The created videos will be saved in the `videos` folder, and automatically uploaded to YouTube. The script will also create a thumbnail and a description for each video, and add a nice background music to it.
|
||||
|
||||
# Other stuff
|
||||
In each channel's folder there will be a `channel.yaml` file with all of the channel's settings. You can change them manually, but you will need to restart the script for the changes to take effect.
|
||||
@@ -39,7 +39,19 @@ VALID_PRIVACY_STATUSES = ('public', 'private', 'unlisted')
|
||||
|
||||
# Authorize the request and store authorization credentials.
|
||||
async def get_authenticated_service(credentialsPath=""):
|
||||
CLIENT_SECRETS_FILE=f'{credentialsPath}/client_secret.json'
|
||||
CLIENT_SECRETS_FILE = ""
|
||||
try:
|
||||
CLIENT_SECRETS_FILE=os.path.join(credentialsPath, "client_secret.json")
|
||||
except:
|
||||
listdir = os.listdir(credentialsPath)
|
||||
for file in listdir:
|
||||
if file.startswith("client_secret"):
|
||||
#rename file to client_secret.json
|
||||
os.rename(os.path.join(credentialsPath, file), os.path.join(credentialsPath, "client_secret.json"))
|
||||
CLIENT_SECRETS_FILE=os.path.join(credentialsPath, "client_secret.json")
|
||||
break
|
||||
if CLIENT_SECRETS_FILE == "":
|
||||
raise FileNotFoundError("No client_secret.json file found in the specified path !")
|
||||
if os.path.exists(f'{credentialsPath}/credentials.json'):
|
||||
with open(f'{credentialsPath}/credentials.json') as json_file:
|
||||
data = json.load(json_file)
|
||||
@@ -143,7 +155,7 @@ async def upload_video(path, title, description, category, keywords, privacyStat
|
||||
print('An HTTP error %d occurred:\n%s' % (e.resp.status, e.content))
|
||||
|
||||
async def upload_thumbnail(video_id, file, credentials_path=""):
|
||||
youtube = get_authenticated_service(credentials_path)
|
||||
youtube = await get_authenticated_service(credentials_path)
|
||||
youtube.thumbnails().set( # type: ignore
|
||||
videoId=video_id,
|
||||
media_body=file
|
||||
|
||||
Reference in New Issue
Block a user