Files
Runware-ComfyUI-Runware/modules/videoBgRemoval.py
T
Sirshendu Ganguly 056ade0661 Refactor: Use librosa instead of torchaudio, Add dedicated handlers for all use parameters and fix widget ordering
- Use librosa instead of torchaudio for mediaStorage
- Created dedicated toggle handlers for Image Inference, Video Inference, Upscaler, Audio Inference, Accelerator Options, Bytedance Provider Settings, and OpenAI Provider Settings
- Fixed Audio Inference widget ordering (use parameters now appear before their corresponding parameters)
- All handlers use the same proven pattern from videoInferenceDimensionsHandler
- Improved widget disabling/enabling functionality across all nodes
2025-11-05 22:31:15 -05:00

146 lines
5.6 KiB
Python

from .utils import runwareUtils as rwUtils
import json
import comfy.model_management
class videoBgRemoval:
"""Video Background Removal node for removing video backgrounds"""
RUNWARE_VRMBG_MODELS = {
"bria:51@1": "bria:51@1",
}
BACKGROUND_COLORS = {
"Black [0, 0, 0, 1]": [0, 0, 0, 1],
"White [255, 255, 255, 0]": [255, 255, 255, 0],
"Gray [128, 128, 128, 0]": [128, 128, 128, 0],
"Red [255, 0, 0, 0]": [255, 0, 0, 0],
"Green [0, 255, 0, 0]": [0, 255, 0, 0],
"Blue [0, 0, 255, 0]": [0, 0, 255, 0],
"Yellow [255, 255, 0, 0]": [255, 255, 0, 0],
"Cyan [0, 255, 255, 0]": [0, 255, 255, 0],
"Magenta [255, 0, 255, 0]": [255, 0, 255, 0],
"Orange [255, 165, 0, 0]": [255, 165, 0, 0],
}
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"Video": ("STRING", {
"tooltip": "MediaUUID from Runware Media Upload node for the video to process (max 30 seconds). Supports resolution up to 16000x16000 (16K)."
}),
"Model": (list(cls.RUNWARE_VRMBG_MODELS.keys()), {
"tooltip": "Select the video background removal model to use.",
"default": "Bria Video Background Removal",
}),
},
"optional": {
"Background Color": (list(cls.BACKGROUND_COLORS.keys()), {
"default": "White",
"tooltip": "Background color preset to use. Hex values are not supported.",
}),
"Output Format": (["mp4", "webm", "mov"], {
"default": "mp4",
"tooltip": "Choose the output video format.",
}),
}
}
DESCRIPTION = "Remove complex or moving video backgrounds in real time, isolating subjects with clean alpha channels for seamless compositing."
FUNCTION = "removeBackground"
RETURN_TYPES = ("VIDEO",)
RETURN_NAMES = ("VIDEO",)
CATEGORY = "Runware"
def removeBackground(self, **kwargs):
"""Remove background from video"""
videoUuid = kwargs.get("Video")
modelName = kwargs.get("Model", "Bria Video Background Removal")
backgroundColor = kwargs.get("Background Color", "Transparent")
outputFormat = kwargs.get("Output Format", "mp4")
if not videoUuid or videoUuid.strip() == "":
raise ValueError("Video mediaUUID is required")
modelAir = self.RUNWARE_VRMBG_MODELS.get(modelName, "bria:51@1")
rgbaColor = self.BACKGROUND_COLORS.get(backgroundColor, [255, 255, 255, 0])
genConfig = self._buildGenConfig(videoUuid, modelAir, outputFormat, rgbaColor)
print(f"[DEBUG] Sending Video Background Removal Request:")
print(f"[DEBUG] Request Payload: {json.dumps(genConfig, indent=2)}")
genResult = rwUtils.inferenecRequest(genConfig)
print(f"[DEBUG] Received Video Background Removal Response:")
print(f"[DEBUG] Response: {json.dumps(genResult, indent=2)}")
self._validateResponse(genResult)
taskUuid = genConfig[0]["taskUUID"]
videos = self._pollForVideoResult(taskUuid)
return videos
def _buildGenConfig(self, videoUuid, modelAir, outputFormat, rgbaColor):
"""Build generation configuration for API request"""
return [{
"taskType": "removeBackground",
"taskUUID": rwUtils.genRandUUID(),
"inputs": {
"video": videoUuid
},
"model": modelAir,
"outputFormat": outputFormat,
"settings": {
"rgba": rgbaColor
}
}]
def _validateResponse(self, genResult):
"""Validate API response"""
if "errors" in genResult:
errorMessage = genResult["errors"][0]["message"]
raise Exception(f"Video background removal failed: {errorMessage}")
def _pollForVideoResult(self, taskUuid):
"""Poll for video result"""
while True:
comfy.model_management.throw_exception_if_processing_interrupted()
pollResult = rwUtils.pollVideoResult(taskUuid)
print(f"[Debugging] Poll result: {pollResult}")
if pollResult and "errors" in pollResult and len(pollResult["errors"]) > 0:
errorInfo = pollResult["errors"][0]
errorMessage = errorInfo.get("message", "Unknown error")
raise Exception(f"Video background removal failed: {errorMessage}")
if pollResult and "data" in pollResult and len(pollResult["data"]) > 0:
videoData = pollResult["data"][0]
if "status" in videoData:
status = videoData["status"]
if status == "success":
if "videoURL" in videoData or "videoBase64Data" in videoData:
videos = rwUtils.convertVideoB64List(pollResult, 1920, 1080)
return videos
comfy.model_management.throw_exception_if_processing_interrupted()
for _ in range(10):
comfy.model_management.throw_exception_if_processing_interrupted()
rwUtils.time.sleep(0.1)
# Node class mappings
NODE_CLASS_MAPPINGS = {
"RunwareVideoBgRemoval": videoBgRemoval,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareVideoBgRemoval": "Runware Video Background Removal",
}