Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RSDK-8760] - README improvements #21

Merged
merged 15 commits into from
Oct 8, 2024
175 changes: 136 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,66 @@
# Video Storage
# [`video-store` module](https://app.viam.com/module/viam/video-store)
seanavery marked this conversation as resolved.
Show resolved Hide resolved
The `video-store` module brings security camera functionality to your smart machine! The module consumes a source [Camera](https://docs.viam.com/components/camera/) and saves the output as video files on disk. You can then upload video slices to the cloud using the [save](#save) command, or request the video bytes directly using the [fetch](#fetch) command.

## Configure your `video-store` component

Fill in the attributes as applicable to the component, according to the template below.
> [!NOTE]
seanavery marked this conversation as resolved.
Show resolved Hide resolved
> For more information, see [Configure a Machine](https://docs.viam.com/manage/configuration/).

### Attributes

| Attribute | Sub-Attribute | Type | Inclusion | Description |
|-----------------|-------------------|---------|-----------|---------------------------------------------------------------------------------------------------|
| `camera` | | string | required | Name of the source camera to read images from. |
| `sync` | | string | required | Name of the dependency datamanager service. |
| `storage` | | object | required | |
| | `segment_seconds` | integer | optional | Length in seconds of the individual segment video files. |
| | `size_gb` | integer | required | Total amount of allocated storage in gigabytes. |
| | `storage_path` | string | optional | Custom path to use for video storage. |
| | `upload_path` | string | optional | Custom path to use for uploading files. If not under `~/.viam/capture`, you will need to add to `additional_sync_paths` in datamanager service configuration. |
| `video` | | object | optional | |
| | `format` | string | optional | Name of video format to use (e.g., mp4). |
| | `codec` | string | optional | Name of video codec to use (e.g., h264). |
| | `bitrate` | integer | optional | Throughput of encoder in bits per second. Higher for better quality video, and lower for better storage efficiency. |
| | `preset` | string | optional | Name of codec video preset to use. See [here](https://trac.ffmpeg.org/wiki/Encode/H.264#a2.Chooseapresetandtune) for preset options. |
| `cam_props` | | object | required | |
| | `width` | integer | required | Width of the source camera frames in pixels. |
| | `height` | integer | required | Height of the source camera frames in pixels. |
| | `framerate` | integer | required | Number of frames per second provided by the source camera. |
randhid marked this conversation as resolved.
Show resolved Hide resolved

### Example Configuration

```json
{
"name": <video_store_component_name>,
"name": "video-store",
"namespace": "rdk",
"type": "camera",
"model": "viam:video:storage",
"attributes": {
"camera": <camera_component_name>, [required]
"sync": <data_manager_service_name>, [required]
"storage": { [required]
"segment_seconds": <length_of_video_segments>, [optional]
"size_gb": <total_storage_max_size>, [required]
"storage_path": <custom_path_to_store_video_files>, [optional]
"upload_path": <custom_path_to_upload_video_files>, [optional]
},
"video": { [optional]
"format": <video_format>, [optional]
"codec": <video_codec>, [optional]
"bitrate": <bits_pers_second>, [optional]
"preset": <video_preset>, [optional]
},
"cam_props": { [required]
"width": <pixel_width>, [required]
"height": <pixel_height>, [required]
"framerate": <frames_per_second>, [required]
"camera": "wc-cam"
"sync": "data-manager",
"storage": {
"segment_seconds": 10,
"size_gb": 50,
},
"cam_props": {
"width": 640,
"height": 480,
"framerate": 25
}
},
"depends_on": [
<camera_component_name>, [required]
<data_manager_service_name> [required]
"wc-cam",
"data-manager"
]
}
```

Make sure to configure a [Data Manager Service](https://docs.viam.com/services/data/cloud-sync/) to uplaod video files to the cloud.
### Configure a Data Manager Service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would suggest moving this up to above configure a video-store section in a section called ## Requirements and also adding the instructions to configure through the UI:

Navigate to the [**CONFIGURE** tab](https://docs.viam.com/configure/) of your [machine](https://docs.viam.com/fleet/machines/) in [the Viam app](https://app.viam.com/). [Add data-management to your machine](https://docs.viam.com/configure/#services).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added requirements section.


Make sure to configure a [Data Manager Service](https://docs.viam.com/services/data/cloud-sync/) to uplaod video files to the cloud when saving video slices.
seanavery marked this conversation as resolved.
Show resolved Hide resolved

> [!NOTE]
> The `additional_sync_paths` attribute must include the custom path specified in the `upload_path` attribute of the `video-store` component if it is not under `~/.viam/capture`.

```json
{
Expand All @@ -58,7 +79,7 @@ Make sure to configure a [Data Manager Service](https://docs.viam.com/services/d
}
```

## DoCommands API
## DoCommand API

### From/To

Expand All @@ -81,50 +102,77 @@ The datetime format used is: `YYYY-MM-DD_HH-MM-SS`

### `save`

The save command retreives video from local storage and, uploads the clip to the cloud.
The save command retreives video from local storage, concatenates and trims underlying storage segments based on time range, and uploads the clip to the cloud.

| Attribute | Type | Required/Optional | Description |
|-------------|---------------------|-------------------|----------------------------------|
| `command` | string | required | Command to be executed. |
| `from` | timestamp | required | Start timestamp. |
| `to` | timestamp | required | End timestamp. |
| `metadata` | string | optional | Arbitrary metadata string. |
| `async` | boolean | optional | Whether the operation is async. |

#### Save Request
```json
{
"command": "save",
"from": <start_timestamp>, [required]
"to": <end_timestamp>, [required]
"metadata": <arbitrary_metadata_string> [optional]
"from": <start_timestamp>,
"to": <end_timestamp>,
"metadata": <arbitrary_metadata_string>
}
```

#### Save Response
```json
{
"command": "save",
"filename": <filename_to_be_uploaded>
}
```

#### Async Save Request

The async save command performs the same operation as the save command, but does not wait for the operation to complete. Use this command when you want to save video slices that include the current in-progress video storage segment. It will wait for the current segment to finish recording before saving the video slice.

> [!NOTE]
> The async save command does not support future timestamps. The `from` timestamp must be in the past.
> and the `to` timestamp must be the current time or in the past.
seanavery marked this conversation as resolved.
Show resolved Hide resolved

```json
{
"command": "save",
"from": <start_timestamp>, [required]
"to": <end_timestamp>, [required]
"metadata": <arbitrary_metadata_string>, [optional]
"async": true [optional]
"from": <start_timestamp>,
"to": <end_timestamp>,
"metadata": <arbitrary_metadata_string>,
"async": true
}
```

#### Save Response
#### Async Save Response
```json
{
"command": "save",
"filename": <filename_to_be_uploaded>
"filename": <filename_to_be_uploaded>,
"status": "async"
}
```

### `fetch`

The fetch command retrieves video from local storage, and sends the bytes back to the client.
The fetch command retrieves video from local storage, and sends the bytes directly back to the client.

| Attribute | Type | Required/Optional | Description |
|-----------|------------|-------------------|----------------------|
| `command` | string | required | Command to be executed. |
| `from` | timestamp | required | Start timestamp. |
| `to` | timestamp | required | End timestamp. |

#### Fetch Request
```json
{
"command": "fetch",
"from": <start_timestamp>, [required]
"to": <end_timestamp> [required]
"from": <start_timestamp>,
"to": <end_timestamp>
}
```

Expand All @@ -134,4 +182,53 @@ The fetch command retrieves video from local storage, and sends the bytes back t
"command": "fetch",
"video": <video_bytes>
}
```
```

## Local Development

### Building

The [Makefile](./Makefile) supports building for the following platforms:

| Platform | Architecture |
|----------------|--------------|
| `linux` | `arm64` |
| `linux` | `amd64` |
| `darwin` | `arm64` |

To build for linux/arm64, run the following commands:
```
canon -arch arm64
make
```

To build for linux/amd64, run the following commands:
```
canon -arch amd64
make
```

To build for darwin/arm64, run the following command on a Mac with an M series chip:
```
make
```

### Testing

Run [tests](./tests) to ensure the module is functioning as expected with the following command:

```
make test
```

### Linting

```
make lint
```

### Package module

```
make module
```
4 changes: 2 additions & 2 deletions meta.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"module_id": "viam:video-store",
"visibility": "private",
"visibility": "public",
"url": "https://github.com/viam-modules/video-store",
"description": "module for video storage and retrieval",
"description": "Golang module for video storage and retrieval from a camera",
"models": [
{
"api": "rdk:component:camera",
Expand Down