pull/2070/head
cyteon 1 year ago
parent 83f6b983d4
commit ffd7f2518e

1
.gitignore vendored

@ -240,6 +240,7 @@ out
.DS_Store
.setup-done-before
results/*
capcut_results/*
clipped/*
reddit-bot-351418-5560ebc49cac.json
/.idea

@ -70,7 +70,7 @@ def run_many(times) -> None:
f'on the {x}{("th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th")[x % 10]} iteration of {times}'
) # correct 1st 2nd 3rd 4th 5th....
main()
Popen("cls" if name == "nt" else "clear", shell=True).wait()
#Popen("cls" if name == "nt" else "clear", shell=True).wait()
if settings.config["settings"]["mememode"]:
make_meme_video()
@ -103,7 +103,7 @@ if __name__ == "__main__":
f'on the {index}{("st" if index % 10 == 1 else ("nd" if index % 10 == 2 else ("rd" if index % 10 == 3 else "th")))} post of {len(config["reddit"]["thread"]["post_id"].split("+"))}'
)
main(post_id)
Popen("cls" if name == "nt" else "clear", shell=True).wait()
#Popen("cls" if name == "nt" else "clear", shell=True).wait()
elif config["settings"]["times_to_run"]:
run_many(config["settings"]["times_to_run"])
else:

@ -21,3 +21,4 @@ transformers==4.39.3
ffmpeg-python==0.2.0
elevenlabs==0.2.17
yt-dlp==2023.7.6
bs4

@ -5,6 +5,11 @@ username = { optional = false, nmin = 3, nmax = 20, explanation = "The username
password = { optional = false, nmin = 8, explanation = "The password of your reddit account", example = "fFAGRNJru1FTz70BzhT3Zg", oob_error = "Password too short" }
2fa = { optional = true, type = "bool", options = [true, false, ], default = false, explanation = "Whether you have Reddit 2FA enabled, Valid options are True and False", example = true }
[capcut]
email = { optional = false, nmin = 3, nmax = 50, explanation = "The email of your CapCut account", example = ""}
password = { optional = false, nmin = 8, explanation = "The password of your CapCut account", example = ""}
cloud_id = { optional = false, nmin = 8, type="int", explanation = "The cloud id of your CapCut account", example = ""}
preset_number = { optional = true, default=18, type="int", explanation = "The preset number of your CapCut account", example = 1}
[reddit.thread]
random = { optional = true, options = [true, false, ], default = false, type = "bool", explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it. Default: 'False'", example = "True" }

@ -0,0 +1,191 @@
import json
import time
import os
from playwright.sync_api import sync_playwright
from playwright.async_api import async_playwright
import asyncio
from bs4 import BeautifulSoup
from utils import settings
# Utils
def check_similarity(video_title, text):
video_title_words = set(video_title.lower().split())
text_words = set(text.lower().split())
common_words = text_words.intersection(video_title_words)
return len(common_words) / len(text_words) >= 0.6
# Runthrough
def generate_captions(file_path, title):
with sync_playwright() as playwright:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context(viewport={"width": 1920, "height": 1080})
page = context.new_page()
page.goto("https://www.capcut.com/")
email = settings.config["capcut"]["email"]
password = settings.config["capcut"]["password"]
video_title = title.lower()
video_file_name = title.replace(" ", "_")
page.click("//span[contains(text(),'Decline all')]")
page.click("//span[contains(text(),'OK')]")
page.click("//span[contains(text(),'Sign in')]")
page.fill("//input[@class='lv-input lv-input-size-default lv_sign_in_panel_wide-input']", email)
page.click("//span[normalize-space()='Continue']")
# time.sleep(5)
page.fill("//input[@type='password']", password)
page.click("//span[contains(text(),'Sign in')]")
try:
page.click("//div[@class='skip--kncMC']")
except:
pass
page.goto(f"https://www.capcut.com/my-cloud/{str(settings.config['capcut']['cloud_id'])}?start_tab=video&enter_from=page_header&from_page=work_space&tab=all")
try:
page.click("//span[contains(text(),'Decline all')]")
except:
pass
page.click("//div[@class='guide-modal-close-icon']")
page.hover("//div[@data-selectable-item-id]")
page.click("//*[@width='16']")
page.click("//div[contains(text(),'Move to Trash')]")
page.click("//span[contains(text(),'Confirm')]")
# time.sleep(2)
# page.click("//span[contains(text(),'Trash')]")
# page.hover("//div[@data-selectable-item-id]")
# page.screenshot(path="video_creation/Error3.png")
page.goto("https://www.capcut.com/editor?enter_from=create_new&current_page=landing_page&from_page=work_space&start_tab=video&__action_from=my_draft&position=my_draft&scenario=youtube_ads&scale=16%3A9")
page.click("//div[@class='guide-close-icon-f8J9FZ']//*[name()='svg']")
page.click("//div[@class='guide-placeholder-before-OsTdXF']")
page.click("//div[@class='guide-close-icon-f8J9FZ']//*[name()='svg']")
page.set_input_files("(//input[@type='file'])[1]", file_path)
time.sleep(20)
page.click("//div[@id='siderMenuCaption']//div[@class='menu-inner-box']//*[name()='svg']")
page.click("//div[normalize-space()='Auto captions']")
video_ready = False
while not video_ready:
page.click("//footer[@class='active-panel']//span[contains(text(),'Generate')]")
try:
# check if class="lv-message lv-message-error" is visible
if page.locator("//div[@class='lv-message lv-message-error']").is_visible():
video_ready = False
else:
video_ready = True
except:
pass
time.sleep(10)
print("Changing settings")
page.click("//div[@id='workbench-tool-bar-toolbarTextPreset']")
time.sleep(1)
page.click("//div[@id='lv-tabs-1-tab-1']")
time.sleep(1)
page.click(f"(//img[@class='image-DUnWNW'])[{str(settings.config['capcut']['preset_number'])}]")
time.sleep(2)
page.click("//div[@id='workbench-tool-bar-toolbarTextBasic']//div[@class='tool-bar-icon']//*[name()='svg']")
time.sleep(2)
page.fill("//input[@value='-255']", "0")
time.sleep(1)
page.fill("//input[@value='100' and @aria-valuemax='500']", "40")
time.sleep(2)
print("Cleaning up captions")
for _ in range(10):
element = page.query_selector("//div[@class='subtitle-list-content']/section[1]")
html_code = page.evaluate("element => element.innerHTML", element)
soup = BeautifulSoup(html_code, 'html.parser')
textarea = soup.find('textarea', {'class': 'lv-textarea'})
text = textarea.text.lower()
if check_similarity(video_title.lower(), text.lower()):
page.click("//section[@class='subtitle-list-item']")
page.click("//button[@class='lv-btn lv-btn-text lv-btn-size-default lv-btn-shape-square']//*[name()='svg']")
else:
break
print("Exporting video")
page.click("//div[contains(@data-id,'titlebarExport')]//div[contains(@style,'position: relative;')]")
page.click("//div[contains(@class,'content_7ddfe')]")
page.fill("//input[@id='form-video_name_input']", video_file_name )
page.click("//span[contains(text(),'720p')]")
page.click("//span[contains(text(),'1080p')]")
page.click("//span[contains(text(),'Recommended quality')]")
page.click("//li[contains(text(),'High quality')]")
page.click("//span[contains(text(),'30fps')]")
page.click("//li[contains(text(),'60fps')]")
time.sleep(2)
page.click("//button[@id='export-confirm-button']")
time.sleep(35)
with page.expect_download() as download_info:
page.locator("//a[@class='shadowAnchor_5bc06']").click()
dl = download_info.value
print(dl.path())
working_dir_path = os.getcwd()
os.makedirs(os.path.join(working_dir_path, "capcut_results", "videos"), exist_ok=True)
final_path = os.path.join(working_dir_path, "capcut_results", "videos", video_file_name + ".mp4")
print(final_path)
dl.save_as(final_path)
browser.close()

@ -16,6 +16,7 @@ from rich.console import Console
from rich.progress import track
from utils import settings
from utils import capcut
from utils.cleanup import cleanup
from utils.console import print_step, print_substep
from utils.thumbnail import create_thumbnail
@ -492,8 +493,16 @@ def make_final_video(
old_percentage = pbar.n
pbar.update(100 - old_percentage)
pbar.close()
if settings.config["settings"]["storymodemethod"] == 0:
print_step("Adding CapCut captions 📝")
file_path = os.getcwd() + f"/results/{subreddit}/{filename}.mp4"
capcut.generate_captions(file_path, filename)
save_data(subreddit, filename + ".mp4", title, idx, background_config["video"][2])
print_step("Removing temporary files 🗑")
cleanups = cleanup(reddit_id)
print_substep(f"Removed {cleanups} temporary files 🗑")
print_step("Done! 🎉 The video is in the results folder 📁")

Loading…
Cancel
Save