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​
using var fsVideo = File.OpenRead("files/test_video.mp4");
var response = client.PostFileWithRequest(new CropVideo {
X = 100,
Y = 100,
Width = 500,
Height = 300
},
new UploadFile("test_video.mp4", fsVideo, "video"));
File.WriteAllBytes(saveToPath, response.Results[0].Url.GetBytesFromUrl());
Queue Crop Video​
using var fsVideo = File.OpenRead("files/test_video.mp4");
var response = client.PostFileWithRequest(new QueueCropVideo {
X = 100,
Y = 100,
Width = 500,
Height = 300
},
new UploadFile("test_video.mp4", fsVideo, "video")
);
GetArtifactGenerationStatusResponse status = new();
while (status.JobState is BackgroundJobState.Started or BackgroundJobState.Queued)
{
status = await client.GetAsync(new GetArtifactGenerationStatus { RefId = response.RefId });
await Task.Delay(1000);
}
// Download the cropped video
File.WriteAllBytes(saveToPath, status.Results[0].Url.GetBytesFromUrl());
Convert Video​
using var fsVideo = File.OpenRead("files/test_video.webm");
var response = client.PostFileWithRequest(new ConvertVideo {
OutputFormat = ConvertVideoOutputFormat.MOV
},
new UploadFile("test_video.webm", fsVideo, "video"));
File.WriteAllBytes(saveToPath, response.Results[0].Url.GetBytesFromUrl());
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​
using var fsVideo = File.OpenRead("files/test_video.mp4");
var response = client.PostFileWithRequest(new ScaleVideo {
Width = 1280,
Height = 720,
},
new UploadFile("test_video.mp4", fsVideo, "video"));
File.WriteAllBytes(saveToPath, response.Results[0].Url.GetBytesFromUrl());
Queue Scale Video​
using var fsVideo = File.OpenRead("files/test_video.mp4");
var response = client.PostFileWithRequest(new QueueScaleVideo {
Width = 1280,
Height = 720,
ReplyTo = "https://example.com/my/reply/endpoint" // optional
},
new UploadFile("test_video.mp4", fsVideo, "video"));
GetArtifactGenerationStatusResponse status = new();
while (status.JobState is BackgroundJobState.Started or BackgroundJobState.Queued)
{
status = await client.GetAsync(new GetArtifactGenerationStatus { RefId = response.RefId });
await Task.Delay(1000);
}
// Download the scaled video
File.WriteAllBytes(saveToPath, status.Results[0].Url.GetBytesFromUrl());
Watermark Video​
using var fsVideo = File.OpenRead("files/test_video.mp4");
using var fsWatermark = File.OpenRead("files/watermark_image.png");
var response = client.PostFilesWithRequest(new WatermarkVideo {
Position = WatermarkPosition.BottomRight
},
[
new UploadFile("test_video.mp4", fsVideo, "video"),
new UploadFile("watermark_image.png", fsWatermark, "watermark")
]);
File.WriteAllBytes(saveToPath, response.Results[0].Url.GetBytesFromUrl());
Queue Watermark Video​
using var fsVideo = File.OpenRead("files/test_video.mp4");
using var fsWatermark = File.OpenRead("files/watermark_image.png");
var response = client.PostFilesWithRequest(new QueueWatermarkVideo {
Position = WatermarkPosition.BottomRight
}, [
new UploadFile("test_video.mp4", fsVideo, "video"),
new UploadFile("watermark_image.png", fsWatermark, "watermark")
]);
GetArtifactGenerationStatusResponse status = new();
while (status.JobState is BackgroundJobState.Started or BackgroundJobState.Queued)
{
status = await client.GetAsync(new GetArtifactGenerationStatus { RefId = response.RefId });
await Task.Delay(1000);
}
// Download the watermarked video
File.WriteAllBytes(saveToPath, status.Results[0].Url.GetBytesFromUrl());
Trim Video​
using var fsVideo = File.OpenRead("files/test_video.mp4");
var response = client.PostFileWithRequest(new TrimVideo {
StartTime = "00:05",
EndTime = "00:10"
},
new UploadFile("test_video.mp4", fsVideo, "video"));
File.WriteAllBytes(saveToPath, response.Results[0].Url.GetBytesFromUrl());
Queue Trim Video​
using var fsVideo = File.OpenRead("files/test_video.mp4");
var response = client.PostFileWithRequest(new QueueTrimVideo {
StartTime = "00:05",
EndTime = "00:10"
},
new UploadFile("test_video.mp4", fsVideo, "video"));
GetArtifactGenerationStatusResponse status = new();
while (status.JobState is BackgroundJobState.Started or BackgroundJobState.Queued)
{
status = await client.GetAsync(new GetArtifactGenerationStatus { RefId = response.RefId });
await Task.Delay(1000);
}
// Download the trimmed video
File.WriteAllBytes(saveToPath, status.Results[0].Url.GetBytesFromUrl());
INFO
These operations depend on support from FFmpeg, which comes installed with the ComfyUI Agent. Limitations on encoders, decoders, and filters may apply.