Metadata-Version: 2.4
Name: ros-streamer
Version: 0.3.0
Summary: ROS 2 카메라 이미지를 ZMQ로 스트리밍하는 뷰어 CLI (uvx로 실행 가능)
Author: wkqco33
License-Expression: Apache-2.0
Project-URL: Homepage, https://gitlab.com/wkqco33/ros-streamer
Project-URL: Repository, https://gitlab.com/wkqco33/ros-streamer
Project-URL: Issues, https://gitlab.com/wkqco33/ros-streamer/-/issues
Keywords: ros2,zmq,camera,streaming,viewer,opencv
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Video
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=2.0
Requires-Dist: opencv-python>=4.10
Requires-Dist: pyzmq>=27.1.0
Requires-Dist: wpycli>=0.3.1
Requires-Dist: wpyconf>=0.2.5
Requires-Dist: wpylog>=0.2.0
Dynamic: license-file

# ros-stream-viewer

[ROS Streamer](https://gitlab.com/wkqco33/ros-streamer) 서버가 ZMQ로 발행하는
카메라 이미지를 구독해 화면에 표시하는 CLI입니다. ROS 설치 없이 단독 실행되며,
Python 3.12+ 에서 동작합니다.

```console
# 설치 없이 실행 (권장)
uvx ros-streamer stream --host <HOST> --port 5556

# 설치
uv tool install ros-streamer    # 또는: pip install ros-streamer
ros-stream-viewer stream
```

> `ros-streamer`, `ros-stream-viewer`, `rviewer`는 동일한 실행 파일입니다.

## 빠른 시작

```console
# compressed(JPEG) 스트림 표시 (서버 base+1, 기본 5556)
ros-stream-viewer stream

# raw 스트림 표시 (서버 base, 기본 5555)
ros-stream-viewer stream --port 5555 --stream-type raw

# 창 없이 100프레임만 수신하고 JSON 요약을 stdout으로 출력 (CI/스크립트)
ros-stream-viewer stream --headless --max-frames 100 --json
```

표시 중 단축키: `i` 정보 오버레이 토글 · `p`/Space 일시정지 · `s` PNG 스냅샷 ·
`v` mp4 녹화 · `f` 전체화면 · `q`/ESC 종료.

## 주요 플래그

| 플래그 | 설명 | 기본값 |
| --- | --- | --- |
| `--host` | 서버 호스트 | `localhost` |
| `--port` | ZMQ 포트 (서버 규약: base=raw, base+1=compressed) | `5556` |
| `--stream-type` | `auto`(매직 자동 판별) / `raw` / `compressed` | `auto` |
| `--width`, `--height` | 헤더 없는 raw 스트림의 해상도 (헤더가 있으면 무시) | `640x480` |
| `--connect-timeout` | 첫 프레임 대기 시간(초). 초과 시 종료 코드 4 (`0`=무한) | `5` |
| `--stall-timeout` | 수신이 멈춘 것으로 경고할 임계(초, `0`=끄기) | `3` |
| `--max-frames`, `--duration` | N프레임/N초 후 종료 (`0`=무제한) | `0` |
| `--snapshot-dir` | `s`/`v` 저장 디렉터리 | 현재 디렉터리 |
| `--network-info` | 네트워크 정보 오버레이 (`--network-info=false`로 끔) | `true` |
| `--headless` | 창 없이 통계만 로그로 출력 | `false` |
| `--json` | 실행 요약(JSON)을 stdout으로 출력 | `false` |
| `-q`, `--quiet` / `-d`, `--debug` | 경고만 출력 / DEBUG 로그 출력 | - |
| `--config`, `--dotenv` | 설정 파일 / `.env` 경로 | - |
| `--log-level`, `--log-file` | 로그 레벨 / JSON Lines 로그 파일 | `INFO` / - |
| `--no-color` | 색상 출력 끄기 | - |

## 설정

우선순위는 **플래그 > 환경변수 > `.env` > 설정 파일 > 기본값**이며, 환경변수
prefix는 `ROS_STREAMER`, 중첩 키 구분자는 `__`입니다.

```console
ROS_STREAMER_STREAM__HOST=10.0.0.2 ROS_STREAMER_STREAM__PORT=15555 \
  ros-stream-viewer stream
```

설정 파일(JSON/TOML/YAML)은 `--config`로 지정합니다. 지정하지 않으면
`.env`와 OS 설정 디렉터리(`$XDG_CONFIG_HOME/ros-streamer/config.toml`,
macOS는 `~/Library/Application Support`, Windows는 `%APPDATA%`)의
`config.{toml,yaml,yml,json}`을 자동으로 찾습니다.

```yaml
# viewer.yaml
stream:
  host: 10.0.0.2
  port: 5555
  type: raw
  connect_timeout: 5.0
  network_info: false
logging:
  level: INFO
```

불리언은 `true/false/1/0/yes/no/on/off`(대소문자 무관)만 인정합니다.
해석할 수 없는 값은 기본값으로, 해석됐지만 규약을 벗어난 값(포트 범위 등)은
종료 코드 2로 거부합니다.

## 출력과 종료 코드

결과(도움말, `--json` 요약)는 **stdout**, 로그·진행·오류는 **stderr**로
나갑니다.

```console
$ ros-stream-viewer stream --headless --max-frames 100 --json 2>/dev/null
{"backlog_skipped": 0, "decode_errors": 0, "dropped_frames": 0, "exit_code": 0,
 "fps": 30.0, "frames": 100, "frames_processed": 100, "host": "localhost",
 "latency_ms": 0.4, "port": 5556, "resolution": "640x480", "status": "ok", ...}
```

| 코드 | 의미 |
| --- | --- |
| 0 | 정상 종료(사용자 종료, `--max-frames`/`--duration` 도달 포함) |
| 1 | 예기치 않은 시스템 오류 |
| 2 | 사용법/설정 오류 |
| 3 | 뷰어 서비스 시작 실패(ZMQ 소켓 생성/연결 실패) |
| 4 | 실행 중 서비스 실패(첫 프레임 타임아웃, 소켓/프로토콜 오류) |

## 요구 사항과 지원 범위

* Python **3.12 / 3.13** (CI에서 두 버전 모두 테스트)
* Linux/macOS/Windows. GUI 표시에는 OpenCV 창이 필요하며, 헤드리스 환경에서는
  `--headless`를 사용하세요.
* 일부 Linux 배포판은 OpenCV 런타임 의존성(`libGL`)이 필요합니다:
  `apt-get install -y libgl1 libglib2.0-0`
* ROS 서버 없이도 동작하며, ROS 패키지는 필요하지 않습니다.

0.x 버전은 API가 아직 안정적이지 않습니다. 하위 호환이 깨지는 변경은
[CHANGELOG](https://gitlab.com/wkqco33/ros-streamer/blob/master/CHANGELOG.md)에
기록합니다.

## 문서

* 저장소·서버 노드·프로토콜: <https://gitlab.com/wkqco33/ros-streamer#readme>
* 이슈/요청: <https://gitlab.com/wkqco33/ros-streamer/-/issues>

## 라이선스

Apache-2.0 ([LICENSE](https://gitlab.com/wkqco33/ros-streamer/blob/master/LICENSE)).
