ADD 增加视频帧率转换节点
This commit is contained in:
parent
1b6e2d8faa
commit
d91c536a66
|
|
@ -9,7 +9,7 @@ from .nodes.cos import COSUpload, COSDownload
|
||||||
from .nodes.face_detect import FaceDetect
|
from .nodes.face_detect import FaceDetect
|
||||||
from .nodes.face_extract import FaceExtract
|
from .nodes.face_extract import FaceExtract
|
||||||
from .nodes.log2db import LogToDB
|
from .nodes.log2db import LogToDB
|
||||||
from .nodes.videocut import VideoCut, VideoCutByFramePoint
|
from .nodes.video import VideoCut, VideoCutByFramePoint, VideoChangeFPS
|
||||||
from .nodes.vod2local import VodToLocalNode
|
from .nodes.vod2local import VodToLocalNode
|
||||||
|
|
||||||
# A dictionary that contains all nodes you want to export with their names
|
# A dictionary that contains all nodes you want to export with their names
|
||||||
|
|
@ -23,6 +23,7 @@ NODE_CLASS_MAPPINGS = {
|
||||||
"S3Download": S3Download,
|
"S3Download": S3Download,
|
||||||
"VideoCutCustom": VideoCut,
|
"VideoCutCustom": VideoCut,
|
||||||
"VideoCutByFramePoint": VideoCutByFramePoint,
|
"VideoCutByFramePoint": VideoCutByFramePoint,
|
||||||
|
"VideoChangeFPS": VideoChangeFPS,
|
||||||
"VodToLocal": VodToLocalNode,
|
"VodToLocal": VodToLocalNode,
|
||||||
"LogToDB": LogToDB,
|
"LogToDB": LogToDB,
|
||||||
"VideoPointCompute": VideoStartPointDurationCompute,
|
"VideoPointCompute": VideoStartPointDurationCompute,
|
||||||
|
|
@ -45,6 +46,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||||
"S3Download": "S3下载",
|
"S3Download": "S3下载",
|
||||||
"VideoCutCustom": "视频剪裁",
|
"VideoCutCustom": "视频剪裁",
|
||||||
"VideoCutByFramePoint": "视频剪裁(精确帧位)",
|
"VideoCutByFramePoint": "视频剪裁(精确帧位)",
|
||||||
|
"VideoChangeFPS": "视频转换帧率",
|
||||||
"VodToLocal": "腾讯云VOD下载",
|
"VodToLocal": "腾讯云VOD下载",
|
||||||
"LogToDB": "状态持久化DB",
|
"LogToDB": "状态持久化DB",
|
||||||
"VideoPointCompute": "视频帧位计算",
|
"VideoPointCompute": "视频帧位计算",
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ class FaceDetect:
|
||||||
|
|
||||||
FUNCTION = "predict"
|
FUNCTION = "predict"
|
||||||
|
|
||||||
CATEGORY = "不忘科技-自定义节点🚩"
|
CATEGORY = "不忘科技-自定义节点🚩/面部"
|
||||||
|
|
||||||
def predict(self, image, main_seed, model, length, threshold):
|
def predict(self, image, main_seed, model, length, threshold):
|
||||||
image, image_selected, cls, prob, nums, period = test_node(
|
image, image_selected, cls, prob, nums, period = test_node(
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class FaceExtract:
|
||||||
|
|
||||||
FUNCTION = "crop"
|
FUNCTION = "crop"
|
||||||
|
|
||||||
CATEGORY = "不忘科技-自定义节点🚩"
|
CATEGORY = "不忘科技-自定义节点🚩/面部"
|
||||||
|
|
||||||
def crop(self, image):
|
def crop(self, image):
|
||||||
device = model_management.get_torch_device()
|
device = model_management.get_torch_device()
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ class HeyGemF2F:
|
||||||
RETURN_TYPES = ("STRING",)
|
RETURN_TYPES = ("STRING",)
|
||||||
RETURN_NAMES = ("视频存储路径",)
|
RETURN_NAMES = ("视频存储路径",)
|
||||||
FUNCTION = "f2f"
|
FUNCTION = "f2f"
|
||||||
CATEGORY = "不忘科技-自定义节点🚩"
|
CATEGORY = "不忘科技-自定义节点🚩/口型同步"
|
||||||
|
|
||||||
def f2f(self, video:Tensor, audio:dict, heygem_url:str, heygem_temp_path:str, is_Windows:bool):
|
def f2f(self, video:Tensor, audio:dict, heygem_url:str, heygem_temp_path:str, is_Windows:bool):
|
||||||
uid = str(uuid.uuid4())
|
uid = str(uuid.uuid4())
|
||||||
|
|
@ -206,7 +206,7 @@ class HeyGemF2FFromFile:
|
||||||
RETURN_TYPES = ("STRING",)
|
RETURN_TYPES = ("STRING",)
|
||||||
RETURN_NAMES = ("视频存储路径",)
|
RETURN_NAMES = ("视频存储路径",)
|
||||||
FUNCTION = "f2f"
|
FUNCTION = "f2f"
|
||||||
CATEGORY = "不忘科技-自定义节点🚩"
|
CATEGORY = "不忘科技-自定义节点🚩/口型同步"
|
||||||
|
|
||||||
def f2f(self, video:str, audio:str, heygem_url:str, heygem_temp_path:str, is_Windows:bool):
|
def f2f(self, video:str, audio:str, heygem_url:str, heygem_temp_path:str, is_Windows:bool):
|
||||||
uid = str(uuid.uuid4())
|
uid = str(uuid.uuid4())
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class S3Download:
|
||||||
RETURN_TYPES = ("STRING",)
|
RETURN_TYPES = ("STRING",)
|
||||||
RETURN_NAMES = ("视频存储路径",)
|
RETURN_NAMES = ("视频存储路径",)
|
||||||
FUNCTION = "download"
|
FUNCTION = "download"
|
||||||
CATEGORY = "不忘科技-自定义节点🚩"
|
CATEGORY = "不忘科技-自定义节点🚩/S3"
|
||||||
|
|
||||||
def download(self, s3_bucket, s3_key):
|
def download(self, s3_bucket, s3_key):
|
||||||
s3_key_in = s3_key.replace("/",os.sep)
|
s3_key_in = s3_key.replace("/",os.sep)
|
||||||
|
|
@ -62,7 +62,7 @@ class S3Upload:
|
||||||
RETURN_NAMES = ("S3文件Key",)
|
RETURN_NAMES = ("S3文件Key",)
|
||||||
|
|
||||||
FUNCTION = "upload"
|
FUNCTION = "upload"
|
||||||
CATEGORY = "不忘科技-自定义节点🚩"
|
CATEGORY = "不忘科技-自定义节点🚩/S3"
|
||||||
|
|
||||||
def upload(self, s3_bucket, path, subfolder):
|
def upload(self, s3_bucket, path, subfolder):
|
||||||
loguru.logger.info(f"S3 UPLOAD {path} to {s3_bucket}/{subfolder}")
|
loguru.logger.info(f"S3 UPLOAD {path} to {s3_bucket}/{subfolder}")
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import uuid
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import ffmpy
|
import ffmpy
|
||||||
|
import loguru
|
||||||
import torchvision.io
|
import torchvision.io
|
||||||
|
|
||||||
video_extensions = ['webm', 'mp4', 'mkv', 'gif', 'mov']
|
video_extensions = ['webm', 'mp4', 'mkv', 'gif', 'mov']
|
||||||
|
|
@ -32,7 +33,7 @@ class VideoCut:
|
||||||
|
|
||||||
# OUTPUT_NODE = False
|
# OUTPUT_NODE = False
|
||||||
|
|
||||||
CATEGORY = "不忘科技-自定义节点🚩"
|
CATEGORY = "不忘科技-自定义节点🚩/视频"
|
||||||
|
|
||||||
def cut(self, video_path, start, end):
|
def cut(self, video_path, start, end):
|
||||||
try:
|
try:
|
||||||
|
|
@ -111,7 +112,6 @@ class VideoCut:
|
||||||
files = glob.glob(output.replace("%03d", "*"))
|
files = glob.glob(output.replace("%03d", "*"))
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
video, audio, info = torchvision.io.read_video(files[0])
|
video, audio, info = torchvision.io.read_video(files[0])
|
||||||
video.mul_(255)
|
|
||||||
audio.unsqueeze_(0)
|
audio.unsqueeze_(0)
|
||||||
try:
|
try:
|
||||||
os.remove(files[0])
|
os.remove(files[0])
|
||||||
|
|
@ -144,7 +144,7 @@ class VideoCutByFramePoint:
|
||||||
|
|
||||||
# OUTPUT_NODE = False
|
# OUTPUT_NODE = False
|
||||||
|
|
||||||
CATEGORY = "不忘科技-自定义节点🚩"
|
CATEGORY = "不忘科技-自定义节点🚩/视频"
|
||||||
|
|
||||||
def cut(self, video_path, start_point, duration, fps, force_match_fps):
|
def cut(self, video_path, start_point, duration, fps, force_match_fps):
|
||||||
try:
|
try:
|
||||||
|
|
@ -234,3 +234,54 @@ class VideoCutByFramePoint:
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
raise Exception("Cut Failed")
|
raise Exception("Cut Failed")
|
||||||
|
|
||||||
|
class VideoChangeFPS:
|
||||||
|
"""FFMPEG视频FPS转换"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(s):
|
||||||
|
return {
|
||||||
|
"required": {
|
||||||
|
"video_path": ("STRING",{"placeholder": "X://insert/path/here.mp4", "vhs_path_extensions": video_extensions}),
|
||||||
|
"fps": ("INT", {"default": 30}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_TYPES = ("STRING",)
|
||||||
|
RETURN_NAMES = ("视频路径",)
|
||||||
|
|
||||||
|
FUNCTION = "changeFps"
|
||||||
|
|
||||||
|
OUTPUT_NODE = True
|
||||||
|
|
||||||
|
CATEGORY = "不忘科技-自定义节点🚩/视频"
|
||||||
|
|
||||||
|
def changeFps(self, video_path, fps):
|
||||||
|
try:
|
||||||
|
print(video_path[1])
|
||||||
|
if not (video_path.startswith("/") or video_path.startswith("output/") or video_path[1] == ":"):
|
||||||
|
video_path = "output/" + video_path
|
||||||
|
loguru.logger.info("Processing video: %s", video_path)
|
||||||
|
output = ".".join([video_path.split(".")[-2]+"-%dfps" % fps,video_path.split(".")[-1]])
|
||||||
|
ff = ffmpy.FFmpeg(
|
||||||
|
inputs={video_path: None},
|
||||||
|
outputs={
|
||||||
|
output: [
|
||||||
|
"-vf",
|
||||||
|
"fps=%d" % fps,
|
||||||
|
"-c:v",
|
||||||
|
"libx264",
|
||||||
|
"-crf",
|
||||||
|
"16",
|
||||||
|
"-preset",
|
||||||
|
"slow",
|
||||||
|
"-c:a",
|
||||||
|
"copy"
|
||||||
|
]
|
||||||
|
})
|
||||||
|
print(ff.cmd)
|
||||||
|
ff.run()
|
||||||
|
return (output,)
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
raise Exception("ChangeFPS Failed")
|
||||||
Loading…
Reference in New Issue