mirror of
https://github.com/linyqh/NarratoAI.git
synced 2025-12-12 19:52:48 +00:00
fix(video_processor_v2): 优化视频处理流程并添加异常处理- 在提取关键帧时添加 tqdm 进度条
- 移除不必要的空行和多余的换行符 - 添加异常捕获和详细的错误日志记录 -优化临时文件清理逻辑,增加重试机制 - 释放资源,包括视频文件句柄和临时对象
This commit is contained in:
parent
3d4a58e5cf
commit
97c3ed1fbe
@ -83,7 +83,7 @@ class VideoProcessor:
|
|||||||
keyframes = []
|
keyframes = []
|
||||||
keyframe_indices = []
|
keyframe_indices = []
|
||||||
|
|
||||||
for i in range(len(shot_boundaries)):
|
for i in tqdm(range(len(shot_boundaries)), desc="提取关键帧"):
|
||||||
start = shot_boundaries[i - 1] if i > 0 else 0
|
start = shot_boundaries[i - 1] if i > 0 else 0
|
||||||
end = shot_boundaries[i]
|
end = shot_boundaries[i]
|
||||||
shot_frames = frames[start:end]
|
shot_frames = frames[start:end]
|
||||||
@ -217,11 +217,10 @@ class VideoProcessor:
|
|||||||
if not frames:
|
if not frames:
|
||||||
raise ValueError(f"跳过 {skip_seconds} 秒后没有剩余帧可以处理")
|
raise ValueError(f"跳过 {skip_seconds} 秒后没有剩余帧可以处理")
|
||||||
|
|
||||||
logger.info("\n检测场景边界...")
|
logger.info("检测场景边界...")
|
||||||
shot_boundaries = self.detect_shot_boundaries(frames, threshold)
|
shot_boundaries = self.detect_shot_boundaries(frames, threshold)
|
||||||
logger.info(f"检测到 {len(shot_boundaries)} 个场景边界")
|
logger.info(f"检测到 {len(shot_boundaries)} 个场景边界")
|
||||||
|
|
||||||
logger.info("\n提取关键帧...")
|
|
||||||
keyframes, keyframe_indices = self.extract_keyframes(frames, shot_boundaries)
|
keyframes, keyframe_indices = self.extract_keyframes(frames, shot_boundaries)
|
||||||
|
|
||||||
adjusted_indices = [idx + skip_frames for idx in keyframe_indices]
|
adjusted_indices = [idx + skip_frames for idx in keyframe_indices]
|
||||||
@ -247,6 +246,9 @@ class VideoProcessor:
|
|||||||
os.makedirs(mini_frames_dir, exist_ok=True)
|
os.makedirs(mini_frames_dir, exist_ok=True)
|
||||||
os.makedirs(hd_frames_dir, exist_ok=True)
|
os.makedirs(hd_frames_dir, exist_ok=True)
|
||||||
|
|
||||||
|
mini_processor = None
|
||||||
|
compressed_video = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 1. 压缩视频
|
# 1. 压缩视频
|
||||||
video_name = os.path.splitext(os.path.basename(self.video_path))[0]
|
video_name = os.path.splitext(os.path.basename(self.video_path))[0]
|
||||||
@ -268,20 +270,61 @@ class VideoProcessor:
|
|||||||
|
|
||||||
# 3. 从原始视频提取高清关键帧
|
# 3. 从原始视频提取高清关键帧
|
||||||
logger.info("\n步骤3: 提取高清关键帧...")
|
logger.info("\n步骤3: 提取高清关键帧...")
|
||||||
frame_numbers = mini_processor.extract_numbers_from_folder(mini_frames_dir)
|
frame_numbers = self.extract_numbers_from_folder(mini_frames_dir)
|
||||||
|
|
||||||
|
if not frame_numbers:
|
||||||
|
raise ValueError("未能从压缩视频中提取到有效的关键帧")
|
||||||
|
|
||||||
self.extract_frames_by_numbers(frame_numbers, hd_frames_dir)
|
self.extract_frames_by_numbers(frame_numbers, hd_frames_dir)
|
||||||
|
|
||||||
logger.info(f"\n处理完成!")
|
logger.info(f"处理完成!高清关键帧保存在: {hd_frames_dir}")
|
||||||
logger.info(f"高清关键帧保存在: {hd_frames_dir}")
|
|
||||||
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
|
logger.error(f"视频处理失败: \n{traceback.format_exc()}")
|
||||||
|
raise
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
# 释放资源
|
||||||
|
if mini_processor:
|
||||||
|
mini_processor.cap.release()
|
||||||
|
del mini_processor
|
||||||
|
|
||||||
|
# 确保视频文件句柄被释放
|
||||||
|
if hasattr(self, 'cap'):
|
||||||
|
self.cap.release()
|
||||||
|
|
||||||
|
# 等待资源释放
|
||||||
|
import time
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
if not keep_temp:
|
if not keep_temp:
|
||||||
|
try:
|
||||||
|
# 先删除压缩视频文件
|
||||||
|
if compressed_video and os.path.exists(compressed_video):
|
||||||
|
try:
|
||||||
|
os.remove(compressed_video)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"删除压缩视频失败: {e}")
|
||||||
|
|
||||||
|
# 再删除临时目录
|
||||||
import shutil
|
import shutil
|
||||||
|
if os.path.exists(temp_dir):
|
||||||
|
max_retries = 3
|
||||||
|
for i in range(max_retries):
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(temp_dir)
|
shutil.rmtree(temp_dir)
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
if i == max_retries - 1:
|
||||||
|
logger.warning(f"清理临时文件失败: {e}")
|
||||||
|
else:
|
||||||
|
time.sleep(1) # 等待1秒后重试
|
||||||
|
continue
|
||||||
|
|
||||||
logger.info("临时文件已清理")
|
logger.info("临时文件已清理")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(f"清理临时文件时出错: {e}")
|
logger.warning(f"清理临时文件时出错: {e}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user