Working with Files

Not everything in a video is generated. You may have footage you shot, a photo, a song, a recorded interview. This page covers the three classes that bring files into the library, ImageFile, VideoFile and AudioFile, and the handful of operations on them that video editing needs.

The library deliberately does not manage files for you. Copying, renaming, listing folders and the like are Python's job, and pathlib does them well. These classes only know how to read a media file and prepare it for the timeline.

Paths

Each class takes a path, as a string or a pathlib.Path. A relative path is relative to the current working directory, which is usually not what you want, so scripts anchor paths to their own location:

from pathlib import Path
from imaginaryarts import ImageFile, VideoFile, AudioFile

ROOT = Path(__file__).parent

photo = ImageFile(ROOT / "assets/photo.jpg")
footage = VideoFile(ROOT / "assets/interview.mp4")
music = AudioFile(ROOT / "assets/song.mp3")

A file that does not exist raises immediately, when the object is created, not later during the render.

ImageFile

An image on disk: PNG, JPEG or WebP.

MemberWhat it is
.pathThe path.
.width, .heightIts size in pixels.

Images go on the timeline with add_image, for an interval, since a picture has no length of its own. They are scaled and cropped to fill the canvas, so a landscape photo on a vertical canvas shows its middle; if you want a specific crop, crop the image first.

video.add_image(photo, interval=[0, 4000])

An ImageFile can also be handed to image generation as a reference, so a generated picture includes a real person, product or place. See Using reference characters, props, and environments.

VideoFile

A video on disk, in any common container (mp4, mov, webm, mkv).

MemberWhat it is
.pathThe path.
.durationIts length in milliseconds.
.has_audioWhether the file contains a sound track.
.trim([start, end])A copy that plays only that window of the file. end may be None.
.audioThe sound track as an AudioFile, extracted from the video.

Placing it

video.add_video(footage, at=0)                        # whole file, at its own length
video.add_video(footage, interval=[0, 20000])         # loops or freezes to fill 20 s
video.add_video(footage.trim([5000, 15000]), at=0)    # ten seconds from the middle

fit, volume and z_index work as described in Placement. The file's own sound plays along with it; volume=0 mutes it.

Cutting a file into pieces

Trimming returns a new object each time, so one file can appear many times:

hook = footage.trim([42000, 45000])       # the best three seconds
video.add_video(hook, at=0)
video.add_video(footage.trim([0, 42000]), at=3000)

Getting the audio out

.audio extracts the sound track once and caches it in the project's assets folder. The two common uses are transcribing it and placing the sound separately from the picture:

speech = create_stt(footage.audio, project=project)   # word timestamps for captions

video.add_video(footage, at=0, volume=0)               # the picture, muted
video.add_audio(footage.audio, volume=1.0)             # the sound, as its own track

The audio of a trimmed file is the audio of that window: footage.trim([5000, 15000]).audio is ten seconds long.

Frame rate and shape

Files are converted to the canvas's size, aspect ratio and frame rate when the video is rendered. Nothing is letterboxed; a file with a different shape is cropped to fill the frame. Frame rate conversion is automatic and does not change speed.

AudioFile

A sound file: mp3, wav, m4a, aac, ogg or flac.

MemberWhat it is
.pathThe path.
.durationIts length in milliseconds.
.trim([start, end])A copy that plays only that window.
.fade_in(ms), .fade_out(ms)A copy with a fade at the start or the end.

Loudness is decided when the track is placed, with add_audio(..., volume=), not on the file, so the same file can be loud in one place and quiet in another.

music = AudioFile(ROOT / "assets/song.mp3")

video.add_audio(music.trim([30000, None]).fade_in(1000), volume=0.25)
video.add_audio(AudioFile(ROOT / "assets/rain.wav"), volume=0.4, interval=[8000, 20000])

A track shorter than the video, or shorter than its interval, loops to fill it. Pass AudioFile(path, loop=False) to play it once and go silent.

Mixing your files with generated material

Files and generated assets are interchangeable on the timeline. A generated clip and a VideoFile are both placed with add_video; a generated image and an ImageFile both with add_image. The one practical difference: generated clips come in the lengths their model offers (4 to 8 seconds with Veo 3.1, 4 to 30 with Seedance 2.5) and are already the shape of the canvas, while your files can be anything and get cropped to fit.

video.add_video(footage, at=0)                                      # your interview
video.add_image(generated[0], interval=[6000, 11000], z_index=2)     # generated b-roll over it
video.add_video(generated[1], at=20000, z_index=2)