From db56f1da6257b241dc7af000ec2e134f301ca0d2 Mon Sep 17 00:00:00 2001 From: flt6 <1404262047@qq.com> Date: Sun, 11 Jan 2026 13:19:56 +0800 Subject: [PATCH] update VideoCompress --- VideoCompress/config.json | 8 ++++---- VideoCompress/main.py | 41 ++++++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/VideoCompress/config.json b/VideoCompress/config.json index 4c61e34..afa3138 100644 --- a/VideoCompress/config.json +++ b/VideoCompress/config.json @@ -1,9 +1,9 @@ { "save_to": "single", - "crf": 18, - "bitrate": null, - "codec": "h264", - "hwaccel": null, + "crf": null, + "bitrate": "15M", + "codec": "h264_qsv", + "hwaccel": "qsv", "extra": [], "ffmpeg": "ffmpeg", "ffprobe": "ffprobe", diff --git a/VideoCompress/main.py b/VideoCompress/main.py index 60e0889..82e8543 100644 --- a/VideoCompress/main.py +++ b/VideoCompress/main.py @@ -7,7 +7,6 @@ from datetime import datetime from time import time from rich.logging import RichHandler from rich.progress import Progress -from rich.console import Console from pickle import dumps, loads from typing import Optional, Callable, Literal, List, Any, TYPE_CHECKING import atexit @@ -15,6 +14,7 @@ import re import get_frame import json import argparse +import shutil try: from pydantic import BaseModel, Field, field_validator, model_validator @@ -171,6 +171,7 @@ else: except Exception as e: logging.warning("Failed to create config file.", exc_info=e) +current_running_file:Optional[Path] = None def get_cmd(video_path: str | Path, output_file: str | Path) -> list[str]: if isinstance(video_path, Path): @@ -289,6 +290,7 @@ def process_video( compress_dir: Optional[Path] = None, update_func: Optional[Callable[[Optional[int], Optional[str]], None]] = None, ): + global current_running_file if compress_dir is None: # 在视频文件所在目录下创建 compress 子目录(如果不存在) @@ -308,6 +310,7 @@ def process_video( video_path_str = str(video_path.absolute()) command = get_cmd(video_path_str, output_file) + current_running_file = output_file try: result = subprocess.Popen( @@ -340,6 +343,8 @@ def process_video( match = re.search(r"[\d\.]+x", line) rate = match.group(0) if match else None update_func(frame_number, rate) + + current_running_file = None if result.returncode != 0: logging.error( @@ -392,7 +397,15 @@ def process_video( logging.error("重试仍然失败。") return False else: - logging.debug(f"文件处理成功: {video_path_str} -> {output_file}") + if video_path.stat().st_size <= output_file.stat().st_size: + logging.info( + f"压缩后文件比原文件大,直接复制原文件: {video_path_str}" + ) + output_file.unlink(missing_ok=True) + shutil.copy2(video_path, output_file) + return True + else: + logging.debug(f"文件处理成功: {video_path_str} -> {output_file}") except KeyboardInterrupt as e: raise e @@ -401,6 +414,9 @@ def process_video( f"执行 ffmpeg 命令时发生异常, 文件:{str(video_path_str)},cmd={' '.join(map(str,command))}", exc_info=e, ) + if current_running_file is not None: + current_running_file.unlink(missing_ok=True) + current_running_file = None return False return True @@ -578,12 +594,27 @@ def exit_pause(): elif os.name == "posix": os.system("read -p 'Press Enter to continue...'") +def finalize(): + global current_running_file + if current_running_file is not None: + try: + current_running_file.unlink(missing_ok=True) + except Exception as e: + try: + logging.error( + "Failed to delete incomplete output file after keyboard interrupt. CHECK IF LAST PROCSSING VIDEO IS COMPLETED", + exc_info=e, + ) + except Exception: + print("Failed to delete incomplete output file after keyboard interrupt. CHECK IF LAST PROCSSING VIDEO IS COMPLETED") + current_running_file = None def main(_root=None): atexit.register(exit_pause) + atexit.register(finalize) - global root + global root, current_running_file if _root is not None: setup_logging() @@ -623,11 +654,11 @@ def main(_root=None): logging.info("Normal termination of Video Compress.") except KeyboardInterrupt: logging.warning( - "Error termination via keyboard interrupt, CHECK IF LAST PROCSSING VIDEO IS COMPLETED." + "Error termination via keyboard interrupt." ) except Exception as e: logging.error( - "Error termination via unhandled error, CHECK IF LAST PROCSSING VIDEO IS COMPLETED.", + "Error termination via unhandled error", exc_info=e, )