https://github.com/eigenein/nest-restream
Helper scripts to restream Google Nest cams to YouTube
https://github.com/eigenein/nest-restream
device-access ffmpeg google-api nest nest-cam nest-camera nest-cams rtsp systemd-service systemd-unit
Last synced: 6 months ago
JSON representation
Helper scripts to restream Google Nest cams to YouTube
- Host: GitHub
- URL: https://github.com/eigenein/nest-restream
- Owner: eigenein
- License: mit
- Created: 2021-05-14T18:49:23.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2021-05-15T18:58:35.000Z (over 4 years ago)
- Last Synced: 2025-01-08T13:21:03.855Z (9 months ago)
- Topics: device-access, ffmpeg, google-api, nest, nest-cam, nest-camera, nest-cams, rtsp, systemd-service, systemd-unit
- Language: Python
- Homepage:
- Size: 20.5 KB
- Stars: 4
- Watchers: 3
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README

[](https://github.com/psf/black)This is a small toolbox to simplify re-streaming a [Google Nest Cam](https://store.google.com/product/nest_cam) to YouTube.
## High-level overview
- Set up a Google Cloud Platform project and [Device Access project](https://developers.google.com/nest/device-access/get-started)
- Set up `token-keeper.py` service unit
- Set up `stream-keeper.py` service unit
- Set up re-streaming service unit
- Set up `subtitles-sender.py` service unit (TODO)## `token-keeper.py`
This is a simple service to keep a valid access token in a file. Basically, it [obtains a new token](https://developers.google.com/identity/protocols/oauth2/web-server#offline) as soon as old one expires.
To use it, you need a client ID, client secret, and a refresh token. See the [Quick Start Guide on Google Developers](https://developers.google.com/nest/device-access/get-started) to obtain them.
```text
Usage: token-keeper.py [OPTIONS]Google Device Access token refresh service.
Implements https://developers.google.com/identity/protocols/oauth2/web-server#offline
Options:
--client-id TEXT [env var: TOKEN_KEEPER_CLIENT_ID;required]
--client-secret TEXT [env var: TOKEN_KEEPER_CLIENT_SECRET;required]
--refresh-token TEXT [env var: TOKEN_KEEPER_REFRESH_TOKEN;required]
--access-token-file FILE [env var: TOKEN_KEEPER_ACCESS_TOKEN_FILE;required]
--help Show this message and exit.
```### [systemd](https://en.wikipedia.org/wiki/Systemd) service
```ini
[Unit]
Description = Token Keeper
BindsTo = network-online.target
After = network.target network-online.target[Install]
WantedBy = multi-user.target[Service]
WorkingDirectory = /home/pi
StandardOutput = journal
StandardError = journal
Restart = always
User = pi
ExecStart = /home/pi/nest-restream/venv/bin/python /home/pi/nest-restream/token-keeper.py
Environment = "TOKEN_KEEPER_CLIENT_ID="
Environment = "TOKEN_KEEPER_CLIENT_SECRET="
Environment = "TOKEN_KEEPER_REFRESH_TOKEN="
Environment = "TOKEN_KEEPER_ACCESS_TOKEN_FILE=/home/pi/access-token.txt"
```## `stream-keeper.py`
This is a service to [generate an RSTP stream](https://developers.google.com/nest/device-access/traits/device/camera-live-stream#generatertspstream) and to [extend it](https://developers.google.com/nest/device-access/traits/device/camera-live-stream#extendrtspstream) periodically before it expires. It keeps a valid stream URL in a file that can be specified as `EnvironmentFile` in `systemd`.
Requires a valid access token from `token-keeper.py`.
```text
Usage: stream-keeper.py [OPTIONS]Keeps a valid RTSP stream URL.
Options:
--access-token-file FILE [env var: STREAM_KEEPER_ACCESS_TOKEN_FILE;required]
--device-id TEXT [env var: STREAM_KEEPER_DEVICE_ID;required]
--project-id TEXT Device Access project ID. [env var: STREAM_KEEPER_PROJECT_ID;required]
--stream-url-file FILE [env var: STREAM_KEEPER_STREAM_URL_FILE;required]
--help Show this message and exit.
```### [systemd](https://en.wikipedia.org/wiki/Systemd) service
```ini
[Unit]
Description = Stream Keeper
BindsTo = network-online.target
After = network.target network-online.target[Install]
WantedBy = multi-user.target[Service]
WorkingDirectory = /home/pi
StandardOutput = journal
StandardError = journal
Restart = always
User = pi
ExecStart = /home/pi/nest-restream/venv/bin/python /home/pi/nest-restream/stream-keeper.py
Environment = "STREAM_KEEPER_ACCESS_TOKEN_FILE=/home/pi/access-token.txt"
Environment = "STREAM_KEEPER_DEVICE_ID="
Environment = "STREAM_KEEPER_PROJECT_ID="
Environment = "STREAM_KEEPER_STREAM_URL_FILE=/home/pi/stream-url.txt"
```## Integrating with [`ffmpeg`](https://www.ffmpeg.org/)
### Example: re-streaming to YouTube
The stream URL changes every few minutes, thus I set `RestartSec = 0` to make restarts as quick as possible. This isn't perfect, of course, and I'd be happy to hear a better solution.
`${STREAM_KEEPER_STREAM_URL}` is being set in `stream-url.txt` by `stream-keeper.py`.
```ini
[Unit]
Description = Restream
BindsTo = network-online.target
After = network.target network-online.target[Service]
WorkingDirectory = /home/pi
StandardOutput = journal
StandardError = journal
Restart = always
RestartSec = 0
TimeoutStopSec = 3
StartLimitInterval = 0
User = pi
EnvironmentFile = /home/pi/stream-url.txt
ExecStart = ffmpeg \
-loglevel warning \
-nostdin \
-stats \
-xerror \
-thread_queue_size 256 \
-fflags nobuffer \
-rtsp_transport tcp \
-stimeout 3000000 \
-i ${STREAM_KEEPER_STREAM_URL} \
-codec copy \
-flags +cgop \
-hls_time 2 \
-hls_list_size 4 \
-method PUT \
-http_persistent 1 \
'https://a.upload.youtube.com/http_upload_hls?cid=©=0&file=live.m3u8'[Install]
WantedBy = multi-user.target
```