Metadata-Version: 2.4
Name: nooie-proxy
Version: 0.1.0
Summary: A live MPEG-TS stream from your own Nooie IP camera
Project-URL: Homepage, https://github.com/ltrgoddard/nooie-proxy
Project-URL: Repository, https://github.com/ltrgoddard/nooie-proxy
Project-URL: Issues, https://github.com/ltrgoddard/nooie-proxy/issues
Author-email: Louis Goddard <louisgoddard@gmail.com>
License: MIT
License-File: LICENSE
Keywords: camera,go2rtc,home-assistant,nooie,webrtc
Requires-Python: >=3.11
Requires-Dist: aiohttp<4,>=3.12
Requires-Dist: aiomqtt<3,>=2.5.1
Requires-Dist: aiortc<2,>=1.14
Requires-Dist: av<18,>=15
Requires-Dist: cryptography<50,>=45
Description-Content-Type: text/markdown

# nooie-proxy

Your own Nooie IP camera has a WebRTC path but no RTSP output. nooie-proxy
uses that path to stream live H.264 and AAC, without the official app. The
proxy signs in, places the call, and muxes the result to stdout or to a URL.
It does not decode or re-encode the media.

```sh
nooie-proxy | vlc -                              # watch it
NOOIE_OUTPUT=udp://127.0.0.1:5004 nooie-proxy &  # serve it to other tools
ffmpeg -i udp://127.0.0.1:5004 frame%04d.jpg     # attach and detach freely
```

To use this in Home Assistant instead, see
[hass-nooie](https://github.com/ltrgoddard/hass-nooie). It is an add-on and
component that run the proxy with go2rtc. Each camera becomes a camera
entity.

## Install

The proxy needs Python 3.11 or later.

```sh
uv tool install nooie-proxy      # or: pipx install nooie-proxy
```

To install from a checkout, use [uv](https://docs.astral.sh/uv/):

```sh
git clone https://github.com/ltrgoddard/nooie-proxy.git
cd nooie-proxy
uv tool install --editable .
```

## Configure

The proxy reads its configuration from the environment. Copy `.env.example`
to `~/.config/nooie-proxy/.env`, or to
`~/Library/Application Support/nooie-proxy/.env` on macOS, then `chmod 600`
it. The proxy reads the values literally. An exported variable replaces the
value in the file.

| variable | default | meaning |
| --- | --- | --- |
| `NOOIE_USERNAME`, `NOOIE_PASSWORD` | — | the account login |
| `NOOIE_COUNTRY_CODE` | `44` | your mobile phone's country code |
| `NOOIE_DEVICE_ID` | — | the camera to use when the account has more than one |
| `NOOIE_OUTPUT` | `-` | `-` for stdout, or any path or URL that PyAV writes |

`nooie-proxy --list-devices` prints the UUID, name, model, and online state
of every camera on the account. The proxy also stores a UUID beside the
dotenv to identify this install. Do not edit or delete it.

## Stream

Every sink carries MPEG-TS with the camera's own H.264 and AAC. As a result, a
consumer can attach later and synchronize at the next keyframe, which takes
about two seconds. One process serves one consumer. To serve more, use
`ffmpeg -f tee` or the Home Assistant add-on.

The first frame arrives 10 to 20 seconds after the start. The login, the P2P
registration, and the WebRTC handshake each occur once for every call. The
option `-probesize 200000` reduces the time a player spends on probing.

## Service

The proxy exits when the camera ends the call, so run it with a supervisor
that restarts it, such as launchd or systemd. A restart recovers a dropped
call. Limit the retry rate to avoid too many login attempts.

## Design

Three independent handshakes precede each call, and each one has a module.

| module | contents |
| --- | --- |
| `cloud` | the Nooie REST API: login, registration, camera selection, session |
| `thing` | the bundled Tuya account: UID login and MQTT presence |
| `apeman` | publishes the local NAT mapping on the Nooie P2P network |
| `sdp` | the compact Nooie SDP and ICE dialect, in both directions |
| `signalling` | the WebSocket envelopes and the answer matching |
| `rtc` | the aiortc patches: AAC, passthrough, RSA DTLS at 1200 bytes, ICE sizes |
| `stream` | places the call and muxes the tracks |
| `env` | the dotenv, the install identity, and the credentials |
| `profile` | the app build the proxy presents itself as |
| `service` | the command line entry point |
| `twofish` | the cipher the apeman RPC uses |

The proxy muxes the media as it arrives, so it costs a few percent of one
core. Use it only with accounts and cameras that you own.
