def build_main(self, clip, max_duration: int = 0) -> StoryBuild: """Build clip :clip: Clip object (VideoFileClip, ImageClip) :max_duration: Result duration in seconds :return: StoryBuild (with new path and mentions) """ clips = [] # Background if self.bgpath: assert self.bgpath.exists(),\ f'Wrong path to background {self.bgpath}' background = ImageClip(str(self.bgpath)) clips.append(background) # Media clip clip_left = (self.width - clip.size[0]) / 2 clip_top = (self.height - clip.size[1]) / 2 if clip_top > 90: clip_top -= 50 media_clip = clip.set_position((clip_left, clip_top)) clips.append(media_clip) mention = self.mentions[0] if self.mentions else None # Text clip caption = "@%s" % mention.user.username if mention.user.username else self.caption text_clip = TextClip(caption, color="white", font="Arial", kerning=-1, fontsize=100, method="label") text_clip_left = (self.width - 600) / 2 text_clip_top = clip_top + clip.size[1] + 50 offset = (text_clip_top + text_clip.size[1]) - self.height if offset > 0: text_clip_top -= offset + 90 text_clip = text_clip.resize(width=600).set_position( (text_clip_left, text_clip_top)).fadein(3) clips.append(text_clip) # Mentions mentions = [] if mention: mention.x = 0.49892962 # approximately center mention.y = (text_clip_top + text_clip.size[1] / 2) / self.height mention.width = text_clip.size[0] / self.width mention.height = text_clip.size[1] / self.height mentions = [mention] duration = max_duration if max_duration and clip.duration and max_duration > clip.duration: duration = clip.duration destination = tempfile.mktemp('.mp4') CompositeVideoClip(clips, size=(self.width, self.height))\ .set_fps(24)\ .set_duration(duration)\ .write_videofile(destination, codec='libx264', audio=True, audio_codec='aac') return StoryBuild(mentions=mentions, path=destination)
def build_clip(self, clip, max_duration): background = ImageClip(self.bgpath) clip_left = (self.width - clip.size[0]) / 2 clip_top = (self.height - clip.size[1]) / 2 if clip_top > 90: clip_top -= 50 clip = clip.set_position((clip_left, clip_top)) caption = self.caption tag = None if self.usertags: tag = self.usertags[0] caption = "@%s" % tag["user"]["name"] text_clip = TextClip(caption, color="white", font="Arial", kerning=-1, fontsize=100, method="label") text_clip_left = (self.width - 600) / 2 text_clip_top = clip_top + clip.size[1] + 50 offset = (text_clip_top + text_clip.size[1]) - self.height if offset > 0: text_clip_top -= offset + 90 text_clip = text_clip.resize(width=600).set_position( (text_clip_left, text_clip_top)).fadein(3) usertags = [] if tag: tag['x'] = 0.49892962 # approximately center tag['y'] = (text_clip_top + text_clip.size[1] / 2) / self.height tag['width'] = text_clip.size[0] / self.width tag['height'] = text_clip.size[1] / self.height usertags = [tag] duration = max_duration if max_duration and clip.duration and max_duration > clip.duration: duration = clip.duration destination = tempfile.mktemp('.mp4') CompositeVideoClip( [background, clip, text_clip], size=(self.width, self.height )).set_fps(24).set_duration(duration).write_videofile( destination, codec='libx264', audio=True, audio_codec='aac') return {'usertags': usertags, 'filepath': destination}
def build_main(self, clip, max_duration: int = 0) -> StoryBuild: """ Build clip Parameters ---------- clip: (VideoFileClip, ImageClip) An object of either VideoFileClip or ImageClip max_duration: int, optional Duration of the clip if a video clip, default value is 0 Returns ------- StoryBuild An object of StoryBuild """ clips = [] # Background if self.bgpath: assert self.bgpath.exists( ), f"Wrong path to background {self.bgpath}" background = ImageClip(str(self.bgpath)) clips.append(background) # Media clip clip_left = (self.width - clip.size[0]) / 2 clip_top = (self.height - clip.size[1]) / 2 if clip_top > 90: clip_top -= 50 media_clip = clip.set_position((clip_left, clip_top)) clips.append(media_clip) mention = self.mentions[0] if self.mentions else None # Text clip caption = ("@%s" % mention.user.username if mention.user.username else self.caption) text_clip = TextClip( caption, color="white", font="Arial", kerning=-1, fontsize=100, method="label", ) text_clip_left = (self.width - 600) / 2 text_clip_top = clip_top + clip.size[1] + 50 offset = (text_clip_top + text_clip.size[1]) - self.height if offset > 0: text_clip_top -= offset + 90 text_clip = (text_clip.resize(width=600).set_position( (text_clip_left, text_clip_top)).fadein(3)) clips.append(text_clip) # Mentions mentions = [] if mention: mention.x = 0.49892962 # approximately center mention.y = (text_clip_top + text_clip.size[1] / 2) / self.height mention.width = text_clip.size[0] / self.width mention.height = text_clip.size[1] / self.height mentions = [mention] duration = max_duration if max_duration and clip.duration and max_duration > clip.duration: duration = clip.duration destination = tempfile.mktemp(".mp4") CompositeVideoClip(clips, size=( self.width, self.height)).set_fps(24).set_duration(duration).write_videofile( destination, codec="libx264", audio=True, audio_codec="aac") return StoryBuild(mentions=mentions, path=destination)
def build_main(self, clip, max_duration: int = 0, font: str = 'Arial', fontsize: int = 100, color: str = 'white', link: str = "") -> StoryBuild: """ Build clip Parameters ---------- clip: (VideoFileClip, ImageClip) An object of either VideoFileClip or ImageClip max_duration: int, optional Duration of the clip if a video clip, default value is 0 font: str, optional Name of font for text clip fontsize: int, optional Size of font color: str, optional Color of text Returns ------- StoryBuild An object of StoryBuild """ clips = [] stickers = [] # Background if self.bgpath: assert self.bgpath.exists( ), f"Wrong path to background {self.bgpath}" background = ImageClip(str(self.bgpath)) clips.append(background) # Media clip clip_left = (self.width - clip.size[0]) / 2 clip_top = (self.height - clip.size[1]) / 2 if clip_top > 90: clip_top -= 50 media_clip = clip.set_position((clip_left, clip_top)) clips.append(media_clip) mention = self.mentions[0] if self.mentions else None # Text clip caption = self.caption if self.mentions: mention = self.mentions[0] if getattr(mention, 'user', None): caption = f"@{mention.user.username}" if caption: text_clip = TextClip( caption, color=color, font=font, kerning=-1, fontsize=fontsize, method="label", ) text_clip_left = (self.width - 600) / 2 text_clip_top = clip_top + clip.size[1] + 50 offset = (text_clip_top + text_clip.size[1]) - self.height if offset > 0: text_clip_top -= offset + 90 text_clip = (text_clip.resize(width=600).set_position( (text_clip_left, text_clip_top)).fadein(3)) clips.append(text_clip) if link: url = urlparse(link) link_clip = TextClip( url.netloc, color="blue", bg_color="white", font=font, kerning=-1, fontsize=32, method="label", ) link_clip_left = (self.width - 400) / 2 link_clip_top = clip.size[1] / 2 link_clip = (link_clip.resize(width=400).set_position( (link_clip_left, link_clip_top)).fadein(3)) link_sticker = StorySticker( # x=160.0, y=641.0, z=0, width=400.0, height=88.0, x=round(link_clip_left / self.width, 7), # e.g. 0.49953705 y=round(link_clip_top / self.height, 7), # e.g. 0.5 z=0, width=round(link_clip.size[0] / self.width, 7), # e.g. 0.50912 height=round(link_clip.size[1] / self.height, 7), # e.g. 0.06875 rotation=0.0, # id="link_sticker_default", type="story_link", extra=dict( link_type="web", url=str(link), # e.g. "https//github.com/" tap_state_str_id="link_sticker_default", )) stickers.append(link_sticker) clips.append(link_clip) # Mentions mentions = [] if mention: mention.x = 0.49892962 # approximately center mention.y = (text_clip_top + text_clip.size[1] / 2) / self.height mention.width = text_clip.size[0] / self.width mention.height = text_clip.size[1] / self.height mentions = [mention] duration = max_duration if getattr(clip, 'duration', None): if duration > int(clip.duration) or not duration: duration = int(clip.duration) destination = tempfile.mktemp(".mp4") cvc = CompositeVideoClip(clips, size=(self.width, self.height))\ .set_fps(24)\ .set_duration(duration) cvc.write_videofile(destination, codec="libx264", audio=True, audio_codec="aac") paths = [] if duration > 15: for i in range(duration // 15 + (1 if duration % 15 else 0)): path = tempfile.mktemp(".mp4") start = i * 15 rest = duration - start end = start + (rest if rest < 15 else 15) sub = cvc.subclip(start, end) sub.write_videofile(path, codec="libx264", audio=True, audio_codec="aac") paths.append(path) return StoryBuild(mentions=mentions, path=destination, paths=paths, stickers=stickers)
def build_start_title(vid, title_end, texts, text_i): dirname = os.path.dirname(__file__) # Relative path to the folder # Images maila = "Karttu.png" logo = "logo.png" # Fonts font = "Ebrima-Bold" # font = "Fixedsys Regular" fontsize = 150 color = "#e94b3cff" stroke_color = "#1d1b1b" if float(title_end) - 4.0 > 0.0: clip = vid.subclip(float(title_end) - 4.0, title_end) else: # if start is shorter than 4 s rate = title_end / 4 clip = vid.subclip(0, title_end).speedx(rate) t = texts[text_i] t = t.replace('\\n', '\n') t = t.split(";") # separate players and event. Example: player1 vs. player2; Event 2020 if len(t) == 2: players = t[0] event = t[1] else: event = t[0] players = "" maila_img = ImageClip(os.path.join(dirname ,maila), duration = 4)\ .resize(height = int(clip.size[1] * 0.7)) logo_img = ImageClip(os.path.join(dirname ,logo), duration = 4)\ .resize(width = maila_img.size[0] + 100)\ .set_position(("center", "top")) maila_img = maila_img.margin(top = logo_img.size[1],\ left = int((logo_img.size[0] - maila_img.size[0]) / 2),\ right = int((logo_img.size[0] - maila_img.size[0]) / 2),\ opacity = 0) images = CompositeVideoClip([maila_img,logo_img]) images_rot = images.set_position("center")\ .resize(lambda t: min(0.2 + t*1.5 , 1))\ .rotate(lambda t: 500 * (tanh(t*4 + 0.5) * -5 + 5), resample = "nearest") event_txt = TextClip(event, stroke_color = stroke_color,\ stroke_width = 4, color=color,\ font= font,\ kerning = 5,\ fontsize=fontsize)\ .set_duration(4) event_txt = event_txt.resize(width = clip.size[0] / 2 - 300) event_txt = event_txt.set_pos(lambda t:(min(clip.size[0]/2 + 100,-800 + t * 1500),clip.size[1]/2)) player_txt = TextClip(players,\ stroke_color = stroke_color,\ stroke_width = 4, color=color,\ font=font,\ kerning = 5,\ fontsize=fontsize)\ .set_duration(4) player_txt = player_txt.set_pos(lambda t:(max(clip.size[0]/2 - player_txt.size[0]- 100, clip.size[0] + 600 + t * -1800),clip.size[1]/2 - player_txt.size[1]/2)) mask_left = np.zeros((clip.size[1],clip.size[0], 4)) mask_right = B = np.copy(mask_left) mask_left = cv2.rectangle(mask_left, (0, 0), (int(clip.size[0]/2), clip.size[1]), (255,255,255,255), -1) mask_right = cv2.rectangle(mask_right, (int(clip.size[0]/2), 0), (clip.size[0], clip.size[1]), (255,255,255,255), -1) mask_left = ImageClip(mask_left, duration=2, ismask=True) mask_right = ImageClip(mask_right, duration=2, ismask=True) # cv2.imwrite("kala.png",mask_right) comp_clip = CompositeVideoClip([clip, event_txt, clip.set_mask(mask_left)]) comp_clip = CompositeVideoClip([comp_clip, player_txt, comp_clip.set_mask(mask_right), images_rot]) return comp_clip, text_i + 1