1 #-*- coding:utf-8 -*-
2 #coding:utf-8
3 importos, cv2, subprocess4 from cv2 importVideoWriter, VideoWriter_fourcc, imread, resize5 from PIL importImage, ImageFont, ImageDraw6
7 ffmpeg = r‘G:\ffmpeg\bin\ffmpeg.exe‘
8 code_color = (169,169,169) #颜色RGB 默认灰色 ,‘‘ 则彩色
9
10 #像素对应ascii码
11 #ascii_char = list("[email protected]%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:oa+>!:+. ")
12 #ascii_char = [‘.‘,‘,‘,‘:‘,‘;‘,‘+‘,‘*‘,‘?‘,‘%‘,‘S‘,‘#‘,‘@‘][::-1]
13 #ascii_char = list("MNHQ$OC67+>!:-. ")
14 ascii_char = list("MNHQ$OC67)oa+>!:+.")15
16 #将像素转换为ascii码
17 def get_char(r, g, b, alpha=256):18 if alpha ==0:19 return ‘‘
20 length =len(ascii_char)21 gray = int(0.2126 * r + 0.7152 * g + 0.0722 *b)22 unit = (256.0 + 1) /length23 return ascii_char[int(gray /unit)]24
25 #将txt转换为图片
26 deftxt2image(file_name):27 im = Image.open(file_name).convert(‘RGB‘)28 #gif拆分后的图像,需要转换,否则报错,由于gif分割后保存的是索引颜色
29 raw_width =im.width30 raw_height =im.height31 width = int(raw_width / 6)32 height = int(raw_height / 15)33 im =im.resize((width, height), Image.NEAREST)34
35 txt = ""
36 colors =[]37 for i inrange(height):38 for j inrange(width):39 pixel =im.getpixel((j, i))40 colors.append((pixel[0], pixel[1], pixel[2]))41 if (len(pixel) == 4):42 txt += get_char(pixel[0], pixel[1], pixel[2], pixel[3])43 else:44 txt += get_char(pixel[0], pixel[1], pixel[2])45 txt += ‘\n‘
46 colors.append((255, 255, 255))47
48 im_txt = Image.new("RGB", (raw_width, raw_height), (255, 255, 255))49 dr =ImageDraw.Draw(im_txt)50 #font = ImageFont.truetype(os.path.join("fonts","汉仪楷体简.ttf"),18)
51 font =ImageFont.load_default().font52 x = y =053 #获取字体的宽高
54 font_w, font_h = font.getsize(txt[1])55 font_h *= 1.37 #调整后更佳
56 #ImageDraw为每个ascii码进行上色
57 for i inrange(len(txt)):58 if (txt[i] == ‘\n‘):59 x +=font_h60 y = -font_w61 #self, xy, text, fill = None, font = None, anchor = None,
62 #*args, ** kwargs
63 ifcode_color:64 dr.text((y, x), txt[i], fill=code_color) #fill=colors[i]彩色
65 else:66 dr.text((y, x), txt[i], fill=colors[i]) #fill=colors[i]彩色
67 #dr.text((y, x), txt[i], font=font, fill=colors[i])
68 y +=font_w69
70 name =file_name71 #print(name + ‘ changed‘)
72 im_txt.save(name)73
74 #将视频拆分成图片
75 defvideo2txt_jpg(file_name):76 vc =cv2.VideoCapture(file_name)77 c = 1
78 ifvc.isOpened():79 r, frame =vc.read()80 if not os.path.exists(‘Cache‘):81 os.mkdir(‘Cache‘)82 os.chdir(‘Cache‘)83 else:84 r =False85 whiler:86 cv2.imwrite(str(c) + ‘.jpg‘, frame)87 txt2image(str(c) + ‘.jpg‘) #同时转换为ascii图
88 r, frame =vc.read()89 c += 1
90 os.chdir(‘..‘)91 returnvc92
93 #将图片合成视频
94 defjpg2video(outfile_name, fps):95 fourcc = VideoWriter_fourcc(*"MJPG")96 images = os.listdir(‘Cache‘)97 im = Image.open(‘Cache/‘ +images[0])98 vw =cv2.VideoWriter(outfile_name, fourcc, fps, im.size)99
100 os.chdir(‘Cache‘)101 for image inrange(len(images)):102 #Image.open(str(image)+‘.jpg‘).convert("RGB").save(str(image)+‘.jpg‘)
103 frame = cv2.imread(str(image + 1) + ‘.jpg‘)104 vw.write(frame)105 #print(str(image + 1) + ‘.jpg‘ + ‘ finished‘)
106 os.chdir(‘..‘)107 vw.release()108
109 #递归删除目录
110 defremove_dir(path):111 ifos.path.exists(path):112 ifos.path.isdir(path):113 dirs =os.listdir(path)114 for d indirs:115 if os.path.isdir(path + ‘/‘ +d):116 remove_dir(path + ‘/‘ +d)117 elif os.path.isfile(path + ‘/‘ +d):118 os.remove(path + ‘/‘ +d)119 os.rmdir(path)120 return
121 elifos.path.isfile(path):122 os.remove(path)123 return
124
125 #调用ffmpeg获取mp3音频文件
126 defvideo2mp3(file_name, outfile_name):127 cmdstr = "-i {0} -f mp3 {1} -y".format(file_name, outfile_name)128 cmd(cmdstr)129
130 #合成音频和视频文件
131 defvideo_add_mp3(file_name, mp3_file,outfile_name):132 cmdstr = "-i {0} -i {1} -strict -2 -f mp4 {2} -y".format(file_name, mp3_file, outfile_name)133 cmd(cmdstr)134
135 #视频截取
136 defvediocut(file_name, outfile_name, start, end):137 cmdstr = "-i {0} -vcodec copy -acodec copy -ss {1} -to {2} {3} -y".format(file_name,start,end,outfile_name)138 cmd(cmdstr)139
140 #执行脚本命令
141 defcmd(cmdstr):142 cmdstr = ffmpeg +cmdstr143 response = subprocess.call(cmdstr, shell=True, creationflags=0x08000000)144 if response == 1:145 print("ffmpeg脚本执行失败,请尝试手动执行:{0}".format(cmdstr))146
147 #主函数
148 def main(vedio, save=False, iscut=False, start=‘00:00:00‘, end=‘00:00:14‘):149 """
150 :param vedio: 原视频文件地址151 :param save: 是否保存临时文件 默认不保存152 :param iscut: 是否先对原视频做截取处理 默认不截取153 :param start: 视频截取开始时间点 仅当iscut=True时有效154 :param end: 视频截取结束时间点 仅当iscut=True时有效155 :return: 输出目标视频文件 vedio.split(‘.‘)[0] + ‘-code.mp4‘156 """
157 file_cut = vedio.split(‘.‘)[0] + ‘_cut.mp4‘
158 file_mp3 = vedio.split(‘.‘)[0] + ‘.mp3‘
159 file_temp_avi = vedio.split(‘.‘)[0] + ‘_temp.avi‘
160 outfile_name = vedio.split(‘.‘)[0] + ‘-code.mp4‘
161 print("开始生成...")162 ifiscut:163 print("正在截取视频...")164 vediocut(vedio, file_cut, start, end)165 vedio =file_cut166 print("正在转换代码图片...")167 vc = video2txt_jpg(vedio) #视频转图片,图片转代码图片
168 FPS = vc.get(cv2.CAP_PROP_FPS) #获取帧率
169 vc.release()170 print("正在分离音频...")171 video2mp3(vedio, file_mp3) #从原视频分离出 音频mp3
172 print("正在转换代码视频...")173 jpg2video(file_temp_avi, FPS) #代码图片转视频
174 print("正在合成目标视频...")175 video_add_mp3(file_temp_avi, file_mp3, outfile_name) #将音频合成到代码视频
176 print("正在移除临时文件...")177 if (not save): #移除临时文件
178 remove_dir("Cache")179 for file in[file_cut, file_mp3, file_temp_avi]:180 ifos.path.exists(file):181 os.remove(file)182 print("生成成功:{0}".format(outfile_name))183
184 if __name__ == ‘__main__‘:185 vedio = r"H:\Projects\test\抖音.mp4"
186 main(vedio, save=False, iscut=False, start=‘00:00:00‘, end=‘00:00:14‘)