FIX 对其音视频长度

This commit is contained in:
kyj@bowong.ai 2025-04-24 19:19:50 +08:00
parent c798e90b56
commit dd359ccbdf
1 changed files with 68 additions and 23 deletions

View File

@ -260,35 +260,80 @@ class VideoChangeFPS:
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):
try:
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_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]])
ff = ffmpy.FFmpeg(
inputs={video_path: ["-loglevel", "info","-y"]},
outputs={
output: [
"-vf",
"fps=%d" % fps,
"-c:v",
"libx264",
"-crf",
"16",
"-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)
# 分步执行
self.adjust_video_fps(video_path, output_temp, fps) # 第一步调整FPS
self.align_audio_to_video(output_temp, output) # 第二步:对齐音频
# 校验结果
final_video_dur = self.get_media_duration(output, "v")
final_audio_dur = self.get_media_duration(output, "a")
print("video_duration:", final_video_dur, "audio_duration:", final_audio_dur)
assert abs(final_video_dur - final_audio_dur) < 0.01, "音视频长度未对齐!"
loguru.logger.success(f"处理成功!视频长度: {final_video_dur:.3f}s, 音频长度: {final_audio_dur:.3f}s")
return (output,)
except:
traceback.print_exc()