1, 增加一次性输出多个视频

2, 增加背景音乐音量设置
3, 增加字幕位置
4, UI优化
5, 一些其他Bug修复和优化
This commit is contained in:
harry
2024-03-23 15:31:34 +08:00
parent ce4b3771b6
commit 0771b3268c
7 changed files with 146 additions and 65 deletions

View File

@@ -34,31 +34,30 @@ def combine_videos(combined_video_path: str,
max_clip_duration: int = 5,
threads: int = 2,
) -> str:
logger.info(f"combining {len(video_paths)} videos into one file: {combined_video_path}")
audio_clip = AudioFileClip(audio_file)
max_duration = audio_clip.duration
logger.info(f"max duration of audio: {max_duration} seconds")
audio_duration = audio_clip.duration
logger.info(f"max duration of audio: {audio_duration} seconds")
# Required duration of each clip
req_dur = max_duration / len(video_paths)
req_dur = audio_duration / len(video_paths)
req_dur = max_clip_duration
logger.info(f"each clip will be maximum {req_dur} seconds long")
aspect = VideoAspect(video_aspect)
video_width, video_height = aspect.to_resolution()
clips = []
tot_dur = 0
video_duration = 0
# Add downloaded clips over and over until the duration of the audio (max_duration) has been reached
while tot_dur < max_duration:
while video_duration < audio_duration:
# random video_paths order
if video_concat_mode.value == VideoConcatMode.random.value:
random.shuffle(video_paths)
for video_path in video_paths:
clip = VideoFileClip(video_path)
clip = clip.without_audio()
clip = VideoFileClip(video_path).without_audio()
# Check if clip is longer than the remaining audio
if (max_duration - tot_dur) < clip.duration:
clip = clip.subclip(0, (max_duration - tot_dur))
if (audio_duration - video_duration) < clip.duration:
clip = clip.subclip(0, (audio_duration - video_duration))
# Only shorten clips if the calculated clip length (req_dur) is shorter than the actual clip to prevent still image
elif req_dur < clip.duration:
clip = clip.subclip(0, req_dur)
@@ -88,7 +87,7 @@ def combine_videos(combined_video_path: str,
clip = clip.subclip(0, max_clip_duration)
clips.append(clip)
tot_dur += clip.duration
video_duration += clip.duration
final_clip = concatenate_videoclips(clips)
final_clip = final_clip.set_fps(30)
@@ -125,7 +124,7 @@ def wrap_text(text, max_width, font='Arial', fontsize=60):
_wrapped_lines_.append(_txt_)
_txt_ = ''
_wrapped_lines_.append(_txt_)
return '\n'.join(_wrapped_lines_)
return '\n'.join(_wrapped_lines_).strip()
def generate_video(video_path: str,
@@ -153,11 +152,23 @@ def generate_video(video_path: str,
logger.info(f"using font: {font_path}")
def generator(txt):
wrapped_txt = wrap_text(txt, max_width=video_width - 100,
if params.subtitle_position == "top":
position_height = video_height * 0.1
elif params.subtitle_position == "bottom":
position_height = video_height * 0.9
else:
position_height = "center"
def generator(txt, **kwargs):
max_width = video_width * 0.9
# logger.debug(f"rendering text: {txt}")
wrapped_txt = wrap_text(txt,
max_width=max_width,
font=font_path,
fontsize=params.font_size) # 调整max_width以适应你的视频
return TextClip(
fontsize=params.font_size
) # 调整max_width以适应你的视频
clip = TextClip(
wrapped_txt,
font=font_path,
fontsize=params.font_size,
@@ -167,18 +178,16 @@ def generate_video(video_path: str,
stroke_width=params.stroke_width,
print_cmd=False,
)
position_height = video_height - 200
if params.video_aspect == VideoAspect.landscape:
position_height = video_height - 100
return clip
clips = [
VideoFileClip(video_path),
]
if subtitle_path and os.path.exists(subtitle_path):
subtitles = SubtitlesClip(subtitles=subtitle_path, make_textclip=generator, encoding='utf-8')
clips.append(subtitles.set_position(lambda _t: ('center', position_height)))
sub = SubtitlesClip(subtitles=subtitle_path, make_textclip=generator, encoding='utf-8')
sub_clip = sub.set_position(lambda _t: ('center', position_height))
clips.append(sub_clip)
result = CompositeVideoClip(clips)
@@ -199,7 +208,7 @@ def generate_video(video_path: str,
original_audio = video_clip.audio
song_clip = AudioFileClip(bgm_file).set_fps(44100)
# Set the volume of the song to 10% of the original volume
song_clip = song_clip.volumex(0.2).set_fps(44100)
song_clip = song_clip.volumex(params.bgm_volume)
# Add the song to the video
comp_audio = CompositeAudioClip([original_audio, song_clip])
video_clip = video_clip.set_audio(comp_audio)
@@ -211,3 +220,38 @@ def generate_video(video_path: str,
os.remove(temp_output_file)
logger.success(f"completed")
if __name__ == "__main__":
txt = "hello 幸福经常被描述为最终人生目标和人类追求的核心 但它通常涉及对个人生活中意义和目的的深刻感悟"
font = utils.resource_dir() + "/fonts/STHeitiMedium.ttc"
t = wrap_text(text=txt, max_width=1000, font=font, fontsize=60)
print(t)
task_id = "69232dfa-f6c5-4b5e-80ba-be3098d3f930"
task_dir = utils.task_dir(task_id)
video_file = f"{task_dir}/combined-1.mp4"
audio_file = f"{task_dir}/audio.mp3"
subtitle_file = f"{task_dir}/subtitle.srt"
output_file = f"{task_dir}/final.mp4"
cfg = VideoParams()
cfg.video_aspect = VideoAspect.portrait
cfg.font_name = "STHeitiMedium.ttc"
cfg.font_size = 60
cfg.stroke_color = "#000000"
cfg.stroke_width = 1.5
cfg.text_fore_color = "#FFFFFF"
cfg.text_background_color = "transparent"
cfg.bgm_file = ""
cfg.bgm_volume = 0.2
cfg.subtitle_enabled = True
cfg.subtitle_position = "bottom"
cfg.n_threads = 2
cfg.paragraph_number = 1
generate_video(video_path=video_file,
audio_path=audio_file,
subtitle_path=subtitle_file,
output_file=output_file,
params=cfg
)