FIX 对其音视频长度
This commit is contained in:
parent
c798e90b56
commit
dd359ccbdf
|
|
@ -260,35 +260,80 @@ class VideoChangeFPS:
|
||||||
|
|
||||||
CATEGORY = "不忘科技-自定义节点🚩/视频"
|
CATEGORY = "不忘科技-自定义节点🚩/视频"
|
||||||
|
|
||||||
|
def get_media_duration(self, input_file, stream_type="v"):
|
||||||
|
"""获取视频或音频的精确时长(秒)"""
|
||||||
|
cmd = [
|
||||||
|
"ffprobe", "-v", "error",
|
||||||
|
"-select_streams", f"{stream_type}:0",
|
||||||
|
"-show_entries", "stream=duration",
|
||||||
|
"-of", "csv=p=0",
|
||||||
|
input_file
|
||||||
|
]
|
||||||
|
return float(subprocess.check_output(cmd).decode().strip())
|
||||||
|
|
||||||
|
def adjust_video_fps(self, input_video, output_temp, target_fps):
|
||||||
|
"""仅调整视频FPS,输出临时文件"""
|
||||||
|
ff = ffmpy.FFmpeg(
|
||||||
|
inputs={input_video: None},
|
||||||
|
outputs={
|
||||||
|
output_temp: f"-y -vf fps={target_fps} -c:v libx264 -c:a aac"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
print("调整FPS命令:", ff.cmd)
|
||||||
|
with open("user/ffmpeg.txt", "a") as log:
|
||||||
|
log.write("\n----" + f"{datetime.now()}----\n" + ff.cmd + "\n========\n")
|
||||||
|
with open("user/ffmpeg.txt", "a") as log:
|
||||||
|
ff.run(stdout=log, stderr=log)
|
||||||
|
|
||||||
|
def align_audio_to_video(self, input_video, output_final):
|
||||||
|
"""将音频精确对齐到视频长度"""
|
||||||
|
video_duration = self.get_media_duration(input_video, "v")
|
||||||
|
audio_duration = self.get_media_duration(input_video, "a")
|
||||||
|
print("video_duration:", video_duration, "audio_duration:", audio_duration)
|
||||||
|
|
||||||
|
# 动态选择补静音或剪切
|
||||||
|
filter_audio = (
|
||||||
|
f"atrim=end={video_duration},asetpts=PTS-STARTPTS"
|
||||||
|
if audio_duration > video_duration
|
||||||
|
else f"apad=whole_dur={video_duration},asetpts=PTS-STARTPTS"
|
||||||
|
)
|
||||||
|
|
||||||
|
ff = ffmpy.FFmpeg(
|
||||||
|
inputs={input_video: None},
|
||||||
|
outputs={
|
||||||
|
output_final: f""" -y
|
||||||
|
-filter_complex "
|
||||||
|
[0:v]copy[v];
|
||||||
|
[0:a]{filter_audio}[a]
|
||||||
|
"
|
||||||
|
-map "[v]" -map "[a]"
|
||||||
|
-c:v libx264 -c:a aac
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
)
|
||||||
|
print("对齐音频命令:", ff.cmd)
|
||||||
|
with open("user/ffmpeg.txt", "a") as log:
|
||||||
|
log.write("\n----" + f"{datetime.now()}----\n" + ff.cmd + "\n========\n")
|
||||||
|
with open("user/ffmpeg.txt", "a") as log:
|
||||||
|
ff.run(stdout=log, stderr=log)
|
||||||
|
|
||||||
def changeFps(self, video_path, fps):
|
def changeFps(self, video_path, fps):
|
||||||
try:
|
try:
|
||||||
if not (video_path.startswith("/") or video_path.startswith("output/") or video_path[1] == ":"):
|
if not (video_path.startswith("/") or video_path.startswith("output/") or video_path[1] == ":"):
|
||||||
video_path = "output/" + video_path
|
video_path = "output/" + video_path
|
||||||
loguru.logger.info("Processing video: %s" % video_path)
|
loguru.logger.info("Processing video: %s" % video_path)
|
||||||
|
output_temp = ".".join([video_path.split(".")[-2] + "-%dfps-temp" % fps, video_path.split(".")[-1]])
|
||||||
output = ".".join([video_path.split(".")[-2]+"-%dfps" % fps,video_path.split(".")[-1]])
|
output = ".".join([video_path.split(".")[-2]+"-%dfps" % fps,video_path.split(".")[-1]])
|
||||||
ff = ffmpy.FFmpeg(
|
# 分步执行
|
||||||
inputs={video_path: ["-loglevel", "info","-y"]},
|
self.adjust_video_fps(video_path, output_temp, fps) # 第一步:调整FPS
|
||||||
outputs={
|
self.align_audio_to_video(output_temp, output) # 第二步:对齐音频
|
||||||
output: [
|
|
||||||
"-vf",
|
# 校验结果
|
||||||
"fps=%d" % fps,
|
final_video_dur = self.get_media_duration(output, "v")
|
||||||
"-c:v",
|
final_audio_dur = self.get_media_duration(output, "a")
|
||||||
"libx264",
|
print("video_duration:", final_video_dur, "audio_duration:", final_audio_dur)
|
||||||
"-crf",
|
assert abs(final_video_dur - final_audio_dur) < 0.01, "音视频长度未对齐!"
|
||||||
"16",
|
loguru.logger.success(f"处理成功!视频长度: {final_video_dur:.3f}s, 音频长度: {final_audio_dur:.3f}s")
|
||||||
"-preset",
|
|
||||||
"slow",
|
|
||||||
"-threads",
|
|
||||||
"12",
|
|
||||||
"-c:a",
|
|
||||||
"copy",
|
|
||||||
]
|
|
||||||
})
|
|
||||||
print(ff.cmd)
|
|
||||||
with open("user/ffmpeg.txt", "a") as log:
|
|
||||||
log.write("\n----"+f"{datetime.now()}----\n"+ff.cmd+"\n========\n")
|
|
||||||
with open("user/ffmpeg.txt", "a") as log:
|
|
||||||
ff.run(stdout=log, stderr=log)
|
|
||||||
return (output,)
|
return (output,)
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue