You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
6.1 KiB
191 lines
6.1 KiB
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¤t_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() |