Video Transform Endpoints

Also incorporated into the ComfyUI Agent is FFmpeg, which can be used to process videos. AI Server wraps some common operations into easier-to-use endpoints, such as:

  • Crop Video: Crop a video to a specific size.
  • Convert Video: Convert a video to a different format.
  • Scale Video: Scale a video to a different resolution.
  • Watermark Video: Add a watermark to a video.
  • Trim Video: Trim a video to a specific length.

Using Video Endpoints

These endpoints are used in a similar way to the other AI Server endpoints, e.g., you can provide a RefId and Tag to help categorize the request, and for Queue requests, you can provide a ReplyTo URL to send a POST request to when the request is complete.

Crop Video

var response = client.PostFilesWithRequest(new CropVideo {
        X = 100,
        Y = 100,
        Width = 500,
        Height = 300
    },
    [new UploadFile("test_video.mp4", File.OpenRead("files/test_video.mp4"), "video")]
);

var videoUrl = response.Outputs[0].Url;
videoUrl.DownloadFileTo(outputFileName);

Queue Crop Video

var response = client.PostFilesWithRequest(new QueueCropVideo {
        X = 100,
        Y = 100,
        Width = 500,
        Height = 300
    },
    [new UploadFile("test_video.mp4", File.OpenRead("files/test_video.mp4"), "video")]
);

var status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
while (status.JobState is BackgroundJobState.Started or BackgroundJobState.Queued)
{
    await Task.Delay(1000);
    status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
}

// Download the cropped video
var videoUrl = status.Outputs[0].Url;
videoUrl.DownloadFileTo($"cropped-video-{status.RefId}.mp4");

Convert Video

var response = client.PostFilesWithRequest(new ConvertVideo {
        OutputFormat = ConvertVideoOutputFormat.MOV
    },
    [new UploadFile("test_video.webm", File.OpenRead("files/test_video.webm"), "video")]
);

var videoUrl = response.Outputs[0].Url;
videoUrl.DownloadFileTo(outputFileName);

Queue Convert Video

var response = client.PostFilesWithRequest(new QueueConvertVideo {
        Format = "mp4",
        ReplyTo = "https://example.com/my/reply/endpoint"
    },
    [new UploadFile("video", File.OpenRead("video.avi"), "video.avi")]
);

var status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
var timeout = DateTime.UtcNow.AddMinutes(5);
while (status.JobState is not BackgroundJobState.Completed &&
       DateTime.UtcNow < timeout)
{
    await Task.Delay(1000);
    status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
}

// Download the converted video
var videoUrl = status.Outputs[0].Url;
videoUrl.DownloadFileTo("converted-video.mp4");

Scale Video

var response = client.PostFilesWithRequest(new ScaleVideo {
        Width = 1280,
        Height = 720,
    },
    [new UploadFile("test_video.mp4", File.OpenRead("files/test_video.mp4"), "video")]
);

var videoUrl = response.Outputs[0].Url;
videoUrl.DownloadFileTo(outputFileName);

Queue Scale Video

var response = client.PostFilesWithRequest(new QueueScaleVideo {
        Width = 1280,
        Height = 720,
        ReplyTo = "https://example.com/my/reply/endpoint" // optional
    },
    [new UploadFile("test_video.mp4", File.OpenRead("files/test_video.mp4"), "video")]
);

var status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
while (status.JobState is BackgroundJobState.Started or BackgroundJobState.Queued)
{
    await Task.Delay(1000);
    status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
}

// Download the scaled video
var videoUrl = status.Outputs[0].Url;
videoUrl.DownloadFileTo($"scaled-video-{status.RefId}.mp4");

Watermark Video

var response = client.PostFilesWithRequest(new WatermarkVideo {
        Position = WatermarkPosition.BottomRight
    },
    [new UploadFile("test_video.mp4", File.OpenRead("files/test_video.mp4"), "video"),
     new UploadFile("watermark_image.png", File.OpenRead("files/watermark_image.png"), "watermark")]
);

var videoUrl = response.Outputs[0].Url;
videoUrl.DownloadFileTo(outputFileName);

Queue Watermark Video

var response = client.PostFilesWithRequest(new QueueWatermarkVideo {
        Position = WatermarkPosition.BottomRight
    },
    [new UploadFile("test_video.mp4", File.OpenRead("files/test_video.mp4"), "video"),
     new UploadFile("watermark_image.png", File.OpenRead("files/watermark_image.png"), "watermark")]
);

var status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
while (status.JobState is BackgroundJobState.Started or BackgroundJobState.Queued)
{
    await Task.Delay(1000);
    status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
}

// Download the watermarked video
var videoUrl = status.Outputs[0].Url;
videoUrl.DownloadFileTo($"watermarked-video-{status.RefId}.mp4");

Trim Video

var response = client.PostFilesWithRequest(new TrimVideo {
        StartTime = "00:05",
        EndTime = "00:10"
    },
    [new UploadFile("test_video.mp4", File.OpenRead("files/test_video.mp4"), "video")]
);

var videoUrl = response.Outputs[0].Url;
videoUrl.DownloadFileTo(outputFileName);

Queue Trim Video

var response = client.PostFilesWithRequest(new QueueTrimVideo {
        StartTime = "00:05",
        EndTime = "00:10"
    },
    [new UploadFile("test_video.mp4", File.OpenRead("files/test_video.mp4"), "video")]
);

var status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
while (status.JobState is BackgroundJobState.Started or BackgroundJobState.Queued)
{
    await Task.Delay(1000);
    status = await client.GetAsync(new GetJobStatus { RefId = response.RefId });
}

// Download the trimmed video
var videoUrl = status.Outputs[0].Url;
videoUrl.DownloadFileTo($"trimmed-video-{status.RefId}.mp4");

INFO

These operations depend on support from FFmpeg, which comes installed with the ComfyUI Agent. Limitations on encoders, decoders, and filters may apply.