共计 7088 个字符,预计需要花费 18 分钟才能阅读完成。
代码成果演示
Gitee 源码
# -*- coding: utf-8 -*- | |
# Version: Python 3.9.7 | |
# Author: TRIX | |
# Date: 2021-09-14 21:34:14 | |
# Use: 主动生成视频封面 并主动上传视频到 B 站 和 西瓜视频 因为该程序局部代码只适配于作者的硬件和软件 局部快捷键为作者自定义 在对代码批改前 请勿随便运行该程序 视频配置要求文件 VideoConfig.txt | |
#应用之前 先配置 VideoConfig.txt 且保障网络失常 如果程序出错 鼠标挪动到屏幕左上角进行程序运行 | |
from pyautogui import * | |
from PIL import Image,ImageDraw,ImageFont | |
from time import sleep,time | |
import pyperclip | |
import os,fnmatch | |
import shutil | |
from send2trash import send2trash | |
def coverGener(title,fontPath,coverSavePath): | |
'''题目文本 最多九个汉字 字体 封面生成目录''' | |
pic=Image.new('RGBA',(1146,717),'#1D1D1F')# 以 MODE 模式 新建一个 (weight,height) 纯色图片 如果不指定色彩 默认为通明彩色 0 0 0 0 默认分辨率 72 图片打印分辨率要求 300 | |
drawer=ImageDraw.Draw(pic)# 绘制器 | |
fontCode=ImageFont.truetype(font=fontPath,size=100)#ImageFont 对象 ttf 字体格局 | |
drawer.text((650,64),'源码',fill='#F25228',align='center',font=fontCode)#(x,y)处 写入 str fill 色彩 align 对齐 | |
fontBrief=ImageFont.truetype(font=fontPath,size=74)#ImageFont 对象 ttf 字体格局 | |
drawer.text((850,85),'在简介',fill='#F25228',align='center',font=fontBrief)#(x,y)处 写入 str fill 色彩 align 对齐 | |
fontTitle=ImageFont.truetype(font=fontPath,size=120)#ImageFont 对象 ttf 字体格局 | |
titleW,titleH=drawer.textsize(title,font=fontTitle)# 返回 str 的(weight,height) | |
drawer.text((int((1146-titleW)/2),215),title,fill='#00A3ED',align='center',font=fontTitle)#(x,y)处 写入 str fill 色彩 align 对齐 | |
fontSub=ImageFont.truetype(font=fontPath,size=88)#ImageFont 对象 ttf 字体格局 | |
drawer.text((128,400),'Python 程序 成果演示',fill='#F5F5F7',align='center',font=fontSub)#(x,y)处 写入 D:\[vidstr fill 色彩 align 对齐 | |
pic.save(coverSavePath, quality=100,dpi=(300,300))# 无色差保留 网络图片不会呈现色差问题 只有 拍摄照片 或 PS 等软件 解决后的图片会有色差问题 罕用模式 RGB RGBA CMYK L 黑白模式 高质量 300 分辨率 默认分辨率 72 图片打印分辨率要求 300 | |
def uploadToXigua(delay,videoSavePath,title,titleSuffix,coverSavePath,videoBriefTitle,videoBrief,codeSiteTitle,codeSite,mode): | |
click(1440,140)# 点击集体网站 | |
click(1732,244,button='right')# 抉择西瓜上传视频页面 | |
click(1463,245)# 在新页面关上 | |
hotkey('ctrl','pgdn')# 切换到上传页面 | |
sleep(2.5+delay) | |
click(1210,578)# 点击上传视频 | |
sleep(1+delay) | |
hotkey('shift','alt','s')# 抉择文件快捷键 | |
typewrite(videoSavePath)# 抉择视频贮存文件夹 | |
sleep(0.5+delay) | |
press('enter') | |
hotkey('winleft','left')# 分屏窗口快捷键 | |
click(570,191)# 抉择视频 | |
click(760,990)# 确认视频 | |
sleep(0.5+delay) | |
#编辑题目 | |
click(767,651)# 进入题目编辑区域 | |
pyperclip.copy(title)# 复制题目到剪贴板 | |
hotkey('ctrl','v')# 粘贴题目 | |
pyperclip.copy(titleSuffix)# 复制题目后缀到剪贴板 | |
hotkey('ctrl','v')# 粘贴题目后缀 | |
#抉择封面 | |
click(690,884)# 抉择视频封面 | |
sleep(0.5+delay) | |
click(464,230)# 抉择本地上传 | |
click(950,615)# 抉择上传本地图片 | |
sleep(1+delay) | |
hotkey('winleft','left')# 分屏窗口快捷键 | |
hotkey('shift','alt','s')# 抉择文件快捷键 | |
typewrite(coverSavePath)# 抉择视频封面 | |
sleep(0.5+delay) | |
press('enter') | |
sleep(1+delay) | |
click(1215,567)# 切换到封面编辑界面 | |
dragTo(1215,258,duration=0.5)# 编辑视频封面 | |
sleep(1+delay) | |
click(1195,982)# 退出编辑区域 | |
sleep(1+delay) | |
click(1545,834)# 实现剪裁 | |
sleep(1+delay) | |
click(1593,992)# 点击确定 | |
sleep(0.5+delay) | |
click(1060,682)# 点击最终确定 | |
sleep(2+delay) | |
click(1120,855)# 退出封面编辑界面 | |
#编辑视频为原创 | |
hotkey('ctrl','home')# 转到视频上传页面结尾 | |
typewrite(['down' for n in range(4)])# 向下滚动 4 格 | |
click(535,778)# 点击原创 | |
#编辑简介 | |
click(450,939)# 点击更多选项 | |
typewrite(['down' for n in range(2)])# 向下滚动 2 格 | |
click(623,868)# 进入简介编辑区域 | |
pyperclip.copy(videoBriefTitle) | |
hotkey('ctrl','v')# 粘贴简介题目 | |
pyperclip.copy(videoBrief) | |
hotkey('ctrl','v')# 粘贴简介 | |
press('enter')# 分段 | |
pyperclip.copy(codeSiteTitle) | |
hotkey('ctrl','v')# 粘贴源码链接题目 | |
pyperclip.copy(codeSite) | |
hotkey('ctrl','v')# 粘贴源码链接 | |
click(1244,574)# 退出标签编辑区域 | |
#投稿 | |
hotkey('ctrl','end')# 挪动到视频编辑页面尾部 | |
if mode=='upload': | |
click(447,933)# 点击公布 | |
elif mode=='test': | |
click(586,934)# 点击存草稿 | |
def uploadToBilibil(delay,videoSavePath,coverSavePath,title,labelList,videoBrief,codeSite,mode): | |
click(1440,140)# 点击集体网站 | |
click(1730,350,button='right')# 抉择 B 站上传视频页面 | |
click(1440,250)# 在新页面关上 | |
hotkey('ctrl','pgdn')# 切换到上传页面 | |
sleep(2.5+delay) | |
click(1120,800)# 点击上传视频 | |
sleep(1+delay) | |
hotkey('shift','alt','s')# 抉择文件快捷键 | |
typewrite(videoSavePath)# 抉择视频贮存文件夹 | |
sleep(0.5+delay) | |
press('enter') | |
hotkey('winleft','left')# 分屏窗口快捷键 | |
click(570,191)# 抉择视频 | |
click(760,990)# 确认视频 | |
sleep(0.5+delay) | |
#抉择视频模板 | |
click(1600,810)# 抉择模板界面 | |
click(1430,930)# 点击 Python 模板 | |
#抉择封面 | |
press('tab')# 切换到封面按钮 | |
click(580,955)# 点击抉择封面 | |
sleep(1+delay) | |
hotkey('winleft','left')# 分屏窗口快捷键 | |
hotkey('shift','alt','s')# 抉择文件快捷键 | |
typewrite(coverSavePath)# 抉择视频封面 | |
sleep(0.5+delay) | |
press('enter') | |
sleep(1+delay) | |
click(1280,740)# 切换到封面编辑界面 | |
press('down')# 向下滚动一格 | |
click(1210,930)# 确认封面 | |
sleep(1+delay) | |
#编辑题目 | |
typewrite(['down','down','down','down',])# 向下滚动页面 4 格 | |
click(785,895)# 进入题目编辑区域 | |
press('home')# 光标挪动到题目结尾 | |
pyperclip.copy(title)# 复制题目到剪贴板 | |
hotkey('ctrl','v')# 粘贴题目 | |
click(1100,780)# 退出题目编辑区域 | |
#编辑标签 | |
typewrite(['down','down','down','down',])# 向下滚动页面 4 格 | |
click(1300,875)# 进入标签编辑区域 | |
for label in labelList:# 粘贴标签 | |
pyperclip.copy(label) | |
hotkey('ctrl','v') | |
press('enter') | |
sleep(0.5) | |
click(1275,730)# 退出标签编辑区域 | |
#编辑粉丝动静 | |
hotkey('ctrl','end')# 挪动到视频编辑界面结尾 | |
click(900,490)# 进入粉丝动静编辑区域 | |
pyperclip.copy(videoBrief) | |
hotkey('ctrl','v')# 粘贴简介 | |
click(1170,760)# 退出粉丝动静编辑区域 | |
#编辑简介 | |
typewrite(['up' for n in range(18)])# 向上滚动页面 18 格 | |
click(650,459)# 进入视频简介编辑 | |
hotkey('ctrl','v')# 粘贴简介 | |
hotkey('ctrl','end')# 挪动到简介编辑区结尾 | |
pyperclip.copy(codeSite) | |
hotkey('ctrl','v')# 粘贴源码链接 | |
click(1234,815)# 退出视频简介编辑 | |
#投稿 | |
hotkey('ctrl','end')# 挪动到视频上传页面尾部 | |
if mode=='upload': | |
click(595,780)# 投稿视频 | |
elif mode=='test': | |
click(795,780)# 保留模板 | |
def uploadVideo(mode='upload',delay=0):# 上传视频所有步骤 mode 上传模式 | |
startTimeStamp=time()-90# 程序开始运行的工夫 | |
#关上 VideoConfig.txt 具体介绍和条件要求 在 VideoConfig.txt | |
with open('VideoConfig.txt','r',encoding='utf-8')as f:# 读取视频所有配置 | |
config = f.readlines()[1:13] | |
title=config[0].split('=')[1].strip() | |
videoLabels = config[1].split('=')[1].strip() | |
labelList=videoLabels.split() | |
if len(labelList)>4: | |
raise ValueError('标签最多 4 个 请从新编辑') | |
videoBriefTitle = config[2].split('=')[1].strip() | |
videoBrief = config[3].split('=')[1].strip() | |
codeSiteTitle=config[4].split('=')[1].strip() | |
codeSite=config[5].split('://')[1].strip() | |
if len(codeSite)>131: | |
raise ValueError('源码链接最多 131 个字符 请从新编辑') | |
coverSavePath=config[6].split('=')[1].strip() | |
fontPath=config[7].split('=')[1].strip() | |
videoSavePath=config[8].split('=')[1].strip() | |
titleSuffix=config[9].split('=')[1].strip() | |
videoUploadedPath=config[10].split('=')[1].strip() | |
videoFormat=config[11].split('=')[1].strip() | |
#生成视频封面 | |
coverGener(title,fontPath,coverSavePath) | |
#上传视频 缩放比例为 90% 分辨率 1920x1080 固定坐标 执行操作有提早 相应点击坐标不能大幅度扭转 | |
#关上 Edge 浏览器 | |
click(160,1060) | |
sleep(2+delay) | |
#切换输入法 | |
click(1802,1056)# 点击输入法 | |
click(1720,885)# 切换到美式键盘 | |
#上传视频到 B 站 | |
uploadToBilibil(delay,videoSavePath,coverSavePath,title,labelList,videoBrief,codeSite,mode) | |
#上传视频到西瓜视频 | |
uploadToXigua(delay,videoSavePath,title,titleSuffix,coverSavePath,videoBriefTitle,videoBrief,codeSiteTitle,codeSite,mode) | |
#挪动本次上传视频到 videoUploadedPath 文件夹 | |
for file in fnmatch.filter(os.listdir(videoSavePath), '*.'+videoFormat):# 在第一级目录匹配惟一的 mp4 文件 | |
if startTimeStamp>os.path.getctime(videoSavePath+'\\'+file):# 所要上传的视频创立的工夫戳 < 程序开始运行工夫戳 -90s< 正在录制的这个视频创立的工夫戳 | |
shutil.move(videoSavePath+'\\'+file,videoUploadedPath)# 挪动本次上传视频到 videoUploadedPath 文件夹 | |
#检测 videoUploadedPath 文件夹内 video 个数 把文件夹内 创立工夫最早的文件 挪动到回收站 | |
leastTimeStamp=time()# 返回当初 unix 工夫戳 | |
for i,file in enumerate(fnmatch.filter(os.listdir(videoUploadedPath), '*.'+videoFormat)):# 对外面的每个 mp4 文件 | |
fileTimeStamp=os.path.getctime(videoUploadedPath+'\\'+file)# 输入文件创建工夫 unix 工夫戳 | |
if fileTimeStamp<=leastTimeStamp:# 如果文件创建工夫戳比以后最小工夫戳还小 | |
leastTimeStamp=fileTimeStamp | |
for i,file in enumerate(os.listdir(videoUploadedPath)):# 对外面的每个 mp4 文件 | |
if leastTimeStamp==os.path.getctime(videoUploadedPath+'\\'+file):# 如果最小工夫戳 = 文件创建工夫戳 | |
send2trash(videoUploadedPath+'\\'+file)# 把该文件挪动到回收站 | |
FAILSAFE=True# 如果程序出错 鼠标挪动到屏幕左上角 抛出 pyautogui.FailSafeException 异样 并进行程序 | |
#应用之前 先配置 VideoConfig.txt 且确保网络失常 确保浏览器关上的页面不超过 1 | |
uploadVideo(mode='upload',delay=0) | |
#mode:test 测试是否失常执行上传步骤 或 upload 上传视频 默认为 upload | |
#delay:float 程序关键步骤执行提早秒数 默认提早 0 秒 |
正文完