from fastapi import FastAPI import openshot from os import listdir from os.path import isfile, isdir, join import threading from gtts import gTTS import os import urllib from typing import List import requests from pydantic import BaseModel from bs4 import BeautifulSoup import time from PIL import Image,ImageDraw,ImageFont import pyttsx3 import rpyc import random import time import math import hashlib import re import urllib.request #service nginx restart # app = FastAPI() dir_sound = 'mp3_track/' dir_photo = 'photo/' dir_text = 'text_file/' dir_video = 'video_material/' dir_title = 'title/' dir_subtitle = 'subtitle/' dir_anchor = 'anchor_raw/' class request(BaseModel): name: str text_content: str image_urls: List[str] class request2(BaseModel): name: str text_content: List[str] image_urls: List[str] class anchor_request(BaseModel): name: str text_content: str image_urls: List[str] @app.get("/") async def root(): return {"message": "Hello, this is index"} @app.post("/make_video_req") async def make_video_req(req:request): x = threading.Thread(target=make_video, args=(req.name, req.text_content, req.image_urls)) x.start() return {"msg":"製作影片需要時間,請您耐心等候"} @app.post("/make_anchor_video") async def make_anchor_video(req:request): x = threading.Thread(target=anchor_video, args=(req.name, req.text_content, req.image_urls)) x.start() return {"msg":"製作影片需要時間,請您耐心等候 稍後可以在www.choozmo.com:8168/"+req.name+".mp4 中觀看"} @app.post("/make_anchor_video_v2") async def make_anchor_video_v2(req:request2): x = threading.Thread(target=anchor_video_v2, args=(req.name, req.text_content, req.image_urls)) x.start() return {"msg":"製作影片需要時間,請您耐心等候 稍後可以在www.choozmo.com:8168/"+req.name+".mp4 中觀看"} def notify_group(msg): headers = { "Authorization": "Bearer " + "WekCRfnAirSiSxALiD6gcm0B56EejsoK89zFbIaiZQD", "Content-Type": "application/x-www-form-urlencoded" } params = {"message": msg} r = requests.post("https://notify-api.line.me/api/notify",headers=headers, params=params) #print(r) def make_video(name, text_content, image_urls): #save image try: os.mkdir(dir_photo+name) except FileExistsError: print("Directory " , dir_photo+name , " already exists") img_num = 1 for imgu in image_urls: im = Image.open(requests.get(imgu, stream=True).raw) im.save(dir_photo+name+"/"+str(img_num)+".jpg") img_num+=1 #save text text_file = open(dir_text+name+".txt", "w") text_file.write(text_content) text_file.close() print("text file made") #make mp3 language = 'zh-tw' output = gTTS(text=text_content, lang=language, slow=False) output.save(dir_sound+name+".mp3") print("mp3 file made") #make vido t = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO) t.Open() sound = openshot.FFmpegReader(dir_sound+name+".mp3") sound.Open() sound_track = openshot.Clip(sound) t.AddClip(sound_track) duration = sound.info.duration w = openshot.FFmpegWriter("../html/"+name+".mp4") w.SetAudioOptions(True, "libmp3lame", 44100, 2, openshot.LAYOUT_STEREO, 3000000) w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720, openshot.Fraction(1, 1), False, False, 3000000) w.Open() p_num = len(listdir(dir_photo+name)) clip_list = [None]*p_num img_list = [None]*p_num single_duration = int(duration/p_num) frame_cnt = 0 for p in listdir(dir_photo+name): img_list[frame_cnt] = openshot.QtImageReader(dir_photo+name+"/"+p) clip_list[frame_cnt] = openshot.Clip(img_list[frame_cnt]) clip_list[frame_cnt].has_audio=openshot.Keyframe(0) clip_list[frame_cnt].Layer(1) clip_list[frame_cnt].Position(frame_cnt*single_duration) # start from time 0 sec t.AddClip(clip_list[frame_cnt]) frame_cnt+=1 t_op = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO) t_op.Open() op_vid = openshot.FFmpegReader(dir_video+"LOGO_OP.mp4") op_vid.Open() op_clip = openshot.Clip(op_vid) t_op.AddClip(op_clip) duration_op = op_vid.info.duration for n in range(int(t_op.info.fps)*int(duration_op)): f=t_op.GetFrame(n) w.WriteFrame(f) for n in range(int(t.info.fps)*int(duration)): f=t.GetFrame(n) w.WriteFrame(f) t_ed = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO) t_ed.Open() ed_vid = openshot.FFmpegReader(dir_video+"LOGO_ED.avi") ed_vid.Open() ed_clip = openshot.Clip(ed_vid) t_ed.AddClip(ed_clip) duration_ed = ed_vid.info.duration for n in range(int(t_ed.info.fps)*int(duration_ed)): f=t_ed.GetFrame(n) w.WriteFrame(f) t_ed.Close() t_op.Close() t.Close() w.Close() sound.Close() notify_group(name+"的影片已經產生完成囉! www.choozmo.com:8168/"+name+".mp4") def cKey(r,g,b,fuzz): col=openshot.Color() col.red=openshot.Keyframe(r) col.green=openshot.Keyframe(g) col.blue=openshot.Keyframe(b) return openshot.ChromaKey(col, openshot.Keyframe(fuzz)) def video_photo_clip(vid=None,layer=None, position=None, end=None ,scale_x=1,scale_y=1,location_x=0,location_y=0,ck=None,audio=True): clip = openshot.Clip(vid) clip.Layer(layer) clip.Position(position) clip.End(end) clip.scale_x=openshot.Keyframe(scale_x) clip.scale_y=openshot.Keyframe(scale_y) clip.location_x=openshot.Keyframe(location_x) clip.location_y=openshot.Keyframe(location_y) if ck!=None: clip.AddEffect(ck) if audio==True: clip.has_audio=openshot.Keyframe(1) else: clip.has_audio=openshot.Keyframe(0) return clip def myunichchar(unicode_char): mb_string = unicode_char.encode('big5') try: unicode_char = unichr(ord(mb_string[0]) << 8 | ord(mb_string[1])) except NameError: unicode_char = chr(mb_string[0] << 8 | mb_string[1]) return unicode_char def file_prepare(name, name_hash,text_content,image_urls): #save image try: os.mkdir(dir_photo+name_hash) except FileExistsError: print("Directory " , dir_photo+name_hash , " already exists") img_num = 1 for imgu in image_urls: im = Image.open(requests.get(imgu, stream=True).raw) im.save(dir_photo+name_hash+"/"+str(img_num)+".jpg") img_num+=1 #save text text_file = open(dir_text+name_hash+".txt", "w") text_file.write(text_content) text_file.close() print("text file made") #make mp3 language = 'zh-tw' output = gTTS(text=text_content, lang=language, slow=False) output.save(dir_sound+name_hash+".mp3") print("mp3 file made") #make title as image txt2image(name, dir_title+name_hash+".png") def get_url_type(url): req = urllib.request.Request(url, method='HEAD', headers={'User-Agent': 'Mozilla/5.0'}) r = urllib.request.urlopen(req) contentType = r.getheader('Content-Type') return contentType def downloadfile(name,url): name=name+".mp4" def make_dir(name_hash): #save image try: os.mkdir(dir_photo+name_hash) except FileExistsError: print("~~~~~~Warning~~~~~~~~~Directory " , dir_photo+name_hash , " already exists") try: os.mkdir(dir_text+name_hash) except FileExistsError: print("~~~~~~Warning~~~~~~~~~Directory " , dir_text+name_hash , " already exists") try: os.mkdir(dir_sound+name_hash) except FileExistsError: print("~~~~~~Warning~~~~~~~~~Directory " , dir_sound+name_hash , " already exists") try: os.mkdir(dir_video+name_hash) except FileExistsError: print("~~~~~~Warning~~~~~~~~~Directory " , dir_video+name_hash , " already exists") try: os.mkdir(dir_anchor+name_hash) except FileExistsError: print("~~~~~~Warning~~~~~~~~~Directory " , dir_anchor+name_hash , " already exists") try: os.mkdir(dir_subtitle+name_hash) except FileExistsError: print("~~~~~~Warning~~~~~~~~~Directory " , dir_subtitle+name_hash , " already exists") def file_prepare_v2(name, name_hash,text_content,image_urls): make_dir(name_hash) img_num = 1 for imgu in image_urls: if get_url_type(imgu) =='video/mp4': r=requests.get(imgu) f=open(dir_photo+name_hash+"/"+str(img_num)+".mp4",'wb') for chunk in r.iter_content(chunk_size=255): if chunk: f.write(chunk) f.close() else: im = Image.open(requests.get(imgu, stream=True).raw) im.save(dir_photo+name_hash+"/"+str(img_num)+".jpg") img_num+=1 #save text txt_idx=0 for txt in text_content: text_file = open(dir_text+name_hash+"/"+str(txt_idx)+".txt", "w") text_file.write(txt) text_file.close() txt_idx+=1 print("text file made") #make mp3 language = 'zh-tw' txt_idx = 0 for txt in text_content: output = gTTS(text=txt, lang=language, slow=False) output.save(dir_sound+name_hash+"/"+str(txt_idx)+".mp3") txt_idx+=1 print("mp3 file made") #make title as image txt2image_title(name, dir_title+name_hash+".png") def txt2image(content, save_target): unicode_text = trim_punctuation(content) font = ImageFont.truetype(font="msjh.ttf", size=30) text_width, text_height = font.getsize(unicode_text) canvas = Image.new('RGBA', (700, 500), (255, 0, 0, 0) ) draw = ImageDraw.Draw(canvas) text= unicode_text draw.text((5,5), text, (255, 255, 0), font) canvas.save(save_target, "PNG") def txt2image_title(content, save_target): unicode_text =content font = ImageFont.truetype("font.ttf", 23,encoding='big5') text_width, text_height = font.getsize(unicode_text) canvas = Image.new('RGBA', (500, 500), (255, 0, 0, 0) ) draw = ImageDraw.Draw(canvas) text='' for c in unicode_text: if len(re.findall(r'[\u4e00-\u9fff]+', c))>0: text+=myunichchar(c) else: text+=c draw.text((5,5), text, (17, 41, 167), font) canvas.save(save_target, "PNG") def call_achor_video_v2(fileName): conn = rpyc.classic.connect("192.168.1.105",18812) ros = conn.modules.os rsys = conn.modules.sys fr=open(dir_sound+fileName+".mp3",'rb')# voice #warning!!! file my be replaced by other process fw=conn.builtins.open('/tmp/output.mp3','wb') while True: b=fr.read(1024) if b: fw.write(b) else: break fr.close() fw.close() val=random.randint(1000000,9999999) ros.chdir('/home/jared/to_video') ros.system('./p6.sh '+str(val)+' &') while True: print('waiting...') if ros.path.exists('/tmp/results/'+str(val)): break time.sleep(5) print('waiting...') fr=conn.builtins.open('/tmp/results/'+str(val)+'.mp4','rb') fw=open(dir_anchor+fileName+".mp4",'wb')#peggy1_1 while True: b=fr.read(1024) if b: fw.write(b) else: break fr.close() fw.close() def call_achor_video(name): conn = rpyc.classic.connect("192.168.1.105",18812) ros = conn.modules.os rsys = conn.modules.sys fr=open(dir_sound+name+".mp3",'rb')# voice #warning!!! file my be replaced by other process fw=conn.builtins.open('/tmp/output.mp3','wb') while True: b=fr.read(1024) if b: fw.write(b) else: break fr.close() fw.close() val=random.randint(1000000,9999999) ros.chdir('/home/jared/to_video') ros.system('./p6.sh '+str(val)+' &') while True: print('waiting...') if ros.path.exists('/tmp/results/'+str(val)): break time.sleep(15) print('waiting...') fr=conn.builtins.open('/tmp/results/'+str(val)+'.mp4','rb') fw=open(dir_anchor+name+'.mp4','wb')#peggy1_1 while True: b=fr.read(1024) if b: fw.write(b) else: break fr.close() fw.close() print('called............................................') def trim_punctuation(s): pat_block = u'[^\u4e00-\u9fff0-9a-zA-Z]+'; pattern = u'([0-9]+{0}[0-9]+)|{0}'.format(pat_block) res = re.sub(pattern, lambda x: x.group(1) if x.group(1) else u"" ,s) return res def splitter(s): for sent in re.findall(u'[^!?,。\.\!\?]+[!?。\.\!\?]?', s, flags=re.U): yield sent def split_by_pun(s): res = list(splitter(s)) return res def generate_subtitle_image(name_hash,text_content): ''' sub_len = 10 img_list = [None]*len(text_content) for idx in range(len(text_content)): img_list[idx] = [] for step in range(math.ceil(len(text_content[idx])/sub_len)): sv_path = dir_subtitle + name_hash +'/'+str(idx)+ str(step) +'.png' sub = text_content[idx][step*sub_len:step*sub_len+sub_len] txt2image(sub, sv_path) img_list[idx] += [{"count":len(sub),"path":sv_path}] print(sub+':'+sv_path) ''' img_list = [None]*len(text_content) for idx in range(len(text_content)): img_list[idx]=[] senList = split_by_pun(text_content[idx]) for inner_idx in range(len(senList)): sv_path = dir_subtitle + name_hash +'/'+str(idx)+ str(inner_idx) +'.png' sub = senList[inner_idx] txt2image(sub,sv_path) img_list[idx]+=[{"count":len(sub),"path":sv_path}] return img_list def anchor_video(name,text_content, image_urls): m = hashlib.md5() m.update(name.encode("utf-8")) name_hash = m.hexdigest() file_prepare(name, name_hash, text_content,image_urls) call_achor_video(name_hash) ck=cKey(0,254,0,150) ck_anchor=cKey(0,255,1,320) duration = 0 current_time = 0 current_time_photo = 0 #average layer level is 3 t = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO) t.Open() bg_head = openshot.FFmpegReader(dir_video+"bg_head.avi") bg_head.Open() bg_head_clip = video_photo_clip(vid=bg_head,layer=2,position=current_time,end=bg_head.info.duration,ck=ck) t.AddClip(bg_head_clip) LOGO_OP = openshot.FFmpegReader(dir_video+"LOGO_OP.mp4") LOGO_OP.Open() # Open the reader LOGO_OP_clip = video_photo_clip(vid=LOGO_OP,layer=4,position=current_time,end=bg_head.info.duration ,location_y=-0.03,scale_x=0.8,scale_y=0.71) t.AddClip(LOGO_OP_clip) duration+=bg_head.info.duration current_time += bg_head.info.duration current_time_photo += bg_head.info.duration sound = openshot.FFmpegReader(dir_sound+name_hash+".mp3") sound.Open() sound_clip = openshot.Clip(sound) sound_clip.Position(current_time) t.AddClip(sound_clip) duration += sound.info.duration bg = openshot.FFmpegReader(dir_video+"bg.mp4") bg.Open() bg_times = math.floor(sound.info.duration/bg.info.duration) left_time = sound.info.duration % bg.info.duration bg_clip_list = [None] * bg_times bg_list = [None] * bg_times bg.Close() for idx in range(bg_times): bg_list[idx] = openshot.FFmpegReader(dir_video+"bg.mp4") bg_list[idx].Open() bg_clip_list[idx] = video_photo_clip(bg_list[idx],layer=2,position=current_time ,end=bg_list[idx].info.duration,ck=ck) t.AddClip(bg_clip_list[idx]) current_time += bg_list[idx].info.duration bg_list[idx].Close() bg_left = openshot.FFmpegReader(dir_video+"bg.mp4") bg_left.Open() bg_left_clip = video_photo_clip(bg_left,layer=2,position=current_time,end=left_time,ck=ck) t.AddClip(bg_left_clip) current_time += left_time bg_left.Close() p_num = len(listdir(dir_photo+name_hash)) photo_clip_list = [None]*p_num img_list = [None]*p_num photo_idx = 0 photo_duration = sound.info.duration/p_num for p in listdir(dir_photo+name_hash): img_list[photo_idx] = openshot.QtImageReader(dir_photo+name_hash+'/'+p) photo_clip_list[photo_idx] = video_photo_clip(vid=img_list[photo_idx],layer=3 ,scale_x=0.81,scale_y=0.68,location_y=-0.03,position=current_time_photo,end=photo_duration ,audio=False) t.AddClip(photo_clip_list[photo_idx]) current_time_photo+=photo_duration photo_idx+=1 current_time_anchor = bg_head.info.duration anchor = openshot.FFmpegReader(dir_anchor+name_hash+".mp4") anchor.Open() anchor_times = math.floor(sound.info.duration/anchor.info.duration) left_time = sound.info.duration % anchor.info.duration anchor_clip_list = [None] * anchor_times anchor_list = [None] * anchor_times anchor.Close() for idx in range(anchor_times): anchor_list[idx] = openshot.FFmpegReader(dir_anchor+name_hash+".mp4") anchor_list[idx].Open() anchor_clip_list[idx] = video_photo_clip(vid=anchor_list[idx],layer=4,scale_x=0.65,scale_y=0.65, location_x=0.35,location_y=0.25,position=current_time_anchor, end=anchor_list[idx].info.duration, ck=ck_anchor,audio=False) t.AddClip(anchor_clip_list[idx]) current_time_anchor += anchor_list[idx].info.duration anchor_list[idx].Close() anchor = openshot.FFmpegReader(dir_anchor+"peggy1_1.mp4") anchor.Open() anchor_left_clip = video_photo_clip(vid=anchor,layer=4,scale_x=0.65,scale_y=0.65,location_x=0.35,location_y=0.25 , position=current_time_anchor,end=left_time,ck=ck_anchor) t.AddClip(anchor_left_clip) anchor.Close() title = openshot.QtImageReader(dir_title+name_hash+".png") title.Open() # Open the reader title_clip = video_photo_clip(vid=title, layer=4, location_y=0.9,position=0,end=duration) t.AddClip(title_clip) ####start building w = openshot.FFmpegWriter("../html/"+name_hash+".mp4") w.SetAudioOptions(True, "libmp3lame", 44100, 2, openshot.LAYOUT_STEREO, 3000000) w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720, openshot.Fraction(1, 1), False, False, 3000000) w.Open() #may change duration into t.info.duration for n in range(int(t.info.fps)*int(duration)): f=t.GetFrame(n) w.WriteFrame(f) t.Close() w.Close() sound.Close() print("It's fine") notify_group(name+"的影片已經產生完成囉! www.choozmo.com:8168/"+name_hash+".mp4") def anchor_video_v2(name,text_content, image_urls): m = hashlib.md5() m.update(name.encode("utf-8")) name_hash = m.hexdigest() print('sub image made') file_prepare_v2(name, name_hash, text_content,image_urls) sub_list=generate_subtitle_image(name_hash,text_content) for fname in range(len(text_content)): call_achor_video_v2(name_hash+"/"+str(fname)) print('step finish') print('called............................................') ck=cKey(0,254,0,150) ck_anchor=cKey(0,255,1,320) duration = 0 #average layer level is 3 t = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO) t.Open() main_timer = 0 LOGO_OP = openshot.FFmpegReader(dir_video+"LOGO_OP.mp4") LOGO_OP.Open() # Open the reader LOGO_OP_clip = video_photo_clip(vid=LOGO_OP,layer=4,position=0,end=LOGO_OP.info.duration ,location_y=-0.03,scale_x=0.8,scale_y=0.71) t.AddClip(LOGO_OP_clip) bg_head = openshot.FFmpegReader(dir_video+"bg_head.avi") bg_head.Open() bg_head_clip = video_photo_clip(vid=bg_head,layer=2,position=0,end=LOGO_OP.info.duration,ck=ck) t.AddClip(bg_head_clip) main_timer += LOGO_OP.info.duration head_duration = LOGO_OP.info.duration bg_head.Close() LOGO_OP.Close() clip_duration=0 photo_clip_list = [None]*len(text_content) img_list = [None]*len(text_content) anchor_clip_list = [None] * len(text_content) anchor_list = [None] * len(text_content) audio_clip_list = [None] * len(text_content) audio_list = [None] * len(text_content) sub_clip_list = [None] * len(text_content) sub_img_list = [None] * len(text_content) idx = 0 for p in listdir(dir_photo+name_hash): anchor_list[idx] = openshot.FFmpegReader(dir_anchor+name_hash+"/"+str(idx)+".mp4") clip_duration = anchor_list[idx].info.duration-0.3 anchor_list[idx].Open() anchor_clip_list[idx] = video_photo_clip(vid=anchor_list[idx],layer=4,scale_x=0.65,scale_y=0.65, location_x=0.35,location_y=0.25,position=main_timer, end=clip_duration,ck=ck_anchor,audio=False) t.AddClip(anchor_clip_list[idx]) img_list[idx] = openshot.FFmpegReader(dir_photo+name_hash+'/'+p) img_list[idx].Open() photo_clip_list[idx] = video_photo_clip(vid=img_list[idx],layer=3 ,scale_x=0.81,scale_y=0.68,location_y=-0.03,position=main_timer,end=clip_duration,audio=False) t.AddClip(photo_clip_list[idx]) img_list[idx].Close() audio_list[idx] = openshot.FFmpegReader(dir_sound+name_hash+"/"+str(idx)+".mp3") audio_list[idx].Open() audio_clip_list[idx] = openshot.Clip(audio_list[idx]) audio_clip_list[idx].Position(main_timer) audio_clip_list[idx].End(clip_duration) t.AddClip(audio_clip_list[idx]) img_list[idx].Close() anchor_list[idx].Close() audio_list[idx].Close() sub_img_list[idx] = [None] * len(sub_list[idx]) sub_clip_list[idx] = [None] * len(sub_list[idx]) sub_timer = 0 for sub_idx in range(len(sub_list[idx])): sub_img_list[idx][sub_idx] = openshot.QtImageReader(sub_list[idx][sub_idx]['path']) sub_img_list[idx][sub_idx].Open() sub_duration = 0.275*sub_list[idx][sub_idx]['count'] sub_clip_list[idx][sub_idx] = video_photo_clip(vid=sub_img_list[idx][sub_idx], layer=6,location_x=-0.05, location_y=0.85,position=main_timer+sub_timer,end=sub_duration) t.AddClip(sub_clip_list[idx][sub_idx]) sub_img_list[idx][sub_idx].Close() sub_timer += sub_duration print(sub_list[idx][sub_idx]['path']) main_timer += clip_duration idx+=1 LOGO_ED = openshot.FFmpegReader(dir_video+"LOGO_ED.avi") LOGO_ED.Open() LOGO_ED_clip = video_photo_clip(vid=LOGO_ED,layer=4,position=main_timer,end=LOGO_ED.info.duration ,location_y=-0.03,scale_x=0.8,scale_y=0.71) t.AddClip(LOGO_ED_clip) ED_duration = LOGO_ED.info.duration LOGO_ED.Close() bg = openshot.FFmpegReader(dir_video+"bg.mp4") bg.Open() bg_times = math.floor(main_timer+ED_duration/bg.info.duration) left_time = (main_timer+ED_duration) % bg.info.duration bg_clip_list = [None] * bg_times bg_list = [None] * bg_times bg.Close() bg_timer = head_duration for idx in range(bg_times): bg_list[idx] = openshot.FFmpegReader(dir_video+"bg.mp4") bg_list[idx].Open() bg_clip_list[idx] = video_photo_clip(bg_list[idx],layer=2,position=bg_timer ,end=bg_list[idx].info.duration,ck=ck) t.AddClip(bg_clip_list[idx]) bg_timer += bg_list[idx].info.duration bg_list[idx].Close() bg_left = openshot.FFmpegReader(dir_video+"bg.mp4") bg_left.Open() bg_left_clip = video_photo_clip(bg_left,layer=2,position=bg_timer,end=left_time,ck=ck) t.AddClip(bg_left_clip) bg_left.Close() title = openshot.QtImageReader(dir_title+name_hash+".png") title.Open() # Open the reader title_clip = video_photo_clip(vid=title, layer=4,location_x=-0.05, location_y=0.805,position=0,end=head_duration+main_timer) t.AddClip(title_clip) ####start building w = openshot.FFmpegWriter("../html/"+name_hash+".mp4") w.SetAudioOptions(True, "libmp3lame", 44100, 2, openshot.LAYOUT_STEREO, 3000000) w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720, openshot.Fraction(1, 1), False, False, 3000000) w.Open() #may change duration into t.info.duration for n in range(int(t.info.fps)*int(head_duration+main_timer+ED_duration)): f=t.GetFrame(n) w.WriteFrame(f) t.Close() w.Close() print("Raw Video done") print("video at : www.choozmo.com:8168/"+name_hash+".mp4") #line notifs #notify_group(name+"的影片已經產生完成囉! www.choozmo.com:8168/"+name_hash+".mp4")