基于moviepy库利用图片制作简易视频
- 改进了程序,增加了多线程运行,大幅提高速度
- 利用一个图片库,每次从中抽取一定数量的图片,裁剪成同一尺寸后,利用moviepy这个库的ImageSequenceClip批量生成简易视频,可加入音频。
- 每次运行程序都会将用于储存的文件夹刷新清空
- 加入了背景音乐,还有水印图片的镶嵌,因为利用moviepy的直接图片嵌入失败,也没有找到合适的解决方案,所以利用PIL先将图片拼接到每张图片上,在用moviepy合成视频,最后加上背景音乐。
- 更新!增加了多线程机制,提高生成速度
import moviepy.editor
from PIL import Image,ImageFile
import os.path , random, shutil
import glob
from pydub import AudioSegment
ImageFile.LOAD_TRUNCATED_IMAGES = True
fileDir = "图库" #源图片文件夹路径
cut_Dir = "image" #移动到新的文件夹路径\裁剪图片源
tarDir =cut_Dir+"/"
ima_url = "image/images" #用于存放裁剪后的图片
v_url = "vedio" #视频存放的文件夹
vedio_url = v_url+"/new" #最后为视频保存的文件名
logo_url = "logo/二维码图.png" #二维码的位置
music_url = "music" #音乐所处文件夹
#主要参数设置
photo_num = 25 #一个视频使用多少图片
vedio_num = 1 #制作视频的数量
# 加水印/二维码
# logo = Image.open(logo_url)
#从图片库中提取图片
def moveFile(fileDir):
pathDir = os.listdir(fileDir) #取图片的原始路径
# filenumber=len(pathDir)
# rate=0.026 #自定义抽取图片的比例,比方说100张抽10张,那就是0.1
picknumber=int(photo_num) #按照rate比例从文件夹中取一定数量图片
sample = random.sample(pathDir, picknumber) #随机选取picknumber数量的样本图片
# print (sample)
Dir = fileDir + '/'
for name in sample:
# print(name)
fileDir = Dir + name
# print(fileDir)
shutil.copy(fileDir, tarDir+name)
# print(tarDir+name)
# print(tarDir+"logo.jpg",logo)
shutil.copy(logo_url,tarDir+"logo.jpg")
return
def musicFile(fileDir):
pathDir = os.listdir(fileDir) #取音乐的原始路径
sample = random.sample(pathDir, 1)
print(fileDir+'/'+sample[0])
return fileDir+'/'+sample[0]
#把文件钟图片的分辨率进行修改
def convertjpg(jpgfile,outdir,width=1280,height=720):
img=Image.open(jpgfile)
img=img.convert('RGB')
try:
new_img=img.resize((width,height),Image.BILINEAR)
# 加水印图片
# new_img.paste(logo)
new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
except Exception as e:
print(e)
#刷新保存视频的文件夹,避免文件存在无法写入
try:
os.mkdir("vedio")
except:
shutil.rmtree("vedio")
os.mkdir("vedio")
for i in range(vedio_num): #视频制作数量
#图片文件夹的刷新
try:
os.mkdir(tarDir) #尝试创建,若存在则失败
except:
# print("文件夹已存在")
shutil.rmtree(tarDir) #删除已有文件夹,重新创建
os.mkdir(tarDir)
os.mkdir(ima_url) #创建多级文件
#图片的挑选
moveFile(fileDir)
#图片裁剪
rurl = cut_Dir +r"/*.jpg"
for jpgfile in glob.glob(rurl): #裁剪图片
convertjpg(jpgfile,ima_url) #图片写入的地址
#生成视频
try:
image_clip = ImageSequenceClip(ima_url, fps=0.5) #生成视频
except:
print("图片有错误,放弃制作")
continue
#写入视频
vurl = vedio_url+"%d" %(i)
vurl = vurl+".mp4"
# print(vurl)
audio_background = AudioFileClip(musicFile(music_url))
image_clip = image_clip.set_audio(audio_background) #加入音乐
image_clip.write_videofile(vurl) #将视频写入本地
改进了程序,增加了多线程运行,大幅提高速度
from moviepy.editor import *
import moviepy.editor
from PIL import Image,ImageFile
import os.path , random, shutil
import glob
from pydub import AudioSegment
import time
from multiprocessing.pool import ThreadPool
import psutil
ImageFile.LOAD_TRUNCATED_IMAGES = True
fileDir = "图库" #源图片文件夹路径
cut_Dir = "image" #移动到新的文件夹路径\裁剪图片源
tarDir =cut_Dir+"/"
ima_url = "image/images" #用于存放裁剪后的图片
v_url = "vedio" #视频存放的文件夹
vedio_url = v_url+"/new" #最后为视频保存的文件名
logo_url = "logo/二维码图.png" #二维码的位置
music_url = "music" #音乐所处文件夹
#主要参数设置
photo_num = 25 #一个视频使用多少图片
vedio_num = 10 #制作视频的数量
# 加水印/二维码
# logo = Image.open(logo_url)
#从图片库中提取图片
def moveFile(fileDir,writeDir):
pathDir = os.listdir(fileDir) #取图片的原始路径
# filenumber=len(pathDir)
# rate=0.026 #自定义抽取图片的比例,比方说100张抽10张,那就是0.1
picknumber=int(photo_num) #按照rate比例从文件夹中取一定数量图片
sample = random.sample(pathDir, picknumber) #随机选取picknumber数量的样本图片
# print (sample)
Dir = fileDir + '/'
for name in sample:
# print(name)
fileDir = Dir + name
# print(fileDir)
shutil.copy(fileDir, writeDir+name)
# print(tarDir+name)
# print(tarDir+"logo.jpg",logo)
shutil.copy(logo_url,writeDir+"logo.jpg")
return
def musicFile(fileDir):
pathDir = os.listdir(fileDir) #取音乐的原始路径
sample = random.sample(pathDir, 1)
print(fileDir+'/'+sample[0])
return fileDir+'/'+sample[0]
#把文件钟图片的分辨率进行修改
def convertjpg(jpgfile,outdir,width=1280,height=720):
img=Image.open(jpgfile)
img=img.convert('RGB')
try:
new_img=img.resize((width,height),Image.BILINEAR)
# 加水印图片
# new_img.paste(logo)
new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
except Exception as e:
print(e)
def make(num):
tarDir = cut_Dir+str(num)+"/"
ima_url = tarDir+"images"
try:
os.mkdir(tarDir) #尝试创建,若存在则失败
os.mkdir(ima_url) #创建多级文件
except:
# print("文件夹已存在")
shutil.rmtree(tarDir) #删除已有文件夹,重新创建
os.mkdir(tarDir)
os.mkdir(ima_url) #创建多级文件
#图片的挑选
moveFile(fileDir,tarDir)
#图片裁剪
rurl = cut_Dir +"/*.jpg"
for jpgfile in glob.glob(rurl): #裁剪图片
convertjpg(jpgfile,ima_url) #图片写入的地址
#生成视频
image_clip = ImageSequenceClip(ima_url, fps=0.5) #生成视频
#写入视频
vurl = vedio_url+"%d" %(num)
vurl = vurl+".mp4"
# print(vurl)
audio_background = AudioFileClip(musicFile(music_url))
image_clip = image_clip.set_audio(audio_background) #加入音乐
image_clip.write_videofile(vurl) #将视频写入本地
shutil.rmtree(tarDir) #删除前面用于缓存图片的文件夹
def main():
starttime =time.time()
#刷新保存视频的文件夹,避免文件存在无法写入
try:
os.mkdir("vedio")
except:
shutil.rmtree("vedio")
os.mkdir("vedio")
pool = ThreadPool(psutil.cpu_count()) #根据cpu线程数建立线程池
returnValues = pool.map(make, range(vedio_num))
endtime=time.time()
print(endtime-starttime)
main()