intial commit

This commit is contained in:
zakariasaputra committed 2026-07-17 14:58:29 +07:00
commit a54a070ca9
49 files changed
+2960

No files matched your search

+111
View File
@@ -0,0 +1,111 @@
"""Run CC1–CC4 sequentially, then compress videos and write the JSON report."""
from __future__ import annotations
from datetime import date as date_type
from pathlib import Path
from chicken_counter.batch_discovery import discover_camera_videos
from chicken_counter.compress import compress_video_to_target
from chicken_counter.config import BatchSettings, build_camera_config_from_batch
from chicken_counter.pipeline import run_pipeline
from chicken_counter.report import build_batch_report, persist_batch_reports
from chicken_counter.tracking import DetectionTracker
from chicken_counter.types import CameraBatchResult
def run_daily_batch(settings: BatchSettings, date: str | None = None) -> Path:
run_date = date or date_type.today().isoformat()
day_dir = Path(settings.batch.root_dir) / run_date
output_dir = day_dir / settings.batch.output_subdir
output_dir.mkdir(parents=True, exist_ok=True)
print(f"[batch] starting daily run for {run_date}")
print(f"[batch] input folder: {day_dir}")
print(f"[batch] output folder: {output_dir}")
discovery = discover_camera_videos(day_dir, settings)
camera_order = sorted(settings.cameras.items(), key=lambda item: item[1].camera_num)
first_camera_id = next(
camera_id for camera_id, _preset in camera_order if camera_id in discovery.found
)
first_source = discovery.found[first_camera_id]
init_config = build_camera_config_from_batch(
settings,
first_camera_id,
source=first_source,
output_path=output_dir / f"{first_camera_id}_vis.mp4",
checkpoint_dir=output_dir / "checkpoints" / first_camera_id,
)
shared_tracker = DetectionTracker(init_config)
camera_results: list[CameraBatchResult] = []
report_path = output_dir / f"counts_{run_date}.json"
for camera_id, _preset in camera_order:
if camera_id in discovery.skipped:
skip_reason = discovery.skipped[camera_id]
print(f"[batch] skipping {camera_id}: {skip_reason}")
camera_results.append(
CameraBatchResult(
camera_id=camera_id,
skipped=True,
skip_reason=skip_reason,
)
)
persist_batch_reports(run_date, camera_results, output_dir)
continue
source_path = discovery.found[camera_id]
vis_path = output_dir / f"{camera_id}_vis.mp4"
checkpoint_dir = output_dir / "checkpoints" / camera_id
print(f"[batch] processing {camera_id} from {source_path.name}")
camera_config = build_camera_config_from_batch(
settings,
camera_id,
source=source_path,
output_path=vis_path,
checkpoint_dir=checkpoint_dir,
)
pipeline_result = run_pipeline(camera_config, tracker=shared_tracker)
camera_results.append(
CameraBatchResult(
camera_id=camera_id,
pipeline=pipeline_result,
)
)
print(
f"[batch] finished {camera_id}: total_entered={pipeline_result.total_entered_count} "
f"frames={pipeline_result.frames_processed} reason={pipeline_result.stopped_reason}"
)
persist_batch_reports(run_date, camera_results, output_dir)
print("[batch] all cameras complete; starting compression")
for item in camera_results:
if item.skipped or item.pipeline is None:
continue
vis_path = item.pipeline.vis_video_path
if not vis_path:
continue
compressed_path = output_dir / f"{item.camera_id}_compressed.mp4"
size_mb = compress_video_to_target(
vis_path,
compressed_path,
max_mb=settings.batch.compress_max_mb,
)
item.compressed_video_path = str(compressed_path)
item.compressed_size_mb = size_mb
if settings.batch.delete_intermediate:
Path(vis_path).unlink(missing_ok=True)
persist_batch_reports(run_date, camera_results, output_dir)
report = build_batch_report(run_date, camera_results, output_dir=output_dir)
print(
f"[batch] complete for {run_date}: total_entered_sum={report.total_entered_sum} "
f"report={report_path}"
)
return report_path