#!/usr/bin/env python3 import pathlib import sys import wave import bpy def write_silence(path): path.parent.mkdir(parents=True, exist_ok=True) with wave.open(str(path), "wb") as stream: stream.setnchannels(1) stream.setsampwidth(2) stream.setframerate(8000) stream.writeframes(b"\0\0" * 8000) def main(output_path): output = pathlib.Path(output_path).resolve() media = output.parent / "media" audio_path = media / "WBV2P5002-silence.wav" image_path = media / "WBV2P5002-frame.png" write_silence(audio_path) bpy.ops.wm.read_factory_settings(use_empty=True) image = bpy.data.images.new("WBV2P5002Frame", width=8, height=8, alpha=True) image.generated_color = (0.12, 0.35, 0.8, 1.0) image.filepath_raw = str(image_path) image.file_format = "PNG" image.save() bpy.data.images.remove(image) scene = bpy.context.scene scene.name = "WBV2P5002MediaScene" scene.frame_start = 1 scene.frame_end = 48 scene.frame_set(1) scene.render.fps = 24 scene.render.fps_base = 1.0 tree = bpy.data.node_groups.new("WBV2P5002CompositorTree", "CompositorNodeTree") scene.compositing_node_group = tree tree.interface.new_socket(name="Image", in_out="OUTPUT", socket_type="NodeSocketColor") color = tree.nodes.new("CompositorNodeRGB") color.name = "WBV2P5002Constant" color.outputs["Color"].default_value = (0.1, 0.2, 0.4, 1.0) exposure = tree.nodes.new("CompositorNodeExposure") exposure.name = "WBV2P5002Exposure" exposure.inputs["Exposure"].default_value = 0.5 invert = tree.nodes.new("CompositorNodeInvert") invert.name = "WBV2P5002Invert" composite = tree.nodes.new("NodeGroupOutput") composite.name = "WBV2P5002Composite" tree.links.new(color.outputs["Color"], exposure.inputs["Image"]) tree.links.new(exposure.outputs["Image"], invert.inputs["Color"]) tree.links.new(invert.outputs["Color"], composite.inputs["Image"]) editor = scene.sequence_editor_create() sound = editor.strips.new_sound("WBV2P5002Sound", str(audio_path), channel=1, frame_start=1) sound.sound.filepath = "//media/WBV2P5002-silence.wav" sound.mute = True image_strip = editor.strips.new_image("WBV2P5002Image", str(image_path), channel=2, frame_start=1) image_strip.directory = "//media/" image_strip.elements[0].filename = "WBV2P5002-frame.png" image_strip.frame_final_duration = 24 second = editor.strips.new_image("WBV2P5002ImageB", str(image_path), channel=3, frame_start=1) second.directory = "//media/" second.elements[0].filename = "WBV2P5002-frame.png" second.frame_final_duration = 24 cross = editor.strips.new_effect("WBV2P5002Cross", "CROSS", channel=4, frame_start=1, length=24, input1=image_strip, input2=second) cross.mute = True output.parent.mkdir(parents=True, exist_ok=True) bpy.ops.wm.save_as_mainfile(filepath=str(output), check_existing=False, compress=True) if __name__ == "__main__": arguments = sys.argv[sys.argv.index("--") + 1 :] if len(arguments) != 1: raise SystemExit("usage: blender -b --factory-startup --python WBV2-P5-002.py -- OUTPUT") main(arguments[0])