File size: 4,853 Bytes
1e06115 d48fce1 1e06115 4471c86 1e06115 4471c86 1e06115 4471c86 1e06115 4471c86 1e06115 d76c658 d48fce1 d76c658 d48fce1 d76c658 1e06115 4471c86 1e06115 d76c658 1e06115 4471c86 1e06115 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
import glob
import os
import random
import requests
from loguru import logger
from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip
# Đường dẫn đầy đủ tới các file
video_file = "input/video.mp4" # Đảm bảo có tên file và định dạng
bgm_file = "data/bg_music.mp3" # Đảm bảo có tên file và định dạng
output_path = "output/final_video.mp4" # Đảm bảo có tên file và định dạng
video = VideoFileClip(video_file)
bgm = AudioFileClip(bgm_file).subclip(0, video.duration)
final_audio = CompositeAudioClip([video.audio, bgm])
final_video = video.set_audio(final_audio)
final_video.write_videofile(output_path, audio_codec="aac")
def get_pexels_video(query):
"""
Lấy video từ Pexels API dựa trên query.
"""
api_key = os.getenv('Pexels_API_KEY')
url = f"https://api.pexels.com/videos/search?query={query}&per_page=30"
headers = {"Authorization": api_key}
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
if data['videos']:
return random.choice(data['videos'])['video_files'][0]['link']
return None
def download_video(url, save_path="downloaded_video.mp4"):
"""
Tải video từ URL và lưu vào tệp cục bộ.
"""
try:
response = requests.get(url, stream=True)
response.raise_for_status()
with open(save_path, 'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
f.write(chunk)
return save_path
except requests.exceptions.RequestException as e:
logger.error(f"Failed to download video from {url}: {e}")
return None
def get_bgm_file(bgm_type: str = "random", bgm_file: str = ""):
"""
Lấy file nhạc nền.
"""
if not bgm_type:
return ""
if bgm_type == "random":
suffix = "*.mp3"
song_dir = "/data/bg-music" # Thay thế bằng đường dẫn thực tế
files = glob.glob(os.path.join(song_dir, suffix))
return random.choice(files) if files else ""
if os.path.exists(bgm_file):
return bgm_file
return ""
def add_background_music(video_path, bgm_file, output_path="video_with_bgm.mp4"):
"""
Thêm nhạc nền vào video.
"""
video = VideoFileClip(video_path)
bgm = AudioFileClip(bgm_file).subclip(0, video.duration)
final_audio = CompositeAudioClip([video.audio, bgm])
final_video = video.set_audio(final_audio)
final_video.write_videofile(output_path, audio_codec="aac")
return output_path
def combine_videos(combined_video_path: str,
video_paths: list[str],
audio_file: str,
max_clip_duration: int = 5,
threads: int = 2,
) -> str:
"""
Kết hợp nhiều video thành một video duy nhất.
"""
audio_clip = AudioFileClip(audio_file)
audio_duration = audio_clip.duration
logger.info(f"Max duration of audio: {audio_duration} seconds")
clips = []
video_duration = 0
while video_duration < audio_duration:
random.shuffle(video_paths)
for video_path in video_paths:
clip = VideoFileClip(video_path).without_audio()
# Cắt video nếu dài hơn thời lượng tối đa
if (audio_duration - video_duration) < clip.duration:
clip = clip.subclip(0, (audio_duration - video_duration))
elif max_clip_duration < clip.duration:
clip = clip.subclip(0, max_clip_duration)
clip = clip.set_fps(30)
clips.append(clip)
video_duration += clip.duration
final_clip = concatenate_videoclips(clips)
final_clip = final_clip.set_fps(30)
logger.info(f"Writing combined video to {combined_video_path}")
final_clip.write_videofile(combined_video_path, threads=threads)
logger.success(f"Completed combining videos")
return combined_video_path
def generate_video(video_paths: list[str],
audio_path: str,
output_file: str,
) -> str:
"""
Tạo video cuối cùng bằng cách kết hợp video và âm thanh.
"""
logger.info(f"Start generating video")
combined_video_path = "temp_combined_video.mp4"
combine_videos(combined_video_path, video_paths, audio_path)
final_video = VideoFileClip(combined_video_path)
audio_clip = AudioFileClip(audio_path)
final_video = final_video.set_audio(audio_clip)
logger.info(f"Writing final video to {output_file}")
final_video.write_videofile(output_file, audio_codec="aac")
os.remove(combined_video_path)
logger.success(f"Completed generating video: {output_file}")
return output_file |