优化音画不同步问题

This commit is contained in:
puke
2025-10-27 10:57:24 +08:00
committed by puke
parent abae34b5d2
commit 9e133d71a2
2 changed files with 16 additions and 5 deletions

View File

@@ -345,33 +345,38 @@ class VideoService:
logger.info("Creating video from image and audio") logger.info("Creating video from image and audio")
try: try:
# Get audio duration to ensure exact video duration match
probe = ffmpeg.probe(audio)
audio_duration = float(probe['format']['duration'])
logger.debug(f"Audio duration: {audio_duration:.3f}s")
# Input image with loop (loop=1 means loop indefinitely) # Input image with loop (loop=1 means loop indefinitely)
# Use framerate to set input framerate # Use framerate to set input framerate
input_image = ffmpeg.input(image, loop=1, framerate=fps) input_image = ffmpeg.input(image, loop=1, framerate=fps)
input_audio = ffmpeg.input(audio) input_audio = ffmpeg.input(audio)
# Combine image and audio # Combine image and audio
# Use -shortest to match audio duration # Use -t to explicitly set video duration = audio duration
( (
ffmpeg ffmpeg
.output( .output(
input_image, input_image,
input_audio, input_audio,
output, output,
t=audio_duration, # Force video duration to match audio exactly
vcodec='libx264', vcodec='libx264',
acodec='aac', acodec='aac',
pix_fmt='yuv420p', pix_fmt='yuv420p',
audio_bitrate='192k', audio_bitrate='192k',
preset='medium', preset='medium',
crf=23, crf=23,
shortest=None, # Duration = shortest input (audio)
**{'b:v': '2M'} # Video bitrate **{'b:v': '2M'} # Video bitrate
) )
.overwrite_output() .overwrite_output()
.run(capture_stdout=True, capture_stderr=True) .run(capture_stdout=True, capture_stderr=True)
) )
logger.success(f"Video created from image: {output}") logger.success(f"Video created from image: {output} (duration: {audio_duration:.3f}s)")
return output return output
except ffmpeg.Error as e: except ffmpeg.Error as e:
error_msg = e.stderr.decode() if e.stderr else str(e) error_msg = e.stderr.decode() if e.stderr else str(e)

View File

@@ -286,29 +286,35 @@ class VideoCompositor:
logger.info("Creating video from image and audio") logger.info("Creating video from image and audio")
try: try:
# Get audio duration to ensure exact video duration match
probe = ffmpeg.probe(audio)
audio_duration = float(probe['format']['duration'])
logger.debug(f"Audio duration: {audio_duration:.3f}s")
# Input image with loop # Input image with loop
input_image = ffmpeg.input(image, loop=1, framerate=fps) input_image = ffmpeg.input(image, loop=1, framerate=fps)
input_audio = ffmpeg.input(audio) input_audio = ffmpeg.input(audio)
# Combine image and audio # Combine image and audio
# Use -t to explicitly set video duration = audio duration
( (
ffmpeg ffmpeg
.output( .output(
input_image.video, input_image.video,
input_audio.audio, input_audio.audio,
output, output,
t=audio_duration, # Force video duration to match audio exactly
vcodec='libx264', vcodec='libx264',
acodec='aac', acodec='aac',
pix_fmt='yuv420p', pix_fmt='yuv420p',
audio_bitrate='192k', audio_bitrate='192k',
shortest=None, # Duration = audio duration
**{'b:v': '2M'} # Video bitrate **{'b:v': '2M'} # Video bitrate
) )
.overwrite_output() .overwrite_output()
.run(capture_stdout=True, capture_stderr=True) .run(capture_stdout=True, capture_stderr=True)
) )
logger.success(f"Video created from image: {output}") logger.success(f"Video created from image: {output} (duration: {audio_duration:.3f}s)")
return output return output
except ffmpeg.Error as e: except ffmpeg.Error as e:
error_msg = e.stderr.decode() if e.stderr else str(e) error_msg = e.stderr.decode() if e.stderr else str(e)