- Removed inline JSON data for video clips; replaced with API endpoint to fetch video data. - Simplified camera angle switching UI with a 3-column button grid around a Model Y graphic. - Updated camera view mapping to use 'back' instead of 'rear'. - Enhanced noise canvas handling during video loading. - Streamlined clip playback logic and added auto-play for next clips in the same camera. - Improved search and sorting functionality by removing unnecessary elements. - Updated HTML structure for better accessibility and user experience.
152 lines
6.1 KiB
Markdown
152 lines
6.1 KiB
Markdown
# TeslaCam View
|
|
|
|
A Flask web app for browsing and playing TeslaCam (Tesla Dashcam/Sentry) recordings from a local drive. It scans a TeslaCam folder for video files, categorizes them by camera view, and presents them in a dark, Tesla-styled web interface with synchronized multi-angle playback.
|
|
|
|
## Features
|
|
|
|
- **Recursive scan** of the TeslaCam directory tree (`RecentClips`, `SavedClips`, `SentryClips`, etc.) for `.mp4` files matching the TeslaCam naming convention `YYYY-MM-DD_HH-MM-SS-${camera_view}.mp4`.
|
|
- **Categorization by camera view** — front, left repeater, right repeater, back, left pillar, right pillar — with friendly display names.
|
|
- **Multi-angle synchronized playback** — clips sharing the same timestamp are grouped so you can switch between camera angles for the same moment.
|
|
- **3-column camera selector** with a top-down Model Y graphic showing camera positions.
|
|
- **Auto-play** — oldest front camera clip plays on page load.
|
|
- **Safe streaming** — videos are served via Flask with path resolution relative to the configured TeslaCam root.
|
|
- **Password-protected** — simple session-based login page.
|
|
- **Dark Tesla-themed UI** built with responsive HTML/CSS (no build step).
|
|
|
|
## Project Structure
|
|
|
|
```txt
|
|
tesla-cam-view/
|
|
├── videoplayer.py # Flask app: scanning, routing, video streaming, auth
|
|
├── requirements.txt # Python dependencies
|
|
├── .env # Local configuration (git-ignored)
|
|
├── .env.example # Configuration template (committed)
|
|
├── .gitignore
|
|
├── templates/
|
|
│ ├── index.html # Main page: video player + 3-col camera selector
|
|
│ ├── login.html # Password login page
|
|
│ └── camera_view.html # Single-camera view page
|
|
├── static/
|
|
│ ├── css/
|
|
│ │ └── style.css # Dark Tesla-themed styles
|
|
│ └── js/
|
|
│ └── app.js # Video player, camera switching, prefetch
|
|
└── README.md
|
|
```
|
|
|
|
## Requirements
|
|
|
|
- Python 3.x
|
|
- See `requirements.txt`: Flask, python-dotenv, gunicorn
|
|
|
|
## Setup
|
|
|
|
1. Create and activate a virtual environment (optional but recommended):
|
|
|
|
```bash
|
|
python -m venv venv
|
|
# Windows
|
|
venv\Scripts\activate
|
|
# macOS/Linux
|
|
source venv/bin/activate
|
|
```
|
|
|
|
2. Install dependencies:
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
3. Configure the app via environment variables. Copy the example file and edit it:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
`TESLACAM_DIRECTORY` should point to the root folder containing your
|
|
`RecentClips`, `SavedClips`, and `SentryClips` subfolders. Variables set in
|
|
the real environment take precedence over `.env`.
|
|
|
|
## Configuration
|
|
|
|
All settings are read from environment variables, with sensible defaults. You
|
|
can set them in a `.env` file, export them in the shell, or pass them to the
|
|
process manager.
|
|
|
|
| Variable | Default | Description |
|
|
| -------------------- | --------------- | ----------------------------------------------- |
|
|
| `TESLACAM_DIRECTORY` | `/mnt/TeslaCam` | Root directory of the TeslaCam USB drive |
|
|
| `LOGIN_PASSWORD` | `teslacam` | Password for the web login page |
|
|
| `SECRET_KEY` | auto-generated | Flask session secret (set in production) |
|
|
| `FLASK_RUN_HOST` | `0.0.0.0` | Bind address (local dev server only) |
|
|
| `FLASK_RUN_PORT` | `5000` | Port (local dev server only) |
|
|
| `FLASK_DEBUG` | `0` | Enable Flask debug mode (local dev server only) |
|
|
| `SCAN_CACHE_TTL` | `3600` | Seconds to cache the directory scan. Hit |
|
|
| | | `/refresh` to force a re-scan. |
|
|
|
|
## Usage
|
|
|
|
### Local development server
|
|
|
|
```bash
|
|
python videoplayer.py
|
|
```
|
|
|
|
Then open [http://localhost:5000](http://localhost:5000) in your browser.
|
|
|
|
### Production (WSGI server on Linux)
|
|
|
|
For production, run the app behind a WSGI server such as **gunicorn**. The
|
|
`app` object in `videoplayer.py` is the WSGI entry point:
|
|
|
|
```bash
|
|
# Two workers are sufficient for this app
|
|
gunicorn -w 2 -b 0.0.0.0:5000 'videoplayer:app'
|
|
```
|
|
|
|
Make sure `TESLACAM_DIRECTORY` is set for the gunicorn process, e.g.:
|
|
|
|
```bash
|
|
export TESLACAM_DIRECTORY=/mnt/TeslaCam
|
|
gunicorn -w 2 -b 0.0.0.0:5000 'videoplayer:app'
|
|
```
|
|
|
|
For a systemd service or other process manager, set the variable in the unit
|
|
file / environment rather than relying on `.env`.
|
|
|
|
- The **main page** lists all clips grouped by camera view with a player.
|
|
- Click a play button to start playing; use the camera switch buttons to jump between angles for the same timestamp.
|
|
|
|
## Routes
|
|
|
|
| Route | Description |
|
|
| ------------------------ | ---------------------------------------------------- |
|
|
| `/` | Main page with all videos categorized by camera view |
|
|
| `/video/<path:filepath>` | Streams a video file from the TeslaCam directory |
|
|
| `/refresh` | Forces a re-scan of the TeslaCam directory |
|
|
|
|
## Camera Views
|
|
|
|
| Key | Display Name |
|
|
| ---------------- | -------------- |
|
|
| `front` | Front |
|
|
| `left_repeater` | Left Repeater |
|
|
| `right_repeater` | Right Repeater |
|
|
| `back` | Back |
|
|
| `left_pillar` | Left Pillar |
|
|
| `right_pillar` | Right Pillar |
|
|
|
|
## Notes
|
|
|
|
- The directory scan is cached in memory for `SCAN_CACHE_TTL` seconds
|
|
(default 3600) to avoid re-walking the tree on every request. Hit
|
|
`/refresh` to force a re-scan after copying new clips onto the drive.
|
|
- Under gunicorn with multiple workers, each worker keeps its own cache; a
|
|
`/refresh` only refreshes the worker that handles the request.
|
|
- Debug mode is off by default (`FLASK_DEBUG=0`) and is only used by the local
|
|
dev server. It has no effect when running under a WSGI server like gunicorn.
|
|
- The TeslaCam directory must be accessible from the machine running the app
|
|
(e.g., a mounted USB drive or network share).
|
|
- Filename parsing assumes the standard TeslaCam naming format; files not
|
|
matching the regex are ignored.
|