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))