- Take videos from back-facing-camera and put it in channel 2. Add audio but keep it mute.
- Take videos from front-facing-camera in to channel 1 of blender's sequence editor. Make sure that the two channels have videos of same time duration.
import bpy
from pathlib import Path
from datetime import datetime
import math
class BlenderVideoEditor:
def __init__(self):
'''initialize start_frame and duration of video-synced-audio'''
self.vsa="/media/amit/4CFC-8D04/DCIM/1"
self.start_n_dur=list()
self.mask_images = list()
def get_video_file_names(self, dir="/media/amit/4CFC-8D04/DCIM/1"):
p = Path(dir)
return [x.absolute() for x in sorted(p.iterdir()) if not x.is_dir()]
def add_movie_clips_from(self, dir="/media/amit/4CFC-8D04/DCIM/2", start_frame=1, channel=2):
frame_s = start_frame
for i, x in enumerate(self.get_video_file_names(dir=dir)):
clip_v = bpy.context.scene.sequence_editor.sequences.new_movie(name=str(i),filepath=str(x),channel=channel, frame_start = frame_s)
clip_a = bpy.context.scene.sequence_editor.sequences.new_sound(name=str(i),filepath=str(x),channel=channel+1, frame_start = frame_s)
dur = max([clip_v.frame_duration, clip_a.frame_duration])
self.start_n_dur.append((frame_s, dur))
frame_s = frame_s + dur
def add_dependent_movie_clip(self, dir="/media/amit/4CFC-8D04/DCIM/1", start_frame=1, channel=1):
assert len(self.start_n_dur) > 0
try:
for i, x in enumerate(self.get_video_file_names(dir=dir)):
clip_v = bpy.context.scene.sequence_editor.sequences.new_movie(name=str(i), filepath=str(x), channel=channel, frame_start=self.start_n_dur[i][0])
clip_v.frame_final_duration = self.start_n_dur[i][1]
except Exception as e:
print(e)
def transform_overlay_video(self, channel=3):
'''Ensure that the overlay video is positioned at near top right corner'''
for strip in bpy.data.scenes["Scene"].sequence_editor.sequences_all:
if strip.channel == channel:
assert strip.type == "MOVIE"
strip.transform.offset_x = 440
strip.transform.offset_y = 260
strip.transform.scale_x = 0.8
strip.transform.scale_y = 0.8
def mute_sequence(movieSequence=None, mute=True):
'''Mute a supplied movie sequence'''
if None != movieSequence:
movieSequence.mute = mute
def create_mask(self, file="", for_moviesequence=None):
# name for a new image that would be used as a mask
time_string = datetime.now().strftime("%f")
mask_image = None
if len(self.mask_images) == 0:
mask_image = bpy.data.scenes["Scene"].sequence_editor.sequences.new_image(name=time_string, filepath=file, channel=4, frame_start=1)
self.mask_images.append(mask_image)
if None != for_moviesequence:
mask_image.frame_final_duration = for_moviesequence.frame_duration
else:
mask_image = self.mask_images[-1]
for_moviesequence.modifiers.new(name="circle", type="MASK")
if None != mask_image:
for_moviesequence.modifiers["circle"].input_mask_strip = mask_image
def rotate_moviesequences_by_180(self):
for seq in bpy.data.scenes["Scene"].sequence_editor.sequences:
if 'MOVIE' == seq.type:
seq.transform.rotation = math.pi
def render(self):
bpy.context.scene.render.resolution_percentage = 100
bpy.context.scene.render.use_file_extension = True
bpy.context.scene.render.image_settings.file_format = 'FFMPEG'
bpy.context.scene.render.ffmpeg.format = 'MPEG4'
bpy.context.scene.render.fps = 24
bpy.context.scene.render.use_overwrite = True
bpy.context.scene.render.filepath = '/home/amit/Downloads/final_timelapse.mp4'
bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end = 239326
step = 14
for frame in range(bpy.context.scene.frame_start, bpy.context.scene.frame_end + 1, step):
bpy.context.scene.frame_set(frame)
bpy.ops.render.render(write_still=False)
def process(self):
self.add_movie_clips_from()
self.add_dependent_movie_clip()
self.transform_overlay_video(channel=2)
mask_image_file = "/home/amit/Documents/pendrive/Career-Template/7-podcasts-blender/3-dashcam-template/masks/0.png"
for seq in bpy.data.scenes["Scene"].sequence_editor.sequences:
if 'MOVIE' == seq.type and 2 == seq.channel:
self.create_mask(file=mask_image_file, for_moviesequence=seq)
for seq in bpy.data.scenes["Scene"].sequence_editor.sequences:
if 3==seq.channel:
seq.mute = True
#self.rotate_moviesequences_by_180()
#self.render()
if __name__ == '__main__':
bve = BlenderVideoEditor()
bve.process()
This one is for adding english text based subtitles anywhere in the timeline of video sequence editor:
import bpy
from pathlib import Path
from datetime import datetime
import math
class BlenderVideoEditor:
def __init__(self):
'''initialize start_frame and duration of video-synced-audio'''
self.vsa="/media/amit/4CFC-8D04/DCIM/1"
self.start_n_dur=list()
self.mask_images = list()
def get_video_file_names(self, dir="/media/amit/4CFC-8D04/DCIM/1"):
p = Path(dir)
return [x.absolute() for x in sorted(p.iterdir()) if not x.is_dir()]
def add_movie_clips_from(self, dir="/media/amit/4CFC-8D04/DCIM/2", start_frame=1, channel=2):
frame_s = start_frame
for i, x in enumerate(self.get_video_file_names(dir=dir)):
clip_v = bpy.context.scene.sequence_editor.sequences.new_movie(name=str(i),filepath=str(x),channel=channel, frame_start = frame_s)
clip_a = bpy.context.scene.sequence_editor.sequences.new_sound(name=str(i),filepath=str(x),channel=channel+1, frame_start = frame_s)
dur = max([clip_v.frame_duration, clip_a.frame_duration])
self.start_n_dur.append((frame_s, dur))
frame_s = frame_s + dur
def add_dependent_movie_clip(self, dir="/media/amit/4CFC-8D04/DCIM/1", start_frame=1, channel=1):
assert len(self.start_n_dur) > 0
try:
for i, x in enumerate(self.get_video_file_names(dir=dir)):
clip_v = bpy.context.scene.sequence_editor.sequences.new_movie(name=str(i), filepath=str(x), channel=channel, frame_start=self.start_n_dur[i][0])
clip_v.frame_final_duration = self.start_n_dur[i][1]
except Exception as e:
print(e)
def transform_overlay_video(self, channel=3):
'''Ensure that the overlay video is positioned at near top right corner'''
for strip in bpy.data.scenes["Scene"].sequence_editor.sequences_all:
if strip.channel == channel:
assert strip.type == "MOVIE"
strip.transform.offset_x = 440
strip.transform.offset_y = 260
strip.transform.scale_x = 0.8
strip.transform.scale_y = 0.8
def mute_sequence(movieSequence=None, mute=True):
'''Mute a supplied movie sequence'''
if None != movieSequence:
movieSequence.mute = mute
def create_mask(self, file="", for_moviesequence=None):
# name for a new image that would be used as a mask
time_string = datetime.now().strftime("%f")
mask_image = None
if len(self.mask_images) == 0:
mask_image = bpy.data.scenes["Scene"].sequence_editor.sequences.new_image(name=time_string, filepath=file, channel=4, frame_start=1)
self.mask_images.append(mask_image)
if None != for_moviesequence:
mask_image.frame_final_duration = for_moviesequence.frame_duration
else:
mask_image = self.mask_images[-1]
for_moviesequence.modifiers.new(name="circle", type="MASK")
if None != mask_image:
for_moviesequence.modifiers["circle"].input_mask_strip = mask_image
def rotate_moviesequences_by_180(self):
for seq in bpy.data.scenes["Scene"].sequence_editor.sequences:
if 'MOVIE' == seq.type:
seq.transform.rotation = math.pi
def render(self):
bpy.context.scene.render.resolution_percentage = 100
bpy.context.scene.render.use_file_extension = True
bpy.context.scene.render.image_settings.file_format = 'FFMPEG'
bpy.context.scene.render.ffmpeg.format = 'MPEG4'
bpy.context.scene.render.fps = 24
bpy.context.scene.render.use_overwrite = True
bpy.context.scene.render.filepath = '/home/amit/Downloads/final_timelapse.mp4'
bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end = 239326
step = 14
for frame in range(bpy.context.scene.frame_start, bpy.context.scene.frame_end + 1, step):
bpy.context.scene.frame_set(frame)
bpy.ops.render.render(write_still=False)
def add_mask_to_all_in_channel(self, channel=2, mask_file="/home/amit/Documents/pendrive/Career-Template/7-podcasts-blender/3-dashcam-template/masks/0.png"):
mask_image_file = mask_file
for seq in bpy.data.scenes["Scene"].sequence_editor.sequences:
if 'MOVIE' == seq.type and channel == seq.channel:
self.create_mask(file=mask_image_file, for_moviesequence=seq)
def mute_all_in_channel(self, channel=3):
for seq in bpy.data.scenes["Scene"].sequence_editor.sequences:
if channel==seq.channel:
seq.mute = True
def add_text_strip(self):
'''Add text strip to the video sequence'''
path="///home/amit/Documents/pendrive/Career-Template/7-podcasts-blender/2-personal-youtube-channel/Diplomatic-Dispatch-Series-Sansad-Tv/LabelTrack.txt"
p = Path(path)
lines = list()
with open(p, "r", encoding='utf-8-sig') as f:
lines = f.readlines()
ts = None
for l in lines:
la = l.split("\t")
fs = (int(float(la[0].strip())) + 1) * 15
fe = ((int(float(la[1].strip())) + 1) * 15 ) + 3
ts = context.scene.sequence_editor.sequences.new_effect(name="subtitle", type="TEXT", channel=6, frame_start = fs, frame_end = fe)
ts = context.scene.sequence_editor.sequences.new_effect(name="subtitle", type="TEXT", channel=6, frame_start = fs, frame_end = fe)
ts = context.scene.sequence_editor.sequences.new_effect(name="subtitle", type="TEXT", channel=6, frame_start = fs, frame_end = fe)
ts.text = l.split("\t")[2].strip()
ts.transform.offset_y=-444
ts.font_size = 42
def add_banner_at(self, font_size=42 ,start_f=1, x=0, y=0, w=1, h=0.1, text="", dur=64826, channel=5, banner_color=(0, 0.5, 0.5), text_color=(1, 1, 1, 1)):
'''Add a banner with text'''
frame_s = start_f
timestring = datetime.now().strftime("%f")
color_clip = bpy.context.scene.sequence_editor.sequences.new_effect(name="color"+timestring, type="COLOR", channel = channel+2, frame_start = frame_s, frame_end = frame_s + 240)
color_clip.color = banner_color
color_clip.blend_type = 'ALPHA_OVER'
color_clip.blend_alpha = 0.5
color_clip.transform.scale_y = h
color_clip.transform.scale_x = w
color_clip.transform.offset_y = y
color_clip.transform.offset_x = x
subtitle_clip = bpy.context.scene.sequence_editor.sequences.new_effect(name="subtitle"+timestring, type="TEXT", channel = channel+3, frame_start = frame_s, frame_end = frame_s + 240)
# subtitle_clip.text = str(x[1]) + " UTC; " + str(self.readExif(filename=str(x[0])))
subtitle_clip.text = text
subtitle_clip.color = text_color
subtitle_clip.transform.offset_y= y
subtitle_clip.transform.offset_x= x
subtitle_clip.font_size = font_size
color_clip.frame_final_duration = dur
subtitle_clip.frame_final_duration = dur
def add_image(self, file=""):
'''add image in the sequence editor'''
timestring = datetime.now().strftime("%f")
img = bpy.context.scene.sequence_editor.sequences.new_image(name=timestring, filepath=file, channel=16, frame_start=3646)
img.frame_final_duration = 1827
def process(self):
#self.add_movie_clips_from(dir="/home/amit/Documents/pendrive/Career-Template/7-podcasts-blender/0-workbench/2-Site-Reliability-Engineering-In-IT-Consulting/media/videos")
#self.add_banner_at(text="CICD+'Repository Management' in one Application", y=-180, font_size=24, dur=1280, channel=10, text_color=(1, 0.12, 0.33, 1))
# self.add_banner_at(text="CICD+'Repository Management' in one Application", y=-500, font_size=42, dur=1280, channel=10, text_color=(1, 0.12, 0.33, 1))
# self.add_banner_at(text="Supports DevSecOps philosophy by design", start_f=2128 , y=-500, font_size=42, dur=3345, channel=10, text_color=(1, 0.12, 0.33, 1))
# self.add_banner_at(x=-500,y=130,w=0.4,h=0.2,text="Traditional Agile", start_f=2128 , font_size=42, dur=3345, channel=11, text_color=(1, 0.12, 0.33, 1))
self.add_image(file="/home/amit/Documents/pendrive/Career-Template/7-podcasts-blender/0-workbench/2-Site-Reliability-Engineering-In-IT-Consulting/media/images/SRE-DevOps.png")
if __name__ == '__main__':
bve = BlenderVideoEditor()
bve.process()