提交必要文件
This commit is contained in:
+150
@@ -0,0 +1,150 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
DEFAULT_TEST_TXT = """# 频道,URL
|
||||
# 示例:
|
||||
# CCTV-1,http://example.com/live/index.m3u8
|
||||
"""
|
||||
|
||||
DEFAULT_PASS_TEST_TXT = "# channel,url\n"
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class RuntimePaths:
|
||||
app_dir: Path
|
||||
settings_file: Path
|
||||
test_file: Path
|
||||
pass_test_file: Path
|
||||
input_dir: Path
|
||||
output_dir: Path
|
||||
logs_dir: Path
|
||||
reports_dir: Path
|
||||
del_line_dir: Path
|
||||
download_dir: Path
|
||||
|
||||
|
||||
def get_runtime_dir() -> Path:
|
||||
if getattr(sys, "frozen", False):
|
||||
return Path(sys.executable).resolve().parent
|
||||
return Path(__file__).resolve().parent
|
||||
|
||||
|
||||
def get_runtime_paths() -> RuntimePaths:
|
||||
app_dir = get_runtime_dir()
|
||||
return RuntimePaths(
|
||||
app_dir=app_dir,
|
||||
settings_file=app_dir / "videoconvert_settings.json",
|
||||
test_file=app_dir / "test.txt",
|
||||
pass_test_file=app_dir / "pass_test.txt",
|
||||
input_dir=app_dir / "input",
|
||||
output_dir=app_dir / "output",
|
||||
logs_dir=app_dir / "logs",
|
||||
reports_dir=app_dir / "reports",
|
||||
del_line_dir=app_dir / "delLine",
|
||||
download_dir=app_dir / "download",
|
||||
)
|
||||
|
||||
|
||||
def build_default_settings(paths: RuntimePaths) -> dict:
|
||||
cpu_count = 8
|
||||
try:
|
||||
import os
|
||||
|
||||
cpu_count = os.cpu_count() or 8
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return {
|
||||
"probe_input_file": str(paths.test_file),
|
||||
"probe_output_file": str(paths.pass_test_file),
|
||||
"probe_workers": min(96, max(24, cpu_count * 2)),
|
||||
"probe_host_limit": 3,
|
||||
"probe_timeout": 8.0,
|
||||
"probe_min_speed": 400.0,
|
||||
"probe_sample_bytes": 384,
|
||||
"probe_sample_segments": 3,
|
||||
"probe_ffmpeg_fallback": True,
|
||||
"convert_root_dir": str(paths.app_dir),
|
||||
"convert_parallel_jobs": min(4, max(2, (cpu_count + 2) // 6)),
|
||||
"convert_resolution": "1280:720",
|
||||
"convert_video_bitrate": "0",
|
||||
"convert_audio_bitrate": "96k",
|
||||
"convert_hls_time": 10,
|
||||
"convert_preset": "p3",
|
||||
"convert_episode_mode": False,
|
||||
"shuffle_file": str(paths.pass_test_file),
|
||||
"shuffle_keep_header": True,
|
||||
"trim_dir": str(paths.del_line_dir),
|
||||
"trim_remove_segments": 40,
|
||||
"trim_min_segments": 120,
|
||||
"trim_recursive": True,
|
||||
}
|
||||
|
||||
|
||||
def _ensure_text_file(path: Path, content: str) -> None:
|
||||
if not path.exists():
|
||||
path.write_text(content, encoding="utf-8")
|
||||
|
||||
|
||||
def ensure_runtime_workspace() -> RuntimePaths:
|
||||
paths = get_runtime_paths()
|
||||
for directory in (
|
||||
paths.app_dir,
|
||||
paths.input_dir,
|
||||
paths.output_dir,
|
||||
paths.logs_dir,
|
||||
paths.reports_dir,
|
||||
paths.del_line_dir,
|
||||
paths.download_dir,
|
||||
):
|
||||
directory.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
_ensure_text_file(paths.test_file, DEFAULT_TEST_TXT)
|
||||
_ensure_text_file(paths.pass_test_file, DEFAULT_PASS_TEST_TXT)
|
||||
|
||||
if not paths.settings_file.exists():
|
||||
defaults = build_default_settings(paths)
|
||||
paths.settings_file.write_text(json.dumps(defaults, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
|
||||
return paths
|
||||
|
||||
|
||||
def initialize_runtime_workspace() -> dict[str, object]:
|
||||
paths = ensure_runtime_workspace()
|
||||
created = {
|
||||
"app_dir": str(paths.app_dir),
|
||||
"settings_file": str(paths.settings_file),
|
||||
"test_file": str(paths.test_file),
|
||||
"pass_test_file": str(paths.pass_test_file),
|
||||
"input_dir": str(paths.input_dir),
|
||||
"output_dir": str(paths.output_dir),
|
||||
"logs_dir": str(paths.logs_dir),
|
||||
"reports_dir": str(paths.reports_dir),
|
||||
"del_line_dir": str(paths.del_line_dir),
|
||||
"download_dir": str(paths.download_dir),
|
||||
}
|
||||
return created
|
||||
|
||||
|
||||
def load_settings_with_defaults(paths: RuntimePaths | None = None) -> dict:
|
||||
runtime_paths = paths or ensure_runtime_workspace()
|
||||
defaults = build_default_settings(runtime_paths)
|
||||
|
||||
if runtime_paths.settings_file.exists():
|
||||
try:
|
||||
loaded = json.loads(runtime_paths.settings_file.read_text(encoding="utf-8"))
|
||||
defaults.update(loaded)
|
||||
except Exception:
|
||||
pass
|
||||
return defaults
|
||||
|
||||
|
||||
def save_settings(paths: RuntimePaths, data: dict) -> None:
|
||||
merged = build_default_settings(paths)
|
||||
merged.update(data)
|
||||
paths.settings_file.write_text(json.dumps(merged, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
Reference in New Issue
Block a user