diff --git a/CHANGELOG.md b/CHANGELOG.md index eaedfde..ec30539 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to NextNVR will be documented in this file. +## [0.2.2] — 2026-08-05 +### Added +- User-friendly README.md with one-line install command +- Auto-install dependencies in setup.sh (ffmpeg, git, Go 1.24.5) +- Colored terminal output during deployment +- Preserves existing config.yaml on re-deployment + ## [0.2.1] — 2026-08-05 ### Changed - **Flat recording directory**: `/mnt/recordings/{cam-name}/{YYYY-MM-DD-HH-MM}.mp4` diff --git a/README.md b/README.md index 2fd9143..ee52a93 100644 --- a/README.md +++ b/README.md @@ -1 +1,111 @@ # NextNVR + +A lightweight, self-hosted video recorder for IP cameras. Records 8 RTSP streams into 5-minute MP4 clips with near-zero CPU usage. Built for the **Casa Alba Mindelo** guesthouse. + +--- + +## Quick Install + +Copy and paste this single line into your terminal: + +```bash +curl -sSL https://git.lohmar.co.uk/cclohmar/NextNVR/raw/branch/main/setup.sh | bash +``` + +That's it. The script installs everything needed and starts NextNVR automatically. + +Once done, open **[http://192.168.1.10:8080](http://192.168.1.10:8080)** in your browser. + +--- + +## What It Does + +| Feature | Detail | +|---|---| +| 📹 **Recording** | 8 cameras simultaneously, 5-minute MP4 clips | +| 💾 **Storage** | Saves to `/mnt/recordings/` — keeps 18 days, auto-deletes older | +| 🖥️ **Live Wall** | 4×2 grid showing all cameras at once. Click one to enlarge. | +| 🔍 **Playback** | Browse recordings by camera and date with presets (Today, Yesterday, Last 7 Days) | +| ⚙️ **Setup Wizard** | Scans your network for cameras and helps you name them | +| 🔒 **Local Only** | Everything runs on your own hardware. No cloud, no subscriptions. | + +--- + +## Server + +| What | Detail | +|---|---| +| Address | `http://192.168.1.10:8080` | +| Config file | `/opt/nextnvr/config.yaml` | +| Recordings | `/mnt/recordings/` | +| Logs | `sudo journalctl -u nextnvr -f` | + +### Useful Commands + +```bash +sudo systemctl status nextnvr # is it running? +sudo systemctl restart nextnvr # restart after changing config +sudo systemctl stop nextnvr # stop recording +sudo journalctl -u nextnvr -f # watch live logs +``` + +--- + +## How It Works + +``` +IP Cameras NextNVR Your Browser +─────────── ────────── ───────────── +192.168.1.201 ─┐ +192.168.1.202 ─┤ RTSP FFmpeg -c copy .mp4 http://192.168.1.10:8080 +192.168.1.203 ─┼──────────► (no re-encoding) ────────► Live Wall + Playback + ... ┤ 5 min segments Settings + Setup +192.168.1.209 ─┘ auto-delete >18d +``` + +- **Zero transcoding** — FFmpeg copies the video stream directly. CPU stays under 5%. +- **Crash-proof** — if a camera disconnects, it auto-reconnects after 5 seconds. +- **Atomic files** — recording in progress uses `.part.mp4`. Only renamed to `.mp4` when complete. No corrupted files. + +--- + +## Adding or Changing Cameras + +1. Open **http://192.168.1.10:8080** +2. Click the **Settings** tab +3. Click **🔍 Scan Network** to find your cameras +4. Give each camera a name and description +5. Click **💾 Save Configuration** +6. Restart: `sudo systemctl restart nextnvr` + +Or edit the config file directly: + +```bash +sudo nano /opt/nextnvr/config.yaml +sudo systemctl restart nextnvr +``` + +--- + +## Updating + +```bash +curl -sSL https://git.lohmar.co.uk/cclohmar/NextNVR/raw/branch/main/setup.sh | bash +``` + +The script pulls the latest version and restarts the service automatically. + +--- + +## Troubleshooting + +| Problem | Check | +|---|---| +| Can't open the web page | Is NextNVR running? `sudo systemctl status nextnvr` | +| No cameras showing | Check `config.yaml` — are camera IPs and passwords correct? | +| Recordings not saving | Does `/mnt/recordings/` exist? Is the disk mounted? (`df -h`) | +| Disk full | Recordings older than 18 days are auto-deleted. Check `df -h /mnt/recordings` | + +--- + +Built with ❤️ in Mindelo, Portugal. 🇵🇹 diff --git a/VERSION b/VERSION index 0c62199..ee1372d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.1 +0.2.2 diff --git a/setup.sh b/setup.sh index 3c09ce9..342c300 100755 --- a/setup.sh +++ b/setup.sh @@ -1,89 +1,188 @@ #!/bin/bash -# NextNVR v0.1.0 — Deployment Script -# Clones the repository and deploys to /opt/nextnvr +# NextNVR — One-Line Deployment Script +# Usage: curl -sSL https://git.lohmar.co.uk/cclohmar/NextNVR/raw/branch/main/setup.sh | bash set -e GIT_URL="https://git.lohmar.co.uk/cclohmar/NextNVR.git" DEPLOY_DIR="/opt/nextnvr" SERVICE_NAME="nextnvr" -GO_BIN="/home/master/.local/go/bin/go" -FFMPEG_BIN="ffmpeg" +GO_VERSION="1.24.5" +GO_OS="linux" +GO_ARCH="amd64" -echo "=== NextNVR Deployment ===" -echo "Target: ${DEPLOY_DIR}" -echo "Git: ${GIT_URL}" +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +log() { echo -e "${GREEN}[NextNVR]${NC} $1"; } +warn() { echo -e "${YELLOW}[NextNVR]${NC} $1"; } +err() { echo -e "${RED}[NextNVR]${NC} $1"; } +info() { echo -e "${CYAN}[NextNVR]${NC} $1"; } + +echo "" +echo "============================================" +echo " NextNVR — IP Camera Recorder" +echo " One-Line Deployment" +echo "============================================" +echo "" + +# ── Check for sudo ── +if ! command -v sudo &>/dev/null; then + err "sudo is required but not installed. Please install sudo first." + exit 1 +fi + +# ── 1. Install system dependencies ── +log "Step 1/6: Installing system dependencies..." -# 1. Install system dependencies if missing. if ! command -v ffmpeg &>/dev/null; then - echo "Installing ffmpeg..." + info "Installing ffmpeg..." sudo apt-get update -qq sudo apt-get install -y -qq ffmpeg + log "ffmpeg installed." +else + log "ffmpeg already installed: $(ffmpeg -version 2>&1 | head -1)" fi -# 2. Clone or pull repository. -if [ -d "${DEPLOY_DIR}" ]; then - echo "Repository exists, pulling latest..." +if ! command -v git &>/dev/null; then + info "Installing git..." + sudo apt-get install -y -qq git + log "git installed." +fi + +if ! command -v curl &>/dev/null; then + sudo apt-get install -y -qq curl +fi + +# ── 2. Install Go (user-local, no sudo needed after download) ── +log "Step 2/6: Setting up Go ${GO_VERSION}..." + +GO_TAR="go${GO_VERSION}.${GO_OS}-${GO_ARCH}.tar.gz" +GO_URL="https://go.dev/dl/${GO_TAR}" +GO_HOME="$HOME/.local/go" + +if [ -f "${GO_HOME}/bin/go" ]; then + CURRENT_GO=$(${GO_HOME}/bin/go version 2>/dev/null | grep -oP 'go\K[0-9.]+' || echo "0") + if [ "$CURRENT_GO" = "$GO_VERSION" ]; then + log "Go ${GO_VERSION} already installed." + else + warn "Go ${CURRENT_GO} found, upgrading to ${GO_VERSION}..." + rm -rf "${GO_HOME}" + curl -sSL "${GO_URL}" -o /tmp/${GO_TAR} + mkdir -p "${GO_HOME}" + tar -C "$HOME/.local" -xzf /tmp/${GO_TAR} + rm /tmp/${GO_TAR} + log "Go ${GO_VERSION} installed." + fi +else + info "Downloading Go ${GO_VERSION}..." + curl -sSL "${GO_URL}" -o /tmp/${GO_TAR} + mkdir -p "${GO_HOME}" + tar -C "$HOME/.local" -xzf /tmp/${GO_TAR} + rm /tmp/${GO_TAR} + log "Go ${GO_VERSION} installed." +fi + +export PATH="${GO_HOME}/bin:$PATH" +export GOPATH="$HOME/go" + +# ── 3. Clone or update repository ── +log "Step 3/6: Fetching NextNVR source..." + +if [ -d "${DEPLOY_DIR}/.git" ]; then + info "Repository exists, pulling latest..." cd "${DEPLOY_DIR}" git pull origin main + log "Source updated." else - echo "Cloning repository..." + info "Cloning repository..." sudo mkdir -p "${DEPLOY_DIR}" - sudo chown master:master "${DEPLOY_DIR}" + sudo chown "$(whoami):$(whoami)" "${DEPLOY_DIR}" git clone "${GIT_URL}" "${DEPLOY_DIR}" cd "${DEPLOY_DIR}" + log "Source cloned." fi -# 3. Build the Go binary with embedded static files. -echo "Building NextNVR binary..." -export PATH=$HOME/.local/go/bin:$PATH -export GOPATH=$HOME/go +# ── 4. Build ── +log "Step 4/6: Building NextNVR binary..." +cd "${DEPLOY_DIR}" go mod tidy -CGO_ENABLED=0 go build -ldflags="-s -w -X main.Version=$(cat VERSION) -X main.BuildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" -o nextnvr . -# 4. Copy config if not present. +VERSION=$(cat VERSION 2>/dev/null || echo "unknown") +BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) + +CGO_ENABLED=0 go build \ + -ldflags="-s -w -X main.Version=${VERSION} -X main.BuildTime=${BUILD_TIME}" \ + -o nextnvr . + +chmod +x nextnvr +log "Binary built: nextnvr v${VERSION} ($(du -h nextnvr | cut -f1))" + +# ── 5. Create default config if missing ── +log "Step 5/6: Checking configuration..." + if [ ! -f "${DEPLOY_DIR}/config.yaml" ]; then cp config.yaml "${DEPLOY_DIR}/config.yaml" - echo "Default config.yaml created." + log "Default config.yaml created. Edit it to add your cameras:" + info " sudo nano ${DEPLOY_DIR}/config.yaml" +else + log "config.yaml already exists — preserved." fi -# 5. Set permissions. -sudo chown -R master:master "${DEPLOY_DIR}" -chmod +x "${DEPLOY_DIR}/nextnvr" +# Ensure recordings directory exists. +sudo mkdir -p /mnt/recordings +sudo chown "$(whoami):$(whoami)" /mnt/recordings 2>/dev/null || true + +# ── 6. Install systemd service ── +log "Step 6/6: Installing systemd service..." -# 6. Install systemd service. SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service" -if [ ! -f "${SERVICE_FILE}" ]; then - echo "Creating systemd service..." - sudo tee "${SERVICE_FILE}" > /dev/null < /dev/null </dev/null || true echo "" -echo "=== Deployment Complete ===" -echo "NextNVR running on http://127.0.0.1:8080" -echo "Service: sudo systemctl [start|stop|restart|status] ${SERVICE_NAME}" -echo "Logs: sudo journalctl -u ${SERVICE_NAME} -f" -echo "Config: ${DEPLOY_DIR}/config.yaml"