Write to Video¶
Documentation¶
- Class name:
Write to Video
- Category:
WAS Suite/Animation/Writer
- Output node:
False
The 'Write to Video' node is designed to facilitate the creation and manipulation of video files from images. It encompasses functionalities such as writing individual images to a video, generating transition frames between images, adding still image delays, and configuring video properties like frame rate and resolution. This node aims to provide a comprehensive set of tools for video editing and generation, making it easier to produce high-quality video content.
Input types¶
Required¶
image
- The image or sequence of images to be written into the video. This is the primary content that will be displayed in the video.
- Comfy dtype:
IMAGE
- Python dtype:
np.ndarray or list of np.ndarray
transition_frames
- Specifies the number of frames used for creating smooth transitions between images in the video. It enhances the visual flow of the video content.
- Comfy dtype:
INT
- Python dtype:
int
image_delay_sec
- Determines the duration for which each image is displayed in the video, allowing for the creation of still image delays. This parameter helps in controlling the pacing of the video content.
- Comfy dtype:
FLOAT
- Python dtype:
float
fps
- Sets the frame rate of the video, defining how many frames are displayed per second. This parameter is crucial for determining the smoothness and playback speed of the video.
- Comfy dtype:
INT
- Python dtype:
int
max_size
- Specifies the maximum size (in pixels) for the images in the video, ensuring that all images are uniformly scaled. This parameter helps in maintaining consistent video quality and aspect ratio.
- Comfy dtype:
INT
- Python dtype:
int
output_path
- The path to the directory where the video will be saved. It determines the location of the output video file.
- Comfy dtype:
STRING
- Python dtype:
str
filename
- The name of the output video file. It allows for easy identification and organization of created videos.
- Comfy dtype:
STRING
- Python dtype:
str
codec
- Defines the codec used for encoding the video. Different codecs can affect the video's compatibility, size, and quality.
- Comfy dtype:
COMBO[STRING]
- Python dtype:
str
Output types¶
IMAGE_PASS
- Comfy dtype:
IMAGE
- Indicates whether the image processing and video writing operations were successful.
- Python dtype:
bool
- Comfy dtype:
filepath_text
- Comfy dtype:
STRING
- The full path to the created video file, including its name. It provides a direct link to access or share the video.
- Python dtype:
str
- Comfy dtype:
filename_text
- Comfy dtype:
STRING
- The name of the created video file. It helps in identifying the video among other files.
- Python dtype:
str
- Comfy dtype:
Usage tips¶
- Infra type:
CPU
- Common nodes: unknown
Source code¶
class WAS_Video_Writer:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
WTools = WAS_Tools_Class()
v = WTools.VideoWriter()
codecs = []
for codec in v.get_codecs():
codecs.append(codec.upper())
codecs = sorted(codecs)
return {
"required": {
"image": ("IMAGE",),
"transition_frames": ("INT", {"default":30, "min":0, "max":120, "step":1}),
"image_delay_sec": ("FLOAT", {"default":2.5, "min":0.1, "max":60000.0, "step":0.1}),
"fps": ("INT", {"default":30, "min":1, "max":60.0, "step":1}),
"max_size": ("INT", {"default":512, "min":128, "max":1920, "step":1}),
"output_path": ("STRING", {"default": "./ComfyUI/output", "multiline": False}),
"filename": ("STRING", {"default": "comfy_writer", "multiline": False}),
"codec": (codecs,),
}
}
#@classmethod
#def IS_CHANGED(cls, **kwargs):
# return float("NaN")
RETURN_TYPES = ("IMAGE",TEXT_TYPE,TEXT_TYPE)
RETURN_NAMES = ("IMAGE_PASS","filepath_text","filename_text")
FUNCTION = "write_video"
CATEGORY = "WAS Suite/Animation/Writer"
def write_video(self, image, transition_frames=10, image_delay_sec=10, fps=30, max_size=512,
output_path="./ComfyUI/output", filename="morph", codec="H264"):
conf = getSuiteConfig()
if not conf.__contains__('ffmpeg_bin_path'):
cstr(f"Unable to use MP4 Writer because the `ffmpeg_bin_path` is not set in `{WAS_CONFIG_FILE}`").error.print()
return (image,"","")
if conf.__contains__('ffmpeg_bin_path'):
if conf['ffmpeg_bin_path'] != "/path/to/ffmpeg":
sys.path.append(conf['ffmpeg_bin_path'])
os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;udp"
os.environ['OPENCV_FFMPEG_BINARY'] = conf['ffmpeg_bin_path']
if output_path.strip() in [None, "", "."]:
output_path = "./ComfyUI/output"
if image == None:
image = pil2tensor(Image.new("RGB", (512,512), (0,0,0)))
if transition_frames < 0:
transition_frames = 0
elif transition_frames > 60:
transition_frames = 60
if fps < 1:
fps = 1
elif fps > 60:
fps = 60
results = []
for img in image:
print(img.shape)
new_image = self.rescale_image(tensor2pil(img), max_size)
print(new_image.size)
tokens = TextTokens()
output_path = os.path.abspath(os.path.join(*tokens.parseTokens(output_path).split('/')))
output_file = os.path.join(output_path, tokens.parseTokens(filename))
if not os.path.exists(output_path):
os.makedirs(output_path, exist_ok=True)
WTools = WAS_Tools_Class()
MP4Writer = WTools.VideoWriter(int(transition_frames), int(fps), int(image_delay_sec), max_size=max_size, codec=codec)
path = MP4Writer.write(new_image, output_file)
results.append(img)
return (torch.cat(results, dim=0), path, filename)
def rescale_image(self, image, max_dimension):
width, height = image.size
if width > max_dimension or height > max_dimension:
scaling_factor = max(width, height) / max_dimension
new_width = int(width / scaling_factor)
new_height = int(height / scaling_factor)
image = image.resize((new_width, new_height), Image.Resampling(1))
return image