Skip to content

Commit c7dc912

Browse files
authored
Merge pull request #496 from OpenTrafficCam/feature/8704-download-files-from-file-server-via-ftp-in-otvision-remote-worker
Feature/8704 download files from file server via ftp in otvision remote worker
2 parents 9c7037a + b3e4426 commit c7dc912

2 files changed

Lines changed: 105 additions & 3 deletions

File tree

OTVision/application/config_parser.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@
7373
_UndistortConfig,
7474
)
7575
from OTVision.domain.serialization import Deserializer
76+
from OTVision.plugin.ffmpeg_video_writer import (
77+
ConstantRateFactor,
78+
EncodingSpeed,
79+
VideoCodec,
80+
)
7681

7782

7883
class InvalidOtvisionConfigError(Exception):
@@ -190,6 +195,21 @@ def parse_detect_config(self, data: dict) -> DetectConfig:
190195
if expected_duration is not None:
191196
expected_duration = timedelta(seconds=int(expected_duration))
192197

198+
if video_codec := data.get(VIDEO_CODEC, None):
199+
video_codec = VideoCodec(video_codec)
200+
else:
201+
video_codec = DetectConfig.video_codec
202+
203+
if encoding_speed := data.get(ENCODING_SPEED, None):
204+
encoding_speed = EncodingSpeed(encoding_speed)
205+
else:
206+
encoding_speed = DetectConfig.encoding_speed
207+
208+
if data.get(CRF, None) is not None:
209+
crf = ConstantRateFactor[data[CRF]]
210+
else:
211+
crf = DetectConfig.crf
212+
193213
start_time = self._parse_start_time(data)
194214
return DetectConfig(
195215
paths=sources,
@@ -202,9 +222,9 @@ def parse_detect_config(self, data: dict) -> DetectConfig:
202222
detect_start=data.get(DETECT_START, DetectConfig.detect_start),
203223
detect_end=data.get(DETECT_END, DetectConfig.detect_end),
204224
write_video=data.get(WRITE_VIDEO, DetectConfig.write_video),
205-
video_codec=data.get(VIDEO_CODEC, DetectConfig.video_codec),
206-
encoding_speed=data.get(ENCODING_SPEED, DetectConfig.encoding_speed),
207-
crf=data.get(CRF, DetectConfig.crf),
225+
video_codec=video_codec,
226+
encoding_speed=encoding_speed,
227+
crf=crf,
208228
)
209229

210230
def parse_yolo_config(self, data: dict) -> YoloConfig:

tests/application/test_config_parser.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,97 @@
1+
from datetime import datetime, timedelta
12
from pathlib import Path
23
from unittest.mock import Mock
34

45
import pytest
56

67
from OTVision.application.config import (
78
Config,
9+
DetectConfig,
810
StreamConfig,
911
TrackConfig,
12+
YoloConfig,
1013
_TrackIouConfig,
1114
)
1215
from OTVision.application.config_parser import ConfigParser, InvalidOtvisionConfigError
16+
from OTVision.plugin.ffmpeg_video_writer import (
17+
ConstantRateFactor,
18+
EncodingSpeed,
19+
VideoCodec,
20+
)
21+
22+
# Ensure paths are translated to the respective platform (unix, windows)
23+
VIDEO_1 = str(Path("tests/data/video1.mp4"))
24+
VIDEO_2 = str(Path("tests/data/video2.mp4"))
25+
26+
27+
class TestConfigParser:
28+
@pytest.fixture
29+
def given_deserializer(self) -> Mock:
30+
return Mock()
31+
32+
@pytest.fixture
33+
def given_config_parser(self, given_deserializer: Mock) -> ConfigParser:
34+
return ConfigParser(given_deserializer)
35+
36+
def test_parse_detect_config_with_fully_specified_config(
37+
self, given_config_parser: ConfigParser
38+
) -> None:
39+
detect_dict = {
40+
"PATHS": [VIDEO_1, VIDEO_2],
41+
"RUN_CHAINED": False,
42+
"YOLO": {
43+
"WEIGHTS": "yolov8m.pt",
44+
"CONF": 0.35,
45+
"IOU": 0.5,
46+
"IMGSIZE": 1280,
47+
"NORMALIZED": False,
48+
},
49+
"EXPECTED_DURATION": 3600,
50+
"OVERWRITE": False,
51+
"HALF_PRECISION": True,
52+
"START_TIME": "2025-10-15_14-30-00",
53+
"DETECT_START": 10,
54+
"DETECT_END": 100,
55+
"WRITE_VIDEO": True,
56+
"VIDEO_CODEC": "h264_nvenc",
57+
"ENCODING_SPEED": "medium",
58+
"CRF": "HIGH_QUALITY",
59+
}
60+
61+
result = given_config_parser.parse_detect_config(detect_dict)
62+
63+
expected = DetectConfig(
64+
paths=[VIDEO_1, VIDEO_2],
65+
run_chained=False,
66+
yolo_config=YoloConfig(
67+
weights="yolov8m.pt",
68+
conf=0.35,
69+
iou=0.5,
70+
img_size=1280,
71+
normalized=False,
72+
),
73+
expected_duration=timedelta(seconds=3600),
74+
overwrite=False,
75+
half_precision=True,
76+
start_time=datetime(2025, 10, 15, 14, 30, 0),
77+
detect_start=10,
78+
detect_end=100,
79+
write_video=True,
80+
video_codec=VideoCodec.H264_NVENC,
81+
encoding_speed=EncodingSpeed.MEDIUM,
82+
crf=ConstantRateFactor.HIGH_QUALITY,
83+
)
84+
assert result == expected
85+
86+
def test_parse_detect_config_with_empty_config(
87+
self, given_config_parser: ConfigParser
88+
) -> None:
89+
detect_dict: dict = {}
90+
91+
result = given_config_parser.parse_detect_config(detect_dict)
92+
93+
expected = DetectConfig()
94+
assert result == expected
1395

1496

1597
class TestConfigParserValidateFlushBufferSupportTrackLifecycle:

0 commit comments

Comments
 (0)