chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
import logging
|
||||
import requests
|
||||
from moviepy import VideoFileClip, concatenate_videoclips
|
||||
from utils.retry import download_retry
|
||||
|
||||
|
||||
@download_retry
|
||||
def download_video(url, save_path):
|
||||
try:
|
||||
logging.info(f"Downloading video from {url} to {save_path}")
|
||||
|
||||
response = requests.get(url, stream=True, timeout=(10, 300))
|
||||
response.raise_for_status() # 检查请求是否成功
|
||||
|
||||
with open(save_path, 'wb') as f:
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
|
||||
logging.info(f"Video downloaded successfully to {save_path}")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error downloading video: {e}")
|
||||
raise e
|
||||
|
||||
|
||||
def concatenate_video_files(video_paths, output_path, codec="libx264", preset="medium"):
|
||||
"""Concatenate video files, releasing every ffmpeg reader even on failure.
|
||||
|
||||
Each VideoFileClip keeps an ffmpeg subprocess and file handle open until
|
||||
closed; leaking them exhausts file descriptors on long multi-scene runs.
|
||||
"""
|
||||
clips = []
|
||||
final = None
|
||||
try:
|
||||
for path in video_paths:
|
||||
clips.append(VideoFileClip(path))
|
||||
final = concatenate_videoclips(clips)
|
||||
final.write_videofile(output_path, codec=codec, preset=preset)
|
||||
finally:
|
||||
if final is not None:
|
||||
final.close()
|
||||
for clip in clips:
|
||||
clip.close()
|
||||
return output_path
|
||||
Reference in New Issue
Block a user