mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-01-12 23:43:22 -05:00
Reorganize and expand documentation
This commit is contained in:
parent
04e9f3f160
commit
cbd8f7d3d2
242
README.md
242
README.md
@ -50,209 +50,11 @@ make this possible:
|
||||
don't provide any information beyond if motion exceeded the threshold or
|
||||
not.
|
||||
|
||||
# Downloading
|
||||
# Documentation
|
||||
|
||||
See the [github page](https://github.com/scottlamb/moonfire-nvr) (in case
|
||||
you're not reading this text there already). You can download the bleeding
|
||||
edge version from the command line via git:
|
||||
|
||||
$ git clone https://github.com/scottlamb/moonfire-nvr.git
|
||||
|
||||
# Building from source
|
||||
|
||||
There are no binary packages of Moonfire NVR available yet, so it must be built
|
||||
from source.
|
||||
|
||||
Moonfire NVR is written in the [Rust Programming
|
||||
Language](https://www.rust-lang.org/en-US/). In the long term, I expect this
|
||||
will result in a more secure, full-featured, easy-to-install software. In the
|
||||
short term, there will be growing pains. Rust is a new programming language.
|
||||
Moonfire NVR's primary author is new to Rust. And Moonfire NVR is a young
|
||||
project.
|
||||
|
||||
You will need the following C libraries installed:
|
||||
|
||||
* [ffmpeg](http://ffmpeg.org/) version 2.x or 3.x, including `libavutil`,
|
||||
`libavcodec` (to inspect H.264 frames), and `libavformat` (to connect to RTSP
|
||||
servers and write `.mp4` files).
|
||||
|
||||
Note ffmpeg library versions older than 55.1.101, along with all versions of
|
||||
the competing project [libav](http://libav.org), don't not support socket
|
||||
timeouts for RTSP. For reliable reconnections on error, it's strongly
|
||||
recommended to use ffmpeg library versions >= 55.1.101.
|
||||
|
||||
* [SQLite3](https://www.sqlite.org/).
|
||||
|
||||
* [`ncursesw`](https://www.gnu.org/software/ncurses/), the UTF-8 version of
|
||||
the `ncurses` library.
|
||||
|
||||
On Ubuntu 16.04.1 LTS or Raspbian Jessie, the following command will install
|
||||
all non-Rust dependencies:
|
||||
|
||||
$ sudo apt-get install \
|
||||
build-essential \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libncurses5-dev \
|
||||
libncursesw5-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
pkgconf
|
||||
|
||||
Next, you need Rust 1.15+ and Cargo. The easiest way to install them is by following
|
||||
the instructions at [rustup.rs](https://www.rustup.rs/).
|
||||
|
||||
You can continue to follow the build/install instructions below for a manual
|
||||
build and install, or alternatively you can run the prep script called `prep.sh`.
|
||||
|
||||
$ cd moonfire-nvr
|
||||
$ ./prep.sh
|
||||
|
||||
The script will take the following command line options, should you need them:
|
||||
|
||||
* `-S`: Skip updating and installing dependencies through apt-get. This too can be
|
||||
useful on repeated builds.
|
||||
|
||||
You can edit variables at the start of the script to influence names and
|
||||
directories, but defaults should suffice in most cases. For details refer to
|
||||
the script itself. We will mention just one option, needed when you follow the
|
||||
suggestion to separate database and samples between flash storage and a hard disk.
|
||||
If you have the hard disk mounted on, lets say `/media/nvr`, and you want to
|
||||
store the video samples inside a directory named `samples` there, you would set:
|
||||
|
||||
SAMPLES_DIR=/media/nvr/samples
|
||||
|
||||
The script will perform all necessary steps to leave you with a fully built,
|
||||
installed moonfire-nvr binary. The only thing
|
||||
you'll have to do manually is add your camera configuration(s) to the database.
|
||||
Alternatively, before running the script, you can create a file named `cameras.sql`
|
||||
in the same directory as the `prep.sh` script and it will be automatically
|
||||
included for you.
|
||||
For instructions, you can skip to "[Camera configuration and hard disk mounting](#camera)".
|
||||
|
||||
Once prerequisites are installed, Moonfire NVR can be built as follows:
|
||||
|
||||
$ cargo test
|
||||
$ cargo build --release
|
||||
$ sudo install -m 755 target/release/moonfire-nvr /usr/local/bin
|
||||
|
||||
# Further configuration
|
||||
|
||||
Moonfire NVR should be run under a dedicated user. It keeps two kinds of
|
||||
state:
|
||||
|
||||
* a SQLite database, typically <1 GiB. It should be stored on flash if
|
||||
available.
|
||||
* the "sample file directory", which holds the actual samples/frames of
|
||||
H.264 video. This should be quite large and typically is stored on a hard
|
||||
drive.
|
||||
|
||||
(See [guide/schema.md](guide/schema.md) for more information.)
|
||||
|
||||
Both kinds of state are intended to be accessed only by Moonfire NVR itself.
|
||||
However, the interface for adding new cameras is not yet written, so you will
|
||||
have to manually insert cameras with the `sqlite3` command line tool prior to
|
||||
starting Moonfire NVR.
|
||||
|
||||
Manual commands would look something like this:
|
||||
|
||||
$ sudo addgroup --system moonfire-nvr
|
||||
$ sudo adduser --system moonfire-nvr --home /var/lib/moonfire-nvr
|
||||
$ sudo mkdir /var/lib/moonfire-nvr
|
||||
$ sudo -u moonfire-nvr -H mkdir db sample
|
||||
$ sudo -u moonfire-nvr moonfire-nvr init
|
||||
|
||||
## <a name="cameras"></a>Camera configuration and hard drive mounting
|
||||
|
||||
If a dedicated hard drive is available, set up the mount point:
|
||||
|
||||
$ sudo vim /etc/fstab
|
||||
$ sudo mount /var/lib/moonfire-nvr/sample
|
||||
|
||||
Once setup is complete, it is time to add camera configurations to the
|
||||
database. If the daemon is running, you will need to stop it temporarily:
|
||||
|
||||
$ sudo systemctl stop moonfire-nvr
|
||||
|
||||
You can configure the system through a text-based user interface:
|
||||
|
||||
$ sudo -u moonfire-nvr moonfire-nvr config 2>debug-log
|
||||
|
||||
In the user interface, add your cameras under the "Edit cameras" dialog.
|
||||
There's a "Test" button to verify your settings directly from the dialog.
|
||||
|
||||
After the cameras look correct, go to "Edit retention" to assign disk space to
|
||||
each camera. Leave a little slack (at least 100 MB per camera) between the total
|
||||
limit and the filesystem capacity, even if you store nothing else on the disk.
|
||||
There are several reasons this is needed:
|
||||
|
||||
* The limit currently controls fully-written files only. There will be up
|
||||
to two minutes of video per camera of additional video.
|
||||
* The rotation happens after the limit is exceeded, not proactively.
|
||||
* Moonfire NVR currently doesn't account for the unused space in the final
|
||||
filesystem block at the end of each file.
|
||||
* Moonfire NVR doesn't account for the space used for directory listings.
|
||||
* If a file is open when it is deleted (such as if a HTTP client is
|
||||
downloading it), it stays around until the file is closed. Moonfire NVR
|
||||
currently doesn't account for this.
|
||||
|
||||
When finished, start the daemon:
|
||||
|
||||
$ sudo systemctl start moonfire-nvr
|
||||
|
||||
## System Service
|
||||
|
||||
Moonfire NVR can be run as a systemd service. If you used `prep.sh` this has
|
||||
been done for you. If not, Create
|
||||
`/etc/systemd/system/moonfire-nvr.service`:
|
||||
|
||||
[Unit]
|
||||
Description=Moonfire NVR
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/moonfire-nvr run \
|
||||
--sample-file-dir=/var/lib/moonfire-nvr/sample \
|
||||
--db-dir=/var/lib/moonfire-nvr/db \
|
||||
--http-addr=0.0.0.0:8080
|
||||
Environment=TZ=:/etc/localtime
|
||||
Environment=MOONFIRE_FORMAT=google-systemd
|
||||
Environment=MOONFIRE_LOG=info
|
||||
Type=simple
|
||||
User=moonfire-nvr
|
||||
Nice=-20
|
||||
Restart=on-abnormal
|
||||
CPUAccounting=true
|
||||
MemoryAccounting=true
|
||||
BlockIOAccounting=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
Note that the HTTP port currently has no authentication; it should not be
|
||||
directly exposed to the Internet.
|
||||
|
||||
Complete the installation through `systemctl` commands:
|
||||
|
||||
$ sudo systemctl daemon-reload
|
||||
$ sudo systemctl start moonfire-nvr
|
||||
$ sudo systemctl status moonfire-nvr
|
||||
$ sudo systemctl enable moonfire-nvr
|
||||
|
||||
See the [systemd](http://www.freedesktop.org/wiki/Software/systemd/)
|
||||
documentation for more information. The [manual
|
||||
pages](http://www.freedesktop.org/software/systemd/man/) for `systemd.service`
|
||||
and `systemctl` may be of particular interest.
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
While Moonfire NVR is running, logs will be written to stderr. The
|
||||
`MOONFIRE_LOG` environmental variable controls the log level;
|
||||
`MOONFIRE_LOG=info` is the default. `MOONFIRE_FORMAT` controls the
|
||||
logging style; options are `google` (default, like the Google glog package)
|
||||
or `google-systemd` (formatted for the systemd journal). If running through
|
||||
systemd, try `sudo journalctl --unit moonfire-nvr` to view the logs.
|
||||
* [License](LICENSE.txt) — GPLv3
|
||||
* [Building and installing](guide/install.md)
|
||||
* [Troubleshooting](guide/troubleshooting.md)
|
||||
|
||||
# <a name="help"></a> Getting help and getting involved
|
||||
|
||||
@ -263,37 +65,5 @@ you love/hate the software and why.
|
||||
|
||||
I'd welcome help with testing, development (in Rust, JavaScript, and HTML),
|
||||
user interface/graphic design, and documentation. Please email the mailing
|
||||
list if interested. Patches are welcome, but I encourage you to discuss large
|
||||
changes on the mailing list first to save effort.
|
||||
|
||||
# License
|
||||
|
||||
This file is part of Moonfire NVR, a security camera digital video recorder.
|
||||
Copyright (C) 2016 Scott Lamb <slamb@slamb.org>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
list if interested. Pull requests are welcome, but I encourage you to discuss
|
||||
large changes on the mailing list or in a github issue first to save effort.
|
||||
|
198
guide/install.md
Normal file
198
guide/install.md
Normal file
@ -0,0 +1,198 @@
|
||||
# Installing Moonfire NVR
|
||||
|
||||
This document describes how to install Moonfire NVR on a Linux system.
|
||||
|
||||
## Downloading
|
||||
|
||||
See the [github page](https://github.com/scottlamb/moonfire-nvr) (in case
|
||||
you're not reading this text there already). You can download the bleeding
|
||||
edge version from the command line via git:
|
||||
|
||||
$ git clone https://github.com/scottlamb/moonfire-nvr.git
|
||||
|
||||
## Building from source
|
||||
|
||||
There are no binary packages of Moonfire NVR available yet, so it must be built
|
||||
from source.
|
||||
|
||||
Moonfire NVR is written in the [Rust Programming
|
||||
Language](https://www.rust-lang.org/en-US/). In the long term, I expect this
|
||||
will result in a more secure, full-featured, easy-to-install software. In the
|
||||
short term, there will be growing pains. Rust is a new programming language.
|
||||
Moonfire NVR's primary author is new to Rust. And Moonfire NVR is a young
|
||||
project.
|
||||
|
||||
You will need the following C libraries installed:
|
||||
|
||||
* [ffmpeg](http://ffmpeg.org/) version 2.x or 3.x, including `libavutil`,
|
||||
`libavcodec` (to inspect H.264 frames), and `libavformat` (to connect to RTSP
|
||||
servers and write `.mp4` files).
|
||||
|
||||
Note ffmpeg library versions older than 55.1.101, along with all versions of
|
||||
the competing project [libav](http://libav.org), don't not support socket
|
||||
timeouts for RTSP. For reliable reconnections on error, it's strongly
|
||||
recommended to use ffmpeg library versions >= 55.1.101.
|
||||
|
||||
* [SQLite3](https://www.sqlite.org/).
|
||||
|
||||
* [`ncursesw`](https://www.gnu.org/software/ncurses/), the UTF-8 version of
|
||||
the `ncurses` library.
|
||||
|
||||
On recent Ubuntu or Raspbian, the following command will install
|
||||
all non-Rust dependencies:
|
||||
|
||||
$ sudo apt-get install \
|
||||
build-essential \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libncurses5-dev \
|
||||
libncursesw5-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
pkgconf
|
||||
|
||||
Next, you need Rust 1.17+ and Cargo. The easiest way to install them is by following
|
||||
the instructions at [rustup.rs](https://www.rustup.rs/).
|
||||
|
||||
You can continue to follow the build/install instructions below for a manual
|
||||
build and install, or alternatively you can run the prep script called `prep.sh`.
|
||||
|
||||
$ cd moonfire-nvr
|
||||
$ ./prep.sh
|
||||
|
||||
The script will take the following command line options, should you need them:
|
||||
|
||||
* `-S`: Skip updating and installing dependencies through apt-get. This too can be
|
||||
useful on repeated builds.
|
||||
|
||||
You can edit variables at the start of the script to influence names and
|
||||
directories, but defaults should suffice in most cases. For details refer to
|
||||
the script itself. We will mention just one option, needed when you follow the
|
||||
suggestion to separate database and samples between flash storage and a hard disk.
|
||||
If you have the hard disk mounted on, lets say `/media/nvr`, and you want to
|
||||
store the video samples inside a directory named `samples` there, you would set:
|
||||
|
||||
SAMPLES_DIR=/media/nvr/samples
|
||||
|
||||
The script will perform all necessary steps to leave you with a fully built,
|
||||
installed moonfire-nvr binary. The only thing
|
||||
you'll have to do manually is add your camera configuration(s) to the database.
|
||||
Alternatively, before running the script, you can create a file named `cameras.sql`
|
||||
in the same directory as the `prep.sh` script and it will be automatically
|
||||
included for you.
|
||||
For instructions, you can skip to "[Camera configuration and hard disk mounting](#camera)".
|
||||
|
||||
Once prerequisites are installed, Moonfire NVR can be built as follows:
|
||||
|
||||
$ cargo test
|
||||
$ cargo build --release
|
||||
$ sudo install -m 755 target/release/moonfire-nvr /usr/local/bin
|
||||
|
||||
## Further configuration
|
||||
|
||||
Moonfire NVR should be run under a dedicated user. It keeps two kinds of
|
||||
state:
|
||||
|
||||
* a SQLite database, typically <1 GiB. It should be stored on flash if
|
||||
available.
|
||||
* the "sample file directory", which holds the actual samples/frames of
|
||||
H.264 video. This should be quite large and typically is stored on a hard
|
||||
drive.
|
||||
|
||||
(See [schema.md](schema.md) for more information.)
|
||||
|
||||
Both kinds of state are intended to be accessed only by Moonfire NVR itself.
|
||||
However, the interface for adding new cameras is not yet written, so you will
|
||||
have to manually insert cameras with the `sqlite3` command line tool prior to
|
||||
starting Moonfire NVR.
|
||||
|
||||
Manual commands would look something like this:
|
||||
|
||||
$ sudo addgroup --system moonfire-nvr
|
||||
$ sudo adduser --system moonfire-nvr --home /var/lib/moonfire-nvr
|
||||
$ sudo mkdir /var/lib/moonfire-nvr
|
||||
$ sudo -u moonfire-nvr -H mkdir db sample
|
||||
$ sudo -u moonfire-nvr moonfire-nvr init
|
||||
|
||||
### <a name="cameras"></a>Camera configuration and hard drive mounting
|
||||
|
||||
If a dedicated hard drive is available, set up the mount point:
|
||||
|
||||
$ sudo vim /etc/fstab
|
||||
$ sudo mount /var/lib/moonfire-nvr/sample
|
||||
|
||||
Once setup is complete, it is time to add camera configurations to the
|
||||
database. If the daemon is running, you will need to stop it temporarily:
|
||||
|
||||
$ sudo systemctl stop moonfire-nvr
|
||||
|
||||
You can configure the system through a text-based user interface:
|
||||
|
||||
$ sudo -u moonfire-nvr moonfire-nvr config 2>debug-log
|
||||
|
||||
In the user interface, add your cameras under the "Edit cameras" dialog.
|
||||
There's a "Test" button to verify your settings directly from the dialog.
|
||||
|
||||
After the cameras look correct, go to "Edit retention" to assign disk space to
|
||||
each camera. Leave a little slack (at least 100 MB per camera) between the total
|
||||
limit and the filesystem capacity, even if you store nothing else on the disk.
|
||||
There are several reasons this is needed:
|
||||
|
||||
* The limit currently controls fully-written files only. There will be up
|
||||
to two minutes of video per camera of additional video.
|
||||
* The rotation happens after the limit is exceeded, not proactively.
|
||||
* Moonfire NVR currently doesn't account for the unused space in the final
|
||||
filesystem block at the end of each file.
|
||||
* Moonfire NVR doesn't account for the space used for directory listings.
|
||||
* If a file is open when it is deleted (such as if a HTTP client is
|
||||
downloading it), it stays around until the file is closed. Moonfire NVR
|
||||
currently doesn't account for this.
|
||||
|
||||
When finished, start the daemon:
|
||||
|
||||
$ sudo systemctl start moonfire-nvr
|
||||
|
||||
### System Service
|
||||
|
||||
Moonfire NVR can be run as a systemd service. If you used `prep.sh` this has
|
||||
been done for you. If not, Create
|
||||
`/etc/systemd/system/moonfire-nvr.service`:
|
||||
|
||||
[Unit]
|
||||
Description=Moonfire NVR
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/moonfire-nvr run \
|
||||
--sample-file-dir=/var/lib/moonfire-nvr/sample \
|
||||
--db-dir=/var/lib/moonfire-nvr/db \
|
||||
--http-addr=0.0.0.0:8080
|
||||
Environment=TZ=:/etc/localtime
|
||||
Environment=MOONFIRE_FORMAT=google-systemd
|
||||
Environment=MOONFIRE_LOG=info
|
||||
Type=simple
|
||||
User=moonfire-nvr
|
||||
Nice=-20
|
||||
Restart=on-abnormal
|
||||
CPUAccounting=true
|
||||
MemoryAccounting=true
|
||||
BlockIOAccounting=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
Note that the HTTP port currently has no authentication, encryption, or
|
||||
logging; it should not be directly exposed to the Internet.
|
||||
|
||||
Complete the installation through `systemctl` commands:
|
||||
|
||||
$ sudo systemctl daemon-reload
|
||||
$ sudo systemctl start moonfire-nvr
|
||||
$ sudo systemctl status moonfire-nvr
|
||||
$ sudo systemctl enable moonfire-nvr
|
||||
|
||||
See the [systemd](http://www.freedesktop.org/wiki/Software/systemd/)
|
||||
documentation for more information. The [manual
|
||||
pages](http://www.freedesktop.org/software/systemd/man/) for `systemd.service`
|
||||
and `systemctl` may be of particular interest.
|
70
guide/troubleshooting.md
Normal file
70
guide/troubleshooting.md
Normal file
@ -0,0 +1,70 @@
|
||||
# Troubleshooting
|
||||
|
||||
## Logs
|
||||
|
||||
While Moonfire NVR is running, logs will be written to stderr.
|
||||
|
||||
* When running `moonfire-nvr config`, you typically should redirect stderr
|
||||
to a text file to avoid poor interaction between the interactive stdout
|
||||
output and the logging.
|
||||
* When running through systemd, stderr will be redirected to the journal.
|
||||
Try `sudo journalctl --unit moonfire-nvr` to view the logs. You also
|
||||
likely want to set `MOONFIRE_FORMAT=google-systemd` to format logs as
|
||||
expected by systemd.
|
||||
|
||||
Logging options are controlled by environmental variables:
|
||||
|
||||
* `MOONFIRE_LOG` controls the log level. Its format is similar to the
|
||||
`RUST_LOG` variable used by the
|
||||
[env-logger](http://rust-lang-nursery.github.io/log/env_logger/) crate.
|
||||
`MOONFIRE_LOG=info` is the default.
|
||||
`MOONFIRE_LOG=info,moonfire_nvr=debug` gives more detailed logging of the
|
||||
`moonfire_nvr` crate itself.
|
||||
* `MOONFIRE_FORMAT` selects the output format. The two options currently
|
||||
accepted are `google` (the default, like the Google
|
||||
[glog](https://github.com/google/glog) package) and `google-systemd` (a
|
||||
variation for better systemd compatibility).
|
||||
|
||||
## Problems
|
||||
|
||||
### `Error: pts not monotonically increasing; got 26615520 then 26539470`
|
||||
|
||||
If your streams cut out with an error message like this one, there are a
|
||||
couple possibilities.
|
||||
|
||||
One is that your camera outputs [B
|
||||
frames](https://en.wikipedia.org/wiki/Video_compression_picture_types#Bi-directional_predicted_.28B.29_frames.2Fslices_.28macroblocks.29).
|
||||
If you believe this is the case, file a feature request; Moonfire NVR
|
||||
currently doesn't support B frames. You may be able to configure your camera
|
||||
to disable B frames in the meantime.
|
||||
|
||||
A more subtle problem occurs in cameras such as the Dahua Starlight series
|
||||
when the following is true:
|
||||
|
||||
* Audio is enabled (thus a single RTSP session has two streams).
|
||||
* The camera's clock changes abruptly. Note that many cameras use SNTP
|
||||
rather than NTP to adjust time, so they consistently step time rather
|
||||
than slew it.
|
||||
* They send RTCP Sender Reports (these include the NTP time).
|
||||
|
||||
Moonfire NVR currently uses the ffmpeg library to talk to the cameras. ffmpeg
|
||||
doesn't properly support this situation. It uses the NTP time to adjust the
|
||||
PTS and DTS, and thus experiences jumps forward and backward. The forward
|
||||
jumps cause one frame to be artificially lengthened. The backward jumps create
|
||||
an impossible situation which causes Moonfire NVR to abort the session and
|
||||
retry.
|
||||
|
||||
In the long term, Moonfire NVR will likely implement its own RTSP support.
|
||||
|
||||
In the short term, you can use either of two workarounds:
|
||||
|
||||
* Disable audio in the camera settings. Note that Moonfire NVR doesn't
|
||||
yet support recording audio anyway.
|
||||
* Disable time adjustment. You'll likely want to disable in-picture
|
||||
timestamps as well as they will become untrustworthy.
|
||||
|
||||
### `moonfire-nvr config` displays garbage
|
||||
|
||||
This happens if your machine is configured to a non-UTF-8 locale, due to
|
||||
gyscos/Cursive#13. As a workaround, type `export LC_ALL=en_US.UTF-8` prior to
|
||||
running `moonfire-nvr config`.
|
Loading…
Reference in New Issue
Block a user