|
|
import os.path
|
|
|
import random
|
|
|
import subprocess
|
|
|
import time
|
|
|
import uuid
|
|
|
import pyautogui
|
|
|
|
|
|
from Util import ConfigUtil
|
|
|
from Util.Win32Util import *
|
|
|
import pyperclip
|
|
|
|
|
|
# pip install pyautogui
|
|
|
# pip install pywin32
|
|
|
# pip install pyperclip
|
|
|
|
|
|
# PyAutoGUI fail-safe triggered from mouse moving to a corner of the screen
|
|
|
|
|
|
# pip install screeninfo
|
|
|
from screeninfo import get_monitors
|
|
|
|
|
|
|
|
|
def open_jian_ying():
|
|
|
# 关闭剪映
|
|
|
subprocess.Popen(['taskkill', '/F', '/IM', 'JianyingPro.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
|
text=True)
|
|
|
time.sleep(1)
|
|
|
# 清理剪映的草稿区
|
|
|
remove_dir_contents(JianYingCaoGao)
|
|
|
# 打开剪眏
|
|
|
subprocess.Popen([jianYingExePath])
|
|
|
time.sleep(3)
|
|
|
|
|
|
# 检查是不是已经正确打开了
|
|
|
while True:
|
|
|
appwindows = get_app_list()
|
|
|
found = False
|
|
|
for x in appwindows:
|
|
|
if x[1] == '剪映专业版':
|
|
|
found = True
|
|
|
break
|
|
|
if found:
|
|
|
break
|
|
|
else:
|
|
|
printf('Loading...')
|
|
|
time.sleep(1)
|
|
|
|
|
|
# 激活剪映为当前操作窗口
|
|
|
hwnd = x[0]
|
|
|
time.sleep(3)
|
|
|
# 显示为当前窗口
|
|
|
win32gui.SetForegroundWindow(hwnd)
|
|
|
# 移动窗口到指定的显示器左上角上去
|
|
|
win32gui.SetWindowPos(hwnd, win32con.HWND_TOP, wm.x, wm.y, 0, 0, win32con.SWP_NOSIZE)
|
|
|
# 最大化
|
|
|
win32gui.ShowWindow(hwnd, win32con.SW_SHOWMAXIMIZED)
|
|
|
# 破解剪映
|
|
|
crack_jian_ying()
|
|
|
return hwnd
|
|
|
|
|
|
|
|
|
# 破解剪映VIP
|
|
|
def crack_jian_ying():
|
|
|
jian_ying_exe_path = r'解锁版本插件_5.5.0.exe'
|
|
|
# 关闭剪映破解插件
|
|
|
subprocess.Popen(['taskkill', '/F', '/IM', jian_ying_exe_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
|
text=True)
|
|
|
# 等待关闭完成
|
|
|
time.sleep(3)
|
|
|
subprocess.Popen([jian_ying_exe_path]) # 打开破解软件
|
|
|
time.sleep(4)
|
|
|
|
|
|
# 检查内存中破解软件是否已经打开
|
|
|
appwindows = get_app_list()
|
|
|
is_running = False
|
|
|
for x in appwindows:
|
|
|
if x[1] == '---bili-瓜皮lin':
|
|
|
hwnd = x[0]
|
|
|
is_running = True
|
|
|
|
|
|
if is_running:
|
|
|
win32gui.SetForegroundWindow(hwnd)
|
|
|
# 移动窗口到指定的显示器左上角上去
|
|
|
win32gui.SetWindowPos(hwnd, win32con.HWND_TOP, wm.x, wm.y, 0, 0, win32con.SWP_NOSIZE)
|
|
|
pyautogui.press('enter')
|
|
|
time.sleep(1)
|
|
|
pyautogui.press('enter')
|
|
|
else:
|
|
|
printf("剪映未运行!")
|
|
|
|
|
|
|
|
|
# 导入图片
|
|
|
def import_img(hwnd, img_path):
|
|
|
# 开始创作
|
|
|
x = wm.x + 554
|
|
|
y = 90
|
|
|
|
|
|
# 将鼠标移动到坐标处
|
|
|
pyautogui.moveTo(x, y)
|
|
|
# 单击左键
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
#
|
|
|
# 此时有两个剪映专业版, 我们找第二个
|
|
|
while True:
|
|
|
appwindows = get_app_list()
|
|
|
found = False
|
|
|
for x in appwindows:
|
|
|
if x[1] == '剪映专业版' and x[0] != hwnd:
|
|
|
found = True
|
|
|
break
|
|
|
if found:
|
|
|
time.sleep(1)
|
|
|
break
|
|
|
hwnd = x[0]
|
|
|
time.sleep(1)
|
|
|
# 最大化
|
|
|
win32gui.ShowWindow(hwnd, win32con.SW_SHOWMAXIMIZED)
|
|
|
time.sleep(1)
|
|
|
|
|
|
# # 导入按钮
|
|
|
x = wm.x + 398
|
|
|
y = 321
|
|
|
# 将鼠标移动到坐标处
|
|
|
pyautogui.moveTo(x, y)
|
|
|
# 单击左键
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
# 输入图片路径
|
|
|
pyautogui.typewrite(img_path)
|
|
|
# # 回车
|
|
|
pyautogui.press('enter')
|
|
|
time.sleep(1)
|
|
|
|
|
|
# # 【还在是选择所有图片!!!】 图片选择区域的空白部分
|
|
|
x = wm.x + 581
|
|
|
y = 385
|
|
|
pyautogui.moveTo(x, y)
|
|
|
# 单击左键,获取焦点
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
# Ctrl+A,全选
|
|
|
# 组合按键 ctrl + a
|
|
|
pyautogui.hotkey('ctrl', 'a')
|
|
|
pyautogui.press('enter')
|
|
|
time.sleep(1)
|
|
|
|
|
|
pyautogui.moveTo(wm.x + 173, wm.y + 231) # 移动到导入区的空白位置
|
|
|
pyautogui.dragTo(wm.x + 233, wm.y + 814, 0.5, button='left') # 进行拖动
|
|
|
pyautogui.dragTo(wm.x + 188, wm.y + 810, 0.5, button='left') # 进行拖动
|
|
|
|
|
|
|
|
|
def cut_mp3(img_count):
|
|
|
# 切割歌曲,将标尺在开头定位住
|
|
|
pyautogui.moveTo(wm.x + 169, 610)
|
|
|
# 拖动标尺到达最后一个图片的边缘
|
|
|
pyautogui.dragTo(wm.x + 169 + img_count * 41, 605, 0.5, button='left')
|
|
|
# 移动鼠标到声音轨
|
|
|
pyautogui.moveTo(wm.x + 169 + img_count * 41, 888)
|
|
|
# 点击鼠标使声音轨获取焦点
|
|
|
pyautogui.click()
|
|
|
# 移动鼠标到向右切割按钮处
|
|
|
pyautogui.moveTo(wm.x + 245, 584)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
|
# 导出功能
|
|
|
def export(video_name):
|
|
|
# 导出
|
|
|
pyautogui.moveTo(1530, 20)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
# 导出窗口的配置页面
|
|
|
pyautogui.moveTo(1027, 245)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
pyautogui.hotkey('ctrl', 'a')
|
|
|
time.sleep(1)
|
|
|
pyautogui.hotkey('backspace') # 退格
|
|
|
time.sleep(1)
|
|
|
pyautogui.typewrite(video_name)
|
|
|
time.sleep(1)
|
|
|
|
|
|
# 导出目录
|
|
|
fullPath = os.path.join(JiangYingOutPath, video_name + '.mp4')
|
|
|
if os.path.exists(fullPath):
|
|
|
os.remove(fullPath)
|
|
|
|
|
|
# 输出路径
|
|
|
# 使用pyperclip复制字符串到剪贴板
|
|
|
pyperclip.copy(JiangYingOutPath)
|
|
|
|
|
|
pyautogui.moveTo(1130, 284)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
pyautogui.hotkey('ctrl', 'v')
|
|
|
time.sleep(1)
|
|
|
|
|
|
pyautogui.hotkey('tab')
|
|
|
pyautogui.hotkey('enter')
|
|
|
time.sleep(1)
|
|
|
|
|
|
# 点击导出按钮
|
|
|
pyautogui.moveTo(1027, 812)
|
|
|
pyautogui.click()
|
|
|
|
|
|
# 等待导出完成
|
|
|
while True:
|
|
|
if os.path.exists(fullPath):
|
|
|
printf('导出完成')
|
|
|
time.sleep(3) # 多等3秒已确保完成
|
|
|
# 根据handler关闭第二个窗口
|
|
|
pyautogui.hotkey('alt', 'f4') # 关闭
|
|
|
time.sleep(1)
|
|
|
pyautogui.hotkey('alt', 'f4') # 关闭
|
|
|
time.sleep(1)
|
|
|
break
|
|
|
else:
|
|
|
printf('waiting...')
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
|
def run_once(hwnd, img_path, img_count):
|
|
|
# 视频名称
|
|
|
video_name = str(uuid.uuid4())
|
|
|
# 导入图片到时间轴
|
|
|
import_img(hwnd, img_path)
|
|
|
|
|
|
# 切割歌曲
|
|
|
cut_mp3(img_count)
|
|
|
|
|
|
# 每个图片添加动画换场效果
|
|
|
dhx = wm.x + 1404
|
|
|
dhy = 57
|
|
|
d = 0
|
|
|
imgList = []
|
|
|
xgx = wm.x + 170 # 效果的第一个图片左侧边缘位置坐标
|
|
|
|
|
|
for i in range(0, img_count):
|
|
|
# 点击封面轨道中的每张图片
|
|
|
x = wm.x + 190 + d # (190,813)是指第一张的位置
|
|
|
y = 813
|
|
|
imgList.append({x, y})
|
|
|
pyautogui.moveTo(x, y)
|
|
|
d += 40
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
|
|
|
# 动画按钮
|
|
|
pyautogui.moveTo(dhx, dhy)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
# 选择了过场动画1~6
|
|
|
zb = [(wm.x + 1334, 174), (wm.x + 1413, 174), (wm.x + 1492, 174), (wm.x + 1569, 174), (wm.x + 1254, 244),
|
|
|
(wm.x + 1332, 244)]
|
|
|
# 产生一个0~5的随机值
|
|
|
r = random.randint(0, 5)
|
|
|
pyautogui.moveTo(zb[r][0], zb[r][1])
|
|
|
pyautogui.click()
|
|
|
# 休息一下
|
|
|
time.sleep(1)
|
|
|
|
|
|
# 拖拽特效
|
|
|
pyautogui.moveTo(wm.x + 265, 58) # 顶部特效按钮
|
|
|
pyautogui.click()
|
|
|
pyautogui.moveTo(wm.x + 67, 150) # 左侧人物特效按钮
|
|
|
pyautogui.click()
|
|
|
time.sleep(0.5)
|
|
|
|
|
|
# 首次多等一会
|
|
|
# if i == 0:
|
|
|
# pyautogui.moveTo(wm.x + 265, 58) # 顶部特效按钮
|
|
|
# pyautogui.click()
|
|
|
# pyautogui.moveTo(wm.x + 67, 150) # 左侧人物特效按钮
|
|
|
# pyautogui.click()
|
|
|
# # 首次多等一会
|
|
|
# time.sleep(3)
|
|
|
#
|
|
|
# zb = [(wm.x + 158, 221), (wm.x + 258, 221), (wm.x + 358, 221),
|
|
|
# (wm.x + 157, 337), (wm.x + 260, 337),
|
|
|
# (wm.x + 360, 337), (wm.x + 465, 335),
|
|
|
# (wm.x + 266, wm.x + 457)]
|
|
|
# # 产生一个0~7的随机值
|
|
|
# r = random.randint(0, 7)
|
|
|
# pyautogui.moveTo(zb[r][0], zb[r][1])
|
|
|
# pyautogui.click()
|
|
|
# # 鼠标拖拽到轨道上
|
|
|
# pyautogui.dragTo(wm.x + xgx, 763, 0.5, button='left')
|
|
|
# xgx = xgx + 38 # 38是偏移量,即每个特效有效长度38
|
|
|
# # 导出
|
|
|
# export(video_name)
|
|
|
return video_name
|
|
|
|
|
|
|
|
|
# 生成图片切换效果
|
|
|
def run_switch(hwnd, source_img, cartoon_img):
|
|
|
if os.path.exists(tempDir):
|
|
|
remove_dir_contents(tempDir) # 存在这个目录,就删除掉
|
|
|
else:
|
|
|
os.makedirs(tempDir)
|
|
|
# 将sourceImg,CartoonImg复制到tempDir目录下
|
|
|
shutil.copy(source_img, tempDir)
|
|
|
shutil.copy(cartoon_img, tempDir)
|
|
|
# 将tempDir目录下的sourceImg,CartoonImg两个文件修改名称为1.png,2.png,这样方便一会批量导入到剪映中,知道哪个在第一个位置上
|
|
|
os.rename(os.path.join(tempDir, source_img.split('\\')[-1]), os.path.join(tempDir, '1.png'))
|
|
|
os.rename(os.path.join(tempDir, cartoon_img.split('\\')[-1]), os.path.join(tempDir, '2.png'))
|
|
|
shutil.copy(mp3, tempDir)
|
|
|
|
|
|
# 将三个文件导入到剪映中
|
|
|
import_img(hwnd, tempDir)
|
|
|
|
|
|
# 将图2.png向上拖动到封面轨道的上方
|
|
|
pyautogui.moveTo(232, 816)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
pyautogui.dragTo(189, 744, 0.5, button='left')
|
|
|
|
|
|
# pyautogui.moveTo(2110, 741) # 定位卡通画
|
|
|
# pyautogui.click() # 点击使得卡通画成为焦点
|
|
|
pyautogui.moveTo(211, 742) # 开始拖拽卡通画的右侧边缘
|
|
|
pyautogui.dragTo(256, 742, 0.5, button='left')
|
|
|
|
|
|
pyautogui.moveTo(191, 817) # 定们原画
|
|
|
pyautogui.click() # 点击使得原画成为焦点
|
|
|
pyautogui.moveTo(211, 815) # 开始拖拽原画的右侧边缘
|
|
|
pyautogui.dragTo(256, 797, 0.5, button='left')
|
|
|
|
|
|
# 将MP3也处理相同的长度
|
|
|
cut_mp3(2.4)
|
|
|
|
|
|
# # 点击卡通图片
|
|
|
pyautogui.moveTo(218, 746)
|
|
|
pyautogui.click()
|
|
|
|
|
|
pyautogui.moveTo(1287, 60) # 移动鼠标到动画上
|
|
|
pyautogui.click()
|
|
|
time.sleep(3)
|
|
|
|
|
|
pyautogui.moveTo(1416, 256) # 移动鼠标到入场的空白区域内
|
|
|
pyautogui.click()
|
|
|
pyautogui.scroll(-10) # 向下滚动鼠标10个刻度,保证向左滑动露出来
|
|
|
|
|
|
pyautogui.moveTo(1253, 522) # 点击向左滑动
|
|
|
pyautogui.doubleClick()
|
|
|
|
|
|
pyautogui.moveTo(1300, 548) # 动画时长
|
|
|
pyautogui.click()
|
|
|
pyautogui.hotkey('ctrl', 'a')
|
|
|
pyautogui.press('backspace')
|
|
|
time.sleep(1)
|
|
|
pyautogui.typewrite("6")
|
|
|
pyautogui.press('enter')
|
|
|
|
|
|
# 导出
|
|
|
video_name = str(uuid.uuid4())
|
|
|
export(video_name)
|
|
|
return video_name
|
|
|
|
|
|
|
|
|
# https://blog.csdn.net/nongcunqq/article/details/114022284
|
|
|
def keybd_event(VK_CODE): # VK_CODE为键盘编码
|
|
|
win32api.keybd_event(VK_CODE, 0, 0, 0)
|
|
|
win32api.keybd_event(VK_CODE, 0, win32con.KEYEVENTF_KEYUP, 0)
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
# 打开CapsLock,防止中文输入法影响程序运行
|
|
|
if win32api.GetKeyState(win32con.VK_CAPITAL) == 0:
|
|
|
keybd_event(20)
|
|
|
|
|
|
# 配置文件
|
|
|
config = ConfigUtil.getConfig()
|
|
|
# 剪映运行的显示器编号
|
|
|
working_id = int(config['monitor']['working_id'])
|
|
|
# 显示器个数检查
|
|
|
monitors = get_monitors()
|
|
|
if len(monitors) < working_id:
|
|
|
printf('显示器数量小于配置的显示器编号')
|
|
|
exit(0)
|
|
|
|
|
|
# 坐标测试的屏幕分辨率:1680*1050
|
|
|
wm = monitors[working_id - 1]
|
|
|
|
|
|
# 获取当前脚本文件的绝对路径
|
|
|
script_path = os.path.abspath(__file__)
|
|
|
# 获取脚本文件所在的磁盘分区
|
|
|
# 这将返回脚本文件所在的完整路径,包括磁盘分区
|
|
|
disk_partition = os.path.splitdrive(script_path)[0]
|
|
|
|
|
|
# 清时剪映的草稿区
|
|
|
JianYingCaoGao = r'C:\Users\Administrator\AppData\Local\JianyingPro\User Data\Projects\com.lveditor.draft'
|
|
|
# 打开剪眏
|
|
|
jianYingExePath = r'C:\Users\Administrator\AppData\Local\JianyingPro\Apps\JianyingPro.exe'
|
|
|
|
|
|
# 模拟用户图片的位置
|
|
|
imgPath = disk_partition + r'\KeCheng\BaiHu\TestImage\Wife'
|
|
|
# 歌曲
|
|
|
mp3 = disk_partition + r'\KeCheng\BaiHu\Mp3\歌曲.mp3'
|
|
|
# 输出的路径
|
|
|
JiangYingOutPath = disk_partition + r'\JianYingOut'
|
|
|
# 临时目录
|
|
|
tempDir = disk_partition + r'\KeCheng\BaiHu\TestImage\temp'
|
|
|
|
|
|
# 打开剪映
|
|
|
hwnd = open_jian_ying()
|
|
|
|
|
|
# 操作类型,1:生成MV,2:生成图片切换
|
|
|
type_id = 1
|
|
|
|
|
|
# 生成MV
|
|
|
if type_id == 1:
|
|
|
# 用户上传了多少张图片
|
|
|
imgCount = count_files(imgPath) - 1 # 因为有一个是MP3
|
|
|
# 拷贝MP3文件到imgPath目录
|
|
|
shutil.copy(mp3, imgPath)
|
|
|
videoName = run_once(hwnd, imgPath, imgCount) + '.mp4'
|
|
|
print(os.path.join(JiangYingOutPath, videoName))
|
|
|
#
|
|
|
# # 生成图片切换
|
|
|
# if type_id == 2:
|
|
|
# sourceImg = disk_partition + r'\KeCheng\BaiHu\TestImage\Wife\wife.jpg'
|
|
|
# CartoonImg = disk_partition + r'\KeCheng\BaiHu\TestImage\Wife\3.png'
|
|
|
# videoName = run_switch(hwnd, sourceImg, CartoonImg) + '.mp4'
|
|
|
# print(os.path.join(JiangYingOutPath, videoName))
|