FIX 对其音视频长度
This commit is contained in:
parent
c798e90b56
commit
dd359ccbdf
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue