Upload utils.py
Browse files
utils.py
CHANGED
@@ -5,10 +5,17 @@ import requests
|
|
5 |
from loguru import logger
|
6 |
from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip
|
7 |
|
|
|
|
|
|
|
|
|
8 |
# Đường dẫn đầy đủ tới các file
|
9 |
-
video_file = "input/video.mp4"
|
10 |
-
bgm_file = "data/bg_music.mp3"
|
11 |
-
output_path = "output/final_video.mp4"
|
|
|
|
|
|
|
12 |
|
13 |
video = VideoFileClip(video_file)
|
14 |
bgm = AudioFileClip(bgm_file).subclip(0, video.duration)
|
@@ -17,10 +24,10 @@ final_video = video.set_audio(final_audio)
|
|
17 |
final_video.write_videofile(output_path, audio_codec="aac")
|
18 |
|
19 |
def get_pexels_video(query):
|
20 |
-
"""
|
21 |
-
Lấy video từ Pexels API dựa trên query.
|
22 |
-
"""
|
23 |
api_key = os.getenv('Pexels_API_KEY')
|
|
|
|
|
|
|
24 |
url = f"https://api.pexels.com/videos/search?query={query}&per_page=30"
|
25 |
headers = {"Authorization": api_key}
|
26 |
response = requests.get(url, headers=headers)
|
@@ -28,12 +35,10 @@ def get_pexels_video(query):
|
|
28 |
data = response.json()
|
29 |
if data['videos']:
|
30 |
return random.choice(data['videos'])['video_files'][0]['link']
|
|
|
31 |
return None
|
32 |
|
33 |
def download_video(url, save_path="downloaded_video.mp4"):
|
34 |
-
"""
|
35 |
-
Tải video từ URL và lưu vào tệp cục bộ.
|
36 |
-
"""
|
37 |
try:
|
38 |
response = requests.get(url, stream=True)
|
39 |
response.raise_for_status()
|
@@ -46,14 +51,11 @@ def download_video(url, save_path="downloaded_video.mp4"):
|
|
46 |
return None
|
47 |
|
48 |
def get_bgm_file(bgm_type: str = "random", bgm_file: str = ""):
|
49 |
-
"""
|
50 |
-
Lấy file nhạc nền.
|
51 |
-
"""
|
52 |
if not bgm_type:
|
53 |
return ""
|
54 |
if bgm_type == "random":
|
55 |
suffix = "*.mp3"
|
56 |
-
song_dir = "/data/bg-music"
|
57 |
files = glob.glob(os.path.join(song_dir, suffix))
|
58 |
return random.choice(files) if files else ""
|
59 |
|
@@ -63,9 +65,9 @@ def get_bgm_file(bgm_type: str = "random", bgm_file: str = ""):
|
|
63 |
return ""
|
64 |
|
65 |
def add_background_music(video_path, bgm_file, output_path="video_with_bgm.mp4"):
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
video = VideoFileClip(video_path)
|
70 |
bgm = AudioFileClip(bgm_file).subclip(0, video.duration)
|
71 |
final_audio = CompositeAudioClip([video.audio, bgm])
|
@@ -79,9 +81,8 @@ def combine_videos(combined_video_path: str,
|
|
79 |
max_clip_duration: int = 5,
|
80 |
threads: int = 2,
|
81 |
) -> str:
|
82 |
-
|
83 |
-
|
84 |
-
"""
|
85 |
audio_clip = AudioFileClip(audio_file)
|
86 |
audio_duration = audio_clip.duration
|
87 |
logger.info(f"Max duration of audio: {audio_duration} seconds")
|
@@ -93,8 +94,8 @@ def combine_videos(combined_video_path: str,
|
|
93 |
random.shuffle(video_paths)
|
94 |
|
95 |
for video_path in video_paths:
|
|
|
96 |
clip = VideoFileClip(video_path).without_audio()
|
97 |
-
# Cắt video nếu dài hơn thời lượng tối đa
|
98 |
if (audio_duration - video_duration) < clip.duration:
|
99 |
clip = clip.subclip(0, (audio_duration - video_duration))
|
100 |
elif max_clip_duration < clip.duration:
|
@@ -114,9 +115,6 @@ def generate_video(video_paths: list[str],
|
|
114 |
audio_path: str,
|
115 |
output_file: str,
|
116 |
) -> str:
|
117 |
-
"""
|
118 |
-
Tạo video cuối cùng bằng cách kết hợp video và âm thanh.
|
119 |
-
"""
|
120 |
logger.info(f"Start generating video")
|
121 |
combined_video_path = "temp_combined_video.mp4"
|
122 |
|
|
|
5 |
from loguru import logger
|
6 |
from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip
|
7 |
|
8 |
+
def check_file_exists(file_path):
|
9 |
+
if not os.path.exists(file_path):
|
10 |
+
raise FileNotFoundError(f"Tệp {file_path} không tồn tại.")
|
11 |
+
|
12 |
# Đường dẫn đầy đủ tới các file
|
13 |
+
video_file = "input/video.mp4"
|
14 |
+
bgm_file = "data/bg_music.mp3"
|
15 |
+
output_path = "output/final_video.mp4"
|
16 |
+
|
17 |
+
check_file_exists(video_file)
|
18 |
+
check_file_exists(bgm_file)
|
19 |
|
20 |
video = VideoFileClip(video_file)
|
21 |
bgm = AudioFileClip(bgm_file).subclip(0, video.duration)
|
|
|
24 |
final_video.write_videofile(output_path, audio_codec="aac")
|
25 |
|
26 |
def get_pexels_video(query):
|
|
|
|
|
|
|
27 |
api_key = os.getenv('Pexels_API_KEY')
|
28 |
+
if not api_key:
|
29 |
+
raise ValueError("API key không được tìm thấy trong biến môi trường.")
|
30 |
+
|
31 |
url = f"https://api.pexels.com/videos/search?query={query}&per_page=30"
|
32 |
headers = {"Authorization": api_key}
|
33 |
response = requests.get(url, headers=headers)
|
|
|
35 |
data = response.json()
|
36 |
if data['videos']:
|
37 |
return random.choice(data['videos'])['video_files'][0]['link']
|
38 |
+
logger.error("Không tìm thấy video nào.")
|
39 |
return None
|
40 |
|
41 |
def download_video(url, save_path="downloaded_video.mp4"):
|
|
|
|
|
|
|
42 |
try:
|
43 |
response = requests.get(url, stream=True)
|
44 |
response.raise_for_status()
|
|
|
51 |
return None
|
52 |
|
53 |
def get_bgm_file(bgm_type: str = "random", bgm_file: str = ""):
|
|
|
|
|
|
|
54 |
if not bgm_type:
|
55 |
return ""
|
56 |
if bgm_type == "random":
|
57 |
suffix = "*.mp3"
|
58 |
+
song_dir = "/data/bg-music"
|
59 |
files = glob.glob(os.path.join(song_dir, suffix))
|
60 |
return random.choice(files) if files else ""
|
61 |
|
|
|
65 |
return ""
|
66 |
|
67 |
def add_background_music(video_path, bgm_file, output_path="video_with_bgm.mp4"):
|
68 |
+
check_file_exists(video_path)
|
69 |
+
check_file_exists(bgm_file)
|
70 |
+
|
71 |
video = VideoFileClip(video_path)
|
72 |
bgm = AudioFileClip(bgm_file).subclip(0, video.duration)
|
73 |
final_audio = CompositeAudioClip([video.audio, bgm])
|
|
|
81 |
max_clip_duration: int = 5,
|
82 |
threads: int = 2,
|
83 |
) -> str:
|
84 |
+
check_file_exists(audio_file)
|
85 |
+
|
|
|
86 |
audio_clip = AudioFileClip(audio_file)
|
87 |
audio_duration = audio_clip.duration
|
88 |
logger.info(f"Max duration of audio: {audio_duration} seconds")
|
|
|
94 |
random.shuffle(video_paths)
|
95 |
|
96 |
for video_path in video_paths:
|
97 |
+
check_file_exists(video_path)
|
98 |
clip = VideoFileClip(video_path).without_audio()
|
|
|
99 |
if (audio_duration - video_duration) < clip.duration:
|
100 |
clip = clip.subclip(0, (audio_duration - video_duration))
|
101 |
elif max_clip_duration < clip.duration:
|
|
|
115 |
audio_path: str,
|
116 |
output_file: str,
|
117 |
) -> str:
|
|
|
|
|
|
|
118 |
logger.info(f"Start generating video")
|
119 |
combined_video_path = "temp_combined_video.mp4"
|
120 |
|