Skip to content

Video Encoding

x264 & x265

The only two lossy encoders you should need.
Mostly only x265 tbh.
These two also support resuming from previous parts of the encode in case it crashed or whatever.
It's done somewhat automagically and you don't really have to worry about it.


FFMPEG's lossless codec.
Basically the lossless codec to use. Supports just about everything and has way better compression than lossless x264.


Another option for lossless encodes.
Way worse compression than FFV1 but also way faster. Limited to 10 bit video.

Basic Usage

from vsmuxtools import src_file, x265, x264, FFV1, LosslessX264, LosslessPreset, settings_builder_x265, settings_builder_x264
from vstools import vs, core, finalize_clip

JPBD = src_file(R"F:\BDMV\Main Disc\BDMV\STREAM\00002.m2ts", True, (24, 500))

# This calls initialize_clip from vstools which creates a 16 bit clip to work with
src = JPBD.init_cut()

filtered = denoise(src)
filtered = grain(filtered)

output = finalize_clip(filtered)

# This will run if the current script is started without vspreview and whatnot
# Alternatively you can use: if not vspreview.is_preview():
if __name__ == "__main__":
    # Convenience function to make a settings string
    settings = settings_builder_x265(preset="slower", crf=13.5)

    # Basic bitrate multiplier zones
    x265_zones = [(100, 400, 0.5), (450, 480, 1.25)]

    # QP Clip can be a normal videonode or the src_file/FileInfo
    # You can also pass existing files to the qp_file parameter
    video_hevc = x265(settings, x265_zones, qp_clip=JPBD).encode(output)

    # x264 Zones can be a bit more useful with params like crf
    # You can still pass stuff like this with x265 but it can only do b and q.
    x264_zones = [(100, 400, "crf", 15), (450, 480, "crf", 13)]

    # You can also use a file with settings tho there's also a settings builder for x264
    # QP file generation will be skipped in this example
    video_avc = x264(R"./path/x264_settings", x264_zones).encode(output)

    # These two have way less params and don't support resumable encodes.
    # You only really have to care about the 3 presets this package offers.
    video_ffv1 = FFV1(LosslessPreset.COMPRESSION).encode(output)
    video_ll_avc = LosslessX264(LosslessPreset.SPEED).encode(output)

All of those video_* variables return a VideoFile object.
To get the filepath you simply do video_hevc.file.

Here you can also have your first look at the to_track() function of the *File types.
These convert the File types to their respective track types. This will be needed for muxing later.