返回 ViMax
video.py
根目录 / utils / video.py
1 import logging
2 import requests
3 from moviepy import VideoFileClip, concatenate_videoclips
4 from utils.retry import download_retry
5
6
7 @download_retry
8 def download_video(url, save_path):
9 try:
10 logging.info(f"Downloading video from {url} to {save_path}")
11
12 response = requests.get(url, stream=True, timeout=(10, 300))
13 response.raise_for_status() # 检查请求是否成功
14
15 with open(save_path, 'wb') as f:
16 for chunk in response.iter_content(chunk_size=8192):
17 f.write(chunk)
18
19 logging.info(f"Video downloaded successfully to {save_path}")
20
21 except Exception as e:
22 logging.error(f"Error downloading video: {e}")
23 raise e
24
25
26 def concatenate_video_files(video_paths, output_path, codec="libx264", preset="medium"):
27 """Concatenate video files, releasing every ffmpeg reader even on failure.
28
29 Each VideoFileClip keeps an ffmpeg subprocess and file handle open until
30 closed; leaking them exhausts file descriptors on long multi-scene runs.
31 """
32 clips = []
33 final = None
34 try:
35 for path in video_paths:
36 clips.append(VideoFileClip(path))
37 final = concatenate_videoclips(clips)
38 final.write_videofile(output_path, codec=codec, preset=preset)
39 finally:
40 if final is not None:
41 final.close()
42 for clip in clips:
43 clip.close()
44 return output_path
45
45 lines PYTHON