Shinobi Pro Lands on Gitlab
commit
c940294f00
|
@ -0,0 +1 @@
|
||||||
|
docker-entrypoint.sh text eol=lf
|
|
@ -0,0 +1,12 @@
|
||||||
|
node_modules
|
||||||
|
videos
|
||||||
|
events
|
||||||
|
frames
|
||||||
|
web.old
|
||||||
|
.DS_Store
|
||||||
|
.vagrant
|
||||||
|
conf.json
|
||||||
|
super.json
|
||||||
|
dbdata
|
||||||
|
npm-debug.log
|
||||||
|
shinobi.sqlite
|
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
conf.json
|
|
@ -0,0 +1,76 @@
|
||||||
|
SHINOBI OPEN SOURCE SOFTWARE LICENSE AGREEMENT
|
||||||
|
Version 1, 04 June 2018
|
||||||
|
|
||||||
|
Copyright (C) 2018 Shinobi Systems <https://shinobi.systems>
|
||||||
|
|
||||||
|
We'll try to keep it simple. Thanks for using Shinobi Software!
|
||||||
|
|
||||||
|
Defintions.
|
||||||
|
|
||||||
|
In this End User Licence Agreement,
|
||||||
|
"EULA" shall mean this End User Licence Agreement
|
||||||
|
"Licenser" shall mean SHINOBI SYSTEMS
|
||||||
|
"Licensee" shall mean YOU, or the organisation (if any) on whose behalf YOU are taking the EULA.
|
||||||
|
|
||||||
|
"SOFTWARE PRODUCTS" or "SOFTWARE" or "PRODUCTS" shall mean GMASTER and any additional modules or add-ons delivered by Shinobi Systems. The term "SOFTWARE" includes, to the extent provided by SHINOBI SYSTEMS: 1) any revisions, updates and/or upgrades thereto; 2) any data, image or executable files, databases, data engines, computer software, or similar items customarily used or distributed with computer software products; 3) anything in any form whatsoever intended to be used with or in conjunction with the SOFTWARE; and 4) any associated media, documentation (including physical, electronic and on-line) and printed materials (the "Documentation").
|
||||||
|
|
||||||
|
Purpose of the Agreement.
|
||||||
|
|
||||||
|
The Short : Protect the rights of this Software Product and the Licenser.
|
||||||
|
|
||||||
|
The Long : The LICENSER grants the LICENSEE a non-exclusive, non-transferable and perpetual licence to use the SOFTWARE PRODUCTS listed therein and under the terms thereof. By accepting the terms and conditions established in this agreement, the LICENSEE does not acquire any ownership of copyright or other intellectual property rights in any part of the SOFTWARE PRODUCTS. The LICENSEE is only entitled to use the SOFTWARE PRODUCTS in accordance with the terms and conditions set forth by Shinobi Systems. By using the SOFTWARE PRODUCTS, the LICENSEE agrees to accept the terms and conditions presented.
|
||||||
|
|
||||||
|
LICENSEE must purchase the applicable subscription in any other use case unless otherwise granted. If the use case does not have a subscription applicable please contact a representative at support@shinobi.systems.
|
||||||
|
|
||||||
|
Conditions for Free (Unpaid) use.
|
||||||
|
|
||||||
|
- Use in a non commercial area for non commercial purposes
|
||||||
|
- Educational use
|
||||||
|
- Testing Purposes
|
||||||
|
- Use in a School like a elementary school, college, or university
|
||||||
|
|
||||||
|
Support Services.
|
||||||
|
|
||||||
|
The Maintenance and Support Service shall be contracted and provided as per selected plan agreement, taxes will be included in all prices for Support Services.
|
||||||
|
|
||||||
|
Support Services will only provide support services as per the selected agreement.
|
||||||
|
|
||||||
|
This is not the entire agreement on support services. You must also review all agreements provided with subscription plans provided.
|
||||||
|
|
||||||
|
Software Product Ownership.
|
||||||
|
|
||||||
|
This software is property of Shinobi Systems. LICENSEE must keep all copyright notices unchanged.
|
||||||
|
|
||||||
|
Modification of this Software Product.
|
||||||
|
|
||||||
|
LICENSEE may modify the code but LICENSEE must provide the source code if asked by law enforcement or an authorized Shinobi representative. LICENSEE must keep all copyright notices unchanged.
|
||||||
|
|
||||||
|
Software Product Rebranding or "White-Labelling".
|
||||||
|
|
||||||
|
LICENSEE can remove the Shinobi branding from the front end but all copyright notices must remain unchanged.
|
||||||
|
|
||||||
|
Software Product Contributions.
|
||||||
|
|
||||||
|
All contributed code becomes the property of Shinobi Systems. All contributors give permission to Shinobi and Shinobi developers to use the code however it is seen fit.
|
||||||
|
|
||||||
|
Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
Limitation of Liability.
|
||||||
|
|
||||||
|
LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM SHINOBI SYSTEMS AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO $5.00 CAD. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
|
||||||
|
This limitation applies to:
|
||||||
|
|
||||||
|
- anything related to the software, services, content (including code) on third-party Internet sites, or third-party programs; and
|
||||||
|
- claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
|
||||||
|
|
||||||
|
It also applies even if Shinobi Systems knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
|
||||||
|
|
||||||
|
Changes to the Agreement.
|
||||||
|
|
||||||
|
Shinobi Systems reserves the right to change the license and set of terms at any time. Continued use is agreement to those possible changes. Changes to this license will be provided in the commit history of the repository it is located in.
|
||||||
|
|
||||||
|
Legal Proceedings
|
||||||
|
|
||||||
|
All lawsuits must be filed in the city in which the current headquarters is based at the time of the filing.
|
|
@ -0,0 +1,3 @@
|
||||||
|
**Detailed Instructions for multiple Operating Systems can now be found in the docs.**
|
||||||
|
|
||||||
|
https://shinobi.video/docs/start
|
|
@ -0,0 +1 @@
|
||||||
|
installed.txt
|
|
@ -0,0 +1,17 @@
|
||||||
|
#### Fast Install (The Ninja Way)
|
||||||
|
|
||||||
|
1. Become `root` to use the installer and run Shinobi. Use one of the following to do so.
|
||||||
|
|
||||||
|
- Ubuntu 17.04, 17.10
|
||||||
|
- `sudo su`
|
||||||
|
- CentOS 7
|
||||||
|
- `su`
|
||||||
|
- MacOS 10.7(+)
|
||||||
|
- `su`
|
||||||
|
2. Download and run the installer.
|
||||||
|
|
||||||
|
```
|
||||||
|
bash <(curl -s https://raw.githubusercontent.com/ShinobiCCTV/Shinobi-Installer/master/shinobi-install.sh)
|
||||||
|
```
|
||||||
|
|
||||||
|
More info can be found here. https://shinobi.video/docs/start
|
|
@ -0,0 +1,5 @@
|
||||||
|
apt install git -y
|
||||||
|
git clone https://github.com/ShinobiCCTV/Shinobi.git -b dev Shinobi-dev
|
||||||
|
cd Shinobi-dev
|
||||||
|
chmod +x INSTALL/ubuntu-easyinstall.sh && INSTALL/ubuntu-easyinstall.sh
|
||||||
|
bash INSTALL/ubuntu-easyinstall.sh
|
|
@ -0,0 +1,5 @@
|
||||||
|
apt install git -y
|
||||||
|
git clone https://github.com/ShinobiCCTV/Shinobi.git Shinobi
|
||||||
|
cd Shinobi
|
||||||
|
chmod +x INSTALL/ubuntu-easyinstall.sh && INSTALL/ubuntu-easyinstall.sh
|
||||||
|
bash INSTALL/ubuntu-easyinstall.sh
|
|
@ -0,0 +1,188 @@
|
||||||
|
#!/bin/bash
|
||||||
|
echo "========================================================="
|
||||||
|
echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!=="
|
||||||
|
echo "========================================================="
|
||||||
|
echo "To answer yes type the letter (y) in lowercase and press ENTER."
|
||||||
|
echo "Default is no (N). Skip any components you already have or don't need."
|
||||||
|
echo "============="
|
||||||
|
if [ ! -e "./conf.json" ]; then
|
||||||
|
cp conf.sample.json conf.json
|
||||||
|
fi
|
||||||
|
if [ ! -e "./super.json" ]; then
|
||||||
|
echo "Default Superuser : admin@shinobi.video"
|
||||||
|
echo "Default Password : admin"
|
||||||
|
sudo cp super.sample.json super.json
|
||||||
|
echo "Shinobi - Do you want to enable superuser access?"
|
||||||
|
echo "This may be useful if passwords are forgotten or"
|
||||||
|
echo "if you would like to limit accessibility of an"
|
||||||
|
echo "account for business scenarios."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read createSuperJson
|
||||||
|
if [ "$createSuperJson" = "y" ] || [ "$createSuperJson" = "Y" ]; then
|
||||||
|
echo "Default Superuser : admin@shinobi.video"
|
||||||
|
echo "Default Password : admin"
|
||||||
|
echo "* You can edit these settings in \"super.json\" located in the Shinobi directory."
|
||||||
|
sudo cp super.sample.json super.json
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "Shinobi - Run yum update"
|
||||||
|
sudo yum update -y
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to Install FFMPEG?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read ffmpeginstall
|
||||||
|
if [ "$ffmpeginstall" = "y" ] || [ "$ffmpeginstall" = "Y" ]; then
|
||||||
|
echo "Shinobi - Do you want to Install FFMPEG with `apt` or download a static version provided with `npm`?"
|
||||||
|
echo "(a)pt or (N)pm"
|
||||||
|
echo "Press [ENTER] for default (npm)"
|
||||||
|
read ffmpegstaticinstall
|
||||||
|
if [ "$ffmpegstaticinstall" = "a" ] || [ "$ffmpegstaticinstall" = "A" ]; then
|
||||||
|
#Install EPEL Repo
|
||||||
|
sudo yum install epel-release -y
|
||||||
|
#Enable Nux Dextop repo for FFMPEG
|
||||||
|
sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
|
||||||
|
sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-1.el7.nux.noarch.rpm
|
||||||
|
sudo yum install ffmpeg ffmpeg-devel -y
|
||||||
|
else
|
||||||
|
sudo npm install ffmpeg-static
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "Shinobi - Do you want to Install Node.js?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read nodejsinstall
|
||||||
|
if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then
|
||||||
|
sudo wget https://rpm.nodesource.com/setup_8.x
|
||||||
|
sudo chmod +x setup_8.x
|
||||||
|
./setup_8.x
|
||||||
|
sudo yum install nodejs -y
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to use MariaDB or SQLite3?"
|
||||||
|
echo "SQLite3 is better for small installs"
|
||||||
|
echo "MariaDB (MySQL) is better for large installs"
|
||||||
|
echo "(S)QLite3 or (M)ariaDB?"
|
||||||
|
echo "Press [ENTER] for default (MariaDB)"
|
||||||
|
read sqliteormariadb
|
||||||
|
if [ "$sqliteormariadb" = "S" ] || [ "$sqliteormariadb" = "s" ]; then
|
||||||
|
sudo npm install jsonfile
|
||||||
|
sudo yum install -y sqlite sqlite-devel -y
|
||||||
|
sudo npm install sqlite3
|
||||||
|
node ./tools/modifyConfiguration.js databaseType=sqlite3
|
||||||
|
if [ ! -e "./shinobi.sqlite" ]; then
|
||||||
|
echo "Creating shinobi.sqlite for SQLite3..."
|
||||||
|
sudo cp sql/shinobi.sample.sqlite shinobi.sqlite
|
||||||
|
else
|
||||||
|
echo "shinobi.sqlite already exists. Continuing..."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to Install MariaDB?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlagree
|
||||||
|
if [ "$mysqlagree" = "y" ] || [ "$mysqlagree" = "Y" ]; then
|
||||||
|
sudo yum install mariadb mariadb-server -y
|
||||||
|
#Start mysql and enable on boot
|
||||||
|
sudo systemctl start mariadb
|
||||||
|
sudo systemctl enable mariadb
|
||||||
|
#Run mysql install
|
||||||
|
sudo mysql_secure_installation
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Database Installation"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlagreeData
|
||||||
|
if [ "$mysqlagreeData" = "y" ] || [ "$mysqlagreeData" = "Y" ]; then
|
||||||
|
echo "What is your SQL Username?"
|
||||||
|
read sqluser
|
||||||
|
echo "What is your SQL Password?"
|
||||||
|
read sqlpass
|
||||||
|
sudo mysql -u $sqluser -p$sqlpass -e "source sql/user.sql" || true
|
||||||
|
sudo mysql -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true
|
||||||
|
echo "Shinobi - Do you want to create a new user for viewing and managing cameras in Shinobi? You can do this later in the Superuser panel."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlDefaultData
|
||||||
|
if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then
|
||||||
|
escapeReplaceQuote='\\"'
|
||||||
|
groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1)
|
||||||
|
userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)
|
||||||
|
userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com"
|
||||||
|
userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)
|
||||||
|
userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}')
|
||||||
|
userDetails='{"days":"10"}'
|
||||||
|
userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g')
|
||||||
|
echo $userDetailsNew
|
||||||
|
apiIP='0.0.0.0'
|
||||||
|
apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
||||||
|
apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}'
|
||||||
|
apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g')
|
||||||
|
rm sql/default_user.sql || true
|
||||||
|
echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql"
|
||||||
|
sudo mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt"
|
||||||
|
echo "The following details will be shown again at the end of the installation."
|
||||||
|
echo "====================================="
|
||||||
|
echo "======= Login Credentials ======="
|
||||||
|
echo "|| Username : $userEmail"
|
||||||
|
echo "|| Password : $userPasswordPlain"
|
||||||
|
echo "|| API Key : $apiKey"
|
||||||
|
echo "====================================="
|
||||||
|
echo "====================================="
|
||||||
|
echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Install NPM Libraries"
|
||||||
|
sudo npm install
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Install PM2"
|
||||||
|
sudo npm install pm2 -g
|
||||||
|
echo "Shinobi - Finished"
|
||||||
|
sudo chmod -R 755 .
|
||||||
|
touch INSTALL/installed.txt
|
||||||
|
if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then
|
||||||
|
echo "=====================================" > INSTALL/installed.txt
|
||||||
|
echo "======= Login Credentials =======" >> INSTALL/installed.txt
|
||||||
|
echo "|| Username : $userEmail" >> INSTALL/installed.txt
|
||||||
|
echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt
|
||||||
|
echo "|| API Key : $apiKey" >> INSTALL/installed.txt
|
||||||
|
echo "=====================================" >> INSTALL/installed.txt
|
||||||
|
echo "=====================================" >> INSTALL/installed.txt
|
||||||
|
fi
|
||||||
|
echo "Shinobi - Start Shinobi and set to start on boot?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read startShinobi
|
||||||
|
if [ "$startShinobi" = "y" ] || [ "$startShinobi" = "Y" ]; then
|
||||||
|
sudo pm2 start camera.js
|
||||||
|
sudo pm2 start cron.js
|
||||||
|
sudo pm2 startup
|
||||||
|
sudo pm2 save
|
||||||
|
sudo pm2 list
|
||||||
|
fi
|
||||||
|
if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then
|
||||||
|
echo "details written to INSTALL/installed.txt"
|
||||||
|
echo "====================================="
|
||||||
|
echo "======= Login Credentials ======="
|
||||||
|
echo "|| Username : $userEmail"
|
||||||
|
echo "|| Password : $userPasswordPlain"
|
||||||
|
echo "|| API Key : $apiKey"
|
||||||
|
echo "====================================="
|
||||||
|
echo "====================================="
|
||||||
|
fi
|
||||||
|
if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then
|
||||||
|
echo "====================================="
|
||||||
|
echo "||===== Install Completed =====||"
|
||||||
|
echo "====================================="
|
||||||
|
echo "|| Login with the Superuser and create a new user!!"
|
||||||
|
echo "||==================================="
|
||||||
|
echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser."
|
||||||
|
echo "||==================================="
|
||||||
|
echo "|| Default Superuser : admin@shinobi.video"
|
||||||
|
echo "|| Default Password : admin"
|
||||||
|
echo "====================================="
|
||||||
|
echo "====================================="
|
||||||
|
else
|
||||||
|
echo "+=================================+"
|
||||||
|
echo "||===== Install Completed =====||"
|
||||||
|
echo "|| Access the main Shinobi panel at http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080 in your web browser."
|
||||||
|
echo "+=================================+"
|
||||||
|
fi
|
|
@ -0,0 +1,15 @@
|
||||||
|
#https://devtalk.nvidia.com/default/topic/1000340/cuda-setup-and-installation/-quot-nvidia-smi-has-failed-because-it-couldn-t-communicate-with-the-nvidia-driver-quot-ubuntu-16-04/4
|
||||||
|
sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
|
||||||
|
sudo echo "# NVIDIA Graphics Driver Repo (Added by Shinobi installer)" >> /etc/apt/sources.list
|
||||||
|
sudo echo "# Public Key : sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub" >> /etc/apt/sources.list
|
||||||
|
sudo echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" >> /etc/apt/sources.list
|
||||||
|
sudo apt update
|
||||||
|
sudo apt-get -y install cuda-drivers
|
||||||
|
|
||||||
|
echo "After rebooting you need to run part 2. The file is named `cuda9-part2-after-reboot.sh`."
|
||||||
|
echo "Reboot is required. Do it now?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read rebootTheMachineHomie
|
||||||
|
if [ "$rebootTheMachineHomie" = "y" ] || [ "$rebootTheMachineHomie" = "Y" ]; then
|
||||||
|
sudo reboot
|
||||||
|
fi
|
|
@ -0,0 +1,2 @@
|
||||||
|
sudo apt-get -y install cuda-toolkit-9-1
|
||||||
|
nvidia-smi
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
echo "============="
|
||||||
|
echo "Install FFMPEG"
|
||||||
|
echo "What build of FFMPEG do you require?"
|
||||||
|
echo "If you don't know check your CPU specs for a hint."
|
||||||
|
echo "- 32bit"
|
||||||
|
echo "- 64bit"
|
||||||
|
echo "- armel-32bit"
|
||||||
|
echo "- armhf-32bit"
|
||||||
|
read ffmpegbuild
|
||||||
|
wget "https://s3.amazonaws.com/cloudcamio/ffmpeg-release-$ffmpegbuild-static.tar.xz"
|
||||||
|
tar xf "ffmpeg-release-$ffmpegbuild-static.tar.xz"
|
||||||
|
mv "ffmpeg-3.3-$ffmpegbuild-static/ffmpeg" "/usr/bin/ffmpeg"
|
||||||
|
mv "ffmpeg-3.3-$ffmpegbuild-static/ffmpeg-10bit" "/usr/bin/ffmpeg-10bit"
|
||||||
|
mv "ffmpeg-3.3-$ffmpegbuild-static/ffprobe" "/usr/bin/ffprobe"
|
||||||
|
mv "ffmpeg-3.3-$ffmpegbuild-static/ffserver" "/usr/bin/ffserver"
|
||||||
|
chmod +x /usr/bin/ffmpeg
|
||||||
|
chmod +x /usr/bin/ffmpeg-10bit
|
||||||
|
chmod +x /usr/bin/ffprobe
|
||||||
|
chmod +x /usr/bin/ffserver
|
||||||
|
rm -rf "ffmpeg-3.3-$ffmpegbuild-static"
|
||||||
|
rm -rf "ffmpeg-release-$ffmpegbuild-static.tar.xz"
|
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/tcsh
|
||||||
|
echo "========================================================="
|
||||||
|
echo "==== Shinobi : The Open Source CCTV and NVR Solution ===="
|
||||||
|
echo "========================================================="
|
||||||
|
echo "This script should run as root inside your jail from the root"
|
||||||
|
echo "of the cloned git repository."
|
||||||
|
echo "To answer yes type the letter (y) in lowercase and press ENTER."
|
||||||
|
echo "Default is no (N). Skip any components you already have or don't need."
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to Install Node.js?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
set nodejsinstall = $<
|
||||||
|
if ( $nodejsinstall == "y" ) then
|
||||||
|
pkg install -y node npm
|
||||||
|
endif
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to Install FFMPEG?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
set ffmpeginstall = $<
|
||||||
|
if ( $ffmpeginstall == "y" ) then
|
||||||
|
pkg install -y ffmpeg libav x264 x265
|
||||||
|
endif
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Database Installation"
|
||||||
|
echo "WARNING - This requires an existing and running mariadb service."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
set mysqlagreeData = $<
|
||||||
|
if ( $mysqlagreeData == "y" ) then
|
||||||
|
echo "What is your SQL Username?"
|
||||||
|
set sqluser = $<
|
||||||
|
echo "What is your SQL Password?"
|
||||||
|
set sqlpass = $<
|
||||||
|
echo "What is your SQL Host?"
|
||||||
|
set sqlhost = $<
|
||||||
|
echo "Installing mariadb client..."
|
||||||
|
pkg install -y mariadb102-client
|
||||||
|
echo "Installing database schema..."
|
||||||
|
mysql -h $sqlhost -u $sqluser -p$sqlpass -e "source sql/user.sql" || true
|
||||||
|
mysql -h $sqlhost -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true
|
||||||
|
echo "Shinobi - Use the /super endpoint to create your super user."
|
||||||
|
endif
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Install NPM Libraries"
|
||||||
|
npm install
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Install PM2"
|
||||||
|
npm install pm2 -g
|
||||||
|
if (! -e "./conf.json" ) then
|
||||||
|
cp conf.sample.json conf.json
|
||||||
|
endif
|
||||||
|
if (! -e "./super.json" ) then
|
||||||
|
echo "Default Superuser : admin@shinobi.video"
|
||||||
|
echo "Default Password : admin"
|
||||||
|
cp super.sample.json super.json
|
||||||
|
endif
|
||||||
|
echo "Shinobi - Start Shinobi?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
set startShinobi = $<
|
||||||
|
if ( $startShinobi == "y" ) then
|
||||||
|
set PM2BIN="$PWD/node_modules/pm2/bin"
|
||||||
|
$PM2BIN/pm2 start camera.js
|
||||||
|
$PM2BIN/pm2 start cron.js
|
||||||
|
$PM2BIN/pm2 save
|
||||||
|
$PM2BIN/pm2 list
|
||||||
|
endif
|
||||||
|
echo "Shinobi - Start on boot?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
set startupShinobi = $<
|
||||||
|
if ( $startupShinobi == "y" ) then
|
||||||
|
set PM2BIN="$PWD/node_modules/pm2/bin"
|
||||||
|
$PM2BIN/pm2 startup rcd
|
||||||
|
endif
|
||||||
|
echo "Shinobi - Finished"
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
echo "========================================================="
|
||||||
|
echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!=="
|
||||||
|
echo "=================== Mac OS Install Part 2 ==============="
|
||||||
|
echo "========================================================="
|
||||||
|
echo "Shinobi - Database Installation"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlagreeData
|
||||||
|
if [ "$mysqlagreeData" = "y" ]; then
|
||||||
|
echo "Shinobi will now use root for database installation..."
|
||||||
|
echo "What is your SQL Username?"
|
||||||
|
read sqluser
|
||||||
|
echo "What is your SQL Password?"
|
||||||
|
read sqlpass
|
||||||
|
echo "You may now be asked for your Administator (root for Mac OS, not MySQL) password"
|
||||||
|
sudo mysql -u $sqluser -p$sqlpass -e "source sql/user.sql" || true
|
||||||
|
sudo mysql -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true
|
||||||
|
echo "Shinobi - Do you want to create a new user for viewing and managing cameras in Shinobi? You can do this later in the Superuser panel."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlDefaultData
|
||||||
|
if [ "$mysqlDefaultData" = "y" ]; then
|
||||||
|
escapeReplaceQuote='\\"'
|
||||||
|
groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1)
|
||||||
|
userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)
|
||||||
|
userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com"
|
||||||
|
userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)
|
||||||
|
userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}')
|
||||||
|
userDetails='{"days":"10"}'
|
||||||
|
userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g')
|
||||||
|
echo $userDetailsNew
|
||||||
|
apiIP='0.0.0.0'
|
||||||
|
apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
||||||
|
apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}'
|
||||||
|
apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g')
|
||||||
|
rm sql/default_user.sql || true
|
||||||
|
echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql"
|
||||||
|
sudo mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt"
|
||||||
|
echo "The following details will be shown again at the end of the installation."
|
||||||
|
echo "====================================="
|
||||||
|
echo "======= Login Credentials ======="
|
||||||
|
echo "|| Username : $userEmail"
|
||||||
|
echo "|| Password : $userPasswordPlain"
|
||||||
|
echo "|| API Key : $apiKey"
|
||||||
|
echo "====================================="
|
||||||
|
echo "====================================="
|
||||||
|
echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Install NPM Libraries"
|
||||||
|
sudo npm install
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Install PM2"
|
||||||
|
sudo npm install pm2 -g
|
||||||
|
if [ ! -e "./conf.json" ]; then
|
||||||
|
sudo cp conf.sample.json conf.json
|
||||||
|
fi
|
||||||
|
if [ ! -e "./super.json" ]; then
|
||||||
|
echo "Default Superuser : admin@shinobi.video"
|
||||||
|
echo "Default Password : admin"
|
||||||
|
sudo cp super.sample.json super.json
|
||||||
|
fi
|
||||||
|
echo "Shinobi - Finished"
|
||||||
|
touch INSTALL/installed.txt
|
||||||
|
sudo chmod -R 755 .
|
||||||
|
echo "=====================================" > INSTALL/installed.txt
|
||||||
|
echo "======= Login Credentials =======" >> INSTALL/installed.txt
|
||||||
|
echo "|| Username : $userEmail" >> INSTALL/installed.txt
|
||||||
|
echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt
|
||||||
|
echo "|| API Key : $apiKey" >> INSTALL/installed.txt
|
||||||
|
echo "=====================================" >> INSTALL/installed.txt
|
||||||
|
echo "=====================================" >> INSTALL/installed.txt
|
||||||
|
echo "Shinobi - Start Shinobi and set to start on boot?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read startShinobi
|
||||||
|
if [ "$startShinobi" = "y" ]; then
|
||||||
|
sudo pm2 start camera.js
|
||||||
|
sudo pm2 startup
|
||||||
|
sudo pm2 save
|
||||||
|
sudo pm2 list
|
||||||
|
fi
|
||||||
|
echo "details written to INSTALL/installed.txt"
|
||||||
|
echo "====================================="
|
||||||
|
echo "======= Login Credentials ======="
|
||||||
|
echo "|| Username : $userEmail"
|
||||||
|
echo "|| Password : $userPasswordPlain"
|
||||||
|
echo "|| API Key : $apiKey"
|
||||||
|
echo "====================================="
|
||||||
|
echo "====================================="
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/bin/bash
|
||||||
|
echo "========================================================="
|
||||||
|
echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!=="
|
||||||
|
echo "=================== Mac OS Install Part 1 ==============="
|
||||||
|
echo "========================================================="
|
||||||
|
echo "To answer yes type the letter (y) in lowercase and press ENTER."
|
||||||
|
echo "Default is no (N). Skip any components you already have or don't need."
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to Install Node.js?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read nodejsinstall
|
||||||
|
if [ "$nodejsinstall" = "y" ]; then
|
||||||
|
curl -o node-v8.9.3.pkg https://nodejs.org/dist/v8.9.3/node-v8.9.3.pkg
|
||||||
|
sudo installer -pkg node-v8.9.3.pkg -target /
|
||||||
|
rm node-v8.9.3.pkg
|
||||||
|
sudo ln -s /usr/local/bin/node /usr/bin/nodejs
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to Install FFmpeg?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read ffmpeginstall
|
||||||
|
if [ "$ffmpeginstall" = "y" ]; then
|
||||||
|
echo "Shinobi - Installing FFmpeg"
|
||||||
|
curl -o ffmpeg.zip https://cdn.shinobi.video/installers/ffmpeg-3.4.1-macos.zip
|
||||||
|
sudo unzip ffmpeg.zip
|
||||||
|
sudo rm ffmpeg.zip
|
||||||
|
sudo mv ffmpeg-3.4.1-macos/ffmpeg /usr/bin/ffmpeg
|
||||||
|
sudo mv ffmpeg-3.4.1-macos/ffplay /usr/bin/ffplay
|
||||||
|
sudo mv ffmpeg-3.4.1-macos/ffprobe /usr/bin/ffprobe
|
||||||
|
sudo mv ffmpeg-3.4.1-macos/ffserver /usr/bin/ffserver
|
||||||
|
sudo chmod +x /usr/local/bin/ffmpeg
|
||||||
|
sudo chmod +x /usr/local/bin/ffplay
|
||||||
|
sudo chmod +x /usr/local/bin/ffprobe
|
||||||
|
sudo chmod +x /usr/local/bin/ffserver
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to Install MySQL? Choose No if you have MySQL or MySQL already."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlagree
|
||||||
|
if [ "$mysqlagree" = "y" ]; then
|
||||||
|
echo "Shinobi - Installing MySQL"
|
||||||
|
bash <(curl -Ls http://git.io/eUx7rg)
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "============="
|
||||||
|
echo "You must now close this terminal window and reopen it."
|
||||||
|
echo "Reopen the Shinobi folder and run"
|
||||||
|
echo "sudo sh INSTALL/macos-part2.sh"
|
||||||
|
echo "============="
|
||||||
|
echo "============="
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/bash
|
||||||
|
echo "Shinobi Installer"
|
||||||
|
echo "========"
|
||||||
|
echo "Select your OS"
|
||||||
|
echo "If your OS is not on the list please refer to the docs."
|
||||||
|
echo "========"
|
||||||
|
echo "1. Ubuntu"
|
||||||
|
echo "2. CentOS"
|
||||||
|
echo "3. MacOS"
|
||||||
|
echo "4. FreeBSD"
|
||||||
|
echo "========"
|
||||||
|
read oschoicee
|
||||||
|
case $oschoicee in
|
||||||
|
"1")
|
||||||
|
chmod +x INSTALL/ubuntu.sh
|
||||||
|
sh INSTALL/ubuntu.sh
|
||||||
|
;;
|
||||||
|
"2")
|
||||||
|
chmod +x INSTALL/centos.sh
|
||||||
|
INSTALL/centos.sh
|
||||||
|
;;
|
||||||
|
"3")
|
||||||
|
chmod +x INSTALL/macos.sh
|
||||||
|
INSTALL/macos.sh
|
||||||
|
;;
|
||||||
|
"4")
|
||||||
|
chmod +x INSTALL/freebsd.sh
|
||||||
|
INSTALL/freebsd.sh
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Choice not found."
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Install prerequisites
|
||||||
|
# this includes all the ones missing from OpenALPR's guide.
|
||||||
|
sudo apt install libtesseract-dev git cmake build-essential libleptonica-dev -y
|
||||||
|
sudo apt install liblog4cplus-dev libcurl3-dev -y
|
||||||
|
sudo apt install libleptonica-dev -y
|
||||||
|
sudo apt install libcurl4-openssl-dev -y
|
||||||
|
sudo apt install liblog4cplus-dev -y
|
||||||
|
sudo apt install beanstalkd -y
|
||||||
|
sudo apt install openjdk-8-jdk -y
|
||||||
|
|
||||||
|
# Clone the latest code from GitHub
|
||||||
|
git clone https://github.com/openalpr/openalpr.git
|
||||||
|
|
||||||
|
# Setup the build directory
|
||||||
|
cd openalpr/src
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
# setup the compile environment
|
||||||
|
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc –DCOMPILE_GPU=1 -D WITH_GPU_DETECTOR=ON ..
|
||||||
|
|
||||||
|
# compile the library
|
||||||
|
make
|
||||||
|
|
||||||
|
# Install the binaries/libraries to your local system (prefix is /usr)
|
||||||
|
sudo make install
|
||||||
|
|
||||||
|
# Test the library
|
||||||
|
wget http://plates.openalpr.com/h786poj.jpg -O lp.jpg
|
||||||
|
alpr lp.jpg
|
||||||
|
rm lp.jpg
|
|
@ -0,0 +1,80 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# OpenCV CUDA
|
||||||
|
if [ $(dpkg-query -W -f='${Status}' git 2>/dev/null | grep -c "ok installed") -eq 0 ]; then
|
||||||
|
echo "Installing Git..."
|
||||||
|
apt install git -y;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -e "./opencv" ]; then
|
||||||
|
echo "Downloading OpenCV..."
|
||||||
|
git clone https://github.com/opencv/opencv.git
|
||||||
|
cd opencv
|
||||||
|
git checkout 3.4.0
|
||||||
|
cd ..
|
||||||
|
fi
|
||||||
|
if [ ! -e "./opencv_contrib" ]; then
|
||||||
|
echo "Downloading OpenCV Modules..."
|
||||||
|
git clone https://github.com/opencv/opencv_contrib.git
|
||||||
|
cd opencv_contrib
|
||||||
|
git checkout 3.4.0
|
||||||
|
cd ..
|
||||||
|
fi
|
||||||
|
echo "Opening OpenCV Directory..."
|
||||||
|
cd opencv
|
||||||
|
if [ ! -e "./build" ]; then
|
||||||
|
echo "Creating OpenCV Build Directory..."
|
||||||
|
mkdir build
|
||||||
|
fi
|
||||||
|
echo "Entering OpenCV Build Directory..."
|
||||||
|
cd build
|
||||||
|
echo "*****************"
|
||||||
|
flavor=$(cat /var/log/installer/media-info)
|
||||||
|
echo "$flavor"
|
||||||
|
echo "*****************"
|
||||||
|
echo "Adding Additional Repository"
|
||||||
|
echo "http://security.ubuntu.com/ubuntu"
|
||||||
|
if [ "$flavor" = *"Artful"* ]; then
|
||||||
|
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu artful-security main"
|
||||||
|
fi
|
||||||
|
if [ "$flavor" = *"Zesty"* ]; then
|
||||||
|
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu zesty-security main"
|
||||||
|
fi
|
||||||
|
if [ "$flavor" = *"Xenial"* ]; then
|
||||||
|
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
|
||||||
|
fi
|
||||||
|
if [ "$flavor" = *"Trusty"* ]; then
|
||||||
|
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu trusty-security main"
|
||||||
|
fi
|
||||||
|
echo "Downloading Libraries"
|
||||||
|
sudo apt-get install libjpeg-dev libpango1.0-dev libgif-dev build-essential gcc-6 g++-6 -y;
|
||||||
|
sudo apt-get install libxvidcore-dev libx264-dev -y;
|
||||||
|
sudo apt-get install libatlas-base-dev gfortran -y;
|
||||||
|
|
||||||
|
sudo apt install build-essential cmake pkg-config unzip ffmpeg qtbase5-dev python-dev python3-dev python-numpy python3-numpy libhdf5-dev libgtk-3-dev libdc1394-22 libdc1394-22-dev libjpeg-dev libtiff5-dev libtesseract-dev -y;
|
||||||
|
|
||||||
|
sudo apt install libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer-plugins-base1.0-0 libgstreamer-plugins-base1.0-dev libpng16-16 libpng-dev libv4l-dev libtbb-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev v4l-utils libleptonica-dev -y
|
||||||
|
|
||||||
|
echo "Setting CUDA Paths"
|
||||||
|
export LD_LIBRARY_PATH=/usr/local/cuda/lib
|
||||||
|
export PATH=$PATH:/usr/local/cuda/bin
|
||||||
|
echo "Configure OpenCV Build"
|
||||||
|
|
||||||
|
cmake -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_NVCUVID=ON -D FORCE_VTK=ON -D WITH_XINE=ON -D WITH_CUDA=ON -D WITH_OPENGL=ON -D WITH_TBB=ON -D WITH_OPENCL=ON -D CMAKE_BUILD_TYPE=RELEASE -D CUDA_NVCC_FLAGS="-D_FORCE_INLINES --expt-relaxed-constexpr" -D WITH_GDAL=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/ -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -D CXXFLAGS="-std=c++11" -DCMAKE_CXX_COMPILER=g++-6 -DCMAKE_C_COMPILER=gcc-6 ..
|
||||||
|
|
||||||
|
echo "Start OpenCV Build"
|
||||||
|
make -j "$(nproc)"
|
||||||
|
echo "Install OpenCV Build"
|
||||||
|
sudo make install
|
||||||
|
sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
|
||||||
|
sudo ldconfig
|
||||||
|
sudo apt-get update
|
||||||
|
echo "============="
|
||||||
|
echo "Done installing OpenCV!"
|
||||||
|
echo "============="
|
||||||
|
echo "Delete OpenCV source files? This will save a lot of space but it will be more tedious to uninstall OpenCV later."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read opencvuninstall
|
||||||
|
if [ "$opencvuninstall" = "y" ] || [ "$opencvuninstall" = "Y" ]; then
|
||||||
|
rm -rf opencv
|
||||||
|
rm -rf opencv_contrib
|
||||||
|
fi
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
if [ -e "INSTALL/installed.txt" ]; then
|
||||||
|
echo "Starting Shinobi"
|
||||||
|
pm2 start camera.js
|
||||||
|
pm2 start cron.js
|
||||||
|
pm2 logs
|
||||||
|
fi
|
||||||
|
if [ ! -e "INSTALL/installed.txt" ]; then
|
||||||
|
chmod +x INSTALL/now.sh&&INSTALL/now.sh
|
||||||
|
fi
|
|
@ -0,0 +1,175 @@
|
||||||
|
#!/bin/bash
|
||||||
|
echo "Shinobi - Do you want to Install Node.js?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read nodejsinstall
|
||||||
|
if [ "$nodejsinstall" = "y" ]; then
|
||||||
|
wget https://deb.nodesource.com/setup_8.x
|
||||||
|
chmod +x setup_8.x
|
||||||
|
./setup_8.x
|
||||||
|
sudo apt install nodejs -y
|
||||||
|
rm setup_8.x
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Detect Ubuntu Version
|
||||||
|
echo "============="
|
||||||
|
echo " Detecting Ubuntu Version"
|
||||||
|
echo "============="
|
||||||
|
declare -i getubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1)
|
||||||
|
echo "============="
|
||||||
|
echo " Ubuntu Version: $getubuntuversion"
|
||||||
|
echo "============="
|
||||||
|
if [[ "$getubuntuversion" == "16" || "$getubuntuversion" < "16" ]]; then
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Get FFMPEG 3.x from ppa:jonathonf/ffmpeg-3"
|
||||||
|
sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y
|
||||||
|
sudo apt update -y && sudo apt install ffmpeg libav-tools x264 x265 -y
|
||||||
|
echo "============="
|
||||||
|
else
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Installing FFMPEG"
|
||||||
|
sudo apt install ffmpeg libav-tools x264 x265 -y
|
||||||
|
echo "============="
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install MariaDB
|
||||||
|
echo "Shinobi - Do you want to Install MariaDB? Choose No if you have MySQL."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlagree
|
||||||
|
if [ "$mysqlagree" = "y" ]; then
|
||||||
|
echo "Shinobi - Installing MariaDB"
|
||||||
|
echo "Password for root SQL user, If you are installing SQL now then you may put anything:"
|
||||||
|
read sqlpass
|
||||||
|
echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections
|
||||||
|
echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections
|
||||||
|
apt install mariadb-server -y
|
||||||
|
service mysql start
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure files have correct perms
|
||||||
|
chmod -R 755 .
|
||||||
|
|
||||||
|
# Database Installation
|
||||||
|
#Check If Mysql-Server is already installed
|
||||||
|
|
||||||
|
echo "============="
|
||||||
|
echo "Checking for mysql-server"
|
||||||
|
echo "============="
|
||||||
|
dpkg -s mysql-server &> /dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "+====================================+"
|
||||||
|
echo "| Warning MYSQL SERVER IS INSTALLED! |"
|
||||||
|
echo "+====================================+"
|
||||||
|
echo "| DO YOU WANT TO INSTALL MariaDB? |"
|
||||||
|
echo "| This will remove MYSQL-Server! |"
|
||||||
|
echo "+====================================+"
|
||||||
|
echo "Shinobi - Do you want to Install MariaDB?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read installmariadb
|
||||||
|
if [ "$installmariadb" = "y" ]; then
|
||||||
|
echo "+=============================================+"
|
||||||
|
echo "| This will DESTORY ALL DATA ON MYSQL SERVER! |"
|
||||||
|
echo "+=============================================+"
|
||||||
|
echo "Please type the following to continue"
|
||||||
|
echo "DESTORY!"
|
||||||
|
read mysqlagree
|
||||||
|
if [ "$mysqlagree" = "DESTORY!" ]; then
|
||||||
|
echo "Shinobi - Installing MariaDB"
|
||||||
|
echo "Password for root SQL user, If you are installing SQL now then you may put anything:"
|
||||||
|
read sqlpass
|
||||||
|
echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections
|
||||||
|
echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections
|
||||||
|
#Create my.cnf file
|
||||||
|
echo "[client]" >> ~/.my.cnf
|
||||||
|
echo "user=root" >> ~/.my.cnf
|
||||||
|
echo "password=$sqlpass" >> ~/.my.cnf
|
||||||
|
chmod 755 ~/.my.cnf
|
||||||
|
apt install mariadb-server
|
||||||
|
service mysql start
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Shinobi - Do you want to Install MariaDB?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlagree
|
||||||
|
if [ "$mysqlagree" = "y" ]; then
|
||||||
|
echo "Shinobi - Installing MariaDB"
|
||||||
|
echo "Password for root SQL user, If you are installing SQL now then you may put anything:"
|
||||||
|
read sqlpass
|
||||||
|
echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections
|
||||||
|
echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections
|
||||||
|
echo "[client]" >> ~/.my.cnf
|
||||||
|
echo "user=root" >> ~/.my.cnf
|
||||||
|
echo "password=$sqlpass" >> ~/.my.cnf
|
||||||
|
chmod 755 ~/.my.cnf
|
||||||
|
apt install mariadb-server -y
|
||||||
|
service mysql start
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod -R 755 .
|
||||||
|
echo "Shinobi - Database Installation"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlagreeData
|
||||||
|
if [ "$mysqlagreeData" = "y" ]; then
|
||||||
|
mysql -e "source sql/user.sql" || true
|
||||||
|
mysql -e "source sql/framework.sql" || true
|
||||||
|
echo "Shinobi - Do you want to Install Default Data (default_data.sql)?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlDefaultData
|
||||||
|
if [ "$mysqlDefaultData" = "y" ]; then
|
||||||
|
escapeReplaceQuote='\\"'
|
||||||
|
groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1)
|
||||||
|
userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)
|
||||||
|
userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com"
|
||||||
|
userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)
|
||||||
|
userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}')
|
||||||
|
userDetails='{"days":"10"}'
|
||||||
|
userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g')
|
||||||
|
echo $userDetailsNew
|
||||||
|
apiIP='0.0.0.0'
|
||||||
|
apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
||||||
|
apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}'
|
||||||
|
apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g')
|
||||||
|
rm sql/default_user.sql || true
|
||||||
|
echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql"
|
||||||
|
mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt"
|
||||||
|
echo "====================================="
|
||||||
|
echo "=======!! Login Credentials !!======="
|
||||||
|
echo "|| Username : $userEmail"
|
||||||
|
echo "|| Password : $userPasswordPlain"
|
||||||
|
echo "|| API Key : $apiKey"
|
||||||
|
echo "====================================="
|
||||||
|
echo "====================================="
|
||||||
|
echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install NPM Libraries
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Install NPM Libraries"
|
||||||
|
npm install
|
||||||
|
echo "============="
|
||||||
|
|
||||||
|
#Install PM2
|
||||||
|
echo "Shinobi - Install PM2"
|
||||||
|
sudo npm install pm2 -g
|
||||||
|
if [ ! -e "./conf.json" ]; then
|
||||||
|
cp conf.sample.json conf.json
|
||||||
|
fi
|
||||||
|
if [ ! -e "./super.json" ]; then
|
||||||
|
getip=$(ip route get 8.8.8.8 | awk '{print $NF; exit}')
|
||||||
|
echo "Admin panel default url: http://$getip:8080/super"
|
||||||
|
echo "Default Superuser : admin@shinobi.video"
|
||||||
|
echo "Default Password : admin"
|
||||||
|
cp super.sample.json super.json
|
||||||
|
fi
|
||||||
|
echo "Shinobi - Finished"
|
||||||
|
touch INSTALL/installed.txt
|
||||||
|
echo "Shinobi - Start Shinobi?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read startShinobi
|
||||||
|
if [ "$startShinobi" = "y" ]; then
|
||||||
|
pm2 start camera.js
|
||||||
|
pm2 start cron.js
|
||||||
|
pm2 list
|
||||||
|
fi
|
|
@ -0,0 +1,202 @@
|
||||||
|
#!/bin/bash
|
||||||
|
echo "========================================================="
|
||||||
|
echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!=="
|
||||||
|
echo "========================================================="
|
||||||
|
echo "To answer yes type the letter (y) in lowercase and press ENTER."
|
||||||
|
echo "Default is no (N). Skip any components you already have or don't need."
|
||||||
|
echo "============="
|
||||||
|
if [ ! -e "./conf.json" ]; then
|
||||||
|
sudo cp conf.sample.json conf.json
|
||||||
|
fi
|
||||||
|
if [ ! -e "./super.json" ]; then
|
||||||
|
echo "Shinobi - Do you want to enable superuser access?"
|
||||||
|
echo "This may be useful if passwords are forgotten or"
|
||||||
|
echo "if you would like to limit accessibility of an"
|
||||||
|
echo "account for business scenarios."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read createSuperJson
|
||||||
|
if [ "$createSuperJson" = "y" ] || [ "$createSuperJson" = "Y" ]; then
|
||||||
|
echo "Default Superuser : admin@shinobi.video"
|
||||||
|
echo "Default Password : admin"
|
||||||
|
echo "* You can edit these settings in \"super.json\" located in the Shinobi directory."
|
||||||
|
sudo cp super.sample.json super.json
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "Shinobi - Do you want to Install Node.js?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read nodejsinstall
|
||||||
|
if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then
|
||||||
|
wget https://deb.nodesource.com/setup_8.x
|
||||||
|
chmod +x setup_8.x
|
||||||
|
./setup_8.x
|
||||||
|
sudo apt install nodejs -y
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to Install FFMPEG?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read ffmpeginstall
|
||||||
|
if [ "$ffmpeginstall" = "y" ] || [ "$ffmpeginstall" = "Y" ]; then
|
||||||
|
echo "Shinobi - Do you want to Install FFMPEG with `apt` or download a static version provided with `npm`?"
|
||||||
|
echo "(a)pt or (N)pm"
|
||||||
|
echo "Press [ENTER] for default (npm)"
|
||||||
|
read ffmpegstaticinstall
|
||||||
|
if [ "$ffmpegstaticinstall" = "a" ] || [ "$ffmpegstaticinstall" = "A" ]; then
|
||||||
|
#Detect Ubuntu Version
|
||||||
|
echo "============="
|
||||||
|
echo " Detecting Ubuntu Version"
|
||||||
|
echo "============="
|
||||||
|
declare -i getubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1)
|
||||||
|
echo "============="
|
||||||
|
echo " Ubuntu Version: $getubuntuversion"
|
||||||
|
echo "============="
|
||||||
|
if [[ "$getubuntuversion" == "16" || "$getubuntuversion" < "16" ]]; then
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Get FFMPEG 3.x from ppa:jonathonf/ffmpeg-3"
|
||||||
|
sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y
|
||||||
|
sudo apt update -y && sudo apt install ffmpeg libav-tools x264 x265 -y
|
||||||
|
echo "============="
|
||||||
|
else
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Installing FFMPEG"
|
||||||
|
sudo apt install ffmpeg -y
|
||||||
|
echo "============="
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
sudo npm install ffmpeg-static
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Do you want to use MariaDB or SQLite3?"
|
||||||
|
echo "SQLite3 is better for small installs"
|
||||||
|
echo "MariaDB (MySQL) is better for large installs"
|
||||||
|
echo "(S)QLite3 or (M)ariaDB?"
|
||||||
|
echo "Press [ENTER] for default (MariaDB)"
|
||||||
|
read sqliteormariadb
|
||||||
|
if [ "$sqliteormariadb" = "S" ] || [ "$sqliteormariadb" = "s" ]; then
|
||||||
|
sudo npm install jsonfile
|
||||||
|
sudo apt-get install sqlite3 libsqlite3-dev -y
|
||||||
|
sudo npm install sqlite3
|
||||||
|
node ./tools/modifyConfiguration.js databaseType=sqlite3
|
||||||
|
if [ ! -e "./shinobi.sqlite" ]; then
|
||||||
|
echo "Creating shinobi.sqlite for SQLite3..."
|
||||||
|
sudo cp sql/shinobi.sample.sqlite shinobi.sqlite
|
||||||
|
else
|
||||||
|
echo "shinobi.sqlite already exists. Continuing..."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Shinobi - Do you want to Install MariaDB? Choose No if you already have it."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlagree
|
||||||
|
if [ "$mysqlagree" = "y" ] || [ "$mysqlagree" = "Y" ]; then
|
||||||
|
echo "Shinobi - Installing MariaDB"
|
||||||
|
echo "Password for root SQL user, If you are installing SQL now then you may put anything:"
|
||||||
|
read sqlpass
|
||||||
|
echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections
|
||||||
|
echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections
|
||||||
|
sudo apt install mariadb-server -y
|
||||||
|
sudo service mysql start
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Database Installation"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlagreeData
|
||||||
|
if [ "$mysqlagreeData" = "y" ] || [ "$mysqlagreeData" = "Y" ]; then
|
||||||
|
if [ "$mysqlagree" = "y" ] || [ "$mysqlagree" = "Y" ]; then
|
||||||
|
sqluser="root"
|
||||||
|
fi
|
||||||
|
if [ ! "$mysqlagree" = "y" ]; then
|
||||||
|
echo "What is your SQL Username?"
|
||||||
|
read sqluser
|
||||||
|
echo "What is your SQL Password?"
|
||||||
|
read sqlpass
|
||||||
|
fi
|
||||||
|
sudo mysql -u $sqluser -p$sqlpass -e "source sql/user.sql" || true
|
||||||
|
sudo mysql -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true
|
||||||
|
echo "Shinobi - Do you want to create a new user for viewing and managing cameras in Shinobi? You can do this later in the Superuser panel."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read mysqlDefaultData
|
||||||
|
if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then
|
||||||
|
escapeReplaceQuote='\\"'
|
||||||
|
groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1)
|
||||||
|
userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)
|
||||||
|
userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com"
|
||||||
|
userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)
|
||||||
|
userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}')
|
||||||
|
userDetails='{"days":"10"}'
|
||||||
|
userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g')
|
||||||
|
echo $userDetailsNew
|
||||||
|
apiIP='0.0.0.0'
|
||||||
|
apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
||||||
|
apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}'
|
||||||
|
apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g')
|
||||||
|
rm sql/default_user.sql || true
|
||||||
|
echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql"
|
||||||
|
sudo mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt"
|
||||||
|
echo "The following details will be shown again at the end of the installation."
|
||||||
|
echo "====================================="
|
||||||
|
echo "======= Login Credentials ======="
|
||||||
|
echo "|| Username : $userEmail"
|
||||||
|
echo "|| Password : $userPasswordPlain"
|
||||||
|
echo "|| API Key : $apiKey"
|
||||||
|
echo "====================================="
|
||||||
|
echo "====================================="
|
||||||
|
echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Install NPM Libraries"
|
||||||
|
sudo npm install
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Install PM2"
|
||||||
|
sudo npm install pm2 -g
|
||||||
|
echo "Shinobi - Finished"
|
||||||
|
sudo chmod -R 755 .
|
||||||
|
touch INSTALL/installed.txt
|
||||||
|
if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then
|
||||||
|
echo "=====================================" > INSTALL/installed.txt
|
||||||
|
echo "======= Login Credentials =======" >> INSTALL/installed.txt
|
||||||
|
echo "|| Username : $userEmail" >> INSTALL/installed.txt
|
||||||
|
echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt
|
||||||
|
echo "|| API Key : $apiKey" >> INSTALL/installed.txt
|
||||||
|
echo "=====================================" >> INSTALL/installed.txt
|
||||||
|
echo "=====================================" >> INSTALL/installed.txt
|
||||||
|
fi
|
||||||
|
echo "Shinobi - Start Shinobi and set to start on boot?"
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read startShinobi
|
||||||
|
if [ "$startShinobi" = "y" ] || [ "$startShinobi" = "y" ]; then
|
||||||
|
sudo pm2 start camera.js
|
||||||
|
sudo pm2 start cron.js
|
||||||
|
sudo pm2 startup
|
||||||
|
sudo pm2 save
|
||||||
|
sudo pm2 list
|
||||||
|
fi
|
||||||
|
if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then
|
||||||
|
echo "details written to INSTALL/installed.txt"
|
||||||
|
echo "====================================="
|
||||||
|
echo "======= Login Credentials ======="
|
||||||
|
echo "|| Username : $userEmail"
|
||||||
|
echo "|| Password : $userPasswordPlain"
|
||||||
|
echo "|| API Key : $apiKey"
|
||||||
|
echo "====================================="
|
||||||
|
echo "====================================="
|
||||||
|
fi
|
||||||
|
if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then
|
||||||
|
echo "====================================="
|
||||||
|
echo "||===== Install Completed =====||"
|
||||||
|
echo "====================================="
|
||||||
|
echo "|| Login with the Superuser and create a new user!!"
|
||||||
|
echo "||==================================="
|
||||||
|
echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser."
|
||||||
|
echo "||==================================="
|
||||||
|
echo "|| Default Superuser : admin@shinobi.video"
|
||||||
|
echo "|| Default Password : admin"
|
||||||
|
echo "====================================="
|
||||||
|
echo "====================================="
|
||||||
|
else
|
||||||
|
echo "+=================================+"
|
||||||
|
echo "||===== Install Completed =====||"
|
||||||
|
echo "|| Access the main Shinobi panel at http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080 in your web browser."
|
||||||
|
echo "+=================================+"
|
||||||
|
fi
|
|
@ -0,0 +1,76 @@
|
||||||
|
SHINOBI OPEN SOURCE SOFTWARE LICENSE AGREEMENT
|
||||||
|
Version 1, 04 June 2018
|
||||||
|
|
||||||
|
Copyright (C) 2018 Shinobi Systems <https://shinobi.systems>
|
||||||
|
|
||||||
|
We'll try to keep it simple. Thanks for using Shinobi Software!
|
||||||
|
|
||||||
|
Defintions.
|
||||||
|
|
||||||
|
In this End User Licence Agreement,
|
||||||
|
"EULA" shall mean this End User Licence Agreement
|
||||||
|
"Licenser" shall mean SHINOBI SYSTEMS
|
||||||
|
"Licensee" shall mean YOU, or the organisation (if any) on whose behalf YOU are taking the EULA.
|
||||||
|
|
||||||
|
"SOFTWARE PRODUCTS" or "SOFTWARE" or "PRODUCTS" shall mean GMASTER and any additional modules or add-ons delivered by Shinobi Systems. The term "SOFTWARE" includes, to the extent provided by SHINOBI SYSTEMS: 1) any revisions, updates and/or upgrades thereto; 2) any data, image or executable files, databases, data engines, computer software, or similar items customarily used or distributed with computer software products; 3) anything in any form whatsoever intended to be used with or in conjunction with the SOFTWARE; and 4) any associated media, documentation (including physical, electronic and on-line) and printed materials (the "Documentation").
|
||||||
|
|
||||||
|
Purpose of the Agreement.
|
||||||
|
|
||||||
|
The Short : Protect the rights of this Software Product and the Licenser.
|
||||||
|
|
||||||
|
The Long : The LICENSER grants the LICENSEE a non-exclusive, non-transferable and perpetual licence to use the SOFTWARE PRODUCTS listed therein and under the terms thereof. By accepting the terms and conditions established in this agreement, the LICENSEE does not acquire any ownership of copyright or other intellectual property rights in any part of the SOFTWARE PRODUCTS. The LICENSEE is only entitled to use the SOFTWARE PRODUCTS in accordance with the terms and conditions set forth by Shinobi Systems. By using the SOFTWARE PRODUCTS, the LICENSEE agrees to accept the terms and conditions presented.
|
||||||
|
|
||||||
|
LICENSEE must purchase the applicable subscription in any other use case unless otherwise granted. If the use case does not have a subscription applicable please contact a representative at support@shinobi.systems.
|
||||||
|
|
||||||
|
Conditions for Free (Unpaid) use.
|
||||||
|
|
||||||
|
- Use in a non commercial area for non commercial purposes
|
||||||
|
- Educational use
|
||||||
|
- Testing Purposes
|
||||||
|
- Use in a School like a elementary school, college, or university
|
||||||
|
|
||||||
|
Support Services.
|
||||||
|
|
||||||
|
The Maintenance and Support Service shall be contracted and provided as per selected plan agreement, taxes will be included in all prices for Support Services.
|
||||||
|
|
||||||
|
Support Services will only provide support services as per the selected agreement.
|
||||||
|
|
||||||
|
This is not the entire agreement on support services. You must also review all agreements provided with subscription plans provided.
|
||||||
|
|
||||||
|
Software Product Ownership.
|
||||||
|
|
||||||
|
This software is property of Shinobi Systems. LICENSEE must keep all copyright notices unchanged.
|
||||||
|
|
||||||
|
Modification of this Software Product.
|
||||||
|
|
||||||
|
LICENSEE may modify the code but LICENSEE must provide the source code if asked by law enforcement or an authorized Shinobi representative. LICENSEE must keep all copyright notices unchanged.
|
||||||
|
|
||||||
|
Software Product Rebranding or "White-Labelling".
|
||||||
|
|
||||||
|
LICENSEE can remove the Shinobi branding from the front end but all copyright notices must remain unchanged.
|
||||||
|
|
||||||
|
Software Product Contributions.
|
||||||
|
|
||||||
|
All contributed code becomes the property of Shinobi Systems. All contributors give permission to Shinobi and Shinobi developers to use the code however it is seen fit.
|
||||||
|
|
||||||
|
Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
Limitation of Liability.
|
||||||
|
|
||||||
|
LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM SHINOBI SYSTEMS AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO $5.00 CAD. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
|
||||||
|
This limitation applies to:
|
||||||
|
|
||||||
|
- anything related to the software, services, content (including code) on third-party Internet sites, or third-party programs; and
|
||||||
|
- claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
|
||||||
|
|
||||||
|
It also applies even if Shinobi Systems knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
|
||||||
|
|
||||||
|
Changes to the Agreement.
|
||||||
|
|
||||||
|
Shinobi Systems reserves the right to change the license and set of terms at any time. Continued use is agreement to those possible changes. Changes to this license will be provided in the commit history of the repository it is located in.
|
||||||
|
|
||||||
|
Legal Proceedings
|
||||||
|
|
||||||
|
All lawsuits must be filed in the city in which the current headquarters is based at the time of the filing.
|
|
@ -0,0 +1,146 @@
|
||||||
|
# Shinobi Pro
|
||||||
|
### (Creative Commons v4.0)
|
||||||
|
|
||||||
|
Shinobi is the Open Source CCTV Solution written in Node.JS. Designed with multiple account system, Streams by WebSocket, and Save to WebM. Shinobi can record IP Cameras and Local Cameras.
|
||||||
|
|
||||||
|
<a href="http://shinobi.video/gallery"><img src="https://github.com/ShinobiCCTV/Shinobi/blob/master/web/libs/img/demo.jpg?raw=true"></a>
|
||||||
|
|
||||||
|
# Key Aspects
|
||||||
|
|
||||||
|
For an updated list of features visit the official website. http://shinobi.video/features
|
||||||
|
|
||||||
|
- Time-lapse Viewer (Watch a hours worth of footage in a few minutes)
|
||||||
|
- 2-Factor Authentication
|
||||||
|
- Defeats stream limit imposed by browsers
|
||||||
|
- With Base64 (Stream Type) and JPEG Mode (Option)
|
||||||
|
- Records IP Cameras and Local Cameras
|
||||||
|
- Streams by WebSocket, HLS (includes audio), and MJPEG
|
||||||
|
- Save to WebM and MP4
|
||||||
|
- Can save Audio
|
||||||
|
- Push Events - When a video is finished it will appear in the dashboard without a refresh
|
||||||
|
- Region Motion Detection (Similar to ZoneMinder Zone Detection)
|
||||||
|
- Represented by a Motion Guage on each monitor
|
||||||
|
- "No Motion" Notifications
|
||||||
|
- 1 Process for Each Camera to do both, Recording and Streaming
|
||||||
|
- Timeline for viewing Motion Events and Videos
|
||||||
|
- Sub-Accounts with permissions
|
||||||
|
- Monitor Viewing
|
||||||
|
- Monitor Editing
|
||||||
|
- Video Deleting
|
||||||
|
- Separate API keys for sub account
|
||||||
|
- Cron Filters can be set based on master account
|
||||||
|
- Stream Analyzer built-in (FFprobe GUI)
|
||||||
|
- Monitor Groups
|
||||||
|
- Can snapshot images from stream directly
|
||||||
|
- Lower Bandwith Mode (JPEG Mode)
|
||||||
|
- Snapshot (cgi-bin) must be enabled in Monitor Settings
|
||||||
|
- Control Cameras from Interface
|
||||||
|
- API
|
||||||
|
- Get videos
|
||||||
|
- Get monitors
|
||||||
|
- Change monitor modes : Disabled, Watch, Record
|
||||||
|
- Embedding streams
|
||||||
|
- Dashboard Framework made with Google Material Design Lite, jQuery, and Bootstrap
|
||||||
|
|
||||||
|
## Asking for help
|
||||||
|
|
||||||
|
Before asking questions it would nice if you read the docs :) http://shinobi.video
|
||||||
|
|
||||||
|
After doing so please head on over to the Discord community chat for support. https://discordapp.com/invite/mdhmvuH
|
||||||
|
|
||||||
|
The Issues section is only for bugs with the software. Comments and feature requests may be closed without comment. http://shinobi.video/docs/contribute
|
||||||
|
|
||||||
|
Please be considerate of developer efforts. If you have simple questions, like "what does this button do?", please be sure to have read the docs entirely before asking. If you would like to skip reading the docs and ask away you can order a support package :) http://shinobi.video/support
|
||||||
|
|
||||||
|
## Making Suggestions or Feature Requests
|
||||||
|
|
||||||
|
You can post suggestions on the Forum in the Suggestions category. Please do not treat this channel like a "demands" window. Developer efforts are limited. Much more than many alternatives.
|
||||||
|
|
||||||
|
when you have a suggestion please try and make the changes yourself then post a pull request to the `dev` branch. Then we can decide if it's a good change for Shinobi. If you don't know how to go about it and want to have me put it higher on my priority list you can order a support package :) Pretty Ferengi of me... but until we live in a world without money please support Shinobi :) Cheers!
|
||||||
|
|
||||||
|
http://shinobi.video/support
|
||||||
|
|
||||||
|
## Help make Shinobi the best Open Source CCTV Solution.
|
||||||
|
Donate - http://shinobi.video/docs/donate
|
||||||
|
|
||||||
|
Ordering a License, Paid Support, or anything from <a href="//camera.observer">here</a> will allow a lot more time to be spent on Shinobi.
|
||||||
|
|
||||||
|
Order Support - http://shinobi.video/support
|
||||||
|
|
||||||
|
# Why make this?
|
||||||
|
|
||||||
|
http://shinobi.video/why
|
||||||
|
|
||||||
|
# What others say
|
||||||
|
|
||||||
|
> "After trying zoneminder without success (heavy unstable and slow) I passed to Shinobi that despite being young spins a thousand times better (I have a setup with 16 cameras recording in FHD to ~ 10fps on a pentium of ~ 2009 and I turn with load below 1.5)."
|
||||||
|
|
||||||
|
> *A Reddit user, /r/ItalyInformatica*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
> "I would suggest Shinobi as a NVR. It's still in the early days but works a lot better than ZoneMinder for me. I'm able to record 16 cams at 1080p 15fps continously whith no load on server (Pentium E5500 3GB RAM) where zm crashed with 6 cams at 720p. Not to mention the better interface."
|
||||||
|
|
||||||
|
> *A Reddit user, /r/HomeNetworking*
|
||||||
|
|
||||||
|
# How to Install and Run
|
||||||
|
|
||||||
|
> FOR DOCKER USERS : Docker is not officially supported and is not recommended. The kitematic method is provided for those who wish to quickly test Shinobi. The Docker files included in the master and dev branches are maintained by the community. If you would like support with Docker please find a community member who maintains the Docker files or please refer to Docker's forum.
|
||||||
|
|
||||||
|
#### Fast Install (The Ninja Way)
|
||||||
|
|
||||||
|
1. Become `root` to use the installer and run Shinobi. Use one of the following to do so.
|
||||||
|
|
||||||
|
- Ubuntu 17.04, 17.10
|
||||||
|
- `sudo su`
|
||||||
|
- CentOS 7
|
||||||
|
- `su`
|
||||||
|
- MacOS 10.7(+)
|
||||||
|
- `su`
|
||||||
|
2. Download and run the installer.
|
||||||
|
|
||||||
|
```
|
||||||
|
bash <(curl -s https://raw.githubusercontent.com/ShinobiCCTV/Shinobi-Installer/master/shinobi-install.sh)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Elaborate Installs
|
||||||
|
|
||||||
|
Installation Tutorials - http://shinobi.video/docs/start
|
||||||
|
|
||||||
|
Troubleshooting Guide - http://shinobi.video/docs/start#trouble-section
|
||||||
|
|
||||||
|
# Author
|
||||||
|
|
||||||
|
Moe Alam
|
||||||
|
|
||||||
|
Follow Shinobi on Twitter https://twitter.com/ShinobiCCTV
|
||||||
|
|
||||||
|
Join the Community Chat
|
||||||
|
|
||||||
|
<a title="Find me on Discord, Get an Invite" href="https://discordapp.com/invite/mdhmvuH"><img src="https://cdn-images-1.medium.com/max/115/1*OoXboCzk0gYvTNwNnV4S9A@2x.png"></a>
|
||||||
|
|
||||||
|
# Support the Development
|
||||||
|
|
||||||
|
Ordering a certificate or support package greatly boosts development. Please consider contributing :)
|
||||||
|
|
||||||
|
http://shinobi.video/support
|
||||||
|
|
||||||
|
# Links
|
||||||
|
|
||||||
|
Documentation - http://shinobi.video/docs
|
||||||
|
|
||||||
|
Donate - https://shinobi.video/docs/donate
|
||||||
|
|
||||||
|
Tested Cameras and Systems - http://shinobi.video/docs/supported
|
||||||
|
|
||||||
|
Features - http://shinobi.video/features
|
||||||
|
|
||||||
|
Reddit (Forum) - https://www.reddit.com/r/ShinobiCCTV/
|
||||||
|
|
||||||
|
YouTube (Tutorials) - https://www.youtube.com/channel/UCbgbBLTK-koTyjOmOxA9msQ
|
||||||
|
|
||||||
|
Discord (Community Chat) - https://discordapp.com/invite/mdhmvuH
|
||||||
|
|
||||||
|
Twitter (News) - https://twitter.com/ShinobiCCTV
|
||||||
|
|
||||||
|
Facebook (News) - https://www.facebook.com/Shinobi-1223193167773738/?ref=bookmarks
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
distro=$1
|
||||||
|
repo=$2
|
||||||
|
if [ -z "$distro" ]; then
|
||||||
|
distro='master'
|
||||||
|
fi
|
||||||
|
if [ -z "$repo" ]; then
|
||||||
|
repo='ShinobiCCTV'
|
||||||
|
fi
|
||||||
|
if [ "$repo" = "ShinobiCCTV" ]; then
|
||||||
|
productName="Shinobi Professional (Pro)"
|
||||||
|
else
|
||||||
|
productName="Shinobi Community Editon (CE)"
|
||||||
|
fi
|
||||||
|
git reset --hard
|
||||||
|
git pull
|
||||||
|
gitURL="https://github.com/$repo/Shinobi"
|
||||||
|
gitVersionNumber=$(git rev-parse HEAD)
|
||||||
|
theDateRightNow=$(date)
|
||||||
|
rm version.json
|
||||||
|
touch version.json
|
||||||
|
chmod 755 version.json
|
||||||
|
echo '{"Product" : "'"$productName"'" , "Branch" : "'"$distro"'" , "Version" : "'"$gitVersionNumber"'" , "Date" : "'"$theDateRightNow"'" , "Repository" : "'"$gitURL"'"}' > version.json
|
||||||
|
echo "Restart Shinobi for updates to take effect."
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"port": 8080,
|
||||||
|
"addStorage": [
|
||||||
|
{"name":"second","path":"__DIR__/videos2"}
|
||||||
|
],
|
||||||
|
"db": {
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"user": "majesticflame",
|
||||||
|
"password": "",
|
||||||
|
"database": "ccio",
|
||||||
|
"port":3306
|
||||||
|
},
|
||||||
|
"mail":{
|
||||||
|
"service": "gmail",
|
||||||
|
"auth": {
|
||||||
|
"user": "your_email@gmail.com",
|
||||||
|
"pass": "your_password_or_app_specific_password"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cron":{
|
||||||
|
"key":"change_this_to_something_very_random__just_anything_other_than_this"
|
||||||
|
},
|
||||||
|
"pluginKeys":{
|
||||||
|
"Motion":"change_this_to_something_very_random____make_sure_to_match__/plugins/motion/conf.json",
|
||||||
|
"OpenCV":"change_this_to_something_very_random____make_sure_to_match__/plugins/opencv/conf.json",
|
||||||
|
"OpenALPR":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,492 @@
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error('uncaughtException',err);
|
||||||
|
});
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
var knex = require('knex');
|
||||||
|
var moment = require('moment');
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
var spawn = require('child_process').spawn;
|
||||||
|
var config=require('./conf.json');
|
||||||
|
|
||||||
|
//set option defaults
|
||||||
|
s={};
|
||||||
|
if(config.cron===undefined)config.cron={};
|
||||||
|
if(config.cron.deleteOld===undefined)config.cron.deleteOld=true;
|
||||||
|
if(config.cron.deleteOrphans===undefined)config.cron.deleteOrphans=false;
|
||||||
|
if(config.cron.deleteNoVideo===undefined)config.cron.deleteNoVideo=true;
|
||||||
|
if(config.cron.deleteNoVideoRecursion===undefined)config.cron.deleteNoVideoRecursion=false;
|
||||||
|
if(config.cron.deleteOverMax===undefined)config.cron.deleteOverMax=true;
|
||||||
|
if(config.cron.deleteLogs===undefined)config.cron.deleteLogs=true;
|
||||||
|
if(config.cron.deleteEvents===undefined)config.cron.deleteEvents=true;
|
||||||
|
if(config.cron.deleteFileBins===undefined)config.cron.deleteFileBins=true;
|
||||||
|
if(config.cron.interval===undefined)config.cron.interval=1;
|
||||||
|
if(config.databaseType===undefined){config.databaseType='mysql'}
|
||||||
|
if(config.databaseLogs===undefined){config.databaseLogs=false}
|
||||||
|
|
||||||
|
if(!config.ip||config.ip===''||config.ip.indexOf('0.0.0.0')>-1)config.ip='localhost';
|
||||||
|
if(!config.videosDir)config.videosDir=__dirname+'/videos/';
|
||||||
|
if(!config.binDir){config.binDir=__dirname+'/fileBin/'}
|
||||||
|
if(!config.addStorage){config.addStorage=[]}
|
||||||
|
|
||||||
|
// Database Connection
|
||||||
|
var databaseOptions = {
|
||||||
|
client: config.databaseType,
|
||||||
|
connection: config.db,
|
||||||
|
}
|
||||||
|
if(databaseOptions.client.indexOf('sqlite')>-1){
|
||||||
|
databaseOptions.client = 'sqlite3';
|
||||||
|
databaseOptions.useNullAsDefault = true;
|
||||||
|
}
|
||||||
|
if(databaseOptions.client === 'sqlite3' && databaseOptions.connection.filename === undefined){
|
||||||
|
databaseOptions.connection.filename = __dirname+"/shinobi.sqlite"
|
||||||
|
}
|
||||||
|
s.databaseEngine = knex(databaseOptions)
|
||||||
|
s.sqlDate = function(value){
|
||||||
|
var dateQueryFunction = ''
|
||||||
|
if(databaseOptions.client === 'sqlite3'){
|
||||||
|
value = value.toLowerCase()
|
||||||
|
if (value.slice(-1) !== 's') {
|
||||||
|
value = value+'s'
|
||||||
|
}
|
||||||
|
dateQueryFunction = "datetime('now', '-"+value+"')"
|
||||||
|
}else{
|
||||||
|
value = value.toUpperCase()
|
||||||
|
if (value.slice(-1) === 'S') {
|
||||||
|
value = value.slice(0, -1);
|
||||||
|
}
|
||||||
|
dateQueryFunction = "DATE_SUB(NOW(), INTERVAL "+value+")"
|
||||||
|
}
|
||||||
|
return dateQueryFunction
|
||||||
|
}
|
||||||
|
s.sqlQuery = function(query,values,onMoveOn,hideLog){
|
||||||
|
if(!values){values=[]}
|
||||||
|
var valuesNotFunction = true;
|
||||||
|
if(typeof values === 'function'){
|
||||||
|
var onMoveOn = values;
|
||||||
|
var values = [];
|
||||||
|
valuesNotFunction = false;
|
||||||
|
}
|
||||||
|
if(!onMoveOn){onMoveOn=function(){}}
|
||||||
|
if(values&&valuesNotFunction){
|
||||||
|
var splitQuery = query.split('?')
|
||||||
|
var newQuery = ''
|
||||||
|
splitQuery.forEach(function(v,n){
|
||||||
|
newQuery += v
|
||||||
|
if(values[n]){
|
||||||
|
if(isNaN(values[n])){
|
||||||
|
newQuery += "'"+values[n]+"'"
|
||||||
|
}else{
|
||||||
|
newQuery += values[n]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
newQuery = query
|
||||||
|
}
|
||||||
|
return s.databaseEngine.raw(newQuery)
|
||||||
|
.asCallback(function(err,r){
|
||||||
|
if(err&&config.databaseLogs){
|
||||||
|
s.systemLog('s.sqlQuery QUERY',query)
|
||||||
|
s.systemLog('s.sqlQuery ERROR',err)
|
||||||
|
}
|
||||||
|
if(onMoveOn)
|
||||||
|
if(typeof onMoveOn === 'function'){
|
||||||
|
switch(databaseOptions.client){
|
||||||
|
case'sqlite3':
|
||||||
|
if(!r)r=[]
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(r)r=r[0]
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
onMoveOn(err,r)
|
||||||
|
}else{
|
||||||
|
console.log(onMoveOn)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//containers
|
||||||
|
s.overlapLock={};
|
||||||
|
s.alreadyDeletedRowsWithNoVideosOnStart={};
|
||||||
|
//functions
|
||||||
|
s.checkCorrectPathEnding=function(x){
|
||||||
|
var length=x.length
|
||||||
|
if(x.charAt(length-1)!=='/'){
|
||||||
|
x=x+'/'
|
||||||
|
}
|
||||||
|
return x.replace('__DIR__',__dirname)
|
||||||
|
}
|
||||||
|
s.dir={
|
||||||
|
videos:s.checkCorrectPathEnding(config.videosDir),
|
||||||
|
fileBin:s.checkCorrectPathEnding(config.binDir),
|
||||||
|
addStorage:config.addStorage,
|
||||||
|
};
|
||||||
|
s.moment=function(e,x){
|
||||||
|
if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};
|
||||||
|
return moment(e).format(x);
|
||||||
|
}
|
||||||
|
s.nameToTime=function(x){x=x.replace('.webm','').replace('.mp4','').split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;}
|
||||||
|
io = require('socket.io-client')('ws://'+config.ip+':'+config.port);//connect to master
|
||||||
|
s.cx=function(x){x.cronKey=config.cron.key;return io.emit('cron',x)}
|
||||||
|
//emulate master socket emitter
|
||||||
|
s.tx=function(x,y){s.cx({f:'s.tx',data:x,to:y})}
|
||||||
|
s.video=function(x,y){s.cx({f:'s.video',data:x,file:y})}
|
||||||
|
//Cron Job
|
||||||
|
s.cx({f:'init',time:moment()})
|
||||||
|
s.getVideoDirectory=function(e){
|
||||||
|
if(e.mid&&!e.id){e.id=e.mid};
|
||||||
|
if(e.details&&(e.details instanceof Object)===false){
|
||||||
|
try{e.details=JSON.parse(e.details)}catch(err){}
|
||||||
|
}
|
||||||
|
if(e.details.dir&&e.details.dir!==''){
|
||||||
|
return s.checkCorrectPathEnding(e.details.dir)+e.ke+'/'+e.id+'/'
|
||||||
|
}else{
|
||||||
|
return s.dir.videos+e.ke+'/'+e.id+'/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.getFileBinDirectory=function(e){
|
||||||
|
if(e.mid&&!e.id){e.id=e.mid};
|
||||||
|
return s.dir.fileBin+e.ke+'/'+e.id+'/';
|
||||||
|
}
|
||||||
|
//filters set by the user in their dashboard
|
||||||
|
//deleting old videos is part of the filter - config.cron.deleteOld
|
||||||
|
s.checkFilterRules=function(v,callback){
|
||||||
|
//filters
|
||||||
|
if(!v.d.filters||v.d.filters==''){
|
||||||
|
v.d.filters={};
|
||||||
|
}
|
||||||
|
//delete old videos with filter
|
||||||
|
if(config.cron.deleteOld===true){
|
||||||
|
v.d.filters.deleteOldByCron={
|
||||||
|
"id":"deleteOldByCron",
|
||||||
|
"name":"deleteOldByCron",
|
||||||
|
"sort_by":"time",
|
||||||
|
"sort_by_direction":"ASC",
|
||||||
|
"limit":"",
|
||||||
|
"enabled":"1",
|
||||||
|
"archive":"0",
|
||||||
|
"email":"0",
|
||||||
|
"delete":"1",
|
||||||
|
"execute":"",
|
||||||
|
"where":[{
|
||||||
|
"p1":"end",
|
||||||
|
"p2":"<",
|
||||||
|
"p3":s.sqlDate(v.d.days+" DAYS"),
|
||||||
|
"p3_type":"function",
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var keys = Object.keys(v.d.filters)
|
||||||
|
if(keys.length>0){
|
||||||
|
keys.forEach(function(m,current){
|
||||||
|
var b=v.d.filters[m];
|
||||||
|
if(b.enabled==="1"){
|
||||||
|
b.ar=[v.ke];
|
||||||
|
b.sql=[];
|
||||||
|
b.where.forEach(function(j,k){
|
||||||
|
if(j.p1==='ke'){j.p3=v.ke}
|
||||||
|
switch(j.p3_type){
|
||||||
|
case'function':
|
||||||
|
b.sql.push(j.p1+' '+j.p2+' '+j.p3)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
b.sql.push(j.p1+' '+j.p2+' ?')
|
||||||
|
b.ar.push(j.p3)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.sql='WHERE ke=? AND status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ('+b.sql.join(' AND ')+')';
|
||||||
|
if(b.sort_by&&b.sort_by!==''){
|
||||||
|
b.sql+=' ORDER BY `'+b.sort_by+'` '+b.sort_by_direction
|
||||||
|
}
|
||||||
|
if(b.limit&&b.limit!==''){
|
||||||
|
b.sql+=' LIMIT '+b.limit
|
||||||
|
}
|
||||||
|
s.sqlQuery('SELECT * FROM Videos '+b.sql,b.ar,function(err,r){
|
||||||
|
if(r&&r[0]){
|
||||||
|
b.cx={
|
||||||
|
f:'filters',
|
||||||
|
name:b.name,
|
||||||
|
videos:r,
|
||||||
|
time:moment(),
|
||||||
|
ke:v.ke,
|
||||||
|
id:b.id
|
||||||
|
};
|
||||||
|
if(b.archive==="1"){
|
||||||
|
s.cx({f:'filters',ff:'archive',videos:r,time:moment(),ke:v.ke,id:b.id});
|
||||||
|
}else{
|
||||||
|
if(b.delete==="1"){
|
||||||
|
s.cx({f:'filters',ff:'delete',videos:r,time:moment(),ke:v.ke,id:b.id});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(b.email==="1"){
|
||||||
|
b.cx.ff='email';
|
||||||
|
b.cx.delete=b.delete;
|
||||||
|
b.cx.mail=v.mail;
|
||||||
|
b.cx.execute=b.execute;
|
||||||
|
b.cx.query=b.sql;
|
||||||
|
s.cx(b.cx);
|
||||||
|
}
|
||||||
|
if(b.execute&&b.execute!==""){
|
||||||
|
s.cx({f:'filters',ff:'execute',execute:b.execute,time:moment()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
if(current===keys.length-1){
|
||||||
|
//last filter
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
//no filters
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//database rows with no videos in the filesystem
|
||||||
|
s.deleteRowsWithNoVideo=function(v,callback){
|
||||||
|
if(
|
||||||
|
config.cron.deleteNoVideo===true&&(
|
||||||
|
config.cron.deleteNoVideoRecursion===true||
|
||||||
|
(config.cron.deleteNoVideoRecursion===false&&!s.alreadyDeletedRowsWithNoVideosOnStart[v.ke])
|
||||||
|
)
|
||||||
|
){
|
||||||
|
s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]=true;
|
||||||
|
es={};
|
||||||
|
s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND status!=0 AND details NOT LIKE \'%"archived":"1"%\' AND time < '+s.sqlDate('10 MINUTE'),[v.ke],function(err,evs){
|
||||||
|
if(evs&&evs[0]){
|
||||||
|
es.del=[];es.ar=[v.ke];
|
||||||
|
evs.forEach(function(ev){
|
||||||
|
ev.dir=s.getVideoDirectory(ev)+s.moment(ev.time)+'.'+ev.ext;
|
||||||
|
if(fs.existsSync(ev.dir)!==true){
|
||||||
|
s.video('delete',ev)
|
||||||
|
es.del.push('(mid=? AND time=?)');
|
||||||
|
es.ar.push(ev.mid),es.ar.push(ev.time);
|
||||||
|
s.tx({f:'video_delete',filename:s.moment(ev.time)+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+ev.ke);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(es.del.length>0){
|
||||||
|
s.cx({f:'deleteNoVideo',msg:es.del.length+' SQL rows with no file deleted',ke:v.ke,time:moment()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setTimeout(function(){
|
||||||
|
callback()
|
||||||
|
},3000)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//info about what the application is doing
|
||||||
|
s.deleteOldLogs=function(v,callback){
|
||||||
|
if(!v.d.log_days||v.d.log_days==''){v.d.log_days=10}else{v.d.log_days=parseFloat(v.d.log_days)};
|
||||||
|
if(config.cron.deleteLogs===true&&v.d.log_days!==0){
|
||||||
|
s.sqlQuery("DELETE FROM Logs WHERE ke=? AND `time` < "+s.sqlDate('? DAYS'),[v.ke,v.d.log_days],function(err,rrr){
|
||||||
|
callback()
|
||||||
|
if(err)return console.error(err);
|
||||||
|
if(rrr.affectedRows && rrr.affectedRows.length>0){
|
||||||
|
s.cx({f:'deleteLogs',msg:rrr.affectedRows+' SQL rows older than '+v.d.log_days+' days deleted',ke:v.ke,time:moment()})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//events - motion, object, etc. detections
|
||||||
|
s.deleteOldEvents=function(v,callback){
|
||||||
|
if(!v.d.event_days||v.d.event_days==''){v.d.event_days=10}else{v.d.event_days=parseFloat(v.d.event_days)};
|
||||||
|
if(config.cron.deleteEvents===true&&v.d.event_days!==0){
|
||||||
|
s.sqlQuery("DELETE FROM Events WHERE ke=? AND `time` < "+s.sqlDate('? DAYS'),[v.ke,v.d.event_days],function(err,rrr){
|
||||||
|
callback()
|
||||||
|
if(err)return console.error(err);
|
||||||
|
if(rrr.affectedRows && rrr.affectedRows.length>0){
|
||||||
|
s.cx({f:'deleteEvents',msg:rrr.affectedRows+' SQL rows older than '+v.d.event_days+' days deleted',ke:v.ke,time:moment()})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//check for temporary files (special archive)
|
||||||
|
s.deleteOldFileBins=function(v,callback){
|
||||||
|
if(!v.d.fileBin_days||v.d.fileBin_days==''){v.d.fileBin_days=10}else{v.d.fileBin_days=parseFloat(v.d.fileBin_days)};
|
||||||
|
if(config.cron.deleteFileBins===true&&v.d.fileBin_days!==0){
|
||||||
|
var fileBinQuery = " FROM Files WHERE ke=? AND `date` < "+s.sqlDate('? DAYS');
|
||||||
|
s.sqlQuery("SELECT *"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,files){
|
||||||
|
if(files&&files[0]){
|
||||||
|
//delete the files
|
||||||
|
files.forEach(function(file){
|
||||||
|
fs.unlink(s.getFileBinDirectory(file)+file.name,function(err){
|
||||||
|
// if(err)console.error(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
//delete the database rows
|
||||||
|
s.sqlQuery("DELETE"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,rrr){
|
||||||
|
callback()
|
||||||
|
if(err)return console.error(err);
|
||||||
|
if(rrr.affectedRows && rrr.affectedRows.length>0){
|
||||||
|
s.cx({f:'deleteFileBins',msg:rrr.affectedRows+' files older than '+v.d.fileBin_days+' days deleted',ke:v.ke,time:moment()})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//check for files with no database row
|
||||||
|
s.checkForOrphanedFiles=function(v,callback){
|
||||||
|
if(config.cron.deleteOrphans===true){
|
||||||
|
var finish=function(count){
|
||||||
|
if(count>0){
|
||||||
|
s.cx({f:'deleteOrphanedFiles',msg:count+' SQL rows with no database row deleted',ke:v.ke,time:moment()})
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
e={};
|
||||||
|
var numberOfItems = 0;
|
||||||
|
s.sqlQuery('SELECT * FROM Monitors WHERE ke=?',[v.ke],function(arr,b) {
|
||||||
|
if(b&&b[0]){
|
||||||
|
b.forEach(function(mon,m){
|
||||||
|
fs.readdir(s.getVideoDirectory(mon), function(err, items) {
|
||||||
|
e.query=[];
|
||||||
|
e.filesFound=[mon.ke,mon.mid];
|
||||||
|
numberOfItems+=items.length;
|
||||||
|
if(items&&items.length>0){
|
||||||
|
items.forEach(function(v,n){
|
||||||
|
e.query.push('time=?')
|
||||||
|
e.filesFound.push(s.nameToTime(v))
|
||||||
|
})
|
||||||
|
s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND mid=? AND ('+e.query.join(' OR ')+')',e.filesFound,function(arr,r) {
|
||||||
|
if(!r){r=[]};
|
||||||
|
e.foundSQLrows=[];
|
||||||
|
r.forEach(function(v,n){
|
||||||
|
v.index=e.filesFound.indexOf(s.moment(v.time,'YYYY-MM-DD HH:mm:ss'));
|
||||||
|
if(v.index>-1){
|
||||||
|
delete(items[v.index-2]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
items.forEach(function(v,n){
|
||||||
|
if(v&&v!==null){
|
||||||
|
exec('rm '+s.getVideoDirectory(mon)+v);
|
||||||
|
}
|
||||||
|
if(m===b.length-1&&n===items.length-1){
|
||||||
|
finish(numberOfItems)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
if(m===b.length-1){
|
||||||
|
finish(numberOfItems)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
finish(numberOfItems)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//user processing function
|
||||||
|
s.processUser = function(number,rows){
|
||||||
|
var v = rows[number];
|
||||||
|
if(!v){
|
||||||
|
//no user object given
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(!s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]){
|
||||||
|
s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]=false;
|
||||||
|
}
|
||||||
|
if(!s.overlapLock[v.ke]){
|
||||||
|
// set overlap lock
|
||||||
|
s.overlapLock[v.ke]=true;
|
||||||
|
//set permissions
|
||||||
|
v.d=JSON.parse(v.details);
|
||||||
|
//size
|
||||||
|
if(!v.d.size||v.d.size==''){v.d.size=10000}else{v.d.size=parseFloat(v.d.size)};
|
||||||
|
//days to keep videos
|
||||||
|
if(!v.d.days||v.d.days==''){v.d.days=5}else{v.d.days=parseFloat(v.d.days)};
|
||||||
|
s.sqlQuery('SELECT * FROM Monitors WHERE ke=?', [v.ke], function(err,rr) {
|
||||||
|
rr.forEach(function(b,m){
|
||||||
|
b.details=JSON.parse(b.details);
|
||||||
|
if(b.details.max_keep_days&&b.details.max_keep_days!==''){
|
||||||
|
v.d.filters['deleteOldByCron'+b.mid]={
|
||||||
|
"id":'deleteOldByCron'+b.mid,
|
||||||
|
"name":'deleteOldByCron'+b.mid,
|
||||||
|
"sort_by":"time",
|
||||||
|
"sort_by_direction":"ASC",
|
||||||
|
"limit":"",
|
||||||
|
"enabled":"1",
|
||||||
|
"archive":"0",
|
||||||
|
"email":"0",
|
||||||
|
"delete":"1",
|
||||||
|
"execute":"",
|
||||||
|
"where":[{
|
||||||
|
"p1":"ke",
|
||||||
|
"p2":"=",
|
||||||
|
"p3":b.mid
|
||||||
|
},{
|
||||||
|
"p1":"end",
|
||||||
|
"p2":"<",
|
||||||
|
"p3":s.sqlDate(b.details.max_keep_days+" DAYS"),
|
||||||
|
"p3_type":"function",
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
s.deleteOldLogs(v,function(){
|
||||||
|
s.deleteOldFileBins(v,function(){
|
||||||
|
s.deleteOldEvents(v,function(){
|
||||||
|
s.checkFilterRules(v,function(){
|
||||||
|
s.deleteRowsWithNoVideo(v,function(){
|
||||||
|
s.checkForOrphanedFiles(v,function(){
|
||||||
|
//done user, unlock current, and do next
|
||||||
|
s.overlapLock[v.ke]=false;
|
||||||
|
s.processUser(number+1,rows)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//recursive function
|
||||||
|
s.cron=function(){
|
||||||
|
x={};
|
||||||
|
s.cx({f:'start',time:moment()})
|
||||||
|
s.sqlQuery('SELECT ke,uid,details,mail FROM Users WHERE details NOT LIKE \'%"sub"%\'', function(err,rows) {
|
||||||
|
if(err){
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
if(rows&&rows[0]){
|
||||||
|
s.processUser(0,rows)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
s.timeout=setTimeout(function(){
|
||||||
|
s.cron();
|
||||||
|
},parseFloat(config.cron.interval)*60000*60)
|
||||||
|
}
|
||||||
|
s.cron();
|
||||||
|
//socket commander
|
||||||
|
io.on('f',function(d){
|
||||||
|
switch(d.f){
|
||||||
|
case'start':case'restart':
|
||||||
|
clearTimeout(s.timeout);
|
||||||
|
s.cron();
|
||||||
|
break;
|
||||||
|
case'stop':
|
||||||
|
clearTimeout(s.timeout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log('Shinobi : cron.js started')
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,497 @@
|
||||||
|
{
|
||||||
|
"\"No Motion\" Detector": "\"لا الحركة\" كاشف",
|
||||||
|
"# of Allow MJPEG Clients": "# of Allow MJPEG Clients <small>0 for infinite</small>",
|
||||||
|
"180 Degrees": "180 درجة",
|
||||||
|
"2-Factor Authentication": "2-عامل التوثيق",
|
||||||
|
"90 Clockwise": "90 اتجاه عقارب الساعة",
|
||||||
|
"90 Clockwise and Vertical Flip": "90 اتجاه عقارب الساعة العمودي الوجه",
|
||||||
|
"90 Counter Clockwise and Vertical Flip (default)": "90 عكس اتجاه عقارب الساعة و انعكاس عمودي (الافتراضي)",
|
||||||
|
"API": "API",
|
||||||
|
"API Key Added": "مفتاح API وأضاف",
|
||||||
|
"API Key Deleted": "مفتاح API حذف",
|
||||||
|
"API Keys": "مفاتيح API",
|
||||||
|
"APIKeyAddedText": "يمكنك استخدام هذا المفتاح الآن.",
|
||||||
|
"APIKeyDeletedText": "تم حذف مفتاح. وسوف لم يعد يعمل.",
|
||||||
|
"ASC": "ASC",
|
||||||
|
"Account Info": "معلومات الحساب",
|
||||||
|
"AccountEditText1": "لا يمكن تحريرها. تحديث الصفحة إذا كانت المشكلة لا تزال.",
|
||||||
|
"Accounts": "حسابات",
|
||||||
|
"Action for Selected": "العمل المحدد",
|
||||||
|
"Add": "إضافة",
|
||||||
|
"Add Monitor": "إضافة مراقبة",
|
||||||
|
"Add New": "إضافة جديدة",
|
||||||
|
"Admin": "المشرف",
|
||||||
|
"Advanced": "المتقدمة",
|
||||||
|
"Again": "مرة أخرى",
|
||||||
|
"All Monitors": "جميع الشاشات",
|
||||||
|
"All Monitors and Privileges": "جميع شاشات والامتيازات",
|
||||||
|
"All Warnings": "كل التحذيرات",
|
||||||
|
"Allow Next Command": "تسمح الأمر التالي <small>في دقائق</small>",
|
||||||
|
"Allow Next Email": "تسمح المقبل البريد الإلكتروني <small>في غضون دقائق</small>",
|
||||||
|
"Allow Next Trigger": "تسمح الزناد التالي <small>في ميلي ثانية</small>",
|
||||||
|
"Allowed IPs": "يسمح IPs",
|
||||||
|
"Analyzation Duration": "Analyzation مدة",
|
||||||
|
"Archive": "أرشيف",
|
||||||
|
"Audio Codec": "ترميز الصوت",
|
||||||
|
"Authenticate": "المصادقة",
|
||||||
|
"Auto": "السيارات",
|
||||||
|
"Autosave": "الحفظ التلقائي",
|
||||||
|
"Base64 over Websocket": "Base64 على Websocket",
|
||||||
|
"Bottom Left": "أسفل اليسار",
|
||||||
|
"Bottom Right": "أسفل اليمين",
|
||||||
|
"Browser Console Log": "المتصفح سجل وحدة",
|
||||||
|
"CPU": "وحدة المعالجة المركزية",
|
||||||
|
"CPU indicator will not work. Continuing...": "وحدة المعالجة المركزية المؤشر لا يعمل. استمرار...",
|
||||||
|
"CSS": "CSS <small>أسلوب لوحة القيادة الخاصة بك.</small>",
|
||||||
|
"Calendar": "التقويم",
|
||||||
|
"Camera Password": "كاميرا المرور",
|
||||||
|
"Camera Username": "الكاميرا المستخدم",
|
||||||
|
"Camera is not recording": "الكاميرا ليست تسجيل",
|
||||||
|
"CameraNotRecordingText": "الإعدادات قد تكون غير متوافقة. التحقق من الترميز. إعادة تشغيل...",
|
||||||
|
"Can Control Monitors": "يمكن التحكم في الشاشات",
|
||||||
|
"Can Delete Videos": "يمكن حذف الفيديو",
|
||||||
|
"Can Delete Videos and Events": "يمكن حذف الفيديو و الأحداث",
|
||||||
|
"Can Edit Monitor": "يمكن تحرير رصد",
|
||||||
|
"Can Get Logs": "يمكن الحصول على سجلات",
|
||||||
|
"Can Get Monitors": "يمكن الحصول على شاشات",
|
||||||
|
"Can View Monitor": "يمكن عرض الشاشة",
|
||||||
|
"Can View Snapshots": "يمكن عرض لقطات",
|
||||||
|
"Can View Streams": "يمكن عرض الجداول",
|
||||||
|
"Can View Videos": "يمكن عرض الفيديو",
|
||||||
|
"Can View Videos and Events": "يمكن عرض أشرطة الفيديو والأحداث",
|
||||||
|
"Can't Connect": "لا يمكن الاتصال",
|
||||||
|
"Center": "مركز <small>عنوان URL</small>",
|
||||||
|
"Chat on Discord": "الدردشة على الفتنة",
|
||||||
|
"Check": "تحقق",
|
||||||
|
"Check Signal Interval": "التحقق من إشارة الفاصل الزمني <small>في دقائق</small>",
|
||||||
|
"Check for Motion First": "تحقق من الحركة الأولى",
|
||||||
|
"Close": "قريب",
|
||||||
|
"Closed": "مغلقة",
|
||||||
|
"Command": "الأمر",
|
||||||
|
"Command on Trigger": "القيادة على الزناد",
|
||||||
|
"Complete Stream URL": "كاملة تيار URL",
|
||||||
|
"Confirm": "تأكيد",
|
||||||
|
"Connected": "متصل",
|
||||||
|
"Connection Type": "نوع الاتصال",
|
||||||
|
"Control": "التحكم",
|
||||||
|
"Control Error": "السيطرة على خطأ",
|
||||||
|
"ControlErrorText1": "لم يتم تمكين التحكم",
|
||||||
|
"Controllable": "يمكن السيطرة عليها",
|
||||||
|
"Country of Plates": "البلد من لوحات",
|
||||||
|
"Counts of Motion": "تهم الحركة",
|
||||||
|
"Current": "الحالي",
|
||||||
|
"Currently viewing": "حاليا عرض",
|
||||||
|
"Custom": "مخصص",
|
||||||
|
"Custom Base URL": "العرف قاعدة URL <small>ترك فارغا لاستخدام المضيف URL</small>",
|
||||||
|
"DB Lost.. Retrying..": "قاعدة البيانات المفقودة.. إعادة المحاولة..",
|
||||||
|
"DESC": "DESC",
|
||||||
|
"Dashboard": "لوحة القيادة",
|
||||||
|
"Dashboard Language": "لوحة أجهزة القياس في اللغة",
|
||||||
|
"Dashcam": "Dashcam",
|
||||||
|
"Dashcam (Streamer v2)": "Dashcam (غاسل v2)",
|
||||||
|
"Date Range": "نطاق التاريخ",
|
||||||
|
"Debug": "التصحيح",
|
||||||
|
"Default": "الافتراضي",
|
||||||
|
"Delete": "حذف",
|
||||||
|
"Delete Filter": "حذف الفلتر",
|
||||||
|
"Delete Matches": "حذف المباريات",
|
||||||
|
"Delete Monitor": "حذف رصد",
|
||||||
|
"Delete Motionless Video": "حذف حراك الفيديو",
|
||||||
|
"Delete Motionless Videos (Record)": "حذف حراك الفيديو (رقم قياسي)",
|
||||||
|
"Delete Selected Videos": "حذف الفيديو المختار",
|
||||||
|
"Delete Video": "حذف الفيديو",
|
||||||
|
"Delete selected": "حذف المحدد",
|
||||||
|
"DeleteMonitorText": "هل تريد حذف هذا العرض ؟ لا يمكنك استرداد. ملفات هذه الهوية ستبقى في نظام الملفات. إذا اخترت إعادة رصد مع نفس معرف الفيديو و أحداث سوف تصبح مرئية في لوحة القيادة.",
|
||||||
|
"DeleteSelectedVideosMsg": "هل تريد حذف هذا الفيديو ؟ لا يمكنك استرداد.",
|
||||||
|
"DeleteVideoMsg": "هل تريد حذف هذا الفيديو ؟ لا يمكنك استرداد.",
|
||||||
|
"Deleted": "حذف",
|
||||||
|
"Detect Objects": "الكشف عن الكائنات <small class=\"\">انظر أدناه</small>",
|
||||||
|
"Detector": "كاشف",
|
||||||
|
"Detector Flags": "كشف أعلام",
|
||||||
|
"Detector Rate": "للكشف عن معدل <small>(FPS)</small>",
|
||||||
|
"DetectorText": "<p>عندما المربعات عرض وارتفاع ترد عليك أن مجموعة منهم إلى 640 × 480 أو أقل. هذا وسوف تحسين سرعة القراءة من الإطارات.</p>",
|
||||||
|
"Disable Night Vision": "تعطيل للرؤية الليلية <small>عنوان URL</small>",
|
||||||
|
"Disable Nightvision": "تعطيل رؤية ليلية",
|
||||||
|
"Disabled": "تعطيل",
|
||||||
|
"Documentation": "الوثائق",
|
||||||
|
"Don't show this anymore": "لا تظهر هذا بعد الآن",
|
||||||
|
"Double Quote Directory": "اقتباس مزدوجة الدليل <small>بعض الدلائل التي تحتوي على مسافات. باستخدام هذا قد يتلف بعض الكاميرات.</small>",
|
||||||
|
"Down": "أسفل <small>عنوان URL</small>",
|
||||||
|
"Down Stop": "أسفل وقف <small>عنوان URL</small>",
|
||||||
|
"Download": "تحميل",
|
||||||
|
"EU": "الاتحاد الأوروبي",
|
||||||
|
"Edit": "تحرير",
|
||||||
|
"Email": "البريد الإلكتروني",
|
||||||
|
"Email Details": "البريد الإلكتروني التفاصيل",
|
||||||
|
"Email on No Motion": "البريد الإلكتروني على \"لا الحركة\"",
|
||||||
|
"Email on Trigger": "البريد الإلكتروني على الزناد <small>رسائل البريد الإلكتروني الذهاب إلى الحساب الرئيسي حامل عنوان تسجيل الدخول.</small>",
|
||||||
|
"Enable Night Vision": "تمكين الرؤية الليلية <small>عنوان URL</small>",
|
||||||
|
"Enable Nightvision": "تمكن رؤية ليلية",
|
||||||
|
"Enabled": "تمكين",
|
||||||
|
"End": "نهاية",
|
||||||
|
"End Time": "نهاية الوقت",
|
||||||
|
"Ended": "انتهت",
|
||||||
|
"Enlarge": "تكبير",
|
||||||
|
"Enter this code to proceed": "أدخل هذا الرمز إلى المضي قدما",
|
||||||
|
"Equal to": "يساوي",
|
||||||
|
"Error Connecting": "حدث خطأ أثناء الاتصال",
|
||||||
|
"Event": "الحدث",
|
||||||
|
"Event Limit": "الحدث الحد",
|
||||||
|
"EventText1": "أثار الحدث الحركة في",
|
||||||
|
"EventText2": "لا يمكن أن البريد الإلكتروني صورة الملف لا يمكن الوصول إليها",
|
||||||
|
"Events": "الأحداث",
|
||||||
|
"Example": "على سبيل المثال",
|
||||||
|
"Execute Command": "تنفيذ الأوامر",
|
||||||
|
"Executed": "أعدم",
|
||||||
|
"Export": "التصدير",
|
||||||
|
"FFmpegCantStart": "FFmpeg لم تبدأ",
|
||||||
|
"FFmpegCantStartText": "تسجيل محرك هذه الكاميرا لا يمكن أن تبدأ. قد يكون هناك شيء خاطئ مع الكاميرا التكوين. إذا كان هناك أي سجلات أخرى من هذا واحد يرجى نشرها في <b>القضايا</b> على جيثب.",
|
||||||
|
"FFmpegTip": "FFprobe بسيط تيارات متعددة الوسائط محلل. يمكنك استخدامه لانتاج جميع أنواع المعلومات حول المدخلات بما في ذلك مدة, معدل الإطار, حجم الإطار ، إلخ.",
|
||||||
|
"FFprobe": "التحقيق",
|
||||||
|
"FactorAuthText1": "كود سوف يكون نشطا فقط لمدة 15 دقيقة. إذا كنت تسجيل الدخول مرة أخرى الموقت سيتم إعادة تعيين إلى 15 دقيقة مع نفس القانون.",
|
||||||
|
"Fatal": "قاتلة",
|
||||||
|
"Fatal Maximum Reached": "قاتلة الأقصى التوصل إلى وقف الكاميرا.",
|
||||||
|
"FatalMaximumReachedText": "JPEG كان خطأ فادح.",
|
||||||
|
"Feed-in Image Height": "تغذية في ارتفاع الصورة",
|
||||||
|
"Feed-in Image Width": "تغذية في صورة العرض",
|
||||||
|
"Fields cannot be empty": "المجالات لا يمكن أن تكون فارغة",
|
||||||
|
"File Not Exist": "الملف غير موجود",
|
||||||
|
"File Not Found": "لم يتم العثور على الملف",
|
||||||
|
"File Type": "نوع الملف",
|
||||||
|
"FileNotExistText": "لا يمكن حفظ غير متوفرة. شيء ذهب على نحو خاطئ.",
|
||||||
|
"Filename": "اسم الملف",
|
||||||
|
"Filesize": "حجم الملف",
|
||||||
|
"Filter ID": "تصفية معرف",
|
||||||
|
"Filter Matches": "تصفية المباريات",
|
||||||
|
"Filter Name": "اسم عامل التصفية",
|
||||||
|
"FilterMatchesText1": "هذا الفلتر قد استوفت الشروط.",
|
||||||
|
"FilterMatchesText2": "أشرطة الفيديو وجدت.",
|
||||||
|
"Filters": "المرشحات",
|
||||||
|
"Filters Updated": "مرشحات تحديث",
|
||||||
|
"FiltersUpdatedText": "التغييرات التي تم حفظها وتطبيقها.",
|
||||||
|
"Find Where": "تجد فيها",
|
||||||
|
"Fix": "Fix",
|
||||||
|
"Fix Video": "إصلاح الفيديو",
|
||||||
|
"FixVideoMsg": "هل تريد إصلاح هذا الفيديو ؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||||
|
"Font Path": "مسار الخط",
|
||||||
|
"Font Size": "حجم الخط",
|
||||||
|
"Force Port": "القوة ميناء",
|
||||||
|
"Found Devices": "وجدت الأجهزة",
|
||||||
|
"Frame Rate": "معدل الإطار <small>(FPS)</small>",
|
||||||
|
"Full Frame Detection": "الإطار الكامل الكشف",
|
||||||
|
"Fullscreen": "ملء الشاشة",
|
||||||
|
"Greater Than": "أكبر من",
|
||||||
|
"Greater Than or Equal to": "أكبر من أو يساوي",
|
||||||
|
"Group Key": "المجموعة الرئيسية",
|
||||||
|
"Group Name": "اسم المجموعة",
|
||||||
|
"Grouping": "تجمع ",
|
||||||
|
"H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ",
|
||||||
|
"HLS (.m3u8)": "HLS (.m3u8)",
|
||||||
|
"HLS (includes Audio)": "HLS (ويشمل الصوت)",
|
||||||
|
"HLS Audio Encoder": "HLS ترميز الصوت",
|
||||||
|
"HLS List Size": "HLS قائمة الحجم",
|
||||||
|
"HLS Preset": "HLS مسبقا",
|
||||||
|
"HLS Segment Length": "HLS قطعة طول <small>في ثواني</small>",
|
||||||
|
"HLS Video Encoder": "HLS ترميز الفيديو",
|
||||||
|
"HTTP": "HTTP",
|
||||||
|
"HTTPS": "HTTPS",
|
||||||
|
"Height": "ارتفاع",
|
||||||
|
"Help": "مساعدة",
|
||||||
|
"Hide List": "إخفاء قائمة",
|
||||||
|
"Hide Notes": "إخفاء الملاحظات",
|
||||||
|
"Host": "المضيف",
|
||||||
|
"Hotswap Modes (Watch-Only)": "Hotswap وسائط (مشاهدة فقط)",
|
||||||
|
"How to Record": "كيفية تسجيل",
|
||||||
|
"IP Address": "عنوان IP",
|
||||||
|
"Identity": "الهوية",
|
||||||
|
"IdentityText1": "هذا هو كيف نظام تحديد البيانات عن هذا التيار. لا يمكنك تغيير <b>الشاشة معرف</b> بمجرد الضغط على حفظ. إذا كنت تريد أن تجعل <b>الشاشة معرف</b> المزيد الإنسان للقراءة قبل المتابعة.",
|
||||||
|
"IdentityText2": "يمكنك تكرار رصد بتعديل <b>رصد الهوية</b> ثم الضغط على حفظ. هل <b>يمكن</b> استخدام معرف جهاز موجود بالفعل أو أنه سيوفر أكثر من أن الشاشة معلومات قاعدة البيانات.",
|
||||||
|
"Idle": "الخمول",
|
||||||
|
"Image Height": "ارتفاع الصورة",
|
||||||
|
"Image Location": "صورة موقع <small>المسار المطلق أو ترك فارغا لاستخدام العالمية</small>",
|
||||||
|
"Image Position": "صورة الموقف",
|
||||||
|
"Image Width": "صورة العرض",
|
||||||
|
"Import": "استيراد",
|
||||||
|
"Import Monitor Configuration": "استيراد رصد التكوين",
|
||||||
|
"ImportMonitorConfigurationText": "عند القيام بذلك سوف overrwrite أي تغييرات في الوقت الراهن لم يتم حفظها. التغييرات المستوردة تطبق فقط عند الضغط على <b>حفظ</b>.",
|
||||||
|
"In": "في",
|
||||||
|
"Incorrect Settings Chosen": "إعدادات غير صحيحة المختار",
|
||||||
|
"Indifference": "اللامبالاة",
|
||||||
|
"Input": "المدخلات",
|
||||||
|
"Input Flags": "إدخال الأعلام",
|
||||||
|
"Input Type": "نوع الإدخال",
|
||||||
|
"InputText1": "هذا المقطع يحكي شينوبي كيفية تستهلك تيار. للحصول على الأداء الأمثل محاولة ضبط الكاميرا الإعدادات الداخلية. العثور على الخيارات التالية ومجموعة منهم كما هو مبين. العثور على الكاميرا الخاصة بك يمكنك استخدام <b>بنيت في ONVIF الماسح الضوئي</b> من شينوبي. بعض كاميرات ONVIF تتطلب استخدام أداة إدارة إلى تعديل الإعدادات الداخلية. إذا كنت لا يمكن العثور على الكاميرات الخاصة بك يمكنك محاولة <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">ONVIF مدير جهاز ويندوز</a>.",
|
||||||
|
"InputText2": "<ul><li><b>فراميراتي (FPS) :</b> : 10 - 15 إطارا في الثانية ، منخفض : 2-5 إطارا في الثانية</li><li><b>I-الإطار الزمني :</b> 80</li><li><b>نوع معدل بت :</b> CBR (ثابت معدل بت)</li><li><b>معدل بت :</b> بين 256kbps - 500kbps</li></ul>",
|
||||||
|
"InputText3": "إذا كنت بحاجة إلى مساعدة في معرفة ما هو إدخال نوع الكاميرا الخاصة بك يمكنك أن تأخذ نظرة في <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">الكاميرا عناوين قائمة</a> على شينوبي الموقع.",
|
||||||
|
"Invalid JSON": "صالح سلمان",
|
||||||
|
"InvalidJSONText": "يرجى التأكد من هذا هو صالح سلمان سلسلة شينوبي رصد التكوين.",
|
||||||
|
"JPEG": "JPEG",
|
||||||
|
"JPEG (Auto Enables JPEG API)": "JPEG (السيارات تمكن JPEG API)",
|
||||||
|
"JPEG API": "JPEG API <small>لقطة (cgi-bin)</small>",
|
||||||
|
"JPEG Error": "JPEG خطأ",
|
||||||
|
"JPEG Mode": "وضع JPEG",
|
||||||
|
"JPEGErrorText": "كان هناك مشكلة في الحصول على البيانات من الكاميرا الخاصة بك.",
|
||||||
|
"Leave blank for random.": "ترك فارغا عشوائية.",
|
||||||
|
"Left": "ترك <small>عنوان URL</small>",
|
||||||
|
"Left Stop": "غادر وقف <small>عنوان URL</small>",
|
||||||
|
"Less Than": "أقل من",
|
||||||
|
"Less Than or Equal to": "أقل من أو يساوي",
|
||||||
|
"Like": "مثل",
|
||||||
|
"Lisence Plate Detector": "رخصة لوحة كاشف",
|
||||||
|
"List Toggle": "قائمة تبديل",
|
||||||
|
"Live Stream Toggle": "بث مباشر تبديل",
|
||||||
|
"Live View": "عرض لايف",
|
||||||
|
"Local": "المحلية",
|
||||||
|
"Log Level": "سجل مستوى",
|
||||||
|
"Log Signal Event": "سجل إشارة الحدث <small>من جانب العميل فقط</small>",
|
||||||
|
"Logging": "تسجيل",
|
||||||
|
"Login": "تسجيل الدخول",
|
||||||
|
"Logout": "خروج",
|
||||||
|
"Logs": "سجلات",
|
||||||
|
"MB": "MB",
|
||||||
|
"MJPEG": "MJPEG",
|
||||||
|
"MP4 (copy, libx264, libx265)": "MP4 (نسخ ، libx264, libx265)",
|
||||||
|
"MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)",
|
||||||
|
"MailError": "البريد خطأ : لا يمكن إرسال البريد الإلكتروني التحقق من conf.json. تخطي أي ملامح الاعتماد على البريدية.",
|
||||||
|
"Matches": "مباريات",
|
||||||
|
"Max Storage Amount": "ماكس تخزين كمية <small>في ميغا بايت</small>",
|
||||||
|
"Mode": "وضع",
|
||||||
|
"Monitor": "رصد",
|
||||||
|
"Monitor Added by user": "رصد المضافة من قبل المستخدم.",
|
||||||
|
"Monitor Capture Rate": "رصد معدل التقاط <small>(FPS)</small>",
|
||||||
|
"Monitor Groups": "رصد مجموعات",
|
||||||
|
"Monitor ID": "رصد ID",
|
||||||
|
"Monitor Idling": "رصد تسكع",
|
||||||
|
"Monitor Name": "رصد اسم",
|
||||||
|
"Monitor Settings": "إعدادات الشاشة",
|
||||||
|
"Monitor Stopped": "رصد توقف",
|
||||||
|
"Monitor Updated by user": "مراقبة تحديث من قبل المستخدم.",
|
||||||
|
"Monitor mode changed": "مراقبة الوضع تغير",
|
||||||
|
"Monitor mode is already": "رصد وضع بالفعل",
|
||||||
|
"Monitor or Key does not exist.": "مراقبة أو عدم وجود مفتاح.",
|
||||||
|
"MonitorIdlingText": "مراقبة الدورة وقد أمر إلى الخمول.",
|
||||||
|
"MonitorStoppedText": "مراقبة الدورة وقد أمر التوقف.",
|
||||||
|
"Monitors": "شاشات",
|
||||||
|
"Monitors per row": "شاشات لكل صف <small>على المونتاج</small>",
|
||||||
|
"Montage": "المونتاج",
|
||||||
|
"Motion GUI": "الحركة واجهة المستخدم الرسومية",
|
||||||
|
"Motion Meter": "الحركة متر",
|
||||||
|
"Name": "اسم",
|
||||||
|
"No": "لا",
|
||||||
|
"No Audio": "لا الصوت",
|
||||||
|
"No Data": "لا توجد بيانات",
|
||||||
|
"No Events found for this video": "لا الأحداث وجدت هذا الفيديو",
|
||||||
|
"No Group with this key exists": "أي جماعة مع هذا المفتاح موجود",
|
||||||
|
"No Monitor Found, Ignoring Request": "لا مراقبة وجدت تجاهل الطلب",
|
||||||
|
"No Rotation": "لا دوران",
|
||||||
|
"No such file": "لا يوجد مثل هذا الملف",
|
||||||
|
"NoMotionEmailText1": "لا الحركة",
|
||||||
|
"NoMotionEmailText2": "لم يكن هناك أي حركة الكشف على الكاميرا",
|
||||||
|
"NoVideosFoundForDateRange": "لا أشرطة الفيديو الموجودة في هذا النطاق الزمني. محاولة تحديد بداية التاريخ إلى الوراء.",
|
||||||
|
"Not Authorized": "لا يؤذن",
|
||||||
|
"Not Connected": "غير متصل",
|
||||||
|
"Not Equal to": "لا يساوي",
|
||||||
|
"Not In": "لا في",
|
||||||
|
"Not Matches": "لا يطابق",
|
||||||
|
"Not Permitted": "لا يسمح",
|
||||||
|
"Not an Administrator Account": "لا حساب مسؤول",
|
||||||
|
"NotAuthorizedText1": "لا يحق تقديم init الأمر مع \"مصادقة\",\"كه\", \"uid\"",
|
||||||
|
"Notes": "ملاحظات",
|
||||||
|
"NotesPlacholder": "التعليقات كنت تريد أن تترك هذه الكاميرات الإعدادات.",
|
||||||
|
"Number of Days to keep": "عدد أيام الاحتفاظ",
|
||||||
|
"ONVIF": "ONVIF",
|
||||||
|
"ONVIF Scanner": "ONVIF الماسح الضوئي",
|
||||||
|
"ONVIFnote": "اكتشاف ONVIF الأجهزة على الشبكات خارج الخاص بك أو اتركه فارغا لمسح شبكة الاتصال الحالية الخاصة بك. <br>اسم المستخدم وكلمة المرور يمكن أن تترك فارغة.",
|
||||||
|
"OpenCV Cascades": "بنسف شلالات",
|
||||||
|
"Order Streams": "ترتيب الجداول",
|
||||||
|
"Output Method": "أسلوب الإخراج",
|
||||||
|
"Password": "كلمة المرور",
|
||||||
|
"Password Again": "كلمة المرور مرة أخرى",
|
||||||
|
"Passwords don't match": "كلمات السر لا تتطابق",
|
||||||
|
"Paste JSON here.": "لصق JSON هنا.",
|
||||||
|
"Path": "المسار",
|
||||||
|
"Permissions": "أذونات",
|
||||||
|
"Points": "نقاط <small>عند إضافة نقاط انقر على حافة المضلع.</small>",
|
||||||
|
"Port": "ميناء",
|
||||||
|
"Position X": "موقف X",
|
||||||
|
"Position Y": "موقف Y",
|
||||||
|
"Power Video Viewer": "فيديو المشاهد",
|
||||||
|
"Power Viewer": "السلطة المشاهد",
|
||||||
|
"Preferences": "تفضيلات",
|
||||||
|
"Preset": "مسبقا",
|
||||||
|
"Probe Size": "التحقيق الحجم",
|
||||||
|
"Process Crashed for Monitor": "عملية تحطمت على رصد",
|
||||||
|
"Process Unexpected Exit": "عملية خروج غير متوقع",
|
||||||
|
"Profile": "الملف الشخصي",
|
||||||
|
"Quality": "جودة <small>1 عالية ، 23 منخفضة</small>",
|
||||||
|
"Query": "الاستعلام",
|
||||||
|
"RAM": "ذاكرة الوصول العشوائي",
|
||||||
|
"RTSP": "RTSP",
|
||||||
|
"RTSP Transport": "RTSP النقل",
|
||||||
|
"Range or Single": "مجموعة أو واحد",
|
||||||
|
"Rate": "معدل <small>(FPS)</small>",
|
||||||
|
"Record": "سجل",
|
||||||
|
"Record File Type": "تسجيل نوع الملف",
|
||||||
|
"Record Height": "سجل ارتفاع",
|
||||||
|
"Record Video Filter": "تسجيل الفيديو فلتر",
|
||||||
|
"Record Width": "سجل العرض",
|
||||||
|
"Recording": "تسجيل",
|
||||||
|
"Recording Flags": "تسجيل الأعلام",
|
||||||
|
"Recording Segment Interval": "تسجيل الجزء الفاصل الزمني <small>في دقائق</small>",
|
||||||
|
"Recording Timeout": "تسجيل مهلة <small>في دقائق</small>",
|
||||||
|
"Recording Timestamp": "تسجيل الزمني",
|
||||||
|
"Recording Watermark": "تسجيل العلامة المائية",
|
||||||
|
"RecordingText": "فمن المستحسن أن تقوم بتعيين <b>تسجيل نوع الملف</b> إلى <b class=\"h_t_input h_t_jpeg h_t_socket\">WebM</b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">MP4</b> و <b>ترميز الفيديو</b> إلى <b class=\"h_t_input h_t_jpeg h_t_socket\">libvpx</b><b class=\"h_t_input h_t_h264 h_t_hls h_t_mp4\">نسخ أو </b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">libx264</b> لأن <b>إدخال نوع</b> هو <b class=\"h_t_text\"></b>.",
|
||||||
|
"Refresh List of Cascades": "تحديث قائمة شلالات",
|
||||||
|
"Region Editor": "المنطقة محرر",
|
||||||
|
"Region Name": "اسم المنطقة",
|
||||||
|
"RegionNote": "النقاط يتم حفظها فقط عند الضغط <b>حفظ</b> على <b>إعدادات الشاشة</b> نافذة.",
|
||||||
|
"Regions": "المناطق",
|
||||||
|
"Remember Me": "تذكر لي",
|
||||||
|
"Reset Timer": "إعادة تعيين جهاز ضبط الوقت",
|
||||||
|
"Restarting Process": "إعادة تشغيل العملية",
|
||||||
|
"Retry Connection": "إعادة المحاولة اتصال <small>عدد المرات التي يسمح تفشل</small>",
|
||||||
|
"Retrying...": "إعادة المحاولة...",
|
||||||
|
"Right": "صحيح <small>عنوان URL</small>",
|
||||||
|
"Right Stop": "صحيح وقف <small>عنوان URL</small>",
|
||||||
|
"Rotate": "تدوير",
|
||||||
|
"Save": "حفظ",
|
||||||
|
"Save Directory": "حفظ الدليل",
|
||||||
|
"Save Events to SQL": "حفظ الأحداث إلى SQL",
|
||||||
|
"Save Log in SQL": "حفظ سجل في SQL <small>وهذا يمكن أن تملأ بسرعة.</small>",
|
||||||
|
"Save as": "حفظ باسم",
|
||||||
|
"Saved Filters": "حفظ الفلاتر",
|
||||||
|
"Scan Settings": "إعدادات المسح الضوئي",
|
||||||
|
"Search": "البحث",
|
||||||
|
"Send Frames": "إرسال إطارات <small>دفع الإطارات ليتم تحليلها</small>",
|
||||||
|
"Separate with commas, no spaces": "منفصلة بفواصل, بدون مسافات",
|
||||||
|
"Set to Watch Only": "تعيين مشاهدة فقط",
|
||||||
|
"Settings": "الإعدادات",
|
||||||
|
"Settings Changed": "تغيير الإعدادات",
|
||||||
|
"SettingsChangedText": "إعدادات تم حفظها وتطبيقها.",
|
||||||
|
"Shinobi": "شينوبي",
|
||||||
|
"Shinobi Streamer": "شينوبي غاسل",
|
||||||
|
"Show Logs": "تظهر سجلات",
|
||||||
|
"Silent": "الصمت",
|
||||||
|
"Simple": "بسيطة",
|
||||||
|
"Size (mb)": "الحجم (ميجا بايت)",
|
||||||
|
"Snapshot": "لقطة",
|
||||||
|
"Snapshot Flags": "لقطة الأعلام",
|
||||||
|
"Snapshots": "لقطات",
|
||||||
|
"Sort By": "فرز حسب",
|
||||||
|
"Start": "تبدأ",
|
||||||
|
"Start Recording": "بدء التسجيل",
|
||||||
|
"Start Time": "وقت البدء",
|
||||||
|
"Started": "بدأت",
|
||||||
|
"Status Indicator": "مؤشر حالة",
|
||||||
|
"Stop URL": "وقف URL",
|
||||||
|
"Stream": "تيار",
|
||||||
|
"Stream Flags": "تيار الأعلام",
|
||||||
|
"Stream Timestamp": "تيار الزمني",
|
||||||
|
"Stream Type": "تيار من نوع",
|
||||||
|
"Stream Watermark": "تيار مائية",
|
||||||
|
"Stream to YouTube": "تيار يوتيوب",
|
||||||
|
"Stream to YouTube Flags": "تيار يوتيوب الأعلام",
|
||||||
|
"StreamText": "<p>هذا القسم سوف تعين الابتدائي تيار الأسلوب وإعدادات. هذا التيار سوف يتم عرضها في لوحة القيادة. إذا اخترت استخدام HLS, JPEG, أو MJPEG ثم يمكنك تستهلك تيار من خلال البرامج الأخرى.</p><p class=\"h_st_input h_st_jpeg\">استخدام JPEG تيار أساسا إيقاف البث الأساسية يستخدم اللقطة بن للحصول على إطارات.</p>",
|
||||||
|
"Streamer": "غاسل",
|
||||||
|
"Streams": "تيارات",
|
||||||
|
"Superuser": "الخارق",
|
||||||
|
"Switch on for Still Image": "التبديل على صورة ثابتة",
|
||||||
|
"TCP": "TCP",
|
||||||
|
"Text Box Color": "النص مربع اللون",
|
||||||
|
"Text Color": "لون النص",
|
||||||
|
"Time-lapse": "الوقت الفاصل بين",
|
||||||
|
"Time-lapse Tool": "الوقت الفاصل بين أداة",
|
||||||
|
"Timeout": "مهلة",
|
||||||
|
"Timeout Reset on Next Motion": "مهلة إعادة تعيين على الحركة القادمة",
|
||||||
|
"Toggle Sidebar": "تبديل الشريط الجانبي",
|
||||||
|
"Top Left": "أعلى اليسار",
|
||||||
|
"Top Right": "أعلى اليمين",
|
||||||
|
"Trigger Record": "الزناد سجل",
|
||||||
|
"Trigger Successful": "الزناد ناجحة",
|
||||||
|
"UDP": "UDP",
|
||||||
|
"URL": "URL",
|
||||||
|
"URL Stop Timeout": "URL وقف مهلة <small>تشغيل إيقاف URL بعد X ثانية</small>",
|
||||||
|
"US": "لنا",
|
||||||
|
"Unable to Launch": "قادر على إطلاق",
|
||||||
|
"UnabletoLaunchText": "الرجاء حفظ رصد جديدة أولا. ثم محاولة إطلاق محرر المنطقة.",
|
||||||
|
"Up": "حتى <small>عنوان URL</small>",
|
||||||
|
"Up Stop": "حتى وقف <small>عنوان URL</small>",
|
||||||
|
"Username": "اسم المستخدم",
|
||||||
|
"Value": "القيمة",
|
||||||
|
"Video": "فيديو",
|
||||||
|
"Video Codec": "ترميز الفيديو",
|
||||||
|
"Video Filter": "فيديو مرشح",
|
||||||
|
"Video Finished": "الفيديو النهائي",
|
||||||
|
"Video Length (minutes) and Motion Count per video": "طول الفيديو (دقيقة) و الحركة الاعتماد في الفيديو",
|
||||||
|
"Video Record Rate": "الفيديو سجل معدل <small>(FPS)</small>",
|
||||||
|
"Video Status": "فيديو حالة",
|
||||||
|
"Video and Time Span (Minutes)": "فيديو من الزمن (دقيقة)",
|
||||||
|
"Videos": "الفيديو",
|
||||||
|
"Videos List": "قائمة أشرطة الفيديو",
|
||||||
|
"Watch": "مشاهدة",
|
||||||
|
"Watch Only": "مشاهدة فقط",
|
||||||
|
"WebDAV": "WebDAV",
|
||||||
|
"WebM (libvpx)": "WebM (libvpx)",
|
||||||
|
"Webdav Error": "خطأ Webdav",
|
||||||
|
"WebdavErrorText": "لا يمكن حفظ. هل جعل الكاميرا المجلدات داخل اخترتها حفظ الدليل ؟ ",
|
||||||
|
"Webhook": "Webhook",
|
||||||
|
"Webhook URL": "Webhook URL",
|
||||||
|
"Width": "العرض",
|
||||||
|
"Yes": "نعم",
|
||||||
|
"Zoom In": "التكبير في <small>عنوان URL</small>",
|
||||||
|
"Zoom In Stop": "التكبير في التوقف عن <small>عنوان URL</small>",
|
||||||
|
"Zoom Out": "تصغير <small>عنوان URL</small>",
|
||||||
|
"Zoom Out Stop": "تصغير وقف <small>عنوان URL</small>",
|
||||||
|
"a day": "اليوم",
|
||||||
|
"a few seconds": "بضع ثوان",
|
||||||
|
"a minute": "دقيقة",
|
||||||
|
"a month": "شهر",
|
||||||
|
"a year": "في السنة",
|
||||||
|
"aac": "الجميح للسيارات",
|
||||||
|
"aac (Default)": "الجميح للسيارات (افتراضي)",
|
||||||
|
"ac3": "ac3",
|
||||||
|
"ago": "قبل",
|
||||||
|
"an hour": "ساعة",
|
||||||
|
"blankPassword": "تترك فارغة إلى الحفاظ على نفس كلمة المرور",
|
||||||
|
"calendar": "التقويم",
|
||||||
|
"clientStreamFailedattemptingReconnect": "العميل ctream تحقق فشلت محاولة إعادة الاتصال.",
|
||||||
|
"confirmDeleteFilter": "هل تريد حذف هذا الفلتر ؟ لا يمكنك استرداد.",
|
||||||
|
"copy": "نسخ",
|
||||||
|
"days": "أيام",
|
||||||
|
"dropBoxSuccess": "النجاح! الملفات المحفوظة إلى دروببوإكس الخاص بك.",
|
||||||
|
"for Global Access": "من أجل الوصول العالمي",
|
||||||
|
"hours": "ساعات",
|
||||||
|
"in": "في",
|
||||||
|
"libmp3lame": "libmp3lame",
|
||||||
|
"libopus": "libopus",
|
||||||
|
"libvorbis (Default)": "libvorbis (الافتراضي)",
|
||||||
|
"libvpx (Default)": "libvpx (الافتراضي)",
|
||||||
|
"libvpx-vp9": "libvpx-vp9",
|
||||||
|
"libx264": "libx264",
|
||||||
|
"libx264 (Default)": "libx264 (الافتراضي)",
|
||||||
|
"libx265": "libx265",
|
||||||
|
"minutes": "دقائق",
|
||||||
|
"modifyVideoText1": "طريقة لا وجود لها. تحقق للتأكد من أن آخر قيمة URL ليست فارغة.",
|
||||||
|
"monitorEditFailedMaxReached": "حسابك قد بلغ أقصى عدد من الكاميرات التي يمكن إنشاؤها. التحدث إلى مسؤول إذا كنت ترغب في تغيير هذا.",
|
||||||
|
"monitorEditText1": "بيانات غير صالحة ، تحقق لمعرفة هذا هو صالح استيراد السلسلة.",
|
||||||
|
"monitorEditText2": "غير صالحة تفاصيل السلسلة. تحقق لمعرفة ما هو سلسلة JSON و غير منتظم وجوه يتم تمريرها.",
|
||||||
|
"monitorGetText1": "الطلب غير المكتمل ، وإزالة الماضي مائل في URL أو وضع مقبول القيمة.",
|
||||||
|
"months": "أشهر",
|
||||||
|
"noSpecialCharacters": "بدون مسافات أو أحرف خاصة.",
|
||||||
|
"on": "على",
|
||||||
|
"on Error": "على خطأ",
|
||||||
|
"startUpText0": "حجم التحقق من أشرطة الفيديو",
|
||||||
|
"startUpText1": "الغاية من حجم التحقق من أشرطة الفيديو",
|
||||||
|
"startUpText2": "جميع المستخدمين فحص الانتظار لإغلاق الملفات المفتوحة وإزالة الملفات على حد المستخدم",
|
||||||
|
"startUpText3": "في انتظار أن تعطي لم تنته الفيديو تحقق بعض الوقت. 3 ثوان.",
|
||||||
|
"startUpText4": "بدأت كل مجموعة شاشات لمشاهدة وتسجيل",
|
||||||
|
"startUpText5": "شينوبي جاهز.",
|
||||||
|
"superAdminText": "\"السوبر.سلمان\" لا وجود لها. الرجاء إعادة تسمية \"سوبر.العينة.سلمان\" إلى \"السوبر.سلمان\".",
|
||||||
|
"superAdminTitle": "شينوبي : المشرف المميز",
|
||||||
|
"total": "مجموع",
|
||||||
|
"undefined": "غير معرف",
|
||||||
|
"updateKeyText1": "\"updateKey\" مفقود من \"conf.json\", لا يمكن أن تفعل التحديثات هذه الطريقة حتى يمكنك إضافته.",
|
||||||
|
"updateKeyText2": "\"updateKey\" غير صحيحة.",
|
||||||
|
"years": "سنوات"
|
||||||
|
}
|
|
@ -0,0 +1,496 @@
|
||||||
|
{
|
||||||
|
"\"No Motion\" Detector": "\"কোন গতি\" আবিষ্কারক",
|
||||||
|
"# of Allow MJPEG Clients": "# of Allow MJPEG Clients <small>0 for infinite</small>",
|
||||||
|
"180 Degrees": "180 ডিগ্রী",
|
||||||
|
"2-Factor Authentication": "2 ফ্যাক্টর প্রমাণীকরণ",
|
||||||
|
"90 Clockwise": "ঘড়ির কাঁটার দিকে 90",
|
||||||
|
"90 Clockwise and Vertical Flip": "90 ঘড়ির কাঁটার দিকে এবং উল্লম্ব উল্টানো",
|
||||||
|
"90 Counter Clockwise and Vertical Flip (default)": "90 পাল্টা ঘড়ির কাঁটার দিকে এবং উল্লম্ব উল্টানো (ডিফল্ট)",
|
||||||
|
"API": "এপিআই",
|
||||||
|
"API Key Added": "API কী যোগ করা হয়েছে",
|
||||||
|
"API Key Deleted": "API কী মুছে ফেলা",
|
||||||
|
"API Keys": "API কী",
|
||||||
|
"APIKeyAddedText": "আপনি এই ব্যবহার করতে পারেন কী এখন.",
|
||||||
|
"APIKeyDeletedText": "কী মুছে ফেলা হয়েছে. এটা আর কাজ.",
|
||||||
|
"ASC": "ASC",
|
||||||
|
"Account Info": "অ্যাকাউন্ট তথ্য",
|
||||||
|
"AccountEditText1": "না পারে সম্পাদনা করুন. রিফ্রেশ পাতা যদি সমস্যা চলতে থাকে.",
|
||||||
|
"Accounts": "অ্যাকাউন্ট",
|
||||||
|
"Action for Selected": "কর্ম জন্য নির্বাচিত",
|
||||||
|
"Add": "যোগ",
|
||||||
|
"Add Monitor": "যোগ মনিটর",
|
||||||
|
"Add New": "নতুন যুক্ত করুন",
|
||||||
|
"Admin": "অ্যাডমিন",
|
||||||
|
"Advanced": "উন্নত",
|
||||||
|
"Again": "আবার",
|
||||||
|
"All Monitors": "সব মনিটর",
|
||||||
|
"All Monitors and Privileges": "সব মনিটর এবং বিশেষাধিকার",
|
||||||
|
"All Warnings": "সব সতর্কবার্তা",
|
||||||
|
"Allow Next Command": "অনুমতি পরবর্তী কমান্ড <small>মিনিটের মধ্যে</small>",
|
||||||
|
"Allow Next Email": "অনুমতি পরবর্তী ইমেইল <small>মিনিটের মধ্যে</small>",
|
||||||
|
"Allow Next Trigger": "অনুমতি পরবর্তী ট্রিগার <small>মিলিসেকেন্ডে ব্যক্ত</small>",
|
||||||
|
"Allowed IPs": "অনুমোদিত আইপিএস",
|
||||||
|
"Analyzation Duration": "Analyzation সময়কাল",
|
||||||
|
"Archive": "আর্কাইভ",
|
||||||
|
"Audio Codec": "অডিও কোডেক",
|
||||||
|
"Authenticate": "প্রমাণীকরণ",
|
||||||
|
"Auto": "অটো",
|
||||||
|
"Autosave": "স্বয়ংসংরক্ষিত",
|
||||||
|
"Base64 over Websocket": "Base64 উপর Websocket",
|
||||||
|
"Bottom Left": "নীচে বাম",
|
||||||
|
"Bottom Right": "নীচের অংশে ডানদিকে",
|
||||||
|
"Browser Console Log": "ব্রাউজার কনসোল লগ",
|
||||||
|
"CPU": "CPU-র",
|
||||||
|
"CPU indicator will not work. Continuing...": "CPU-র সূচক কাজ করবে না. অব্যাহত...",
|
||||||
|
"CSS": "CSS এর <small>শৈলী আপনার ড্যাশবোর্ড.</small>",
|
||||||
|
"Calendar": "ক্যালেন্ডার",
|
||||||
|
"Camera Password": "ক্যামেরা পাসওয়ার্ড",
|
||||||
|
"Camera Username": "ক্যামেরা ব্যবহারকারীর নাম",
|
||||||
|
"Camera is not recording": "ক্যামেরা নয়, রেকর্ডিং",
|
||||||
|
"CameraNotRecordingText": "সেটিংস বেমানান হতে পারে. পরীক্ষা এনকোডার. রিস্টার্ট...",
|
||||||
|
"Can Control Monitors": "নিয়ন্ত্রণ করতে পারেন মনিটর",
|
||||||
|
"Can Delete Videos": "মুছে দিতে পারেন ভিডিও",
|
||||||
|
"Can Delete Videos and Events": "মুছে দিতে পারেন ভিডিও এবং ঘটনা",
|
||||||
|
"Can Edit Monitor": "সম্পাদনা করতে পারেন নিরীক্ষণ",
|
||||||
|
"Can Get Logs": "পেতে পারেন, লগ",
|
||||||
|
"Can Get Monitors": "পেতে পারেন মনিটর",
|
||||||
|
"Can View Monitor": "দেখতে পারেন, নিরীক্ষণ",
|
||||||
|
"Can View Snapshots": "স্ন্যাপশট দেখতে পারেন",
|
||||||
|
"Can View Streams": "দেখতে পারেন স্ট্রিম",
|
||||||
|
"Can View Videos": "করতে পারেন, দেখুন ভিডিও",
|
||||||
|
"Can View Videos and Events": "করতে পারেন, দেখুন ভিডিও এবং ঘটনা",
|
||||||
|
"Can't Connect": "সংযোগ করতে পারবেন না পারে",
|
||||||
|
"Center": "কেন্দ্র <small>URL ঠিকানা</small>",
|
||||||
|
"Chat on Discord": "চ্যাট বিভেদ",
|
||||||
|
"Check": "পরীক্ষা",
|
||||||
|
"Check Signal Interval": "পরীক্ষা সংকেত ব্যবধান <small>মিনিটের মধ্যে</small>",
|
||||||
|
"Check for Motion First": "পরীক্ষা গতি জন্য প্রথম",
|
||||||
|
"Close": "বন্ধ",
|
||||||
|
"Closed": "বন্ধ",
|
||||||
|
"Command": "কমান্ড",
|
||||||
|
"Command on Trigger": "কমান্ড ট্রিগার",
|
||||||
|
"Complete Stream URL": "সম্পূর্ণ স্ট্রিম URL",
|
||||||
|
"Confirm": "নিশ্চিত",
|
||||||
|
"Connected": "সংযুক্ত",
|
||||||
|
"Connection Type": "সংযোগের ধরন",
|
||||||
|
"Control": "নিয়ন্ত্রণ",
|
||||||
|
"Control Error": "কন্ট্রোল ত্রুটি",
|
||||||
|
"ControlErrorText1": "নিয়ন্ত্রণ সক্রিয় করা হয় না",
|
||||||
|
"Controllable": "নিয়ন্ত্রণযোগ্য",
|
||||||
|
"Country of Plates": "দেশ প্লেট",
|
||||||
|
"Counts of Motion": "সংখ্যা, গতি",
|
||||||
|
"Current": "বর্তমান",
|
||||||
|
"Currently viewing": "বর্তমানে দেখছেন",
|
||||||
|
"Custom": "কাস্টম",
|
||||||
|
"Custom Base URL": "কাস্টম বেস URL <small>ফাঁকা ছেড়ে দিন ব্যবহার করে হোস্ট URL টি</small>",
|
||||||
|
"DB Lost.. Retrying..": "ডাটাবেস হারিয়ে.. Retrying..",
|
||||||
|
"DESC": "নিম্নক্রমে",
|
||||||
|
"Dashboard": "ড্যাশবোর্ড",
|
||||||
|
"Dashboard Language": "ড্যাশবোর্ড ভাষা",
|
||||||
|
"Dashcam": "Dashcam",
|
||||||
|
"Dashcam (Streamer v2)": "Dashcam (আলোকরশ্মি v2)",
|
||||||
|
"Date Range": "তারিখ পরিসীমা",
|
||||||
|
"Debug": "ডিবাগ",
|
||||||
|
"Default": "ডিফল্ট",
|
||||||
|
"Delete": "মুছে দিন",
|
||||||
|
"Delete Filter": "মুছে দিন, ফিল্টার",
|
||||||
|
"Delete Matches": "মুছে ম্যাচ",
|
||||||
|
"Delete Monitor": "মুছে মনিটর",
|
||||||
|
"Delete Motionless Video": "মুছে নিস্পন্দ ভিডিও",
|
||||||
|
"Delete Motionless Videos (Record)": "মুছে নিস্পন্দ ভিডিও (রেকর্ড)",
|
||||||
|
"Delete Selected Videos": "মুছে ফেলুন ভিডিও",
|
||||||
|
"Delete Video": "মুছে ভিডিও",
|
||||||
|
"Delete selected": "মুছে ফেলুন",
|
||||||
|
"DeleteMonitorText": "আপনি মুছে ফেলতে চান, এই নিরীক্ষণ? আপনি পুনরুদ্ধার করা সম্ভব না, এটা. ফাইল জন্য এই আইডি থাকবে ফাইলসিস্টেম. যদি আপনি চয়ন করতে পুনঃ একটি মনিটর সঙ্গে একই আইডি ভিডিও এবং ঘটনা হয়ে যাবে দৃশ্যমান ড্যাশবোর্ড.",
|
||||||
|
"DeleteSelectedVideosMsg": "আপনি মুছে ফেলতে চান, এই ভিডিও? আপনি পুনরুদ্ধার করা সম্ভব না তাদের.",
|
||||||
|
"DeleteVideoMsg": "আপনি মুছে ফেলতে চান, এই ভিডিও? আপনি পুনরুদ্ধার করা সম্ভব না, এটা.",
|
||||||
|
"Deleted": "মুছে ফেলা",
|
||||||
|
"Detect Objects": "সনাক্ত বস্তু <small class=\"\">নিচে দেখুন</small>",
|
||||||
|
"Detector": "আবিষ্কারক",
|
||||||
|
"Detector Flags": "আবিষ্কারক পতাকা",
|
||||||
|
"Detector Rate": "আবিষ্কারক হার <small>(FPS যে)</small>",
|
||||||
|
"DetectorText": "<p>যখন প্রস্থ এবং উচ্চতা বাক্সে দেখানো হয়, আপনি সেট করা উচিত তাদের 640x480 বা নিচে. এই হবে নিখুত, গতি পড়া ফ্রেম.</p>",
|
||||||
|
"Disable Night Vision": "নিষ্ক্রিয় রাতে দৃষ্টি <small>URL ঠিকানা</small>",
|
||||||
|
"Disable Nightvision": "নিষ্ক্রিয় Nightvision",
|
||||||
|
"Disabled": "প্রতিবন্ধী",
|
||||||
|
"Documentation": "ডকুমেন্টেশন",
|
||||||
|
"Don't show this anymore": "প্রদর্শন করবেন না, এই আর",
|
||||||
|
"Double Quote Directory": "ডবল উদ্ধৃতি ডিরেক্টরি <small>কিছু ডিরেক্টরি আছে স্পেস. এই ব্যবহার করে বিপর্যস্ত হতে পারে, কিছু ক্যামেরা.</small>",
|
||||||
|
"Down": "নিচে <small>URL ঠিকানা</small>",
|
||||||
|
"Down Stop": "নিচে বন্ধ <small>URL ঠিকানা</small>",
|
||||||
|
"Download": "ডাউনলোড",
|
||||||
|
"EU": "ইইউ",
|
||||||
|
"Edit": "সম্পাদনা",
|
||||||
|
"Email": "ইমেইল",
|
||||||
|
"Email Details": "ইমেইল বিস্তারিত",
|
||||||
|
"Email on No Motion": "ইমেইল, \"কোন গতি\"",
|
||||||
|
"Email on Trigger": "ইমেইল উপর ট্রিগার <small>ইমেল যান প্রধান অ্যাকাউন্ট ধারক এর লগইন ঠিকানা.</small>",
|
||||||
|
"Enable Night Vision": "সক্রিয় নাইট দৃষ্টি <small>URL ঠিকানা</small>",
|
||||||
|
"Enable Nightvision": "সক্রিয় Nightvision",
|
||||||
|
"Enabled": "সক্রিয়",
|
||||||
|
"End": "শেষ",
|
||||||
|
"End Time": "শেষ সময়",
|
||||||
|
"Ended": "শেষ",
|
||||||
|
"Enlarge": "বিবর্ধন",
|
||||||
|
"Enter this code to proceed": "এই কোড লিখুন এগিয়ে যেতে",
|
||||||
|
"Equal to": "সমান",
|
||||||
|
"Error Connecting": "সংযোগ ত্রুটি",
|
||||||
|
"Event": "ইভেন্ট",
|
||||||
|
"Event Limit": "ইভেন্ট সীমা",
|
||||||
|
"EventText1": "সূত্রপাত গতি এ ঘটনা",
|
||||||
|
"EventText2": "না পারে, ইমেইল, ইমেজ ফাইল ছিল না, প্রবেশযোগ্য",
|
||||||
|
"Events": "ঘটনা",
|
||||||
|
"Example": "উদাহরণ",
|
||||||
|
"Execute Command": "চালানো কমান্ড",
|
||||||
|
"Executed": "মৃত্যুদন্ড কার্যকর",
|
||||||
|
"Export": "রপ্তানি",
|
||||||
|
"FFmpegCantStart": "FFmpeg শুরু করতে পারে না",
|
||||||
|
"FFmpegCantStartText": "রেকর্ডিং ইঞ্জিন জন্য এই ক্যামেরা শুরু করতে পারে না. হতে পারে, কিছু ভুল আপনার ক্যামেরা সঙ্গে কনফিগারেশন. যদি সেখানে হয় কোন লগ তুলনায় অন্যান্য, এই এক পোস্ট করুন তাদের <b>সমস্যা</b> Github উপর.",
|
||||||
|
"FFmpegTip": "FFprobe একটি সহজ মাল্টিমিডিয়া স্ট্রিম বিশ্লেষক. আপনি এটি ব্যবহার করতে পারেন আউটপুট সব ধরণের তথ্য সম্পর্কে একটি ইনপুট সহ, সময়কাল, ফ্রেম রেট, ফ্রেম সাইজ, ইত্যাদি.",
|
||||||
|
"FFprobe": "প্রোবের",
|
||||||
|
"FactorAuthText1": "কোড কেবল তখনই সক্রিয় করা হবে 15 মিনিটের জন্য. যদি আপনি আবার লগইন হবে টাইমার রিসেট করার 15 মিনিট একই সঙ্গে কোড.",
|
||||||
|
"Fatal": "মারাত্মক",
|
||||||
|
"Fatal Maximum Reached": "মারাত্মক সর্বোচ্চ পৌঁছেছেন বাঁধন ক্যামেরা.",
|
||||||
|
"FatalMaximumReachedText": "কোন JPEG ত্রুটি ছিল মারাত্মক.",
|
||||||
|
"Feed-in Image Height": "ফিড-ইন ইমেজ উচ্চতা",
|
||||||
|
"Feed-in Image Width": "ফিড-ইন ইমেজ প্রস্থ",
|
||||||
|
"Fields cannot be empty": "ক্ষেত্র হতে পারে না, খালি",
|
||||||
|
"File Not Exist": "ফাইল উপস্থিত না",
|
||||||
|
"File Not Found": "ফাইল পাওয়া যায় না",
|
||||||
|
"File Type": "ফাইল টাইপ",
|
||||||
|
"FileNotExistText": "সংরক্ষণ করতে পারবেন না, অ existant ফাইল. কিছু ভুল হয়েছে.",
|
||||||
|
"Filename": "ফাইলের নাম",
|
||||||
|
"Filesize": "Filesize",
|
||||||
|
"Filter ID": "ফিল্টার আইডি",
|
||||||
|
"Filter Matches": "ফিল্টার ম্যাচ",
|
||||||
|
"Filter Name": "ফিল্টার নাম",
|
||||||
|
"FilterMatchesText1": "এই ফিল্টার শর্ত পূরণ করা হয়েছে.",
|
||||||
|
"FilterMatchesText2": "ভিডিও পাওয়া যায়.",
|
||||||
|
"Filters": "ফিল্টার",
|
||||||
|
"Filters Updated": "ফিল্টার আপডেট করা হয়েছে",
|
||||||
|
"FiltersUpdatedText": "আপনার পরিবর্তনগুলি সংরক্ষণ করা হয়েছে এবং প্রয়োগ.",
|
||||||
|
"Find Where": "এটি যেখানে",
|
||||||
|
"Fix": "ফিক্স",
|
||||||
|
"Fix Video": "ফিক্স ভিডিও",
|
||||||
|
"FixVideoMsg": "আপনি কি করতে চান ঠিক এই ভিডিও? আপনি পূর্বাবস্থা করতে পারবেন না, এই কর্ম.",
|
||||||
|
"Font Path": "ফন্ট পথ",
|
||||||
|
"Font Size": "ফন্টের আকার",
|
||||||
|
"Force Port": "বল পোর্ট",
|
||||||
|
"Found Devices": "পাওয়া ডিভাইসের",
|
||||||
|
"Frame Rate": "ফ্রেম হার <small>(FPS যে)</small>",
|
||||||
|
"Full Frame Detection": "পুরো ফ্রেম সনাক্তকরণ",
|
||||||
|
"Fullscreen": "পর্দা জুড়ে প্রদর্শন",
|
||||||
|
"Greater Than": "তার চেয়ে অনেক বেশী",
|
||||||
|
"Greater Than or Equal to": "তার চেয়ে অনেক বেশী বা সমান",
|
||||||
|
"Group Key": "গ্রুপ কী",
|
||||||
|
"Group Name": "গ্রুপের নাম",
|
||||||
|
"Grouping": "জোট ",
|
||||||
|
"H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ",
|
||||||
|
"HLS (.m3u8)": "HLS (.m3u8)",
|
||||||
|
"HLS (includes Audio)": "HLS (অন্তর্ভুক্ত অডিও)",
|
||||||
|
"HLS Audio Encoder": "HLS অডিও এনকোডার",
|
||||||
|
"HLS List Size": "HLS তালিকা আকার",
|
||||||
|
"HLS Preset": "HLS প্রিসেট",
|
||||||
|
"HLS Segment Length": "HLS সেগমেন্ট দৈর্ঘ্য <small>সেকেন্ডের মধ্যে</small>",
|
||||||
|
"HLS Video Encoder": "HLS ভিডিও এনকোডার",
|
||||||
|
"HTTP": "HTTP",
|
||||||
|
"HTTPS": "HTTPS",
|
||||||
|
"Height": "উচ্চতা",
|
||||||
|
"Help": "সাহায্য",
|
||||||
|
"Hide List": "আড়াল তালিকা",
|
||||||
|
"Hide Notes": "আড়াল নোট",
|
||||||
|
"Host": "হোস্ট",
|
||||||
|
"Hotswap Modes (Watch-Only)": "Hotswap মোড (দেখুন শুধুমাত্র)",
|
||||||
|
"How to Record": "রেকর্ড কিভাবে",
|
||||||
|
"IP Address": "আইপি ঠিকানা",
|
||||||
|
"Identity": "পরিচয়",
|
||||||
|
"IdentityText1": "কিভাবে এই সিস্টেম সনাক্ত করা হবে এই জন্য তথ্য প্রবাহ. আপনি পরিবর্তন করতে পারবেন না, <b>মনিটর আইডি</b> আছে একবার আপনি চাপা সংরক্ষণ করুন. যদি আপনি চান আপনি করতে পারেন <b>নিরীক্ষণ, আইডি</b> , আরো মানুষের পাঠযোগ্য আপনি অবিরত আগে.",
|
||||||
|
"IdentityText2": "আপনি প্রতিলিপি করতে পারেন একটি মনিটর পরিবর্তন করে <b>মনিটর আইডি</b> , তারপর টিপে সংরক্ষণ করুন. আপনি <b>না</b> ব্যবহার করে আইডি এর একটি মনিটর যে ইতিমধ্যেই বিদ্যমান, অথবা এটি সংরক্ষণ করতে হবে যে ওভার মনিটর এর ডাটাবেস তথ্য.",
|
||||||
|
"Idle": "অলস",
|
||||||
|
"Image Height": "ইমেজ উচ্চতা",
|
||||||
|
"Image Location": "ইমেজ অবস্থান <small>পরম পাথ অথবা ফাঁকা ছেড়ে দিন ব্যবহার করতে গ্লোবাল</small>",
|
||||||
|
"Image Position": "ইমেজ অবস্থান",
|
||||||
|
"Image Width": "চিত্র প্রস্থ",
|
||||||
|
"Import": "আমদানি",
|
||||||
|
"Import Monitor Configuration": "আমদানি মনিটর কনফিগারেশন",
|
||||||
|
"ImportMonitorConfigurationText": "এই কাজ হবে overrwrite কোন পরিবর্তন বর্তমানে সংরক্ষিত নয়. আমদানি পরিবর্তন হবে শুধুমাত্র প্রয়োগ করা হলে, আপনি প্রেস <b>সংরক্ষণ করুন</b>.",
|
||||||
|
"In": "এ",
|
||||||
|
"Incorrect Settings Chosen": "ভুল সেটিংস চয়ন",
|
||||||
|
"Indifference": "অযত্ন",
|
||||||
|
"Input": "ইনপুট",
|
||||||
|
"Input Flags": "ইনপুট পতাকা",
|
||||||
|
"Input Type": "ইনপুট টাইপ",
|
||||||
|
"InputText1": "এই অধ্যায় বলে Shinobi গ্রাস কিভাবে একটি স্ট্রিম. অনুকূল কর্ম সঞ্চালনের জন্য টিউন করার চেষ্টা করুন, আপনার ক্যামেরা এর অভ্যন্তরীণ সেটিংস. এটি নিম্নলিখিত অপশন এবং তাদের সেট হিসাবে দেখানো হয়েছে. খুঁজে বের করতে আপনার ক্যামেরা ব্যবহার করতে পারেন <b>বিল্ট ইন ONVIF স্ক্যানার</b> এর Shinobi. কিছু ONVIF ক্যামেরা ব্যবহারের প্রয়োজন একটি ম্যানেজমেন্ট টুল পরিবর্তন করতে তাদের অভ্যন্তরীণ সেটিংস. যদি আপনি না করতে পারেন, এটি আপনার ক্যামেরা আপনি চেষ্টা করতে পারেন, <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">ONVIF ডিভাইস ম্যানেজার উইন্ডোজের জন্য</a>.",
|
||||||
|
"InputText2": "<ul><li><b>ফ্রেমরেট (FPS) :</b> উচ্চ : 10 - 15 FPS কম : 2-5 FPS</li><li><b>আমি-ফ্রেম ব্যবধান :</b> 80</li><li><b>বিট রেট টাইপ :</b> CBR (ধ্রুবক বিট রেট)</li><li><b>বিট রেট :</b> মধ্যে 256kbps - 500kbps</li></ul>",
|
||||||
|
"InputText3": "যদি আপনি সাহায্য প্রয়োজন figuring আউট কি ইনপুট টাইপ আপনার ক্যামেরা, হয়, আপনি গ্রহণ করতে পারেন, একটি বর্ণন মধ্যে <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">ক্যামেরা Url গুলি তালিকা</a> উপর Shinobi ওয়েবসাইট.",
|
||||||
|
"Invalid JSON": "অবৈধ JSON",
|
||||||
|
"InvalidJSONText": "দয়া করে নিশ্চিত করুন, এটি একটি বৈধ JSON স্ট্রিং জন্য Shinobi মনিটর কনফিগারেশন.",
|
||||||
|
"JPEG": "কোন JPEG",
|
||||||
|
"JPEG (Auto Enables JPEG API)": "কোন JPEG (অটো সক্ষম হবেন, কোন JPEG, এপিআই)",
|
||||||
|
"JPEG API": "কোন JPEG এপিআই <small>স্ন্যাপশট (cgi-bin)</small>",
|
||||||
|
"JPEG Error": "কোন JPEG ত্রুটি",
|
||||||
|
"JPEG Mode": "কোন JPEG মোড",
|
||||||
|
"JPEGErrorText": "সেখানে ছিল একটি ইস্যু পেয়ে তথ্য আপনার ক্যামেরা থেকে.",
|
||||||
|
"Leave blank for random.": "ফাঁকা ছেড়ে দিন জন্য র্যান্ডম.",
|
||||||
|
"Left": "বাম <small>URL ঠিকানা</small>",
|
||||||
|
"Left Stop": "বাম বন্ধ <small>URL ঠিকানা</small>",
|
||||||
|
"Less Than": "কম",
|
||||||
|
"Less Than or Equal to": "কম বা সমান",
|
||||||
|
"Like": "মত",
|
||||||
|
"Lisence Plate Detector": "অনুজ্ঞাপত্র প্লেট আবিষ্কারক",
|
||||||
|
"List Toggle": "তালিকা টগল",
|
||||||
|
"Live Stream Toggle": "লাইভ স্ট্রিম টগল",
|
||||||
|
"Live View": "লাইভ দেখুন",
|
||||||
|
"Local": "স্থানীয়",
|
||||||
|
"Log Level": "লগ স্তর",
|
||||||
|
"Log Signal Event": "লগ সংকেত ইভেন্ট <small>ক্লায়েন্ট প্রান্তের শুধুমাত্র</small>",
|
||||||
|
"Logging": "লগিং",
|
||||||
|
"Login": "লগইন",
|
||||||
|
"Logout": "লগ আউট",
|
||||||
|
"Logs": "লগ",
|
||||||
|
"MB": "MB",
|
||||||
|
"MJPEG": "MJPEG",
|
||||||
|
"MP4 (copy, libx264, libx265)": "আছে MP4 (কপি, libx264, libx265)",
|
||||||
|
"MPEG-4 (.mp4 / .ts)": "MPEG-4 (.আছে mp4 / .ts)",
|
||||||
|
"MailError": "মেইল ত্রুটি : যায়নি পাঠাতে ইমেইল চেক conf.json. কুঁদন কোন বৈশিষ্ট্য উপর নির্ভর মেইলিং.",
|
||||||
|
"Matches": "ম্যাচ",
|
||||||
|
"Max Storage Amount": "সর্বোচ্চ স্টোরেজ পরিমাণ <small>মেগাবাইটের মধ্যে</small>",
|
||||||
|
"Mode": "মোড",
|
||||||
|
"Monitor": "মনিটর",
|
||||||
|
"Monitor Added by user": "মনিটর যোগ করা হয়েছে ব্যবহারকারী দ্বারা.",
|
||||||
|
"Monitor Capture Rate": "মনিটর ক্যাপচার হার <small>(FPS যে)</small>",
|
||||||
|
"Monitor Groups": "মনিটর গ্রুপ",
|
||||||
|
"Monitor ID": "মনিটর আইডি",
|
||||||
|
"Monitor Idling": "মনিটর আলসে",
|
||||||
|
"Monitor Name": "মনিটর নাম",
|
||||||
|
"Monitor Settings": "মনিটর সেটিংস",
|
||||||
|
"Monitor Stopped": "মনিটর বন্ধ",
|
||||||
|
"Monitor Updated by user": "মনিটর দ্বারা আপডেট ব্যবহারকারী.",
|
||||||
|
"Monitor mode changed": "মনিটর মোড পরিবর্তন",
|
||||||
|
"Monitor mode is already": "মনিটর মোড ইতিমধ্যে",
|
||||||
|
"Monitor or Key does not exist.": "মনিটর বা কী নেই.",
|
||||||
|
"MonitorIdlingText": "মনিটর অধিবেশন করার নির্দেশ দেয়া হয়েছে অলস.",
|
||||||
|
"MonitorStoppedText": "মনিটর অধিবেশন বন্ধ করার নির্দেশ দেয়া হয়েছে.",
|
||||||
|
"Monitors": "মনিটর",
|
||||||
|
"Monitors per row": "মনিটর প্রতি সারির <small>জন্য পূর্ণাঙ্গতা</small>",
|
||||||
|
"Montage": "পূর্ণাঙ্গতা",
|
||||||
|
"Motion GUI": "গতি গ্রাফিক্যাল ইউজার ইন্টারফেস",
|
||||||
|
"Motion Meter": "গতি মিটার",
|
||||||
|
"Name": "নাম",
|
||||||
|
"No": "কোন",
|
||||||
|
"No Audio": "কোন অডিও",
|
||||||
|
"No Data": "কোন তথ্য",
|
||||||
|
"No Events found for this video": "কোন ঘটনা পাওয়া জন্য এই ভিডিও",
|
||||||
|
"No Group with this key exists": "কোন গ্রুপ এই কী দিয়ে বিদ্যমান",
|
||||||
|
"No Monitor Found, Ignoring Request": "কোন মনিটর পাওয়া উপেক্ষা অনুরোধ",
|
||||||
|
"No Rotation": "কোন ঘূর্ণন",
|
||||||
|
"No such file": "কোন ধরনের ফাইল",
|
||||||
|
"NoMotionEmailText1": "কোন গতি জন্য",
|
||||||
|
"NoMotionEmailText2": "সেখানে এখন পর্যন্ত হয়েছে, কোন গতি সনাক্ত ক্যামেরা জন্য",
|
||||||
|
"NoVideosFoundForDateRange": "কোন ভিডিও পাওয়া যায়, এই তারিখ পরিসীমা. চেষ্টা সেটিং আরম্ভের তারিখ আরও ফিরে.",
|
||||||
|
"Not Authorized": "অনুমোদিত না",
|
||||||
|
"Not Connected": "সংযুক্ত নয়",
|
||||||
|
"Not Equal to": "সমান না",
|
||||||
|
"Not In": "না",
|
||||||
|
"Not Matches": "না, ম্যাচ",
|
||||||
|
"Not Permitted": "অনুমতি না",
|
||||||
|
"Not an Administrator Account": "না, একজন প্রশাসক অ্যাকাউন্ট",
|
||||||
|
"NotAuthorizedText1": "না, কঠিন জমা init কমান্ড দিয়ে \"প্রমাণীকরণ\",\"কে\" এবং \"uid\"",
|
||||||
|
"Notes": "নোট",
|
||||||
|
"NotesPlacholder": "মন্তব্য, আপনি ছেড়ে দিতে চান জন্য এই ক্যামেরা সেটিংস.",
|
||||||
|
"Number of Days to keep": "দিনের সংখ্যা রাখা",
|
||||||
|
"ONVIF": "ONVIF",
|
||||||
|
"ONVIF Scanner": "ONVIF স্ক্যানার",
|
||||||
|
"ONVIFnote": "আবিষ্কার ONVIF ডিভাইসের উপর নেটওয়ার্কের বাইরে আপনার নিজের অথবা এটি ফাঁকা ছেড়ে স্ক্যান করার জন্য আপনার বর্তমান নেটওয়ার্ক. <br>ব্যবহারকারীর নাম এবং পাসওয়ার্ড ফাঁকা রাখা যেতে পারে.",
|
||||||
|
"OpenCV Cascades": "OpenCV ক্যাসকেড",
|
||||||
|
"Order Streams": "যাতে স্ট্রিম",
|
||||||
|
"Output Method": "আউটপুট পদ্ধতি",
|
||||||
|
"Password": "পাসওয়ার্ড",
|
||||||
|
"Password Again": "আবার পাসওয়ার্ড",
|
||||||
|
"Passwords don't match": "পাসওয়ার্ড মেলে না",
|
||||||
|
"Paste JSON here.": "পেস্ট JSON আছেন.",
|
||||||
|
"Path": "পথ",
|
||||||
|
"Permissions": "অনুমতি",
|
||||||
|
"Points": "পয়েন্ট <small>যোগ করার সময় পয়েন্ট উপর ক্লিক করুন ধারে বহুভুজ.</small>",
|
||||||
|
"Port": "পোর্ট",
|
||||||
|
"Position X": "অবস্থান X",
|
||||||
|
"Position Y": "অবস্থান Y",
|
||||||
|
"Power Video Viewer": "পাওয়ার ভিডিও ভিউয়ার",
|
||||||
|
"Power Viewer": "ক্ষমতা ভিউয়ার",
|
||||||
|
"Preferences": "পছন্দ",
|
||||||
|
"Preset": "প্রিসেট",
|
||||||
|
"Probe Size": "প্রোব ফাইলের আকার",
|
||||||
|
"Process Crashed for Monitor": "প্রক্রিয়া ক্র্যাশ জন্য মনিটর",
|
||||||
|
"Process Unexpected Exit": "প্রক্রিয়া অপ্রত্যাশিত প্রস্থান",
|
||||||
|
"Profile": "প্রোফাইল",
|
||||||
|
"Quality": "মান <small>1 উচ্চ, 23 হয় কম</small>",
|
||||||
|
"Query": "ক্যোয়ারী",
|
||||||
|
"RAM": "র্যাম",
|
||||||
|
"RTSP": "RTSP",
|
||||||
|
"RTSP Transport": "RTSP পরিবহন",
|
||||||
|
"Range or Single": "পরিসীমা বা একক",
|
||||||
|
"Rate": "হার <small>(FPS যে)</small>",
|
||||||
|
"Record": "রেকর্ড",
|
||||||
|
"Record File Type": "রেকর্ড ফাইল টাইপ",
|
||||||
|
"Record Height": "রেকর্ড উচ্চতা",
|
||||||
|
"Record Video Filter": "রেকর্ড ভিডিও ফিল্টার",
|
||||||
|
"Record Width": "রেকর্ড প্রস্থ",
|
||||||
|
"Recording": "রেকর্ডিং",
|
||||||
|
"Recording Flags": "রেকর্ডিং পতাকা",
|
||||||
|
"Recording Segment Interval": "রেকর্ডিং সেগমেন্ট ব্যবধান <small>মিনিটের মধ্যে</small>",
|
||||||
|
"Recording Timeout": "রেকর্ডিং সময়সীমার <small>মধ্যে মিনিট</small>",
|
||||||
|
"Recording Timestamp": "রেকর্ডিং টাইমস্ট্যাম্প",
|
||||||
|
"Recording Watermark": "রেকর্ডিং জলছাপ",
|
||||||
|
"RecordingText": "এটা বাঞ্ছনীয় যে আপনি সেট <b>রেকর্ড ফাইল টাইপ</b> করতে <b class=\"h_t_input h_t_jpeg h_t_socket\">WebM</b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">, আছে MP4</b> , এবং <b>ভিডিও কোডেক</b> করতে <b class=\"h_t_input h_t_jpeg h_t_socket\">libvpx</b><b class=\"h_t_input h_t_h264 h_t_hls h_t_mp4\">কপি বা </b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">libx264</b> , কারণ আপনার <b>ইনপুট টাইপ</b> সেট করা হয় <b class=\"h_t_text\"></b>.",
|
||||||
|
"Refresh List of Cascades": "রিফ্রেশ তালিকা ক্যাসকেড",
|
||||||
|
"Region Editor": "অঞ্চল সম্পাদক",
|
||||||
|
"Region Name": "অঞ্চলের নাম",
|
||||||
|
"RegionNote": "পয়েন্ট হয় শুধুমাত্র সংরক্ষিত যখন আপনি টিপুন <b>সংরক্ষণ</b> করে <b>মনিটর সেটিংস</b> উইন্ডো.",
|
||||||
|
"Regions": "অঞ্চল",
|
||||||
|
"Remember Me": "আমাকে মনে রেখো",
|
||||||
|
"Reset Timer": "রিসেট টাইমার",
|
||||||
|
"Restarting Process": "পুনরায় আরম্ভ করার প্রক্রিয়া",
|
||||||
|
"Retry Connection": "পুনরায় সংযোগ <small>সংখ্যা বার অনুমোদিত করতে ব্যর্থ</small>",
|
||||||
|
"Retrying...": "Retrying...",
|
||||||
|
"Right": "সঠিক <small>URL ঠিকানা</small>",
|
||||||
|
"Right Stop": "ডান বন্ধ <small>URL ঠিকানা</small>",
|
||||||
|
"Rotate": "ঘোরান",
|
||||||
|
"Save": "সংরক্ষণ করুন",
|
||||||
|
"Save Directory": "ডিরেক্টরি সংরক্ষণ করুন",
|
||||||
|
"Save Events to SQL": "সংরক্ষণ ঘটনা এসকিউএল",
|
||||||
|
"Save Log in SQL": "সংরক্ষণ লগ ইন এসকিউএল <small>এই পূরণ করতে পারেন, দ্রুত.</small>",
|
||||||
|
"Save as": "হিসাবে সংরক্ষণ করুন",
|
||||||
|
"Saved Filters": "সংরক্ষিত ফিল্টার",
|
||||||
|
"Scan Settings": "স্ক্যান সেটিংস",
|
||||||
|
"Search": "অনুসন্ধান",
|
||||||
|
"Send Frames": "পাঠাতে ফ্রেম <small>ধাক্কা ফ্রেম বিশ্লেষণ করা</small>",
|
||||||
|
"Separate with commas, no spaces": "পৃথক কমা দিয়ে কোন স্পেস",
|
||||||
|
"Set to Watch Only": "সেট দেখতে শুধুমাত্র",
|
||||||
|
"Settings": "সেটিংস",
|
||||||
|
"Settings Changed": "সেটিংস পরিবর্তন",
|
||||||
|
"SettingsChangedText": "আপনার সেটিংস সংরক্ষণ করা হয়েছে এবং প্রয়োগ.",
|
||||||
|
"Shinobi": "Shinobi",
|
||||||
|
"Shinobi Streamer": "Shinobi উজ্জ্বল আলোকরশ্মি",
|
||||||
|
"Show Logs": "শো লগ",
|
||||||
|
"Silent": "নীরব",
|
||||||
|
"Simple": "সহজ",
|
||||||
|
"Size (mb)": "মাপ (মেগাবাইট)",
|
||||||
|
"Snapshot": "স্ন্যাপশট",
|
||||||
|
"Snapshot Flags": "স্ন্যাপশট পতাকা",
|
||||||
|
"Snapshots": "স্ন্যাপশট",
|
||||||
|
"Sort By": "দ্বারা বাছাই",
|
||||||
|
"Start": "শুরু",
|
||||||
|
"Start Recording": "রেকর্ডিং শুরু",
|
||||||
|
"Start Time": "সময় শুরু",
|
||||||
|
"Started": "শুরু",
|
||||||
|
"Status Indicator": "অবস্থা সূচক",
|
||||||
|
"Stop URL": "বন্ধ URL টি",
|
||||||
|
"Stream": "স্ট্রিম",
|
||||||
|
"Stream Flags": "স্ট্রিম পতাকা",
|
||||||
|
"Stream Timestamp": "স্ট্রিম টাইমস্ট্যাম্প",
|
||||||
|
"Stream Type": "প্রবাহ টাইপ,",
|
||||||
|
"Stream Watermark": "স্ট্রিম জলছাপ",
|
||||||
|
"Stream to YouTube": "স্ট্রিম YouTube",
|
||||||
|
"Stream to YouTube Flags": "স্ট্রিম করতে ইউটিউব পতাকা",
|
||||||
|
"StreamText": "<p>এই বিভাগে নামকরণ করা হবে এই প্রাথমিক স্ট্রিম আউট পদ্ধতি এবং এটি এর সেটিংস. এই স্ট্রিম প্রদর্শন করা হবে ড্যাশবোর্ড. আপনি ব্যবহার করতে পছন্দ HLS, কোন JPEG, বা MJPEG, তারপর আপনি গ্রাস করতে পারেন স্ট্রিম মাধ্যমে অন্যান্য প্রোগ্রাম.</p><p class=\"h_st_input h_st_jpeg\">ব্যবহার কোন JPEG স্ট্রিম মূলত বন্ধ করিয়া প্রাথমিক স্ট্রিম এবং ব্যবহার স্ন্যাপশট বিন পেতে ফ্রেম.</p>",
|
||||||
|
"Streamer": "উজ্জ্বল আলোকরশ্মি",
|
||||||
|
"Streams": "স্ট্রিম",
|
||||||
|
"Superuser": "Superuser",
|
||||||
|
"Switch on for Still Image": "সুইচ জন্য এখনও ইমেজ",
|
||||||
|
"TCP": "TCP",
|
||||||
|
"Text Box Color": "টেক্সট বক্স রঙ",
|
||||||
|
"Text Color": "টেক্সট রঙ",
|
||||||
|
"Time-lapse": "সময় ভ্রষ্টতা",
|
||||||
|
"Time-lapse Tool": "সময় ভ্রষ্টতা টুল",
|
||||||
|
"Timeout": "সময়সীমার",
|
||||||
|
"Timeout Reset on Next Motion": "সময়সীমার রিসেট পরবর্তী গতি",
|
||||||
|
"Toggle Sidebar": "টগল পার্শ্বদন্ডে",
|
||||||
|
"Top Left": "উপরের বাম",
|
||||||
|
"Top Right": "উপরের ডান",
|
||||||
|
"Trigger Record": "ট্রিগার রেকর্ড",
|
||||||
|
"Trigger Successful": "ট্রিগার সফল",
|
||||||
|
"UDP": "এর ফলে UDP",
|
||||||
|
"URL": "URL টি",
|
||||||
|
"URL Stop Timeout": "URL বন্ধ সময়সীমার <small>চালানো বন্ধ URL পরে এক্স মিলিসেকেন্ড</small>",
|
||||||
|
"US": "আমাদের",
|
||||||
|
"Unable to Launch": "আরম্ভ করতে অক্ষম",
|
||||||
|
"UnabletoLaunchText": "সংরক্ষণ করুন, নতুন মনিটর প্রথম. তারপর চেষ্টা করতে আরম্ভ অঞ্চলের সম্পাদক.",
|
||||||
|
"Up": "আপ <small>URL ঠিকানা</small>",
|
||||||
|
"Up Stop": "আপ বন্ধ <small>URL ঠিকানা</small>",
|
||||||
|
"Username": "ব্যবহারকারীর নাম",
|
||||||
|
"Value": "মান",
|
||||||
|
"Video": "ভিডিও",
|
||||||
|
"Video Codec": "ভিডিও কোডেক",
|
||||||
|
"Video Filter": "ভিডিও ফিল্টার",
|
||||||
|
"Video Finished": "ভিডিও সমাপ্ত",
|
||||||
|
"Video Length (minutes) and Motion Count per video": "ভিডিও দৈর্ঘ্য (মিনিট) এবং গতি গণনা প্রতি ভিডিও",
|
||||||
|
"Video Record Rate": "ভিডিও রেকর্ড হার <small>(FPS যে)</small>",
|
||||||
|
"Video Status": "ভিডিও অবস্থা",
|
||||||
|
"Video and Time Span (Minutes)": "ভিডিও এবং সময় স্প্যান (মিনিট)",
|
||||||
|
"Videos": "ভিডিও",
|
||||||
|
"Videos List": "ভিডিও তালিকা",
|
||||||
|
"Watch": "ওয়াচ",
|
||||||
|
"Watch Only": "ওয়াচ শুধুমাত্র",
|
||||||
|
"WebDAV": "অম্রো",
|
||||||
|
"WebM (libvpx)": "WebM (libvpx)",
|
||||||
|
"Webdav Error": "অম্রো ত্রুটি",
|
||||||
|
"WebdavErrorText": "উদ্ধার করতে পারে না. আপনি কি করতে ক্যামেরা ফোল্ডার ভিতরে আপনার নির্বাচিত ডিরেক্টরি সংরক্ষণ করুন?",
|
||||||
|
"Webhook": "Webhook",
|
||||||
|
"Webhook URL": "Webhook URL টি",
|
||||||
|
"Width": "প্রস্থ",
|
||||||
|
"Yes": "হ্যাঁ",
|
||||||
|
"Zoom In": "জুম ইন <small>URL ঠিকানা</small>",
|
||||||
|
"Zoom In Stop": "জুম বন্ধ <small>URL ঠিকানা</small>",
|
||||||
|
"Zoom Out": "জুম আউট <small>URL ঠিকানা</small>",
|
||||||
|
"Zoom Out Stop": "জুম আউট বন্ধ <small>URL ঠিকানা</small>",
|
||||||
|
"a day": "একটি দিন",
|
||||||
|
"a few seconds": "কয়েক সেকেন্ড",
|
||||||
|
"a minute": "একটি মিনিট",
|
||||||
|
"a month": "একটি মাস",
|
||||||
|
"a year": "একটি বছর",
|
||||||
|
"aac": "এএসি",
|
||||||
|
"aac (Default)": "এএসি (ডিফল্ট)",
|
||||||
|
"ac3": "ac3",
|
||||||
|
"ago": "আগে",
|
||||||
|
"an hour": "একটি ঘন্টা",
|
||||||
|
"blankPassword": "ছেড়ে ফাঁকা রাখা একই পাসওয়ার্ড",
|
||||||
|
"calendar": "ক্যালেন্ডার",
|
||||||
|
"clientStreamFailedattemptingReconnect": "ক্লায়েন্ট সাইড ctream পরীক্ষা ব্যর্থ প্রয়াস পুনরায় সংযোগ স্থাপন.",
|
||||||
|
"confirmDeleteFilter": "আপনি চাই প্রতি মুছে ফেলা এই ফিল্টার? আপনি পুনরুদ্ধার করা সম্ভব না, এটা.",
|
||||||
|
"copy": "কপি",
|
||||||
|
"days": "দিন",
|
||||||
|
"dropBoxSuccess": "সাফল্য! ফাইল সংরক্ষণ করার জন্য আপনার ড্রপবক্স.",
|
||||||
|
"for Global Access": "গ্লোবাল এক্সেস",
|
||||||
|
"hours": "ঘন্টা",
|
||||||
|
"in": "এ",
|
||||||
|
"libmp3lame": "libmp3lame",
|
||||||
|
"libopus": "libopus",
|
||||||
|
"libvorbis (Default)": "libvorbis (ডিফল্ট)",
|
||||||
|
"libvpx (Default)": "libvpx (ডিফল্ট)",
|
||||||
|
"libvpx-vp9": "libvpx-vp9",
|
||||||
|
"libx264": "libx264",
|
||||||
|
"libx264 (Default)": "libx264 (ডিফল্ট)",
|
||||||
|
"libx265": "libx265",
|
||||||
|
"minutes": "মিনিট",
|
||||||
|
"modifyVideoText1": "পদ্ধতি বিদ্যমান নেই. পরীক্ষা নিশ্চিত করুন যে আপনি সর্বশেষ মান URL টি নয়, ফাঁকা.",
|
||||||
|
"monitorEditFailedMaxReached": "আপনার অ্যাকাউন্ট পৌঁছেছে সর্বোচ্চ সংখ্যা, যে ক্যামেরা তৈরি করা যেতে পারে. কথা বলতে একজন প্রশাসক যদি আপনি চান এই পরিবর্তন.",
|
||||||
|
"monitorEditText1": "অবৈধ তথ্য পরীক্ষা করে দেখুন, এই একটি বৈধ আমদানি স্ট্রিং.",
|
||||||
|
"monitorEditText2": "অবৈধ বিবরণ স্ট্রিং. দেখতে পরীক্ষা করুন, এটি একটি JSON স্ট্রিং এবং না একটি নিয়মিত বস্তুর অতিক্রান্ত হচ্ছে.",
|
||||||
|
"monitorGetText1": "অসম্পূর্ণ অনুরোধ অপসারণ, গত স্ল্যাশ মধ্যে URL বা করা গ্রহণযোগ্য মান.",
|
||||||
|
"months": "মাস",
|
||||||
|
"noSpecialCharacters": "কোন স্পেস বা বিশেষ অক্ষর.",
|
||||||
|
"on": "উপর",
|
||||||
|
"on Error": "উপর ত্রুটি",
|
||||||
|
"startUpText0": "আকার জন্য পরীক্ষা করে দেখুন ভিডিও",
|
||||||
|
"startUpText1": "শেষে আকার জন্য পরীক্ষা করে দেখুন ভিডিও",
|
||||||
|
"startUpText2": "সব ব্যবহারকারীদের চেক অপেক্ষা করুন, বন্ধ করতে, খোলা ফাইল এবং ফাইল মুছে ফেলুন উপর ব্যবহারকারী সীমা",
|
||||||
|
"startUpText3": "অপেক্ষা করতে দিতে অসমাপ্ত ভিডিও পরীক্ষা কিছু সময়. 3 সেকেন্ড.",
|
||||||
|
"startUpText4": "শুরু, সব মনিটর সেট দেখতে এবং রেকর্ড",
|
||||||
|
"startUpText5": "Shinobi প্রস্তুত হয়.",
|
||||||
|
"superAdminText": "\"সুপার.json\" বিদ্যমান নয়. দয়া করে নামান্তর \"সুপার.নমুনা.json\", \"সুপার.json\".",
|
||||||
|
"superAdminTitle": "Shinobi : সুপার অ্যাডমিন",
|
||||||
|
"total": "মোট",
|
||||||
|
"updateKeyText1": "\"updateKey\" থেকে অনুপস্থিত, \"conf.json\", আপডেট করতে পারবেন না এই ভাবে যতক্ষণ না আপনি এটি যোগ করুন.",
|
||||||
|
"updateKeyText2": "\"updateKey\" ভুল হয়.",
|
||||||
|
"years": "বছর"
|
||||||
|
}
|
|
@ -0,0 +1,497 @@
|
||||||
|
{
|
||||||
|
"\"No Motion\" Detector": "Detektor für \"keine Bewegung\"",
|
||||||
|
"# of Allow MJPEG Clients": "Max. Anz. von MJPEG-Clients <small>0 = unbeschränkt</small>",
|
||||||
|
"180 Degrees": "180 Grad",
|
||||||
|
"2-Factor Authentication": "2-Faktor-Authentifizierung",
|
||||||
|
"90 Clockwise": "90° im Uhrzeigersinn",
|
||||||
|
"90 Clockwise and Vertical Flip": "90° im Uhrzeigersinn drehen und vertikal spiegeln",
|
||||||
|
"90 Counter Clockwise and Vertical Flip (default)": "90° entgegen dem Uhrzeigersinn drehen und vertikal spiegeln (Standard)",
|
||||||
|
"API": "API",
|
||||||
|
"API Key Added": "API-Schlüssel hinzugefügt",
|
||||||
|
"API Key Deleted": "API-Schlüssel gelöscht",
|
||||||
|
"API Keys": "API-Schlüssel",
|
||||||
|
"APIKeyAddedText": "Sie können diesen API-Schlüssel nun verwenden.",
|
||||||
|
"APIKeyDeletedText": "Der API-Schlüssel wurde gelöscht. Er wird nicht mehr funktionieren.",
|
||||||
|
"ASC": "Auf",
|
||||||
|
"Account Info": "Account-Info",
|
||||||
|
"AccountEditText1": "Ändern nicht möglich. Bitte die Seite neu laden, falls das Problem weiterhin besteht.",
|
||||||
|
"Accounts": "Konten",
|
||||||
|
"Action for Selected": "Aktion für Ausgewählte",
|
||||||
|
"Add": "Hinzufügen",
|
||||||
|
"Add Monitor": "Monitor Hinzufügen",
|
||||||
|
"Add New": "Neu hinzufügen",
|
||||||
|
"Admin": "Admin",
|
||||||
|
"Advanced": "Experten",
|
||||||
|
"Again": "Erneut",
|
||||||
|
"All Monitors": "Alle Monitore",
|
||||||
|
"All Monitors and Privileges": "Alle Monitore und Privilegien",
|
||||||
|
"All Warnings": "Alle Warnungen",
|
||||||
|
"Allow Next Command": "Min. Zeitspanne zwischen zwei Befehlen<small>in Minuten</small>",
|
||||||
|
"Allow Next Email": "Min. Zeitspanne zwischen zwei E-Mails<small>in Minuten</small>",
|
||||||
|
"Allow Next Trigger": "Min. Zeitspanne zwischen zwei Triggern<small>in Millisekunden</small>",
|
||||||
|
"Allowed IPs": "Erlaubte IPs",
|
||||||
|
"Analyzation Duration": "Analyse-Dauer",
|
||||||
|
"Archive": "Archiv",
|
||||||
|
"Audio Codec": "Audio-Codec",
|
||||||
|
"Authenticate": "Authentifizieren",
|
||||||
|
"Auto": "Auto",
|
||||||
|
"Autosave": "Autom. Speichern",
|
||||||
|
"Base64 over Websocket": "Base64 über Websocket",
|
||||||
|
"Bottom Left": "Unten links",
|
||||||
|
"Bottom Right": "Unten rechts",
|
||||||
|
"Browser Console Log": "Browser-Konsole",
|
||||||
|
"CPU": "CPU",
|
||||||
|
"CPU indicator will not work. Continuing...": "Die CPU-Anzeige funktioniert nicht. Weiter...",
|
||||||
|
"CSS": "CSS - <small>Definiert eigene Styles im Dashboard</small>",
|
||||||
|
"Calendar": "Kalender",
|
||||||
|
"Camera Password": "Kamera-Passwort",
|
||||||
|
"Camera Username": "Kamera-Benutzername",
|
||||||
|
"Camera is not recording": "Die Kamera nimmt nicht auf.",
|
||||||
|
"CameraNotRecordingText": "Die Einstellungen sind möglicherweise nicht kompatibel. Bitte die Encoder-Einstellung überprüfen.",
|
||||||
|
"Can Control Monitors": "Darf Monitore steuern",
|
||||||
|
"Can Delete Videos": "Darf Videos löschen",
|
||||||
|
"Can Delete Videos and Events": "Darf Videos und Events löschen",
|
||||||
|
"Can Edit Monitor": "Darf Monitor-Einstellungen bearbeiten",
|
||||||
|
"Can Get Logs": "Darf die Logs sehen",
|
||||||
|
"Can Get Monitors": "Darf Monitore auflisten",
|
||||||
|
"Can View Monitor": "Darf Monitore sehen",
|
||||||
|
"Can View Snapshots": "Darf Snapshots erstellen/sehen",
|
||||||
|
"Can View Streams": "Darf Streams sehen",
|
||||||
|
"Can View Videos": "Darf Videos anschauen",
|
||||||
|
"Can View Videos and Events": "Darf Videos und Events ansehen",
|
||||||
|
"Can't Connect": "Konnte nicht Verbinden.",
|
||||||
|
"Center": "Mitte <small>- URL-Adresse</small>",
|
||||||
|
"Chat on Discord": "Chat auf Discord",
|
||||||
|
"Check": "Überprüfen",
|
||||||
|
"Check Signal Interval": "Signal-Überprüfungsintervall <small>in Minuten</small>",
|
||||||
|
"Check for Motion First": "Bewegungserkennung zuerst",
|
||||||
|
"Close": "Schließen",
|
||||||
|
"Closed": "Geschlossen",
|
||||||
|
"Command": "Befehl",
|
||||||
|
"Command on Trigger": "Befehl beim Trigger",
|
||||||
|
"Complete Stream URL": "Komplette Stream-URL",
|
||||||
|
"Confirm": "Bestätigen",
|
||||||
|
"Connected": "Verbunden",
|
||||||
|
"Connection Type": "Verbindungstyp",
|
||||||
|
"Control": "Steuerung",
|
||||||
|
"Control Error": "Steuerungsfehler",
|
||||||
|
"ControlErrorText1": "Die Steuerung ist nicht aktiviert",
|
||||||
|
"Controllable": "Steuerbar",
|
||||||
|
"Country of Plates": "Kennzeichen-Land",
|
||||||
|
"Counts of Motion": "Bewegungsschwelle",
|
||||||
|
"Current": "Aktuell",
|
||||||
|
"Currently viewing": "Anzahl Beobachter",
|
||||||
|
"Custom": "Benutzerdefiniert",
|
||||||
|
"Custom Base URL": "Eigene Basis-URL <small>leer Lassen, um Host-URL zu verwenden</small>",
|
||||||
|
"DB Lost.. Retrying..": "Datenbank-Verbindung verloren... Erneuter Versuch...",
|
||||||
|
"DESC": "Ab",
|
||||||
|
"Dashboard": "Dashboard",
|
||||||
|
"Dashboard Language": "Dashboard-Sprache",
|
||||||
|
"Dashcam": "Dashcam",
|
||||||
|
"Dashcam (Streamer v2)": "Dashcam (Streamer v2)",
|
||||||
|
"Date Range": "Datumsbereich",
|
||||||
|
"Debug": "Debug",
|
||||||
|
"Default": "Standard",
|
||||||
|
"Delete": "Löschen",
|
||||||
|
"Delete Filter": "Filter Löschen",
|
||||||
|
"Delete Matches": "Lösche Treffer",
|
||||||
|
"Delete Monitor": "Lösche Monitor",
|
||||||
|
"Delete Motionless Video": "Videos ohne Bewegung löschen",
|
||||||
|
"Delete Motionless Videos (Record)": "Videos ohne Bewegung löschen (Aufzeichnung)",
|
||||||
|
"Delete Selected Videos": "Ausgewählte Videos löschen",
|
||||||
|
"Delete Video": "Video Löschen",
|
||||||
|
"Delete selected": "Ausgewählte löschen",
|
||||||
|
"DeleteMonitorText": "Möchten Sie diesen Monitor wirklich löschen? Sie können diese Löschung nicht mehr rückgängig machen. Die Dateien für diese Monitor-ID verbleiben im Dateisystem. Wenn Sie einen Monitor mit der gleichen ID erstellen, werden die Videos und Ereignisse wieder sichtbar.",
|
||||||
|
"DeleteSelectedVideosMsg": "Wollen Sie diese Videos löschen? Sie können diese Löschung nicht mehr rückgängig machen.",
|
||||||
|
"DeleteVideoMsg": "Wollen Sie dieses Video löschen? Sie können diese Löschung nicht mehr rückgängig machen.",
|
||||||
|
"Deleted": "Gelöscht",
|
||||||
|
"Detect Objects": "Erkennung von Objekten <small class=\"\">Siehe unten</small>",
|
||||||
|
"Detector": "Detektor",
|
||||||
|
"Detector Flags": "Detektor-Flags",
|
||||||
|
"Detector Rate": "Detektor-Rate <small>(Bilder pro Sekunde)</small>",
|
||||||
|
"DetectorText": "<p>Die Detektor-Bildgröße sollte auf 640x480 oder kleiner eingestellt werden.. Dies optimiert die Geschwindigkeit beim Auslesen der Bilder.</p>",
|
||||||
|
"Disable Night Vision": "Nachtsicht deaktivieren <small>URL-Adresse</small>",
|
||||||
|
"Disable Nightvision": "Nachtsicht deaktivieren",
|
||||||
|
"Disabled": "Deaktiviert",
|
||||||
|
"Documentation": "Dokumentation",
|
||||||
|
"Don't show this anymore": "Nicht erneut anzeigen",
|
||||||
|
"Double Quote Directory": "Verzeichnisse doppelt quoten <small>Z.B. bei Verzeichnissen mit Leerzeichen sinnvoll, da es bei diesen zu Abstürzen kommen kann.</small>",
|
||||||
|
"Down": "Nach unten <small>URL-Adresse</small>",
|
||||||
|
"Down Stop": "Nach unten-Stopp <small>URL-Adresse</small>",
|
||||||
|
"Download": "Download",
|
||||||
|
"EU": "EU",
|
||||||
|
"Edit": "Bearbeiten",
|
||||||
|
"Email": "E-Mail",
|
||||||
|
"Email Details": "E-Mail-Details",
|
||||||
|
"Email on No Motion": "E-Mail bei \"Keine Bewegung\"",
|
||||||
|
"Email on Trigger": "E-Mail beim Trigger <small>- E-Mails werden an dem Haupt-Account-Inhaber geschickt.</small>",
|
||||||
|
"Enable Night Vision": "Nachtsicht aktivieren - <small>URL-Adresse</small>",
|
||||||
|
"Enable Nightvision": "Nachtsicht aktivieren",
|
||||||
|
"Enabled": "Aktiviert",
|
||||||
|
"End": "Ende",
|
||||||
|
"End Time": "Endzeit",
|
||||||
|
"Ended": "Beendet",
|
||||||
|
"Enlarge": "Vergrößern",
|
||||||
|
"Enter this code to proceed": "Geben Sie bitte diesen Code ein um fortzufahren.",
|
||||||
|
"Equal to": "Gleich",
|
||||||
|
"Error Connecting": "Fehler bei der Verbindung",
|
||||||
|
"Event": "Ereignis",
|
||||||
|
"Event Limit": "Max. Anzahl der Ereignisse",
|
||||||
|
"EventText1": "Ein Bewegungsereignis wurde ausgelöst.",
|
||||||
|
"EventText2": "Konnte die E-Mail nicht versenden, der Zugriff auf die Datei war nicht möglich.",
|
||||||
|
"Events": "Ereignisse",
|
||||||
|
"Example": "Beispiel",
|
||||||
|
"Execute Command": "Befehl ausführen",
|
||||||
|
"Executed": "Ausgeführt",
|
||||||
|
"Export": "Export",
|
||||||
|
"FFmpegCantStart": "Der FFmpeg-Prozess konnte nicht gestartet werden.",
|
||||||
|
"FFmpegCantStartText": "Die Recording-Engine (FFmpeg) für diese Kamera konnte nicht gestartet werden. Möglicherweise ist die Kamera-Konfiguration falsch. Bitte in den Logs nachschauen und diese ggf. in <b>Issues</b> auf Github veröffentlichen.",
|
||||||
|
"FFmpegTip": "FFprobe ist ein Multimedia-Stream-Analyser. Sie können es verwenden, um Informationen über den Streamtyp, -Dauer, -Bildrate, -Bildgröße, usw. zu erhalten.",
|
||||||
|
"FFprobe": "FFprobe",
|
||||||
|
"FactorAuthText1": "Diese Code ist 15 Minuten aktiv. Nach der Anmeldung, wird der Timer für den gleichen Code um weitere 15 Minuten verlängert.",
|
||||||
|
"Fatal": "Fatal",
|
||||||
|
"Fatal Maximum Reached": "Max. Verbindungsversuche erreicht, die Kamera wird gestoppt.",
|
||||||
|
"FatalMaximumReachedText": "Max. Verbindungsversuche erreicht.",
|
||||||
|
"Feed-in Image Height": "Feed-in-Bildhöhe",
|
||||||
|
"Feed-in Image Width": "Feed-in-Bildbreite",
|
||||||
|
"Fields cannot be empty": "Die Felder dürfen nicht leer sein.",
|
||||||
|
"File Not Exist": "Datei nicht vorhanden.",
|
||||||
|
"File Not Found": "Datei nicht gefunden.",
|
||||||
|
"File Type": "Dateityp",
|
||||||
|
"FileNotExistText": "Die Datei konnte nicht gespeichert werden, die Datei existiert nicht mehr.",
|
||||||
|
"Filename": "Dateiname",
|
||||||
|
"Filesize": "Dateigröße",
|
||||||
|
"Filter ID": "Filter-ID",
|
||||||
|
"Filter Matches": "Filter-Bedingung",
|
||||||
|
"Filter Name": "Filter-Name",
|
||||||
|
"FilterMatchesText1": "Die Filter-Bedingung war erfüllt.",
|
||||||
|
"FilterMatchesText2": "Videos gefunden.",
|
||||||
|
"Filters": "Filter",
|
||||||
|
"Filters Updated": "Filter aktualisiert",
|
||||||
|
"FiltersUpdatedText": "Ihre Änderungen wurden gespeichert und angewendet.",
|
||||||
|
"Find Where": "Suchort",
|
||||||
|
"Fix": "Reparieren",
|
||||||
|
"Fix Video": "Video reparieren",
|
||||||
|
"FixVideoMsg": "Dieses Video reparieren? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||||
|
"Font Path": "Schrift-Pfad",
|
||||||
|
"Font Size": "Schriftgröße",
|
||||||
|
"Force Port": "Port forcieren",
|
||||||
|
"Found Devices": "Gefundene Geräte",
|
||||||
|
"Frame Rate": "Bildrate <small>(Bilder pro Sekunde)</small>",
|
||||||
|
"Full Frame Detection": "Vollbilder erkennen",
|
||||||
|
"Fullscreen": "Vollbild",
|
||||||
|
"Greater Than": "Größer als",
|
||||||
|
"Greater Than or Equal to": "Größer als oder gleich",
|
||||||
|
"Group Key": "Gruppen-Schlüssel",
|
||||||
|
"Group Name": "Gruppenname",
|
||||||
|
"Grouping": "Gruppierung ",
|
||||||
|
"H.264 / H.265 / H.265+": "H.264 / H.265 / H.265+",
|
||||||
|
"HLS (.m3u8)": "HLS - (.m3u8)",
|
||||||
|
"HLS (includes Audio)": "HLS (mit Audio)",
|
||||||
|
"HLS Audio Encoder": "HLS-Audio-Encoder",
|
||||||
|
"HLS List Size": "HLS-Listen-Größe",
|
||||||
|
"HLS Preset": "HLS-Preset",
|
||||||
|
"HLS Segment Length": "HLS-Segment-Länge <small>in Sekunden</small>",
|
||||||
|
"HLS Video Encoder": "HLS-Video-Encoder",
|
||||||
|
"HTTP": "HTTP",
|
||||||
|
"HTTPS": "HTTPS",
|
||||||
|
"Height": "Höhe",
|
||||||
|
"Help": "Hilfe",
|
||||||
|
"Hide List": "Liste ausblenden",
|
||||||
|
"Hide Notes": "Meldungen auszublenden",
|
||||||
|
"Host": "Host",
|
||||||
|
"Hotswap Modes (Watch-Only)": "Hotswap-Mode (Betrachtungsmodus)",
|
||||||
|
"How to Record": "Aufnahmeart",
|
||||||
|
"IP Address": "IP-Adresse",
|
||||||
|
"Identity": "Identität",
|
||||||
|
"IdentityText1": "Mit dieser ID wird ein Monitor eindeutig identifiziert. Sie können es nicht nachträglich ändern. Tipp: Verwenden Sie für die <b>Monitor-ID</b> eine für Menschen gut lesbare Bezeichnung, z.B. Parkplatz.",
|
||||||
|
"IdentityText2": "Sie können einen Monitor dadurch duplizieren (klonen), indem Sie die <b>Monitor-ID</b> ändern und anschließend speichern. Wenn Sie hingegen eine bereits vorhandene Monitor-ID verwenden, wird der entsprechende Monitor überschrieben.",
|
||||||
|
"Idle": "Im Leerlauf",
|
||||||
|
"Image Height": "Bildhöhe",
|
||||||
|
"Image Location": "Bild-Pfad <small>Absoluter Pfad, oder leer lassen, um die globale Einstellung zu übernehmen</small>",
|
||||||
|
"Image Position": "Bild-Position",
|
||||||
|
"Image Width": "Bildbreite",
|
||||||
|
"Import": "Import",
|
||||||
|
"Import Monitor Configuration": "Monitor-Konfiguration importieren",
|
||||||
|
"ImportMonitorConfigurationText": "Dadurch werden nicht gespeicherte änderungen überschrieben. Importierte Änderungen werden nur dann angewendet, wenn Sie <b>Speichern</b> drücken.",
|
||||||
|
"In": "In",
|
||||||
|
"Incorrect Settings Chosen": "Falsche Einstellungen gewählt",
|
||||||
|
"Indifference": "Erkennungsschwelle",
|
||||||
|
"Input": "Eingang",
|
||||||
|
"Input Flags": "Eingang-Flags",
|
||||||
|
"Input Type": "Input-Typ",
|
||||||
|
"InputText1": "Hier wird festgelegt, wie der Kamera-Stream verarbeitet wird. Für eine optimale Leistung, müssen manchmal die internen Kamera-Einstellungen angepasst werden. Die Kamera kann auch über den <b>eingebauten ONVIF-Scanner</b> gefunden werden. Einige ONVIF-Kameras müssen im dazu Vorfeld mit einem Hersteller-Tool angepasst werden. Hilfreiches Tool: <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">ONVIF Device Manager für Windows</a>.",
|
||||||
|
"InputText2": "<ul><li><b>Bildrate (Bilder pro Sekunde) :</b> Hoch : 10-15 B/s, Niedrig : 2-5 B/s</li><li><b>I-frame-Interval :</b> 80</li><li><b>Bit-Raten-Typ :</b> CBR (Konstante Bitrate)</li><li><b>Bitrate :</b> zwischen 256 Kbps - 500 Kbps</li></ul>",
|
||||||
|
"InputText3": "Wenn Sie Hilfe bei der Bestimmung der Kamera-Parameter benötigen, werfen Sie einen Blick auf die <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">Kamera-URL-Liste</a> auf der Shinobi-Website.",
|
||||||
|
"Invalid JSON": "Ungültiges JSON-Fragment",
|
||||||
|
"InvalidJSONText": "Bitte sicherstellen, dass ein Gültiger JSON-Fragment mit der Shinobi-Monitor-Konfiguration benutzt wird.",
|
||||||
|
"JPEG": "JPEG",
|
||||||
|
"JPEG (Auto Enables JPEG API)": "JPEG (aktiviert die JPEG-API)",
|
||||||
|
"JPEG API": "JPEG-API - <small>Snapshot (cgi-bin)</small>",
|
||||||
|
"JPEG Error": "JPEG-Fehler",
|
||||||
|
"JPEG Mode": "Im JPEG-Modus",
|
||||||
|
"JPEGErrorText": "Ein Fehler beim Abrufen der Kamera-Daten ist aufgetreten.",
|
||||||
|
"Leave blank for random.": "Leer lassen für einen zufälligen Wert.",
|
||||||
|
"Left": "Nach links <small>URL-Adresse</small>",
|
||||||
|
"Left Stop": "Nach links-Stopp <small>URL-Adresse</small>",
|
||||||
|
"Less Than": "Weniger als",
|
||||||
|
"Less Than or Equal to": "Weniger als oder gleich",
|
||||||
|
"Like": "Wie",
|
||||||
|
"Lisence Plate Detector": "Kfz-Kennzeichen-Detektor",
|
||||||
|
"List Toggle": "Liste umschalten",
|
||||||
|
"Live Stream Toggle": "Live-Stream umschalten",
|
||||||
|
"Live View": "Live-Ansicht",
|
||||||
|
"Local": "Lokal",
|
||||||
|
"Log Level": "Log-Level",
|
||||||
|
"Log Signal Event": "Logge Signal-Ereignisse <small>nur Client-Seite</small>",
|
||||||
|
"Logging": "Logging",
|
||||||
|
"Login": "Login",
|
||||||
|
"Logout": "Logout",
|
||||||
|
"Logs": "Logs",
|
||||||
|
"MB": "MB",
|
||||||
|
"MJPEG": "MJPEG",
|
||||||
|
"MP4 (copy, libx264, libx265)": "MP4 (kopieren, libx264, libx265)",
|
||||||
|
"MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)",
|
||||||
|
"MailError": "E-Mail-Fehler: Es Konnte keine E-Mail versendet werden. Bitte die conf.json überprüfen. Alle E-Mail-Funktionen werden vorübergehend deaktiviert.",
|
||||||
|
"Matches": "Trifft zu",
|
||||||
|
"Max Storage Amount": "Max Speichermenge <small>in MB</small>",
|
||||||
|
"Mode": "Modus",
|
||||||
|
"Monitor": "Monitor",
|
||||||
|
"Monitor Added by user": "Monitor durch Benutzer hinzugefügt.",
|
||||||
|
"Monitor Capture Rate": "Monitor Bildrate <small>(Bilder pro Sekunde)</small>",
|
||||||
|
"Monitor Groups": "Monitor-Gruppen",
|
||||||
|
"Monitor ID": "Monitor-ID",
|
||||||
|
"Monitor Idling": "Monitor im Leerlauf",
|
||||||
|
"Monitor Name": "Monitor Name",
|
||||||
|
"Monitor Settings": "Monitor-Einstellungen",
|
||||||
|
"Monitor Stopped": "Monitor gestoppt",
|
||||||
|
"Monitor Updated by user": "Monitor durch den Benutzer aktualisiert.",
|
||||||
|
"Monitor mode changed": "Monitor-Modus geändert",
|
||||||
|
"Monitor mode is already": "Monitor-Modus ist bereits",
|
||||||
|
"Monitor or Key does not exist.": "Monitor oder Schlüssel nicht vorhanden.",
|
||||||
|
"MonitorIdlingText": "Der Monitor wurde in den Leerlauf geschaltet.",
|
||||||
|
"MonitorStoppedText": "Der Monitor wurde gestoppt.",
|
||||||
|
"Monitors": "Monitore",
|
||||||
|
"Monitors per row": "Monitore pro Zeile <small>in der Montage-Ansicht</small>",
|
||||||
|
"Montage": "Montage",
|
||||||
|
"Motion GUI": "Motion-GUI",
|
||||||
|
"Motion Meter": "Bewegungsindikator",
|
||||||
|
"Name": "Name",
|
||||||
|
"No": "Keine",
|
||||||
|
"No Audio": "Kein Audio",
|
||||||
|
"No Data": "Keine Daten",
|
||||||
|
"No Events found for this video": "Keine Ereignisse für dieses Video gefunden.",
|
||||||
|
"No Group with this key exists": "Keine Gruppe mit diesem Schlüssel vorhanden.",
|
||||||
|
"No Monitor Found, Ignoring Request": "Kein Monitor gefunden, ignoriere Anfrage.",
|
||||||
|
"No Rotation": "Keine Rotation",
|
||||||
|
"No such file": "Keine solche Datei",
|
||||||
|
"NoMotionEmailText1": "Keine Bewegung",
|
||||||
|
"NoMotionEmailText2": "Es wurden keine Bewegungen für die Kamera erkannt für",
|
||||||
|
"NoVideosFoundForDateRange": "Keine Videos in diesem Zeitraum gefunden. Eventuell das Start-Datum weiter zurück stellen.",
|
||||||
|
"Not Authorized": "Nicht autorisiert",
|
||||||
|
"Not Connected": "Nicht verbunden",
|
||||||
|
"Not Equal to": "Ungleich",
|
||||||
|
"Not In": "Nicht in",
|
||||||
|
"Not Matches": "Trifft nicht zu",
|
||||||
|
"Not Permitted": "Nicht erlaubt",
|
||||||
|
"Not an Administrator Account": "Kein Administrator-Konto",
|
||||||
|
"NotAuthorizedText1": "Sie sind nicht berechtigt, init-Befehle mit \"auth\",\"ke\" und \"uid\" zu senden.",
|
||||||
|
"Notes": "Hinweise",
|
||||||
|
"NotesPlacholder": "Ihre Kommentare zu diesen Kamera-Einstellungen",
|
||||||
|
"Number of Days to keep": "Für die Anzahl von Tagen behalten",
|
||||||
|
"ONVIF": "ONVIF",
|
||||||
|
"ONVIF Scanner": "ONVIF-Scanner",
|
||||||
|
"ONVIFnote": "Leer lassen, um ONVIF-Geräte im eigenen Netzwerk zu suchen. Netzwerk spezifizieren, für Suchen außerhalb des eigenen Netzwerks. <br>Benutzername und Kennwort können leer gelassen werden.",
|
||||||
|
"OpenCV Cascades": "OpenCV-Kaskaden",
|
||||||
|
"Order Streams": "Streams ordnen",
|
||||||
|
"Output Method": "Ausgabe-Methode",
|
||||||
|
"Password": "Passwort",
|
||||||
|
"Password Again": "Passwort (Wiederh.)",
|
||||||
|
"Passwords don't match": "Die Passwörter stimmen nicht überein.",
|
||||||
|
"Paste JSON here.": "Fügen Sie hier ein JSON-Fragment ein.",
|
||||||
|
"Path": "Pfad",
|
||||||
|
"Permissions": "Berechtigungen",
|
||||||
|
"Points": "Punkte <small>Um weitere Punkte hinzuzufügen, klicken Sie bitte auf den Rand des Polygons.</small>",
|
||||||
|
"Port": "Port",
|
||||||
|
"Position X": "Position X",
|
||||||
|
"Position Y": "Position Y",
|
||||||
|
"Power Video Viewer": "Power-Video-Viewer",
|
||||||
|
"Power Viewer": "Power-Viewer",
|
||||||
|
"Preferences": "Einstellungen",
|
||||||
|
"Preset": "Voreinstellung",
|
||||||
|
"Probe Size": "Probe-Größe",
|
||||||
|
"Process Crashed for Monitor": "Der Prozess für den Monitor ist abgestürzt",
|
||||||
|
"Process Unexpected Exit": "Der Prozess wurde unerwartet beendet.",
|
||||||
|
"Profile": "Profil",
|
||||||
|
"Quality": "Qualität <small>1 = hoch, 23 = gering</small>",
|
||||||
|
"Query": "Query",
|
||||||
|
"RAM": "RAM",
|
||||||
|
"RTSP": "RTSP",
|
||||||
|
"RTSP Transport": "RTSP-Transport",
|
||||||
|
"Range or Single": "Bereich oder Einzeln",
|
||||||
|
"Rate": "Bildrate <small>(Bilder pro Sekunde)</small>",
|
||||||
|
"Record": "Aufnahme",
|
||||||
|
"Record File Type": "Datei-Typ (Aufnahme)",
|
||||||
|
"Record Height": "Bidhöhe (Aufnahme)",
|
||||||
|
"Record Video Filter": "Video-Filter (Aufnahme)",
|
||||||
|
"Record Width": "Bildbreite (Aufnahme)",
|
||||||
|
"Recording": "Aufnahme",
|
||||||
|
"Recording Flags": "Aufnahme-Flags",
|
||||||
|
"Recording Segment Interval": "Aufnahme-Dauer pro Segment <small>in Minuten</small>",
|
||||||
|
"Recording Timeout": "Aufnahme-Timeout <small>in Minuten</small>",
|
||||||
|
"Recording Timestamp": "Aufnahme-Zeitstempel",
|
||||||
|
"Recording Watermark": "Aufnahme-Wasserzeichen",
|
||||||
|
"RecordingText": "",
|
||||||
|
"Refresh List of Cascades": "Liste der Kaskaden einlesen",
|
||||||
|
"Region Editor": "Region-Editor",
|
||||||
|
"Region Name": "Name der Region",
|
||||||
|
"RegionNote": "Die hier definierten Punkte werden erst dann gespeichert, wenn Sie auf <b>Speichern</b> im Fenster <b>Monitor-Einstellungen</b> klicken.",
|
||||||
|
"Regions": "Regionen",
|
||||||
|
"Remember Me": "Merken",
|
||||||
|
"Reset Timer": "Reset-Timer",
|
||||||
|
"Restarting Process": "Der Prozess wird neu gestartet.",
|
||||||
|
"Retry Connection": "Verbindungsversuche <small>Maximale Anzahl von Verbindungsversuchen. 0 = unendlich</small>",
|
||||||
|
"Retrying...": "Erneuter Versuch...",
|
||||||
|
"Right": "Nach rechts <small>URL-Adresse</small>",
|
||||||
|
"Right Stop": "Nach rechts-Stopp <small>URL-Adresse</small>",
|
||||||
|
"Rotate": "Drehen",
|
||||||
|
"Save": "Speichern",
|
||||||
|
"Save Directory": "Verzeichnis Speichern",
|
||||||
|
"Save Events to SQL": "Ereignisse in der Datenbank speichern",
|
||||||
|
"Save Log in SQL": "Log in der Datenbank speichern<small>Achtung: Die Datenbank kann dabei sehr schnell groß werden.</small>",
|
||||||
|
"Save as": "Speichern als",
|
||||||
|
"Saved Filters": "Gespeicherte Filter",
|
||||||
|
"Scan Settings": "Scan-Einstellungen",
|
||||||
|
"Search": "Suche",
|
||||||
|
"Send Frames": "Bilddaten zum Detektor senden <small>Bilddaten werden analysiert</small>",
|
||||||
|
"Separate with commas, no spaces": "Getrennt mit Kommas, ohne Leerzeichen",
|
||||||
|
"Set to Watch Only": "Aufnahme beenden",
|
||||||
|
"Settings": "Einstellungen",
|
||||||
|
"Settings Changed": "Einstellungen geändert",
|
||||||
|
"SettingsChangedText": "Die Einstellungen wurden gespeichert und angewendet.",
|
||||||
|
"Shinobi": "Shinobi",
|
||||||
|
"Shinobi Streamer": "Shinobi-Streamer",
|
||||||
|
"Show Logs": "Logs anzeigen",
|
||||||
|
"Silent": "Still",
|
||||||
|
"Simple": "Einfach",
|
||||||
|
"Size (mb)": "Größe (MB)",
|
||||||
|
"Snapshot": "Snapshot",
|
||||||
|
"Snapshot Flags": "Snapshot-Flags",
|
||||||
|
"Snapshots": "Snapshots",
|
||||||
|
"Sort By": "Sortieren nach",
|
||||||
|
"Start": "Starten",
|
||||||
|
"Start Recording": "Aufnahme starten",
|
||||||
|
"Start Time": "Startzeit",
|
||||||
|
"Started": "Gestartet",
|
||||||
|
"Status Indicator": "Statusanzeige",
|
||||||
|
"Stop URL": "Stop-URL",
|
||||||
|
"Stream": "Stream",
|
||||||
|
"Stream Flags": "Stream-Flags",
|
||||||
|
"Stream Timestamp": "Stream-Timestamp",
|
||||||
|
"Stream Type": "Stream-Typ",
|
||||||
|
"Stream Watermark": "Stream-Wasserzeichen",
|
||||||
|
"Stream to YouTube": "Stream zu YouTube schicken",
|
||||||
|
"Stream to YouTube Flags": "YouTube-Flags",
|
||||||
|
"StreamText": "<p>Dieser Abschnitt legt die primäre Stream-Methode und ihre Einstellungen fest. Dieser Stream wird im Dashboard angezeigt. Wenn Sie HLS, JPEG oder MJPEG verwenden, können Sie den Stream durch andere Programme nutzen.</p><p class=\"h_st_input h_st_jpeg\">Beim JPEG-Stream wird der primäre Stream abgeschaltet und stattdessen den Snapshot-Modus verwendet.</p>",
|
||||||
|
"Streamer": "Streamer",
|
||||||
|
"Streams": "Streams",
|
||||||
|
"Superuser": "Superuser",
|
||||||
|
"Switch on for Still Image": "Schalter für Standbild",
|
||||||
|
"TCP": "TCP",
|
||||||
|
"Text Box Color": "Textbox-Farbe",
|
||||||
|
"Text Color": "Textfarbe",
|
||||||
|
"Time-lapse": "Zeitraffer",
|
||||||
|
"Time-lapse Tool": "Zeitraffer-Werkzeug",
|
||||||
|
"Timeout": "Timeout",
|
||||||
|
"Timeout Reset on Next Motion": "Timeout-Zähler bei nächster Bewegung zurücksetzen",
|
||||||
|
"Toggle Sidebar": "Sidebar umschalten",
|
||||||
|
"Top Left": "Oben links",
|
||||||
|
"Top Right": "Oben rechts",
|
||||||
|
"Trigger Record": "Aufzeichnung triggern",
|
||||||
|
"Trigger Successful": "Trigger erfolgreich",
|
||||||
|
"UDP": "UDP",
|
||||||
|
"URL": "URL",
|
||||||
|
"URL Stop Timeout": "Stopp-URL-Timeout <small>Ruft die Stopp-URL nach X Millisekunden auf</small>",
|
||||||
|
"US": "US",
|
||||||
|
"Unable to Launch": "Konnte nicht starten",
|
||||||
|
"UnabletoLaunchText": "Bitte speichern Sie zuerst die neuen Monitor-Einstellungen. Danach steht der Region-Editor zur Verfügung.",
|
||||||
|
"Up": "Nach oben <small>URL-Adresse</small>",
|
||||||
|
"Up Stop": "Nach oben-Stopp <small>URL-Adresse</small>",
|
||||||
|
"Username": "Benutzername",
|
||||||
|
"Value": "Wert",
|
||||||
|
"Video": "Video",
|
||||||
|
"Video Codec": "Video-Codec",
|
||||||
|
"Video Filter": "Video-Filter",
|
||||||
|
"Video Finished": "Das Video ist fertig.",
|
||||||
|
"Video Length (minutes) and Motion Count per video": "Video-Länge (in Minuten) und Bewegungsanzahl pro video",
|
||||||
|
"Video Record Rate": "Video-Aufnahme-Rate <small>(Bilder pro Sekunde)</small>",
|
||||||
|
"Video Status": "Video-Status",
|
||||||
|
"Video and Time Span (Minutes)": "Video und Zeitspanne (in Minuten)",
|
||||||
|
"Videos": "Videos",
|
||||||
|
"Videos List": "Video-Liste",
|
||||||
|
"Watch": "Anschauen",
|
||||||
|
"Watch Only": "Nur Anschauen",
|
||||||
|
"WebDAV": "WebDAV",
|
||||||
|
"WebM (libvpx)": "WebM (libvpx)",
|
||||||
|
"Webdav Error": "WebDAV-Fehler",
|
||||||
|
"WebdavErrorText": "Kann nicht speichern. Bitte überprüfen, ob die Kamera-Ordner im gewählten Verzeichnis angelegt sind.",
|
||||||
|
"Webhook": "Webhook",
|
||||||
|
"Webhook URL": "Webhook-URL",
|
||||||
|
"Width": "Breite",
|
||||||
|
"Yes": "Ja",
|
||||||
|
"Zoom In": "Zoom-In <small>URL-Adresse</small>",
|
||||||
|
"Zoom In Stop": "Zoom-In Stopp <small>URL-Adresse</small>",
|
||||||
|
"Zoom Out": "Zoom-Out <small>URL-Adresse</small>",
|
||||||
|
"Zoom Out Stop": "Zoom-Out Stopp <small>URL-Adresse</small>",
|
||||||
|
"a day": "einen Tag",
|
||||||
|
"a few seconds": "ein paar Sekunden",
|
||||||
|
"a minute": "eine Minute",
|
||||||
|
"a month": "einen Monat",
|
||||||
|
"a year": "ein Jahr",
|
||||||
|
"aac": "aac",
|
||||||
|
"aac (Default)": "aac (Standard)",
|
||||||
|
"ac3": "ac3",
|
||||||
|
"ago": "vor",
|
||||||
|
"an hour": "eine Stunde",
|
||||||
|
"blankPassword": "Leer lassen, um das gleiche Passwort zu verwenden.",
|
||||||
|
"calendar": "Kalender",
|
||||||
|
"clientStreamFailedattemptingReconnect": "Client-seitiger Stream-Check fehlgeschlagen. Erneuter Versuch...",
|
||||||
|
"confirmDeleteFilter": "Wollen Sie diesen Filter wirklich löschen? Sie können ihn nicht mehr wiederherstellen.",
|
||||||
|
"copy": "kopieren",
|
||||||
|
"days": "Tage",
|
||||||
|
"dropBoxSuccess": "Die Dateien wurden erfolgreich in der Dropbox gespeichert.",
|
||||||
|
"for Global Access": "Für den weltweiten Zugriff",
|
||||||
|
"hours": "Stunden",
|
||||||
|
"in": "in",
|
||||||
|
"libmp3lame": "libmp3lame",
|
||||||
|
"libopus": "libopus",
|
||||||
|
"libvorbis (Default)": "libvorbis (Standard)",
|
||||||
|
"libvpx (Default)": "libvpx (Standard)",
|
||||||
|
"libvpx-vp9": "libvpx-vp9",
|
||||||
|
"libx264": "libx264",
|
||||||
|
"libx264 (Default)": "libx264 (Standard)",
|
||||||
|
"libx265": "libx265",
|
||||||
|
"minutes": "Minuten",
|
||||||
|
"modifyVideoText1": "Die Methode ist nicht vorhanden. Bitte sicherstellen, dass der letzte Wert der URL nicht leer ist.",
|
||||||
|
"monitorEditFailedMaxReached": "Die maximale Anzahl von Kameras wurde erreicht. Zum Erhöhen des Wertes wenden Sie sich an Ihren Administrator.",
|
||||||
|
"monitorEditText1": "Ungültige Daten. Bitte einen gültigen Import-String eingeben.",
|
||||||
|
"monitorEditText2": "Ungültiger Details-String. Bitte einen gültigen JSON-String eingeben.",
|
||||||
|
"monitorGetText1": "Unvollständiger Request. Entweder den Schrägstrich am Ende entfernen oder einen gültigen Wert setzen.",
|
||||||
|
"months": "Monate",
|
||||||
|
"noSpecialCharacters": "Es dürfen keine Leerzeichen oder Sonderzeichen enthalten sein.",
|
||||||
|
"on": "auf",
|
||||||
|
"on Error": "bei Fehlern",
|
||||||
|
"startUpText0": "Größe der Videos überprüfen",
|
||||||
|
"startUpText1": "Größe der Videos überprüft",
|
||||||
|
"startUpText2": "Alle Benutzer überprüft. Bitte warten, geöffnete Dateien werden geschlossen und Dateien über Benutzer-Limit werden entfernt.",
|
||||||
|
"startUpText3": "Warte weitere 3 Sekunden auf den Abschluss der Überprüfung.",
|
||||||
|
"startUpText4": "Starte alle Monitore.",
|
||||||
|
"startUpText5": "Shinobi ist bereit.",
|
||||||
|
"superAdminText": "\"super.json\" ist nicht vorhanden. Die Datei \"super.Probe.json\" kann als Vorlage für \"super.json\" verwendet werden.",
|
||||||
|
"superAdminTitle": "Shinobi : Super Admin",
|
||||||
|
"total": "insgesamt",
|
||||||
|
"undefined": "nicht definiert",
|
||||||
|
"updateKeyText1": "Kein \"updateKey\" in \"conf.json\" vorhanden. Es werden keine Updates durchgeführt.",
|
||||||
|
"updateKeyText2": "\"updateKey\" ist falsch.",
|
||||||
|
"years": "Jahre"
|
||||||
|
}
|
|
@ -0,0 +1,695 @@
|
||||||
|
{
|
||||||
|
"Shinobi": "Shinobi",
|
||||||
|
"superAdminTitle": "Shinobi : Super Admin",
|
||||||
|
"Login": "Login",
|
||||||
|
"Authenticate": "Authenticate",
|
||||||
|
"Dashboard": "Dashboard",
|
||||||
|
"Streamer": "Streamer",
|
||||||
|
"Admin": "Admin",
|
||||||
|
"Superuser": "Superuser",
|
||||||
|
"Dashcam": "Dashcam",
|
||||||
|
"Email": "Email",
|
||||||
|
"Username": "Username",
|
||||||
|
"Profile": "Profile",
|
||||||
|
"Password": "Password",
|
||||||
|
"Password Again": "Password Again",
|
||||||
|
"Remember Me": "Remember Me",
|
||||||
|
"RAM": "RAM",
|
||||||
|
"CPU": "CPU",
|
||||||
|
"on": "on",
|
||||||
|
"Power Viewer": "Power Viewer",
|
||||||
|
"Power Video Viewer": "Power Video Viewer",
|
||||||
|
"Time-lapse": "Time-lapse",
|
||||||
|
"Montage": "Montage",
|
||||||
|
"Accounts": "Accounts",
|
||||||
|
"Settings": "Settings",
|
||||||
|
"Recording FPS": "Recording FPS",
|
||||||
|
"Input Selector": "Input Selector",
|
||||||
|
"Input Settings": "Input Settings",
|
||||||
|
"Connection": "Connection",
|
||||||
|
"API": "API",
|
||||||
|
"ONVIF": "ONVIF",
|
||||||
|
"FFprobe": "Probe",
|
||||||
|
"Filters": "Filters",
|
||||||
|
"Full URL Path": "Full URL Path",
|
||||||
|
"Logs": "Logs",
|
||||||
|
"Full Stream URL": "Full Stream URL",
|
||||||
|
"Manual": "Manual",
|
||||||
|
"List Toggle": "List Toggle",
|
||||||
|
"Hide List": "Hide List",
|
||||||
|
"Motion GUI": "Motion GUI",
|
||||||
|
"Motion": "Motion",
|
||||||
|
"Global Detector Settings": "Global Detector Settings",
|
||||||
|
"Motion Detection": "Motion Detection",
|
||||||
|
"Object Detection": "Object Detection",
|
||||||
|
"JPEG Mode": "JPEG Mode",
|
||||||
|
"Order Streams": "Order Streams",
|
||||||
|
"Hide Notes": "Hide Notes",
|
||||||
|
"Example": "Example",
|
||||||
|
"Logout": "Logout",
|
||||||
|
"Closed": "Closed",
|
||||||
|
"Ended": "Ended",
|
||||||
|
"Options": "Options",
|
||||||
|
"Started": "Started",
|
||||||
|
"Monitor": "Monitor",
|
||||||
|
"Filename": "Filename",
|
||||||
|
"Size (mb)": "Size (mb)",
|
||||||
|
"Watch": "Watch",
|
||||||
|
"Download": "Download",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Fix": "Fix",
|
||||||
|
"Use HTML5 Play Method": "Use HTML5 Play Method",
|
||||||
|
"Connection timed out": "Connection timed out",
|
||||||
|
"skipPingText1": "Try setting \"Skip Ping\" to Yes.",
|
||||||
|
"Ping Failed": "Ping Failed",
|
||||||
|
"Zoom In": "Zoom In <small>URL Address</small>",
|
||||||
|
"Zoom Out": "Zoom Out <small>URL Address</small>",
|
||||||
|
"Enable Nightvision": "Enable Nightvision",
|
||||||
|
"Disable Nightvision": "Disable Nightvision",
|
||||||
|
"Current": "Current",
|
||||||
|
"Monitors": "Monitors",
|
||||||
|
"Video": "Video",
|
||||||
|
"Themes": "Themes",
|
||||||
|
"Videos": "Videos",
|
||||||
|
"Events": "Events",
|
||||||
|
"Streams": "Streams",
|
||||||
|
"Snapshot": "Snapshot",
|
||||||
|
"Snapshots": "Snapshots",
|
||||||
|
"Date Range": "Date Range",
|
||||||
|
"Event Limit": "Event Limit",
|
||||||
|
"No Data": "No Data",
|
||||||
|
"Live View": "Live View",
|
||||||
|
"New Monitor": "New Monitor",
|
||||||
|
"Please Check Your Settings": "Please Check Your Settings",
|
||||||
|
"migrateText1": "<b>Input Type</b> could not be parsed. Please set it manually.",
|
||||||
|
"Add": "Add",
|
||||||
|
"Save": "Save",
|
||||||
|
"Close": "Close",
|
||||||
|
"Secure": "Secure",
|
||||||
|
"Check": "Check",
|
||||||
|
"Stop": "Stop",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Enable": "Enable",
|
||||||
|
"Enabled": "Enabled",
|
||||||
|
"API Key": "API Key",
|
||||||
|
"API Keys": "API Keys",
|
||||||
|
"Group Key": "Group Key",
|
||||||
|
"Allowed IPs": "Allowed IPs",
|
||||||
|
"Separate with commas, no spaces": "Separate with commas, no spaces",
|
||||||
|
"Can Get Monitors": "Can Get Monitors",
|
||||||
|
"Can Get Logs": "Can Get Logs",
|
||||||
|
"Can Authenticate Websocket": "Can Authenticate Websocket",
|
||||||
|
"Can Control Monitors": "Can Control Monitors",
|
||||||
|
"Can View Snapshots": "Can View Snapshots",
|
||||||
|
"Can View Streams": "Can View Streams",
|
||||||
|
"Can View Videos": "Can View Videos",
|
||||||
|
"Can View Monitor": "Can View Monitor",
|
||||||
|
"Can Edit Monitor": "Can Edit Monitor",
|
||||||
|
"Can Delete Videos": "Can Delete Videos",
|
||||||
|
"Delete Video": "Delete Video",
|
||||||
|
"Can View Videos and Events": "Can View Videos and Events",
|
||||||
|
"Can Delete Videos and Events": "Can Delete Videos and Events",
|
||||||
|
"Saved Filters": "Saved Filters",
|
||||||
|
"Filter Name": "Filter Name",
|
||||||
|
"Find Where": "Find Where",
|
||||||
|
"Sort By": "Sort By",
|
||||||
|
"Start Time": "Start Time",
|
||||||
|
"End Time": "End Time",
|
||||||
|
"Monitor ID": "Monitor ID",
|
||||||
|
"File Type": "File Type",
|
||||||
|
"Filesize": "Filesize",
|
||||||
|
"Video Status": "Video Status",
|
||||||
|
"Preferences": "Preferences",
|
||||||
|
"Equal to": "Equal to",
|
||||||
|
"Not Equal to": "Not Equal to",
|
||||||
|
"Greater Than or Equal to": "Greater Than or Equal to",
|
||||||
|
"Greater Than": "Greater Than",
|
||||||
|
"Less Than": "Less Than",
|
||||||
|
"Less Than or Equal to": "Less Than or Equal to",
|
||||||
|
"Like": "Like",
|
||||||
|
"Matches": "Matches",
|
||||||
|
"Not Matches": "Not Matches",
|
||||||
|
"In": "In",
|
||||||
|
"Not In": "Not In",
|
||||||
|
"ASC": "ASC",
|
||||||
|
"DESC": "DESC",
|
||||||
|
"Action for Selected": "Action for Selected",
|
||||||
|
"Search": "Search",
|
||||||
|
"No": "No",
|
||||||
|
"Yes": "Yes",
|
||||||
|
"Start": "Start",
|
||||||
|
"End": "End",
|
||||||
|
"Archive": "Archive",
|
||||||
|
"Email Details": "Email Details",
|
||||||
|
"Delete Matches": "Delete Matches",
|
||||||
|
"Delete selected": "Delete selected",
|
||||||
|
"Execute Command": "Execute Command",
|
||||||
|
"for Global Access": "for Global Access",
|
||||||
|
"Help": "Help",
|
||||||
|
"Don't show this anymore": "Don't show this anymore",
|
||||||
|
"Chat on Discord": "Chat on Discord",
|
||||||
|
"Documentation": "Documentation",
|
||||||
|
"All Monitors": "All Monitors",
|
||||||
|
"Motion Meter": "Motion Meter",
|
||||||
|
"FFmpegTip": "FFprobe is a simple multimedia streams analyzer. You can use it to output all kinds of information about an input including duration, frame rate, frame size, etc.",
|
||||||
|
"Complete Stream URL": "Complete Stream URL",
|
||||||
|
"ONVIF Scanner": "ONVIF Scanner",
|
||||||
|
"Scan Settings": "Scan Settings",
|
||||||
|
"ONVIFnote": "Discover ONVIF devices on networks outside your own or leave it blank to scan your current network. <br>Username and Password can be left blank.",
|
||||||
|
"Range or Single": "Range or Single",
|
||||||
|
"IP Address": "IP Address",
|
||||||
|
"Port": "Port",
|
||||||
|
"Camera Username": "Camera Username",
|
||||||
|
"Camera Password": "Camera Password",
|
||||||
|
"Found Devices": "Found Devices",
|
||||||
|
"Switch on for Still Image": "Switch on for Still Image",
|
||||||
|
"Live Stream Toggle": "Live Stream Toggle",
|
||||||
|
"RegionNote": "Points are only saved when you press <b>Save</b> on the <b>Monitor Settings</b> window.",
|
||||||
|
"Points": "Points <small>When adding points click on the edge of the polygon.</small>",
|
||||||
|
"Indifference": "Indifference",
|
||||||
|
"Region Name": "Region Name",
|
||||||
|
"Regions": "Regions",
|
||||||
|
"Again": "Again",
|
||||||
|
"Account Info": "Account Info",
|
||||||
|
"blankPassword": "Leave blank to keep same password",
|
||||||
|
"2-Factor Authentication": "2-Factor Authentication",
|
||||||
|
"Max Storage Amount": "Max Storage Amount <small>in Megabytes</small>",
|
||||||
|
"Number of Days to keep": "Number of Days to keep",
|
||||||
|
"Monitor Groups": "Monitor Groups",
|
||||||
|
"Group Name": "Group Name",
|
||||||
|
"WebDAV": "WebDAV",
|
||||||
|
"URL": "URL",
|
||||||
|
"Autosave": "Autosave",
|
||||||
|
"Save Directory": "Save Directory",
|
||||||
|
"CSS": "CSS <small>Style your dashboard.</small>",
|
||||||
|
"Force Monitors Per Row": "Force Monitors Per Row",
|
||||||
|
"Monitors per row": "Monitors per row <small>for Montage</small>",
|
||||||
|
"Browser Console Log": "Browser Console Log",
|
||||||
|
"All Monitors and Privileges": "All Monitors and Privileges",
|
||||||
|
"Permissions": "Permissions",
|
||||||
|
"Time-lapse Tool": "Time-lapse Tool",
|
||||||
|
"total": "total",
|
||||||
|
"MB": "MB",
|
||||||
|
"Calendar": "Calendar",
|
||||||
|
"Leave blank for random.": "Leave blank for random.",
|
||||||
|
"Currently viewing": "Currently viewing",
|
||||||
|
"Status Indicator": "Status Indicator",
|
||||||
|
"Show Logs": "Show Logs",
|
||||||
|
"Videos List": "Videos List",
|
||||||
|
"Monitor Settings": "Monitor Settings",
|
||||||
|
"Enlarge": "Enlarge",
|
||||||
|
"Fullscreen": "Fullscreen",
|
||||||
|
"Value": "Value",
|
||||||
|
"Idle": "Idle",
|
||||||
|
"Disabled": "Disabled",
|
||||||
|
"Record": "Record",
|
||||||
|
"Watch Only": "Watch Only",
|
||||||
|
"Toggle Sidebar": "Toggle Sidebar",
|
||||||
|
"Add Monitor": "Add Monitor",
|
||||||
|
"Start Recording": "Start Recording",
|
||||||
|
"Set to Watch Only": "Set to Watch Only",
|
||||||
|
"Save as": "Save as",
|
||||||
|
"Add New": "Add New",
|
||||||
|
"Delete Selected Videos": "Delete Selected Videos",
|
||||||
|
"DeleteSelectedVideosMsg": "Do you want to delete these videos? You cannot recover them.",
|
||||||
|
"clientStreamFailedattemptingReconnect": "Client side ctream check failed, attempting reconnect.",
|
||||||
|
"Delete Filter": "Delete Filter",
|
||||||
|
"confirmDeleteFilter": "Do you want to delete this filter? You cannot recover it.",
|
||||||
|
"Fix Video": "Fix Video",
|
||||||
|
"FixVideoMsg": "Do you want to fix this video? You cannot undo this action.",
|
||||||
|
"DeleteVideoMsg": "Do you want to delete this video? You cannot recover it.",
|
||||||
|
"dropBoxSuccess": "Success! Files saved to your Dropbox.",
|
||||||
|
"API Key Deleted": "API Key Deleted",
|
||||||
|
"APIKeyDeletedText": "Key has been deleted. It will no longer work.",
|
||||||
|
"API Key Added": "API Key Added",
|
||||||
|
"APIKeyAddedText": "You may use this key now.",
|
||||||
|
"Update": "Update",
|
||||||
|
"Update to Master": "Update to Master",
|
||||||
|
"Update to Development": "Update to Development",
|
||||||
|
"Filters Updated": "Filters Updated",
|
||||||
|
"FiltersUpdatedText": "Your changes have been saved and applied.",
|
||||||
|
"Settings Changed": "Settings Changed",
|
||||||
|
"SettingsChangedText": "Your settings have been saved and applied. Some settings may require a refresh of this page.",
|
||||||
|
"Are you sure?": "Are you sure?",
|
||||||
|
"Import Monitor Configuration": "Import Monitor Configuration",
|
||||||
|
"ImportMultiMonitorConfigurationText": "Doing this will overrwrite any monitors with IDs existing in the import file.",
|
||||||
|
"ImportMonitorConfigurationText": "Doing this will overrwrite any changes currently not saved. Imported changes will only be applied when you press <b>Save</b>.",
|
||||||
|
"Paste JSON here.": "Paste JSON here.",
|
||||||
|
"Delete Monitor": "Delete Monitor",
|
||||||
|
"DeleteMonitorText": "Do you want to delete this monitor? You cannot recover it. The files for this ID will remain in the filesystem. If you choose to recreate a monitor with the same ID the videos and events will become visible in the dashboard.",
|
||||||
|
"DeleteMonitorsText": "Do you want to delete these monitors? You cannot recover them. The files for these IDs will remain in the filesystem. If you choose to recreate a monitor with one of the IDs the videos and events will become visible in the dashboard.",
|
||||||
|
"Invalid JSON": "Invalid JSON",
|
||||||
|
"InvalidJSONText": "Please ensure this is a valid JSON string for Shinobi monitor configuration.",
|
||||||
|
"Passwords don't match": "Passwords don't match",
|
||||||
|
"No Events found for this video": "No Events found for this video",
|
||||||
|
"Video and Time Span (Minutes)": "Video and Time Span (Minutes)",
|
||||||
|
"Video Length (minutes) and Motion Count per video": "Video Length (minutes) and Motion Count per video",
|
||||||
|
"Counts of Motion": "Counts of Motion",
|
||||||
|
"Unable to Launch": "Unable to Launch",
|
||||||
|
"UnabletoLaunchText": "Please save new monitor first. Then attempt to launch the region editor.",
|
||||||
|
"NoVideosFoundForDateRange": "No Videos found in this date range. Try setting the start date further back.",
|
||||||
|
"monitorEditFailedMaxReached": "Your account has reached the maximum number of cameras that can be created. Speak to an administrator if you would like this changed.",
|
||||||
|
"in": "in",
|
||||||
|
"ago": "ago",
|
||||||
|
"a few seconds": "a few seconds",
|
||||||
|
"a minute": "a minute",
|
||||||
|
"minutes": "minutes",
|
||||||
|
"an hour": "an hour",
|
||||||
|
"hours": "hours",
|
||||||
|
"a day": "a day",
|
||||||
|
"days": "days",
|
||||||
|
"a month": "a month",
|
||||||
|
"months": "months",
|
||||||
|
"a year": "a year",
|
||||||
|
"years": "years",
|
||||||
|
"Identity": "Identity",
|
||||||
|
"Input": "Input",
|
||||||
|
"Input Feed": "Input Feed",
|
||||||
|
"Stream": "Stream",
|
||||||
|
"Stream Timestamp": "Stream Timestamp",
|
||||||
|
"Stream Watermark": "Stream Watermark",
|
||||||
|
"JPEG API": "JPEG API <small>Snapshot (cgi-bin)</small>",
|
||||||
|
"Raw H.264 Stream": "Raw H.264 Stream",
|
||||||
|
"Recording": "Recording",
|
||||||
|
"Recording Timestamp": "Recording Timestamp",
|
||||||
|
"Recording Watermark": "Recording Watermark",
|
||||||
|
"Region Editor": "Region Editor",
|
||||||
|
"Custom": "Custom",
|
||||||
|
"Detector": "Detector",
|
||||||
|
"Connected": "Connected",
|
||||||
|
"Not Saved": "Not Saved",
|
||||||
|
"Not Connected": "Not Connected",
|
||||||
|
"Lisence Plate Detector": "Lisence Plate Detector",
|
||||||
|
"OpenCV Cascades": "OpenCV Cascades",
|
||||||
|
"Refresh List of Cascades": "Refresh List of Cascades",
|
||||||
|
"\"No Motion\" Detector": "\"No Motion\" Detector",
|
||||||
|
"Control": "Control",
|
||||||
|
"Grouping": "Grouping <small>Add groups in <b>Settings</b></small>",
|
||||||
|
"Detector Grouping": "Detector Grouping <small>Add groups in <b>Settings</b></small>",
|
||||||
|
"Logging": "Logging",
|
||||||
|
"IdentityText1": "This is how the system will identify the data for this stream. You cannot change the <b>Monitor ID</b> once you have pressed save. If you want you can make the <b>Monitor ID</b> more human readable before you continue.",
|
||||||
|
"IdentityText2": "You can duplicate a monitor by modifying the <b>Monitor ID</b> then pressing save. You <b>cannot</b> use the ID of a monitor that already exists or it will save over that monitor's database information.",
|
||||||
|
"noSpecialCharacters": "No spaces or special characters.",
|
||||||
|
"NotesPlacholder": "Comments you want to leave for this cameras settings.",
|
||||||
|
"InputText1": "This section tells Shinobi how to consume a stream. For optimal performance try tuning your camera's internal settings. Find the following options and set them as shown. To find your camera you can use the <b>built in ONVIF Scanner</b> of Shinobi. Some ONVIF cameras require the use of a management tool to modify their internal settings. If you can't find your cameras you can try <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">ONVIF Device Manager for Windows</a>.",
|
||||||
|
"InputText2": "<ul><li><b>Framerate (FPS) :</b> High : 10 - 15 FPS, Low : 2-5 FPS</li><li><b>I-frame interval :</b> 80</li><li><b>Bit Rate Type :</b> CBR (Constant Bit Rate)</li><li><b>Bit Rate :</b> between 256kbps - 500kbps</li></ul>",
|
||||||
|
"InputText3": "If you need help figuring out what input type your camera is you can take a look in the <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">Camera URLs List</a> on the Shinobi website.",
|
||||||
|
"StreamText": "<p>This section will designate the primary method of streaming out and its settings. This stream will be displayed in the dashboard. If you choose to use HLS, JPEG, or MJPEG then you can consume the stream through other programs.</p><p class=\"h_st_input h_st_jpeg\">Using JPEG stream essentially turns off the primary stream and uses the snapshot bin to get frames.</p>",
|
||||||
|
"DetectorText": "<p>When the Width and Height boxes are shown you should set them to 640x480 or below. This will optimize the read speed of frames.</p>",
|
||||||
|
"RecordingText": "It is recommended that you set <b>Record File Type</b> to <b class=\"h_t_input h_t_jpeg h_t_socket\">WebM</b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">MP4</b> and <b>Video Codec</b> to <b class=\"h_t_input h_t_jpeg h_t_socket\">libvpx</b><b class=\"h_t_input h_t_h264 h_t_hls h_t_mp4\">copy or </b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">libx264</b> because your <b>Input Type</b> is set to <b class=\"h_t_text\"></b>.",
|
||||||
|
"Mode": "Mode",
|
||||||
|
"Name": "Name",
|
||||||
|
"Skip Ping": "Skip Ping",
|
||||||
|
"Retry Connection": "Retry Connection <small>Number of times allowed to fail</small>",
|
||||||
|
"Notes": "Notes",
|
||||||
|
"Input Type": "Input Type",
|
||||||
|
"Connection Type": "Connection Type",
|
||||||
|
"RTSP Transport": "RTSP Transport",
|
||||||
|
"Host": "Host",
|
||||||
|
"Force Port": "Force Port",
|
||||||
|
"Path": "Path",
|
||||||
|
"Monitor Capture Rate": "Monitor Capture Rate <small>(FPS)</small>",
|
||||||
|
"Analyzation Duration": "Analyzation Duration",
|
||||||
|
"Probe Size": "Probe Size",
|
||||||
|
"Stream Type": "Stream Type",
|
||||||
|
"# of Allow MJPEG Clients": "# of Allow MJPEG Clients <small>0 for infinite</small>",
|
||||||
|
"HLS Video Encoder": "Video Encoder",
|
||||||
|
"HLS Audio Encoder": "Audio Encoder",
|
||||||
|
"HLS Segment Length": "Segment Length <small>in Seconds</small>",
|
||||||
|
"HLS Preset": "Preset Template",
|
||||||
|
"HLS List Size": "List Size",
|
||||||
|
"Traditional Recording": "Traditional Recording",
|
||||||
|
"Buffer Preview": "Buffer Preview",
|
||||||
|
"HLS Start Number": "HLS Start Number",
|
||||||
|
"HLS Live Start Index": "HLS Live Start Index",
|
||||||
|
"Check Signal Interval": "Check Signal Interval <small>in Minutes</small>",
|
||||||
|
"Log Signal Event": "Log Signal Event <small>Client side only</small>",
|
||||||
|
"Quality": "Quality <small>1 is High, 23 is Low</small>",
|
||||||
|
"Rate": "Rate <small>(FPS)</small>",
|
||||||
|
"Width": "Width",
|
||||||
|
"Height": "Height",
|
||||||
|
"Rotate": "Rotate",
|
||||||
|
"Primary Engine": "Primary Engine",
|
||||||
|
"Video Filter": "Video Filter",
|
||||||
|
"Font Path": "Font Path",
|
||||||
|
"Font Size": "Font Size",
|
||||||
|
"Text Color": "Text Color",
|
||||||
|
"Text Box Color": "Text Box Color",
|
||||||
|
"Position X": "Position X",
|
||||||
|
"Position Y": "Position Y",
|
||||||
|
"Image Location": "Image Location <small>Absolute Path or leave blank to use global</small>",
|
||||||
|
"Image Position": "Image Position",
|
||||||
|
"Frame Rate": "Frame Rate <small>(FPS)</small>",
|
||||||
|
"Image Width": "Image Width",
|
||||||
|
"Image Height": "Image Height",
|
||||||
|
"Record File Type": "Record File Type",
|
||||||
|
"Video Codec": "Video Codec",
|
||||||
|
"Preset": "Preset",
|
||||||
|
"Audio Codec": "Audio Codec",
|
||||||
|
"Video Record Rate": "Video Record Rate <small>(FPS)</small>",
|
||||||
|
"Record Width": "Record Width",
|
||||||
|
"Record Height": "Record Height",
|
||||||
|
"Double Quote Directory": "Double Quote Directory <small>Some directories have spaces. Using this may crash some cameras.</small>",
|
||||||
|
"Recording Segment Interval": "Recording Segment Interval <small>in minutes</small>",
|
||||||
|
"Record Video Filter": "Record Video Filter",
|
||||||
|
"Input Flags": "Input Flags",
|
||||||
|
"Snapshot Flags": "Snapshot Flags",
|
||||||
|
"Detector Flags": "Detector Flags",
|
||||||
|
"Stream Flags": "Stream Flags",
|
||||||
|
"Stream to YouTube": "Stream to YouTube",
|
||||||
|
"Stream to YouTube Flags": "Stream to YouTube Flags",
|
||||||
|
"Recording Flags": "Recording Flags",
|
||||||
|
"Output Method": "Output Method",
|
||||||
|
"Webhook": "Webhook",
|
||||||
|
"Webhook URL": "Webhook URL",
|
||||||
|
"Command on Trigger": "Command on Trigger",
|
||||||
|
"Command": "Command",
|
||||||
|
"Allow Next Command": "Allow Next Command <small>in Minutes</small>",
|
||||||
|
"Allow Next Trigger": "Allow Next Trigger <small>in Milliseconds</small>",
|
||||||
|
"Save Events to SQL": "Save Events to SQL",
|
||||||
|
"Email on Trigger": "Email on Trigger <small>Emails go to the main account holder's login address.</small>",
|
||||||
|
"Allow Next Email": "Allow Next Email <small>in Minutes</small>",
|
||||||
|
"How to Record": "How to Record",
|
||||||
|
"Trigger Record": "Trigger Record",
|
||||||
|
"Recording Timeout": "Recording Timeout <small>in Minutes</small>",
|
||||||
|
"Timeout Reset on Next Motion": "Timeout Reset on Next Motion",
|
||||||
|
"Timeout Reset on Next Event": "Timeout Reset on Next Event",
|
||||||
|
"Delete Motionless Video": "Delete Motionless Video",
|
||||||
|
"Send Frames": "Send Frames <small>Push frames to be analyzed</small>",
|
||||||
|
"Detector Rate": "Detector Rate <small>(FPS)</small>",
|
||||||
|
"Feed-in Image Width": "Feed-in Image Width",
|
||||||
|
"Feed-in Image Height": "Feed-in Image Height",
|
||||||
|
"Check for Motion First": "Check for Motion First",
|
||||||
|
"Detect Objects": "Detect Objects <small class=\"\">See below</small>",
|
||||||
|
"Full Frame Detection": "Full Frame Detection",
|
||||||
|
"Country of Plates": "Country of Plates",
|
||||||
|
"Email on No Motion": "Email on \"No Motion\"",
|
||||||
|
"Timeout": "Timeout",
|
||||||
|
"Controllable": "Controllable",
|
||||||
|
"Custom Base URL": "Custom Base URL <small>Leave blank to use Host URL</small>",
|
||||||
|
"Stop URL": "Stop URL",
|
||||||
|
"Stop Command": "Stop Command",
|
||||||
|
"Digest Authentication": "Digest Authentication",
|
||||||
|
"URL Stop Timeout": "URL Stop Timeout <small>Run stop URL after X milliseconds</small>",
|
||||||
|
"Center": "Center <small>URL Address</small>",
|
||||||
|
"Left": "Left <small>URL Address</small>",
|
||||||
|
"Left Stop": "Left Stop <small>URL Address</small>",
|
||||||
|
"Right": "Right <small>URL Address</small>",
|
||||||
|
"Right Stop": "Right Stop <small>URL Address</small>",
|
||||||
|
"Up": "Up <small>URL Address</small>",
|
||||||
|
"Up Stop": "Up Stop <small>URL Address</small>",
|
||||||
|
"Down": "Down <small>URL Address</small>",
|
||||||
|
"Down Stop": "Down Stop <small>URL Address</small>",
|
||||||
|
"Enable Night Vision": "Enable Night Vision <small>URL Address</small>",
|
||||||
|
"Disable Night Vision": "Disable Night Vision <small>URL Address</small>",
|
||||||
|
"Zoom Out Stop": "Zoom Out Stop <small>URL Address</small>",
|
||||||
|
"Zoom In Stop": "Zoom In Stop <small>URL Address</small>",
|
||||||
|
"Log Level": "Log Level",
|
||||||
|
"Save Log in SQL": "Save Log in SQL <small>This can fill up quickly.</small>",
|
||||||
|
"JPEG": "JPEG",
|
||||||
|
"MJPEG": "MJPEG",
|
||||||
|
"H.264 / H.265 / H.265+": "H.264 / H.265 / H.265+",
|
||||||
|
"HLS (.m3u8)": "HLS (.m3u8)",
|
||||||
|
"MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)",
|
||||||
|
"Shinobi Streamer": "Shinobi Streamer",
|
||||||
|
"Dashcam (Streamer v2)": "Dashcam (Streamer v2)",
|
||||||
|
"Local": "Local",
|
||||||
|
"Raw": "Raw",
|
||||||
|
"HTTP": "HTTP",
|
||||||
|
"HTTPS": "HTTPS",
|
||||||
|
"RTSP": "RTSP",
|
||||||
|
"RTMP": "RTMP",
|
||||||
|
"RTMPS": "RTMPS",
|
||||||
|
"UDP": "UDP",
|
||||||
|
"Auto": "Auto",
|
||||||
|
"TCP": "TCP",
|
||||||
|
"Base64 over Websocket": "Base64 over Websocket",
|
||||||
|
"Websocket": "Websocket",
|
||||||
|
"JPEG (Auto Enables JPEG API)": "JPEG (Auto Enables JPEG API)",
|
||||||
|
"HLS (includes Audio)": "HLS (includes Audio)",
|
||||||
|
"MPEG-DASH (includes Audio)": "MPEG-DASH (includes Audio)",
|
||||||
|
"libx264": "libx264",
|
||||||
|
"libx265": "libx265",
|
||||||
|
"copy": "copy",
|
||||||
|
"No Audio": "No Audio",
|
||||||
|
"aac": "aac",
|
||||||
|
"ac3": "ac3",
|
||||||
|
"libmp3lame": "libmp3lame",
|
||||||
|
"No Rotation": "No Rotation",
|
||||||
|
"180 Degrees": "180 Degrees",
|
||||||
|
"90 Counter Clockwise and Vertical Flip (default)": "90 Counter Clockwise and Vertical Flip (default)",
|
||||||
|
"90 Clockwise": "90 Clockwise",
|
||||||
|
"90 Clockwise and Vertical Flip": "90 Clockwise and Vertical Flip",
|
||||||
|
"Top Right": "Top Right",
|
||||||
|
"Top Left": "Top Left",
|
||||||
|
"Bottom Right": "Bottom Right",
|
||||||
|
"Bottom Left": "Bottom Left",
|
||||||
|
"WebM (libvpx)": "WebM (libvpx)",
|
||||||
|
"Poseidon": "Poseidon",
|
||||||
|
"MP4 (copy, libx264, libx265)": "MP4 (copy, libx264, libx265)",
|
||||||
|
"Default": "Default",
|
||||||
|
"libvpx (Default)": "libvpx (Default)",
|
||||||
|
"libvpx-vp9": "libvpx-vp9",
|
||||||
|
"libx264 (Default)": "libx264 (Default)",
|
||||||
|
"libvorbis (Default)": "libvorbis (Default)",
|
||||||
|
"libopus": "libopus",
|
||||||
|
"aac (Default)": "aac (Default)",
|
||||||
|
"Traditional (Watch-Only, Includes Buffer)": "Traditional (Watch-Only, Includes Buffer)",
|
||||||
|
"Hotswap Modes (Watch-Only)": "Hotswap Modes (Watch-Only)",
|
||||||
|
"Delete Motionless Videos (Record)": "Delete Motionless Videos (Record)",
|
||||||
|
"US": "US",
|
||||||
|
"EU": "EU",
|
||||||
|
"Silent": "Silent",
|
||||||
|
"Fatal": "Fatal",
|
||||||
|
"on Error": "on Error",
|
||||||
|
"All Warnings": "All Warnings",
|
||||||
|
"Warning": "Warning",
|
||||||
|
"Debug": "Debug",
|
||||||
|
"Export": "Export",
|
||||||
|
"Import": "Import",
|
||||||
|
"Simple": "Simple",
|
||||||
|
"Advanced": "Advanced",
|
||||||
|
"Error Connecting": "Error Connecting",
|
||||||
|
"DB Lost.. Retrying..": "Database Lost.. Retrying..",
|
||||||
|
"Retrying...": "Retrying...",
|
||||||
|
"Filter Matches": "Filter Matches",
|
||||||
|
"FilterMatchesText1": "This filter has met conditions.",
|
||||||
|
"FilterMatchesText2": "videos found.",
|
||||||
|
"Executed": "Executed",
|
||||||
|
"Deleted": "Deleted",
|
||||||
|
"Query": "Query",
|
||||||
|
"Request": "Request",
|
||||||
|
"System": "System",
|
||||||
|
"Restart Core": "Restart Core",
|
||||||
|
"Restart CRON": "Restart CRON",
|
||||||
|
"Flush PM2 Logs": "Flush PM2 Logs",
|
||||||
|
"Filter ID": "Filter ID",
|
||||||
|
"Webdav Error": "Webdav Error",
|
||||||
|
"WebdavErrorText": "Cannot save. Did you make the camera folders inside your chosen save directory?",
|
||||||
|
"File Not Exist": "File Not Exist",
|
||||||
|
"No Videos Found": "No Videos Found",
|
||||||
|
"FileNotExistText": "Cannot save non existant file. Something went wrong.",
|
||||||
|
"CameraNotRecordingText": "Settings may be incompatible. Check encoders. Restarting...",
|
||||||
|
"Camera is not recording": "Camera is not recording",
|
||||||
|
"Camera is not streaming": "Camera is not streaming",
|
||||||
|
"Restarting Process": "Restarting Process",
|
||||||
|
"Restart": "Restart",
|
||||||
|
"Monitor Stopped": "Monitor Stopped",
|
||||||
|
"MonitorStoppedText": "Monitor session has been ordered to stop.",
|
||||||
|
"Monitor Idling": "Monitor Idling",
|
||||||
|
"MonitorIdlingText": "Monitor session has been ordered to idle.",
|
||||||
|
"NoMotionEmailText1": "No Motion for",
|
||||||
|
"NoMotionEmailText2": "There hasn't been any motion detected on camera for",
|
||||||
|
"Monitor Name": "Monitor Name",
|
||||||
|
"Process Unexpected Exit": "Process Unexpected Exit",
|
||||||
|
"Process Crashed for Monitor": "Process Crashed for Monitor",
|
||||||
|
"FFmpegCantStart": "FFmpeg Couldn't Start",
|
||||||
|
"FFmpegCantStartText": "The recording engine for this camera could not start. There may be something wrong with your camera configuration. If there are any logs other than this one please post them in the <b>Issues</b> on Github.",
|
||||||
|
"JPEG Error": "JPEG Error",
|
||||||
|
"JPEGErrorText": "There was an issue getting data from your camera.",
|
||||||
|
"Fatal Maximum Reached": "Fatal Maximum Reached, Stopping Camera.",
|
||||||
|
"FatalMaximumReachedText": "JPEG Error was fatal.",
|
||||||
|
"Incorrect Settings Chosen": "Incorrect Settings Chosen",
|
||||||
|
"Can't Connect": "Can't Connect",
|
||||||
|
"Video Finished": "Video Finished",
|
||||||
|
"No Monitors Selected": "No Monitors Selected",
|
||||||
|
"monSavedButNotCopied": "Your monitor was saved but not copied to any other monitor.",
|
||||||
|
"No Monitor Found, Ignoring Request": "No Monitor Found, Ignoring Request",
|
||||||
|
"Event": "Event",
|
||||||
|
"Detector Buffer": "Detector Buffer",
|
||||||
|
"EventText1": "Triggered a motion event at",
|
||||||
|
"EventText2": "Could not email image, file was not accessible",
|
||||||
|
"MailError": "MAIL ERROR : Could not send email, Check conf.json. Skipping any features relying on mailing.",
|
||||||
|
"updateKeyText1": "\"updateKey\" is missing from \"conf.json\", cannot do updates this way until you add it.",
|
||||||
|
"updateKeyText2": "\"updateKey\" is incorrect.",
|
||||||
|
"Control Error": "Control Error",
|
||||||
|
"ControlErrorText1": "Control is not enabled",
|
||||||
|
"ControlErrorText2": "Check your connection details. You may need to point the Base URL at port 8000 or 80. Check your authentication info.",
|
||||||
|
"NotAuthorizedText1": "Not Authorized, Submit init command with \"auth\",\"ke\", and \"uid\"",
|
||||||
|
"Fields cannot be empty": "Fields cannot be empty",
|
||||||
|
"AccountEditText1": "Could not edit. Refresh page if problem continues.",
|
||||||
|
"Not an Administrator Account": "Not an Administrator Account",
|
||||||
|
"superAdminText": "\"super.json\" does not exist. Please rename \"super.sample.json\" to \"super.json\".",
|
||||||
|
"Enter this code to proceed": "Enter this code to proceed",
|
||||||
|
"FactorAuthText1": "The code will only be active for 15 minutes. If you login again the timer will be reset to 15 minutes with the same code.",
|
||||||
|
"monitorEditText1": "Invalid Data, Check to see this is a valid import string.",
|
||||||
|
"monitorEditText2": "Invalid Details String. Check to see it is a JSON string and not a regular object being passed.",
|
||||||
|
"Monitor Updated by user": "Monitor Updated by user.",
|
||||||
|
"Monitor Added by user": "Monitor Added by user.",
|
||||||
|
"monitorGetText1": "incomplete request, remove last slash in URL or put acceptable value.",
|
||||||
|
"Monitor mode changed": "Monitor mode changed",
|
||||||
|
"Reset Timer": "Reset Timer",
|
||||||
|
"Monitor mode is already": "Monitor mode is already",
|
||||||
|
"Monitor or Key does not exist.": "Monitor or Key does not exist.",
|
||||||
|
"No Group with this key exists": "No Group with this key exists",
|
||||||
|
"Trigger Successful": "Trigger Successful",
|
||||||
|
"No such file": "No such file",
|
||||||
|
"modifyVideoText1": "Method doesn't exist. Check to make sure that the last value of the URL is not blank.",
|
||||||
|
"CPU indicator will not work. Continuing...": "CPU indicator will not work. Continuing...",
|
||||||
|
"startUpText0": "size check for videos",
|
||||||
|
"startUpText1": "end of size check for videos",
|
||||||
|
"startUpText2": "all users checked, wait to close open files and remove files over user limit",
|
||||||
|
"startUpText3": "waiting to give unfinished video check some time. 3 seconds.",
|
||||||
|
"startUpText4": "starting all monitors set to watch and record",
|
||||||
|
"startUpText5": "Shinobi is ready.",
|
||||||
|
"Migrator": "Migrator",
|
||||||
|
"Host Type": "Host Type",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Dashboard Language": "Dashboard Language",
|
||||||
|
"File Not Found": "File Not Found",
|
||||||
|
"File Not Found in Filesystem": "File Not Found in Filesystem",
|
||||||
|
"File Not Found in Database": "File Not Found in Database",
|
||||||
|
"No Monitor Exists with this ID.": "No Monitor Exists with this ID.",
|
||||||
|
"Cannot watch a monitor that isn't running.": "Cannot watch a monitor that isn't running.",
|
||||||
|
"Not Permitted": "Not Permitted",
|
||||||
|
"notPermitted1": "This action is not permitted by the administrator of your account.'",
|
||||||
|
"Not Authorized": "Not Authorized",
|
||||||
|
"Generate Subtitles": "Generate Subtitles",
|
||||||
|
"Video Limit":"Video Limit",
|
||||||
|
"Preview":"Preview",
|
||||||
|
"Websocket Connected":"Websocket Connected",
|
||||||
|
"Websocket Disconnected":"Websocket Disconnected",
|
||||||
|
"New Authentication Token":"New Authentication Token",
|
||||||
|
"All Logs":"All Logs",
|
||||||
|
"For Group":"For Group",
|
||||||
|
"Basic Authentication":"Basic Authentication",
|
||||||
|
"Superuser Logs":"Superuser Logs",
|
||||||
|
"Authentication Failed":"Authentication Failed",
|
||||||
|
"Max Number of Cameras":"Max Number of Cameras",
|
||||||
|
"Can edit Max Storage":"Can edit Max Storage",
|
||||||
|
"Can edit Max Days":"Can edit Max Days",
|
||||||
|
"in Days":"in Days",
|
||||||
|
"Can edit how long to keep Logs":"Can edit how long to keep Logs",
|
||||||
|
"Can use Admin Panel":"Can use Admin Panel",
|
||||||
|
"Can use WebDAV":"Can use WebDAV",
|
||||||
|
"Can use LDAP":"Can use LDAP",
|
||||||
|
"Can edit how long to keep Events":"Can edit how long to keep Events",
|
||||||
|
"Leave blank for unlimited":"Leave blank for unlimited",
|
||||||
|
"Limited":"Limited",
|
||||||
|
"All Privileges":"All Privileges",
|
||||||
|
"LDAP":"LDAP",
|
||||||
|
"LDAP Success":"LDAP Success",
|
||||||
|
"LDAP User Authenticated":"LDAP User Authenticated",
|
||||||
|
"LDAP User is New":"LDAP User is New",
|
||||||
|
"Creating New Account":"Creating New Account",
|
||||||
|
"bindDN":"bindDN",
|
||||||
|
"Bind Credentials":"Bind Credentials (Password)",
|
||||||
|
"Search Base":"Search Base",
|
||||||
|
"Configuration":"Configuration",
|
||||||
|
"Blank for No Change":"Blank for No Change",
|
||||||
|
"Pop":"Pop",
|
||||||
|
"Recording FPS Change on Start":"Recording FPS Change on Start",
|
||||||
|
"Save Frames to Events":"Save Frames to Events",
|
||||||
|
"Search Filter":"Search Filter",
|
||||||
|
"h264_cuvid": "H.264 CUVID",
|
||||||
|
"hevc_cuvid": "H.265 CUVID",
|
||||||
|
"mjpeg_cuvid": "MJPEG CUVID",
|
||||||
|
"mpeg4_cuvid": "MPEG4 CUVID",
|
||||||
|
"h264_qsv": "H.264 (Quick Sync Video)",
|
||||||
|
"hevc_qsv": "H.265 (Quick Sync Video)",
|
||||||
|
"vp8_qsv": "VP8 (Quick Sync Video)",
|
||||||
|
"mpeg2_qsv": "MPEG2 (Quick Sync Video)",
|
||||||
|
"h264_vaapi": "H.264 VA-API (Intel HW Accel)",
|
||||||
|
"h264_nvenc": "H.264 NVENC (NVIDIA HW Accel)",
|
||||||
|
"hevc_nvenc": "H.265 NVENC (NVIDIA HW Accel)",
|
||||||
|
"hevc_vaapi": "H.265 VA-API (Intel HW Accel)",
|
||||||
|
"vp8_cuvid": "VP8 NVENC (NVIDIA HW Accel)",
|
||||||
|
"vp9_cuvid": "VP9 NVENC (NVIDIA HW Accel)",
|
||||||
|
"hwaccel": "Acceleration Engine",
|
||||||
|
"hwaccel_vcodec": "Video Decoder",
|
||||||
|
"hwaccel_device": "HWAccel Device",
|
||||||
|
"Get Logs to Client": "Get Logs to Client",
|
||||||
|
"Hardware Accelerated": "Hardware Accelerated",
|
||||||
|
"Accelerator": "Accelerator",
|
||||||
|
"qsv": "qsv",
|
||||||
|
"dxva2": "dxva2 (DirectX Video, Windows)",
|
||||||
|
"vdpau": "vdpau",
|
||||||
|
"vaapi": "vaapi (VA-API)",
|
||||||
|
"vda": "vda (Apple VDA Hardware Acceleration)",
|
||||||
|
"videotoolbox": "videotoolbox",
|
||||||
|
"cuvid": "cuvid (NVIDIA NVENC)",
|
||||||
|
"Main": "Main",
|
||||||
|
"Storage Location": "Storage Location",
|
||||||
|
"Recommended": "Recommended",
|
||||||
|
"Please Wait for Completion": "Please Wait for Completion, Depending on the number of files selected this may take some time. Refresh to check again.",
|
||||||
|
"flv": "flv",
|
||||||
|
"FLV": "FLV",
|
||||||
|
"FLV Stream Type": "FLV Stream Type",
|
||||||
|
"Link Shinobi": "Link Shinobi",
|
||||||
|
"Show Stream HUD":"Show Stream HUD",
|
||||||
|
"Call Method":"Call Method",
|
||||||
|
"Gender":"Gender",
|
||||||
|
"Emotion":"Emotion",
|
||||||
|
"Age":"Age",
|
||||||
|
"Object":"Object",
|
||||||
|
"Uniform":"Uniform",
|
||||||
|
"Pose":"Pose",
|
||||||
|
"Male":"Male",
|
||||||
|
"Female":"Female",
|
||||||
|
"Channel":"Channel",
|
||||||
|
"Stream Key":"Stream Key",
|
||||||
|
"Server URL":"Server URL",
|
||||||
|
"Video Bit Rate":"Video Bit Rate",
|
||||||
|
"Audio Bit Rate":"Audio Bit Rate",
|
||||||
|
"RTMP Stream Flags":"RTMP Stream Flags",
|
||||||
|
"RTMP Stream":"RTMP Stream",
|
||||||
|
"Stream Channel":"Stream Channel",
|
||||||
|
"Confidence":"Confidence",
|
||||||
|
"Map":"Map",
|
||||||
|
"Add Map":"Add Map",
|
||||||
|
"Add Input Feed":"Add Input Feed",
|
||||||
|
"Add Channel":"Add Channel",
|
||||||
|
"Automatic":"Automatic",
|
||||||
|
"Max Latency":"Max Latency",
|
||||||
|
"Loop Stream":"Loop Stream",
|
||||||
|
"Object Tag":"Object Tag",
|
||||||
|
"Noise Filter":"Noise Filter",
|
||||||
|
"Noise Filter Range":"Noise Filter Range",
|
||||||
|
"TV Channel":"TV Channel",
|
||||||
|
"Channel ID":"Channel ID",
|
||||||
|
"TV Channel ID":"TV Channel ID",
|
||||||
|
"TV Channel Group":"TV Channel Group",
|
||||||
|
"Emotion Average":"Emotion Average",
|
||||||
|
"Show Regions of Interest":"Show Regions of Interest",
|
||||||
|
"Confidence of Detection":"Confidence of Detection",
|
||||||
|
"Edit Selected":"Edit Selected",
|
||||||
|
"Copy Settings":"Copy Settings",
|
||||||
|
"Copy to Settings":"Copy to Settings",
|
||||||
|
"Copy Group Settings":"Copy Group Settings",
|
||||||
|
"Copy Connection Settings":"Copy Connection Settings",
|
||||||
|
"Copy Custom Settings":"Copy Custom Settings",
|
||||||
|
"Copy Logging Settings":"Copy Logging Settings",
|
||||||
|
"Copy JPEG API Settings":"Copy JPEG API Settings",
|
||||||
|
"Copy Input Settings":"Copy Input Settings",
|
||||||
|
"Copy Stream Settings":"Copy Stream Settings",
|
||||||
|
"Copy Stream Channel Settings":"Copy Stream Channel Settings",
|
||||||
|
"Copy Recording Settings":"Copy Recording Settings",
|
||||||
|
"Copy Detector Settings":"Copy Detector Settings",
|
||||||
|
"Monitors to Copy to":"Monitors to Copy to",
|
||||||
|
"Notification Sound":"Notification Sound",
|
||||||
|
"Alert Sound":"Alert Sound",
|
||||||
|
"Alert Sound Delay":"Alert Sound Delay",
|
||||||
|
"powerVideoEventLimit":"You have set a high event limit. Are you sure you want to make this request?",
|
||||||
|
"There are no monitors that you can view with this account.":"There are no monitors that you can view with this account.",
|
||||||
|
"Use Built-In":"Use Built-In"
|
||||||
|
}
|
|
@ -0,0 +1,666 @@
|
||||||
|
{
|
||||||
|
"\"No Motion\" Detector": "\"Aucun Mouvement\" Détecteur De",
|
||||||
|
"# of Allow MJPEG Clients": "# of Allow MJPEG Clients <small>0 for infinite</small>",
|
||||||
|
"180 Degrees": "180 Degrés",
|
||||||
|
"2-Factor Authentication": "Une Authentification À 2 Facteurs",
|
||||||
|
"90 Clockwise": "90 dans le sens des Aiguilles",
|
||||||
|
"90 Clockwise and Vertical Flip": "90 vers la gauche et Vertical Flip",
|
||||||
|
"90 Counter Clockwise and Vertical Flip (default)": "90 dans le sens antihoraire et la rotation Verticale (par défaut)",
|
||||||
|
"API": "API",
|
||||||
|
"API Key": "Clé API",
|
||||||
|
"API Key Added": "Clé API Ajouté",
|
||||||
|
"API Key Deleted": "API Clé Supprimée",
|
||||||
|
"API Keys": "Clés API",
|
||||||
|
"APIKeyAddedText": "Vous pouvez utiliser cette clé maintenant.",
|
||||||
|
"APIKeyDeletedText": "Clé a été supprimé. Elle ne fonctionnera plus.",
|
||||||
|
"ASC": "ASC",
|
||||||
|
"Accelerator": "Accélérateur",
|
||||||
|
"Account Info": "Les Informations De Compte",
|
||||||
|
"AccountEditText1": "Ne pouvait pas modifier. Actualiser la page si le problème persiste.",
|
||||||
|
"Accounts": "Comptes",
|
||||||
|
"Action for Selected": "Action Sélectionnés",
|
||||||
|
"Add": "Ajouter",
|
||||||
|
"Add Channel": "Ajouter Un Canal",
|
||||||
|
"Add Input Feed": "Ajoutez D'Entrée D'Alimentation",
|
||||||
|
"Add Map": "Ajouter La Carte",
|
||||||
|
"Add Monitor": "Ajouter Moniteur",
|
||||||
|
"Add New": "Ajouter De Nouveaux",
|
||||||
|
"Admin": "Admin",
|
||||||
|
"Advanced": "Avancé",
|
||||||
|
"Again": "Encore",
|
||||||
|
"Age": "L'âge",
|
||||||
|
"All Logs": "Tous Les Journaux",
|
||||||
|
"All Monitors": "Tous Les Moniteurs",
|
||||||
|
"All Monitors and Privileges": "Tous les Moniteurs et Privilèges",
|
||||||
|
"All Privileges": "Tous Les Privilèges",
|
||||||
|
"All Warnings": "Tous Les Avertissements",
|
||||||
|
"Allow Next Command": "Permettre Prochaine Commande <small>en quelques Minutes</small>",
|
||||||
|
"Allow Next Email": "Permettre Prochain Email <small>en quelques Minutes</small>",
|
||||||
|
"Allow Next Trigger": "Permettre à Côté de Déclenchement <small>en Millisecondes</small>",
|
||||||
|
"Allowed IPs": "Permis IPs",
|
||||||
|
"Analyzation Duration": "Analyzation Durée",
|
||||||
|
"Archive": "Archive",
|
||||||
|
"Are you sure?": "Êtes-vous sûr?",
|
||||||
|
"Audio Bit Rate": "Le Débit Binaire Audio",
|
||||||
|
"Audio Codec": "Codec Audio",
|
||||||
|
"Authenticate": "Authentifier",
|
||||||
|
"Authentication Failed": "Échec De L'Authentification",
|
||||||
|
"Auto": "Auto",
|
||||||
|
"Automatic": "Automatique",
|
||||||
|
"Autosave": "Autosave",
|
||||||
|
"Base64 over Websocket": "Base64 sur Websocket",
|
||||||
|
"Basic Authentication": "L'Authentification De Base",
|
||||||
|
"Bind Credentials": "Lier Les Informations D'Identification (Mot De Passe)",
|
||||||
|
"Blank for No Change": "Vide pour Pas Changer",
|
||||||
|
"Bottom Left": "En Bas À Gauche",
|
||||||
|
"Bottom Right": "En Bas À Droite",
|
||||||
|
"Browser Console Log": "Le Navigateur De La Console De Log",
|
||||||
|
"Buffer Preview": "Tampon Aperçu",
|
||||||
|
"CPU": "CPU",
|
||||||
|
"CPU indicator will not work. Continuing...": "CPU indicateur ne fonctionnera pas. Continue...",
|
||||||
|
"CSS": "CSS <small>Style de votre tableau de bord.</small>",
|
||||||
|
"Calendar": "Calendrier",
|
||||||
|
"Call Method": "Appel De La Méthode",
|
||||||
|
"Camera Password": "Mot De Passe De La Caméra",
|
||||||
|
"Camera Username": "Nom D'Utilisateur De La Caméra",
|
||||||
|
"Camera is not recording": "Appareil photo n'est pas de l'enregistrement",
|
||||||
|
"Camera is not streaming": "La caméra n'est pas en streaming",
|
||||||
|
"CameraNotRecordingText": "Les paramètres peuvent être incompatibles. Vérifier les encodeurs. Le redémarrage...",
|
||||||
|
"Can Authenticate Websocket": "Peut Authentifier Websocket",
|
||||||
|
"Can Control Monitors": "Peut Moniteurs De Contrôle",
|
||||||
|
"Can Delete Videos": "Pouvez Supprimer Des Vidéos",
|
||||||
|
"Can Delete Videos and Events": "Pouvez Supprimer des Vidéos et des Événements",
|
||||||
|
"Can Edit Monitor": "Pouvez Modifier Moniteur",
|
||||||
|
"Can Get Logs": "Pouvez Obtenir Les Journaux",
|
||||||
|
"Can Get Monitors": "Pouvez Obtenir Des Moniteurs",
|
||||||
|
"Can View Monitor": "Peut Moniteur De Vue",
|
||||||
|
"Can View Snapshots": "Peut Afficher Des Instantanés",
|
||||||
|
"Can View Streams": "Peut Afficher Des Flux",
|
||||||
|
"Can View Videos": "Peut Visionner Des Vidéos",
|
||||||
|
"Can View Videos and Events": "Pouvez Visualiser des Vidéos et des Événements",
|
||||||
|
"Can edit Max Days": "Pouvez éditer Max Jours",
|
||||||
|
"Can edit Max Storage": "Pouvez éditer Max de Stockage",
|
||||||
|
"Can edit how long to keep Events": "Pouvez modifier la durée de conservation des Événements",
|
||||||
|
"Can edit how long to keep Logs": "Pouvez modifier la durée de conservation des Journaux d'",
|
||||||
|
"Can use Admin Panel": "Pouvez utiliser le Panneau d'administration",
|
||||||
|
"Can use LDAP": "Peut utiliser le protocole LDAP",
|
||||||
|
"Can use WebDAV": "Pouvez utiliser WebDAV",
|
||||||
|
"Can't Connect": "Ne peut pas se Connecter",
|
||||||
|
"Cannot watch a monitor that isn't running.": "Impossible de regarder un moniteur qui n'est pas en cours d'exécution.",
|
||||||
|
"Center": "Centre d' <small>Adresse URL</small>",
|
||||||
|
"Channel": "Canal",
|
||||||
|
"Channel ID": "ID de canal",
|
||||||
|
"Chat on Discord": "Chat sur la Discorde",
|
||||||
|
"Check": "Vérifier",
|
||||||
|
"Check Signal Interval": "Vérifier le Signal de l'Intervalle <small>en Minutes</small>",
|
||||||
|
"Check for Motion First": "Vérifier le Mouvement de la Première",
|
||||||
|
"Close": "Fermer",
|
||||||
|
"Closed": "Fermé",
|
||||||
|
"Command": "Commande",
|
||||||
|
"Command on Trigger": "Commande sur la Gâchette",
|
||||||
|
"Complete Stream URL": "Compléter l'URL du Flux",
|
||||||
|
"Confidence": "La confiance",
|
||||||
|
"Confidence of Detection": "La confiance de Détection",
|
||||||
|
"Configuration": "Configuration",
|
||||||
|
"Confirm": "Confirmer",
|
||||||
|
"Connected": "Connecté",
|
||||||
|
"Connection": "Connexion",
|
||||||
|
"Connection Type": "Type De Connexion",
|
||||||
|
"Control": "Contrôle",
|
||||||
|
"Control Error": "Erreur De Contrôle De La",
|
||||||
|
"ControlErrorText1": "Le contrôle n'est pas activé",
|
||||||
|
"Controllable": "Contrôlable",
|
||||||
|
"Copy Connection Settings": "Copie Des Paramètres De Connexion",
|
||||||
|
"Copy Custom Settings": "Copie Des Paramètres Personnalisés",
|
||||||
|
"Copy Detector Settings": "Copie Réglages Du Détecteur",
|
||||||
|
"Copy Group Settings": "Copier Les Paramètres De Groupe",
|
||||||
|
"Copy Input Settings": "Copier Les Paramètres D'Entrée",
|
||||||
|
"Copy Logging Settings": "Copie Des Paramètres De Journalisation",
|
||||||
|
"Copy Recording Settings": "Copier Les Paramètres D'Enregistrement",
|
||||||
|
"Copy Settings": "Paramètres De Copie",
|
||||||
|
"Copy Stream Channel Settings": "Copie De Flux De Paramètres De Canal",
|
||||||
|
"Copy Stream Settings": "Copier Les Paramètres De Flux",
|
||||||
|
"Copy to Settings": "Copie des Paramètres de",
|
||||||
|
"Country of Plates": "Pays de Plaques",
|
||||||
|
"Counts of Motion": "Comtes de Mouvement",
|
||||||
|
"Creating New Account": "La Création D'Un Nouveau Compte",
|
||||||
|
"Current": "Actuel",
|
||||||
|
"Currently viewing": "Visualisez actuellement",
|
||||||
|
"Custom": "Personnalisé",
|
||||||
|
"Custom Base URL": "Base d'URL personnalisée <small>Laissez le champ vide pour utiliser l'Hôte de l'URL</small>",
|
||||||
|
"DB Lost.. Retrying..": "Base De Données Perdues.. Réessayer..",
|
||||||
|
"DESC": "DESC",
|
||||||
|
"Dashboard": "Tableau de bord",
|
||||||
|
"Dashboard Language": "Langue Du Tableau De Bord",
|
||||||
|
"Dashcam": "Dashcam",
|
||||||
|
"Dashcam (Streamer v2)": "Dashcam (Streamer v2)",
|
||||||
|
"Date Range": "La Plage De Dates",
|
||||||
|
"Debug": "Debug",
|
||||||
|
"Default": "Par défaut",
|
||||||
|
"Delete": "Supprimer",
|
||||||
|
"Delete Filter": "Supprimer Le Filtre",
|
||||||
|
"Delete Matches": "Supprimer Les Matchs",
|
||||||
|
"Delete Monitor": "Supprimer Moniteur",
|
||||||
|
"Delete Motionless Video": "Supprimer Immobile Vidéo",
|
||||||
|
"Delete Motionless Videos (Record)": "Supprimer Immobile Vidéos (Enregistrement)",
|
||||||
|
"Delete Selected Videos": "Supprimer La Sélection Des Vidéos",
|
||||||
|
"Delete Video": "Supprimer La Vidéo",
|
||||||
|
"Delete selected": "Supprimer la sélection",
|
||||||
|
"DeleteMonitorText": "Voulez-vous supprimer ce moniteur? Vous ne pouvez pas le récupérer. Les fichiers de cet ID restera dans le système de fichiers. Si vous choisissez de recréer un moniteur avec le même ID, les vidéos et les événements deviennent visibles dans le tableau de bord.",
|
||||||
|
"DeleteMonitorsText": "Voulez-vous supprimer ces moniteurs? Vous ne pouvez pas les récupérer. Les fichiers de ces Identifiants de rester dans le système de fichiers. Si vous choisissez de recréer un moniteur avec un de l'IDs, les vidéos et les événements deviennent visibles dans le tableau de bord.",
|
||||||
|
"DeleteSelectedVideosMsg": "Voulez-vous supprimer ces vidéos? Vous ne pouvez pas les récupérer.",
|
||||||
|
"DeleteVideoMsg": "Voulez-vous supprimer cette vidéo? Vous ne pouvez pas le récupérer.",
|
||||||
|
"Deleted": "Supprimé",
|
||||||
|
"Detect Objects": "Détecter les Objets <small class=\"\">Voir ci-dessous</small>",
|
||||||
|
"Detector": "Détecteur de",
|
||||||
|
"Detector Buffer": "Détecteur De Tampon",
|
||||||
|
"Detector Flags": "Détecteur De Drapeaux",
|
||||||
|
"Detector Grouping": "Détecteur de Groupement <small>d'Ajouter des groupes de <b>Paramètres</b></small>",
|
||||||
|
"Detector Rate": "Détecteur de Taux <small>(FPS)</small>",
|
||||||
|
"DetectorText": "<p>Lorsque les zones Largeur et Hauteur sont affichés, vous devriez les mettre à 640x480 ou ci-dessous. Cela permettra d'optimiser la vitesse de lecture d'images.</p>",
|
||||||
|
"Disable Night Vision": "Désactiver la Vision de Nuit <small>Adresse URL</small>",
|
||||||
|
"Disable Nightvision": "Désactiver Nightvision",
|
||||||
|
"Disabled": "Désactivé",
|
||||||
|
"Documentation": "La Documentation",
|
||||||
|
"Don't show this anymore": "Ne pas afficher plus",
|
||||||
|
"Double Quote Directory": "Devis Double Répertoire de <small>Certains répertoires sont séparés par des espaces. L'utilisation de ce peut se bloquer certains appareils photo.</small>",
|
||||||
|
"Down": "Bas <small>Adresse URL</small>",
|
||||||
|
"Down Stop": "Vers le bas Arrêter <small>Adresse URL</small>",
|
||||||
|
"Download": "Télécharger",
|
||||||
|
"EU": "L'UE",
|
||||||
|
"Edit": "Modifier",
|
||||||
|
"Edit Selected": "Modifier Les",
|
||||||
|
"Email": "E-mail",
|
||||||
|
"Email Details": "E-Mail Les Détails",
|
||||||
|
"Email on No Motion": "E-mail sur \"Aucun Mouvement\"",
|
||||||
|
"Email on Trigger": "E-mail sur la Gâchette <small>e-Mails passent à la principale du titulaire de compte de connexion l'adresse.</small>",
|
||||||
|
"Emotion": "L'émotion",
|
||||||
|
"Emotion Average": "L'Émotion De La Moyenne",
|
||||||
|
"Enable": "Activer",
|
||||||
|
"Enable Night Vision": "Activer la Vision Nocturne <small>Adresse URL</small>",
|
||||||
|
"Enable Nightvision": "Activer La Vision Nocturne",
|
||||||
|
"Enabled": "Activé",
|
||||||
|
"End": "Fin",
|
||||||
|
"End Time": "Heure De Fin",
|
||||||
|
"Ended": "Terminé",
|
||||||
|
"Enlarge": "Agrandir",
|
||||||
|
"Enter this code to proceed": "Entrez ce code pour procéder",
|
||||||
|
"Equal to": "Égal à",
|
||||||
|
"Error Connecting": "Erreur Lors De La Connexion",
|
||||||
|
"Event": "L'événement",
|
||||||
|
"Event Limit": "Cas Limite",
|
||||||
|
"EventText1": "Déclenché un mouvement à",
|
||||||
|
"EventText2": "Pourrait pas l'email de l'image, le fichier n'est pas accessible",
|
||||||
|
"Events": "Les événements",
|
||||||
|
"Example": "Exemple",
|
||||||
|
"Execute Command": "Exécuter La Commande",
|
||||||
|
"Executed": "Exécuté",
|
||||||
|
"Export": "L'exportation",
|
||||||
|
"FFmpegCantStart": "FFmpeg ne Pouvait pas Commencer",
|
||||||
|
"FFmpegCantStartText": "Le moteur d'enregistrement pour cette caméra n'a pas pu démarrer. Il y a peut être quelque chose de mal avec votre configuration de la caméra. S'il y a des journaux autres que celui-ci, veuillez les poster dans les <b>Questions</b> sur Github.",
|
||||||
|
"FFmpegTip": "FFprobe est un simple flux multimédias de l'analyseur. Vous pouvez l'utiliser pour afficher toutes sortes d'informations sur les intrants, y compris la durée, taux d'armature, taille de l'image, etc.",
|
||||||
|
"FFprobe": "Sonde",
|
||||||
|
"FLV": "FLV",
|
||||||
|
"FLV Stream Type": "FLV Type de Flux",
|
||||||
|
"FactorAuthText1": "Le code ne sera actif pendant 15 minutes. Si vous vous connectez de nouveau la minuterie est réinitialisée à 15 minutes avec le même code.",
|
||||||
|
"Fatal": "Fatale",
|
||||||
|
"Fatal Maximum Reached": "Fatale Maximum Atteint, L'Arrêt De La Caméra.",
|
||||||
|
"FatalMaximumReachedText": "JPEG Erreur a été fatale.",
|
||||||
|
"Feed-in Image Height": "De rachat à la Hauteur de l'Image",
|
||||||
|
"Feed-in Image Width": "Alimentation sur la Largeur de l'Image",
|
||||||
|
"Female": "Femelle",
|
||||||
|
"Fields cannot be empty": "Les champs ne peut pas être vide",
|
||||||
|
"File Not Exist": "Le Fichier N'Existe Pas",
|
||||||
|
"File Not Found": "Fichier Non Trouvé",
|
||||||
|
"File Type": "Type De Fichier",
|
||||||
|
"FileNotExistText": "Impossible d'enregistrer non existant fichier. Quelque chose s'est mal passé.",
|
||||||
|
"Filename": "Filename",
|
||||||
|
"Filesize": "La taille du fichier",
|
||||||
|
"Filter ID": "Filtre ID",
|
||||||
|
"Filter Matches": "Filtre Correspond",
|
||||||
|
"Filter Name": "Nom Du Filtre",
|
||||||
|
"FilterMatchesText1": "Ce filtre a rencontré des conditions.",
|
||||||
|
"FilterMatchesText2": "les vidéos trouvées.",
|
||||||
|
"Filters": "Les filtres",
|
||||||
|
"Filters Updated": "Les Filtres Mis À Jour",
|
||||||
|
"FiltersUpdatedText": "Vos modifications ont été enregistrées et appliquées.",
|
||||||
|
"Find Where": "Trouver Où",
|
||||||
|
"Fix": "Fix",
|
||||||
|
"Fix Video": "Corriger La Vidéo",
|
||||||
|
"FixVideoMsg": "Voulez-vous corriger cette vidéo? Vous ne pouvez pas annuler cette action.",
|
||||||
|
"Flush PM2 Logs": "Rincer les PM2 Journaux",
|
||||||
|
"Font Path": "Le Chemin De Police",
|
||||||
|
"Font Size": "Taille De La Police",
|
||||||
|
"For Group": "Pour Le Groupe",
|
||||||
|
"Force Port": "La Force De Port",
|
||||||
|
"Found Devices": "Appareils Trouvés",
|
||||||
|
"Frame Rate": "Le Taux d'image <small>par seconde(FPS)</small>",
|
||||||
|
"Full Frame Detection": "Plein Cadre La Détection",
|
||||||
|
"Full Stream URL": "Complet de l'URL du Flux",
|
||||||
|
"Full URL Path": "Plein Chemin d'accès d'URL",
|
||||||
|
"Fullscreen": "Plein écran",
|
||||||
|
"Gender": "Genre",
|
||||||
|
"Generate Subtitles": "Générer Des Sous-Titres",
|
||||||
|
"Get Logs to Client": "Obtenir les Journaux du Client",
|
||||||
|
"Greater Than": "Plus De",
|
||||||
|
"Greater Than or Equal to": "Supérieure ou Égale à",
|
||||||
|
"Group Key": "La Clé De Groupe",
|
||||||
|
"Group Name": "Nom Du Groupe",
|
||||||
|
"Grouping": "Groupement <small>d'Ajouter des groupes de <b>Paramètres</b></small>",
|
||||||
|
"H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ",
|
||||||
|
"HLS (.m3u8)": "HLS (.m3u8)",
|
||||||
|
"HLS (includes Audio)": "HLS (Audio)",
|
||||||
|
"HLS Audio Encoder": "Encodeur Audio",
|
||||||
|
"HLS List Size": "La Taille De La Liste",
|
||||||
|
"HLS Live Start Index": "HLS Vivre Index de Début",
|
||||||
|
"HLS Preset": "Modèle Préréglé",
|
||||||
|
"HLS Segment Length": "La Longueur du Segment <small>en quelques Secondes</small>",
|
||||||
|
"HLS Start Number": "HLS Nombre de Départ",
|
||||||
|
"HLS Video Encoder": "Encodeur Vidéo",
|
||||||
|
"HTTP": "HTTP",
|
||||||
|
"HTTPS": "HTTPS",
|
||||||
|
"Hardware Accelerated": "L'Accélération Matérielle",
|
||||||
|
"Height": "Hauteur",
|
||||||
|
"Help": "Aider",
|
||||||
|
"Hide List": "Masquer La Liste",
|
||||||
|
"Hide Notes": "Masquer Les Notes",
|
||||||
|
"Host": "Accueil",
|
||||||
|
"Hotswap Modes (Watch-Only)": "Hotswap Modes (Watch)",
|
||||||
|
"How to Record": "Comment faire pour Enregistrer",
|
||||||
|
"IP Address": "Adresse IP",
|
||||||
|
"Identity": "Identité",
|
||||||
|
"IdentityText1": "C'est la façon dont le système permettra d'identifier les données pour ce flux. Vous ne pouvez pas modifier le <b>Moniteur ID</b> une fois que vous avez appuyé sur la touche enregistrer. Si vous le souhaitez, vous pouvez faire le <b>Moniteur ID</b> plus lisible par l'homme avant de continuer.",
|
||||||
|
"IdentityText2": "Vous pouvez dupliquer l'écran en modifiant le <b>Moniteur ID</b> , puis appuyez sur save. Vous <b>ne peut pas</b> utiliser l'ID d'un moniteur qui existe déjà ou qu'il permettra d'économiser plus que surveiller les informations de base de données.",
|
||||||
|
"Idle": "Inactif",
|
||||||
|
"Image Height": "La Hauteur De L'Image",
|
||||||
|
"Image Location": "Emplacement de l'Image <small>de Chemin d'accès Absolu ou laissez le champ vide pour utiliser mondiale</small>",
|
||||||
|
"Image Position": "La Position De L'Image",
|
||||||
|
"Image Width": "La Largeur De L'Image",
|
||||||
|
"Import": "L'importation",
|
||||||
|
"Import Monitor Configuration": "L'Importation De Configuration Du Moniteur De",
|
||||||
|
"ImportMonitorConfigurationText": "En faisant cela, vous overrwrite toutes les modifications ne sont pas enregistrées. Les modifications importées ne sera appliquée que lorsque vous appuyez sur <b>Enregistrer</b>.",
|
||||||
|
"ImportMultiMonitorConfigurationText": "En faisant cela, vous overrwrite tous les moniteurs avec des Id existant dans le fichier d'importation.",
|
||||||
|
"In": "Dans",
|
||||||
|
"Incorrect Settings Chosen": "Des Paramètres Incorrects Choisi",
|
||||||
|
"Indifference": "L'indifférence",
|
||||||
|
"Input": "Entrée",
|
||||||
|
"Input Feed": "Entrée D'Alimentation",
|
||||||
|
"Input Flags": "Entrée Des Drapeaux",
|
||||||
|
"Input Selector": "Sélecteur D'Entrée",
|
||||||
|
"Input Settings": "Les Paramètres D'Entrée",
|
||||||
|
"Input Type": "Type D'Entrée",
|
||||||
|
"InputText1": "Cette section indique Shinobi comment utiliser un flux. Pour des performances optimales, essayez de régler votre appareil photo les réglages internes. Trouvez les options suivantes et de les définir comme illustré. Pour trouver votre appareil photo vous pouvez utiliser le <b>construit en ONVIF Scanner</b> de Shinobi. Certaines caméras ONVIF nécessitent l'utilisation d'un outil de gestion pour modifier leurs paramètres internes. Si vous ne trouvez pas votre appareil, vous pouvez essayer <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">ONVIF le Gestionnaire de Périphériques de Windows</a>.",
|
||||||
|
"InputText2": "<ul><li><b>Framerate (FPS) :</b> Haut : 10 - 15 FPS, Faible : 2 à 5 FPS</li><li><b>I-frame interval :</b> 80</li><li><b>Taux de bits Type :</b> CBR (Constant Bit rate)</li><li><b>Débit binaire :</b> entre 256kbps - 500kbps</li></ul>",
|
||||||
|
"InputText3": "Si vous avez besoin d'aide pour déterminer ce type d'entrée de votre appareil photo vous pouvez prendre un coup d'oeil à la <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">Caméra Liste d'URLs</a> sur le Shinobi site web.",
|
||||||
|
"Invalid JSON": "Invalid JSON",
|
||||||
|
"InvalidJSONText": "Veuillez vous assurer que c'est une chaîne JSON valide pour les Shinobi de configuration du moniteur.",
|
||||||
|
"JPEG": "JPEG",
|
||||||
|
"JPEG (Auto Enables JPEG API)": "JPEG (Auto Permet JPEG API)",
|
||||||
|
"JPEG API": "JPEG API <small>Instantané (cgi-bin)</small>",
|
||||||
|
"JPEG Error": "JPEG Erreur",
|
||||||
|
"JPEG Mode": "Le Mode JPEG",
|
||||||
|
"JPEGErrorText": "Il y avait un problème dans l'obtention de données de votre appareil photo.",
|
||||||
|
"LDAP": "LDAP",
|
||||||
|
"LDAP Success": "LDAP Succès",
|
||||||
|
"LDAP User Authenticated": "LDAP de l'Utilisateur Authentifié",
|
||||||
|
"LDAP User is New": "Utilisateur LDAP est Nouveau",
|
||||||
|
"Leave blank for random.": "Laissez vide pour aléatoire.",
|
||||||
|
"Leave blank for unlimited": "Laissez vide pour un nombre illimité de",
|
||||||
|
"Left": "Gauche <small>Adresse URL</small>",
|
||||||
|
"Left Stop": "Butée gauche, <small>Adresse URL</small>",
|
||||||
|
"Less Than": "Moins De",
|
||||||
|
"Less Than or Equal to": "Inférieure ou Égale à",
|
||||||
|
"Like": "Comme",
|
||||||
|
"Limited": "Limitée",
|
||||||
|
"Link Shinobi": "Lien Shinobi",
|
||||||
|
"Lisence Plate Detector": "Lisence Détecteur De Plaque",
|
||||||
|
"List Toggle": "Liste De Bascule",
|
||||||
|
"Live Stream Toggle": "Live Stream De La Bascule",
|
||||||
|
"Live View": "Vue En Direct",
|
||||||
|
"Local": "Local",
|
||||||
|
"Log Level": "Le Niveau De Journal",
|
||||||
|
"Log Signal Event": "Journal du Signal d'Événements <small>côté Client seulement</small>",
|
||||||
|
"Logging": "La journalisation",
|
||||||
|
"Login": "Connexion",
|
||||||
|
"Logout": "Déconnexion",
|
||||||
|
"Logs": "Les journaux",
|
||||||
|
"Loop Stream": "Boucle De Flux",
|
||||||
|
"MB": "MO",
|
||||||
|
"MJPEG": "MJPEG",
|
||||||
|
"MP4 (copy, libx264, libx265)": "MP4 (copie, libx264, libx265)",
|
||||||
|
"MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)",
|
||||||
|
"MPEG-DASH (includes Audio)": "MPEG-DASH (Audio)",
|
||||||
|
"MailError": "MAIL d'ERREUR : impossible d'envoyer des e-mail, Vérifiez conf.json. En ignorant toutes les fonctionnalités en s'appuyant sur l'envoi.",
|
||||||
|
"Main": "Principal",
|
||||||
|
"Male": "Mâle",
|
||||||
|
"Manual": "Manuel",
|
||||||
|
"Map": "Carte",
|
||||||
|
"Matches": "Matchs",
|
||||||
|
"Max Latency": "Max Latence",
|
||||||
|
"Max Number of Cameras": "Le Nombre maximum de Caméras",
|
||||||
|
"Max Storage Amount": "Max de la Quantité de Stockage <small>en mo</small>",
|
||||||
|
"Mode": "Mode",
|
||||||
|
"Monitor": "Moniteur",
|
||||||
|
"Monitor Added by user": "Moniteur Ajoutés par l'utilisateur.",
|
||||||
|
"Monitor Capture Rate": "Surveiller les Taux de Capture <small>(FPS)</small>",
|
||||||
|
"Monitor Groups": "La Surveillance De Groupes",
|
||||||
|
"Monitor ID": "Moniteur ID",
|
||||||
|
"Monitor Idling": "Surveiller La Marche Au Ralenti",
|
||||||
|
"Monitor Name": "Nom De Moniteur",
|
||||||
|
"Monitor Settings": "Paramètres Du Moniteur",
|
||||||
|
"Monitor Stopped": "Moniteur Arrêté",
|
||||||
|
"Monitor Updated by user": "Surveiller les mises à Jour par l'utilisateur.",
|
||||||
|
"Monitor mode changed": "Le mode moniteur changé",
|
||||||
|
"Monitor mode is already": "Le mode Monitor est déjà",
|
||||||
|
"Monitor or Key does not exist.": "Le moniteur ou la Clé n'existe pas.",
|
||||||
|
"MonitorIdlingText": "Surveiller la session a été commandé au ralenti.",
|
||||||
|
"MonitorStoppedText": "Surveiller la session a été ordonné d'arrêter.",
|
||||||
|
"Monitors": "Les moniteurs",
|
||||||
|
"Monitors per row": "Surveille par ligne <small>de Montage</small>",
|
||||||
|
"Monitors to Copy to": "Les moniteurs de Copie à",
|
||||||
|
"Montage": "Montage",
|
||||||
|
"Motion GUI": "Motion GUI",
|
||||||
|
"Motion Meter": "Motion Compteur",
|
||||||
|
"Name": "Nom",
|
||||||
|
"New Authentication Token": "Nouveau Jeton D'Authentification",
|
||||||
|
"New Monitor": "Nouveau Moniteur",
|
||||||
|
"No": "Pas de",
|
||||||
|
"No Audio": "Pas D'Audio",
|
||||||
|
"No Data": "Pas De Données",
|
||||||
|
"No Events found for this video": "Aucun événement trouvé pour cette vidéo",
|
||||||
|
"No Group with this key exists": "Pas de Groupe avec cette clé existe",
|
||||||
|
"No Monitor Exists with this ID.": "Pas de Moniteur Existe à cet ID.",
|
||||||
|
"No Monitor Found, Ignoring Request": "Pas De Moniteur Trouvé, En Ignorant La Demande",
|
||||||
|
"No Monitors Selected": "Pas De Moniteurs Sélectionnés",
|
||||||
|
"No Rotation": "Pas De Rotation",
|
||||||
|
"No Videos Found": "Pas De Vidéos Trouvées",
|
||||||
|
"No such file": "Pas de tel fichier",
|
||||||
|
"NoMotionEmailText1": "Pas de Mouvement pour",
|
||||||
|
"NoMotionEmailText2": "Il n'y a pas été de tout mouvement détecté sur l'appareil photo pour",
|
||||||
|
"NoVideosFoundForDateRange": "Pas de Vidéos trouvées dans cette plage de dates. Essayez de définir la date de début de la plus en arrière.",
|
||||||
|
"Noise Filter": "Filtre De Bruit",
|
||||||
|
"Not Authorized": "Pas Autorisé",
|
||||||
|
"Not Connected": "Pas Connecté",
|
||||||
|
"Not Equal to": "Pas Égal à",
|
||||||
|
"Not In": "Pas Dans",
|
||||||
|
"Not Matches": "Pas De Matchs",
|
||||||
|
"Not Permitted": "Pas Autorisés",
|
||||||
|
"Not Saved": "Pas Enregistrées",
|
||||||
|
"Not an Administrator Account": "Pas un Compte d'Administrateur",
|
||||||
|
"NotAuthorizedText1": "Pas Autorisé, Soumettre commande init avec \"auth\",\"ke\", et \"uid\"",
|
||||||
|
"Notes": "Notes",
|
||||||
|
"NotesPlacholder": "Les commentaires que vous voulez quitter pour ce caméras de paramètres.",
|
||||||
|
"Number of Days to keep": "Nombre de Jours de conservation",
|
||||||
|
"ONVIF": "ONVIF",
|
||||||
|
"ONVIF Scanner": "ONVIF Scanner",
|
||||||
|
"ONVIFnote": "Découvrez ONVIF appareils sur les réseaux à l'extérieur de votre propre ou la laisser vide pour analyser votre réseau actuel. <br>Nom d'utilisateur et le Mot de passe peut être laissé en blanc.",
|
||||||
|
"Object": "Objet",
|
||||||
|
"Object Tag": "Balise Object",
|
||||||
|
"OpenCV Cascades": "OpenCV Cascades",
|
||||||
|
"Options": "Options",
|
||||||
|
"Order Streams": "Afin De Ruisseaux",
|
||||||
|
"Output Method": "Méthode De Sortie",
|
||||||
|
"Password": "Mot de passe",
|
||||||
|
"Password Again": "Mot De Passe À Nouveau",
|
||||||
|
"Passwords don't match": "Les mots de passe ne correspondent pas",
|
||||||
|
"Paste JSON here.": "Coller JSON ici.",
|
||||||
|
"Path": "Chemin",
|
||||||
|
"Permissions": "Les autorisations",
|
||||||
|
"Please Wait for Completion": "Veuillez Attendre la fin, Selon le nombre de fichiers sélectionnés, cela peut prendre un certain temps. Actualiser pour vérifier de nouveau.",
|
||||||
|
"Points": "Des Points <small>Lors de l'ajout de points de cliquer sur le bord du polygone.</small>",
|
||||||
|
"Pop": "Pop",
|
||||||
|
"Port": "Port",
|
||||||
|
"Pose": "Poser",
|
||||||
|
"Poseidon": "Poseidon",
|
||||||
|
"Position X": "Position X",
|
||||||
|
"Position Y": "Position Y",
|
||||||
|
"Power Video Viewer": "La Puissance Du Visualiseur Vidéo",
|
||||||
|
"Power Viewer": "Visionneuse De L'Alimentation",
|
||||||
|
"Preferences": "Préférences",
|
||||||
|
"Preset": "Preset",
|
||||||
|
"Preview": "Aperçu",
|
||||||
|
"Probe Size": "Longueur De La Sonde",
|
||||||
|
"Process Crashed for Monitor": "Le processus s'est Écrasé pour Surveiller",
|
||||||
|
"Process Unexpected Exit": "Processus Inattendu De Sortie",
|
||||||
|
"Profile": "Profil",
|
||||||
|
"Quality": "La qualité de l' <small>1 est Élevée, 23 est Faible</small>",
|
||||||
|
"Query": "Requête",
|
||||||
|
"RAM": "RAM",
|
||||||
|
"RTMP Stream": "Flux RTMP",
|
||||||
|
"RTMP Stream Flags": "Flux RTMP Drapeaux",
|
||||||
|
"RTSP": "RTSP",
|
||||||
|
"RTSP Transport": "RTSP de Transport",
|
||||||
|
"Range or Single": "Gamme ou Seul",
|
||||||
|
"Rate": "Taux <small>(FPS)</small>",
|
||||||
|
"Raw": "Raw",
|
||||||
|
"Raw H.264 Stream": "Raw H. 264 Flux",
|
||||||
|
"Recommended": "Recommandé",
|
||||||
|
"Record": "Enregistrement",
|
||||||
|
"Record File Type": "Enregistrement De Type De Fichier",
|
||||||
|
"Record Height": "Record De Hauteur",
|
||||||
|
"Record Video Filter": "Enregistrement Vidéo De Filtre",
|
||||||
|
"Record Width": "Enregistrement De Largeur",
|
||||||
|
"Recording": "Enregistrement",
|
||||||
|
"Recording FPS": "L'enregistrement de FPS",
|
||||||
|
"Recording FPS Change on Start": "Enregistrement FPS Changement sur Démarrer",
|
||||||
|
"Recording Flags": "L'Enregistrement Des Drapeaux",
|
||||||
|
"Recording Segment Interval": "Enregistrement Segment de l'Intervalle <small>en minutes</small>",
|
||||||
|
"Recording Timeout": "L'enregistrement de Délai d'attente <small>en Minutes</small>",
|
||||||
|
"Recording Timestamp": "L'Enregistrement D'Horodatage",
|
||||||
|
"Recording Watermark": "Enregistrement Filigrane",
|
||||||
|
"RecordingText": "Il est recommandé que vous définissez <b>Enregistrement de Type de Fichier</b> pour <b class=\"h_t_input h_t_jpeg h_t_socket\">WebM</b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">MP4</b> et <b>Vidéo Codec</b> pour <b class=\"h_t_input h_t_jpeg h_t_socket\">libvpx</b><b class=\"h_t_input h_t_h264 h_t_hls h_t_mp4\">copie ou </b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">libx264</b> parce que votre <b>Type d'Entrée</b> est définie sur <b class=\"h_t_text\"></b>.",
|
||||||
|
"Refresh List of Cascades": "Actualiser la Liste des Cascades",
|
||||||
|
"Region Editor": "Région De L'Éditeur",
|
||||||
|
"Region Name": "Nom De La Région",
|
||||||
|
"RegionNote": "Les Points ne sont enregistrées que lorsque vous appuyez sur <b>Enregistrer</b> sur les <b>Paramètres du Moniteur</b> de la fenêtre.",
|
||||||
|
"Regions": "Les régions",
|
||||||
|
"Remember Me": "Se Souvenir De Moi",
|
||||||
|
"Request": "Demande",
|
||||||
|
"Reset Timer": "Réinitialiser La Minuterie",
|
||||||
|
"Restart": "Redémarrer",
|
||||||
|
"Restart CRON": "Redémarrage du CRON",
|
||||||
|
"Restart Core": "Le Redémarrage De Base",
|
||||||
|
"Restarting Process": "Le Redémarrage Du Processus De",
|
||||||
|
"Retry Connection": "Nouvelle tentative de Connexion <small>Nombre de fois que le droit à l'échec</small>",
|
||||||
|
"Retrying...": "Réessayer...",
|
||||||
|
"Right": "Droit de l' <small>Adresse URL</small>",
|
||||||
|
"Right Stop": "Droit d'Arrêter <small>Adresse URL</small>",
|
||||||
|
"Rotate": "Faites tourner",
|
||||||
|
"Save": "Enregistrer",
|
||||||
|
"Save Directory": "Répertoire De Sauvegarde",
|
||||||
|
"Save Events to SQL": "Enregistrer les Événements dans le SQL",
|
||||||
|
"Save Frames to Events": "D'enregistrer les Images des Événements",
|
||||||
|
"Save Log in SQL": "Enregistrer le Journal dans SQL <small>Cela peut se remplir rapidement.</small>",
|
||||||
|
"Save as": "Enregistrer sous",
|
||||||
|
"Saved Filters": "Enregistré Filtres",
|
||||||
|
"Scan Settings": "Paramètres De Numérisation",
|
||||||
|
"Search": "Recherche",
|
||||||
|
"Search Base": "La Base De Recherche",
|
||||||
|
"Search Filter": "Filtre De Recherche",
|
||||||
|
"Secure": "Sécurisé",
|
||||||
|
"Send Frames": "Envoyer des Images <small>Pousser images à analyser</small>",
|
||||||
|
"Separate with commas, no spaces": "Séparés par des virgules, sans espace",
|
||||||
|
"Server URL": "URL du serveur",
|
||||||
|
"Set to Watch Only": "Mis à Regarder Seulement",
|
||||||
|
"Settings": "Paramètres",
|
||||||
|
"Settings Changed": "La Modification Des Réglages",
|
||||||
|
"SettingsChangedText": "Vos paramètres sont enregistrés et appliqués. Certains paramètres peuvent nécessiter une actualisation de cette page.",
|
||||||
|
"Shinobi": "Shinobi",
|
||||||
|
"Shinobi Streamer": "Shinobi Streamer",
|
||||||
|
"Show Logs": "Afficher Les Journaux D'",
|
||||||
|
"Show Regions of Interest": "Montrer les Régions d'Intérêt",
|
||||||
|
"Show Stream HUD": "Afficher les Flux de PALETTE",
|
||||||
|
"Silent": "Silencieux",
|
||||||
|
"Simple": "Simple",
|
||||||
|
"Size (mb)": "Taille (mo)",
|
||||||
|
"Snapshot": "Instantané",
|
||||||
|
"Snapshot Flags": "Instantané De Drapeaux",
|
||||||
|
"Snapshots": "Instantanés",
|
||||||
|
"Sort By": "Trier Par",
|
||||||
|
"Start": "Démarrer",
|
||||||
|
"Start Recording": "Démarrer L'Enregistrement",
|
||||||
|
"Start Time": "Heure De Début",
|
||||||
|
"Started": "Commencé",
|
||||||
|
"Status Indicator": "Indicateur De L'État De",
|
||||||
|
"Stop": "Arrêter",
|
||||||
|
"Stop URL": "Arrêter URL",
|
||||||
|
"Storage Location": "Emplacement De Stockage",
|
||||||
|
"Stream": "Flux",
|
||||||
|
"Stream Channel": "Canal De Flux De Données",
|
||||||
|
"Stream Flags": "Flux De Drapeaux",
|
||||||
|
"Stream Key": "Flux De Clé",
|
||||||
|
"Stream Timestamp": "Flux D'Horodatage",
|
||||||
|
"Stream Type": "Type De Flux",
|
||||||
|
"Stream Watermark": "Flux De Filigrane",
|
||||||
|
"Stream to YouTube": "Stream sur YouTube",
|
||||||
|
"Stream to YouTube Flags": "Stream sur YouTube Drapeaux",
|
||||||
|
"StreamText": "<p>Cette section permettra de désigner le flux primaire, de méthode et de ses paramètres. Ce flux sera affiché dans le tableau de bord. Si vous choisissez d'utiliser HLS, JPEG, MJPEG, alors vous pouvez consommer du courant à travers d'autres programmes.</p><p class=\"h_st_input h_st_jpeg\">JPEG flux essentiellement désactive le principal cours d'eau et les utilisations de l'instantané bin pour obtenir des images.</p>",
|
||||||
|
"Streamer": "Streamer",
|
||||||
|
"Streams": "Flux",
|
||||||
|
"Superuser": "Superutilisateur",
|
||||||
|
"Superuser Logs": "Superuser Journaux",
|
||||||
|
"Switch on for Still Image": "Interrupteur pour Toujours à l'Image",
|
||||||
|
"System": "Système",
|
||||||
|
"TCP": "TCP",
|
||||||
|
"TV Channel": "Chaîne de TÉLÉVISION",
|
||||||
|
"TV Channel Group": "Chaîne de TÉLÉVISION du Groupe",
|
||||||
|
"TV Channel ID": "Chaîne de TÉLÉVISION ID",
|
||||||
|
"Text Box Color": "Texte De La Boîte De Couleur",
|
||||||
|
"Text Color": "La Couleur Du Texte",
|
||||||
|
"Themes": "Thèmes",
|
||||||
|
"There are no monitors that you can view with this account.": "Il n'y a pas les moniteurs que vous pouvez afficher avec ce compte.",
|
||||||
|
"Time-lapse": "Time-lapse",
|
||||||
|
"Time-lapse Tool": "Time-lapse de l'Outil",
|
||||||
|
"Timeout": "Timeout",
|
||||||
|
"Timeout Reset on Next Motion": "Délai de Réinitialisation sur le Prochain Mouvement",
|
||||||
|
"Toggle Sidebar": "Basculer La Barre Latérale",
|
||||||
|
"Top Left": "En Haut À Gauche",
|
||||||
|
"Top Right": "En Haut À Droite",
|
||||||
|
"Traditional (Watch-Only, Includes Buffer)": "Traditionnel (Watch-Seulement, Comprend Tampon)",
|
||||||
|
"Traditional Recording": "Traditionnelle Enregistrement",
|
||||||
|
"Trigger Record": "Déclencheur D'Enregistrement",
|
||||||
|
"Trigger Successful": "Déclencheur De Succès",
|
||||||
|
"UDP": "UDP",
|
||||||
|
"URL": "URL",
|
||||||
|
"URL Stop Timeout": "URL Arrêter Délai <small>Run stop URL après X millisecondes</small>",
|
||||||
|
"US": "NOUS",
|
||||||
|
"Unable to Launch": "Impossible de Lancer",
|
||||||
|
"UnabletoLaunchText": "Veuillez enregistrer le nouveau moniteur en premier. Tentez ensuite de lancer la région de l'éditeur.",
|
||||||
|
"Uniform": "Uniforme",
|
||||||
|
"Up": "Jusqu' <small>Adresse URL</small>",
|
||||||
|
"Up Stop": "D'Arrêter <small>Adresse URL</small>",
|
||||||
|
"Update": "Mise à jour",
|
||||||
|
"Update to Development": "Mise à jour pour le Développement",
|
||||||
|
"Update to Master": "Mise à jour de Maître",
|
||||||
|
"Use Built-In": "Utilisez La Fonction De",
|
||||||
|
"Username": "Nom d'utilisateur",
|
||||||
|
"Value": "Valeur",
|
||||||
|
"Video": "Vidéo",
|
||||||
|
"Video Bit Rate": "Le Débit Binaire Vidéo",
|
||||||
|
"Video Codec": "Codec Vidéo",
|
||||||
|
"Video Filter": "Filtre Vidéo",
|
||||||
|
"Video Finished": "Vidéo Fini",
|
||||||
|
"Video Length (minutes) and Motion Count per video": "Durée de la vidéo (en minutes) et le Mouvement Comte par vidéo",
|
||||||
|
"Video Limit": "Vidéo Limite",
|
||||||
|
"Video Record Rate": "Vidéo vitesse d'Enregistrement <small>(IPS)</small>",
|
||||||
|
"Video Status": "État De La Vidéo",
|
||||||
|
"Video and Time Span (Minutes)": "La vidéo et la Durée (en Minutes)",
|
||||||
|
"Videos": "Vidéos",
|
||||||
|
"Videos List": "Liste Des Vidéos",
|
||||||
|
"Warning": "Avertissement",
|
||||||
|
"Watch": "Regarder",
|
||||||
|
"Watch Only": "Regarder Seulement",
|
||||||
|
"WebDAV": "WebDAV",
|
||||||
|
"WebM (libvpx)": "WebM (libvpx)",
|
||||||
|
"Webdav Error": "Webdav Erreur",
|
||||||
|
"WebdavErrorText": "Impossible d'enregistrer. Avez-vous rendre l'appareil dossiers à l'intérieur de votre choisi répertoire de sauvegarde?",
|
||||||
|
"Webhook": "Webhook",
|
||||||
|
"Webhook URL": "Webhook URL",
|
||||||
|
"Websocket": "Websocket",
|
||||||
|
"Websocket Connected": "Websocket Connecté",
|
||||||
|
"Websocket Disconnected": "Websocket Déconnecté",
|
||||||
|
"Width": "Largeur",
|
||||||
|
"Yes": "Oui",
|
||||||
|
"Zoom In": "Zoom Dans l' <small>Adresse URL</small>",
|
||||||
|
"Zoom In Stop": "Zoom Arrêter <small>Adresse URL</small>",
|
||||||
|
"Zoom Out": "Zoom <small>Adresse URL</small>",
|
||||||
|
"Zoom Out Stop": "Zoom Arrêter <small>Adresse URL</small>",
|
||||||
|
"a day": "un jour",
|
||||||
|
"a few seconds": "quelques secondes",
|
||||||
|
"a minute": "une minute",
|
||||||
|
"a month": "un mois",
|
||||||
|
"a year": "un an",
|
||||||
|
"aac": "aac",
|
||||||
|
"aac (Default)": "aac (par Défaut)",
|
||||||
|
"ac3": "ac3",
|
||||||
|
"ago": "il y a",
|
||||||
|
"an hour": "une heure",
|
||||||
|
"bindDN": "bindDN",
|
||||||
|
"blankPassword": "Laissez le champ vide pour garder le même mot de passe",
|
||||||
|
"clientStreamFailedattemptingReconnect": "Côté Client ctream échec de la vérification, d'essayer de se reconnecter.",
|
||||||
|
"confirmDeleteFilter": "Voulez-vous supprimer ce filtre? Vous ne pouvez pas le récupérer.",
|
||||||
|
"copy": "copie",
|
||||||
|
"cuvid": "cuvid (NVIDIA NVENC)",
|
||||||
|
"days": "jours",
|
||||||
|
"dropBoxSuccess": "Succès! Les fichiers enregistrés sur votre Dropbox.",
|
||||||
|
"dxva2": "dxva2 (Vidéo DirectX, Windows)",
|
||||||
|
"flv": "flv",
|
||||||
|
"for Global Access": "pour l'Accès Mondial",
|
||||||
|
"h264_cuvid": "H. 264 CUVID",
|
||||||
|
"h264_nvenc": "H. 264 NVENC (NVIDIA HW Accel)",
|
||||||
|
"h264_qsv": "H. 264 (Quick Sync Video)",
|
||||||
|
"h264_vaapi": "H. 264 VA-API (Intel HW Accel)",
|
||||||
|
"hevc_cuvid": "H. 265 CUVID",
|
||||||
|
"hevc_nvenc": "H. 265 NVENC (NVIDIA HW Accel)",
|
||||||
|
"hevc_qsv": "H. 265 (Quick Sync Video)",
|
||||||
|
"hevc_vaapi": "H. 265 VA-API (Intel HW Accel)",
|
||||||
|
"hours": "heures",
|
||||||
|
"hwaccel": "L'Accélération Du Moteur",
|
||||||
|
"hwaccel_device": "HWAccel Appareil",
|
||||||
|
"hwaccel_vcodec": "Décodeur Vidéo",
|
||||||
|
"in": "dans",
|
||||||
|
"in Days": "dans les Jours",
|
||||||
|
"libmp3lame": "libmp3lame",
|
||||||
|
"libopus": "libopus",
|
||||||
|
"libvorbis (Default)": "libvorbis (par Défaut)",
|
||||||
|
"libvpx (Default)": "libvpx (par Défaut)",
|
||||||
|
"libvpx-vp9": "libvpx-vp9",
|
||||||
|
"libx264": "libx264",
|
||||||
|
"libx264 (Default)": "libx264 (par Défaut)",
|
||||||
|
"libx265": "libx265",
|
||||||
|
"minutes": "minutes",
|
||||||
|
"mjpeg_cuvid": "MJPEG CUVID",
|
||||||
|
"modifyVideoText1": "La méthode n'existe pas. Assurez-vous que la dernière valeur de l'URL n'est pas vide.",
|
||||||
|
"monSavedButNotCopied": "Votre moniteur a été sauvé, mais pas copié sur un autre moniteur.",
|
||||||
|
"monitorEditFailedMaxReached": "Votre compte a atteint le nombre maximum de caméras qui peuvent être créés. Parler à un administrateur si vous souhaitez que cela a changé.",
|
||||||
|
"monitorEditText1": "Des Données non valides, Vérifiez la validité de l'importation de la chaîne.",
|
||||||
|
"monitorEditText2": "Non Valide Les Détails De La Chaîne. Vérifiez pour voir c'est une chaîne JSON et non pas un objet normal d'être passé.",
|
||||||
|
"monitorGetText1": "demande incomplète, supprimer le dernier slash dans l'URL ou mettre valeur acceptable.",
|
||||||
|
"months": "mois",
|
||||||
|
"mpeg2_qsv": "MPEG2 (Quick Sync Video)",
|
||||||
|
"mpeg4_cuvid": "MPEG4 CUVID",
|
||||||
|
"noSpecialCharacters": "Pas d'espaces ni de caractères spéciaux.",
|
||||||
|
"notPermitted1": "Cette action n'est pas autorisée par l'administrateur de votre compte\".",
|
||||||
|
"on": "sur",
|
||||||
|
"on Error": "en cas d'Erreur",
|
||||||
|
"powerVideoEventLimit": "Vous avez une grande manifestation limite. Êtes-vous sûr que vous voulez faire cette demande?",
|
||||||
|
"qsv": "qsv",
|
||||||
|
"startUpText0": "vérification de la taille pour les vidéos",
|
||||||
|
"startUpText1": "fin de la vérification de la taille pour les vidéos",
|
||||||
|
"startUpText2": "tous les utilisateurs vérifiés, attendre pour fermer les fichiers ouverts et supprimer les fichiers de plus de limite de l'utilisateur",
|
||||||
|
"startUpText3": "d'attente pour donner inachevé vidéo de vérifier un certain temps. 3 secondes.",
|
||||||
|
"startUpText4": "départ tous les moniteurs ensemble pour regarder et enregistrer",
|
||||||
|
"startUpText5": "Shinobi est prêt.",
|
||||||
|
"superAdminText": "\"super.json\" n'existe pas. Veuillez renommer \"super.de l'échantillon.json\" à \"super.json\".",
|
||||||
|
"total": "total",
|
||||||
|
"updateKeyText1": "\"updateKey\" est manquant à partir de \"conf.json\", ne peut pas faire les mises à jour de cette façon jusqu'à ce que vous l'ajouter.",
|
||||||
|
"updateKeyText2": "\"updateKey\" est incorrecte.",
|
||||||
|
"vaapi": "vaapi (VA-API)",
|
||||||
|
"vda": "vda (Apple VDA l'Accélération Matérielle)",
|
||||||
|
"vdpau": "vdpau",
|
||||||
|
"videotoolbox": "videotoolbox",
|
||||||
|
"vp8_cuvid": "VP8 NVENC (NVIDIA HW Accel)",
|
||||||
|
"vp8_qsv": "VP8 (Quick Sync Video)",
|
||||||
|
"vp9_cuvid": "VP9 NVENC (NVIDIA HW Accel)",
|
||||||
|
"years": "ans"
|
||||||
|
}
|
|
@ -0,0 +1,496 @@
|
||||||
|
{
|
||||||
|
"\"No Motion\" Detector": "\"動き\"の検出器",
|
||||||
|
"# of Allow MJPEG Clients": "# of Allow MJPEG Clients <small>0 for infinite</small>",
|
||||||
|
"180 Degrees": "180度",
|
||||||
|
"2-Factor Authentication": "2要素認証",
|
||||||
|
"90 Clockwise": "時計回りに90",
|
||||||
|
"90 Clockwise and Vertical Flip": "90右回転、上下反転",
|
||||||
|
"90 Counter Clockwise and Vertical Flip (default)": "90反時計方向に回し、上下反転(デフォルト)",
|
||||||
|
"API": "API",
|
||||||
|
"API Key Added": "APIキーの追加",
|
||||||
|
"API Key Deleted": "APIキーの削除",
|
||||||
|
"API Keys": "APIキー",
|
||||||
|
"APIKeyAddedText": "にお使いいただけキーです。",
|
||||||
|
"APIKeyDeletedText": "キーが削除されました。 ではなくなります。",
|
||||||
|
"ASC": "ASC",
|
||||||
|
"Account Info": "アカウント情報",
|
||||||
|
"AccountEditText1": "な編集できるようになります。 リフレッシュページの場合は問題が続きます。",
|
||||||
|
"Accounts": "座",
|
||||||
|
"Action for Selected": "行動選択",
|
||||||
|
"Add": "追加",
|
||||||
|
"Add Monitor": "追加モニター",
|
||||||
|
"Add New": "新規追加",
|
||||||
|
"Admin": "Admin",
|
||||||
|
"Advanced": "先進",
|
||||||
|
"Again": "再",
|
||||||
|
"All Monitors": "すべてのモニター",
|
||||||
|
"All Monitors and Privileges": "すべての監視および権限",
|
||||||
|
"All Warnings": "すべての警告",
|
||||||
|
"Allow Next Command": "を次のコマンド <small>分</small>",
|
||||||
|
"Allow Next Email": "を次のメール <small>に分</small>",
|
||||||
|
"Allow Next Trigger": "を次のトリガ <small>をミリ秒単位</small>",
|
||||||
|
"Allowed IPs": "可IPs",
|
||||||
|
"Analyzation Duration": "解析期間",
|
||||||
|
"Archive": "アーカイブ",
|
||||||
|
"Audio Codec": "オーディオコーデック",
|
||||||
|
"Authenticate": "認証",
|
||||||
|
"Auto": "オート",
|
||||||
|
"Autosave": "ぜ",
|
||||||
|
"Base64 over Websocket": "Base64上Websocket",
|
||||||
|
"Bottom Left": "左下",
|
||||||
|
"Bottom Right": "右下",
|
||||||
|
"Browser Console Log": "ブラウザコンソールのログ",
|
||||||
|
"CPU": "CPU",
|
||||||
|
"CPU indicator will not work. Continuing...": "CPU表示できません。 続きを---",
|
||||||
|
"CSS": "CSS <small>スタイルダッシュボードです。</small>",
|
||||||
|
"Calendar": "カレンダー",
|
||||||
|
"Camera Password": "カメラのパスワード",
|
||||||
|
"Camera Username": "カメラのユーザー名",
|
||||||
|
"Camera is not recording": "カメラは記録",
|
||||||
|
"CameraNotRecordingText": "設定の場合は相容れないものがある。 チェックエンコーダです。 再...",
|
||||||
|
"Can Control Monitors": "を制御できるモニター",
|
||||||
|
"Can Delete Videos": "で削除できる動画",
|
||||||
|
"Can Delete Videos and Events": "削除が可能でのビデオやイベント",
|
||||||
|
"Can Edit Monitor": "編集できるモニター",
|
||||||
|
"Can Get Logs": "でログ",
|
||||||
|
"Can Get Monitors": "できるモニター",
|
||||||
|
"Can View Monitor": "できるビューモニター",
|
||||||
|
"Can View Snapshots": "でスナップショット",
|
||||||
|
"Can View Streams": "での流れ",
|
||||||
|
"Can View Videos": "できるビュー動画",
|
||||||
|
"Can View Videos and Events": "できるビュービデオやイベント",
|
||||||
|
"Can't Connect": "ですね",
|
||||||
|
"Center": "センター <small>のURLアドレス</small>",
|
||||||
|
"Chat on Discord": "チャット上の不和",
|
||||||
|
"Check": "チェック",
|
||||||
|
"Check Signal Interval": "チェック信号の間隔 <small>分</small>",
|
||||||
|
"Check for Motion First": "チェックモーションの最初",
|
||||||
|
"Close": "近",
|
||||||
|
"Closed": "閉鎖",
|
||||||
|
"Command": "コマンド",
|
||||||
|
"Command on Trigger": "コマンドをトリガー",
|
||||||
|
"Complete Stream URL": "完全なストリームURL",
|
||||||
|
"Confirm": "確認",
|
||||||
|
"Connected": "接続",
|
||||||
|
"Connection Type": "接続タイプ",
|
||||||
|
"Control": "制御",
|
||||||
|
"Control Error": "制御エラー",
|
||||||
|
"ControlErrorText1": "制御が有効にならない",
|
||||||
|
"Controllable": "制御可能",
|
||||||
|
"Country of Plates": "国板",
|
||||||
|
"Counts of Motion": "カウントの運動",
|
||||||
|
"Current": "現在の",
|
||||||
|
"Currently viewing": "現在閲覧",
|
||||||
|
"Custom": "カスタム",
|
||||||
|
"Custom Base URL": "カスタムベースURL <small>は空欄で結構使ホストのURL</small>",
|
||||||
|
"DB Lost.. Retrying..": "データベース失われた..再試行す。",
|
||||||
|
"DESC": "お得に!",
|
||||||
|
"Dashboard": "ダッシュボード",
|
||||||
|
"Dashboard Language": "ダッシュボードの言語",
|
||||||
|
"Dashcam": "Dashcam",
|
||||||
|
"Dashcam (Streamer v2)": "Dashcam(ストリーマv2)",
|
||||||
|
"Date Range": "日付の範囲",
|
||||||
|
"Debug": "デバッグ",
|
||||||
|
"Default": "デフォルト",
|
||||||
|
"Delete": "削除",
|
||||||
|
"Delete Filter": "削除フィルター",
|
||||||
|
"Delete Matches": "チ削除",
|
||||||
|
"Delete Monitor": "モニター削除",
|
||||||
|
"Delete Motionless Video": "削除静止画",
|
||||||
|
"Delete Motionless Videos (Record)": "削除静止画録画",
|
||||||
|
"Delete Selected Videos": "削除選択した動画",
|
||||||
|
"Delete Video": "ビデオ削除",
|
||||||
|
"Delete selected": "削除を選択",
|
||||||
|
"DeleteMonitorText": "い削除したいことがわか? はできません回復します。 ファイルのためにこのIDをファイルシステムです。 を選択の場合は再現モニターで同じIDのビデオやイベントが可視のダッシュボードです。",
|
||||||
|
"DeleteSelectedVideosMsg": "に削除しますこれらの動画です。 はできません回復しています。",
|
||||||
|
"DeleteVideoMsg": "に削除しますこの動画です。 はできません回復します。",
|
||||||
|
"Deleted": "削除",
|
||||||
|
"Detect Objects": "検出物体 <small class=\"\">以下参照</small>",
|
||||||
|
"Detector": "検出器",
|
||||||
|
"Detector Flags": "検出フラグ",
|
||||||
|
"Detector Rate": "検出率 <small>(FPS)</small>",
|
||||||
|
"DetectorText": "<p>の幅と高さのボックス表示設定すべきであるし640x480以下になりました。 この最適化とともに、これまでの読取速度のフレームです。</p>",
|
||||||
|
"Disable Night Vision": "除夜のビジョン <small>のURLアドレス</small>",
|
||||||
|
"Disable Nightvision": "Disable Nightvision",
|
||||||
|
"Disabled": "障害者",
|
||||||
|
"Documentation": "文書",
|
||||||
|
"Don't show this anymore": "いこう",
|
||||||
|
"Double Quote Directory": "ダブルクォートディレクトリ <small>の一部のディレクトリしています。 この場合クラッシュカメラです。</small>",
|
||||||
|
"Down": "下 <small>のURLアドレス</small>",
|
||||||
|
"Down Stop": "ダウン停止 <small>URLアドレス</small>",
|
||||||
|
"Download": "ダウンロード",
|
||||||
|
"EU": "EU",
|
||||||
|
"Edit": "編集",
|
||||||
|
"Email": "メール",
|
||||||
|
"Email Details": "メールの詳細",
|
||||||
|
"Email on No Motion": "メールでの\"動き\"",
|
||||||
|
"Email on Trigger": "メールでのトリガー <small>のメールのページ内移動用のメニュー口座のログインアドレスです。</small>",
|
||||||
|
"Enable Night Vision": "するナイトビジョン <small>のURLアドレス</small>",
|
||||||
|
"Enable Nightvision": "をNightvision",
|
||||||
|
"Enabled": "有効な",
|
||||||
|
"End": "終了",
|
||||||
|
"End Time": "終了時間",
|
||||||
|
"Ended": "終了",
|
||||||
|
"Enlarge": "拡大",
|
||||||
|
"Enter this code to proceed": "コードを入力して登録へ",
|
||||||
|
"Equal to": "等しい",
|
||||||
|
"Error Connecting": "接続エラー",
|
||||||
|
"Event": "イベント",
|
||||||
|
"Event Limit": "イベントに制限",
|
||||||
|
"EventText1": "起動イベント",
|
||||||
|
"EventText2": "はメールに画像ファイルにアクセスできないか、または",
|
||||||
|
"Events": "イベント",
|
||||||
|
"Example": "例",
|
||||||
|
"Execute Command": "コマンドを実行し",
|
||||||
|
"Executed": "実行され",
|
||||||
|
"Export": "輸出",
|
||||||
|
"FFmpegCantStart": "Gpartedっ開始",
|
||||||
|
"FFmpegCantStartText": "の記録エンジン本カメラが起動しません。 あかカメラの設定をします。 の場合はログ以外にこだ後の <b>課題を</b> Githubです。",
|
||||||
|
"FFmpegTip": "FFprobeが簡単なマルチメディアの流れの測定を行いました。 利用できる出力のすべての種類に関する情報の入力を含む期間には、フレームレートは、フレームサイズ等",
|
||||||
|
"FFprobe": "プローブ",
|
||||||
|
"FactorAuthText1": "このコードのみで活躍する15分間とさせていただきます。 場合は再度ログインしますタイマーをリセットされます15分と同じコードです。",
|
||||||
|
"Fatal": "致命的な",
|
||||||
|
"Fatal Maximum Reached": "死亡の最大に達し、停止ます。",
|
||||||
|
"FatalMaximumReachedText": "JPEGエラー致命的にするかもしれない。",
|
||||||
|
"Feed-in Image Height": "飼料-画像の高さ",
|
||||||
|
"Feed-in Image Width": "飼料-画像の幅",
|
||||||
|
"Fields cannot be empty": "分野できない空",
|
||||||
|
"File Not Exist": "ファイルが存在しない",
|
||||||
|
"File Not Found": "ファイルが見つかりません",
|
||||||
|
"File Type": "ファイルの種類",
|
||||||
|
"FileNotExistText": "登録できない不existantファイルです。 何かが分かります。",
|
||||||
|
"Filename": "ファイル名",
|
||||||
|
"Filesize": "Filesize",
|
||||||
|
"Filter ID": "フィルタのID",
|
||||||
|
"Filter Matches": "フィルターの試合",
|
||||||
|
"Filter Name": "フィルター名",
|
||||||
|
"FilterMatchesText1": "このフィルタを満たす条件です。",
|
||||||
|
"FilterMatchesText2": "動画で見つかります。",
|
||||||
|
"Filters": "フィル",
|
||||||
|
"Filters Updated": "フィ更新",
|
||||||
|
"FiltersUpdatedText": "ご変更して保存され、適用されます。",
|
||||||
|
"Find Where": "見所",
|
||||||
|
"Fix": "Fix",
|
||||||
|
"Fix Video": "修正ビデオ",
|
||||||
|
"FixVideoMsg": "したい着この動画です。 元に戻せませんこの行動します。",
|
||||||
|
"Font Path": "フォントのパス",
|
||||||
|
"Font Size": "文字サイズ",
|
||||||
|
"Force Port": "力ポート",
|
||||||
|
"Found Devices": "たデバイス",
|
||||||
|
"Frame Rate": "フレームレート <small>(FPS)</small>",
|
||||||
|
"Full Frame Detection": "フルフレーム検出",
|
||||||
|
"Fullscreen": "フルスクリーン",
|
||||||
|
"Greater Than": "以上",
|
||||||
|
"Greater Than or Equal to": "以上",
|
||||||
|
"Group Key": "パブリックグループ",
|
||||||
|
"Group Name": "グループ名",
|
||||||
|
"Grouping": "グループ化 ",
|
||||||
|
"H.264 / H.265 / H.265+": "H.264/H.265/H.265 ",
|
||||||
|
"HLS (.m3u8)": "HLS(します。m3u8)",
|
||||||
|
"HLS (includes Audio)": "HLS(オーディオ)",
|
||||||
|
"HLS Audio Encoder": "HLSオーディオエンコーダ",
|
||||||
|
"HLS List Size": "HLSリストのサイズ",
|
||||||
|
"HLS Preset": "HLSプリセット",
|
||||||
|
"HLS Segment Length": "HLSセグメント長 <small>秒</small>",
|
||||||
|
"HLS Video Encoder": "HLSビデオエンコーダ",
|
||||||
|
"HTTP": "HTTP",
|
||||||
|
"HTTPS": "HTTPS",
|
||||||
|
"Height": "高さ",
|
||||||
|
"Help": "助",
|
||||||
|
"Hide List": "Hide一覧",
|
||||||
|
"Hide Notes": "Hide注",
|
||||||
|
"Host": "ホスト",
|
||||||
|
"Hotswap Modes (Watch-Only)": "Hotswapモード時のみ)",
|
||||||
|
"How to Record": "その記録",
|
||||||
|
"IP Address": "IPアドレス",
|
||||||
|
"Identity": "ティ",
|
||||||
|
"IdentityText1": "このシステムを特定のデータをこのストリームです。 大きさを変えることはできませんの <b>モニタIDを</b> 一度押すと保存されます。 したい場合はしないように注意してください <b>モニタID</b> をより人間が読める形式だけます。",
|
||||||
|
"IdentityText2": "また複数のモニターを変更することにより、 <b>モニタID</b> を押すと保存されます。 す <b>な</b> 利用のIDのモニターするにあたりまえるモニターのデータベースの情報です。",
|
||||||
|
"Idle": "アイドル",
|
||||||
|
"Image Height": "画像の高さ",
|
||||||
|
"Image Location": "画像の位置 <small>を絶対パスまたは空欄で結構使用グローバル</small>",
|
||||||
|
"Image Position": "画像の位置",
|
||||||
|
"Image Width": "画像の幅",
|
||||||
|
"Import": "輸入",
|
||||||
|
"Import Monitor Configuration": "輸入モニターの設定",
|
||||||
|
"ImportMonitorConfigurationText": "そうするとoverrwriteの変更は、現在保存されません。 輸入の変化のみに適用される場合を押すと <b>保存し</b>ます。",
|
||||||
|
"In": "に",
|
||||||
|
"Incorrect Settings Chosen": "誤った設定を選択",
|
||||||
|
"Indifference": "無関心",
|
||||||
|
"Input": "入力",
|
||||||
|
"Input Flags": "入力フラグ",
|
||||||
|
"Input Type": "入力タイプ",
|
||||||
|
"InputText1": "これ忍どのように消費するストリームです。 最適な性能チューニングしてみカメラの内部設定します。 として以下のようなオプションセットとして表示します。 ディスカメラで利用できます <b>内蔵ONVIFスキャナー</b> の向きを変えて走り出した。 一部のONVIFカメラの使用を必要とする管理ツールの変更を内部設定します。 できない場合は空のカメラをお試しいただ <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">ONVIFデバイスマネージャー Windows</a>ます。",
|
||||||
|
"InputText2": "<ul><li><b>Framerate(FPS):</b> 高さ:10-15FPS、低:2-5FPS</li><li><b>Iフレーム間隔:</b> 80</li><li><b>ビットレート:</b> CBR(定ビットレート)</li><li><b>ビットレート:</b> 間256kbps-500kbps</li></ul>",
|
||||||
|
"InputText3": "困ったときにはコーヒーに飽きたら寿司にどのような入力インターネットにアクセスでカメラをご覧になることができる <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">カメラのUrlリスト</a> の商品につけられます。",
|
||||||
|
"Invalid JSON": "無効なJSON",
|
||||||
|
"InvalidJSONText": "ご確認くださいここは有効なJSON文字列のための商品につけられたモニターを設定します。",
|
||||||
|
"JPEG": "JPEG",
|
||||||
|
"JPEG (Auto Enables JPEG API)": "JPEG(自動車をJPEG API)",
|
||||||
|
"JPEG API": "JPEG APIの <small>スナップショット(cgi-bin)</small>",
|
||||||
|
"JPEG Error": "JPEGエラー",
|
||||||
|
"JPEG Mode": "JPEGモード",
|
||||||
|
"JPEGErrorText": "が課題となった取得データからカメラです。",
|
||||||
|
"Leave blank for random.": "空白の場合ランダムです。",
|
||||||
|
"Left": "左 <small>のURLアドレス</small>",
|
||||||
|
"Left Stop": "左停 <small>URLアドレス</small>",
|
||||||
|
"Less Than": "以上",
|
||||||
|
"Less Than or Equal to": "以下の",
|
||||||
|
"Like": "のように",
|
||||||
|
"Lisence Plate Detector": "ライセンプレート検出器",
|
||||||
|
"List Toggle": "リストを切り替え",
|
||||||
|
"Live Stream Toggle": "ライブストリームを切り替え",
|
||||||
|
"Live View": "ライブビュー",
|
||||||
|
"Local": "地",
|
||||||
|
"Log Level": "ログレベル",
|
||||||
|
"Log Signal Event": "ログ信号のイベント <small>クライアント側のみ</small>",
|
||||||
|
"Logging": "ログイン",
|
||||||
|
"Login": "ログイン",
|
||||||
|
"Logout": "アウト",
|
||||||
|
"Logs": "ログ",
|
||||||
|
"MB": "MB",
|
||||||
|
"MJPEG": "MJPEG",
|
||||||
|
"MP4 (copy, libx264, libx265)": "MP4(コピー、libx264は、libx265)",
|
||||||
|
"MPEG-4 (.mp4 / .ts)": "MPEG-4(い。mp4ます。ts)",
|
||||||
|
"MailError": "メールエラーがない送信メールは、チェックconfです。jsonです。 飛び他の特徴に依存のメーリングします。",
|
||||||
|
"Matches": "試合",
|
||||||
|
"Max Storage Amount": "最大の貯蔵量を <small>、メガバイト</small>",
|
||||||
|
"Mode": "モード",
|
||||||
|
"Monitor": "モニター",
|
||||||
|
"Monitor Added by user": "モニター追加によりユーザーです。",
|
||||||
|
"Monitor Capture Rate": "モニター捕捉率 <small>(FPS)</small>",
|
||||||
|
"Monitor Groups": "モニター集団",
|
||||||
|
"Monitor ID": "モニタID",
|
||||||
|
"Monitor Idling": "モニターアイドリング",
|
||||||
|
"Monitor Name": "モニタ名称",
|
||||||
|
"Monitor Settings": "モニタ設定",
|
||||||
|
"Monitor Stopped": "モニターを停止",
|
||||||
|
"Monitor Updated by user": "モニターを更新します。",
|
||||||
|
"Monitor mode changed": "モニタモード変更",
|
||||||
|
"Monitor mode is already": "モニターモードで",
|
||||||
|
"Monitor or Key does not exist.": "モニターやキーが存在しません。",
|
||||||
|
"MonitorIdlingText": "モニターセッションが命じられた。",
|
||||||
|
"MonitorStoppedText": "モニターセッションの中止を命じます。",
|
||||||
|
"Monitors": "モニター",
|
||||||
|
"Monitors per row": "モニター当行 <small>のためのモンタージュ</small>",
|
||||||
|
"Montage": "モンタージュ",
|
||||||
|
"Motion GUI": "動GUI",
|
||||||
|
"Motion Meter": "運動メーター",
|
||||||
|
"Name": "名称",
|
||||||
|
"No": "No",
|
||||||
|
"No Audio": "オーディオ",
|
||||||
|
"No Data": "データなし",
|
||||||
|
"No Events found for this video": "イベントはありませんがこの動画",
|
||||||
|
"No Group with this key exists": "グループはこの鍵が存在する",
|
||||||
|
"No Monitor Found, Ignoring Request": "なモニター、要請を無視して",
|
||||||
|
"No Rotation": "回転無し",
|
||||||
|
"No such file": "なファイル",
|
||||||
|
"NoMotionEmailText1": "不動",
|
||||||
|
"NoMotionEmailText2": "あなたの運動検知のためのカメラ",
|
||||||
|
"NoVideosFoundForDateRange": "ない映像がこの日付範囲から選びます。 う設定の開始日は\"まだ完全に回復してます。",
|
||||||
|
"Not Authorized": "権限がない",
|
||||||
|
"Not Connected": "接続されていない",
|
||||||
|
"Not Equal to": "と等しくない",
|
||||||
|
"Not In": "ない",
|
||||||
|
"Not Matches": "ない試合",
|
||||||
|
"Not Permitted": "許可されない",
|
||||||
|
"Not an Administrator Account": "な管理者のアカウント",
|
||||||
|
"NotAuthorizedText1": "認証されていないの提出からinitコマンド\"auth\"は、\"ke\"、\"uid\"",
|
||||||
|
"Notes": "注記",
|
||||||
|
"NotesPlacholder": "コメントするため、このカメラを設定します。",
|
||||||
|
"Number of Days to keep": "数日間の保",
|
||||||
|
"ONVIF": "ONVIF",
|
||||||
|
"ONVIF Scanner": "ONVIFのスキャナー",
|
||||||
|
"ONVIFnote": "発見ONVIFのデバイスネットワーク以外はと思われる項目に関しては、空白をスキャン現在のネットワークです。 <br>ユーザー名とパスワードを選択することも可能です。",
|
||||||
|
"OpenCV Cascades": "OpenCVンアプリケーション",
|
||||||
|
"Order Streams": "注文の流れ",
|
||||||
|
"Output Method": "出力方法",
|
||||||
|
"Password": "パスワード",
|
||||||
|
"Password Again": "パスワードを再",
|
||||||
|
"Passwords don't match": "パスワードと一致しません",
|
||||||
|
"Paste JSON here.": "ペーストはJSONです。",
|
||||||
|
"Path": "パス",
|
||||||
|
"Permissions": "アクセス権",
|
||||||
|
"Points": "ポイント <small>が加算ポイントをクリックの端にポリゴンです。</small>",
|
||||||
|
"Port": "港",
|
||||||
|
"Position X": "X位置",
|
||||||
|
"Position Y": "位置Y",
|
||||||
|
"Power Video Viewer": "電動画ビューワー",
|
||||||
|
"Power Viewer": "電力ビューア",
|
||||||
|
"Preferences": "設定",
|
||||||
|
"Preset": "プリセット",
|
||||||
|
"Probe Size": "プローブサイズ",
|
||||||
|
"Process Crashed for Monitor": "工程ぶためのモニター",
|
||||||
|
"Process Unexpected Exit": "過程で予想外の出口",
|
||||||
|
"Profile": "概要",
|
||||||
|
"Quality": "品質の <small>1が高く、23日には低</small>",
|
||||||
|
"Query": "クエリ",
|
||||||
|
"RAM": "RAM",
|
||||||
|
"RTSP": "RTSP",
|
||||||
|
"RTSP Transport": "RTSP輸送",
|
||||||
|
"Range or Single": "範囲またはシングル",
|
||||||
|
"Rate": "率 <small>(FPS)</small>",
|
||||||
|
"Record": "記録",
|
||||||
|
"Record File Type": "録音ファイルの種類",
|
||||||
|
"Record Height": "記録の高さ",
|
||||||
|
"Record Video Filter": "ビデオをフィルター",
|
||||||
|
"Record Width": "記録幅",
|
||||||
|
"Recording": "記録",
|
||||||
|
"Recording Flags": "記録フラグ",
|
||||||
|
"Recording Segment Interval": "録音のセグメント間隔 <small>分</small>",
|
||||||
|
"Recording Timeout": "を記録タイムアウト <small>分</small>",
|
||||||
|
"Recording Timestamp": "を記録タイムスタンプ",
|
||||||
|
"Recording Watermark": "録画透かし",
|
||||||
|
"RecordingText": "であることをおすすめの設定 <b>を記録ファイルの種類</b> に <b class=\"h_t_input h_t_jpeg h_t_socket\">WebM</b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">MP4</b> - <b>ビデオコーデック</b> を <b class=\"h_t_input h_t_jpeg h_t_socket\">libvpx</b><b class=\"h_t_input h_t_h264 h_t_hls h_t_mp4\">コピーまたは </b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">libx264</b> でご <b>入力タイプ</b> に設定し <b class=\"h_t_text\"></b>ます。",
|
||||||
|
"Refresh List of Cascades": "リフレッシュリストンアプリケーション",
|
||||||
|
"Region Editor": "地域のエディタ",
|
||||||
|
"Region Name": "地域名",
|
||||||
|
"RegionNote": "ポイントのみ保存を押すと <b>保存</b> の <b>モニター設定</b> ウインドウです。",
|
||||||
|
"Regions": "地域",
|
||||||
|
"Remember Me": "グイン情報を記憶させ",
|
||||||
|
"Reset Timer": "リセットタイマー",
|
||||||
|
"Restarting Process": "再稼働プロセスの加",
|
||||||
|
"Retry Connection": "再接続 <small>回数許されな</small>",
|
||||||
|
"Retrying...": "リトライ動作中に---",
|
||||||
|
"Right": "右 <small>のURLアドレス</small>",
|
||||||
|
"Right Stop": "右停止 <small>のURLアドレス</small>",
|
||||||
|
"Rotate": "回転",
|
||||||
|
"Save": "保存",
|
||||||
|
"Save Directory": "保存ディレクトリ",
|
||||||
|
"Save Events to SQL": "保存イベントへSQL",
|
||||||
|
"Save Log in SQL": "ログの保存アプリケーションで <small>この事がございます。</small>",
|
||||||
|
"Save as": "として保存",
|
||||||
|
"Saved Filters": "保存したフィルター",
|
||||||
|
"Scan Settings": "スキャン設定",
|
||||||
|
"Search": "検索",
|
||||||
|
"Send Frames": "送信フレーム <small>プするフレームの解析</small>",
|
||||||
|
"Separate with commas, no spaces": "分離をカンマ区切りで入力し、空間",
|
||||||
|
"Set to Watch Only": "設定時のみ",
|
||||||
|
"Settings": "設定",
|
||||||
|
"Settings Changed": "設定変更",
|
||||||
|
"SettingsChangedText": "設定して適用されます。",
|
||||||
|
"Shinobi": "忍",
|
||||||
|
"Shinobi Streamer": "商品につけられたストリーマ",
|
||||||
|
"Show Logs": "ショーログ",
|
||||||
|
"Silent": "黙",
|
||||||
|
"Simple": "簡単な",
|
||||||
|
"Size (mb)": "サイズ(mb)",
|
||||||
|
"Snapshot": "スナップショット",
|
||||||
|
"Snapshot Flags": "スナップショットフラグ",
|
||||||
|
"Snapshots": "スナップショット",
|
||||||
|
"Sort By": "並べ替え",
|
||||||
|
"Start": "開始",
|
||||||
|
"Start Recording": "録音を開始",
|
||||||
|
"Start Time": "開始時間",
|
||||||
|
"Started": "を開始",
|
||||||
|
"Status Indicator": "ステータスインジケータ",
|
||||||
|
"Stop URL": "停URL",
|
||||||
|
"Stream": "ストリーム",
|
||||||
|
"Stream Flags": "ストリームフラグ",
|
||||||
|
"Stream Timestamp": "ストリームにタイムスタンプ",
|
||||||
|
"Stream Type": "ストリームタイプ",
|
||||||
|
"Stream Watermark": "ストリームゾート",
|
||||||
|
"Stream to YouTube": "ストリームをYouTube",
|
||||||
|
"Stream to YouTube Flags": "ストリームをYouTube旗",
|
||||||
|
"StreamText": "<p>ここでは指定のストリーム出方法で設定します。 このストリームに表示されるので、ダッシュボードです。 ご利用にHLS、JPEG、MJPEGきを摂取することができ、ストリームを通じてその他のプログラムです。</p><p class=\"h_st_input h_st_jpeg\">使用JPEGストリームは本質的にoffのストリームを使用してスナップショットの原材料へのコンタミ防止のフレームを取得します。</p>",
|
||||||
|
"Streamer": "ストリーマ",
|
||||||
|
"Streams": "渓流",
|
||||||
|
"Superuser": "Superuser",
|
||||||
|
"Switch on for Still Image": "スイッチのための画像",
|
||||||
|
"TCP": "TCP",
|
||||||
|
"Text Box Color": "テキストボックスの色",
|
||||||
|
"Text Color": "テキストカラーを設定します。",
|
||||||
|
"Time-lapse": "時間",
|
||||||
|
"Time-lapse Tool": "インターバル撮ツール",
|
||||||
|
"Timeout": "タイムアウト",
|
||||||
|
"Timeout Reset on Next Motion": "タイムアウトリセットは次の運動",
|
||||||
|
"Toggle Sidebar": "サイドバーを切り替え",
|
||||||
|
"Top Left": "トップ左",
|
||||||
|
"Top Right": "トップ右",
|
||||||
|
"Trigger Record": "トリガ記録",
|
||||||
|
"Trigger Successful": "トリガー成功",
|
||||||
|
"UDP": "UDP",
|
||||||
|
"URL": "URL",
|
||||||
|
"URL Stop Timeout": "URLを停止タイムアウトの <small>実行を停止URLの後にXをミリ秒</small>",
|
||||||
|
"US": "米",
|
||||||
|
"Unable to Launch": "できない開始",
|
||||||
|
"UnabletoLaunchText": "保存しておいてください新しいモニターします。 その試みを開始、地域のエディタです。",
|
||||||
|
"Up": "Up <small>URLアドレス</small>",
|
||||||
|
"Up Stop": "最大停止 <small>のURLアドレス</small>",
|
||||||
|
"Username": "ユーザー名",
|
||||||
|
"Value": "値",
|
||||||
|
"Video": "ビデオ",
|
||||||
|
"Video Codec": "ビデオコーデック",
|
||||||
|
"Video Filter": "映像フィルター",
|
||||||
|
"Video Finished": "ビデオ完成",
|
||||||
|
"Video Length (minutes) and Motion Count per video": "動画の長さ(分)運動回数の映像",
|
||||||
|
"Video Record Rate": "デジタルビデオ入出力率 <small>(FPS)</small>",
|
||||||
|
"Video Status": "ビデオの状況",
|
||||||
|
"Video and Time Span (Minutes)": "映時間(分)",
|
||||||
|
"Videos": "ビデオ",
|
||||||
|
"Videos List": "動画一覧",
|
||||||
|
"Watch": "腕時計",
|
||||||
|
"Watch Only": "時計のみ",
|
||||||
|
"WebDAV": "WebDAV",
|
||||||
|
"WebM (libvpx)": "WebM(libvpx)",
|
||||||
|
"Webdav Error": "Webdavエラー",
|
||||||
|
"WebdavErrorText": "登録できないます。 ただ、カメラ内のフォルダ選択保存ディレクトリのか?",
|
||||||
|
"Webhook": "Webhook",
|
||||||
|
"Webhook URL": "Webhook URL",
|
||||||
|
"Width": "幅",
|
||||||
|
"Yes": "あり",
|
||||||
|
"Zoom In": "ズーム <small>のURLアドレス</small>",
|
||||||
|
"Zoom In Stop": "ズーム停止 <small>のURLアドレス</small>",
|
||||||
|
"Zoom Out": "縮小 <small>URLアドレス</small>",
|
||||||
|
"Zoom Out Stop": "表示が自動的に切り替わり止め <small>のURLアドレス</small>",
|
||||||
|
"a day": "日",
|
||||||
|
"a few seconds": "数秒",
|
||||||
|
"a minute": "分",
|
||||||
|
"a month": "月",
|
||||||
|
"a year": "年",
|
||||||
|
"aac": "デスクトップ、エンタープライズ",
|
||||||
|
"aac (Default)": "デスクトップ、エンタープライズ(デフォルト)",
|
||||||
|
"ac3": "ac3",
|
||||||
|
"ago": "前",
|
||||||
|
"an hour": "時間",
|
||||||
|
"blankPassword": "空欄で結構いパスワード",
|
||||||
|
"calendar": "カレンダー",
|
||||||
|
"clientStreamFailedattemptingReconnect": "クライアント側ctreamチェックに失敗したとしてもう一度接続してください。",
|
||||||
|
"confirmDeleteFilter": "に削除しますこのフィルタすか? はできません回復します。",
|
||||||
|
"copy": "コピー",
|
||||||
|
"days": "日",
|
||||||
|
"dropBoxSuccess": "あなた方の成功を意味する。 ファイルをDropboxに保存されます。",
|
||||||
|
"for Global Access": "グローバルアクセス",
|
||||||
|
"hours": "時間",
|
||||||
|
"in": "に",
|
||||||
|
"libmp3lame": "libmp3lame",
|
||||||
|
"libopus": "libopus",
|
||||||
|
"libvorbis (Default)": "libvorbis(デフォルト)",
|
||||||
|
"libvpx (Default)": "libvpx(デフォルト)",
|
||||||
|
"libvpx-vp9": "libvpx-vp9",
|
||||||
|
"libx264": "libx264",
|
||||||
|
"libx264 (Default)": "libx264(デフォルト)",
|
||||||
|
"libx265": "libx265",
|
||||||
|
"minutes": "分",
|
||||||
|
"modifyVideoText1": "方法は存在しないます。 よって実行されていることを確認する最後の値はURLではない空白にします。",
|
||||||
|
"monitorEditFailedMaxReached": "アカウントの最大数のカメラが作成できます。 話管理者の体力があれば誰でも楽しめます。",
|
||||||
|
"monitorEditText1": "無効なデータを確認する有効なインポート文字列になります。",
|
||||||
|
"monitorEditText2": "無効な内容の文字列です。 確認でJSON文字列ではなく通常のオブジェクトに渡されます。",
|
||||||
|
"monitorGetText1": "不完全な要求の削除、最後のスラッシュのURLまたは許容値です。",
|
||||||
|
"months": "ヶ月",
|
||||||
|
"noSpecialCharacters": "なし空間または特殊文字です。",
|
||||||
|
"on": "月",
|
||||||
|
"on Error": "エラー時",
|
||||||
|
"startUpText0": "サイズのチェックビデオ",
|
||||||
|
"startUpText1": "末サイズをチェックビデオ",
|
||||||
|
"startUpText2": "すべてのユーザーがチェックに近いファイルを開く削除ファイルはユーザー制限",
|
||||||
|
"startUpText3": "待ちに未完成の映像チェックします。 3秒です。",
|
||||||
|
"startUpText4": "すべてのモニタ設定時記録",
|
||||||
|
"startUpText5": "忍びのご用意もあります。",
|
||||||
|
"superAdminText": "\"スーパーです。json\"は存在しない。 お名前を変更する\"スーパーです。サンプルです。json\"\"スーパーです。json\"です。",
|
||||||
|
"superAdminTitle": "世界一のスーパー管理者",
|
||||||
|
"total": "合計",
|
||||||
|
"updateKeyText1": "\"updateKey\"が\"confです。json\"になるんで更新するまでに追加します。",
|
||||||
|
"updateKeyText2": "\"updateKey\"が間違っています。",
|
||||||
|
"years": "年"
|
||||||
|
}
|
|
@ -0,0 +1,531 @@
|
||||||
|
{
|
||||||
|
"Shinobi": "Shinobi",
|
||||||
|
"superAdminTitle": "Shinobi : Super Admin",
|
||||||
|
"Login": "Entrar",
|
||||||
|
"Authenticate": "Autenticar",
|
||||||
|
"Dashboard": "Painel de Controle",
|
||||||
|
"Streamer": "Transmissor",
|
||||||
|
"Admin": "Admin",
|
||||||
|
"Superuser": "Superusuário",
|
||||||
|
"Dashcam": "Dashcam",
|
||||||
|
"Email": "E-mail",
|
||||||
|
"Username": "Usuário",
|
||||||
|
"Profile": "Perfil",
|
||||||
|
"Password": "Senha",
|
||||||
|
"Password Again": "Senha novamente",
|
||||||
|
"Remember Me": "Lembrar",
|
||||||
|
"RAM": "RAM",
|
||||||
|
"CPU": "CPU",
|
||||||
|
"on": "ligado",
|
||||||
|
"Power Viewer": "Ligar visualizador",
|
||||||
|
"Power Video Viewer": "Ligar visualizador de vídeo",
|
||||||
|
"Time-lapse": "Time-lapse",
|
||||||
|
"Montage": "Montagem",
|
||||||
|
"Accounts": "Contas",
|
||||||
|
"Settings": "Configurações",
|
||||||
|
"API": "API",
|
||||||
|
"ONVIF": "ONVIF",
|
||||||
|
"FFprobe": "Probe",
|
||||||
|
"Filters": "Filtros",
|
||||||
|
"Logs": "Logs",
|
||||||
|
"List Toggle": "Mostrar lista",
|
||||||
|
"Hide List": "Esconder Lista",
|
||||||
|
"Motion GUI": "GUI de Movimento",
|
||||||
|
"JPEG Mode": "Modo JPEG",
|
||||||
|
"Order Streams": "Ordenar transmissões",
|
||||||
|
"Hide Notes": "Esconder Notas",
|
||||||
|
"Example": "Exemplo",
|
||||||
|
"Logout": "Sair",
|
||||||
|
"Closed": "Fechado",
|
||||||
|
"Ended": "Finalizado",
|
||||||
|
"Started": "Iniciado",
|
||||||
|
"Monitor": "Monitor",
|
||||||
|
"Filename": "Nome do Arquivo",
|
||||||
|
"Size (mb)": "Tamanho (mb)",
|
||||||
|
"Watch": "Assistir",
|
||||||
|
"Download": "Baixar",
|
||||||
|
"Delete": "Deletar",
|
||||||
|
"Fix": "Corrigir",
|
||||||
|
"Zoom In": "Mais Zoom <small>URL Address</small>",
|
||||||
|
"Zoom Out": "Menos Zoom <small>URL Address</small>",
|
||||||
|
"Enable Nightvision": "Ativar Visão Noturna",
|
||||||
|
"Disable Nightvision": "Desativar Visão Noturna",
|
||||||
|
"Current": "Atual",
|
||||||
|
"Monitors": "Monitors",
|
||||||
|
"Video": "Video",
|
||||||
|
"Videos": "Videos",
|
||||||
|
"Events": "Eventos",
|
||||||
|
"Streams": "Transmissões",
|
||||||
|
"Snapshot": "Snapshot",
|
||||||
|
"Snapshots": "Snapshots",
|
||||||
|
"Date Range": "Intervalo de Data",
|
||||||
|
"Event Limit": "Limite de Evento",
|
||||||
|
"No Data": "Sem Dados",
|
||||||
|
"Live View": "Visualização ao vivo",
|
||||||
|
"Add": "Adicionar",
|
||||||
|
"Save": "Salvar",
|
||||||
|
"Close": "Fechar",
|
||||||
|
"Check": "Verificar",
|
||||||
|
"Confirm": "Confirmar",
|
||||||
|
"Enable": "Habilitar",
|
||||||
|
"Enabled": "Habilitado",
|
||||||
|
"API Keys": "Chaves da API",
|
||||||
|
"Group Key": "Chave do Grupo",
|
||||||
|
"Allowed IPs": "IPs Permitidos",
|
||||||
|
"Separate with commas, no spaces": "Separar com vírgulas, sem espaços",
|
||||||
|
"Can Get Monitors": "Pode Obter Monitores",
|
||||||
|
"Can Get Logs": "Pode Obter Logs",
|
||||||
|
"Can Control Monitors": "Pode Controlar Monitores",
|
||||||
|
"Can View Snapshots": "Pode Visualizar Snapshots",
|
||||||
|
"Can View Streams": "Pode Visualizar Transmissões",
|
||||||
|
"Can View Videos": "Pode Visualizar Vídeos",
|
||||||
|
"Can View Monitor": "Pode Visualizar Monitores",
|
||||||
|
"Can Edit Monitor": "Pode Editar Monitores",
|
||||||
|
"Can Delete Videos": "Pode Deletar Vídeos",
|
||||||
|
"Delete Video": "Deletar Vídeo",
|
||||||
|
"Can View Videos and Events": "Pode Visualizar Vídeos e Eventos",
|
||||||
|
"Can Delete Videos and Events": "Pode Deletar Vídeos e Eventos",
|
||||||
|
"Saved Filters": "Filtros Salvos",
|
||||||
|
"Filter Name": "Filtrar Nome",
|
||||||
|
"Find Where": "Encontrar Onde",
|
||||||
|
"Sort By": "Ordenar Por",
|
||||||
|
"Start Time": "Hora de Início",
|
||||||
|
"End Time": "Hora de Término",
|
||||||
|
"Monitor ID": "ID do Monitor",
|
||||||
|
"File Type": "Tipo de Arquivo",
|
||||||
|
"Filesize": "Tamanho do Arquivo",
|
||||||
|
"Video Status": "Status do Vídeo",
|
||||||
|
"Preferences": "Preferências",
|
||||||
|
"Equal to": "Igual a",
|
||||||
|
"Not Equal to": "Não Igual a",
|
||||||
|
"Greater Than or Equal to": "Maior ou Igual a",
|
||||||
|
"Greater Than": "Maior que",
|
||||||
|
"Less Than": "Menor que",
|
||||||
|
"Less Than or Equal to": "Menor ou Igual a",
|
||||||
|
"Like": "Como",
|
||||||
|
"Matches": "Combina",
|
||||||
|
"Not Matches": "Não Combina",
|
||||||
|
"In": "Em",
|
||||||
|
"Not In": "Não Em",
|
||||||
|
"ASC": "ASC",
|
||||||
|
"DESC": "DESC",
|
||||||
|
"Action for Selected": "Ação para Selecionado",
|
||||||
|
"Search": "Procurar",
|
||||||
|
"No": "Não",
|
||||||
|
"Yes": "Sim",
|
||||||
|
"Start": "Iniciar",
|
||||||
|
"End": "Finalizar",
|
||||||
|
"Archive": "Arquivar",
|
||||||
|
"Email Details": "Detalhes do E-mail",
|
||||||
|
"Delete Matches": "Deletar Combinações",
|
||||||
|
"Delete selected": "Deletar Selecionado",
|
||||||
|
"Execute Command": "Executar Comando",
|
||||||
|
"for Global Access": "para Acesso Global",
|
||||||
|
"Help": "Ajuda",
|
||||||
|
"Don't show this anymore": "Não mostre isso mais",
|
||||||
|
"Chat on Discord": "Conversar no Discord",
|
||||||
|
"Documentation": "Documentação",
|
||||||
|
"All Monitors": "Todos Monitores",
|
||||||
|
"Motion Meter": "Medidos de Movimento",
|
||||||
|
"FFmpegTip": "FFprobe is a simple multimedia streams analyzer. You can use it to output all kinds of information about an input including duration, frame rate, frame size, etc.",
|
||||||
|
"Complete Stream URL": "URL de transmissão completa",
|
||||||
|
"ONVIF Scanner": "ONVIF Scanner",
|
||||||
|
"Scan Settings": "Configurações de digitalização",
|
||||||
|
"ONVIFnote": "Descubra os dispositivos ONVIF em redes fora da sua ou deixe em branco para escanear sua rede atual. <br>O nome de usuário e a senha podem ser deixados em branco.",
|
||||||
|
"Range or Single": "Range or Single",
|
||||||
|
"IP Address": "Endereço IP",
|
||||||
|
"Port": "Porta",
|
||||||
|
"Camera Username": "Usuário da câmera",
|
||||||
|
"Camera Password": "Senha da câmera",
|
||||||
|
"Found Devices": "Dispositivos encontrados",
|
||||||
|
"Switch on for Still Image": "Ligar para manter imagem",
|
||||||
|
"Live Stream Toggle": "Mostrar transmissão ao vivo",
|
||||||
|
"RegionNote": "Os pontos só são salvos quando você pressiona <b>Salvar</b> na janela de <b>Configurações do Monitor</b>.",
|
||||||
|
"Points": "Pontos <small>Ao adicionar pontos, clique na borda do polígono.</small>",
|
||||||
|
"Indifference": "Indiferença",
|
||||||
|
"Region Name": "Nome da região",
|
||||||
|
"Regions": "Regiões",
|
||||||
|
"Again": "De novo",
|
||||||
|
"Account Info": "Informações da conta",
|
||||||
|
"blankPassword": "Deixe em branco para manter a mesma senha",
|
||||||
|
"2-Factor Authentication": "Autenticação de 2 fatores",
|
||||||
|
"Max Storage Amount": "Montante máximo de armazenamento <small>em Megabytes</small>",
|
||||||
|
"Number of Days to keep": "Número de dias para manter",
|
||||||
|
"Monitor Groups": "Grupos de monitores",
|
||||||
|
"Group Name": "Nome do grupo",
|
||||||
|
"WebDAV": "WebDAV",
|
||||||
|
"URL": "URL",
|
||||||
|
"Autosave": "Auto salvar",
|
||||||
|
"Save Directory": "Salvar diretório",
|
||||||
|
"CSS": "CSS <small>Personalize seu painel de controle.</small>",
|
||||||
|
"Monitors per row": "Monitores por linha <small>para montagem</small>",
|
||||||
|
"Browser Console Log": "Navegador de logs",
|
||||||
|
"All Monitors and Privileges": "Todos monitores e privilégios",
|
||||||
|
"Permissions": "Permissões",
|
||||||
|
"Time-lapse Tool": "Ferramenta Time-laps",
|
||||||
|
"total": "total",
|
||||||
|
"MB": "MB",
|
||||||
|
"Calendar": "Calendário",
|
||||||
|
"Leave blank for random.": "Deixe em branco para aleatório.",
|
||||||
|
"Currently viewing": "Visualizando atualmente",
|
||||||
|
"Status Indicator": "Indicador de status",
|
||||||
|
"Show Logs": "Mostrar logs",
|
||||||
|
"Videos List": "Lista de vídeos",
|
||||||
|
"Monitor Settings": "Configurações do monitor",
|
||||||
|
"Enlarge": "Prolongar",
|
||||||
|
"Fullscreen": "Tela cheia",
|
||||||
|
"Value": "Valor",
|
||||||
|
"Idle": "Inativo",
|
||||||
|
"Disabled": "Desabilitado",
|
||||||
|
"Record": "Gravar",
|
||||||
|
"Watch Only": "Visualizar apenas",
|
||||||
|
"Toggle Sidebar": "Mostrar barra lateral",
|
||||||
|
"Add Monitor": "Adicionar monitor",
|
||||||
|
"Start Recording": "Iniciar gravação",
|
||||||
|
"Set to Watch Only": "Definir para apenas visualizar",
|
||||||
|
"Save as": "Salvar como",
|
||||||
|
"Add New": "Adicionar novo",
|
||||||
|
"Delete Selected Videos": "Excluir vídeos selecionados",
|
||||||
|
"DeleteSelectedVideosMsg": "Deseja excluir esses vídeos? Você não poderá recuperá-los.",
|
||||||
|
"clientStreamFailedattemptingReconnect": "A verificação ctream do lado do cliente falhou, tentando reconectar.",
|
||||||
|
"Delete Filter": "Excluir filtro",
|
||||||
|
"confirmDeleteFilter": "Deseja excluir este filtro? Você não poderá recuperá-lo.",
|
||||||
|
"Fix Video": "Corrigir Vídeo",
|
||||||
|
"FixVideoMsg": "Você deseja corrigir esse vídeo? Você não poderá desfazer essa ação..",
|
||||||
|
"DeleteVideoMsg": "Deseja excluir este vídeo? Você não poderá recuperá-lo.",
|
||||||
|
"dropBoxSuccess": "Sucesso! Arquivos salvos em seu Dropbox.",
|
||||||
|
"API Key Deleted": "Chave da API excluída",
|
||||||
|
"APIKeyDeletedText": "A chave foi excluída. Não funcionará mais.",
|
||||||
|
"API Key Added": "Chave da API adicionada",
|
||||||
|
"APIKeyAddedText": "Você pode usar essa chave agora",
|
||||||
|
"Filters Updated": "Filtros atualizados",
|
||||||
|
"FiltersUpdatedText": "Suas alterações foram salvas e aplicadas.",
|
||||||
|
"Settings Changed": "Configurações Alteradas",
|
||||||
|
"SettingsChangedText": "Suas configurações foram salvas e aplicadas.",
|
||||||
|
"Import Monitor Configuration": "Importar Configuração do Monitor",
|
||||||
|
"ImportMonitorConfigurationText": "Fazer isso substituirá todas as alterações atualmente não salvas. As mudanças importadas só serão aplicadas quando você pressionar <b>Salvar</b>.",
|
||||||
|
"Paste JSON here.": "Cole o JSON aqui.",
|
||||||
|
"Delete Monitor": "Deletar Monitor",
|
||||||
|
"DeleteMonitorText": "Deseja excluir este monitor? Você não pode recuperá-lo. Os arquivos para essa ID permanecerão no sistema de arquivos. Se você optar por recriar um monitor com a mesma identificação, os vídeos e eventos tornar-se-ão visíveis no painel de controle.",
|
||||||
|
"Invalid JSON": "JSON inválido",
|
||||||
|
"InvalidJSONText": "Certifique-se de que esta seja uma string JSON válida para a configuração do monitor Shinobi.",
|
||||||
|
"Passwords don't match": "As senhas não combinam",
|
||||||
|
"No Events found for this video": "Nenhum evento encontrado para este vídeo",
|
||||||
|
"Video and Time Span (Minutes)": "Vídeo e intervalo de tempo (minutos)",
|
||||||
|
"Video Length (minutes) and Motion Count per video": "Comprimento do vídeo (minutos) e Contagem de movimento por vídeo",
|
||||||
|
"Counts of Motion": "Contagem de movimento",
|
||||||
|
"Unable to Launch": "Incapaz de executar",
|
||||||
|
"UnabletoLaunchText": "Salve primeiro o monitor novo. Em seguida, tente iniciar o editor da região.",
|
||||||
|
"NoVideosFoundForDateRange": "Nenhum vídeo encontrado neste intervalo de datas. Tente definir a data de início mais adiante.",
|
||||||
|
"monitorEditFailedMaxReached": "Sua conta atingiu o número máximo de câmeras que podem ser criadas. Fale com um administrador se você gostaria que isso mudasse.",
|
||||||
|
"in": "em",
|
||||||
|
"ago": "atrás",
|
||||||
|
"a few seconds": "alguns segundos",
|
||||||
|
"a minute": "um minuto",
|
||||||
|
"minutes": "minutos",
|
||||||
|
"an hour": "uma hora",
|
||||||
|
"hours": "horas",
|
||||||
|
"a day": "um dia",
|
||||||
|
"days": "dias",
|
||||||
|
"a month": "um mês",
|
||||||
|
"months": "meses",
|
||||||
|
"a year": "um ano",
|
||||||
|
"years": "anos",
|
||||||
|
"Identity": "Identidade",
|
||||||
|
"Input": "Entrada",
|
||||||
|
"Stream": "Transmissão",
|
||||||
|
"Stream Timestamp": "Transmitindo horário",
|
||||||
|
"Stream Watermark": "Transmitindo marca d'água",
|
||||||
|
"JPEG API": "JPEG API <small>Snapshot (cgi-bin)</small>",
|
||||||
|
"Recording": "Gravando",
|
||||||
|
"Recording Timestamp": "Gravando horário",
|
||||||
|
"Recording Watermark": "Gravando marca d'água",
|
||||||
|
"Region Editor": "Editor de região",
|
||||||
|
"Custom": "Customizado",
|
||||||
|
"Detector": "Detector",
|
||||||
|
"Connected": "Conectado",
|
||||||
|
"Not Connected": "Não conectado",
|
||||||
|
"Lisence Plate Detector": "Detector de placas",
|
||||||
|
"OpenCV Cascades": "OpenCV Cascatas",
|
||||||
|
"Refresh List of Cascades": "Atualizar Lista de Cascatas",
|
||||||
|
"\"No Motion\" Detector": "\"Sem movimento\" Detector",
|
||||||
|
"Control": "Controle",
|
||||||
|
"Grouping": "Agrupando <small>Adicione grupos em <b>Configurações</b></small>",
|
||||||
|
"Logging": "Logging",
|
||||||
|
"IdentityText1": "É assim que o sistema irá identificar os dados para este fluxo. Você não pode alterar o <b>ID do Monitor</b> uma vez que você pressionou salvar. Se você quiser, você pode fazer o <b>ID do Monitor</b> mais legível para humanos antes de continuar.",
|
||||||
|
"IdentityText2": "Você pode duplicar um monitor modificando o <b>ID do Monitor</b> e depois pressionando salvar. Você <b>não pode</b> usar o ID de um monitor que já existe ou ele economizará sobre as informações do banco de dados desse monitor.",
|
||||||
|
"noSpecialCharacters": "Sem espaços ou caracteres especiais.",
|
||||||
|
"NotesPlacholder": "Comentários que você quer deixar para as configurações desta câmera.",
|
||||||
|
"InputText1": "Esta seção diz a Shinobi como consumir um fluxo. Para um desempenho ideal, tente ajustar as configurações internas da sua câmera. Encontre as seguintes opções e defina-as como mostrado. Para encontrar sua câmera, você pode usar o <b>ONVIF Scanner embarcado</b> do Shinobi. Algumas câmeras ONVIF requerem o uso de uma ferramenta de gerenciamento para modificar suas configurações internas. Se você não consegue encontrar suas câmeras, você pode tentar <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">Gerenciador de dispositivos ONVIF para Windows</a>.",
|
||||||
|
"InputText2": "<ul><li><b>Taxa de quadros por segundo (FPS) :</b> High : 10 - 15 FPS, Low : 2-5 FPS</li><li><b>I-frame interval :</b> 80</li><li><b>Bit Rate Type :</b> CBR (Constant Bit Rate)</li><li><b>Bit Rate :</b> entre 256kbps - 500kbps</li></ul>",
|
||||||
|
"InputText3": "Se você precisar de ajuda para descobrir o tipo de entrada que sua câmera é, você pode dar uma olhada no <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">Camera URLs List</a> na página do Shinobi.",
|
||||||
|
"StreamText": "<p>Esta seção designará o método do fluxo primário e as configurações. Este fluxo será exibido no painel. Se você optar por usar HLS, JPEG ou MJPEG, então você pode consumir o fluxo através de outros programas.</p><p class=\"h_st_input h_st_jpeg\">Usar o fluxo de JPEG essencialmente desativa o fluxo primário e usa o compartimento de instantâneos para obter quadros.</p>",
|
||||||
|
"DetectorText": "<p>Quando as caixas de Largura e Altura são mostradas, você deve configurá-las para 640x480 ou abaixo. Isso otimizará a velocidade de leitura dos quadros.</p>",
|
||||||
|
"RecordingText": "Recomenda-se que você defina <b>Tipo de arquivo de gravação</b> para <b class=\"h_t_input h_t_jpeg h_t_socket\">WebM</b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">MP4</b> e <b>Video Codec</b> para <b class=\"h_t_input h_t_jpeg h_t_socket\">libvpx</b><b class=\"h_t_input h_t_h264 h_t_hls h_t_mp4\">copie ou </b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">libx264</b> porque seu <b>Tipo de Entrada</b> está definido para <b class=\"h_t_text\"></b>.",
|
||||||
|
"Name": "Nome",
|
||||||
|
"Retry Connection": "Tentar novamente a conexão <small>Número de vezes permitido falhar</small>",
|
||||||
|
"Notes": "Notas",
|
||||||
|
"Input Type": "Tipo de entrada",
|
||||||
|
"Connection Type": "Tipo de conexão",
|
||||||
|
"RTSP Transport": "Transporte RTSP",
|
||||||
|
"Host": "Host",
|
||||||
|
"Force Port": "Forçar porta",
|
||||||
|
"Path": "Caminho",
|
||||||
|
"Monitor Capture Rate": "Taxa de captura do monitor <small>(FPS)</small>",
|
||||||
|
"Analyzation Duration": "Duração da análise",
|
||||||
|
"Probe Size": "Probe Size",
|
||||||
|
"Stream Type": "Tipo de transmissão",
|
||||||
|
"# of Allow MJPEG Clients": "# para permitir clientes MJPEG <small>0 para infinito</small>",
|
||||||
|
"HLS Video Encoder": "Codificador de vídeo HLS",
|
||||||
|
"HLS Audio Encoder": "Codificador de áudio HLS",
|
||||||
|
"HLS Segment Length": "Comprimento do segmento HLS <small>em segundos</small>",
|
||||||
|
"HLS Preset": "Pré-definição HLS",
|
||||||
|
"HLS List Size": "Tamanho da lista HLS",
|
||||||
|
"Check Signal Interval": "Verifique o intervalo do sinal <small>em minutos</small>",
|
||||||
|
"Log Signal Event": "Evento de sinal de registro <small>Apenas cliente</small>",
|
||||||
|
"Quality": "Qualidade <small>1 para alta, 23 para Low</small>",
|
||||||
|
"Rate": "Taxa <small>(FPS)</small>",
|
||||||
|
"Width": "Largura",
|
||||||
|
"Height": "Altura",
|
||||||
|
"Rotate": "Rotação",
|
||||||
|
"Video Filter": "Filtro de vídeo",
|
||||||
|
"Font Path": "Caminho da fonte",
|
||||||
|
"Font Size": "Tamanho da fonte",
|
||||||
|
"Text Color": "Cor do texto",
|
||||||
|
"Text Box Color": "Cor da caixa de texto",
|
||||||
|
"Position X": "Posição X",
|
||||||
|
"Position Y": "Posição Y",
|
||||||
|
"Image Location": "Localização da imagem <small>Caminho Absoluto ou deixar em branco para usar global</small>",
|
||||||
|
"Image Position": "Posição da imagem",
|
||||||
|
"Frame Rate": "Taxa de quadros <small>(FPS)</small>",
|
||||||
|
"Image Width": "Largura da imagem",
|
||||||
|
"Image Height": "Altura da imagem",
|
||||||
|
"Record File Type": "Tipo de arquivo de gravação",
|
||||||
|
"Video Codec": "Video Codec",
|
||||||
|
"Preset": "Pré-definição",
|
||||||
|
"Audio Codec": "Audio Codec",
|
||||||
|
"Video Record Rate": "Taxa de gravação de vídeo <small>(FPS)</small>",
|
||||||
|
"Record Width": "Largura da gravação",
|
||||||
|
"Record Height": "Altura da gravação",
|
||||||
|
"Double Quote Directory": "Diretório com aspas duplas <small>Alguns diretórios têm espaços. Usar isso pode bloquear algumas câmeras.</small>",
|
||||||
|
"Recording Segment Interval": "Intervalo de Segmento de Gravação <small>em minutos</small>",
|
||||||
|
"Record Video Filter": "Gravar filtro de vídeo",
|
||||||
|
"Input Flags": "Flags de entrada",
|
||||||
|
"Snapshot Flags": "Snapshot Flags",
|
||||||
|
"Detector Flags": "Detector de Flags",
|
||||||
|
"Stream Flags": "Flags de Transmissão",
|
||||||
|
"Stream to YouTube": "Transmitir para o YouTube",
|
||||||
|
"Stream to YouTube Flags": "Transmitir para o YouTube Flags",
|
||||||
|
"Recording Flags": "Gravando Flags",
|
||||||
|
"Output Method": "Método de saída",
|
||||||
|
"Webhook": "Webhook",
|
||||||
|
"Webhook URL": "Webhook URL",
|
||||||
|
"Command on Trigger": "Comando quando acionado",
|
||||||
|
"Command": "Comando",
|
||||||
|
"Allow Next Command": "Habilitar próximo comando <small>em minutos</small>",
|
||||||
|
"Allow Next Trigger": "Habilitar próxima ação <small>em milissegundos</small>",
|
||||||
|
"Save Events to SQL": "Salvar eventos no SQL",
|
||||||
|
"Email on Trigger": "E-mail quando acionado <small>Emails vão para o endereço de login do titular da conta principal.</small>",
|
||||||
|
"Allow Next Email": "Permitir próximo e-mail <small>em minutos</small>",
|
||||||
|
"How to Record": "Como gravar",
|
||||||
|
"Trigger Record": "Acionar registro",
|
||||||
|
"Recording Timeout": "Gravando Timeout <small>em minutos</small>",
|
||||||
|
"Timeout Reset on Next Motion": "Timeout reiniciará no próximo movimento",
|
||||||
|
"Delete Motionless Video": "Deletar vídeos sem movimento",
|
||||||
|
"Send Frames": "Enviar quadros <small>Envie os quadros a serem analisados</small>",
|
||||||
|
"Detector Rate": "Taxa do detector <small>(FPS)</small>",
|
||||||
|
"Feed-in Image Width": "Largura da imagem de entrada",
|
||||||
|
"Feed-in Image Height": "Altura da imagem de entrada",
|
||||||
|
"Check for Motion First": "Verifique primeiro o movimento",
|
||||||
|
"Detect Objects": "Detectar objetos <small class=\"\">Veja abaixo</small>",
|
||||||
|
"Full Frame Detection": "Detecção de quadro completo",
|
||||||
|
"Country of Plates": "País das placas",
|
||||||
|
"Email on No Motion": "E-mail em \"Sem movimento\"",
|
||||||
|
"Timeout": "Timeout",
|
||||||
|
"Controllable": "Controlável",
|
||||||
|
"Custom Base URL": "URL Customizada <small>Deixe em branco para usar URL do Host</small>",
|
||||||
|
"Stop URL": "Parar URL",
|
||||||
|
"URL Stop Timeout": "URL timeout máximo <small>Parar URL depois de X milissegundos</small>",
|
||||||
|
"Center": "Centro <small>URL Address</small>",
|
||||||
|
"Left": "Esquerda <small>URL Address</small>",
|
||||||
|
"Left Stop": "Esquerda máxima <small>URL Address</small>",
|
||||||
|
"Right": "Direita <small>URL Address</small>",
|
||||||
|
"Right Stop": "Direita máxima <small>URL Address</small>",
|
||||||
|
"Up": "Cima <small>URL Address</small>",
|
||||||
|
"Up Stop": "Cima máximo <small>URL Address</small>",
|
||||||
|
"Down": "Baixo <small>URL Address</small>",
|
||||||
|
"Down Stop": "Baixo máximo <small>URL Address</small>",
|
||||||
|
"Enable Night Vision": "Ativar visão noturna <small>URL Address</small>",
|
||||||
|
"Disable Night Vision": "Desativar visão noturna <small>URL Address</small>",
|
||||||
|
"Zoom Out Stop": "Parar menos zoom <small>URL Address</small>",
|
||||||
|
"Zoom In Stop": "Parar mais zoom <small>URL Address</small>",
|
||||||
|
"Log Level": "Nível de registro",
|
||||||
|
"Save Log in SQL": "Salvar log em SQL <small>Isso pode encher rapidamente.</small>",
|
||||||
|
"JPEG": "JPEG",
|
||||||
|
"MJPEG": "MJPEG",
|
||||||
|
"H.264 / H.265 / H.265+": "H.264 / H.265 / H.265+",
|
||||||
|
"HLS (.m3u8)": "HLS (.m3u8)",
|
||||||
|
"MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)",
|
||||||
|
"Shinobi Streamer": "Shinobi Streamer",
|
||||||
|
"Dashcam (Streamer v2)": "Dashcam (Streamer v2)",
|
||||||
|
"Local": "Local",
|
||||||
|
"HTTP": "HTTP",
|
||||||
|
"HTTPS": "HTTPS",
|
||||||
|
"RTSP": "RTSP",
|
||||||
|
"UDP": "UDP",
|
||||||
|
"Auto": "Auto",
|
||||||
|
"TCP": "TCP",
|
||||||
|
"Base64 over Websocket": "Base64 sobre Websocket",
|
||||||
|
"JPEG (Auto Enables JPEG API)": "JPEG (Auto habilitado JPEG API)",
|
||||||
|
"HLS (includes Audio)": "HLS (inclui áudio)",
|
||||||
|
"libx264": "libx264",
|
||||||
|
"libx265": "libx265",
|
||||||
|
"copy": "copiar",
|
||||||
|
"No Audio": "Sem áudio",
|
||||||
|
"aac": "aac",
|
||||||
|
"ac3": "ac3",
|
||||||
|
"libmp3lame": "libmp3lame",
|
||||||
|
"No Rotation": "Sem rotação",
|
||||||
|
"180 Degrees": "180 Graus",
|
||||||
|
"90 Counter Clockwise and Vertical Flip (default)": "90 no sentido anti-horário e vertical (Padrão)",
|
||||||
|
"90 Clockwise": "90 no sentido horário",
|
||||||
|
"90 Clockwise and Vertical Flip": "90 no sentido horário e vertical",
|
||||||
|
"Top Right": "Superior direito",
|
||||||
|
"Top Left": "Superior esquerdo",
|
||||||
|
"Bottom Right": "Inferior direito",
|
||||||
|
"Bottom Left": "Inferior esquerdo",
|
||||||
|
"WebM (libvpx)": "WebM (libvpx)",
|
||||||
|
"MP4 (copy, libx264, libx265)": "MP4 (copy, libx264, libx265)",
|
||||||
|
"Default": "Padrão",
|
||||||
|
"libvpx (Default)": "libvpx (Padrão)",
|
||||||
|
"libvpx-vp9": "libvpx-vp9",
|
||||||
|
"libx264 (Default)": "libx264 (Padrão)",
|
||||||
|
"libvorbis (Default)": "libvorbis (Padrão)",
|
||||||
|
"libopus": "libopus",
|
||||||
|
"aac (Default)": "aac (Padrão)",
|
||||||
|
"Hotswap Modes (Watch-Only)": "Hotswap Modes (Visualizar Apenas)",
|
||||||
|
"Delete Motionless Videos (Record)": "Eliminar vídeos sem movimento (Gravação)",
|
||||||
|
"US": "US",
|
||||||
|
"EU": "EU",
|
||||||
|
"Silent": "Silencioso",
|
||||||
|
"Fatal": "Fatal",
|
||||||
|
"on Error": "em Erro",
|
||||||
|
"All Warnings": "Todos avisos",
|
||||||
|
"Debug": "Debugar",
|
||||||
|
"Export": "Exportar",
|
||||||
|
"Import": "Importar",
|
||||||
|
"Simple": "Simples",
|
||||||
|
"Advanced": "Avançado",
|
||||||
|
"Error Connecting": "Erro ao conectar",
|
||||||
|
"DB Lost.. Retrying..": "Banco de dados perdido... Repetindo...",
|
||||||
|
"Retrying...": "Repetindo...",
|
||||||
|
"Filter Matches": "Combinações de filtro",
|
||||||
|
"FilterMatchesText1": "Este filtro atingiu as condições.",
|
||||||
|
"FilterMatchesText2": "vídeos encontrados.",
|
||||||
|
"Executed": "Executado",
|
||||||
|
"Deleted": "Deletado",
|
||||||
|
"Query": "Pesquisa",
|
||||||
|
"Filter ID": "Filtrar ID",
|
||||||
|
"Webdav Error": "Erro Webdav",
|
||||||
|
"WebdavErrorText": "Não é possível salvar. Você criou os diretórios da câmera dentro do seu diretório de escolhido para isso?",
|
||||||
|
"File Not Exist": "Arquivo inexistente",
|
||||||
|
"FileNotExistText": "Não é possível salvar o arquivo inexistente. Algo deu errado.",
|
||||||
|
"CameraNotRecordingText": "As configurações podem ser incompatíveis. Verifique os encoders. Reiniciando...",
|
||||||
|
"Camera is not recording": "Câmera não está gravando",
|
||||||
|
"Camera is not streaming": "Câmera não está transmitindo",
|
||||||
|
"Restarting Process": "Reiniciado processo",
|
||||||
|
"Monitor Stopped": "Monitor parado",
|
||||||
|
"MonitorStoppedText": "A sessão do monitor foi ordenada a parar.",
|
||||||
|
"Monitor Idling": "Monitor ocioso",
|
||||||
|
"MonitorIdlingText": "A sessão do monitor foi ordenada para ocioso.",
|
||||||
|
"NoMotionEmailText1": "Nenhum movimento para",
|
||||||
|
"NoMotionEmailText2": "Não houve nenhum movimento detectado na câmera para",
|
||||||
|
"Monitor Name": "Nome do monitor",
|
||||||
|
"Process Unexpected Exit": "Saída inesperado do processo",
|
||||||
|
"Process Crashed for Monitor": "Processo de Monitor quebrado",
|
||||||
|
"FFmpegCantStart": "FFmpeg não pôde iniciar",
|
||||||
|
"FFmpegCantStartText": "O mecanismo de gravação para esta câmera não pôde começar. Pode haver algo errado com a configuração da sua câmera. Se houver algum registro diferente deste, por favor, coloque-os em <b> Problemas </b> no Github.",
|
||||||
|
"JPEG Error": "Erro JPEG",
|
||||||
|
"JPEGErrorText": "Houve um problema ao obter dados da sua câmera.",
|
||||||
|
"Fatal Maximum Reached": "Máximo atingido, parando câmera.",
|
||||||
|
"FatalMaximumReachedText": "Erro JPEG fatal.",
|
||||||
|
"Incorrect Settings Chosen": "Configuração incorreta escolhida",
|
||||||
|
"Can't Connect": "Não pode conectar",
|
||||||
|
"Video Finished": "Vídeo finalizado",
|
||||||
|
"No Monitor Found, Ignoring Request": "Monitor não encontrado, ignorando requisição",
|
||||||
|
"Event": "Evento",
|
||||||
|
"EventText1": "Disparou um evento de movimento",
|
||||||
|
"EventText2": "Não foi possível enviar imagem de e-mail, o arquivo não foi acessado",
|
||||||
|
"MailError": "MAIL ERROR : Não foi possível enviar e-mail, verifique conf.json. Ignorando qualquer recurso que dependa do envio",
|
||||||
|
"updateKeyText1": "\"updateKey\" faltando em \"conf.json\", não é possível atualizar dessa maneira até você adicionar",
|
||||||
|
"updateKeyText2": "\"updateKey\" incorreta",
|
||||||
|
"Control Error": "Erro de controle",
|
||||||
|
"ControlErrorText1": "Controle não está ativado",
|
||||||
|
"NotAuthorizedText1": "Não autorizado, envie o comando inicial com \"auth\",\"ke\", e \"uid\"",
|
||||||
|
"Fields cannot be empty": "Campos não podem estar vazios",
|
||||||
|
"AccountEditText1": "Não foi possível editar. Atualize a página se o problema continuar",
|
||||||
|
"Not an Administrator Account": "Não é uma conta de Administrador",
|
||||||
|
"superAdminText": "\"super.json\" não existe. Por favor, renomeie \"super.sample.json\" para \"super.json\".",
|
||||||
|
"Enter this code to proceed": "Informe este código para prosseguir",
|
||||||
|
"FactorAuthText1": "O código vai estar ativo somente por 15 minutos. Se você entrar novamente o temporizador será reiniciado para 15 minutos com o mesmo código",
|
||||||
|
"monitorEditText1": "Dados inválidos. Verifique se esta é uma string de importação válida.",
|
||||||
|
"monitorEditText2": "String de detalhes inválida. Certifique-se de ser uma string JSON e não um objeto comum que está sendo informado",
|
||||||
|
"Monitor Updated by user": "Monitor atualizado pelo usuário",
|
||||||
|
"Monitor Added by user": "Monitor adicionado pelo usuário",
|
||||||
|
"monitorGetText1": "Requisição incompleta. Remova a última barra da URL ou informe um valor válido",
|
||||||
|
"Monitor mode changed": "Modo de monitor mudou",
|
||||||
|
"Reset Timer": "Temporizador de reinicialização",
|
||||||
|
"Monitor mode is already": "Modo de monitor já está em uso",
|
||||||
|
"Monitor or Key does not exist.": "Monitor ou chave não existe",
|
||||||
|
"No Group with this key exists": "Nenhum grupo com esta chave foi encontrado",
|
||||||
|
"Trigger Successful": "Disparou bem sucedido",
|
||||||
|
"No such file": "Arquivo inexistente",
|
||||||
|
"modifyVideoText1": "Método não existe. Verifique se o último valor da URL não está em branco",
|
||||||
|
"CPU indicator will not work. Continuing...": "Indicador de CPU não irá funcionar. Continuando...",
|
||||||
|
"startUpText0": "Verificação de tamanho para vídeos",
|
||||||
|
"startUpText1": "Verificação de fim de tamanho para vídeos",
|
||||||
|
"startUpText2": "Todos usuário verificados. Aguarde para fechar arquivos abertos e remover arquivos por limite de usuário",
|
||||||
|
"startUpText3": " Esperando dar uma verificação de vídeo inacabada algum tempo. 3 segundos",
|
||||||
|
"startUpText4": "Iniciando todos os monitores para assistir e gravar",
|
||||||
|
"startUpText5": "Shinobi está pronto.",
|
||||||
|
"Edit": "Editar",
|
||||||
|
"Dashboard Language": "Idioma do Painel de Controle",
|
||||||
|
"File Not Found": "Arquivo não encontrado",
|
||||||
|
"No Monitor Exists with this ID.": "Não existem monitores com esse ID.",
|
||||||
|
"Cannot watch a monitor that isn't running.": "Não pode assistir um monitor que não está rodando.",
|
||||||
|
"Not Permitted": "Não permitidos",
|
||||||
|
"Not Authorized": "Não autorizados",
|
||||||
|
"Generate Subtitles": "Gerar legendas",
|
||||||
|
"Video Limit":"Limite de vídeo",
|
||||||
|
"Preview":"Visualização",
|
||||||
|
"Websocket Connected":"Websocket conectado",
|
||||||
|
"Websocket Disconnected":"Websocket desconectado",
|
||||||
|
"New Authentication Token":"Novo token de autenticação",
|
||||||
|
"All Logs":"Todos logs",
|
||||||
|
"For Group":"Para grupo",
|
||||||
|
"Basic Authentication":"Autenticação básica",
|
||||||
|
"Superuser Logs":"Logs do Superusuário",
|
||||||
|
"Authentication Failed":"Autenticação falhou",
|
||||||
|
"Max Number of Cameras":"Número máximo de câmeras",
|
||||||
|
"Can edit Max Storage":"Pode editar Armazenamento Máximo",
|
||||||
|
"Can edit Max Days":"Pode editar Máximo de Dias",
|
||||||
|
"in Days":"em Dias",
|
||||||
|
"Can edit how long to keep Logs":"Pode editar por quanto tempo maneter logs",
|
||||||
|
"Can use Admin Panel":"Pode usar Painel Administrativo",
|
||||||
|
"Can use WebDAV":"Pode usar WebDAV",
|
||||||
|
"Can use LDAP":"Pode usar LDAP",
|
||||||
|
"Can edit how long to keep Events":"Pode editar quanto tempo manter eventos",
|
||||||
|
"Leave blank for unlimited":"Deixe em branco para ilimitado",
|
||||||
|
"Limited":"Limitado",
|
||||||
|
"All Privileges":"Todos Privilégios",
|
||||||
|
"LDAP":"LDAP",
|
||||||
|
"LDAP Success":"LDAP Sucesso",
|
||||||
|
"LDAP User Authenticated":"Usuário LDAP Usuário Autenticado",
|
||||||
|
"LDAP User is New":"Usuário LDAP é Novo",
|
||||||
|
"Creating New Account":"Criando Nova Conta",
|
||||||
|
"bindDN":"Vincular DN",
|
||||||
|
"Bind Credentials":"Vincular Credenciais (Senha)",
|
||||||
|
"Search Base":"Base de Pesquisa",
|
||||||
|
"Mode": "Modo",
|
||||||
|
"Search Filter":"Procurar Filtro"
|
||||||
|
}
|
|
@ -0,0 +1,496 @@
|
||||||
|
{
|
||||||
|
"\"No Motion\" Detector": "\"Нет Движения\" Детектор",
|
||||||
|
"# of Allow MJPEG Clients": "# of Allow MJPEG Clients <small>0 for infinite</small>",
|
||||||
|
"180 Degrees": "180 градусов",
|
||||||
|
"2-Factor Authentication": "2-Факторной Аутентификации",
|
||||||
|
"90 Clockwise": "90 по часовой стрелке",
|
||||||
|
"90 Clockwise and Vertical Flip": "90 по часовой стрелке и вертикальный флип",
|
||||||
|
"90 Counter Clockwise and Vertical Flip (default)": "90 против часовой стрелки и по вертикали (по умолчанию)",
|
||||||
|
"API": "API-интерфейс",
|
||||||
|
"API Key Added": "Ключ API добавлены",
|
||||||
|
"API Key Deleted": "API-ключ удален",
|
||||||
|
"API Keys": "Ключи API",
|
||||||
|
"APIKeyAddedText": "Вы можете использовать этот ключ сейчас.",
|
||||||
|
"APIKeyDeletedText": "Ключ был удален. Он больше не будет работать.",
|
||||||
|
"ASC": "АСК",
|
||||||
|
"Account Info": "Счета Информация",
|
||||||
|
"AccountEditText1": "Не мог изменить. Обновить страницу, если проблема продолжается.",
|
||||||
|
"Accounts": "Счетов",
|
||||||
|
"Action for Selected": "Действие для выбранных",
|
||||||
|
"Add": "Добавить",
|
||||||
|
"Add Monitor": "Добавить Монитор",
|
||||||
|
"Add New": "Добавить Новый",
|
||||||
|
"Admin": "Админ",
|
||||||
|
"Advanced": "Расширенный",
|
||||||
|
"Again": "Снова",
|
||||||
|
"All Monitors": "Все Мониторы",
|
||||||
|
"All Monitors and Privileges": "Все мониторы и привилегии",
|
||||||
|
"All Warnings": "Все Предупреждения",
|
||||||
|
"Allow Next Command": "Разрешить следующей команды <small>в течение нескольких минут</small>",
|
||||||
|
"Allow Next Email": "Разрешить следующей электронной почте <small>в течение нескольких минут</small>",
|
||||||
|
"Allow Next Trigger": "Допустить следующего триггера <small>в Миллисекундах</small>",
|
||||||
|
"Allowed IPs": "Допускается ИПС",
|
||||||
|
"Analyzation Duration": "Продолжительность Анализа",
|
||||||
|
"Archive": "Архив",
|
||||||
|
"Audio Codec": "Аудио Кодек",
|
||||||
|
"Authenticate": "Аутентифицировать",
|
||||||
|
"Auto": "Авто",
|
||||||
|
"Autosave": "Автосохранение",
|
||||||
|
"Base64 over Websocket": "В base64 через websocket",
|
||||||
|
"Bottom Left": "Внизу Слева",
|
||||||
|
"Bottom Right": "Нижний Правый",
|
||||||
|
"Browser Console Log": "Консоли Браузера Войти",
|
||||||
|
"CPU": "Процессор",
|
||||||
|
"CPU indicator will not work. Continuing...": "Индикатор процессора не будет работать. Продолжение...",
|
||||||
|
"CSS": "В CSS <small>Стиль вашей приборной панели.</small>",
|
||||||
|
"Calendar": "Календарь",
|
||||||
|
"Camera Password": "Пароль Камеры",
|
||||||
|
"Camera Username": "Имя Пользователя Камеры",
|
||||||
|
"Camera is not recording": "Камера не записывает",
|
||||||
|
"CameraNotRecordingText": "Параметры могут быть несовместимы. Проверить датчики. Перезапуск...",
|
||||||
|
"Can Control Monitors": "Может Управлять Мониторами",
|
||||||
|
"Can Delete Videos": "Можно Удалять Видео",
|
||||||
|
"Can Delete Videos and Events": "Можно удалять видео и событий",
|
||||||
|
"Can Edit Monitor": "Можете Редактировать Монитор",
|
||||||
|
"Can Get Logs": "Можете Сделать Логи",
|
||||||
|
"Can Get Monitors": "Можете Сделать Мониторы",
|
||||||
|
"Can View Monitor": "Можно Посмотреть Монитор",
|
||||||
|
"Can View Snapshots": "Можете Посмотреть Снимки",
|
||||||
|
"Can View Streams": "Можете Посмотреть Потоков",
|
||||||
|
"Can View Videos": "Можете Посмотреть Видео",
|
||||||
|
"Can View Videos and Events": "Можете посмотреть видео и событий",
|
||||||
|
"Can't Connect": "Не могу подключиться",
|
||||||
|
"Center": "Центр <small>URL-Адрес</small>",
|
||||||
|
"Chat on Discord": "Чат на раздор",
|
||||||
|
"Check": "Проверить",
|
||||||
|
"Check Signal Interval": "Проверка сигнала интервал <small>в минутах</small>",
|
||||||
|
"Check for Motion First": "Проверить в первую очередь для движения",
|
||||||
|
"Close": "Закрыть",
|
||||||
|
"Closed": "Закрытые",
|
||||||
|
"Command": "Команда",
|
||||||
|
"Command on Trigger": "Команду на триггер",
|
||||||
|
"Complete Stream URL": "Полный URL-адрес потока",
|
||||||
|
"Confirm": "Подтвердить",
|
||||||
|
"Connected": "Подключен",
|
||||||
|
"Connection Type": "Тип Подключения",
|
||||||
|
"Control": "Контроль",
|
||||||
|
"Control Error": "Ошибка Контроля",
|
||||||
|
"ControlErrorText1": "Контроль не включен",
|
||||||
|
"Controllable": "Управляема",
|
||||||
|
"Country of Plates": "Страна пластин",
|
||||||
|
"Counts of Motion": "Подсчитывает движения",
|
||||||
|
"Current": "Тока",
|
||||||
|
"Currently viewing": "В настоящее время просмотр",
|
||||||
|
"Custom": "Заказ",
|
||||||
|
"Custom Base URL": "Базовый пользовательский URL-адрес <small>оставить пустым, чтобы использовать URL-адрес узла</small>",
|
||||||
|
"DB Lost.. Retrying..": "База Данных Потеряла.. Повтор..",
|
||||||
|
"DESC": "Описание",
|
||||||
|
"Dashboard": "Приборной панели",
|
||||||
|
"Dashboard Language": "Язык Приборной Панели",
|
||||||
|
"Dashcam": "Автомобильный видеорегистратор",
|
||||||
|
"Dashcam (Streamer v2)": "Автомобильный видеорегистратор (Стример П2)",
|
||||||
|
"Date Range": "Диапазон Дат",
|
||||||
|
"Debug": "Отлаживать",
|
||||||
|
"Default": "По умолчанию",
|
||||||
|
"Delete": "Удалить",
|
||||||
|
"Delete Filter": "Удалить Фильтр",
|
||||||
|
"Delete Matches": "Удалить Играм",
|
||||||
|
"Delete Monitor": "Удалить Монитор",
|
||||||
|
"Delete Motionless Video": "Удалить Недвижно Видео",
|
||||||
|
"Delete Motionless Videos (Record)": "Удалить Неподвижными Видео (Запись)",
|
||||||
|
"Delete Selected Videos": "Удаление Выбранного Видео",
|
||||||
|
"Delete Video": "Удалить Видео",
|
||||||
|
"Delete selected": "Удалить выбранные",
|
||||||
|
"DeleteMonitorText": "Вы действительно хотите удалить этот монитор? Нельзя восстановить. Файлы для этот идентификатор будет оставаться в файловой системе. Если вы решили воссоздать монитора с одинаковым кодом видео и события станут видны в личном кабинете.",
|
||||||
|
"DeleteSelectedVideosMsg": "Вы действительно хотите удалить эти видео? Вы не сможете восстановить их.",
|
||||||
|
"DeleteVideoMsg": "Вы действительно хотите удалить это видео? Нельзя восстановить.",
|
||||||
|
"Deleted": "Удален",
|
||||||
|
"Detect Objects": "Обнаруживать объекты <small class=\"\">ниже</small>",
|
||||||
|
"Detector": "Детектор",
|
||||||
|
"Detector Flags": "Флаги Детектор",
|
||||||
|
"Detector Rate": "Детектор скорости <small>(ФПС)</small>",
|
||||||
|
"DetectorText": "<p>Когда показана Ширина и Высота коробки, вы должны установить их до 640х480 или ниже. Это позволит оптимизировать скорость чтения кадров.</p>",
|
||||||
|
"Disable Night Vision": "Отключить ночное видение <small>URL-Адрес</small>",
|
||||||
|
"Disable Nightvision": "Отключение Ночного Видения",
|
||||||
|
"Disabled": "Отключен",
|
||||||
|
"Documentation": "Документация",
|
||||||
|
"Don't show this anymore": "Больше не показывать это",
|
||||||
|
"Double Quote Directory": "Двойная Кавычка каталога <small>у некоторых каталогов есть пробелы. С помощью этого может произойти сбой некоторых камер.</small>",
|
||||||
|
"Down": "Вниз <small>URL-Адрес</small>",
|
||||||
|
"Down Stop": "Вниз стоп <small>URL-Адрес</small>",
|
||||||
|
"Download": "Скачать",
|
||||||
|
"EU": "ЕС",
|
||||||
|
"Edit": "Редактировать",
|
||||||
|
"Email": "Электронной почты",
|
||||||
|
"Email Details": "Подробности По Электронной Почте",
|
||||||
|
"Email on No Motion": "Электронной почты на \"нет движения\"",
|
||||||
|
"Email on Trigger": "Электронной почты на Триггерных <small>писем перейти к главной владельца счета адрес для входа.</small>",
|
||||||
|
"Enable Night Vision": "Включение ночного видения <small>URL-Адрес</small>",
|
||||||
|
"Enable Nightvision": "Включение Ночного Видения",
|
||||||
|
"Enabled": "Включен",
|
||||||
|
"End": "Конец",
|
||||||
|
"End Time": "Время Окончания",
|
||||||
|
"Ended": "Закончился",
|
||||||
|
"Enlarge": "Увеличить",
|
||||||
|
"Enter this code to proceed": "Введите этот код, чтобы продолжить",
|
||||||
|
"Equal to": "Равна",
|
||||||
|
"Error Connecting": "Ошибка Подключения",
|
||||||
|
"Event": "Событие",
|
||||||
|
"Event Limit": "Лимит Событие",
|
||||||
|
"EventText1": "Срабатывает событие движения в",
|
||||||
|
"EventText2": "Не мог изображения по электронной почте, файл не был доступен",
|
||||||
|
"Events": "События",
|
||||||
|
"Example": "Пример",
|
||||||
|
"Execute Command": "Выполнить Команду",
|
||||||
|
"Executed": "Выполнен",
|
||||||
|
"Export": "Экспорт",
|
||||||
|
"FFmpegCantStart": "Видео не смог запустить",
|
||||||
|
"FFmpegCantStartText": "Запись двигатель для этой камеры не удалось запустить. Там может быть что-то не так с настройкой камеры. Если есть какие-либо другие журналы, чем этот, пожалуйста, пишите в <b>вопросы</b> на github.",
|
||||||
|
"FFmpegTip": "FFprobe-простой мультимедийный анализатор потоков. Вы можете использовать его для вывода всевозможной информации о входных данных, включая Продолжительность, частоту кадров, Размер кадра и т. д.",
|
||||||
|
"FFprobe": "Зонд",
|
||||||
|
"FactorAuthText1": "Код будет активна только в течение 15 минут. Если вы войти снова, Таймер будет сброшен до 15 минут с тем же кодом.",
|
||||||
|
"Fatal": "Роковой",
|
||||||
|
"Fatal Maximum Reached": "Роковой Максимальным Достигнутым, Останавливая Камеру.",
|
||||||
|
"FatalMaximumReachedText": "Ошибка JPEG был смертельным.",
|
||||||
|
"Feed-in Image Height": "Кормить-в Высота изображения",
|
||||||
|
"Feed-in Image Width": "Кормить-в изображения Ширина",
|
||||||
|
"Fields cannot be empty": "Поля не могут быть пустыми",
|
||||||
|
"File Not Exist": "Файл Не Существует",
|
||||||
|
"File Not Found": "Файл Не Найден",
|
||||||
|
"File Type": "Тип Файла",
|
||||||
|
"FileNotExistText": "Не удается сохранить файл не существует. Что-то пошло не так.",
|
||||||
|
"Filename": "Именем",
|
||||||
|
"Filesize": "Размер",
|
||||||
|
"Filter ID": "Идентификатор фильтра",
|
||||||
|
"Filter Matches": "Фильтра",
|
||||||
|
"Filter Name": "Название Фильтра",
|
||||||
|
"FilterMatchesText1": "Этот фильтр имеет условия.",
|
||||||
|
"FilterMatchesText2": "видео нашли.",
|
||||||
|
"Filters": "Фильтры",
|
||||||
|
"Filters Updated": "Фильтры Обновлены",
|
||||||
|
"FiltersUpdatedText": "Ваши изменения были сохранены и применены.",
|
||||||
|
"Find Where": "Найти Где",
|
||||||
|
"Fix": "Исправить",
|
||||||
|
"Fix Video": "Исправить Видео",
|
||||||
|
"FixVideoMsg": "Вы хотите, чтобы удалить это видео? Вы не можете отменить это действие.",
|
||||||
|
"Font Path": "Путь Шрифта",
|
||||||
|
"Font Size": "Размер Шрифта",
|
||||||
|
"Force Port": "Сила Порта",
|
||||||
|
"Found Devices": "Найденные Устройства",
|
||||||
|
"Frame Rate": "Частота кадров <small>(кадров / с)</small>",
|
||||||
|
"Full Frame Detection": "Полное Обнаружение Кадра",
|
||||||
|
"Fullscreen": "Полноэкранный",
|
||||||
|
"Greater Than": "Больше",
|
||||||
|
"Greater Than or Equal to": "Больше или равна",
|
||||||
|
"Group Key": "Ключевые Группы",
|
||||||
|
"Group Name": "Название Группы",
|
||||||
|
"Grouping": "Группировка ",
|
||||||
|
"H.264 / H.265 / H.265+": "Формат H. 264 / H. 265 / H. 265 В ",
|
||||||
|
"HLS (.m3u8)": "ЗОЖ (.m3u8 форматов)",
|
||||||
|
"HLS (includes Audio)": "ЗОЖ (включает Аудио)",
|
||||||
|
"HLS Audio Encoder": "ЗОЖ Аудио Шифратор",
|
||||||
|
"HLS List Size": "Размер списка ЗОЖ",
|
||||||
|
"HLS Preset": "ЗОЖ предустановленных",
|
||||||
|
"HLS Segment Length": "ЗОЖ сегмент длиной <small>в секунд</small>",
|
||||||
|
"HLS Video Encoder": "ЗОЖ видео Энкодера",
|
||||||
|
"HTTP": "Протокол http",
|
||||||
|
"HTTPS": "Протоколу https",
|
||||||
|
"Height": "Высота",
|
||||||
|
"Help": "Помогите",
|
||||||
|
"Hide List": "Скрыть Список",
|
||||||
|
"Hide Notes": "Скрыть Примечания",
|
||||||
|
"Host": "Хозяин",
|
||||||
|
"Hotswap Modes (Watch-Only)": "Режима Горячей Замены (Часы Только)",
|
||||||
|
"How to Record": "Как записать",
|
||||||
|
"IP Address": "IP-адрес",
|
||||||
|
"Identity": "Личность",
|
||||||
|
"IdentityText1": "Это как система будет определять данные для этого потока. Вы не можете изменить <b>идентификатор монитора</b> после того, как вы нажали \"сохранить\". Если вы хотите, вы можете сделать <b>монитор код</b> более читабельным, прежде чем продолжить.",
|
||||||
|
"IdentityText2": "Вы можете дублировать монитор, изменяя <b>идентификатор монитора</b> нажмите клавишу сохранить. Вы <b>не можете</b> использовать идентификатор монитора, который уже существует или он сохранит за монитора базы данных.",
|
||||||
|
"Idle": "Праздный",
|
||||||
|
"Image Height": "Высота Изображения",
|
||||||
|
"Image Location": "Изображения Расположение <small>абсолютный путь или оставьте поле пустым, чтобы использовать глобальные</small>",
|
||||||
|
"Image Position": "Положение Изображения",
|
||||||
|
"Image Width": "Ширина Изображения",
|
||||||
|
"Import": "Импорт",
|
||||||
|
"Import Monitor Configuration": "Импорт Конфигурации Монитора",
|
||||||
|
"ImportMonitorConfigurationText": "Это overrwrite любые изменения в настоящее время не сохранены. Импортированные изменения будут применены только при нажатии <b>сохранить</b>.",
|
||||||
|
"In": "В",
|
||||||
|
"Incorrect Settings Chosen": "Выбраны Неправильные Параметры",
|
||||||
|
"Indifference": "Равнодушие",
|
||||||
|
"Input": "Вход",
|
||||||
|
"Input Flags": "Входных Флагов",
|
||||||
|
"Input Type": "Тип Входного Сигнала",
|
||||||
|
"InputText1": "Этот раздел рассказывает шиноби, как использовать поток. Для оптимальной производительности, попробуйте настройки внутренних параметров камеры. Найти следующие варианты и установить их, как показано. Чтобы найти вашу камеру, вы можете использовать <b>встроенный onvif и сканер</b> шиноби. Некоторые камеры onvif требуют использования инструмента управления, чтобы изменить свои внутренние настройки. Если Вы не можете найти вашей камеры вы можете попробовать <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">onvif и диспетчер устройств для Windows</a>.",
|
||||||
|
"InputText2": "<ul><li><b>Кадров (fps) :</b> высокая : 10 - 15 ФПС, минимум : 2-5 ФПС</li><li><b>I-кадр интервал :</b> 80</li><li><b>Тип битрейта :</b> CBR (Постоянный Битрейт)</li><li><b>Битрейт :</b> между 256кбит / с - 500 Кбит / с</li></ul>",
|
||||||
|
"InputText3": "Если вам нужна помощь в выяснение того, что входной тип Вашей камеры вы можете посмотреть в <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">камеры URL-адреса в списке</a> на шиноби сайт.",
|
||||||
|
"Invalid JSON": "Недопустимый Формат json",
|
||||||
|
"InvalidJSONText": "Пожалуйста, убедитесь, что это действительный json-строку для конфигурации шиноби монитор.",
|
||||||
|
"JPEG": "В формате JPEG",
|
||||||
|
"JPEG (Auto Enables JPEG API)": "В формате JPEG (авто позволит использовать API в формате JPEG)",
|
||||||
|
"JPEG API": "В формате JPEG интерфейс API <small>снимка (цги-бин)</small>",
|
||||||
|
"JPEG Error": "Ошибка формата JPEG",
|
||||||
|
"JPEG Mode": "JPEG режим",
|
||||||
|
"JPEGErrorText": "Возникла проблема получения данных с камеры.",
|
||||||
|
"Leave blank for random.": "Оставьте пустым для случайных.",
|
||||||
|
"Left": "Левый <small>Адрес</small>",
|
||||||
|
"Left Stop": "Левый стоп <small>URL-Адрес</small>",
|
||||||
|
"Less Than": "Меньше",
|
||||||
|
"Less Than or Equal to": "Меньше или равно",
|
||||||
|
"Like": "Как",
|
||||||
|
"Lisence Plate Detector": "Лицензии Детектор Пластины",
|
||||||
|
"List Toggle": "Список Тумблер",
|
||||||
|
"Live Stream Toggle": "Жить Переключения Потока",
|
||||||
|
"Live View": "Живой Просмотр",
|
||||||
|
"Local": "Местные",
|
||||||
|
"Log Level": "Уровень Журнала",
|
||||||
|
"Log Signal Event": "Журнал сигнал события <small>на стороне клиента только</small>",
|
||||||
|
"Logging": "Лесозаготовки",
|
||||||
|
"Login": "Логин",
|
||||||
|
"Logout": "Выход",
|
||||||
|
"Logs": "Журналы",
|
||||||
|
"MB": "МБ",
|
||||||
|
"MJPEG": "Формат MJPEG",
|
||||||
|
"MP4 (copy, libx264, libx265)": "МР4 (копия, поддержкой libx264, libx265)",
|
||||||
|
"MPEG-4 (.mp4 / .ts)": "Формат MPEG-4 (.МР4 / .ТС)",
|
||||||
|
"MailError": "Mail ошибка : не удалось отправить письмо, проверьте конф.в json. Пропуская какие-либо функции, опираясь на рассылки.",
|
||||||
|
"Matches": "Матчи",
|
||||||
|
"Max Storage Amount": "Памяти Макс. объем <small>в мегабайтах</small>",
|
||||||
|
"Mode": "Режим",
|
||||||
|
"Monitor": "Монитор",
|
||||||
|
"Monitor Added by user": "Монитор, добавленные пользователем.",
|
||||||
|
"Monitor Capture Rate": "Монитор скорости захвата <small>(ФПС)</small>",
|
||||||
|
"Monitor Groups": "Мониторинг Групп",
|
||||||
|
"Monitor ID": "Идентификатор монитора",
|
||||||
|
"Monitor Idling": "Монитор Простаивания",
|
||||||
|
"Monitor Name": "Имя Монитора",
|
||||||
|
"Monitor Settings": "Настройки Монитора",
|
||||||
|
"Monitor Stopped": "Монитор Перестал",
|
||||||
|
"Monitor Updated by user": "Монитор обновляться пользователем.",
|
||||||
|
"Monitor mode changed": "Режим монитора меняется",
|
||||||
|
"Monitor mode is already": "Режим монитора уже",
|
||||||
|
"Monitor or Key does not exist.": "Монитор или ключ не существует.",
|
||||||
|
"MonitorIdlingText": "Монитор сессии был заказан на холостом ходу.",
|
||||||
|
"MonitorStoppedText": "Монитор сеансов было приказано прекратить.",
|
||||||
|
"Monitors": "Мониторы",
|
||||||
|
"Monitors per row": "Мониторы на строку <small>для монтажа</small>",
|
||||||
|
"Montage": "Фотомонтаж",
|
||||||
|
"Motion GUI": "ГУЙ движения",
|
||||||
|
"Motion Meter": "Метр Движения",
|
||||||
|
"Name": "Название",
|
||||||
|
"No": "Нет",
|
||||||
|
"No Audio": "Нет Звука",
|
||||||
|
"No Data": "Нет Данных",
|
||||||
|
"No Events found for this video": "Не для этого видео",
|
||||||
|
"No Group with this key exists": "Ни одна группа с таким ключом существует",
|
||||||
|
"No Monitor Found, Ignoring Request": "Нет Монитор Нашли, Игнорируя Просьбу",
|
||||||
|
"No Rotation": "Нет Вращения",
|
||||||
|
"No such file": "Нет такого файла",
|
||||||
|
"NoMotionEmailText1": "Нет движения",
|
||||||
|
"NoMotionEmailText2": "Не было никакого движения на камеру",
|
||||||
|
"NoVideosFoundForDateRange": "Не нашла видео в этот диапазон дат. Попробуйте установить дату начала дальше.",
|
||||||
|
"Not Authorized": "Не Разрешено",
|
||||||
|
"Not Connected": "Не Подключен",
|
||||||
|
"Not Equal to": "Не равны",
|
||||||
|
"Not In": "Не В",
|
||||||
|
"Not Matches": "Не Соответствует",
|
||||||
|
"Not Permitted": "Не Допускается",
|
||||||
|
"Not an Administrator Account": "Не является учетной записью администратора",
|
||||||
|
"NotAuthorizedText1": "Не разрешенные, представить команду init с \"авт\",\"ке\" и \"юид\"",
|
||||||
|
"Notes": "Примечания",
|
||||||
|
"NotesPlacholder": "Комментарии Вы хотите оставить на этом настройки камеры.",
|
||||||
|
"Number of Days to keep": "Количество дней хранения",
|
||||||
|
"ONVIF": "Стандарт onvif",
|
||||||
|
"ONVIF Scanner": "Сканер стандарта onvif",
|
||||||
|
"ONVIFnote": "Откройте стандарт onvif устройств за пределами вашей сети или оставьте его пустым для сканирования сети. <br>Имя пользователя и пароль можно оставить пустым.",
|
||||||
|
"OpenCV Cascades": "В Формате Opencv Каскада",
|
||||||
|
"Order Streams": "Потоки Заказов",
|
||||||
|
"Output Method": "Способ Вывода",
|
||||||
|
"Password": "Пароль",
|
||||||
|
"Password Again": "Пароль Еще Раз",
|
||||||
|
"Passwords don't match": "Пароли не совпадают",
|
||||||
|
"Paste JSON here.": "Вставить json здесь.",
|
||||||
|
"Path": "Путь",
|
||||||
|
"Permissions": "Разрешения",
|
||||||
|
"Points": "Точки <small>при добавлении точек, щелкните на краю полигона.</small>",
|
||||||
|
"Port": "Порт",
|
||||||
|
"Position X": "Положение X",
|
||||||
|
"Position Y": "Позиция Y",
|
||||||
|
"Power Video Viewer": "Питания Видео Просмотра",
|
||||||
|
"Power Viewer": "Зритель Власти",
|
||||||
|
"Preferences": "Предпочтения",
|
||||||
|
"Preset": "Предустановленные",
|
||||||
|
"Probe Size": "Размер Зонда",
|
||||||
|
"Process Crashed for Monitor": "Процесс разбился на монитор",
|
||||||
|
"Process Unexpected Exit": "Процесс Неожиданный Выход",
|
||||||
|
"Profile": "Профиль",
|
||||||
|
"Quality": "Качество <small>1 высота, 23 низкий</small>",
|
||||||
|
"Query": "Запрос",
|
||||||
|
"RAM": "Оперативной памяти",
|
||||||
|
"RTSP": "Протокол RTSP",
|
||||||
|
"RTSP Transport": "РЦП транспорта",
|
||||||
|
"Range or Single": "Диапазон или один",
|
||||||
|
"Rate": "Скорость <small>(кадров в секунду)</small>",
|
||||||
|
"Record": "Запись",
|
||||||
|
"Record File Type": "Тип Записи Файла",
|
||||||
|
"Record Height": "Рекордную Высоту",
|
||||||
|
"Record Video Filter": "Запись Видео Фильтр",
|
||||||
|
"Record Width": "Запись Ширина",
|
||||||
|
"Recording": "Запись",
|
||||||
|
"Recording Flags": "Запись Флаги",
|
||||||
|
"Recording Segment Interval": "Запись сегмента интервала <small>в минутах</small>",
|
||||||
|
"Recording Timeout": "Запись тайм-аута <small>в минутах</small>",
|
||||||
|
"Recording Timestamp": "Метки Записи",
|
||||||
|
"Recording Watermark": "Запись Водяной Знак",
|
||||||
|
"RecordingText": "Рекомендуется установить <b>рекорд типа файла</b> в <b class=\"h_t_input h_t_jpeg h_t_socket\">формате WebM</b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">и MP4</b> и <b>видео кодеков</b> для <b class=\"h_t_input h_t_jpeg h_t_socket\">libvpx</b><b class=\"h_t_input h_t_h264 h_t_hls h_t_mp4\">копия или </b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">поддержкой libx264</b> потому что твой <b>ввод Тип</b> имеет значение <b class=\"h_t_text\"></b>.",
|
||||||
|
"Refresh List of Cascades": "Обновить список каскадов",
|
||||||
|
"Region Editor": "Редактор Области",
|
||||||
|
"Region Name": "Название Области",
|
||||||
|
"RegionNote": "Точки сохраняются только при нажатии <b>Сохранить</b> на <b>монитор настройки</b> окна.",
|
||||||
|
"Regions": "Регионы",
|
||||||
|
"Remember Me": "Запомнить Меня",
|
||||||
|
"Reset Timer": "Сброс Таймера",
|
||||||
|
"Restarting Process": "Процесс Перезагрузки",
|
||||||
|
"Retry Connection": "Повторить попытку подключения <small>несколько раз допустить провала</small>",
|
||||||
|
"Retrying...": "Повторение...",
|
||||||
|
"Right": "Правильный <small>URL-Адрес</small>",
|
||||||
|
"Right Stop": "Право прекратить <small>URL-Адрес</small>",
|
||||||
|
"Rotate": "Повернуть",
|
||||||
|
"Save": "Сохранить",
|
||||||
|
"Save Directory": "Сохранить Каталог",
|
||||||
|
"Save Events to SQL": "Сохранять события в SQL",
|
||||||
|
"Save Log in SQL": "Сохранить журнал в SQL <small>это может быстро заполняются.</small>",
|
||||||
|
"Save as": "Сохранить как",
|
||||||
|
"Saved Filters": "Сохраненные Фильтры",
|
||||||
|
"Scan Settings": "Параметры Сканирования",
|
||||||
|
"Search": "Поиск",
|
||||||
|
"Send Frames": "Отправить кадры <small>пуш-периодах для анализа</small>",
|
||||||
|
"Separate with commas, no spaces": "Отделить запятыми, без пробелов",
|
||||||
|
"Set to Watch Only": "Установить, чтобы смотреть только",
|
||||||
|
"Settings": "Параметры",
|
||||||
|
"Settings Changed": "Настройки Изменились",
|
||||||
|
"SettingsChangedText": "Ваши настройки были сохранены и применены.",
|
||||||
|
"Shinobi": "Шиноби",
|
||||||
|
"Shinobi Streamer": "Шиноби Серпантин",
|
||||||
|
"Show Logs": "Показать Журналы",
|
||||||
|
"Silent": "Молчит",
|
||||||
|
"Simple": "Простой",
|
||||||
|
"Size (mb)": "Размер (Мб)",
|
||||||
|
"Snapshot": "Снимок",
|
||||||
|
"Snapshot Flags": "Снимок Флаги",
|
||||||
|
"Snapshots": "Снимки",
|
||||||
|
"Sort By": "Сортировать По",
|
||||||
|
"Start": "Начать",
|
||||||
|
"Start Recording": "Начать Запись",
|
||||||
|
"Start Time": "Время Начала",
|
||||||
|
"Started": "Начал",
|
||||||
|
"Status Indicator": "Индикатор Состояния",
|
||||||
|
"Stop URL": "Остановить URL",
|
||||||
|
"Stream": "Поток",
|
||||||
|
"Stream Flags": "Флаги Трансляция",
|
||||||
|
"Stream Timestamp": "Метка Поток",
|
||||||
|
"Stream Type": "Тип Потока",
|
||||||
|
"Stream Watermark": "Водяной Поток",
|
||||||
|
"Stream to YouTube": "Трансляцию на YouTube",
|
||||||
|
"Stream to YouTube Flags": "Поток флаги на YouTube",
|
||||||
|
"StreamText": "<p>В этом разделе будет указать основной поток метода и его параметров. Этот поток будет отображаться на приборной панели. Если вы решите использовать ЗОЖ, в формате JPEG или MJPEG, то вы можете потреблять поток через другие программы.</p><p class=\"h_st_input h_st_jpeg\">В формате JPEG потока, по сути, выключает основной поток и использует моментальный снимок ящика, чтобы получить кадры.</p>",
|
||||||
|
"Streamer": "Серпантин",
|
||||||
|
"Streams": "Потоки",
|
||||||
|
"Superuser": "Суперпользователя",
|
||||||
|
"Switch on for Still Image": "Переключиться на еще изображения",
|
||||||
|
"TCP": "Протокол TCP",
|
||||||
|
"Text Box Color": "Цвет Текстового Поля",
|
||||||
|
"Text Color": "Цвет Текста",
|
||||||
|
"Time-lapse": "Промежуток времени",
|
||||||
|
"Time-lapse Tool": "Инструмент покадровой",
|
||||||
|
"Timeout": "Ожидания",
|
||||||
|
"Timeout Reset on Next Motion": "Таймаут сброса на следующем движении",
|
||||||
|
"Toggle Sidebar": "Переключение Боковой Панели",
|
||||||
|
"Top Left": "Верхний Левый",
|
||||||
|
"Top Right": "Вверху Справа",
|
||||||
|
"Trigger Record": "Триггер Записи",
|
||||||
|
"Trigger Successful": "Триггер Успешным",
|
||||||
|
"UDP": "УДП",
|
||||||
|
"URL": "URL-адрес",
|
||||||
|
"URL Stop Timeout": "Адрес останавливать время ожидания <small>запуска остановки URL после x миллисекунд</small>",
|
||||||
|
"US": "Нам",
|
||||||
|
"Unable to Launch": "Не удалось запустить",
|
||||||
|
"UnabletoLaunchText": "Пожалуйста, сохраните сначала новый монитор. Затем попытаться запустить редактор регионе.",
|
||||||
|
"Up": "До <small>URL-Адрес</small>",
|
||||||
|
"Up Stop": "До остановки <small>URL-Адрес</small>",
|
||||||
|
"Username": "Имя пользователя",
|
||||||
|
"Value": "Значение",
|
||||||
|
"Video": "Видео",
|
||||||
|
"Video Codec": "Видеокодек",
|
||||||
|
"Video Filter": "Видеофильтра",
|
||||||
|
"Video Finished": "Видео Закончил",
|
||||||
|
"Video Length (minutes) and Motion Count per video": "Продолжительность видео (минут) и движения на видео",
|
||||||
|
"Video Record Rate": "Видео Скорость записи <small>(кадров в секунду)</small>",
|
||||||
|
"Video Status": "Статус Видео",
|
||||||
|
"Video and Time Span (Minutes)": "Прямая и отрезок времени (минут)",
|
||||||
|
"Videos": "Видео",
|
||||||
|
"Videos List": "Видео Список",
|
||||||
|
"Watch": "Смотреть",
|
||||||
|
"Watch Only": "Смотреть Только",
|
||||||
|
"WebDAV": "Протокол WebDAV",
|
||||||
|
"WebM (libvpx)": "Колсоном (libvpx)",
|
||||||
|
"Webdav Error": "Ошибка В WebDAV",
|
||||||
|
"WebdavErrorText": "Не удается сохранить. Вы сделали камеры папки внутри выбранной сохранить каталог?",
|
||||||
|
"Webhook": "Веб-перехватчик",
|
||||||
|
"Webhook URL": "URL-адрес веб-перехватчик",
|
||||||
|
"Width": "Ширина",
|
||||||
|
"Yes": "Да",
|
||||||
|
"Zoom In": "Зум в <small>URL-Адрес</small>",
|
||||||
|
"Zoom In Stop": "Зум в <small>URL-Адрес</small>",
|
||||||
|
"Zoom Out": "Уменьшать <small>URL-Адрес</small>",
|
||||||
|
"Zoom Out Stop": "Уменьшать остановка <small>URL-Адрес</small>",
|
||||||
|
"a day": "в день",
|
||||||
|
"a few seconds": "несколько секунд",
|
||||||
|
"a minute": "минуту",
|
||||||
|
"a month": "месяц",
|
||||||
|
"a year": "год",
|
||||||
|
"aac": "ААС",
|
||||||
|
"aac (Default)": "ААС (по умолчанию)",
|
||||||
|
"ac3": "АС3",
|
||||||
|
"ago": "назад",
|
||||||
|
"an hour": "час",
|
||||||
|
"blankPassword": "Оставьте поле пустым, чтобы сохранить тот же пароль",
|
||||||
|
"calendar": "календарь",
|
||||||
|
"clientStreamFailedattemptingReconnect": "На стороне клиента проверить ctream не удалось, попытка воссоединиться.",
|
||||||
|
"confirmDeleteFilter": "Вы действительно хотите удалить этот фильтр? Нельзя восстановить.",
|
||||||
|
"copy": "копия",
|
||||||
|
"days": "дней",
|
||||||
|
"dropBoxSuccess": "Успехов! Файлы, сохраненные в Dropbox.",
|
||||||
|
"for Global Access": "для глобального доступа",
|
||||||
|
"hours": "часов",
|
||||||
|
"in": "в",
|
||||||
|
"libmp3lame": "libmp3lame",
|
||||||
|
"libopus": "libopus",
|
||||||
|
"libvorbis (Default)": "libvorbis были (по умолчанию)",
|
||||||
|
"libvpx (Default)": "libvpx (по умолчанию)",
|
||||||
|
"libvpx-vp9": "libvpx-vp9 или",
|
||||||
|
"libx264": "поддержкой libx264",
|
||||||
|
"libx264 (Default)": "поддержкой libx264 (по умолчанию)",
|
||||||
|
"libx265": "libx265",
|
||||||
|
"minutes": "минут",
|
||||||
|
"modifyVideoText1": "Метод не существует. Убедитесь, что последнее значение URL является не пустым.",
|
||||||
|
"monitorEditFailedMaxReached": "Ваша учетная запись, достигнуто Максимальное число камер, которые могут быть созданы. Поговорить с администратором, если вы хотели бы это изменить.",
|
||||||
|
"monitorEditText1": "Неверные данные, проверьте, чтобы увидеть это допустимая строка импорт.",
|
||||||
|
"monitorEditText2": "Поврежденных Деталей Строку. Проверьте, это json-строку, а не обычный объект был принят.",
|
||||||
|
"monitorGetText1": "неполный запрос, удалить последний слеш в URL или положить приемлемой стоимости.",
|
||||||
|
"months": "месяцев",
|
||||||
|
"noSpecialCharacters": "Без пробелов или специальных символов.",
|
||||||
|
"on": "на",
|
||||||
|
"on Error": "в случае ошибки",
|
||||||
|
"startUpText0": "проверка размера для видео",
|
||||||
|
"startUpText1": "конец проверить Размер для видео",
|
||||||
|
"startUpText2": "все пользователи проверены, подождите закрывать открытые файлы и удалить файлы через лимит пользователей",
|
||||||
|
"startUpText3": "ждал недостроенный видео проверяем какое-то время. 3 секунды.",
|
||||||
|
"startUpText4": "начиная все мониторы установить для просмотра и записи",
|
||||||
|
"startUpText5": "Шиноби готов.",
|
||||||
|
"superAdminText": "\"супер.в json\" не существует. Пожалуйста, переименуйте \"супер.образец.в json\" на \"супер.в json\".",
|
||||||
|
"superAdminTitle": "Шиноби : Супер Админ",
|
||||||
|
"total": "общая",
|
||||||
|
"updateKeyText1": "\"updateKey\" отсутствует \"конф.с json\", нельзя делать обновление таким образом, пока вы не добавите его.",
|
||||||
|
"updateKeyText2": "\"updateKey\" - это неправильно.",
|
||||||
|
"years": "лет"
|
||||||
|
}
|
|
@ -0,0 +1,496 @@
|
||||||
|
{
|
||||||
|
"\"No Motion\" Detector": "\"不运动\"探测器",
|
||||||
|
"# of Allow MJPEG Clients": "# of Allow MJPEG Clients <small>0 for infinite</small>",
|
||||||
|
"180 Degrees": "180度",
|
||||||
|
"2-Factor Authentication": "2因素认证",
|
||||||
|
"90 Clockwise": "90顺时针",
|
||||||
|
"90 Clockwise and Vertical Flip": "90顺时针方向和垂直翻转",
|
||||||
|
"90 Counter Clockwise and Vertical Flip (default)": "90逆时针方向和垂直翻转的(默认)",
|
||||||
|
"API": "API",
|
||||||
|
"API Key Added": "API关键的加入",
|
||||||
|
"API Key Deleted": "API关键删除",
|
||||||
|
"API Keys": "API钥匙",
|
||||||
|
"APIKeyAddedText": "你可以用这个关键。",
|
||||||
|
"APIKeyDeletedText": "关键已被删除。 它将不再起作用。",
|
||||||
|
"ASC": "ASC",
|
||||||
|
"Account Info": "帐户信息",
|
||||||
|
"AccountEditText1": "不可能编辑。 刷新页面,如果问题继续进行。",
|
||||||
|
"Accounts": "帐户",
|
||||||
|
"Action for Selected": "行动选择",
|
||||||
|
"Add": "添加",
|
||||||
|
"Add Monitor": "增加监视",
|
||||||
|
"Add New": "添加新的",
|
||||||
|
"Admin": "管理员",
|
||||||
|
"Advanced": "先进的",
|
||||||
|
"Again": "再一次",
|
||||||
|
"All Monitors": "所有监视器",
|
||||||
|
"All Monitors and Privileges": "所有监视和特权",
|
||||||
|
"All Warnings": "所有的警告",
|
||||||
|
"Allow Next Command": "允许下一个命令 <small>在分钟</small>",
|
||||||
|
"Allow Next Email": "允许下电子邮件 <small>在几分钟</small>",
|
||||||
|
"Allow Next Trigger": "允许下一个触发 <small>在毫秒</small>",
|
||||||
|
"Allowed IPs": "允许IPs",
|
||||||
|
"Analyzation Duration": "分析的持续时间",
|
||||||
|
"Archive": "存档",
|
||||||
|
"Audio Codec": "音频编",
|
||||||
|
"Authenticate": "进行身份验证",
|
||||||
|
"Auto": "汽车",
|
||||||
|
"Autosave": "自动保存",
|
||||||
|
"Base64 over Websocket": "Base64过Websocket",
|
||||||
|
"Bottom Left": "左下",
|
||||||
|
"Bottom Right": "右",
|
||||||
|
"Browser Console Log": "浏览器控制台的记录",
|
||||||
|
"CPU": "CPU",
|
||||||
|
"CPU indicator will not work. Continuing...": "CPU指标将不会的工作。 继续...",
|
||||||
|
"CSS": "CSS <small>的风格你的仪表板。</small>",
|
||||||
|
"Calendar": "日历",
|
||||||
|
"Camera Password": "摄像机的密码",
|
||||||
|
"Camera Username": "摄像机的用户名",
|
||||||
|
"Camera is not recording": "摄像机是不是记录",
|
||||||
|
"CameraNotRecordingText": "设置可能不相容的。 检查编码器。 重新启动...",
|
||||||
|
"Can Control Monitors": "可以控制的监视器",
|
||||||
|
"Can Delete Videos": "可以删除的视频",
|
||||||
|
"Can Delete Videos and Events": "可以删除的视频和活动",
|
||||||
|
"Can Edit Monitor": "可以编辑监控",
|
||||||
|
"Can Get Logs": "可以得到日志",
|
||||||
|
"Can Get Monitors": "可以得到监视",
|
||||||
|
"Can View Monitor": "可以查看监视器",
|
||||||
|
"Can View Snapshots": "可以查看的快照",
|
||||||
|
"Can View Streams": "可以看流",
|
||||||
|
"Can View Videos": "可以观看视频",
|
||||||
|
"Can View Videos and Events": "可以观看视频和活动",
|
||||||
|
"Can't Connect": "无法连接",
|
||||||
|
"Center": "中心 <small>的URL地址</small>",
|
||||||
|
"Chat on Discord": "聊天上的不和谐",
|
||||||
|
"Check": "检查",
|
||||||
|
"Check Signal Interval": "检查信号的时间间隔 <small>在分钟</small>",
|
||||||
|
"Check for Motion First": "检查运动的第一个",
|
||||||
|
"Close": "靠近",
|
||||||
|
"Closed": "关闭",
|
||||||
|
"Command": "命令",
|
||||||
|
"Command on Trigger": "命令触发",
|
||||||
|
"Complete Stream URL": "完整的流网址",
|
||||||
|
"Confirm": "确认",
|
||||||
|
"Connected": "连接",
|
||||||
|
"Connection Type": "连接类型",
|
||||||
|
"Control": "控制",
|
||||||
|
"Control Error": "控制误差",
|
||||||
|
"ControlErrorText1": "控制没有启用",
|
||||||
|
"Controllable": "可控的",
|
||||||
|
"Country of Plates": "国家的板",
|
||||||
|
"Counts of Motion": "项运动",
|
||||||
|
"Current": "电流",
|
||||||
|
"Currently viewing": "目前的观察",
|
||||||
|
"Custom": "定义",
|
||||||
|
"Custom Base URL": "定义基地址 <small>留下的空白使用主机URL</small>",
|
||||||
|
"DB Lost.. Retrying..": "数据库丢失。。重试..",
|
||||||
|
"DESC": "DESC",
|
||||||
|
"Dashboard": "仪表板",
|
||||||
|
"Dashboard Language": "仪表板语言",
|
||||||
|
"Dashcam": "行车记录仪",
|
||||||
|
"Dashcam (Streamer v2)": "行车记录仪(流v2)",
|
||||||
|
"Date Range": "日期范围",
|
||||||
|
"Debug": "调试",
|
||||||
|
"Default": "默认的",
|
||||||
|
"Delete": "删除",
|
||||||
|
"Delete Filter": "删除过滤器",
|
||||||
|
"Delete Matches": "删除匹配",
|
||||||
|
"Delete Monitor": "删除监控器",
|
||||||
|
"Delete Motionless Video": "删除一动不动的视频",
|
||||||
|
"Delete Motionless Videos (Record)": "删除一动不动的视频(记录)",
|
||||||
|
"Delete Selected Videos": "删除选择的视频",
|
||||||
|
"Delete Video": "删除的视频",
|
||||||
|
"Delete selected": "删除选择",
|
||||||
|
"DeleteMonitorText": "你想要删除这个监视器吗? 你不能恢复。 该文件为这个ID将保留在文件系统。 如果你选择重新建立一个监测与同一标识的影片和事件将变得可见,在仪表板。",
|
||||||
|
"DeleteSelectedVideosMsg": "你想要删除这些视频? 你不能恢复他们。",
|
||||||
|
"DeleteVideoMsg": "你想要删除这个视频? 你不能恢复。",
|
||||||
|
"Deleted": "已删除",
|
||||||
|
"Detect Objects": "检测对象, <small class=\"\">见下</small>",
|
||||||
|
"Detector": "探测器",
|
||||||
|
"Detector Flags": "探测器的标志",
|
||||||
|
"Detector Rate": "检测率 <small>(》)</small>",
|
||||||
|
"DetectorText": "<p>当宽度和高度框显示,你应该将它们设置为640x480或以下。 这将优化该阅读的速度框架。</p>",
|
||||||
|
"Disable Night Vision": "禁止夜视 <small>的URL地址</small>",
|
||||||
|
"Disable Nightvision": "禁止夜视",
|
||||||
|
"Disabled": "残疾人",
|
||||||
|
"Documentation": "文档",
|
||||||
|
"Don't show this anymore": "不再这样下去了",
|
||||||
|
"Double Quote Directory": "双引目录中的 <small>一些目录具有空间。 使用这个可能会崩溃,一些摄像机。</small>",
|
||||||
|
"Down": "下 <small>URL地址</small>",
|
||||||
|
"Down Stop": "下站 <small>的URL地址</small>",
|
||||||
|
"Download": "下载",
|
||||||
|
"EU": "欧盟",
|
||||||
|
"Edit": "编辑",
|
||||||
|
"Email": "电子邮件",
|
||||||
|
"Email Details": "电子邮件的细节",
|
||||||
|
"Email on No Motion": "电子邮件上的\"不动\"",
|
||||||
|
"Email on Trigger": "电子邮件,在触发 <small>的电子邮件去的主要账户持有人的登录地址。</small>",
|
||||||
|
"Enable Night Vision": "启用夜视 <small>的URL地址</small>",
|
||||||
|
"Enable Nightvision": "启用夜视",
|
||||||
|
"Enabled": "启用",
|
||||||
|
"End": "结束",
|
||||||
|
"End Time": "结束的时间",
|
||||||
|
"Ended": "结束",
|
||||||
|
"Enlarge": "放大",
|
||||||
|
"Enter this code to proceed": "输入这个代码来进入",
|
||||||
|
"Equal to": "等于",
|
||||||
|
"Error Connecting": "错误的连接",
|
||||||
|
"Event": "事件",
|
||||||
|
"Event Limit": "事件的限制",
|
||||||
|
"EventText1": "触发事件在运动",
|
||||||
|
"EventText2": "不能电子邮件的图像、文件是不可访问",
|
||||||
|
"Events": "事件",
|
||||||
|
"Example": "例",
|
||||||
|
"Execute Command": "执行命令",
|
||||||
|
"Executed": "执行",
|
||||||
|
"Export": "出口",
|
||||||
|
"FFmpegCantStart": "。不能开始",
|
||||||
|
"FFmpegCantStartText": "记录的引擎这摄像机不能开始。 有可能是错误的东西与你的摄像机的配置。 如果有任何记录其他比这个请帖子他们在该 <b>问题</b> 上的审查中。",
|
||||||
|
"FFmpegTip": "FFprobe是一个简单的多媒体流的分析仪。 你可以用它来输出的所有种类的信息输入其中包括持续时间,框率,框架大小,等等。",
|
||||||
|
"FFprobe": "探针",
|
||||||
|
"FactorAuthText1": "该守则将只是活跃的15分钟。 如果你再次登录的计时器将是重要15分钟用相同的代码。",
|
||||||
|
"Fatal": "致命的",
|
||||||
|
"Fatal Maximum Reached": "致命达到最大,停止摄像机。",
|
||||||
|
"FatalMaximumReachedText": "JPEG误差是致命的。",
|
||||||
|
"Feed-in Image Height": "在图像的高度",
|
||||||
|
"Feed-in Image Width": "在图像的宽度",
|
||||||
|
"Fields cannot be empty": "田不可能是空的",
|
||||||
|
"File Not Exist": "文件不存在",
|
||||||
|
"File Not Found": "找不到的文件",
|
||||||
|
"File Type": "文件的类型",
|
||||||
|
"FileNotExistText": "无法保存不存在的文件。 事了。",
|
||||||
|
"Filename": "文件名",
|
||||||
|
"Filesize": "Filesize",
|
||||||
|
"Filter ID": "过滤器ID",
|
||||||
|
"Filter Matches": "过滤器匹配",
|
||||||
|
"Filter Name": "过滤器名称",
|
||||||
|
"FilterMatchesText1": "这个过滤器已经满足的条件。",
|
||||||
|
"FilterMatchesText2": "视频发现。",
|
||||||
|
"Filters": "过滤器",
|
||||||
|
"Filters Updated": "过滤器更新",
|
||||||
|
"FiltersUpdatedText": "你有了变化保存和应用。",
|
||||||
|
"Find Where": "找到那里",
|
||||||
|
"Fix": "修复",
|
||||||
|
"Fix Video": "解决视频",
|
||||||
|
"FixVideoMsg": "你要修补这个视频? 你不能撤消这种行动。",
|
||||||
|
"Font Path": "字体路径",
|
||||||
|
"Font Size": "字体大小",
|
||||||
|
"Force Port": "部队口",
|
||||||
|
"Found Devices": "设备找到了",
|
||||||
|
"Frame Rate": "框率 <small>(》)</small>",
|
||||||
|
"Full Frame Detection": "完全检测框架",
|
||||||
|
"Fullscreen": "全屏",
|
||||||
|
"Greater Than": "大于",
|
||||||
|
"Greater Than or Equal to": "大于或等于",
|
||||||
|
"Group Key": "小组密",
|
||||||
|
"Group Name": "小组的名字",
|
||||||
|
"Grouping": "分组 ",
|
||||||
|
"H.264 / H.265 / H.265+": "H.264/H.265/H.265 ",
|
||||||
|
"HLS (.m3u8)": "高级别(中。m3u8)",
|
||||||
|
"HLS (includes Audio)": "高级别(包括音频)",
|
||||||
|
"HLS Audio Encoder": "高级别声音编码器",
|
||||||
|
"HLS List Size": "高级别列出的大小",
|
||||||
|
"HLS Preset": "高级别预先设定",
|
||||||
|
"HLS Segment Length": "高级别段的长度 <small>在几秒钟内</small>",
|
||||||
|
"HLS Video Encoder": "高级别编码视频",
|
||||||
|
"HTTP": "HTTP",
|
||||||
|
"HTTPS": "HTTPS",
|
||||||
|
"Height": "高度",
|
||||||
|
"Help": "帮助",
|
||||||
|
"Hide List": "隐藏列表中的",
|
||||||
|
"Hide Notes": "隐藏的笔记",
|
||||||
|
"Host": "主机",
|
||||||
|
"Hotswap Modes (Watch-Only)": "热交换模式(看-Only)",
|
||||||
|
"How to Record": "如何记录",
|
||||||
|
"IP Address": "IP地址",
|
||||||
|
"Identity": "身份",
|
||||||
|
"IdentityText1": "这是系统将如何识别数据为这个流。 你不能改变的 <b>监测ID</b> 一旦你必须按下保存。 如果你想你可以使 <b>监测ID</b> 更多的人阅读,然后再继续。",
|
||||||
|
"IdentityText2": "你可以重复一个监测通过修改 <b>监测ID</b> 然后按下保存。 你 <b>不能</b> 使用的标识一个监视已经存在或者它将存在于监测的数据库信息。",
|
||||||
|
"Idle": "空闲",
|
||||||
|
"Image Height": "像高",
|
||||||
|
"Image Location": "图像的位置 <small>绝对路径或留下的空白使用全球</small>",
|
||||||
|
"Image Position": "图像的位置",
|
||||||
|
"Image Width": "图像的宽度",
|
||||||
|
"Import": "进口",
|
||||||
|
"Import Monitor Configuration": "进口监测器的配置",
|
||||||
|
"ImportMonitorConfigurationText": "这样做将overrwrite任何改变目前没有保存。 进口的变化将只适用于当按 <b>保存</b>人。",
|
||||||
|
"In": "在",
|
||||||
|
"Incorrect Settings Chosen": "设置不正确的选择",
|
||||||
|
"Indifference": "冷漠",
|
||||||
|
"Input": "输入",
|
||||||
|
"Input Flags": "输入的标志",
|
||||||
|
"Input Type": "输入型",
|
||||||
|
"InputText1": "这部分告诉忍如何消耗流。 最佳性能试图调整你的摄像机的内置。 找到以下选项,并设定他们如图所示。 找到你的摄像机可以使用 <b>建立在升扫描仪</b> 的忍者. 一些升摄像机要求采用一个管理工具,以修改其内部设置。 如果你找不到你的摄像机你可以尝试 <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">提升设备Manager for Windows</a>.",
|
||||||
|
"InputText2": "<ul><li><b>Framerate(》):</b> 高:10-15》,低:2-5》</li><li><b>我框架的时间间隔:</b> 80</li><li><b>比特率类型:</b> 社区康复(恒定的比率)</li><li><b>比特率:</b> 间256kbps-500kbps</li></ul>",
|
||||||
|
"InputText3": "如果你需要帮忙找出来是什么样的输入型你的摄像机是你可以看看 <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">摄像机的Url清单</a> 上的忍者的网站。",
|
||||||
|
"Invalid JSON": "无效JSON",
|
||||||
|
"InvalidJSONText": "请确保这是一个有效的JSON串忍监测配置。",
|
||||||
|
"JPEG": "JPEG",
|
||||||
|
"JPEG (Auto Enables JPEG API)": "JPEG(自动使JPEG API)",
|
||||||
|
"JPEG API": "JPEG API <small>快照(cgi-bin)</small>",
|
||||||
|
"JPEG Error": "JPEG错误",
|
||||||
|
"JPEG Mode": "JPEG模式",
|
||||||
|
"JPEGErrorText": "有一个问题获得数据从你的相机。",
|
||||||
|
"Leave blank for random.": "留下的空白。",
|
||||||
|
"Left": "左 <small>URL地址</small>",
|
||||||
|
"Left Stop": "左站 <small>的URL地址</small>",
|
||||||
|
"Less Than": "不到",
|
||||||
|
"Less Than or Equal to": "小于或等于",
|
||||||
|
"Like": "喜欢",
|
||||||
|
"Lisence Plate Detector": "图编辑功能板检测器",
|
||||||
|
"List Toggle": "列表中切换",
|
||||||
|
"Live Stream Toggle": "现场流肘",
|
||||||
|
"Live View": "现场查看",
|
||||||
|
"Local": "本地",
|
||||||
|
"Log Level": "日志的水平",
|
||||||
|
"Log Signal Event": "登录信号的事件, <small>客户只有一侧</small>",
|
||||||
|
"Logging": "日志记录",
|
||||||
|
"Login": "登录",
|
||||||
|
"Logout": "注销",
|
||||||
|
"Logs": "日志",
|
||||||
|
"MB": "MB",
|
||||||
|
"MJPEG": "安全监控",
|
||||||
|
"MP4 (copy, libx264, libx265)": "MP4(副本,libx264,libx265)",
|
||||||
|
"MPEG-4 (.mp4 / .ts)": "MPEG-4(中。mp4/.ts)",
|
||||||
|
"MailError": "邮件错误:不能发送电子邮件、检查conf.手机中。 跳过的任何功能的依赖邮寄。",
|
||||||
|
"Matches": "比赛",
|
||||||
|
"Max Storage Amount": "最大储存量 <small>在兆</small>",
|
||||||
|
"Mode": "模式",
|
||||||
|
"Monitor": "监视器",
|
||||||
|
"Monitor Added by user": "监控中加入的用户。",
|
||||||
|
"Monitor Capture Rate": "监测捕获率 <small>(》)</small>",
|
||||||
|
"Monitor Groups": "监测组",
|
||||||
|
"Monitor ID": "监测ID",
|
||||||
|
"Monitor Idling": "监测空转",
|
||||||
|
"Monitor Name": "监视器名称",
|
||||||
|
"Monitor Settings": "监测设置",
|
||||||
|
"Monitor Stopped": "监测停止",
|
||||||
|
"Monitor Updated by user": "监测更新用户。",
|
||||||
|
"Monitor mode changed": "监视器模式的改变",
|
||||||
|
"Monitor mode is already": "监视器模式已经",
|
||||||
|
"Monitor or Key does not exist.": "监视器或关键并不存在。",
|
||||||
|
"MonitorIdlingText": "监测会议已订于空闲。",
|
||||||
|
"MonitorStoppedText": "监测会议已被下令停止。",
|
||||||
|
"Monitors": "监视器",
|
||||||
|
"Monitors per row": "监视器,每行 <small>为的蒙太奇</small>",
|
||||||
|
"Montage": "蒙太奇",
|
||||||
|
"Motion GUI": "运动GUI",
|
||||||
|
"Motion Meter": "运动米",
|
||||||
|
"Name": "名称",
|
||||||
|
"No": "没有",
|
||||||
|
"No Audio": "没有音频",
|
||||||
|
"No Data": "没有数据",
|
||||||
|
"No Events found for this video": "没事的找到这个视频",
|
||||||
|
"No Group with this key exists": "没有任何组织这个关键的存在",
|
||||||
|
"No Monitor Found, Ignoring Request": "没有监视器发现,忽略了请求",
|
||||||
|
"No Rotation": "没有旋转",
|
||||||
|
"No such file": "没有这样的文件",
|
||||||
|
"NoMotionEmailText1": "没有运动",
|
||||||
|
"NoMotionEmailText2": "没有任何运动检测摄像机",
|
||||||
|
"NoVideosFoundForDateRange": "没有视频发现在这的日期范围。 试图设置,开始日期进一步回。",
|
||||||
|
"Not Authorized": "没有授权",
|
||||||
|
"Not Connected": "不连接",
|
||||||
|
"Not Equal to": "不等于",
|
||||||
|
"Not In": "不在",
|
||||||
|
"Not Matches": "不匹配",
|
||||||
|
"Not Permitted": "不允许",
|
||||||
|
"Not an Administrator Account": "不是管理员的帐户",
|
||||||
|
"NotAuthorizedText1": "没有授权,提交init命令与\"授权\",\"科\",并\"uid\"",
|
||||||
|
"Notes": "注意到",
|
||||||
|
"NotesPlacholder": "评论你想离开这个相机设置。",
|
||||||
|
"Number of Days to keep": "保留的天数",
|
||||||
|
"ONVIF": "升",
|
||||||
|
"ONVIF Scanner": "升扫描仪",
|
||||||
|
"ONVIFnote": "发现提升设备网络之外自己或留下的空白以扫描你的前的网络。 <br>用户名和密码可以留空。",
|
||||||
|
"OpenCV Cascades": "该版本的瀑布",
|
||||||
|
"Order Streams": "顺流",
|
||||||
|
"Output Method": "输出方法",
|
||||||
|
"Password": "密码",
|
||||||
|
"Password Again": "再次密码",
|
||||||
|
"Passwords don't match": "密码不匹配",
|
||||||
|
"Paste JSON here.": "贴JSON在这里。",
|
||||||
|
"Path": "路径",
|
||||||
|
"Permissions": "权限",
|
||||||
|
"Points": "点 <small>在添加点击边缘上的多边形。</small>",
|
||||||
|
"Port": "口",
|
||||||
|
"Position X": "X位置",
|
||||||
|
"Position Y": "Y位置",
|
||||||
|
"Power Video Viewer": "的电视观众",
|
||||||
|
"Power Viewer": "电观众",
|
||||||
|
"Preferences": "喜好",
|
||||||
|
"Preset": "预先设定",
|
||||||
|
"Probe Size": "探头大小",
|
||||||
|
"Process Crashed for Monitor": "进程崩溃的监视器",
|
||||||
|
"Process Unexpected Exit": "处理意想不到的退出",
|
||||||
|
"Profile": "配置文件",
|
||||||
|
"Quality": "质量 <small>1高,23低</small>",
|
||||||
|
"Query": "查询",
|
||||||
|
"RAM": "RAM",
|
||||||
|
"RTSP": "RTSP",
|
||||||
|
"RTSP Transport": "RTSP运输",
|
||||||
|
"Range or Single": "范围内或单",
|
||||||
|
"Rate": "率 <small>(》)</small>",
|
||||||
|
"Record": "记录",
|
||||||
|
"Record File Type": "记录文件的类型",
|
||||||
|
"Record Height": "记录的高度",
|
||||||
|
"Record Video Filter": "视频录制的过滤器",
|
||||||
|
"Record Width": "记录宽度",
|
||||||
|
"Recording": "记录",
|
||||||
|
"Recording Flags": "记录的标志",
|
||||||
|
"Recording Segment Interval": "记录段时间间隔 <small>在分钟</small>",
|
||||||
|
"Recording Timeout": "记录超时 <small>在分钟</small>",
|
||||||
|
"Recording Timestamp": "记录时间戳",
|
||||||
|
"Recording Watermark": "记录水印",
|
||||||
|
"RecordingText": "它建议设置 <b>的记录文件的类型</b> 来 <b class=\"h_t_input h_t_jpeg h_t_socket\">Divx</b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">MP4</b> 和 <b>视频编</b> 到 <b class=\"h_t_input h_t_jpeg h_t_socket\">libvpx</b><b class=\"h_t_input h_t_h264 h_t_hls h_t_mp4\">复制或 </b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">libx264</b> 因为你的 <b>输入型</b> 设置 <b class=\"h_t_text\"></b>的。",
|
||||||
|
"Refresh List of Cascades": "刷新名单的瀑布",
|
||||||
|
"Region Editor": "地区编辑器",
|
||||||
|
"Region Name": "地区名称",
|
||||||
|
"RegionNote": "点只保存,当你按下 <b>保存</b> 在 <b>监测器设置</b> 窗口。",
|
||||||
|
"Regions": "区域",
|
||||||
|
"Remember Me": "还记得我",
|
||||||
|
"Reset Timer": "重置计时器",
|
||||||
|
"Restarting Process": "重新启动进程",
|
||||||
|
"Retry Connection": "试连接 <small>的次数,允许失败</small>",
|
||||||
|
"Retrying...": "重新尝试...",
|
||||||
|
"Right": "正确的 <small>URL地址</small>",
|
||||||
|
"Right Stop": "右站 <small>的URL地址</small>",
|
||||||
|
"Rotate": "旋转",
|
||||||
|
"Save": "保存",
|
||||||
|
"Save Directory": "保存目录",
|
||||||
|
"Save Events to SQL": "保存活动SQL",
|
||||||
|
"Save Log in SQL": "保存记录在SQL <small>这可以迅速填补的。</small>",
|
||||||
|
"Save as": "保存",
|
||||||
|
"Saved Filters": "保存的过滤器",
|
||||||
|
"Scan Settings": "扫描设置",
|
||||||
|
"Search": "搜索",
|
||||||
|
"Send Frames": "送框架 <small>推框架进行分析</small>",
|
||||||
|
"Separate with commas, no spaces": "独立使用逗号,不空间",
|
||||||
|
"Set to Watch Only": "设置只观看",
|
||||||
|
"Settings": "设置",
|
||||||
|
"Settings Changed": "设置改变",
|
||||||
|
"SettingsChangedText": "你的设置已保存和应用。",
|
||||||
|
"Shinobi": "忍者",
|
||||||
|
"Shinobi Streamer": "忍流光",
|
||||||
|
"Show Logs": "日志显示",
|
||||||
|
"Silent": "沉默",
|
||||||
|
"Simple": "简单的",
|
||||||
|
"Size (mb)": "小(mb)",
|
||||||
|
"Snapshot": "快照",
|
||||||
|
"Snapshot Flags": "快照标志",
|
||||||
|
"Snapshots": "快照",
|
||||||
|
"Sort By": "排序",
|
||||||
|
"Start": "开始",
|
||||||
|
"Start Recording": "开始记录",
|
||||||
|
"Start Time": "开始的时间",
|
||||||
|
"Started": "开始",
|
||||||
|
"Status Indicator": "状态指示器",
|
||||||
|
"Stop URL": "停止URL",
|
||||||
|
"Stream": "流",
|
||||||
|
"Stream Flags": "流的标志",
|
||||||
|
"Stream Timestamp": "流的时间戳",
|
||||||
|
"Stream Type": "流的类型",
|
||||||
|
"Stream Watermark": "流水印",
|
||||||
|
"Stream to YouTube": "流到YouTube",
|
||||||
|
"Stream to YouTube Flags": "流到YouTube的标志",
|
||||||
|
"StreamText": "<p>这部分会指定主流的方法和它的设置。 这种流将显示在仪表板。 如果你选择使用高级别、JPEG或数然后你就可以占用的流通过其他程序。</p><p class=\"h_st_input h_st_jpeg\">使用JPEG流基本上关闭主流和使用的快照站获得的框架。</p>",
|
||||||
|
"Streamer": "经幡",
|
||||||
|
"Streams": "流",
|
||||||
|
"Superuser": "超级用户",
|
||||||
|
"Switch on for Still Image": "开关于仍然图像",
|
||||||
|
"TCP": "TCP",
|
||||||
|
"Text Box Color": "文本框颜色",
|
||||||
|
"Text Color": "文字颜色",
|
||||||
|
"Time-lapse": "时间流逝",
|
||||||
|
"Time-lapse Tool": "延时的工具",
|
||||||
|
"Timeout": "超时",
|
||||||
|
"Timeout Reset on Next Motion": "超时的重置上下运动",
|
||||||
|
"Toggle Sidebar": "切换边栏",
|
||||||
|
"Top Left": "左上",
|
||||||
|
"Top Right": "右上方",
|
||||||
|
"Trigger Record": "触发记录",
|
||||||
|
"Trigger Successful": "触发成功的",
|
||||||
|
"UDP": "UDP",
|
||||||
|
"URL": "URL",
|
||||||
|
"URL Stop Timeout": "URL停止超时 <small>停止运行URL后X毫秒</small>",
|
||||||
|
"US": "我们",
|
||||||
|
"Unable to Launch": "无法启动",
|
||||||
|
"UnabletoLaunchText": "请保存的新的监测第一次。 然后试图启动该地区编辑器。",
|
||||||
|
"Up": "立 <small>URL地址</small>",
|
||||||
|
"Up Stop": "起来站 <small>的URL地址</small>",
|
||||||
|
"Username": "用户名",
|
||||||
|
"Value": "值",
|
||||||
|
"Video": "视频",
|
||||||
|
"Video Codec": "视频编",
|
||||||
|
"Video Filter": "视频的过滤器",
|
||||||
|
"Video Finished": "视频完成",
|
||||||
|
"Video Length (minutes) and Motion Count per video": "视频度(分钟)和运动的计每视频",
|
||||||
|
"Video Record Rate": "视频记录速率 <small>(》)</small>",
|
||||||
|
"Video Status": "视频状态",
|
||||||
|
"Video and Time Span (Minutes)": "视频和时间跨度(分钟)",
|
||||||
|
"Videos": "视频",
|
||||||
|
"Videos List": "视频清单",
|
||||||
|
"Watch": "看",
|
||||||
|
"Watch Only": "只观看",
|
||||||
|
"WebDAV": "WebDAV",
|
||||||
|
"WebM (libvpx)": "Divx(libvpx)",
|
||||||
|
"Webdav Error": "Webdav错误",
|
||||||
|
"WebdavErrorText": "不能保存。 你使摄像文件夹在你选择的保存目录?",
|
||||||
|
"Webhook": "两者",
|
||||||
|
"Webhook URL": "两者URL",
|
||||||
|
"Width": "宽",
|
||||||
|
"Yes": "是的",
|
||||||
|
"Zoom In": "放大 <small>的URL地址</small>",
|
||||||
|
"Zoom In Stop": "放大停止 <small>URL地址</small>",
|
||||||
|
"Zoom Out": "缩小 <small>的URL地址</small>",
|
||||||
|
"Zoom Out Stop": "缩小站 <small>的URL地址</small>",
|
||||||
|
"a day": "一天",
|
||||||
|
"a few seconds": "几秒钟",
|
||||||
|
"a minute": "一分钟",
|
||||||
|
"a month": "一个月",
|
||||||
|
"a year": "一年",
|
||||||
|
"aac": "aac",
|
||||||
|
"aac (Default)": "aac(默认)",
|
||||||
|
"ac3": "ac3",
|
||||||
|
"ago": "前",
|
||||||
|
"an hour": "一个小时",
|
||||||
|
"blankPassword": "留下的空白,以保持同一个密码",
|
||||||
|
"calendar": "日历",
|
||||||
|
"clientStreamFailedattemptingReconnect": "客户的侧ctream检查失败,试图重新连接。",
|
||||||
|
"confirmDeleteFilter": "你想要删除这个过滤器? 你不能恢复。",
|
||||||
|
"copy": "复制",
|
||||||
|
"days": "天",
|
||||||
|
"dropBoxSuccess": "成功! 文件保存到您的序。",
|
||||||
|
"for Global Access": "全球访问",
|
||||||
|
"hours": "小时",
|
||||||
|
"in": "在",
|
||||||
|
"libmp3lame": "libmp3lame",
|
||||||
|
"libopus": "libopus",
|
||||||
|
"libvorbis (Default)": "libvorbis(默认)",
|
||||||
|
"libvpx (Default)": "libvpx(默认)",
|
||||||
|
"libvpx-vp9": "libvpx-vp9",
|
||||||
|
"libx264": "libx264",
|
||||||
|
"libx264 (Default)": "libx264(默认)",
|
||||||
|
"libx265": "libx265",
|
||||||
|
"minutes": "分钟",
|
||||||
|
"modifyVideoText1": "方法并不存在。 检查,以确保最后的价值的网址是没有空白。",
|
||||||
|
"monitorEditFailedMaxReached": "你的账户已经达到最大数量的摄像机,可以创建。 说话给管理员如果你想这改变。",
|
||||||
|
"monitorEditText1": "无效数据后,检查看看,这是一个有效的进口串。",
|
||||||
|
"monitorEditText2": "无效的细节串。 检查看看它是一个JSON串并不是一个普通的物体被通过。",
|
||||||
|
"monitorGetText1": "不完整的请求,删除最后一条斜线网址,或把接受的价值。",
|
||||||
|
"months": "几个月",
|
||||||
|
"noSpecialCharacters": "没有空间或特殊字符。",
|
||||||
|
"on": "上",
|
||||||
|
"on Error": "在错误",
|
||||||
|
"startUpText0": "尺寸检查的视频",
|
||||||
|
"startUpText1": "终端的尺寸检查的视频",
|
||||||
|
"startUpText2": "所有用户的检查,等待关闭打开文件,并删除文件的用户限制",
|
||||||
|
"startUpText3": "等着给未完成的视频检查一些时间。 3秒钟。",
|
||||||
|
"startUpText4": "开始的所有监视器组,以观察和记录",
|
||||||
|
"startUpText5": "忍者已准备就绪。",
|
||||||
|
"superAdminText": "\"超级。json\"不存在。 请重新命名\"超级。样品。json\"到\"超级。json\"。",
|
||||||
|
"superAdminTitle": "忍:超级管理员",
|
||||||
|
"total": "总",
|
||||||
|
"updateKeyText1": "\"updateKey\"缺失\"conf.json\",无法做更新这样直到你加入它。",
|
||||||
|
"updateKeyText2": "\"updateKey\"是不正确的。",
|
||||||
|
"years": "年"
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
{
|
||||||
|
"name": "shinobi",
|
||||||
|
"version": "1.0.37",
|
||||||
|
"description": "CCTV and NVR in Node.js, Version : daf882caf6053a7c2c8f4e69427620356f8a440c",
|
||||||
|
"main": "camera.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "chmod +x INSTALL/start.sh && INSTALL/start.sh"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/moeiscool/Shinobi.git"
|
||||||
|
},
|
||||||
|
"author": "Moe Alam",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/ShinobiCCTV/Shinobi/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/moeiscool/Shinobi#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"body-parser": "^1.15.2",
|
||||||
|
"circular-json": "0.3.1",
|
||||||
|
"connection-tester": "^0.1.1",
|
||||||
|
"chokidar": "^2.0.3",
|
||||||
|
"mp4frag": "^0.0.15",
|
||||||
|
"ejs": "^2.5.5",
|
||||||
|
"express": "^4.14.0",
|
||||||
|
"jsonfile": "^3.0.1",
|
||||||
|
"moment": "^2.17.0",
|
||||||
|
"mysql": "^2.12.0",
|
||||||
|
"knex": "^0.14.2",
|
||||||
|
"pam-diff": "^0.10.2",
|
||||||
|
"pipe2pam": "^0.6.2",
|
||||||
|
"nodemailer": "^4.0.1",
|
||||||
|
"node-onvif": "^0.1.4",
|
||||||
|
"path": "^0.12.7",
|
||||||
|
"request": "^2.79.0",
|
||||||
|
"socket.io": "^1.7.1",
|
||||||
|
"socket.io-client": "^1.7.2",
|
||||||
|
"http-proxy": "^1.17.0",
|
||||||
|
"webdav": "^0.3.1",
|
||||||
|
"ldapauth-fork": "^4.0.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
opencv-python
|
||||||
|
ccv
|
||||||
|
stemkoski
|
||||||
|
variantai
|
|
@ -0,0 +1,3 @@
|
||||||
|
conf.json
|
||||||
|
events
|
||||||
|
frames
|
|
@ -0,0 +1,364 @@
|
||||||
|
var os = require('os');
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
var mysql = require('mysql');
|
||||||
|
var moment = require('moment');
|
||||||
|
var request = require("request");
|
||||||
|
var spawn = require('child_process').spawn;
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
var execSync = require('child_process').execSync;
|
||||||
|
var connectionTester = require('connection-tester');
|
||||||
|
var config = require('./conf.json');
|
||||||
|
|
||||||
|
exec("ps aux | grep -ie ffmpeg | awk '{print $2}' | xargs kill -9");//kill any ffmpeg running
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error('uncaughtException',err);
|
||||||
|
});
|
||||||
|
s={connected:false,child_node:true,platform:os.platform(),group:{}};
|
||||||
|
|
||||||
|
//connect to master
|
||||||
|
io = require('socket.io-client')('ws://'+config.ws);
|
||||||
|
//spawn conatiner
|
||||||
|
s.spawns={};
|
||||||
|
//emulate master sql query
|
||||||
|
sql={
|
||||||
|
query:function(x,y,z){
|
||||||
|
io.emit('c',{f:'sql',query:x,values:y});if(typeof z==='function'){z();}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//get this nodes cpu usage
|
||||||
|
s.cpuUsage=function(e){
|
||||||
|
switch(s.platform){
|
||||||
|
case'darwin':
|
||||||
|
e="ps -A -o %cpu | awk '{s+=$1} END {print s}'";
|
||||||
|
break;
|
||||||
|
case'linux':
|
||||||
|
e="grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage}'";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return execSync(e,{encoding:'utf8'});
|
||||||
|
}
|
||||||
|
setInterval(function(){
|
||||||
|
io.emit('c',{f:'cpu',cpu:parseFloat(s.cpuUsage())});
|
||||||
|
},2000);
|
||||||
|
//interact with server functions
|
||||||
|
s.cx=function(x){io.emit('c',x)}
|
||||||
|
//emulate master socket emitter
|
||||||
|
s.tx=function(x,y){s.cx({f:'s.tx',data:x,to:y})}
|
||||||
|
//emulate master logger
|
||||||
|
s.log=function(x,y){console.log(y);s.cx({f:'s.log',data:s.init('clean',x),to:y})}
|
||||||
|
//emulate master camera function
|
||||||
|
s.camera=function(x,y){s.cx({f:'camera',mode:x,data:y})}
|
||||||
|
|
||||||
|
//load camera controller vars
|
||||||
|
s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;}
|
||||||
|
s.ratio=function(width,height,ratio){ratio = width / height;return ( Math.abs( ratio - 4 / 3 ) < Math.abs( ratio - 16 / 9 ) ) ? '4:3' : '16:9';}
|
||||||
|
s.gid=function(x){
|
||||||
|
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
for( var i=0; i < x; i++ )
|
||||||
|
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
s.moment=function(e,x){if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};return moment(e).utcOffset('-0800').format(x)}
|
||||||
|
s.kill=function(x,e,p){
|
||||||
|
if(e&&s.group[e.ke].mon[e.id].record){
|
||||||
|
clearTimeout(s.group[e.ke].mon[e.id].record.capturing);
|
||||||
|
if(s.group[e.ke].mon[e.id].record.request&&s.group[e.ke].mon[e.id].record.request.abort){s.group[e.ke].mon[e.id].record.request.abort();delete(s.group[e.ke].mon[e.id].record.request);}
|
||||||
|
};
|
||||||
|
if(!x||x===1){return};if(!x.stdin){return};p=x.pid;x.stdin.pause();setTimeout(function(){x.kill('SIGTERM');delete(x);setTimeout(function(){exec('kill -9 '+p)},1000)},1000)
|
||||||
|
}
|
||||||
|
s.cameraVals=function(e){
|
||||||
|
e.t=Object.keys(s.group[e.ke].mon[e.id]);e.a={};
|
||||||
|
e.t.forEach(function(n){
|
||||||
|
if(s.group[e.ke].mon[e.id][n] instanceof Object){e.a[n]=s.group[e.ke].mon[e.id][n]};
|
||||||
|
});
|
||||||
|
return e.a;
|
||||||
|
}
|
||||||
|
//directories
|
||||||
|
s.group={};
|
||||||
|
s.dir={videos:__dirname+'/videos/',frames:__dirname+'/frames/'};
|
||||||
|
if (!fs.existsSync(s.dir.frames)){
|
||||||
|
fs.mkdirSync(s.dir.frames);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(s.dir.videos)){
|
||||||
|
fs.mkdirSync(s.dir.videos);
|
||||||
|
}
|
||||||
|
////Camera Controller
|
||||||
|
s.init=function(x,e){
|
||||||
|
switch(x){
|
||||||
|
case 0://camera
|
||||||
|
if(!s.group[e.ke]){s.group[e.ke]={}};
|
||||||
|
if(!s.group[e.ke].mon){s.group[e.ke].mon={}}
|
||||||
|
if(!s.group[e.ke].mon[e.mid]){s.group[e.ke].mon[e.mid]={}}
|
||||||
|
if(!s.group[e.ke].mon[e.mid].watch){s.group[e.ke].mon[e.mid].watch={}};
|
||||||
|
if(e.type==='record'){e.record=1}else{e.record=0}
|
||||||
|
if(!s.group[e.ke].mon[e.mid].record){s.group[e.ke].mon[e.mid].record={yes:e.record}};
|
||||||
|
if(!s.group[e.ke].mon[e.mid].started){s.group[e.ke].mon[e.mid].started={}};
|
||||||
|
if(!s.group[e.ke].mon[e.mid].running){s.group[e.ke].mon[e.mid].running={}};
|
||||||
|
break;
|
||||||
|
case'clean':
|
||||||
|
if(e instanceof Object){
|
||||||
|
x={keys:Object.keys(e),ar:{}};
|
||||||
|
x.keys.forEach(function(v){
|
||||||
|
if(v!=='record'&&v!=='spawn'&&v!=='running'&&(typeof e[v]!=='function')){x.ar[v]=e[v];}
|
||||||
|
});
|
||||||
|
return x.ar;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'clean':
|
||||||
|
x={keys:Object.keys(e),ar:{}};
|
||||||
|
x.keys.forEach(function(v){
|
||||||
|
if(v!=='record'&&v!=='spawn'&&v!=='running'&&(v!=='time'&&typeof e[v]!=='function')){x.ar[v]=e[v];}
|
||||||
|
});
|
||||||
|
return x.ar;
|
||||||
|
break;
|
||||||
|
case'url':
|
||||||
|
auth_details='';
|
||||||
|
if(e.details.muser&&e.details.muser!==''&&e.details.mpass&&e.details.mpass!=='') {
|
||||||
|
auth_details=e.details.muser+':'+e.details.mpass+'@';
|
||||||
|
}
|
||||||
|
if(e.port==80){e.porty=''}else{e.porty=':'+e.port}
|
||||||
|
e.url=e.protocol+'://'+auth_details+e.host+e.porty+e.path;return e.url;
|
||||||
|
break;
|
||||||
|
case'url_no_path':
|
||||||
|
auth_details='';
|
||||||
|
if(e.details.muser&&e.details.muser!==''&&e.details.mpass&&e.details.mpass!=='') {
|
||||||
|
auth_details=e.details.muser+':'+e.details.mpass+'@';
|
||||||
|
}
|
||||||
|
if(e.port==80){e.porty=''}else{e.porty=':'+e.port}
|
||||||
|
e.url=e.protocol+'://'+auth_details+e.host+e.porty;return e.url;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(typeof e.callback==='function'){setTimeout(function(){e.callback();delete(e.callback);},2000);}
|
||||||
|
}
|
||||||
|
s.video=function(x,e){
|
||||||
|
if(!e){e={}};
|
||||||
|
if(e.mid){e.id=e.mid};
|
||||||
|
switch(x){
|
||||||
|
case'delete':
|
||||||
|
e.dir=s.dir.videos+e.ke+'/'+e.id+'/';
|
||||||
|
e.save=[e.id,e.ke,s.nameToTime(e.filename),0];
|
||||||
|
sql.query('DELETE FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=? AND `status`=?',e.save)
|
||||||
|
s.tx({f:'video_delete',reason:'Camera Error',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),end:moment().format('YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke);
|
||||||
|
if(fs.existsSync(e.dir+e.filename+'.'+e.ext)){
|
||||||
|
return fs.unlink(e.dir+e.filename+'.'+e.ext);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'close':
|
||||||
|
e.dir=s.dir.videos+e.ke+'/'+e.id+'/';
|
||||||
|
console.log(e.dir+e.filename+'.'+e.ext)
|
||||||
|
if(fs.existsSync(e.dir+e.filename+'.'+e.ext)){
|
||||||
|
e.filesize=fs.statSync(e.dir+e.filename+'.'+e.ext)["size"];
|
||||||
|
if((e.filesize/100000).toFixed(2)>0.25){
|
||||||
|
e.save=[e.filesize,e.frames,1,e.id,e.ke,s.nameToTime(e.filename)];
|
||||||
|
sql.query('UPDATE Videos SET `size`=?,`frames`=?,`status`=? WHERE `mid`=? AND `ke`=? AND `time`=?',e.save)
|
||||||
|
fs.readFile(e.dir+e.filename+'.'+e.ext,function (err,data) {
|
||||||
|
s.cx({f:'created_file',mid:e.id,ke:e.ke,created_file:data,filename:e.filename+'.'+e.ext,d:s.init('clean',e)});
|
||||||
|
s.tx({f:'video_build_success',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),size:e.filesize,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke);
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
s.video('delete',e);
|
||||||
|
s.log(e,{type:'File Corrupt',msg:{ffmpeg:s.group[e.ke].mon[e.mid].ffmpeg,filesize:(e.filesize/100000).toFixed(2)}})
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
s.video('delete',e);
|
||||||
|
s.log(e,{type:'File Not Exist',msg:'Cannot save non existant file. Something went wrong.',ffmpeg:s.group[e.ke].mon[e.id].ffmpeg})
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.ffmpeg=function(e,x){
|
||||||
|
if(!x){x={tmp:''}}
|
||||||
|
// if(!e.details.cutoff||e.details.cutoff===''){x.cutoff=15}else{x.cutoff=parseFloat(e.details.cutoff)};if(isNaN(x.cutoff)===true){x.cutoff=15}
|
||||||
|
// x.segment=' -f segment -strftime 1 -segment_time '+(60*x.cutoff)+' -segment_format '+e.ext
|
||||||
|
if(!e.details.timestamp||e.details.timestamp==1){x.time=' -vf drawtext=fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf:text=\'%{localtime}\':x=(w-tw)/2:y=0:fontcolor=white:box=1:boxcolor=0x00000000@1:fontsize=10';}else{x.time=''}
|
||||||
|
switch(e.ext){
|
||||||
|
case'mp4':
|
||||||
|
x.vcodec='libx265';x.acodec='libfaac';
|
||||||
|
if(e.details.vcodec&&e.details.vcodec!==''){x.vcodec=e.details.vcodec}
|
||||||
|
break;
|
||||||
|
case'webm':
|
||||||
|
x.acodec='libvorbis',x.vcodec='libvpx';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(e.details.acodec&&e.details.acodec!==''){x.acodec=e.details.acodec}
|
||||||
|
if(x.acodec==='none'){x.acodec=''}else{x.acodec=' -acodec '+x.acodec}
|
||||||
|
if(x.vcodec!=='none'){x.vcodec=' -vcodec '+x.vcodec}
|
||||||
|
if(e.fps&&e.fps!==''){x.framerate=' -r '+e.fps}else{x.framerate=''}
|
||||||
|
if(e.details.vf&&e.details.vf!==''){
|
||||||
|
if(x.time===''){x.vf=' -vf '}else{x.vf=','}
|
||||||
|
x.vf+=e.details.vf;
|
||||||
|
x.time+=x.vf;
|
||||||
|
}
|
||||||
|
if(e.details.svf&&e.details.svf!==''){x.svf=' -vf '+e.details.svf;}else{x.svf='';}
|
||||||
|
// if(e.details.svf){'-vf "rotate=45*(PI/180)'}
|
||||||
|
switch(e.type){
|
||||||
|
case'socket':case'jpeg':case'pipe':
|
||||||
|
if(!x.vf||x.vf===','){x.vf=''}
|
||||||
|
x.tmp='-loglevel warning -pattern_type glob -f image2pipe'+x.framerate+' -vcodec mjpeg -i -'+x.vcodec+x.time+x.framerate+' -use_wallclock_as_timestamps 1 -q:v 1'+x.vf+' '+e.dir+e.filename+'.'+e.ext;
|
||||||
|
break;
|
||||||
|
case'mjpeg':
|
||||||
|
if(e.mode=='record'){
|
||||||
|
x.watch=x.vcodec+x.time+' -r 10 -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 -q:v 1 '+e.dir+e.filename+'.'+e.ext+''
|
||||||
|
}else{
|
||||||
|
x.watch='';
|
||||||
|
};
|
||||||
|
x.tmp='-loglevel warning -reconnect 1 -f mjpeg -i '+e.url+''+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1';
|
||||||
|
break;
|
||||||
|
case'h264':
|
||||||
|
if(!x.vf||x.vf===','){x.vf=''}
|
||||||
|
if(e.mode=='record'){
|
||||||
|
x.watch=x.vcodec+x.framerate+x.acodec+' -movflags frag_keyframe+empty_moov -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 -q:v 1'+x.vf+' '+e.dir+e.filename+'.'+e.ext
|
||||||
|
}else{
|
||||||
|
x.watch='';
|
||||||
|
};
|
||||||
|
x.tmp='-loglevel warning -i '+e.url+' -stimeout 2000'+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1';
|
||||||
|
break;
|
||||||
|
case'local':
|
||||||
|
if(e.mode=='record'){
|
||||||
|
x.watch=x.vcodec+x.time+x.framerate+x.acodec+' -movflags frag_keyframe+empty_moov -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 '+e.dir+e.filename+'.'+e.ext
|
||||||
|
}else{
|
||||||
|
x.watch='';
|
||||||
|
};
|
||||||
|
x.tmp='-loglevel warning -i '+e.path+''+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s.group[e.ke].mon[e.mid].ffmpeg=x.tmp;
|
||||||
|
return spawn('ffmpeg',x.tmp.split(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
//child functions
|
||||||
|
var cn={};
|
||||||
|
io.on('connect', function(d){
|
||||||
|
console.log('connected');
|
||||||
|
io.emit('c',{f:'init',socket_key:config.key,u:{name:config.name}})
|
||||||
|
});
|
||||||
|
io.on('c',function(d){
|
||||||
|
console.log(d.f);
|
||||||
|
switch(d.f){
|
||||||
|
case'init_success':
|
||||||
|
s.connected=true;
|
||||||
|
s.other_helpers=d.child_helpers;
|
||||||
|
break;
|
||||||
|
case'kill':
|
||||||
|
s.init(0,d.d);
|
||||||
|
s.kill(s.group[d.d.ke].mon[d.d.id].spawn,d.d)
|
||||||
|
break;
|
||||||
|
case'sync':
|
||||||
|
s.init(0,d.sync);
|
||||||
|
Object.keys(d.sync).forEach(function(v){
|
||||||
|
s.group[d.sync.ke].mon[d.sync.mid][v]=d.sync[v];
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case'delete_file'://delete video
|
||||||
|
d.dir=s.dir.videos+d.ke+'/'+d.mid+'/'+d.file;
|
||||||
|
if(fs.existsSync(d.dir)){
|
||||||
|
fs.unlink(d.dir);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'close'://close video
|
||||||
|
s.video('close',d.d);
|
||||||
|
break;
|
||||||
|
case'spawn'://start video
|
||||||
|
s.init(0,d.d);
|
||||||
|
s.group[d.d.ke].mon[d.d.id]=d.mon;
|
||||||
|
s.init(0,d.d);
|
||||||
|
if(!s.group[d.d.ke].mon_conf){s.group[d.d.ke].mon_conf={}}
|
||||||
|
if(!s.group[d.d.ke].mon_conf[d.d.id]){s.group[d.d.ke].mon_conf[d.d.id]=s.init('clean',d.d);}
|
||||||
|
if(s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){return}
|
||||||
|
if(d.d.mode==='record'){
|
||||||
|
console.log(s.group[d.d.ke].mon[d.d.id])
|
||||||
|
s.group[d.d.ke].mon[d.d.id].record.yes=1;
|
||||||
|
d.d.dir=s.dir.videos+d.d.ke+'/';
|
||||||
|
if (!fs.existsSync(d.d.dir)){
|
||||||
|
fs.mkdirSync(d.d.dir);
|
||||||
|
}
|
||||||
|
d.d.dir=s.dir.videos+d.d.ke+'/'+d.d.id+'/';
|
||||||
|
if (!fs.existsSync(d.d.dir)){
|
||||||
|
fs.mkdirSync(d.d.dir);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
s.group[d.d.ke].mon[d.d.mid].record.yes=0;
|
||||||
|
}
|
||||||
|
if(d.d.mode==='record'||d.d.type==='mjpeg'||d.d.type==='h264'||d.d.type==='local'){
|
||||||
|
s.group[d.d.ke].mon[d.d.id].spawn = s.ffmpeg(d.d);
|
||||||
|
s.log(d.d,{type:'FFMPEG Process Starting',msg:{cmd:s.group[d.d.ke].mon[d.d.id].ffmpeg}});
|
||||||
|
}
|
||||||
|
d.d.frames=0;
|
||||||
|
switch(d.d.type){
|
||||||
|
case'jpeg':
|
||||||
|
if(!d.d.details.sfps||d.d.details.sfps===''){
|
||||||
|
d.d.details.sfps=parseFloat(d.d.details.sfps);
|
||||||
|
if(isNaN(d.d.details.sfps)){d.d.details.sfps=1}
|
||||||
|
}
|
||||||
|
d.d.captureOne=function(f){
|
||||||
|
s.group[d.d.ke].mon[d.d.id].record.request=request({url:d.d.url,method:'GET',encoding: null,timeout:3000},function(er,data){
|
||||||
|
++d.d.frames; if(s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){
|
||||||
|
if(er){
|
||||||
|
++d.d.error_count;
|
||||||
|
s.log(d.d,{type:'Snapshot Error',msg:er});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(d.d.mode==='record'&&s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){
|
||||||
|
s.group[d.d.ke].mon[d.d.id].spawn.stdin.write(data.body);
|
||||||
|
}
|
||||||
|
if(s.group[d.d.ke].mon[d.d.id].watch&&Object.keys(s.group[d.d.ke].mon[d.d.id].watch).length>0){
|
||||||
|
s.tx({f:'monitor_frame',ke:d.d.ke,id:d.d.id,time:s.moment(),frame:data.body.toString('base64'),frame_format:'b64'},'MON_'+d.d.id);
|
||||||
|
}
|
||||||
|
s.group[d.d.ke].mon[d.d.id].record.capturing=setTimeout(function(){d.d.captureOne()},1000/d.d.details.sfps);
|
||||||
|
clearTimeout(d.d.timeOut),d.d.timeOut=setTimeout(function(){d.d.error_count=0;},3000)
|
||||||
|
}
|
||||||
|
}).on('error', function(err){
|
||||||
|
// if(s.group[d.d.ke]&&s.group[d.d.ke].mon[d.d.id]&&s.group[d.d.ke].mon[d.d.id].record&&s.group[d.d.ke].mon[d.d.id].record.request){s.group[d.d.ke].mon[d.d.id].record.request.abort();}
|
||||||
|
clearTimeout(s.group[d.d.ke].mon[d.d.id].record.capturing);
|
||||||
|
if(d.d.error_count>4){d.d.fn();return}
|
||||||
|
d.d.captureOne();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
d.d.captureOne()
|
||||||
|
break;
|
||||||
|
case'mjpeg':case'h264'://case'socket':case'local':
|
||||||
|
if(!s.group[d.d.ke]||!s.group[d.d.ke].mon[d.d.id]){s.init(0,d.d)}
|
||||||
|
if(s.group[d.d.ke].mon[d.d.id].spawn){
|
||||||
|
s.group[d.d.ke].mon[d.d.id].spawn.on('error',function(er){d.d.error({type:'Spawn Error',msg:er})})
|
||||||
|
s.group[d.d.ke].mon[d.d.id].spawn.stdout.on('data',function(de){
|
||||||
|
s.tx({f:'monitor_frame',ke:d.d.ke,id:d.d.id,time:s.moment(),frame:de.toString('base64'),frame_format:'b64'},'MON_'+d.d.id);
|
||||||
|
});
|
||||||
|
s.group[d.d.ke].mon[d.d.id].spawn.stderr.on('data',function(de){
|
||||||
|
de=de.toString();
|
||||||
|
d.d.chk=function(x){return de.indexOf(x)>-1;}
|
||||||
|
switch(true){
|
||||||
|
// case d.d.chk('av_interleaved_write_frame'):
|
||||||
|
case d.d.chk('Connection timed out'):
|
||||||
|
setTimeout(function(){s.log(d.d,{type:"Can't Connect",msg:'Retrying...'});d.d.error_fatal();},1000)//restart
|
||||||
|
break;
|
||||||
|
case d.d.chk('No pixel format specified'):
|
||||||
|
s.log(d.d,{type:"FFMPEG STDERR",msg:{ffmpeg:s.group[d.d.ke].mon[d.d.id].ffmpeg,msg:de}})
|
||||||
|
break;
|
||||||
|
case d.d.chk('RTP: missed'):
|
||||||
|
case d.d.chk('deprecated pixel format used, make sure you did set range correctly'):
|
||||||
|
return
|
||||||
|
break;
|
||||||
|
case d.d.chk('No such file or directory'):
|
||||||
|
case d.d.chk('Unable to open RTSP for listening'):
|
||||||
|
case d.d.chk('timed out'):
|
||||||
|
case d.d.chk('Invalid data found when processing input'):
|
||||||
|
case d.d.chk('Immediate exit requested'):
|
||||||
|
case d.d.chk('reset by peer'):
|
||||||
|
if(d.d.frames===0&&x==='record'){s.video('delete',d.d)};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s.log(d.d,{type:"FFMPEG STDERR",msg:de})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'video':
|
||||||
|
s.video(d.d[0],d.d[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
io.on('disconnect',function(d){
|
||||||
|
s.connected=false;
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name":"Macbook",
|
||||||
|
"ws":"66.51.132.100",
|
||||||
|
"key":"3123asdasdf1dtj1hjk23sdfaasd12asdasddfdbtnkkfgvesra3asdsd3123afdsfqw345",
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"host":"127.0.0.1","user":"root","password":"","database":"ccio"}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"plug":"ComputerVision",
|
||||||
|
"host":"localhost",
|
||||||
|
"port":8080,
|
||||||
|
"key":"UNIQUE KEY HERE",
|
||||||
|
"computerVision":{
|
||||||
|
"apiKey":"YOUR_KEY",
|
||||||
|
"endpoint":"http://YOUR_ENDPOINT/analyze",
|
||||||
|
"params":{
|
||||||
|
"visualFeatures": "Categories,Description,Color",
|
||||||
|
"details": "",
|
||||||
|
"language": "en"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EmotionAPI":{
|
||||||
|
"apiKey":"YOUR_KEY",
|
||||||
|
"endpoint":"http://YOUR_ENDPOINT/recognize",
|
||||||
|
"params":{}
|
||||||
|
},
|
||||||
|
"FaceAPI":{
|
||||||
|
"apiKey":"YOUR_KEY",
|
||||||
|
"endpoint":"http://YOUR_ENDPOINT/detect",
|
||||||
|
"params":{
|
||||||
|
"returnFaceId": "true",
|
||||||
|
"returnFaceLandmarks": "false",
|
||||||
|
"returnFaceAttributes": "age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
//
|
||||||
|
// Shinobi - Microsoft Computer Vision Plugin
|
||||||
|
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||||
|
//
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error('uncaughtException',err);
|
||||||
|
});
|
||||||
|
var fs=require('fs');
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
//var http = require('http');
|
||||||
|
var request = require('request');
|
||||||
|
var moment = require('moment');
|
||||||
|
var cognitive = require('cognitive-services');
|
||||||
|
var config=require('./conf.json');
|
||||||
|
if(config.systemLog===undefined){config.systemLog=true}
|
||||||
|
s={
|
||||||
|
group:{},
|
||||||
|
dir:{
|
||||||
|
cascades:__dirname+'/cascades/'
|
||||||
|
},
|
||||||
|
isWin:(process.platform==='win32')
|
||||||
|
}
|
||||||
|
//default stream folder check
|
||||||
|
if(!config.streamDir){
|
||||||
|
if(s.isWin===false){
|
||||||
|
config.streamDir='/dev/shm'
|
||||||
|
}else{
|
||||||
|
config.streamDir=config.windowsTempDir
|
||||||
|
}
|
||||||
|
if(!fs.existsSync(config.streamDir)){
|
||||||
|
config.streamDir=__dirname+'/streams/'
|
||||||
|
}else{
|
||||||
|
config.streamDir+='/streams/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.dir.streams=config.streamDir;
|
||||||
|
//streams dir
|
||||||
|
if(!fs.existsSync(s.dir.streams)){
|
||||||
|
fs.mkdirSync(s.dir.streams);
|
||||||
|
}
|
||||||
|
s.gid=function(x){
|
||||||
|
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
for( var i=0; i < x; i++ )
|
||||||
|
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
s.systemLog=function(q,w,e){
|
||||||
|
if(!w){w=''}
|
||||||
|
if(!e){e=''}
|
||||||
|
if(config.systemLog===true){
|
||||||
|
return console.log(moment().format(),q,w,e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.objectToParameter = function(obj){
|
||||||
|
return Object.keys(obj).map(function(key) {
|
||||||
|
return key + '=' + encodeURIComponent(obj[key]);
|
||||||
|
}).join('&');
|
||||||
|
}
|
||||||
|
s.sendImageToMS=function(sourceImageUrl,API,callback){
|
||||||
|
var URL = API.endpoint+'?'+s.objectToParameter(API.params)
|
||||||
|
request(URL,{
|
||||||
|
method: 'POST',
|
||||||
|
headers:{
|
||||||
|
"Ocp-Apim-Subscription-Key":API.apiKey
|
||||||
|
},
|
||||||
|
json: {
|
||||||
|
url:sourceImageUrl
|
||||||
|
}
|
||||||
|
}, callback)
|
||||||
|
}
|
||||||
|
s.detectObject=function(buffer,d){
|
||||||
|
var sourceImageUrl = 'http://184.105.6.43/'+s.api_key+'/jpeg/'+d.ke+'/'+d.id+'/s.jpg'
|
||||||
|
// const client = new cognitive.computerVision({
|
||||||
|
// apiKey: config.computerVision.apiKey,
|
||||||
|
// endpoint: config.computerVision.endpoint
|
||||||
|
// });
|
||||||
|
// const parameters = {
|
||||||
|
// "visualFeatures": "Categories,Tags,Description",
|
||||||
|
// "details": "Celebrities,Landmarks"
|
||||||
|
// };
|
||||||
|
// const headers = {
|
||||||
|
// 'Content-type': 'application/json'
|
||||||
|
// };
|
||||||
|
// const body = {
|
||||||
|
// "url": sourceImageUrl
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// client.analyzeImage({
|
||||||
|
// parameters,
|
||||||
|
// headers,
|
||||||
|
// body
|
||||||
|
// }).then((response) => {
|
||||||
|
//// should(response).not.be.undefined();
|
||||||
|
//// should(response).have.properties(["categories", "metadata", "requestId"]);
|
||||||
|
// console.log(response)
|
||||||
|
// }).catch((err) => {
|
||||||
|
// console.log('Error',err)
|
||||||
|
// });
|
||||||
|
var responses = {}
|
||||||
|
s.sendImageToMS(sourceImageUrl,config.computerVision,function(err,resp,body1){
|
||||||
|
responses.computerVisionURL = body1
|
||||||
|
s.sendImageToMS(sourceImageUrl,config.FaceAPI,function(err,resp,body2){
|
||||||
|
responses.faceApiURL = body2
|
||||||
|
s.sendImageToMS(sourceImageUrl,config.EmotionAPI,function(err,resp,body3){
|
||||||
|
responses.EmotionAPI = body3
|
||||||
|
console.log('responses',JSON.stringify(responses,null,3))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
s.makeMonitorObject=function(d){
|
||||||
|
if(!s.group[d.ke]){
|
||||||
|
s.group[d.ke]={}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id]={
|
||||||
|
port:null,
|
||||||
|
countStarted:new Date()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master
|
||||||
|
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||||
|
io.on('connect',function(d){
|
||||||
|
s.cx({f:'init',plug:config.plug});
|
||||||
|
})
|
||||||
|
io.on('disconnect',function(d){
|
||||||
|
io.connect()
|
||||||
|
})
|
||||||
|
io.on('f',function(d){
|
||||||
|
switch(d.f){
|
||||||
|
case'api_key':
|
||||||
|
s.api_key=d.key
|
||||||
|
break;
|
||||||
|
case'init_monitor':
|
||||||
|
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id].buffer=null
|
||||||
|
s.group[d.ke][d.id].countStarted=new Date()
|
||||||
|
}
|
||||||
|
s.makeMonitorObject(d)
|
||||||
|
break;
|
||||||
|
case'frame':
|
||||||
|
d.details={}
|
||||||
|
try{
|
||||||
|
s.makeMonitorObject(d)
|
||||||
|
if(!s.group[d.ke][d.id].buffer){
|
||||||
|
s.group[d.ke][d.id].buffer=[d.frame];
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||||
|
}
|
||||||
|
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||||
|
if(d.mon.detector_frame_save==="1"){
|
||||||
|
d.base64=s.group[d.ke][d.id].buffer.toString('base64')
|
||||||
|
}
|
||||||
|
if(d.mon.detector_scale_x&&d.mon.detector_scale_x!==''&&d.mon.detector_scale_y&&d.mon.detector_scale_y!==''){
|
||||||
|
d.width=d.mon.detector_scale_x;
|
||||||
|
d.height=d.mon.detector_scale_y;
|
||||||
|
}else{
|
||||||
|
d.width=640
|
||||||
|
d.height=480
|
||||||
|
}
|
||||||
|
s.detectObject(Buffer.concat(s.group[d.ke][d.id].buffer),d)
|
||||||
|
s.group[d.ke][d.id].buffer=null;
|
||||||
|
}
|
||||||
|
} catch(err){
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1 @@
|
||||||
|
conf.json
|
|
@ -0,0 +1,5 @@
|
||||||
|
apt-get install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++
|
||||||
|
npm install canvas
|
||||||
|
cd plugins/motion
|
||||||
|
cp conf.sample.json conf.json
|
||||||
|
pm2 start shinobi-motion.js
|
|
@ -0,0 +1,56 @@
|
||||||
|
# Shinobi Motion Detector
|
||||||
|
|
||||||
|
Install required libraries.
|
||||||
|
|
||||||
|
**Ubuntu and Debian only**
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++
|
||||||
|
```
|
||||||
|
|
||||||
|
**CentOS only**
|
||||||
|
|
||||||
|
```
|
||||||
|
su -c 'yum install cairo cairo-devel cairomm-devel libjpeg-turbo-devel pango pango-devel pangomm pangomm-devel giflib-devel'
|
||||||
|
yum search arial
|
||||||
|
yum install liberation-sans-fonts.noarch
|
||||||
|
```
|
||||||
|
|
||||||
|
**Install the Node.js Canvas engine**
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo npm install canvas
|
||||||
|
```
|
||||||
|
|
||||||
|
Go to the Shinobi directory. **Below is an example.**
|
||||||
|
|
||||||
|
```
|
||||||
|
cd /home/Shinobi
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy the config file.
|
||||||
|
|
||||||
|
```
|
||||||
|
cp plugins/motion/conf.sample.json plugins/motion/conf.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit it the new file. Host should be `localhost` and port should match the `listening port for camera.js`.
|
||||||
|
|
||||||
|
```
|
||||||
|
nano plugins/motion/conf.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Start the plugin.
|
||||||
|
|
||||||
|
```
|
||||||
|
node plugins/motion/shinobi-motion.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Or to daemonize with PM2.
|
||||||
|
|
||||||
|
```
|
||||||
|
pm2 start plugins/motion/shinobi-motion.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped.
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"plug":"Motion",
|
||||||
|
"host":"localhost",
|
||||||
|
"port":8080,
|
||||||
|
"key":"change_this_to_something_very_random____make_sure_to_match__/plugins/motion/conf.json",
|
||||||
|
"notice":"Looks like you have the Motion plugin running. Don't forget to enable <b>Send Frames</b> to start pushing frames to be read."
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
data: getterSetter([], function(arrayOfArrays) {
|
||||||
|
var n = arrayOfArrays[0].length;
|
||||||
|
return (arrayOfArrays.map(function(array) {
|
||||||
|
return array.length == n;
|
||||||
|
}).reduce(function(boolA, boolB) { return (boolA & boolB) }, true));
|
||||||
|
}),
|
||||||
|
|
||||||
|
clusters: function() {
|
||||||
|
var pointsAndCentroids = kmeans(this.data(), {k: this.k(), iterations: this.iterations() });
|
||||||
|
var points = pointsAndCentroids.points;
|
||||||
|
var centroids = pointsAndCentroids.centroids;
|
||||||
|
|
||||||
|
return centroids.map(function(centroid) {
|
||||||
|
return {
|
||||||
|
centroid: centroid.location(),
|
||||||
|
points: points.filter(function(point) { return point.label() == centroid.label() }).map(function(point) { return point.location() }),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
k: getterSetter(undefined, function(value) { return ((value % 1 == 0) & (value > 0)) }),
|
||||||
|
|
||||||
|
iterations: getterSetter(Math.pow(10, 3), function(value) { return ((value % 1 == 0) & (value > 0)) }),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
function kmeans(data, config) {
|
||||||
|
// default k
|
||||||
|
var k = config.k || Math.round(Math.sqrt(data.length / 2));
|
||||||
|
var iterations = config.iterations;
|
||||||
|
|
||||||
|
// initialize point objects with data
|
||||||
|
var points = data.map(function(vector) { return new Point(vector) });
|
||||||
|
|
||||||
|
// intialize centroids randomly
|
||||||
|
var centroids = [];
|
||||||
|
for (var i = 0; i < k; i++) {
|
||||||
|
centroids.push(new Centroid(points[i % points.length].location(), i));
|
||||||
|
};
|
||||||
|
|
||||||
|
// update labels and centroid locations until convergence
|
||||||
|
for (var iter = 0; iter < iterations; iter++) {
|
||||||
|
points.forEach(function(point) { point.updateLabel(centroids) });
|
||||||
|
centroids.forEach(function(centroid) { centroid.updateLocation(points) });
|
||||||
|
};
|
||||||
|
|
||||||
|
// return points and centroids
|
||||||
|
return {
|
||||||
|
points: points,
|
||||||
|
centroids: centroids
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// objects
|
||||||
|
function Point(location) {
|
||||||
|
var self = this;
|
||||||
|
this.location = getterSetter(location);
|
||||||
|
this.label = getterSetter();
|
||||||
|
this.updateLabel = function(centroids) {
|
||||||
|
var distancesSquared = centroids.map(function(centroid) {
|
||||||
|
return sumOfSquareDiffs(self.location(), centroid.location());
|
||||||
|
});
|
||||||
|
self.label(mindex(distancesSquared));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function Centroid(initialLocation, label) {
|
||||||
|
var self = this;
|
||||||
|
this.location = getterSetter(initialLocation);
|
||||||
|
this.label = getterSetter(label);
|
||||||
|
this.updateLocation = function(points) {
|
||||||
|
var pointsWithThisCentroid = points.filter(function(point) { return point.label() == self.label() });
|
||||||
|
if (pointsWithThisCentroid.length > 0) self.location(averageLocation(pointsWithThisCentroid));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// convenience functions
|
||||||
|
function getterSetter(initialValue, validator) {
|
||||||
|
var thingToGetSet = initialValue;
|
||||||
|
var isValid = validator || function(val) { return true };
|
||||||
|
return function(newValue) {
|
||||||
|
if (typeof newValue === 'undefined') return thingToGetSet;
|
||||||
|
if (isValid(newValue)) thingToGetSet = newValue;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function sumOfSquareDiffs(oneVector, anotherVector) {
|
||||||
|
var squareDiffs = oneVector.map(function(component, i) {
|
||||||
|
return Math.pow(component - anotherVector[i], 2);
|
||||||
|
});
|
||||||
|
return squareDiffs.reduce(function(a, b) { return a + b }, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
function mindex(array) {
|
||||||
|
var min = array.reduce(function(a, b) {
|
||||||
|
return Math.min(a, b);
|
||||||
|
});
|
||||||
|
return array.indexOf(min);
|
||||||
|
};
|
||||||
|
|
||||||
|
function sumVectors(a, b) {
|
||||||
|
return a.map(function(val, i) { return val + b[i] });
|
||||||
|
};
|
||||||
|
|
||||||
|
function averageLocation(points) {
|
||||||
|
var zeroVector = points[0].location().map(function() { return 0 });
|
||||||
|
var locations = points.map(function(point) { return point.location() });
|
||||||
|
var vectorSum = locations.reduce(function(a, b) { return sumVectors(a, b) }, zeroVector);
|
||||||
|
return vectorSum.map(function(val) { return val / points.length });
|
||||||
|
};
|
|
@ -0,0 +1,245 @@
|
||||||
|
//
|
||||||
|
// Shinobi - Motion Plugin
|
||||||
|
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||||
|
//
|
||||||
|
// # Donate
|
||||||
|
//
|
||||||
|
// If you like what I am doing here and want me to continue please consider donating :)
|
||||||
|
// PayPal : paypal@m03.ca
|
||||||
|
//
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error('uncaughtException',err);
|
||||||
|
});
|
||||||
|
var fs = require('fs');
|
||||||
|
var moment = require('moment');
|
||||||
|
var Canvas = require('canvas');
|
||||||
|
var Cluster = require('./libs/clusterPoints.js');
|
||||||
|
var config=require('./conf.json');
|
||||||
|
if(process.argv[2]&&process.argv[3]){
|
||||||
|
config.host=process.argv[2]
|
||||||
|
config.port=process.argv[3]
|
||||||
|
config.key=process.argv[4]
|
||||||
|
}
|
||||||
|
if(config.systemLog===undefined){config.systemLog=true}
|
||||||
|
s={
|
||||||
|
group:{},
|
||||||
|
}
|
||||||
|
s.systemLog=function(q,w,e){
|
||||||
|
if(!w){w=''}
|
||||||
|
if(!e){e=''}
|
||||||
|
if(config.systemLog===true){
|
||||||
|
return console.log(moment().format(),q,w,e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.checkRegion=function(d,cord){
|
||||||
|
d.width = d.image.width;
|
||||||
|
d.height = d.image.height;
|
||||||
|
if(!s.group[d.ke][d.id].canvas[cord.name]){
|
||||||
|
if(!cord.sensitivity||isNaN(cord.sensitivity)){
|
||||||
|
cord.sensitivity=d.mon.detector_sensitivity;
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height);
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d');
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#005337';
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height);
|
||||||
|
if(cord.points&&cord.points.length>0){
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].beginPath();
|
||||||
|
for (var b = 0; b < cord.points.length; b++){
|
||||||
|
cord.points[b][0]=parseFloat(cord.points[b][0]);
|
||||||
|
cord.points[b][1]=parseFloat(cord.points[b][1]);
|
||||||
|
if(b===0){
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]);
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].clip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height);
|
||||||
|
var blenderCanvas = s.group[d.ke][d.id].canvas[cord.name];
|
||||||
|
var blenderCanvasContext = s.group[d.ke][d.id].canvasContext[cord.name];
|
||||||
|
s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber] = blenderCanvasContext.getImageData(0, 0, blenderCanvas.width, blenderCanvas.height);
|
||||||
|
s.group[d.ke][d.id].frameNumber = 0 == s.group[d.ke][d.id].frameNumber ? 1 : 0;
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData = blenderCanvasContext.getImageData(0, 0, blenderCanvas.width, blenderCanvas.height);
|
||||||
|
if(!s.group[d.ke][d.id].lastRegionImageData){return}
|
||||||
|
var foundPixels = [];
|
||||||
|
var average = 0;
|
||||||
|
var currentImageLength = s.group[d.ke][d.id].lastRegionImageData.data.length * 0.25;
|
||||||
|
for (b = 0; b < currentImageLength;){
|
||||||
|
var pos = b * 4
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData.data[pos] = .5 * (255 - s.group[d.ke][d.id].lastRegionImageData.data[pos]) + .5 * s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber].data[pos];
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData.data[pos + 1] = .5 * (255 - s.group[d.ke][d.id].lastRegionImageData.data[pos + 1]) + .5 * s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber].data[pos + 1];
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData.data[pos + 2] = .5 * (255 - s.group[d.ke][d.id].lastRegionImageData.data[pos + 2]) + .5 * s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber].data[pos + 2];
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData.data[pos + 3] = 255;
|
||||||
|
var score = (s.group[d.ke][d.id].lastRegionImageData.data[pos] + s.group[d.ke][d.id].lastRegionImageData.data[pos + 1] + s.group[d.ke][d.id].lastRegionImageData.data[pos + 2]) / 3;
|
||||||
|
if(score>170){
|
||||||
|
var x = (pos / 4) % d.width;
|
||||||
|
var y = Math.floor((pos / 4) / d.width);
|
||||||
|
foundPixels.push([x,y])
|
||||||
|
}
|
||||||
|
|
||||||
|
average += (s.group[d.ke][d.id].lastRegionImageData.data[b * 4] + s.group[d.ke][d.id].lastRegionImageData.data[b * 4 + 1] + s.group[d.ke][d.id].lastRegionImageData.data[b * 4 + 2]);
|
||||||
|
|
||||||
|
b += 4;
|
||||||
|
}
|
||||||
|
// console.log(foundPixels)
|
||||||
|
var matrices
|
||||||
|
if(d.mon.detector_region_of_interest==='1'&&foundPixels.length>0){
|
||||||
|
var groupedPoints = Object.assign({},Cluster);
|
||||||
|
groupedPoints.iterations(25);
|
||||||
|
groupedPoints.data(foundPixels);
|
||||||
|
var groupedPoints = groupedPoints.clusters()
|
||||||
|
var matrices=[]
|
||||||
|
var mostHeight = 0;
|
||||||
|
var mostWidth = 0;
|
||||||
|
var mostWithMotion = null;
|
||||||
|
groupedPoints.forEach(function(v,n){
|
||||||
|
var matrix = {
|
||||||
|
topLeft:[d.width,d.height],
|
||||||
|
topRight:[0,d.height],
|
||||||
|
bottomRight:[0,0],
|
||||||
|
bottomLeft:[d.width,0],
|
||||||
|
}
|
||||||
|
v.points.forEach(function(b){
|
||||||
|
var x = b[0]
|
||||||
|
var y = b[1]
|
||||||
|
if(x<matrix.topLeft[0])matrix.topLeft[0]=x;
|
||||||
|
if(y<matrix.topLeft[1])matrix.topLeft[1]=y;
|
||||||
|
//Top Right point
|
||||||
|
if(x>matrix.topRight[0])matrix.topRight[0]=x;
|
||||||
|
if(y<matrix.topRight[1])matrix.topRight[1]=y;
|
||||||
|
//Bottom Right point
|
||||||
|
if(x>matrix.bottomRight[0])matrix.bottomRight[0]=x;
|
||||||
|
if(y>matrix.bottomRight[1])matrix.bottomRight[1]=y;
|
||||||
|
//Bottom Left point
|
||||||
|
if(x<matrix.bottomLeft[0])matrix.bottomLeft[0]=x;
|
||||||
|
if(y>matrix.bottomLeft[1])matrix.bottomLeft[1]=y;
|
||||||
|
})
|
||||||
|
matrix.x = matrix.topLeft[0];
|
||||||
|
matrix.y = matrix.topLeft[1];
|
||||||
|
matrix.width = matrix.topRight[0] - matrix.topLeft[0]
|
||||||
|
matrix.height = matrix.bottomLeft[1] - matrix.topLeft[1]
|
||||||
|
|
||||||
|
if(matrix.width>mostWidth&&matrix.height>mostHeight){
|
||||||
|
mostWidth = matrix.width;
|
||||||
|
mostHeight = matrix.height;
|
||||||
|
mostWithMotion = matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
matrices.push(matrix)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
average = (average / (currentImageLength));
|
||||||
|
if (average > parseFloat(cord.sensitivity)){
|
||||||
|
s.cx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:cord.name,reason:'motion',confidence:average,matrices:matrices}})
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height);
|
||||||
|
}
|
||||||
|
s.checkAreas=function(d){
|
||||||
|
if(!s.group[d.ke][d.id].cords){
|
||||||
|
if(!d.mon.cords){d.mon.cords={}}
|
||||||
|
s.group[d.ke][d.id].cords=Object.values(d.mon.cords);
|
||||||
|
}
|
||||||
|
if(d.mon.detector_frame==='1'){
|
||||||
|
d.mon.cords.frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]};
|
||||||
|
s.group[d.ke][d.id].cords.push(d.mon.cords.frame);
|
||||||
|
}
|
||||||
|
for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){
|
||||||
|
if(!s.group[d.ke][d.id].cords[b]){return}
|
||||||
|
s.checkRegion(d,s.group[d.ke][d.id].cords[b])
|
||||||
|
}
|
||||||
|
delete(d.image)
|
||||||
|
}
|
||||||
|
|
||||||
|
io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master
|
||||||
|
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||||
|
io.on('connect',function(d){
|
||||||
|
s.cx({f:'init',plug:config.plug,notice:config.notice});
|
||||||
|
})
|
||||||
|
io.on('disconnect',function(d){
|
||||||
|
io.connect();
|
||||||
|
})
|
||||||
|
io.on('f',function(d){
|
||||||
|
switch(d.f){
|
||||||
|
case'init_monitor':
|
||||||
|
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id].canvas={}
|
||||||
|
s.group[d.ke][d.id].canvasContext={}
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData=undefined
|
||||||
|
s.group[d.ke][d.id].frameNumber=0
|
||||||
|
s.group[d.ke][d.id].frameSelected=[]
|
||||||
|
delete(s.group[d.ke][d.id].cords)
|
||||||
|
delete(s.group[d.ke][d.id].buffer)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'frame':
|
||||||
|
try{
|
||||||
|
if(!s.group[d.ke]){
|
||||||
|
s.group[d.ke]={}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id]={
|
||||||
|
canvas:{},
|
||||||
|
canvasContext:{},
|
||||||
|
lastRegionImageData:undefined,
|
||||||
|
frameNumber:0,
|
||||||
|
frameSelected:[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id].buffer){
|
||||||
|
s.group[d.ke][d.id].buffer=[d.frame];
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||||
|
}
|
||||||
|
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||||
|
if(s.group[d.ke][d.id].motion_lock){
|
||||||
|
return
|
||||||
|
}else{
|
||||||
|
if(!d.mon.detector_lock_timeout||d.mon.detector_lock_timeout===''||d.mon.detector_lock_timeout==0){
|
||||||
|
d.mon.detector_lock_timeout=2000
|
||||||
|
}else{
|
||||||
|
d.mon.detector_lock_timeout=parseFloat(d.mon.detector_lock_timeout)
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].motion_lock=setTimeout(function(){
|
||||||
|
clearTimeout(s.group[d.ke][d.id].motion_lock);
|
||||||
|
delete(s.group[d.ke][d.id].motion_lock);
|
||||||
|
},d.mon.detector_lock_timeout)
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer);
|
||||||
|
if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){
|
||||||
|
d.mon.cords=[]
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
d.mon.cords=JSON.parse(d.mon.cords)
|
||||||
|
}catch(err){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(d.mon.detector_frame_save==="1"){
|
||||||
|
d.base64=s.group[d.ke][d.id].buffer.toString('base64')
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].cords=Object.values(d.mon.cords);
|
||||||
|
d.mon.cords=d.mon.cords;
|
||||||
|
d.image = new Canvas.Image;
|
||||||
|
if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){
|
||||||
|
s.systemLog('Must set detector image size')
|
||||||
|
return
|
||||||
|
}else{
|
||||||
|
d.image.width=d.mon.detector_scale_x;
|
||||||
|
d.image.height=d.mon.detector_scale_y;
|
||||||
|
}
|
||||||
|
d.image.onload = function() {
|
||||||
|
s.checkAreas(d);
|
||||||
|
}
|
||||||
|
d.image.src = s.group[d.ke][d.id].buffer;
|
||||||
|
s.group[d.ke][d.id].buffer=null;
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
if(err){
|
||||||
|
s.systemLog(err)
|
||||||
|
delete(s.group[d.ke][d.id].buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,233 @@
|
||||||
|
//
|
||||||
|
// Shinobi - Motion Plugin
|
||||||
|
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||||
|
//
|
||||||
|
// # Donate
|
||||||
|
//
|
||||||
|
// If you like what I am doing here and want me to continue please consider donating :)
|
||||||
|
// PayPal : paypal@m03.ca
|
||||||
|
//
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error('uncaughtException',err);
|
||||||
|
});
|
||||||
|
var fs = require('fs');
|
||||||
|
var moment = require('moment');
|
||||||
|
var Canvas = require('canvas');
|
||||||
|
var config=require('./conf.json');
|
||||||
|
if(process.argv[2]&&process.argv[3]){
|
||||||
|
config.host=process.argv[2]
|
||||||
|
config.port=process.argv[3]
|
||||||
|
config.key=process.argv[4]
|
||||||
|
}
|
||||||
|
if(config.systemLog===undefined){config.systemLog=true}
|
||||||
|
s={
|
||||||
|
group:{},
|
||||||
|
}
|
||||||
|
s.systemLog=function(q,w,e){
|
||||||
|
if(!w){w=''}
|
||||||
|
if(!e){e=''}
|
||||||
|
if(config.systemLog===true){
|
||||||
|
return console.log(moment().format(),q,w,e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.blenderRegion=function(d,cord){
|
||||||
|
d.width = d.image.width;
|
||||||
|
d.height = d.image.height;
|
||||||
|
if(!s.group[d.ke][d.id].canvas[cord.name]){
|
||||||
|
if(!cord.sensitivity||isNaN(cord.sensitivity)){
|
||||||
|
cord.sensitivity=d.mon.detector_sensitivity;
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height);
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d');
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#005337';
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height);
|
||||||
|
if(cord.points&&cord.points.length>0){
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].beginPath();
|
||||||
|
for (var b = 0; b < cord.points.length; b++){
|
||||||
|
cord.points[b][0]=parseFloat(cord.points[b][0]);
|
||||||
|
cord.points[b][1]=parseFloat(cord.points[b][1]);
|
||||||
|
if(b===0){
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]);
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].clip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id].canvasContext[cord.name]){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height);
|
||||||
|
if(!s.group[d.ke][d.id].blendRegion[cord.name]){
|
||||||
|
s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height);
|
||||||
|
s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d');
|
||||||
|
}
|
||||||
|
var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||||
|
// create an image if the previous image doesn<73>t exist
|
||||||
|
if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||||
|
// create a ImageData instance to receive the blended result
|
||||||
|
var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height);
|
||||||
|
// blend the 2 images
|
||||||
|
s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data);
|
||||||
|
// draw the result in a canvas
|
||||||
|
s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0);
|
||||||
|
// store the current webcam image
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData;
|
||||||
|
blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||||
|
var i = 0;
|
||||||
|
var average = 0;
|
||||||
|
while (i < (blendedData.data.length * 0.25)) {
|
||||||
|
average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
average = (average / (blendedData.data.length * 0.25))*10;
|
||||||
|
if (average > parseFloat(cord.sensitivity)){
|
||||||
|
s.cx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:cord.name,reason:'motion',confidence:average}})
|
||||||
|
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height);
|
||||||
|
s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height);
|
||||||
|
}
|
||||||
|
function fastAbs(value) {
|
||||||
|
return (value ^ (value >> 31)) - (value >> 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
function threshold(value) {
|
||||||
|
return (value > 0x15) ? 0xFF : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function difference(target, data1, data2) {
|
||||||
|
// blend mode difference
|
||||||
|
if (data1.length != data2.length) return null;
|
||||||
|
var i = 0;
|
||||||
|
while (i < (data1.length * 0.25)) {
|
||||||
|
target[4 * i] = data1[4 * i] == 0 ? 0 : fastAbs(data1[4 * i] - data2[4 * i]);
|
||||||
|
target[4 * i + 1] = data1[4 * i + 1] == 0 ? 0 : fastAbs(data1[4 * i + 1] - data2[4 * i + 1]);
|
||||||
|
target[4 * i + 2] = data1[4 * i + 2] == 0 ? 0 : fastAbs(data1[4 * i + 2] - data2[4 * i + 2]);
|
||||||
|
target[4 * i + 3] = 0xFF;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.differenceAccuracy=function(target, data1, data2) {
|
||||||
|
if (data1.length != data2.length) return null;
|
||||||
|
var i = 0;
|
||||||
|
while (i < (data1.length * 0.25)) {
|
||||||
|
var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3;
|
||||||
|
var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3;
|
||||||
|
var diff = threshold(fastAbs(average1 - average2));
|
||||||
|
target[4 * i] = diff;
|
||||||
|
target[4 * i + 1] = diff;
|
||||||
|
target[4 * i + 2] = diff;
|
||||||
|
target[4 * i + 3] = 0xFF;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.checkAreas=function(d){
|
||||||
|
if(!s.group[d.ke][d.id].cords){
|
||||||
|
if(!d.mon.cords){d.mon.cords={}}
|
||||||
|
s.group[d.ke][d.id].cords=Object.values(d.mon.cords);
|
||||||
|
}
|
||||||
|
if(d.mon.detector_frame==='1'){
|
||||||
|
d.mon.cords.frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]};
|
||||||
|
s.group[d.ke][d.id].cords.push(d.mon.cords.frame);
|
||||||
|
}
|
||||||
|
for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){
|
||||||
|
if(!s.group[d.ke][d.id].cords[b]){return}
|
||||||
|
s.blenderRegion(d,s.group[d.ke][d.id].cords[b])
|
||||||
|
}
|
||||||
|
delete(d.image)
|
||||||
|
}
|
||||||
|
|
||||||
|
io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master
|
||||||
|
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||||
|
io.on('connect',function(d){
|
||||||
|
s.cx({f:'init',plug:config.plug,notice:config.notice});
|
||||||
|
})
|
||||||
|
io.on('disconnect',function(d){
|
||||||
|
io.connect();
|
||||||
|
})
|
||||||
|
io.on('f',function(d){
|
||||||
|
switch(d.f){
|
||||||
|
case'init_monitor':
|
||||||
|
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id].canvas={}
|
||||||
|
s.group[d.ke][d.id].canvasContext={}
|
||||||
|
s.group[d.ke][d.id].blendRegion={}
|
||||||
|
s.group[d.ke][d.id].blendRegionContext={}
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData={}
|
||||||
|
delete(s.group[d.ke][d.id].cords)
|
||||||
|
delete(s.group[d.ke][d.id].buffer)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'frame':
|
||||||
|
try{
|
||||||
|
if(!s.group[d.ke]){
|
||||||
|
s.group[d.ke]={}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id]={
|
||||||
|
canvas:{},
|
||||||
|
canvasContext:{},
|
||||||
|
lastRegionImageData:{},
|
||||||
|
blendRegion:{},
|
||||||
|
blendRegionContext:{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id].buffer){
|
||||||
|
s.group[d.ke][d.id].buffer=[d.frame];
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||||
|
}
|
||||||
|
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||||
|
if(s.group[d.ke][d.id].motion_lock){
|
||||||
|
return
|
||||||
|
}else{
|
||||||
|
if(!d.mon.detector_lock_timeout||d.mon.detector_lock_timeout===''||d.mon.detector_lock_timeout==0){
|
||||||
|
d.mon.detector_lock_timeout=2000
|
||||||
|
}else{
|
||||||
|
d.mon.detector_lock_timeout=parseFloat(d.mon.detector_lock_timeout)
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].motion_lock=setTimeout(function(){
|
||||||
|
clearTimeout(s.group[d.ke][d.id].motion_lock);
|
||||||
|
delete(s.group[d.ke][d.id].motion_lock);
|
||||||
|
},d.mon.detector_lock_timeout)
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer);
|
||||||
|
if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){
|
||||||
|
d.mon.cords=[]
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
d.mon.cords=JSON.parse(d.mon.cords)
|
||||||
|
}catch(err){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(d.mon.detector_frame_save==="1"){
|
||||||
|
d.base64=s.group[d.ke][d.id].buffer.toString('base64')
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].cords=Object.values(d.mon.cords);
|
||||||
|
d.mon.cords=d.mon.cords;
|
||||||
|
d.image = new Canvas.Image;
|
||||||
|
if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){
|
||||||
|
s.systemLog('Must set detector image size')
|
||||||
|
return
|
||||||
|
}else{
|
||||||
|
d.image.width=d.mon.detector_scale_x;
|
||||||
|
d.image.height=d.mon.detector_scale_y;
|
||||||
|
}
|
||||||
|
d.image.onload = function() {
|
||||||
|
s.checkAreas(d);
|
||||||
|
}
|
||||||
|
d.image.src = s.group[d.ke][d.id].buffer;
|
||||||
|
s.group[d.ke][d.id].buffer=null;
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
if(err){
|
||||||
|
s.systemLog(err)
|
||||||
|
delete(s.group[d.ke][d.id].buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,2 @@
|
||||||
|
conf.json
|
||||||
|
cascades
|
|
@ -0,0 +1,93 @@
|
||||||
|
# OpenALPR and Motion Detector
|
||||||
|
|
||||||
|
Install required libraries.
|
||||||
|
|
||||||
|
**Ubuntu and Debian only**
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt update && sudo apt install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++ openalpr openalpr-daemon openalpr-utils libopenalpr-dev -y
|
||||||
|
```
|
||||||
|
|
||||||
|
**Install the Node.js Canvas engine**
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo npm install canvas@1.6
|
||||||
|
```
|
||||||
|
Go to the Shinobi directory. **Below is an example.**
|
||||||
|
|
||||||
|
```
|
||||||
|
cd /home/Shinobi
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy the config file.
|
||||||
|
|
||||||
|
```
|
||||||
|
cp plugins/openalpr/conf.sample.json plugins/openalpr/conf.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit it the new file. Host should be `localhost` and port should match the `listening port for camera.js`.
|
||||||
|
|
||||||
|
```
|
||||||
|
nano plugins/openalpr/conf.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Start the plugin.
|
||||||
|
|
||||||
|
```
|
||||||
|
node plugins/openalpr/shinobi-motion.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Or to daemonize with PM2.
|
||||||
|
|
||||||
|
```
|
||||||
|
pm2 start plugins/openalpr/shinobi-motion.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped.
|
||||||
|
|
||||||
|
## Run the plugin as a Host
|
||||||
|
> The main app (Shinobi) will be the client and the plugin will be the host. The purpose of allowing this method is so that you can use one plugin for multiple Shinobi instances. Allowing you to easily manage connections without starting multiple processes.
|
||||||
|
|
||||||
|
Edit your plugins configuration file. Set the `hostPort` **to be different** than the `listening port for camera.js`.
|
||||||
|
|
||||||
|
```
|
||||||
|
nano plugins/openalpr/conf.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is a sample of a Host configuration for the plugin.
|
||||||
|
- `plug` is the name of the plugin corresponding in the main configuration file.
|
||||||
|
- `https` choose if you want to use SSL or not. Default is `false`.
|
||||||
|
- `hostPort` can be any available port number. **Don't make this the same port number as Shinobi.** Default is `8082`.
|
||||||
|
- `type` tells the main application (Shinobi) what kind of plugin it is. In this case it is a detector.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"plug":"OpenALPR",
|
||||||
|
"hostPort":8082,
|
||||||
|
"key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi",
|
||||||
|
"mode":"host",
|
||||||
|
"type":"detector"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now modify the **main configuration file** located in the main directory of Shinobi. *Where you currently should be.*
|
||||||
|
|
||||||
|
```
|
||||||
|
nano conf.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the `plugins` array if you don't already have it. Add the following *object inside the array*.
|
||||||
|
|
||||||
|
```
|
||||||
|
"plugins":[
|
||||||
|
{
|
||||||
|
"id" : "OpenALPR",
|
||||||
|
"https" : false,
|
||||||
|
"host" : "localhost",
|
||||||
|
"port" : 8082,
|
||||||
|
"key" : "SomeOpenALPRkeySoPeopleDontMessWithYourShinobi",
|
||||||
|
"mode" : "host",
|
||||||
|
"type" : "detector"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
```
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"plug":"OpenALPR",
|
||||||
|
"host":"localhost",
|
||||||
|
"port":8080,
|
||||||
|
"hostPort":8082,
|
||||||
|
"key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi",
|
||||||
|
"mode":"client",
|
||||||
|
"type":"detector"
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
|
||||||
|
; Specify the path to the runtime data directory
|
||||||
|
runtime_dir = ${CMAKE_INSTALL_PREFIX}/share/openalpr/runtime_data
|
||||||
|
|
||||||
|
|
||||||
|
ocr_img_size_percent = 1.33333333
|
||||||
|
state_id_img_size_percent = 2.0
|
||||||
|
|
||||||
|
; Calibrating your camera improves detection accuracy in cases where vehicle plates are captured at a steep angle
|
||||||
|
; Use the openalpr-utils-calibrate utility to calibrate your fixed camera to adjust for an angle
|
||||||
|
; Once done, update the prewarp config with the values obtained from the tool
|
||||||
|
prewarp =
|
||||||
|
|
||||||
|
; detection will ignore plates that are too large. This is a good efficiency technique to use if the
|
||||||
|
; plates are going to be a fixed distance away from the camera (e.g., you will never see plates that fill
|
||||||
|
; up the entire image
|
||||||
|
max_plate_width_percent = 100
|
||||||
|
max_plate_height_percent = 100
|
||||||
|
|
||||||
|
; detection_iteration_increase is the percentage that the LBP frame increases each iteration.
|
||||||
|
; It must be greater than 1.0. A value of 1.01 means increase by 1%, 1.10 increases it by 10% each time.
|
||||||
|
; So a 1% increase would be ~10x slower than 10% to process, but it has a higher chance of landing
|
||||||
|
; directly on the plate and getting a strong detection
|
||||||
|
detection_iteration_increase = 1.1
|
||||||
|
|
||||||
|
; The minimum detection strength determines how sure the detection algorithm must be before signaling that
|
||||||
|
; a plate region exists. Technically this corresponds to LBP nearest neighbors (e.g., how many detections
|
||||||
|
; are clustered around the same area). For example, 2 = very lenient, 9 = very strict.
|
||||||
|
detection_strictness = 3
|
||||||
|
|
||||||
|
; The detection doesn't necessarily need an extremely high resolution image in order to detect plates
|
||||||
|
; Using a smaller input image should still find the plates and will do it faster
|
||||||
|
; Tweaking the max_detection_input values will resize the input image if it is larger than these sizes
|
||||||
|
; max_detection_input_width/height are specified in pixels
|
||||||
|
max_detection_input_width = 1280
|
||||||
|
max_detection_input_height = 720
|
||||||
|
|
||||||
|
; detector is the technique used to find license plate regions in an image. Value can be set to
|
||||||
|
; lbpcpu - default LBP-based detector uses the system CPU
|
||||||
|
; lbpgpu - LBP-based detector that uses Nvidia GPU to increase recognition speed.
|
||||||
|
; lbpopencl - LBP-based detector that uses OpenCL GPU to increase recognition speed. Requires OpenCV 3.0
|
||||||
|
; morphcpu - Experimental detector that detects white rectangles in an image. Does not require training.
|
||||||
|
detector = lbpgpu
|
||||||
|
|
||||||
|
; If set to true, all results must match a postprocess text pattern if a pattern is available.
|
||||||
|
; If not, the result is disqualified.
|
||||||
|
must_match_pattern = 0
|
||||||
|
|
||||||
|
; Bypasses plate detection. If this is set to 1, the library assumes that each region provided is a likely plate area.
|
||||||
|
skip_detection = 0
|
||||||
|
|
||||||
|
; Specifies the full path to an image file that constrains the detection area. Only the plate regions allowed through the mask
|
||||||
|
; will be analyzed. The mask image must match the resolution of your image to be analyzed. The mask is black and white.
|
||||||
|
; Black areas will be ignored, white areas will be searched. An empty value means no mask (scan the entire image)
|
||||||
|
detection_mask_image =
|
||||||
|
|
||||||
|
; OpenALPR can scan the same image multiple times with different randomization. Setting this to a value larger than
|
||||||
|
; 1 may increase accuracy, but will increase processing time linearly (e.g., analysis_count = 3 is 3x slower)
|
||||||
|
analysis_count = 1
|
||||||
|
|
||||||
|
; OpenALPR detects high-contrast plate crops and uses an alternative edge detection technique. Setting this to 0.0
|
||||||
|
; would classify ALL images as high-contrast, setting it to 1.0 would classify no images as high-contrast.
|
||||||
|
contrast_detection_threshold = 0.3
|
||||||
|
|
||||||
|
max_plate_angle_degrees = 15
|
||||||
|
|
||||||
|
ocr_min_font_point = 6
|
||||||
|
|
||||||
|
; Minimum OCR confidence percent to consider.
|
||||||
|
postprocess_min_confidence = 65
|
||||||
|
|
||||||
|
; Any OCR character lower than this will also add an equally likely
|
||||||
|
; chance that the character is incorrect and will be skipped. Value is a confidence percent
|
||||||
|
postprocess_confidence_skip_level = 80
|
||||||
|
|
||||||
|
|
||||||
|
debug_general = 0
|
||||||
|
debug_timing = 0
|
||||||
|
debug_detector = 0
|
||||||
|
debug_prewarp = 0
|
||||||
|
debug_state_id = 0
|
||||||
|
debug_plate_lines = 0
|
||||||
|
debug_plate_corners = 0
|
||||||
|
debug_char_segment = 0
|
||||||
|
debug_char_analysis = 0
|
||||||
|
debug_color_filter = 0
|
||||||
|
debug_ocr = 0
|
||||||
|
debug_postprocess = 0
|
||||||
|
debug_show_images = 0
|
||||||
|
debug_pause_on_frame = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "shinobi-openalpr",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "OpenALPR plugin for Shinobi",
|
||||||
|
"main": "shinobi-openalpr.js",
|
||||||
|
"dependencies": {
|
||||||
|
"canvas": "^1.6.7",
|
||||||
|
"express": "^4.16.2",
|
||||||
|
"moment": "^2.19.2",
|
||||||
|
"socket.io": "^2.0.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {},
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Moe Alam",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
|
@ -0,0 +1,413 @@
|
||||||
|
//
|
||||||
|
// Shinobi - OpenALPR Plugin
|
||||||
|
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||||
|
//
|
||||||
|
// # Donate
|
||||||
|
//
|
||||||
|
// If you like what I am doing here and want me to continue please consider donating :)
|
||||||
|
// PayPal : paypal@m03.ca
|
||||||
|
//
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error('uncaughtException',err);
|
||||||
|
});
|
||||||
|
//main vars
|
||||||
|
var fs=require('fs');
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
var moment = require('moment');
|
||||||
|
var Canvas = require('canvas');
|
||||||
|
var express = require('express');
|
||||||
|
var config=require('./conf.json');
|
||||||
|
var http = require('http'),
|
||||||
|
app = express(),
|
||||||
|
server = http.createServer(app);
|
||||||
|
s={
|
||||||
|
group:{},
|
||||||
|
dir:{
|
||||||
|
cascades:__dirname+'/cascades/'
|
||||||
|
},
|
||||||
|
isWin:(process.platform==='win32'),
|
||||||
|
s:function(json){return JSON.stringify(json,null,3)}
|
||||||
|
}
|
||||||
|
s.checkCorrectPathEnding=function(x){
|
||||||
|
var length=x.length
|
||||||
|
if(x.charAt(length-1)!=='/'){
|
||||||
|
x=x+'/'
|
||||||
|
}
|
||||||
|
return x.replace('__DIR__',__dirname)
|
||||||
|
}
|
||||||
|
if(!config.port){config.port=8080}
|
||||||
|
if(!config.hostPort){config.hostPort=8082}
|
||||||
|
if(config.systemLog===undefined){config.systemLog=true}
|
||||||
|
if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'}
|
||||||
|
//default stream folder check
|
||||||
|
if(!config.streamDir){
|
||||||
|
if(s.isWin===false){
|
||||||
|
config.streamDir='/dev/shm'
|
||||||
|
}else{
|
||||||
|
config.streamDir=config.windowsTempDir
|
||||||
|
}
|
||||||
|
if(!fs.existsSync(config.streamDir)){
|
||||||
|
config.streamDir=__dirname+'/streams/'
|
||||||
|
}else{
|
||||||
|
config.streamDir+='/streams/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.dir.streams=config.streamDir;
|
||||||
|
//streams dir
|
||||||
|
if(!fs.existsSync(s.dir.streams)){
|
||||||
|
fs.mkdirSync(s.dir.streams);
|
||||||
|
}
|
||||||
|
s.gid=function(x){
|
||||||
|
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
for( var i=0; i < x; i++ )
|
||||||
|
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
s.detectObject=function(buffer,d,tx){
|
||||||
|
var keys = Object.keys(d.mon.detector_cascades);
|
||||||
|
if(d.mon.detector_lisence_plate==="1"){
|
||||||
|
if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){
|
||||||
|
d.mon.detector_lisence_plate_country='us'
|
||||||
|
}
|
||||||
|
d.tmpFile=s.gid(5)+'.jpg'
|
||||||
|
if(!fs.existsSync(s.dir.streams)){
|
||||||
|
fs.mkdirSync(s.dir.streams);
|
||||||
|
}
|
||||||
|
d.dir=s.dir.streams+d.ke+'/'
|
||||||
|
if(!fs.existsSync(d.dir)){
|
||||||
|
fs.mkdirSync(d.dir);
|
||||||
|
}
|
||||||
|
d.dir=s.dir.streams+d.ke+'/'+d.id+'/'
|
||||||
|
if(!fs.existsSync(d.dir)){
|
||||||
|
fs.mkdirSync(d.dir);
|
||||||
|
}
|
||||||
|
fs.writeFile(d.dir+d.tmpFile,buffer,function(err){
|
||||||
|
if(err) return s.systemLog(err);
|
||||||
|
exec('alpr -j --config '+config.alprConfig+' -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => {
|
||||||
|
if(err){
|
||||||
|
s.systemLog(err);
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
try{
|
||||||
|
scan=JSON.parse(scan.replace('--(!)Loaded CUDA classifier','').trim())
|
||||||
|
}catch(err){
|
||||||
|
if(!scan||!scan.results){
|
||||||
|
return s.systemLog(scan,err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log('scan',scan)
|
||||||
|
if(scan.results.length>0){
|
||||||
|
if(s.isNumberOfTriggersMet(d,2)){
|
||||||
|
scan.plates=[]
|
||||||
|
scan.mats=[]
|
||||||
|
scan.results.forEach(function(v){
|
||||||
|
v.candidates.forEach(function(g,n){
|
||||||
|
if(v.candidates[n].matches_template)
|
||||||
|
delete(v.candidates[n].matches_template)
|
||||||
|
})
|
||||||
|
scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate})
|
||||||
|
var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2));
|
||||||
|
var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2))
|
||||||
|
scan.mats.push({
|
||||||
|
x:v.coordinates[0].x,
|
||||||
|
y:v.coordinates[0].y,
|
||||||
|
width:width,
|
||||||
|
height:height,
|
||||||
|
tag:v.plate
|
||||||
|
})
|
||||||
|
})
|
||||||
|
tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
s.systemLog(scan,err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.systemLog=function(q,w,e){
|
||||||
|
if(w===undefined){return}
|
||||||
|
if(!w){w=''}
|
||||||
|
if(!e){e=''}
|
||||||
|
if(config.systemLog===true){
|
||||||
|
return console.log(moment().format(),q,w,e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.blenderRegion=function(d,cord,tx){
|
||||||
|
d.width = d.image.width;
|
||||||
|
d.height = d.image.height;
|
||||||
|
if(!s.group[d.ke][d.id].canvas[cord.name]){
|
||||||
|
if(!cord.sensitivity||isNaN(cord.sensitivity)){
|
||||||
|
cord.sensitivity=d.mon.detector_sensitivity;
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height);
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d');
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#000';
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height);
|
||||||
|
if(cord.points&&cord.points.length>0){
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].beginPath();
|
||||||
|
for (var b = 0; b < cord.points.length; b++){
|
||||||
|
cord.points[b][0]=parseFloat(cord.points[b][0]);
|
||||||
|
cord.points[b][1]=parseFloat(cord.points[b][1]);
|
||||||
|
if(b===0){
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]);
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].clip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id].canvasContext[cord.name]){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height);
|
||||||
|
if(!s.group[d.ke][d.id].blendRegion[cord.name]){
|
||||||
|
s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height);
|
||||||
|
s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d');
|
||||||
|
}
|
||||||
|
var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||||
|
// create an image if the previous image doesn<73>t exist
|
||||||
|
if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||||
|
// create a ImageData instance to receive the blended result
|
||||||
|
var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height);
|
||||||
|
// blend the 2 images
|
||||||
|
s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data);
|
||||||
|
// draw the result in a canvas
|
||||||
|
s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0);
|
||||||
|
// store the current webcam image
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData;
|
||||||
|
blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||||
|
var i = 0;
|
||||||
|
d.average = 0;
|
||||||
|
while (i < (blendedData.data.length * 0.25)) {
|
||||||
|
d.average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
d.average = (d.average / (blendedData.data.length * 0.25))*10;
|
||||||
|
if (d.average > parseFloat(cord.sensitivity)){
|
||||||
|
if(s.isNumberOfTriggersMet(d,2)){
|
||||||
|
if(d.mon.detector_use_detect_object==="1"&&d.mon.detector_second!=='1'){
|
||||||
|
var buffer=s.group[d.ke][d.id].canvas[cord.name].toBuffer();
|
||||||
|
s.detectObject(buffer,d,tx)
|
||||||
|
}else{
|
||||||
|
tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:cord.name,reason:'motion',confidence:d.average,frame:d.base64}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height);
|
||||||
|
s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height);
|
||||||
|
}
|
||||||
|
function blobToBuffer (blob, cb) {
|
||||||
|
if (typeof Blob === 'undefined' || !(blob instanceof Blob)) {
|
||||||
|
throw new Error('first argument must be a Blob')
|
||||||
|
}
|
||||||
|
if (typeof cb !== 'function') {
|
||||||
|
throw new Error('second argument must be a function')
|
||||||
|
}
|
||||||
|
|
||||||
|
var reader = new FileReader()
|
||||||
|
|
||||||
|
function onLoadEnd (e) {
|
||||||
|
reader.removeEventListener('loadend', onLoadEnd, false)
|
||||||
|
if (e.error) cb(e.error)
|
||||||
|
else cb(null, Buffer.from(reader.result))
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.addEventListener('loadend', onLoadEnd, false)
|
||||||
|
reader.readAsArrayBuffer(blob)
|
||||||
|
}
|
||||||
|
function fastAbs(value) {
|
||||||
|
return (value ^ (value >> 31)) - (value >> 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
function threshold(value) {
|
||||||
|
return (value > 0x15) ? 0xFF : 0;
|
||||||
|
}
|
||||||
|
s.differenceAccuracy=function(target, data1, data2) {
|
||||||
|
if (data1.length != data2.length) return null;
|
||||||
|
var i = 0;
|
||||||
|
while (i < (data1.length * 0.25)) {
|
||||||
|
var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3;
|
||||||
|
var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3;
|
||||||
|
var diff = threshold(fastAbs(average1 - average2));
|
||||||
|
target[4 * i] = diff;
|
||||||
|
target[4 * i + 1] = diff;
|
||||||
|
target[4 * i + 2] = diff;
|
||||||
|
target[4 * i + 3] = 0xFF;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.checkAreas=function(d,tx){
|
||||||
|
if(!s.group[d.ke][d.id].cords){
|
||||||
|
if(!d.mon.cords){d.mon.cords={}}
|
||||||
|
s.group[d.ke][d.id].cords=Object.values(d.mon.cords);
|
||||||
|
}
|
||||||
|
if(d.mon.detector_frame==='1'){
|
||||||
|
d.mon.cords.frame={name:'FULL_FRAME',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]};
|
||||||
|
s.group[d.ke][d.id].cords.push(d.mon.cords.frame);
|
||||||
|
}
|
||||||
|
for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){
|
||||||
|
if(!s.group[d.ke][d.id].cords[b]){return}
|
||||||
|
s.blenderRegion(d,s.group[d.ke][d.id].cords[b],tx)
|
||||||
|
}
|
||||||
|
delete(d.image)
|
||||||
|
}
|
||||||
|
s.isNumberOfTriggersMet = function(d,max){
|
||||||
|
// ++s.group[d.ke][d.id].numberOfTriggers
|
||||||
|
// clearTimeout(s.group[d.ke][d.id].numberOfTriggersTimeout)
|
||||||
|
// s.group[d.ke][d.id].numberOfTriggersTimeout = setTimeout(function(){
|
||||||
|
// s.group[d.ke][d.id].numberOfTriggers=0
|
||||||
|
// },10000)
|
||||||
|
// if(s.group[d.ke][d.id].numberOfTriggers>max){
|
||||||
|
return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
}
|
||||||
|
s.MainEventController=function(d,cn,tx){
|
||||||
|
switch(d.f){
|
||||||
|
case'init_plugin_as_host':
|
||||||
|
if(!cn){
|
||||||
|
console.log('No CN',d)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(d.key!==config.key){
|
||||||
|
console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d)
|
||||||
|
cn.emit('init',{ok:false})
|
||||||
|
cn.disconnect()
|
||||||
|
}else{
|
||||||
|
console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress)
|
||||||
|
cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type})
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'init_monitor':
|
||||||
|
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id].canvas={}
|
||||||
|
s.group[d.ke][d.id].canvasContext={}
|
||||||
|
s.group[d.ke][d.id].blendRegion={}
|
||||||
|
s.group[d.ke][d.id].blendRegionContext={}
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData={}
|
||||||
|
s.group[d.ke][d.id].numberOfTriggers=0
|
||||||
|
delete(s.group[d.ke][d.id].cords)
|
||||||
|
delete(s.group[d.ke][d.id].buffer)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'init_aws_push':
|
||||||
|
// console.log('init_aws')
|
||||||
|
s.group[d.ke][d.id].aws={links:[],complete:0,total:d.total,videos:[],tx:tx}
|
||||||
|
break;
|
||||||
|
case'frame':
|
||||||
|
try{
|
||||||
|
if(!s.group[d.ke]){
|
||||||
|
s.group[d.ke]={}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id]={
|
||||||
|
canvas:{},
|
||||||
|
canvasContext:{},
|
||||||
|
lastRegionImageData:{},
|
||||||
|
blendRegion:{},
|
||||||
|
blendRegionContext:{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id].buffer){
|
||||||
|
s.group[d.ke][d.id].buffer=[d.frame];
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||||
|
}
|
||||||
|
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||||
|
s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer);
|
||||||
|
try{
|
||||||
|
d.mon.detector_cascades=JSON.parse(d.mon.detector_cascades)
|
||||||
|
}catch(err){
|
||||||
|
|
||||||
|
}
|
||||||
|
if(d.mon.detector_frame_save==="1"){
|
||||||
|
d.base64=s.group[d.ke][d.id].buffer.toString('base64')
|
||||||
|
}
|
||||||
|
if(d.mon.detector_second==='1'&&d.objectOnly===true){
|
||||||
|
s.detectObject(s.group[d.ke][d.id].buffer,d,tx)
|
||||||
|
}else{
|
||||||
|
if(d.mon.detector_use_motion==="1"||d.mon.detector_use_detect_object!=="1"){
|
||||||
|
if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){
|
||||||
|
d.mon.cords=[]
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
d.mon.cords=JSON.parse(d.mon.cords)
|
||||||
|
}catch(err){
|
||||||
|
// console.log('d.mon.cords',err,d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].cords=Object.values(d.mon.cords);
|
||||||
|
d.mon.cords=d.mon.cords;
|
||||||
|
d.image = new Canvas.Image;
|
||||||
|
if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){
|
||||||
|
s.systemLog('Must set detector image size')
|
||||||
|
return
|
||||||
|
}else{
|
||||||
|
d.image.width=d.mon.detector_scale_x;
|
||||||
|
d.image.height=d.mon.detector_scale_y;
|
||||||
|
}
|
||||||
|
d.width=d.image.width;
|
||||||
|
d.height=d.image.height;
|
||||||
|
d.image.onload = function() {
|
||||||
|
s.checkAreas(d,tx);
|
||||||
|
}
|
||||||
|
d.image.src = s.group[d.ke][d.id].buffer;
|
||||||
|
}else{
|
||||||
|
s.detectObject(s.group[d.ke][d.id].buffer,d,tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].buffer=null;
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
if(err){
|
||||||
|
s.systemLog(err)
|
||||||
|
delete(s.group[d.ke][d.id].buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server.listen(config.hostPort);
|
||||||
|
//web pages and plugin api
|
||||||
|
app.get('/', function (req, res) {
|
||||||
|
res.end('<b>'+config.plug+'</b> for Shinobi is running')
|
||||||
|
});
|
||||||
|
//Conector to Shinobi
|
||||||
|
if(config.mode==='host'){
|
||||||
|
//start plugin as host
|
||||||
|
var io = require('socket.io')(server);
|
||||||
|
io.attach(server);
|
||||||
|
s.connectedClients={};
|
||||||
|
io.on('connection', function (cn) {
|
||||||
|
s.connectedClients[cn.id]={id:cn.id}
|
||||||
|
s.connectedClients[cn.id].tx = function(data){
|
||||||
|
data.pluginKey=config.key;data.plug=config.plug;
|
||||||
|
return io.to(cn.id).emit('ocv',data);
|
||||||
|
}
|
||||||
|
cn.on('f',function(d){
|
||||||
|
s.MainEventController(d,cn,s.connectedClients[cn.id].tx)
|
||||||
|
});
|
||||||
|
cn.on('disconnect',function(d){
|
||||||
|
delete(s.connectedClients[cn.id])
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
//start plugin as client
|
||||||
|
if(!config.host){config.host='localhost'}
|
||||||
|
var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master
|
||||||
|
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||||
|
io.on('connect',function(d){
|
||||||
|
s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type});
|
||||||
|
})
|
||||||
|
io.on('disconnect',function(d){
|
||||||
|
io.connect();
|
||||||
|
})
|
||||||
|
io.on('f',function(d){
|
||||||
|
s.MainEventController(d,null,s.cx)
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
conf.json
|
||||||
|
cascades
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
if [ $(dpkg-query -W -f='${Status}' opencv_version 2>/dev/null | grep -c "ok installed") -eq 0 ]; then
|
||||||
|
echo "Shinobi - Do ypu want to let the `opencv4nodejs` npm package install OpenCV? "
|
||||||
|
echo "Only do this if you do not have OpenCV already or will not use a GPU (Hardware Acceleration)."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read nodejsinstall
|
||||||
|
if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then
|
||||||
|
export OPENCV4NODEJS_DISABLE_AUTOBUILD=0
|
||||||
|
else
|
||||||
|
export OPENCV4NODEJS_DISABLE_AUTOBUILD=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
export OPENCV4NODEJS_DISABLE_AUTOBUILD=1
|
||||||
|
fi
|
||||||
|
npm install opencv4nodejs moment express canvas@1.6 --unsafe-perm
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"plug":"OpenCV",
|
||||||
|
"host":"localhost",
|
||||||
|
"port":8080,
|
||||||
|
"hostPort":8082,
|
||||||
|
"key":"change_this_to_something_very_random____make_sure_to_match__/plugins/opencv/conf.json",
|
||||||
|
"mode":"client",
|
||||||
|
"type":"detector"
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
|
||||||
|
; Specify the path to the runtime data directory
|
||||||
|
runtime_dir = ${CMAKE_INSTALL_PREFIX}/share/openalpr/runtime_data
|
||||||
|
|
||||||
|
|
||||||
|
ocr_img_size_percent = 1.33333333
|
||||||
|
state_id_img_size_percent = 2.0
|
||||||
|
|
||||||
|
; Calibrating your camera improves detection accuracy in cases where vehicle plates are captured at a steep angle
|
||||||
|
; Use the openalpr-utils-calibrate utility to calibrate your fixed camera to adjust for an angle
|
||||||
|
; Once done, update the prewarp config with the values obtained from the tool
|
||||||
|
prewarp =
|
||||||
|
|
||||||
|
; detection will ignore plates that are too large. This is a good efficiency technique to use if the
|
||||||
|
; plates are going to be a fixed distance away from the camera (e.g., you will never see plates that fill
|
||||||
|
; up the entire image
|
||||||
|
max_plate_width_percent = 100
|
||||||
|
max_plate_height_percent = 100
|
||||||
|
|
||||||
|
; detection_iteration_increase is the percentage that the LBP frame increases each iteration.
|
||||||
|
; It must be greater than 1.0. A value of 1.01 means increase by 1%, 1.10 increases it by 10% each time.
|
||||||
|
; So a 1% increase would be ~10x slower than 10% to process, but it has a higher chance of landing
|
||||||
|
; directly on the plate and getting a strong detection
|
||||||
|
detection_iteration_increase = 1.1
|
||||||
|
|
||||||
|
; The minimum detection strength determines how sure the detection algorithm must be before signaling that
|
||||||
|
; a plate region exists. Technically this corresponds to LBP nearest neighbors (e.g., how many detections
|
||||||
|
; are clustered around the same area). For example, 2 = very lenient, 9 = very strict.
|
||||||
|
detection_strictness = 3
|
||||||
|
|
||||||
|
; The detection doesn't necessarily need an extremely high resolution image in order to detect plates
|
||||||
|
; Using a smaller input image should still find the plates and will do it faster
|
||||||
|
; Tweaking the max_detection_input values will resize the input image if it is larger than these sizes
|
||||||
|
; max_detection_input_width/height are specified in pixels
|
||||||
|
max_detection_input_width = 1280
|
||||||
|
max_detection_input_height = 720
|
||||||
|
|
||||||
|
; detector is the technique used to find license plate regions in an image. Value can be set to
|
||||||
|
; lbpcpu - default LBP-based detector uses the system CPU
|
||||||
|
; lbpgpu - LBP-based detector that uses Nvidia GPU to increase recognition speed.
|
||||||
|
; lbpopencl - LBP-based detector that uses OpenCL GPU to increase recognition speed. Requires OpenCV 3.0
|
||||||
|
; morphcpu - Experimental detector that detects white rectangles in an image. Does not require training.
|
||||||
|
detector = lbpgpu
|
||||||
|
|
||||||
|
; If set to true, all results must match a postprocess text pattern if a pattern is available.
|
||||||
|
; If not, the result is disqualified.
|
||||||
|
must_match_pattern = 0
|
||||||
|
|
||||||
|
; Bypasses plate detection. If this is set to 1, the library assumes that each region provided is a likely plate area.
|
||||||
|
skip_detection = 0
|
||||||
|
|
||||||
|
; Specifies the full path to an image file that constrains the detection area. Only the plate regions allowed through the mask
|
||||||
|
; will be analyzed. The mask image must match the resolution of your image to be analyzed. The mask is black and white.
|
||||||
|
; Black areas will be ignored, white areas will be searched. An empty value means no mask (scan the entire image)
|
||||||
|
detection_mask_image =
|
||||||
|
|
||||||
|
; OpenALPR can scan the same image multiple times with different randomization. Setting this to a value larger than
|
||||||
|
; 1 may increase accuracy, but will increase processing time linearly (e.g., analysis_count = 3 is 3x slower)
|
||||||
|
analysis_count = 1
|
||||||
|
|
||||||
|
; OpenALPR detects high-contrast plate crops and uses an alternative edge detection technique. Setting this to 0.0
|
||||||
|
; would classify ALL images as high-contrast, setting it to 1.0 would classify no images as high-contrast.
|
||||||
|
contrast_detection_threshold = 0.3
|
||||||
|
|
||||||
|
max_plate_angle_degrees = 15
|
||||||
|
|
||||||
|
ocr_min_font_point = 6
|
||||||
|
|
||||||
|
; Minimum OCR confidence percent to consider.
|
||||||
|
postprocess_min_confidence = 65
|
||||||
|
|
||||||
|
; Any OCR character lower than this will also add an equally likely
|
||||||
|
; chance that the character is incorrect and will be skipped. Value is a confidence percent
|
||||||
|
postprocess_confidence_skip_level = 80
|
||||||
|
|
||||||
|
|
||||||
|
debug_general = 0
|
||||||
|
debug_timing = 0
|
||||||
|
debug_detector = 0
|
||||||
|
debug_prewarp = 0
|
||||||
|
debug_state_id = 0
|
||||||
|
debug_plate_lines = 0
|
||||||
|
debug_plate_corners = 0
|
||||||
|
debug_char_segment = 0
|
||||||
|
debug_char_analysis = 0
|
||||||
|
debug_color_filter = 0
|
||||||
|
debug_ocr = 0
|
||||||
|
debug_postprocess = 0
|
||||||
|
debug_show_images = 0
|
||||||
|
debug_pause_on_frame = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,212 @@
|
||||||
|
//
|
||||||
|
// Shinobi - OpenCV Plugin
|
||||||
|
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||||
|
//
|
||||||
|
// # Donate
|
||||||
|
//
|
||||||
|
// If you like what I am doing here and want me to continue please consider donating :)
|
||||||
|
// PayPal : paypal@m03.a
|
||||||
|
//
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error('uncaughtException',err);
|
||||||
|
});
|
||||||
|
var fs=require('fs');
|
||||||
|
var cv=require('opencv');
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
var moment = require('moment');
|
||||||
|
var config=require('./conf.json');
|
||||||
|
if(config.systemLog===undefined){config.systemLog=true}
|
||||||
|
s={
|
||||||
|
group:{},
|
||||||
|
dir:{
|
||||||
|
cascades:__dirname+'/cascades/'
|
||||||
|
},
|
||||||
|
isWin:(process.platform==='win32')
|
||||||
|
}
|
||||||
|
//default stream folder check
|
||||||
|
if(!config.streamDir){
|
||||||
|
if(s.isWin===false){
|
||||||
|
config.streamDir='/dev/shm'
|
||||||
|
}else{
|
||||||
|
config.streamDir=config.windowsTempDir
|
||||||
|
}
|
||||||
|
if(!fs.existsSync(config.streamDir)){
|
||||||
|
config.streamDir=__dirname+'/streams/'
|
||||||
|
}else{
|
||||||
|
config.streamDir+='/streams/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.dir.streams=config.streamDir;
|
||||||
|
//streams dir
|
||||||
|
if(!fs.existsSync(s.dir.streams)){
|
||||||
|
fs.mkdirSync(s.dir.streams);
|
||||||
|
}
|
||||||
|
s.gid=function(x){
|
||||||
|
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
for( var i=0; i < x; i++ )
|
||||||
|
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
s.systemLog=function(q,w,e){
|
||||||
|
if(!w){w=''}
|
||||||
|
if(!e){e=''}
|
||||||
|
if(config.systemLog===true){
|
||||||
|
return console.log(moment().format(),q,w,e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.findCascades=function(callback){
|
||||||
|
var tmp={};
|
||||||
|
tmp.foundCascades=[];
|
||||||
|
fs.readdir(s.dir.cascades,function(err,files){
|
||||||
|
files.forEach(function(cascade,n){
|
||||||
|
if(cascade.indexOf('.xml')>-1){
|
||||||
|
tmp.foundCascades.push(cascade.replace('.xml',''))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
s.cascadesInDir=tmp.foundCascades;
|
||||||
|
callback(tmp.foundCascades)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
s.findCascades(function(){
|
||||||
|
//get cascades
|
||||||
|
})
|
||||||
|
s.detectObject=function(buffer,d){
|
||||||
|
var keys = Object.keys(d.mon.detector_cascades);
|
||||||
|
if(d.mon.detector_lisence_plate==="1"){
|
||||||
|
if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){
|
||||||
|
d.mon.detector_lisence_plate_country='us'
|
||||||
|
}
|
||||||
|
d.tmpFile=s.gid(5)+'.jpg'
|
||||||
|
if(!fs.existsSync(s.dir.streams)){
|
||||||
|
fs.mkdirSync(s.dir.streams);
|
||||||
|
}
|
||||||
|
d.dir=s.dir.streams+d.ke+'/'
|
||||||
|
if(!fs.existsSync(d.dir)){
|
||||||
|
fs.mkdirSync(d.dir);
|
||||||
|
}
|
||||||
|
d.dir=s.dir.streams+d.ke+'/'+d.id+'/'
|
||||||
|
if(!fs.existsSync(d.dir)){
|
||||||
|
fs.mkdirSync(d.dir);
|
||||||
|
}
|
||||||
|
fs.writeFile(d.dir+d.tmpFile,buffer,function(err){
|
||||||
|
if(err) return s.systemLog(err);
|
||||||
|
exec('alpr -j -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => {
|
||||||
|
if(err){
|
||||||
|
s.systemLog(err);
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
try{
|
||||||
|
scan=JSON.parse(scan)
|
||||||
|
}catch(err){
|
||||||
|
if(!scan||!scan.results){
|
||||||
|
return s.systemLog(scan,err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(scan.results.length>0){
|
||||||
|
scan.plates=[]
|
||||||
|
scan.mats=[]
|
||||||
|
scan.results.forEach(function(v){
|
||||||
|
v.candidates.forEach(function(g,n){
|
||||||
|
if(v.candidates[n].matches_template)
|
||||||
|
delete(v.candidates[n].matches_template)
|
||||||
|
})
|
||||||
|
scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate})
|
||||||
|
var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2));
|
||||||
|
var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2))
|
||||||
|
scan.mats.push({
|
||||||
|
x:v.coordinates[0].x,
|
||||||
|
y:v.coordinates[0].y,
|
||||||
|
width:width,
|
||||||
|
height:height,
|
||||||
|
tag:v.plate
|
||||||
|
})
|
||||||
|
})
|
||||||
|
tx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,confidence:d.average,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}})
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
s.systemLog(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(keys.length===0){return false}
|
||||||
|
cv.readImage(buffer, function(err,im){
|
||||||
|
if(err){console.log(err);return false;}
|
||||||
|
var width = im.width();
|
||||||
|
var height = im.height();
|
||||||
|
|
||||||
|
if (width < 1 || height < 1) {
|
||||||
|
throw new Error('Image has no size');
|
||||||
|
}
|
||||||
|
keys.forEach(function(v,n){
|
||||||
|
im.detectObject(s.dir.cascades+v+'.xml',{}, function(err,mats){
|
||||||
|
if(err){console.log(err);return false;}
|
||||||
|
if(mats&&mats.length>0){
|
||||||
|
s.cx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:v,reason:'object',matrices:mats,confidence:d.average,imgHeight:height,imgWidth:width}})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master
|
||||||
|
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||||
|
io.on('connect',function(d){
|
||||||
|
s.cx({f:'init',plug:config.plug});
|
||||||
|
})
|
||||||
|
io.on('disconnect',function(d){
|
||||||
|
io.connect()
|
||||||
|
})
|
||||||
|
io.on('f',function(d){
|
||||||
|
switch(d.f){
|
||||||
|
case'refreshPlugins':
|
||||||
|
s.findCascades(function(cascades){
|
||||||
|
s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:cascades},to:'GRP_'+d.ke})
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'readPlugins':
|
||||||
|
s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:s.cascadesInDir},to:'GRP_'+d.ke})
|
||||||
|
break;
|
||||||
|
case'init_monitor':
|
||||||
|
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id].canvas={}
|
||||||
|
s.group[d.ke][d.id].canvasContext={}
|
||||||
|
s.group[d.ke][d.id].blendRegion={}
|
||||||
|
s.group[d.ke][d.id].blendRegionContext={}
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData={}
|
||||||
|
delete(s.group[d.ke][d.id].cords)
|
||||||
|
delete(s.group[d.ke][d.id].buffer)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'frame':
|
||||||
|
d.details={}
|
||||||
|
try{
|
||||||
|
if(!s.group[d.ke]){
|
||||||
|
s.group[d.ke]={}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id]={
|
||||||
|
canvas:{},
|
||||||
|
canvasContext:{},
|
||||||
|
lastRegionImageData:{},
|
||||||
|
blendRegion:{},
|
||||||
|
blendRegionContext:{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id].buffer){
|
||||||
|
s.group[d.ke][d.id].buffer=[d.frame];
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||||
|
}
|
||||||
|
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||||
|
s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer);
|
||||||
|
s.detectObject(s.group[d.ke][d.id].buffer,d)
|
||||||
|
s.group[d.ke][d.id].buffer=null;
|
||||||
|
}
|
||||||
|
} catch(err){
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,465 @@
|
||||||
|
//
|
||||||
|
// Shinobi - OpenCV Plugin
|
||||||
|
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||||
|
//
|
||||||
|
// # Donate
|
||||||
|
//
|
||||||
|
// If you like what I am doing here and want me to continue please consider donating :)
|
||||||
|
// PayPal : paypal@m03.ca
|
||||||
|
//
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error('uncaughtException',err);
|
||||||
|
});
|
||||||
|
var fs=require('fs');
|
||||||
|
var cv=require('opencv4nodejs');
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
var moment = require('moment');
|
||||||
|
var Canvas = require('canvas');
|
||||||
|
var express = require('express');
|
||||||
|
var http = require('http'),
|
||||||
|
app = express(),
|
||||||
|
server = http.createServer(app);
|
||||||
|
var config=require('./conf.json');
|
||||||
|
if(!config.port){config.port=8080}
|
||||||
|
if(!config.hostPort){config.hostPort=8082}
|
||||||
|
if(config.systemLog===undefined){config.systemLog=true}
|
||||||
|
if(config.cascadesDir===undefined){config.cascadesDir=__dirname+'/cascades/'}
|
||||||
|
if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'}
|
||||||
|
s={
|
||||||
|
group:{},
|
||||||
|
dir:{
|
||||||
|
cascades : config.cascadesDir
|
||||||
|
},
|
||||||
|
isWin:(process.platform==='win32'),
|
||||||
|
foundCascades : {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//default stream folder check
|
||||||
|
if(!config.streamDir){
|
||||||
|
if(s.isWin===false){
|
||||||
|
config.streamDir='/dev/shm'
|
||||||
|
}else{
|
||||||
|
config.streamDir=config.windowsTempDir
|
||||||
|
}
|
||||||
|
if(!fs.existsSync(config.streamDir)){
|
||||||
|
config.streamDir=__dirname+'/streams/'
|
||||||
|
}else{
|
||||||
|
config.streamDir+='/streams/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.dir.streams=config.streamDir;
|
||||||
|
//streams dir
|
||||||
|
if(!fs.existsSync(s.dir.streams)){
|
||||||
|
fs.mkdirSync(s.dir.streams);
|
||||||
|
}
|
||||||
|
//streams dir
|
||||||
|
if(!fs.existsSync(s.dir.cascades)){
|
||||||
|
fs.mkdirSync(s.dir.cascades);
|
||||||
|
}
|
||||||
|
s.gid=function(x){
|
||||||
|
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
for( var i=0; i < x; i++ )
|
||||||
|
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
s.findCascades=function(callback){
|
||||||
|
var tmp={};
|
||||||
|
tmp.foundCascades=[];
|
||||||
|
fs.readdir(s.dir.cascades,function(err,files){
|
||||||
|
files.forEach(function(cascade,n){
|
||||||
|
if(cascade.indexOf('.xml')>-1){
|
||||||
|
tmp.foundCascades.push(cascade.replace('.xml',''))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
s.cascadesInDir=tmp.foundCascades;
|
||||||
|
callback(tmp.foundCascades)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
s.findCascades(function(){
|
||||||
|
//get cascades
|
||||||
|
})
|
||||||
|
s.detectLicensePlate=function(buffer,d,tx){
|
||||||
|
if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){
|
||||||
|
d.mon.detector_lisence_plate_country='us'
|
||||||
|
}
|
||||||
|
d.tmpFile=s.gid(5)+'.jpg'
|
||||||
|
if(!fs.existsSync(s.dir.streams)){
|
||||||
|
fs.mkdirSync(s.dir.streams);
|
||||||
|
}
|
||||||
|
d.dir=s.dir.streams+d.ke+'/'
|
||||||
|
if(!fs.existsSync(d.dir)){
|
||||||
|
fs.mkdirSync(d.dir);
|
||||||
|
}
|
||||||
|
d.dir=s.dir.streams+d.ke+'/'+d.id+'/'
|
||||||
|
if(!fs.existsSync(d.dir)){
|
||||||
|
fs.mkdirSync(d.dir);
|
||||||
|
}
|
||||||
|
fs.writeFile(d.dir+d.tmpFile,buffer,function(err){
|
||||||
|
if(err) return s.systemLog(err);
|
||||||
|
exec('alpr -j --config '+config.alprConfig+' -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => {
|
||||||
|
if(err){
|
||||||
|
s.systemLog(err);
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
scan=JSON.parse(scan.replace('--(!)Loaded CUDA classifier','').trim())
|
||||||
|
}catch(err){
|
||||||
|
if(!scan||!scan.results){
|
||||||
|
return s.systemLog(scan,err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(scan.results.length>0){
|
||||||
|
scan.plates=[]
|
||||||
|
scan.mats=[]
|
||||||
|
scan.results.forEach(function(v){
|
||||||
|
v.candidates.forEach(function(g,n){
|
||||||
|
if(v.candidates[n].matches_template)
|
||||||
|
delete(v.candidates[n].matches_template)
|
||||||
|
})
|
||||||
|
scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate})
|
||||||
|
var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2));
|
||||||
|
var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2))
|
||||||
|
scan.mats.push({
|
||||||
|
x:v.coordinates[0].x,
|
||||||
|
y:v.coordinates[0].y,
|
||||||
|
width:width,
|
||||||
|
height:height,
|
||||||
|
tag:v.plate
|
||||||
|
})
|
||||||
|
})
|
||||||
|
tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
s.detectObject=function(buffer,d,tx){
|
||||||
|
//detect license plate?
|
||||||
|
if(d.mon.detector_lisence_plate==="1"){
|
||||||
|
s.detectLicensePlate(buffer,d,tx)
|
||||||
|
}
|
||||||
|
//check selected opencv cascades
|
||||||
|
if(!d.mon.detector_cascades || d.mon.detector_cascades === '')return;
|
||||||
|
var selectedCascades = Object.keys(d.mon.detector_cascades);
|
||||||
|
if(selectedCascades.length > 0){
|
||||||
|
cv.imdecodeAsync(buffer,(err,im) => {
|
||||||
|
if(err){
|
||||||
|
console.log(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selectedCascades.forEach(function(cascade){
|
||||||
|
var cascadePath = s.dir.cascades+cascade+'.xml'
|
||||||
|
if(s.foundCascades[cascadePath] === undefined){
|
||||||
|
s.foundCascades[cascadePath] = fs.existsSync(cascadePath)
|
||||||
|
}else if(s.foundCascades[cascadePath] === false){
|
||||||
|
return s.systemLog('Attempted to use non existant cascade. : '+cascadePath)
|
||||||
|
}
|
||||||
|
var classifier = new cv.CascadeClassifier(cascadePath)
|
||||||
|
var matrices = classifier.detectMultiScaleGpu(im).objects
|
||||||
|
if(matrices.length > 0){
|
||||||
|
matrices.forEach(function(v,n){
|
||||||
|
v.centerX=v.width/2
|
||||||
|
v.centerY=v.height/2
|
||||||
|
v.centerXnoParent=v.x+(v.width/2)
|
||||||
|
v.centerYnoParent=v.y+(v.height/2)
|
||||||
|
})
|
||||||
|
s.cx({
|
||||||
|
f:'trigger',
|
||||||
|
id:d.id,
|
||||||
|
ke:d.ke,
|
||||||
|
name:cascade,
|
||||||
|
details:{
|
||||||
|
plug:'built-in-opencv',
|
||||||
|
name:cascade,
|
||||||
|
reason:'object',
|
||||||
|
matrices : matrices,
|
||||||
|
confidence:d.average
|
||||||
|
},
|
||||||
|
imgHeight:d.mon.detector_scale_y,
|
||||||
|
imgWidth:d.mon.detector_scale_x
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.systemLog=function(q,w,e){
|
||||||
|
if(!w){w=''}
|
||||||
|
if(!e){e=''}
|
||||||
|
if(config.systemLog===true){
|
||||||
|
return console.log(moment().format(),q,w,e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.blenderRegion=function(d,cord,tx){
|
||||||
|
d.width = d.image.width;
|
||||||
|
d.height = d.image.height;
|
||||||
|
if(!s.group[d.ke][d.id].canvas[cord.name]){
|
||||||
|
if(!cord.sensitivity||isNaN(cord.sensitivity)){
|
||||||
|
cord.sensitivity=d.mon.detector_sensitivity;
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height);
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d');
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#000';
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height);
|
||||||
|
if(cord.points&&cord.points.length>0){
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].beginPath();
|
||||||
|
for (var b = 0; b < cord.points.length; b++){
|
||||||
|
cord.points[b][0]=parseFloat(cord.points[b][0]);
|
||||||
|
cord.points[b][1]=parseFloat(cord.points[b][1]);
|
||||||
|
if(b===0){
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]);
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].clip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id].canvasContext[cord.name]){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height);
|
||||||
|
if(!s.group[d.ke][d.id].blendRegion[cord.name]){
|
||||||
|
s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height);
|
||||||
|
s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d');
|
||||||
|
}
|
||||||
|
var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||||
|
// create an image if the previous image doesn<73>t exist
|
||||||
|
if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||||
|
// create a ImageData instance to receive the blended result
|
||||||
|
var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height);
|
||||||
|
// blend the 2 images
|
||||||
|
s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data);
|
||||||
|
// draw the result in a canvas
|
||||||
|
s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0);
|
||||||
|
// store the current webcam image
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData;
|
||||||
|
blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||||
|
var i = 0;
|
||||||
|
d.average = 0;
|
||||||
|
while (i < (blendedData.data.length * 0.25)) {
|
||||||
|
d.average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
d.average = (d.average / (blendedData.data.length * 0.25))*10;
|
||||||
|
if (d.average > parseFloat(cord.sensitivity)){
|
||||||
|
if(d.mon.detector_use_detect_object==="1"&&d.mon.detector_second!=='1'){
|
||||||
|
var buffer=s.group[d.ke][d.id].canvas[cord.name].toBuffer();
|
||||||
|
s.detectObject(buffer,d,tx)
|
||||||
|
}else{
|
||||||
|
tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:cord.name,reason:'motion',confidence:d.average,frame:d.base64}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height);
|
||||||
|
s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height);
|
||||||
|
}
|
||||||
|
function blobToBuffer (blob, cb) {
|
||||||
|
if (typeof Blob === 'undefined' || !(blob instanceof Blob)) {
|
||||||
|
throw new Error('first argument must be a Blob')
|
||||||
|
}
|
||||||
|
if (typeof cb !== 'function') {
|
||||||
|
throw new Error('second argument must be a function')
|
||||||
|
}
|
||||||
|
|
||||||
|
var reader = new FileReader()
|
||||||
|
|
||||||
|
function onLoadEnd (e) {
|
||||||
|
reader.removeEventListener('loadend', onLoadEnd, false)
|
||||||
|
if (e.error) cb(e.error)
|
||||||
|
else cb(null, Buffer.from(reader.result))
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.addEventListener('loadend', onLoadEnd, false)
|
||||||
|
reader.readAsArrayBuffer(blob)
|
||||||
|
}
|
||||||
|
function fastAbs(value) {
|
||||||
|
return (value ^ (value >> 31)) - (value >> 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
function threshold(value) {
|
||||||
|
return (value > 0x15) ? 0xFF : 0;
|
||||||
|
}
|
||||||
|
s.differenceAccuracy=function(target, data1, data2) {
|
||||||
|
if (data1.length != data2.length) return null;
|
||||||
|
var i = 0;
|
||||||
|
while (i < (data1.length * 0.25)) {
|
||||||
|
var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3;
|
||||||
|
var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3;
|
||||||
|
var diff = threshold(fastAbs(average1 - average2));
|
||||||
|
target[4 * i] = diff;
|
||||||
|
target[4 * i + 1] = diff;
|
||||||
|
target[4 * i + 2] = diff;
|
||||||
|
target[4 * i + 3] = 0xFF;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.checkAreas=function(d,tx){
|
||||||
|
if(!s.group[d.ke][d.id].cords){
|
||||||
|
if(!d.mon.cords){d.mon.cords={}}
|
||||||
|
s.group[d.ke][d.id].cords=Object.values(d.mon.cords);
|
||||||
|
}
|
||||||
|
if(d.mon.detector_frame==='1'){
|
||||||
|
d.mon.cords.frame={name:'FULL_FRAME',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]};
|
||||||
|
s.group[d.ke][d.id].cords.push(d.mon.cords.frame);
|
||||||
|
}
|
||||||
|
for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){
|
||||||
|
if(!s.group[d.ke][d.id].cords[b]){return}
|
||||||
|
s.blenderRegion(d,s.group[d.ke][d.id].cords[b],tx)
|
||||||
|
}
|
||||||
|
delete(d.image)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.MainEventController=function(d,cn,tx){
|
||||||
|
switch(d.f){
|
||||||
|
case'refreshPlugins':
|
||||||
|
s.findCascades(function(cascades){
|
||||||
|
s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:cascades},to:'GRP_'+d.ke})
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'readPlugins':
|
||||||
|
s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:s.cascadesInDir},to:'GRP_'+d.ke})
|
||||||
|
break;
|
||||||
|
case'init_plugin_as_host':
|
||||||
|
if(!cn){
|
||||||
|
console.log('No CN',d)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(d.key!==config.key){
|
||||||
|
console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d)
|
||||||
|
cn.emit('init',{ok:false})
|
||||||
|
cn.disconnect()
|
||||||
|
}else{
|
||||||
|
console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress)
|
||||||
|
cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type})
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'init_monitor':
|
||||||
|
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id].canvas={}
|
||||||
|
s.group[d.ke][d.id].canvasContext={}
|
||||||
|
s.group[d.ke][d.id].blendRegion={}
|
||||||
|
s.group[d.ke][d.id].blendRegionContext={}
|
||||||
|
s.group[d.ke][d.id].lastRegionImageData={}
|
||||||
|
s.group[d.ke][d.id].numberOfTriggers=0
|
||||||
|
delete(s.group[d.ke][d.id].cords)
|
||||||
|
delete(s.group[d.ke][d.id].buffer)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'init_aws_push':
|
||||||
|
// console.log('init_aws')
|
||||||
|
s.group[d.ke][d.id].aws={links:[],complete:0,total:d.total,videos:[],tx:tx}
|
||||||
|
break;
|
||||||
|
case'frame':
|
||||||
|
try{
|
||||||
|
if(!s.group[d.ke]){
|
||||||
|
s.group[d.ke]={}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id]){
|
||||||
|
s.group[d.ke][d.id]={
|
||||||
|
canvas:{},
|
||||||
|
canvasContext:{},
|
||||||
|
lastRegionImageData:{},
|
||||||
|
blendRegion:{},
|
||||||
|
blendRegionContext:{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!s.group[d.ke][d.id].buffer){
|
||||||
|
s.group[d.ke][d.id].buffer=[d.frame];
|
||||||
|
}else{
|
||||||
|
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||||
|
}
|
||||||
|
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||||
|
s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer);
|
||||||
|
try{
|
||||||
|
d.mon.detector_cascades=JSON.parse(d.mon.detector_cascades)
|
||||||
|
}catch(err){
|
||||||
|
|
||||||
|
}
|
||||||
|
if(d.mon.detector_frame_save==="1"){
|
||||||
|
d.base64=s.group[d.ke][d.id].buffer.toString('base64')
|
||||||
|
}
|
||||||
|
if(d.mon.detector_second==='1'&&d.objectOnly===true){
|
||||||
|
s.detectObject(s.group[d.ke][d.id].buffer,d,tx)
|
||||||
|
}else{
|
||||||
|
if((d.mon.detector_pam !== '1' && d.mon.detector_use_motion === "1") || d.mon.detector_use_detect_object !== "1"){
|
||||||
|
if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){
|
||||||
|
d.mon.cords=[]
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
d.mon.cords=JSON.parse(d.mon.cords)
|
||||||
|
}catch(err){
|
||||||
|
// console.log('d.mon.cords',err,d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].cords=Object.values(d.mon.cords);
|
||||||
|
d.mon.cords=d.mon.cords;
|
||||||
|
d.image = new Canvas.Image;
|
||||||
|
if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){
|
||||||
|
s.systemLog('Must set detector image size')
|
||||||
|
return
|
||||||
|
}else{
|
||||||
|
d.image.width=d.mon.detector_scale_x;
|
||||||
|
d.image.height=d.mon.detector_scale_y;
|
||||||
|
}
|
||||||
|
d.width=d.image.width;
|
||||||
|
d.height=d.image.height;
|
||||||
|
d.image.onload = function() {
|
||||||
|
s.checkAreas(d,tx);
|
||||||
|
}
|
||||||
|
d.image.src = s.group[d.ke][d.id].buffer;
|
||||||
|
}else{
|
||||||
|
s.detectObject(s.group[d.ke][d.id].buffer,d,tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.group[d.ke][d.id].buffer=null;
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
if(err){
|
||||||
|
s.systemLog(err)
|
||||||
|
delete(s.group[d.ke][d.id].buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server.listen(config.hostPort);
|
||||||
|
//web pages and plugin api
|
||||||
|
app.get('/', function (req, res) {
|
||||||
|
res.end('<b>'+config.plug+'</b> for Shinobi is running')
|
||||||
|
});
|
||||||
|
//Conector to Shinobi
|
||||||
|
if(config.mode==='host'){
|
||||||
|
//start plugin as host
|
||||||
|
var io = require('socket.io')(server);
|
||||||
|
io.attach(server);
|
||||||
|
s.connectedClients={};
|
||||||
|
io.on('connection', function (cn) {
|
||||||
|
s.connectedClients[cn.id]={id:cn.id}
|
||||||
|
s.connectedClients[cn.id].tx = function(data){
|
||||||
|
data.pluginKey=config.key;data.plug=config.plug;
|
||||||
|
return io.to(cn.id).emit('ocv',data);
|
||||||
|
}
|
||||||
|
cn.on('f',function(d){
|
||||||
|
s.MainEventController(d,cn,s.connectedClients[cn.id].tx)
|
||||||
|
});
|
||||||
|
cn.on('disconnect',function(d){
|
||||||
|
delete(s.connectedClients[cn.id])
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
//start plugin as client
|
||||||
|
if(!config.host){config.host='localhost'}
|
||||||
|
var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master
|
||||||
|
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||||
|
io.on('connect',function(d){
|
||||||
|
s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type});
|
||||||
|
})
|
||||||
|
io.on('disconnect',function(d){
|
||||||
|
io.connect();
|
||||||
|
})
|
||||||
|
io.on('f',function(d){
|
||||||
|
s.MainEventController(d,null,s.cx)
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
monitors.sql
|
||||||
|
users.sql
|
||||||
|
shinobi.sqlite
|
|
@ -0,0 +1,20 @@
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 192.168.88.58
|
||||||
|
-- Server version: 5.7.17-0ubuntu0.16.04.1 - (Ubuntu)
|
||||||
|
-- Server OS: Linux
|
||||||
|
-- HeidiSQL Version: 9.3.0.4984
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
|
||||||
|
-- Dumping database structure for ccio
|
||||||
|
CREATE DATABASE IF NOT EXISTS `ccio` /*!40100 DEFAULT CHARACTER SET utf8 */;
|
||||||
|
USE `ccio`;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
@ -0,0 +1,20 @@
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 66.51.132.100
|
||||||
|
-- Server version: 5.7.16-0ubuntu0.16.04.1 - (Ubuntu)
|
||||||
|
-- Server OS: Linux
|
||||||
|
-- HeidiSQL Version: 9.3.0.4984
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
-- Dumping data for table ccio.Users: ~0 rows (approximately)
|
||||||
|
/*!40000 ALTER TABLE `Users` DISABLE KEYS */;
|
||||||
|
INSERT INTO `Users` (`ke`, `uid`, `auth`, `mail`, `pass`, `details`) VALUES
|
||||||
|
('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}');
|
||||||
|
INSERT INTO `Monitors` (`mid`, `ke`, `name`, `shto`, `shfr`, `details`, `type`, `ext`, `protocol`, `host`, `path`, `port`, `fps`, `mode`, `width`, `height`) VALUES ('Demo', '2Df5hBE', 'Demo', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480);
|
||||||
|
/*!40000 ALTER TABLE `Users` ENABLE KEYS */;
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
@ -0,0 +1,107 @@
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 192.168.88.37
|
||||||
|
-- Server version: 10.1.25-MariaDB- - Ubuntu 17.04
|
||||||
|
-- Server OS: debian-linux-gnu
|
||||||
|
-- HeidiSQL Version: 9.4.0.5125
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8 */;
|
||||||
|
/*!50503 SET NAMES utf8mb4 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
|
||||||
|
|
||||||
|
-- Dumping database structure for ccio
|
||||||
|
CREATE DATABASE IF NOT EXISTS `ccio` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
|
||||||
|
USE `ccio`;
|
||||||
|
|
||||||
|
-- Dumping structure for table ccio.API
|
||||||
|
CREATE TABLE IF NOT EXISTS `API` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`uid` varchar(50) DEFAULT NULL,
|
||||||
|
`ip` tinytext,
|
||||||
|
`code` varchar(100) DEFAULT NULL,
|
||||||
|
`details` text,
|
||||||
|
`time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Events
|
||||||
|
CREATE TABLE IF NOT EXISTS `Events` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`details` text,
|
||||||
|
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Logs
|
||||||
|
CREATE TABLE IF NOT EXISTS `Logs` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`info` text,
|
||||||
|
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Monitors
|
||||||
|
CREATE TABLE IF NOT EXISTS `Monitors` (
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`name` varchar(50) DEFAULT NULL,
|
||||||
|
`shto` text,
|
||||||
|
`shfr` text,
|
||||||
|
`details` longtext,
|
||||||
|
`type` varchar(50) DEFAULT 'jpeg',
|
||||||
|
`ext` varchar(50) DEFAULT 'webm',
|
||||||
|
`protocol` varchar(50) DEFAULT 'http',
|
||||||
|
`host` varchar(100) DEFAULT '0.0.0.0',
|
||||||
|
`path` varchar(100) DEFAULT '/',
|
||||||
|
`port` int(8) DEFAULT '80',
|
||||||
|
`fps` int(8) DEFAULT '1',
|
||||||
|
`mode` varchar(15) DEFAULT NULL,
|
||||||
|
`width` int(11) DEFAULT '640',
|
||||||
|
`height` int(11) DEFAULT '360'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Presets
|
||||||
|
CREATE TABLE IF NOT EXISTS `Presets` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`name` text,
|
||||||
|
`details` text,
|
||||||
|
`type` enum('monitor','event','user') DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Users
|
||||||
|
CREATE TABLE IF NOT EXISTS `Users` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`uid` varchar(50) DEFAULT NULL,
|
||||||
|
`auth` varchar(50) DEFAULT NULL,
|
||||||
|
`mail` varchar(100) DEFAULT NULL,
|
||||||
|
`pass` varchar(100) DEFAULT NULL,
|
||||||
|
`details` longtext,
|
||||||
|
UNIQUE KEY `mail` (`mail`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Videos
|
||||||
|
CREATE TABLE IF NOT EXISTS `Videos` (
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`ext` enum('webm','mp4') DEFAULT NULL,
|
||||||
|
`time` timestamp NULL DEFAULT NULL,
|
||||||
|
`duration` float DEFAULT NULL,
|
||||||
|
`size` float DEFAULT NULL,
|
||||||
|
`frames` int(11) DEFAULT NULL,
|
||||||
|
`end` timestamp NULL DEFAULT NULL,
|
||||||
|
`status` int(1) DEFAULT '0' COMMENT '0:Building,1:Complete,2:Read,3:Archive',
|
||||||
|
`details` text
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
@ -0,0 +1,20 @@
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 66.51.132.100
|
||||||
|
-- Server version: 5.7.16-0ubuntu0.16.04.1 - (Ubuntu)
|
||||||
|
-- Server OS: Linux
|
||||||
|
-- HeidiSQL Version: 9.3.0.4984
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
-- Dumping data for table ccio.Users: ~0 rows (approximately)
|
||||||
|
/*!40000 ALTER TABLE `Users` DISABLE KEYS */;
|
||||||
|
INSERT INTO Users ([ke], [uid], [auth], [mail], [pass], [details]) VALUES
|
||||||
|
('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}');
|
||||||
|
INSERT INTO Monitors ([mid], [ke], [name], [shto], [shfr], [details], [type], [ext], [protocol], [host], [path], [port], [fps], [mode], [width], [height]) VALUES ('bunny', '2Df5hBE', 'Bunny', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480);
|
||||||
|
/*!40000 ALTER TABLE `Users` ENABLE KEYS */;
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
@ -0,0 +1,107 @@
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 192.168.88.37
|
||||||
|
-- Server version: 10.1.25-MariaDB- - Ubuntu 17.04
|
||||||
|
-- Server OS: debian-linux-gnu
|
||||||
|
-- HeidiSQL Version: 9.4.0.5125
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8 */;
|
||||||
|
/*!50503 SET NAMES utf8mb4 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
|
||||||
|
|
||||||
|
-- Dumping database structure for ccio
|
||||||
|
CREATE DATABASE `ccio` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
|
||||||
|
USE ccio;
|
||||||
|
|
||||||
|
-- Dumping structure for table ccio.API
|
||||||
|
CREATE TABLE API (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
uid varchar(50) DEFAULT NULL,
|
||||||
|
ip varchar(255),
|
||||||
|
code varchar(100) DEFAULT NULL,
|
||||||
|
details varchar(max),
|
||||||
|
time datetime2(0) NULL DEFAULT GETDATE()
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Events
|
||||||
|
CREATE TABLE Events (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
mid varchar(50) DEFAULT NULL,
|
||||||
|
details varchar(max),
|
||||||
|
time datetime2(0) NOT NULL DEFAULT GETDATE()
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Logs
|
||||||
|
CREATE TABLE Logs (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
mid varchar(50) DEFAULT NULL,
|
||||||
|
info varchar(max),
|
||||||
|
time datetime2(0) NOT NULL DEFAULT GETDATE()
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Monitors
|
||||||
|
CREATE TABLE Monitors (
|
||||||
|
mid varchar(50) DEFAULT NULL,
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
name varchar(50) DEFAULT NULL,
|
||||||
|
shto varchar(max),
|
||||||
|
shfr varchar(max),
|
||||||
|
details varchar(max),
|
||||||
|
type varchar(50) DEFAULT 'jpeg',
|
||||||
|
ext varchar(50) DEFAULT 'webm',
|
||||||
|
protocol varchar(50) DEFAULT 'http',
|
||||||
|
host varchar(100) DEFAULT '0.0.0.0',
|
||||||
|
path varchar(100) DEFAULT '/',
|
||||||
|
port int DEFAULT '80',
|
||||||
|
fps int DEFAULT '1',
|
||||||
|
mode varchar(15) DEFAULT NULL,
|
||||||
|
width int DEFAULT '640',
|
||||||
|
height int DEFAULT '360'
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Presets
|
||||||
|
CREATE TABLE Presets (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
name varchar(max),
|
||||||
|
details varchar(max),
|
||||||
|
type enum('monitor','event','user') DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Users
|
||||||
|
CREATE TABLE Users (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
uid varchar(50) DEFAULT NULL,
|
||||||
|
auth varchar(50) DEFAULT NULL,
|
||||||
|
mail varchar(100) DEFAULT NULL,
|
||||||
|
pass varchar(100) DEFAULT NULL,
|
||||||
|
details varchar(max),
|
||||||
|
CONSTRAINT mail UNIQUE (mail)
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Videos
|
||||||
|
CREATE TABLE Videos (
|
||||||
|
mid varchar(50) DEFAULT NULL,
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
ext enum('webm','mp4') DEFAULT NULL,
|
||||||
|
time datetime2(0) NULL DEFAULT NULL,
|
||||||
|
duration float DEFAULT NULL,
|
||||||
|
size float DEFAULT NULL,
|
||||||
|
frames int DEFAULT NULL,
|
||||||
|
end datetime2(0) NULL DEFAULT NULL,
|
||||||
|
status int DEFAULT '0' ,
|
||||||
|
details varchar(max)
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
@ -0,0 +1,3 @@
|
||||||
|
CREATE USER 'majesticflame'@'127.0.0.1' IDENTIFIED BY '';
|
||||||
|
GRANT ALL PRIVILEGES ON ccio.* TO 'majesticflame'@'127.0.0.1';
|
||||||
|
FLUSH PRIVILEGES;
|
|
@ -0,0 +1,20 @@
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 66.51.132.100
|
||||||
|
-- Server version: 5.7.16-0ubuntu0.16.04.1 - (Ubuntu)
|
||||||
|
-- Server OS: Linux
|
||||||
|
-- HeidiSQL Version: 9.3.0.4984
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
-- Dumping data for table ccio.Users: ~0 rows (approximately)
|
||||||
|
/*!40000 ALTER TABLE `Users` DISABLE KEYS */;
|
||||||
|
INSERT INTO Users (ke, uid, auth, mail, pass, details) VALUES
|
||||||
|
('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}');
|
||||||
|
INSERT INTO Monitors (mid, ke, name, shto, shfr, details, type, ext, protocol, host, path, port, fps, mode, width, height) VALUES ('bunny', '2Df5hBE', 'Bunny', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480);
|
||||||
|
/*!40000 ALTER TABLE `Users` ENABLE KEYS */;
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
@ -0,0 +1,107 @@
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 192.168.88.37
|
||||||
|
-- Server version: 10.1.25-MariaDB- - Ubuntu 17.04
|
||||||
|
-- Server OS: debian-linux-gnu
|
||||||
|
-- HeidiSQL Version: 9.4.0.5125
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8 */;
|
||||||
|
/*!50503 SET NAMES utf8mb4 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
|
||||||
|
|
||||||
|
-- Dumping database structure for ccio
|
||||||
|
CREATE DATABASE `ccio` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
|
||||||
|
USE ccio;
|
||||||
|
|
||||||
|
-- Dumping structure for table ccio.API
|
||||||
|
CREATE TABLE IF NOT EXISTS API (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
uid varchar(50) DEFAULT NULL,
|
||||||
|
ip tinytext,
|
||||||
|
code varchar(100) DEFAULT NULL,
|
||||||
|
details text,
|
||||||
|
time timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Events
|
||||||
|
CREATE TABLE IF NOT EXISTS Events (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
mid varchar(50) DEFAULT NULL,
|
||||||
|
details text,
|
||||||
|
time timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Logs
|
||||||
|
CREATE TABLE IF NOT EXISTS Logs (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
mid varchar(50) DEFAULT NULL,
|
||||||
|
info text,
|
||||||
|
time timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Monitors
|
||||||
|
CREATE TABLE IF NOT EXISTS Monitors (
|
||||||
|
mid varchar(50) DEFAULT NULL,
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
name varchar(50) DEFAULT NULL,
|
||||||
|
shto text,
|
||||||
|
shfr text,
|
||||||
|
details longtext,
|
||||||
|
type varchar(50) DEFAULT 'jpeg',
|
||||||
|
ext varchar(50) DEFAULT 'webm',
|
||||||
|
protocol varchar(50) DEFAULT 'http',
|
||||||
|
host varchar(100) DEFAULT '0.0.0.0',
|
||||||
|
path varchar(100) DEFAULT '/',
|
||||||
|
port int DEFAULT '80',
|
||||||
|
fps int DEFAULT '1',
|
||||||
|
mode varchar(15) DEFAULT NULL,
|
||||||
|
width int DEFAULT '640',
|
||||||
|
height int DEFAULT '360'
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Presets
|
||||||
|
CREATE TABLE IF NOT EXISTS Presets (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
name text,
|
||||||
|
details text,
|
||||||
|
type enum('monitor','event','user') DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Users
|
||||||
|
CREATE TABLE IF NOT EXISTS Users (
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
uid varchar(50) DEFAULT NULL,
|
||||||
|
auth varchar(50) DEFAULT NULL,
|
||||||
|
mail varchar(100) DEFAULT NULL,
|
||||||
|
pass varchar(100) DEFAULT NULL,
|
||||||
|
details longtext,
|
||||||
|
CONSTRAINT mail UNIQUE (mail)
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Videos
|
||||||
|
CREATE TABLE IF NOT EXISTS Videos (
|
||||||
|
mid varchar(50) DEFAULT NULL,
|
||||||
|
ke varchar(50) DEFAULT NULL,
|
||||||
|
ext enum('webm','mp4') DEFAULT NULL,
|
||||||
|
time timestamp(0) NULL DEFAULT NULL,
|
||||||
|
duration double precision DEFAULT NULL,
|
||||||
|
size double precision DEFAULT NULL,
|
||||||
|
frames int DEFAULT NULL,
|
||||||
|
end timestamp(0) NULL DEFAULT NULL,
|
||||||
|
status int DEFAULT '0' ,
|
||||||
|
details text
|
||||||
|
) ;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
@ -0,0 +1,3 @@
|
||||||
|
CREATE USER 'majesticflame'@'127.0.0.1' IDENTIFIED BY '';
|
||||||
|
GRANT ALL PRIVILEGES ON ccio.* TO 'majesticflame'@'127.0.0.1';
|
||||||
|
FLUSH PRIVILEGES;
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
update-5-6-2017.sql - allows Idle mode options and future proofs the mode field for other modes.
|
|
@ -0,0 +1,84 @@
|
||||||
|
-- Dumping structure for table ccio.API
|
||||||
|
CREATE TABLE IF NOT EXISTS `API` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`uid` varchar(50) DEFAULT NULL,
|
||||||
|
`ip` tinytext,
|
||||||
|
`code` varchar(100) DEFAULT NULL,
|
||||||
|
`details` text,
|
||||||
|
`time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Events
|
||||||
|
CREATE TABLE IF NOT EXISTS `Events` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`details` text,
|
||||||
|
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Logs
|
||||||
|
CREATE TABLE IF NOT EXISTS `Logs` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`info` text,
|
||||||
|
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Monitors
|
||||||
|
CREATE TABLE IF NOT EXISTS `Monitors` (
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`name` varchar(50) DEFAULT NULL,
|
||||||
|
`shto` text,
|
||||||
|
`shfr` text,
|
||||||
|
`details` longtext,
|
||||||
|
`type` varchar(50) DEFAULT 'jpeg',
|
||||||
|
`ext` varchar(50) DEFAULT 'webm',
|
||||||
|
`protocol` varchar(50) DEFAULT 'http',
|
||||||
|
`host` varchar(100) DEFAULT '0.0.0.0',
|
||||||
|
`path` varchar(100) DEFAULT '/',
|
||||||
|
`port` int(8) DEFAULT '80',
|
||||||
|
`fps` int(8) DEFAULT '1',
|
||||||
|
`mode` varchar(15) DEFAULT NULL,
|
||||||
|
`width` int(11) DEFAULT '640',
|
||||||
|
`height` int(11) DEFAULT '360'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Presets
|
||||||
|
CREATE TABLE IF NOT EXISTS `Presets` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`name` text,
|
||||||
|
`details` text,
|
||||||
|
`type` enum('monitor','event','user') DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Users
|
||||||
|
CREATE TABLE IF NOT EXISTS `Users` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`uid` varchar(50) DEFAULT NULL,
|
||||||
|
`auth` varchar(50) DEFAULT NULL,
|
||||||
|
`mail` varchar(100) DEFAULT NULL,
|
||||||
|
`pass` varchar(100) DEFAULT NULL,
|
||||||
|
`details` longtext,
|
||||||
|
UNIQUE KEY `mail` (`mail`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Videos
|
||||||
|
CREATE TABLE IF NOT EXISTS `Videos` (
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`ext` enum('webm','mp4') DEFAULT NULL,
|
||||||
|
`time` timestamp NULL DEFAULT NULL,
|
||||||
|
`duration` float DEFAULT NULL,
|
||||||
|
`size` float DEFAULT NULL,
|
||||||
|
`frames` int(11) DEFAULT NULL,
|
||||||
|
`end` timestamp NULL DEFAULT NULL,
|
||||||
|
`status` int(1) DEFAULT '0' COMMENT '0:Building,1:Complete,2:Read,3:Archive',
|
||||||
|
`details` text
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
@ -0,0 +1,11 @@
|
||||||
|
USE ccio;
|
||||||
|
ALTER TABLE Monitors MODIFY ext VARCHAR(50);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `API` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`uid` varchar(50) DEFAULT NULL,
|
||||||
|
`ip` tinytext,
|
||||||
|
`code` varchar(100) DEFAULT NULL,
|
||||||
|
`details` text,
|
||||||
|
`time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
@ -0,0 +1,2 @@
|
||||||
|
USE `ccio`;
|
||||||
|
ALTER TABLE Videos CHANGE end end TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
|
|
@ -0,0 +1,17 @@
|
||||||
|
CREATE DATABASE IF NOT EXISTS `ccio`;
|
||||||
|
USE `ccio`;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `BackupVideos` (
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`ext` varchar(15) DEFAULT NULL,
|
||||||
|
`time` timestamp NULL DEFAULT NULL,
|
||||||
|
`end` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`size` float DEFAULT NULL,
|
||||||
|
`details` longtext
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
ALTER TABLE Videos MODIFY COLUMN `ext` varchar(15);
|
||||||
|
ALTER TABLE Videos ADD `details` longtext;
|
||||||
|
ALTER TABLE Videos DROP COLUMN `frames`;
|
||||||
|
ALTER TABLE Videos DROP COLUMN `duration`;
|
|
@ -0,0 +1,28 @@
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 192.168.88.58
|
||||||
|
-- Server version: 5.7.17-0ubuntu0.16.04.1 - (Ubuntu)
|
||||||
|
-- Server OS: Linux
|
||||||
|
-- HeidiSQL Version: 9.3.0.4984
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
|
||||||
|
-- Dumping database structure for ccio
|
||||||
|
USE ccio;
|
||||||
|
ALTER TABLE `Monitors` CHANGE COLUMN `protocol` `protocol` VARCHAR(50) NULL DEFAULT 'http' AFTER `ext`;
|
||||||
|
|
||||||
|
-- Dumping structure for table ccio.Events
|
||||||
|
CREATE TABLE IF NOT EXISTS `Events` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`mid` varchar(50) DEFAULT NULL,
|
||||||
|
`details` text,
|
||||||
|
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
@ -0,0 +1,2 @@
|
||||||
|
use ccio
|
||||||
|
ALTER TABLE `Videos` ADD COLUMN `details` TEXT NULL DEFAULT NULL AFTER `status`;
|
|
@ -0,0 +1,3 @@
|
||||||
|
USE `ccio`;
|
||||||
|
|
||||||
|
ALTER TABLE Monitors MODIFY COLUMN `mode` varchar(15);
|
|
@ -0,0 +1,3 @@
|
||||||
|
CREATE USER 'majesticflame'@'127.0.0.1' IDENTIFIED BY '';
|
||||||
|
GRANT ALL PRIVILEGES ON ccio.* TO 'majesticflame'@'127.0.0.1';
|
||||||
|
FLUSH PRIVILEGES;
|
|
@ -0,0 +1,6 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"mail":"admin@shinobi.video",
|
||||||
|
"pass":"21232f297a57a5a743894a0e4a801fc3"
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,48 @@
|
||||||
|
//add videos to SQL tables from filesystem
|
||||||
|
var fs = require('fs');
|
||||||
|
var moment = require('moment');
|
||||||
|
var mysql = require('mysql');
|
||||||
|
var config = require('../conf.json');
|
||||||
|
s={}
|
||||||
|
s.disc=function(){
|
||||||
|
sql = mysql.createConnection(config.db);
|
||||||
|
sql.connect(function(err){if(err){console.log('Error Connecting : DB',err);setTimeout(s.disc, 2000);}});
|
||||||
|
sql.on('error',function(err) {console.log('DB Lost.. Retrying..');console.log(err);s.disc();return;});
|
||||||
|
}
|
||||||
|
s.disc();
|
||||||
|
if(!config.videosDir){config.videosDir=__dirname+'/../videos/'}
|
||||||
|
s.dir={videos:config.videosDir};
|
||||||
|
s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;}
|
||||||
|
s.moment=function(e,x){
|
||||||
|
if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};
|
||||||
|
return moment(e).format(x);
|
||||||
|
}
|
||||||
|
fs.readdir(s.dir.videos,function(err,groups){
|
||||||
|
groups.forEach(function(group){
|
||||||
|
fs.readdir(s.dir.videos+group,function(err,cameras){
|
||||||
|
cameras.forEach(function(camera){
|
||||||
|
fs.readdir(s.dir.videos+group+'/'+camera,function(err,videos){
|
||||||
|
sql.query('SELECT * FROM Videos WHERE ke=? AND mid=?',[group,camera],function(err,r){
|
||||||
|
videos.forEach(function(filename){
|
||||||
|
fs.stat(s.dir.videos+group+'/'+camera+'/'+filename,function(err,file){
|
||||||
|
file.startTime=s.nameToTime(filename)
|
||||||
|
file.endTime=s.moment(file.mtime,'YYYY-MM-DD HH:mm:ss')
|
||||||
|
var save=[camera,group,filename.split('.')[1],file.size,file.startTime,file.endTime,1]
|
||||||
|
var found=null
|
||||||
|
r.forEach(function(v){
|
||||||
|
if(s.moment(v.time,'YYYY-MM-DD HH:mm:ss')===file.startTime){
|
||||||
|
found=v
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(!found){
|
||||||
|
console.log('!found',save)
|
||||||
|
sql.query('INSERT INTO Videos (mid,ke,ext,size,time,end,status) VALUES (?,?,?,?,?,?,?)',save)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Shinobi (http://shinobi.video) - FFMPEG H.264 over HTTP Test
|
||||||
|
// How to Use
|
||||||
|
// 1. Start with `node ffmpegToWeb.js`
|
||||||
|
// 2. Get the IP address of the computer where you did step 1. Example : 127.0.0.1
|
||||||
|
// 3. Open VLC and "Open Network Stream".
|
||||||
|
// 4. Input the following without quotes : `http://127.0.0.1:8001` and start.
|
||||||
|
|
||||||
|
var child = require('child_process');
|
||||||
|
var events = require('events');
|
||||||
|
var spawn = child.spawn;
|
||||||
|
var exec = child.exec;
|
||||||
|
var Emitter = new events.EventEmitter().setMaxListeners(0)
|
||||||
|
var config = {
|
||||||
|
port:8001
|
||||||
|
}
|
||||||
|
//ffmpeg
|
||||||
|
console.log('Starting FFMPEG')
|
||||||
|
var ffmpeg = spawn('ffmpeg',('-rtsp_transport tcp -i rtsp://131.95.3.162/axis-media/media.3gp -f mpegts -c:v copy -an -').split(' '));
|
||||||
|
ffmpeg.on('close', function (buffer) {
|
||||||
|
console.log('ffmpeg died')
|
||||||
|
})
|
||||||
|
//ffmpeg.stderr.on('data', function (buffer) {
|
||||||
|
// console.log(buffer.toString())
|
||||||
|
//});
|
||||||
|
ffmpeg.stdout.on('data', function (buffer) {
|
||||||
|
Emitter.emit('data',buffer)
|
||||||
|
});
|
||||||
|
//web app
|
||||||
|
console.log('Starting Express Web Server on Port '+config.port)
|
||||||
|
var express = require('express')
|
||||||
|
var app = express();
|
||||||
|
var http = require('http')
|
||||||
|
var httpServer = http.createServer(app);
|
||||||
|
|
||||||
|
app.get('/', function (req, res) {
|
||||||
|
var contentWriter
|
||||||
|
var date = new Date();
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Date': date.toUTCString(),
|
||||||
|
'Connection': 'close',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
'Pragma': 'no-cache',
|
||||||
|
'Content-Type': 'video/mp4',
|
||||||
|
'Server': 'Shinobi H.264 Test Stream',
|
||||||
|
});
|
||||||
|
Emitter.on('data',contentWriter=function(buffer){
|
||||||
|
res.write(buffer)
|
||||||
|
})
|
||||||
|
res.on('close', function () {
|
||||||
|
Emitter.removeListener('data',contentWriter)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
httpServer.listen(config.port);
|
|
@ -0,0 +1,30 @@
|
||||||
|
process.on('uncaughtException', function (err) {
|
||||||
|
console.error('Uncaught Exception occured!');
|
||||||
|
console.error(err.stack);
|
||||||
|
});
|
||||||
|
var configLocation = __dirname+'/../conf.json';
|
||||||
|
var fs = require('fs');
|
||||||
|
var jsonfile = require("jsonfile");
|
||||||
|
var config = jsonfile.readFileSync(configLocation);
|
||||||
|
var processArgv = process.argv.splice(2,process.argv.length)
|
||||||
|
var arguments = {};
|
||||||
|
processArgv.forEach(function(val) {
|
||||||
|
var theSplit = val.split('=');
|
||||||
|
var index = theSplit[0];
|
||||||
|
var value = theSplit[1];
|
||||||
|
if(value==='DELETE'){
|
||||||
|
delete(config[index])
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
config[index] = JSON.parse(value);
|
||||||
|
}catch(err){
|
||||||
|
config[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(index + ': ' + value);
|
||||||
|
});
|
||||||
|
|
||||||
|
jsonfile.writeFile(configLocation,config,{spaces: 2},function(){
|
||||||
|
console.log('Changes Complete. Here is what it is now.')
|
||||||
|
console.log(JSON.stringify(config,null,2))
|
||||||
|
})
|
|
@ -0,0 +1,84 @@
|
||||||
|
console.log('This translation tool uses Yandex.')
|
||||||
|
if(!process.argv[2]||!process.argv[3]||!process.argv[4]){
|
||||||
|
console.log('You must input arguments.')
|
||||||
|
console.log('# node translateLanguageFile.js <SOURCE> <FROM_LANGUAGE> <TO_LANGUAGE>')
|
||||||
|
console.log('Example:')
|
||||||
|
console.log('# node translateLanguageFile.js en_US en ar')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var langDir='../languages/'
|
||||||
|
var fs=require('fs');
|
||||||
|
var https = require('https');
|
||||||
|
var jsonfile=require('jsonfile');
|
||||||
|
var source=require(langDir+process.argv[2]+'.json')
|
||||||
|
var list = Object.keys(source)
|
||||||
|
console.log(list.length)
|
||||||
|
var extra = ''
|
||||||
|
var current = 1
|
||||||
|
var currentItem = list[0]
|
||||||
|
var chosenFile = langDir+process.argv[4]+'.json'
|
||||||
|
try{
|
||||||
|
newList=require(chosenFile)
|
||||||
|
}catch(err){
|
||||||
|
console.log(chosenFile)
|
||||||
|
var newList={}
|
||||||
|
}
|
||||||
|
var newListAlphabetical={}
|
||||||
|
var goNext=function(){
|
||||||
|
++current
|
||||||
|
currentItem = list[current]
|
||||||
|
if(list.length===current){
|
||||||
|
console.log('complete checking.. please wait')
|
||||||
|
Object.keys(newList).sort().forEach(function(y,t){
|
||||||
|
newListAlphabetical[y]=newList[y]
|
||||||
|
})
|
||||||
|
jsonfile.writeFile(chosenFile,newListAlphabetical,{spaces: 2},function(){
|
||||||
|
console.log('complete writing')
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
next(currentItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var next=function(v){
|
||||||
|
if(v===undefined){return false}
|
||||||
|
//trnsl.1.1.20170718T033617Z.a9bbd3b739ca59df.7f89b7474ec69812afd0014b5e338328ebf3fc39
|
||||||
|
if(newList[v]&&newList[v]!==source[v]){
|
||||||
|
goNext()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(/<[a-z][\s\S]*>/i.test(source[v])===true){
|
||||||
|
extra+='&format=html'
|
||||||
|
}
|
||||||
|
var url = 'https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20160311T042953Z.341f2f63f38bdac6.c7e5c01fff7f57160141021ca61b60e36ff4d379'+extra+'&lang='+process.argv[3]+'-'+process.argv[4]+'&text='+source[v]
|
||||||
|
https.request(url, function(data) {
|
||||||
|
data.setEncoding('utf8');
|
||||||
|
var chunks='';
|
||||||
|
data.on('data', (chunk) => {
|
||||||
|
chunks+=chunk;
|
||||||
|
});
|
||||||
|
data.on('end', () => {
|
||||||
|
try{
|
||||||
|
chunks=JSON.parse(chunks)
|
||||||
|
if(chunks.html){
|
||||||
|
if(chunks.html[0]){
|
||||||
|
var translation=chunks.html[0]
|
||||||
|
}else{
|
||||||
|
var translation=chunks.html
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
var translation=chunks.text[0]
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
var translation=source[v]
|
||||||
|
}
|
||||||
|
newList[v]=translation;
|
||||||
|
console.log(current+'/'+list.length+','+v+' ---> '+translation)
|
||||||
|
goNext()
|
||||||
|
});
|
||||||
|
}).on('error', function(e) {
|
||||||
|
console.log('ERROR : 500 '+v)
|
||||||
|
res.sendStatus(500);
|
||||||
|
}).end();
|
||||||
|
}
|
||||||
|
next(currentItem)
|
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,587 @@
|
||||||
|
/*!
|
||||||
|
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
||||||
|
* Copyright 2011-2016 Twitter, Inc.
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
*/
|
||||||
|
.btn-default,
|
||||||
|
.btn-primary,
|
||||||
|
.btn-success,
|
||||||
|
.btn-info,
|
||||||
|
.btn-warning,
|
||||||
|
.btn-danger {
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
|
||||||
|
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||||
|
}
|
||||||
|
.btn-default:active,
|
||||||
|
.btn-primary:active,
|
||||||
|
.btn-success:active,
|
||||||
|
.btn-info:active,
|
||||||
|
.btn-warning:active,
|
||||||
|
.btn-danger:active,
|
||||||
|
.btn-default.active,
|
||||||
|
.btn-primary.active,
|
||||||
|
.btn-success.active,
|
||||||
|
.btn-info.active,
|
||||||
|
.btn-warning.active,
|
||||||
|
.btn-danger.active {
|
||||||
|
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||||
|
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||||
|
}
|
||||||
|
.btn-default.disabled,
|
||||||
|
.btn-primary.disabled,
|
||||||
|
.btn-success.disabled,
|
||||||
|
.btn-info.disabled,
|
||||||
|
.btn-warning.disabled,
|
||||||
|
.btn-danger.disabled,
|
||||||
|
.btn-default[disabled],
|
||||||
|
.btn-primary[disabled],
|
||||||
|
.btn-success[disabled],
|
||||||
|
.btn-info[disabled],
|
||||||
|
.btn-warning[disabled],
|
||||||
|
.btn-danger[disabled],
|
||||||
|
fieldset[disabled] .btn-default,
|
||||||
|
fieldset[disabled] .btn-primary,
|
||||||
|
fieldset[disabled] .btn-success,
|
||||||
|
fieldset[disabled] .btn-info,
|
||||||
|
fieldset[disabled] .btn-warning,
|
||||||
|
fieldset[disabled] .btn-danger {
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.btn-default .badge,
|
||||||
|
.btn-primary .badge,
|
||||||
|
.btn-success .badge,
|
||||||
|
.btn-info .badge,
|
||||||
|
.btn-warning .badge,
|
||||||
|
.btn-danger .badge {
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
.btn:active,
|
||||||
|
.btn.active {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
.btn-default {
|
||||||
|
text-shadow: 0 1px 0 #fff;
|
||||||
|
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
|
||||||
|
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #dbdbdb;
|
||||||
|
border-color: #ccc;
|
||||||
|
}
|
||||||
|
.btn-default:hover,
|
||||||
|
.btn-default:focus {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
background-position: 0 -15px;
|
||||||
|
}
|
||||||
|
.btn-default:active,
|
||||||
|
.btn-default.active {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
border-color: #dbdbdb;
|
||||||
|
}
|
||||||
|
.btn-default.disabled,
|
||||||
|
.btn-default[disabled],
|
||||||
|
fieldset[disabled] .btn-default,
|
||||||
|
.btn-default.disabled:hover,
|
||||||
|
.btn-default[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-default:hover,
|
||||||
|
.btn-default.disabled:focus,
|
||||||
|
.btn-default[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-default:focus,
|
||||||
|
.btn-default.disabled.focus,
|
||||||
|
.btn-default[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-default.focus,
|
||||||
|
.btn-default.disabled:active,
|
||||||
|
.btn-default[disabled]:active,
|
||||||
|
fieldset[disabled] .btn-default:active,
|
||||||
|
.btn-default.disabled.active,
|
||||||
|
.btn-default[disabled].active,
|
||||||
|
fieldset[disabled] .btn-default.active {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
.btn-primary {
|
||||||
|
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
|
||||||
|
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #245580;
|
||||||
|
}
|
||||||
|
.btn-primary:hover,
|
||||||
|
.btn-primary:focus {
|
||||||
|
background-color: #265a88;
|
||||||
|
background-position: 0 -15px;
|
||||||
|
}
|
||||||
|
.btn-primary:active,
|
||||||
|
.btn-primary.active {
|
||||||
|
background-color: #265a88;
|
||||||
|
border-color: #245580;
|
||||||
|
}
|
||||||
|
.btn-primary.disabled,
|
||||||
|
.btn-primary[disabled],
|
||||||
|
fieldset[disabled] .btn-primary,
|
||||||
|
.btn-primary.disabled:hover,
|
||||||
|
.btn-primary[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-primary:hover,
|
||||||
|
.btn-primary.disabled:focus,
|
||||||
|
.btn-primary[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-primary:focus,
|
||||||
|
.btn-primary.disabled.focus,
|
||||||
|
.btn-primary[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-primary.focus,
|
||||||
|
.btn-primary.disabled:active,
|
||||||
|
.btn-primary[disabled]:active,
|
||||||
|
fieldset[disabled] .btn-primary:active,
|
||||||
|
.btn-primary.disabled.active,
|
||||||
|
.btn-primary[disabled].active,
|
||||||
|
fieldset[disabled] .btn-primary.active {
|
||||||
|
background-color: #265a88;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
.btn-success {
|
||||||
|
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
|
||||||
|
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #3e8f3e;
|
||||||
|
}
|
||||||
|
.btn-success:hover,
|
||||||
|
.btn-success:focus {
|
||||||
|
background-color: #419641;
|
||||||
|
background-position: 0 -15px;
|
||||||
|
}
|
||||||
|
.btn-success:active,
|
||||||
|
.btn-success.active {
|
||||||
|
background-color: #419641;
|
||||||
|
border-color: #3e8f3e;
|
||||||
|
}
|
||||||
|
.btn-success.disabled,
|
||||||
|
.btn-success[disabled],
|
||||||
|
fieldset[disabled] .btn-success,
|
||||||
|
.btn-success.disabled:hover,
|
||||||
|
.btn-success[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-success:hover,
|
||||||
|
.btn-success.disabled:focus,
|
||||||
|
.btn-success[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-success:focus,
|
||||||
|
.btn-success.disabled.focus,
|
||||||
|
.btn-success[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-success.focus,
|
||||||
|
.btn-success.disabled:active,
|
||||||
|
.btn-success[disabled]:active,
|
||||||
|
fieldset[disabled] .btn-success:active,
|
||||||
|
.btn-success.disabled.active,
|
||||||
|
.btn-success[disabled].active,
|
||||||
|
fieldset[disabled] .btn-success.active {
|
||||||
|
background-color: #419641;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
.btn-info {
|
||||||
|
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
|
||||||
|
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #28a4c9;
|
||||||
|
}
|
||||||
|
.btn-info:hover,
|
||||||
|
.btn-info:focus {
|
||||||
|
background-color: #2aabd2;
|
||||||
|
background-position: 0 -15px;
|
||||||
|
}
|
||||||
|
.btn-info:active,
|
||||||
|
.btn-info.active {
|
||||||
|
background-color: #2aabd2;
|
||||||
|
border-color: #28a4c9;
|
||||||
|
}
|
||||||
|
.btn-info.disabled,
|
||||||
|
.btn-info[disabled],
|
||||||
|
fieldset[disabled] .btn-info,
|
||||||
|
.btn-info.disabled:hover,
|
||||||
|
.btn-info[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-info:hover,
|
||||||
|
.btn-info.disabled:focus,
|
||||||
|
.btn-info[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-info:focus,
|
||||||
|
.btn-info.disabled.focus,
|
||||||
|
.btn-info[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-info.focus,
|
||||||
|
.btn-info.disabled:active,
|
||||||
|
.btn-info[disabled]:active,
|
||||||
|
fieldset[disabled] .btn-info:active,
|
||||||
|
.btn-info.disabled.active,
|
||||||
|
.btn-info[disabled].active,
|
||||||
|
fieldset[disabled] .btn-info.active {
|
||||||
|
background-color: #2aabd2;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
.btn-warning {
|
||||||
|
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
|
||||||
|
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #e38d13;
|
||||||
|
}
|
||||||
|
.btn-warning:hover,
|
||||||
|
.btn-warning:focus {
|
||||||
|
background-color: #eb9316;
|
||||||
|
background-position: 0 -15px;
|
||||||
|
}
|
||||||
|
.btn-warning:active,
|
||||||
|
.btn-warning.active {
|
||||||
|
background-color: #eb9316;
|
||||||
|
border-color: #e38d13;
|
||||||
|
}
|
||||||
|
.btn-warning.disabled,
|
||||||
|
.btn-warning[disabled],
|
||||||
|
fieldset[disabled] .btn-warning,
|
||||||
|
.btn-warning.disabled:hover,
|
||||||
|
.btn-warning[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-warning:hover,
|
||||||
|
.btn-warning.disabled:focus,
|
||||||
|
.btn-warning[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-warning:focus,
|
||||||
|
.btn-warning.disabled.focus,
|
||||||
|
.btn-warning[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-warning.focus,
|
||||||
|
.btn-warning.disabled:active,
|
||||||
|
.btn-warning[disabled]:active,
|
||||||
|
fieldset[disabled] .btn-warning:active,
|
||||||
|
.btn-warning.disabled.active,
|
||||||
|
.btn-warning[disabled].active,
|
||||||
|
fieldset[disabled] .btn-warning.active {
|
||||||
|
background-color: #eb9316;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
.btn-danger {
|
||||||
|
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
|
||||||
|
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #b92c28;
|
||||||
|
}
|
||||||
|
.btn-danger:hover,
|
||||||
|
.btn-danger:focus {
|
||||||
|
background-color: #c12e2a;
|
||||||
|
background-position: 0 -15px;
|
||||||
|
}
|
||||||
|
.btn-danger:active,
|
||||||
|
.btn-danger.active {
|
||||||
|
background-color: #c12e2a;
|
||||||
|
border-color: #b92c28;
|
||||||
|
}
|
||||||
|
.btn-danger.disabled,
|
||||||
|
.btn-danger[disabled],
|
||||||
|
fieldset[disabled] .btn-danger,
|
||||||
|
.btn-danger.disabled:hover,
|
||||||
|
.btn-danger[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-danger:hover,
|
||||||
|
.btn-danger.disabled:focus,
|
||||||
|
.btn-danger[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-danger:focus,
|
||||||
|
.btn-danger.disabled.focus,
|
||||||
|
.btn-danger[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-danger.focus,
|
||||||
|
.btn-danger.disabled:active,
|
||||||
|
.btn-danger[disabled]:active,
|
||||||
|
fieldset[disabled] .btn-danger:active,
|
||||||
|
.btn-danger.disabled.active,
|
||||||
|
.btn-danger[disabled].active,
|
||||||
|
fieldset[disabled] .btn-danger.active {
|
||||||
|
background-color: #c12e2a;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
.thumbnail,
|
||||||
|
.img-thumbnail {
|
||||||
|
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||||
|
}
|
||||||
|
.dropdown-menu > li > a:hover,
|
||||||
|
.dropdown-menu > li > a:focus {
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||||
|
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.dropdown-menu > .active > a,
|
||||||
|
.dropdown-menu > .active > a:hover,
|
||||||
|
.dropdown-menu > .active > a:focus {
|
||||||
|
background-color: #2e6da4;
|
||||||
|
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||||
|
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.navbar-default {
|
||||||
|
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
|
||||||
|
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||||
|
}
|
||||||
|
.navbar-default .navbar-nav > .open > a,
|
||||||
|
.navbar-default .navbar-nav > .active > a {
|
||||||
|
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
|
||||||
|
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||||
|
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||||
|
}
|
||||||
|
.navbar-brand,
|
||||||
|
.navbar-nav > li > a {
|
||||||
|
text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
|
||||||
|
}
|
||||||
|
.navbar-inverse {
|
||||||
|
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
|
||||||
|
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.navbar-inverse .navbar-nav > .open > a,
|
||||||
|
.navbar-inverse .navbar-nav > .active > a {
|
||||||
|
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
|
||||||
|
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||||
|
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||||
|
}
|
||||||
|
.navbar-inverse .navbar-brand,
|
||||||
|
.navbar-inverse .navbar-nav > li > a {
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
|
||||||
|
}
|
||||||
|
.navbar-static-top,
|
||||||
|
.navbar-fixed-top,
|
||||||
|
.navbar-fixed-bottom {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.navbar .navbar-nav .open .dropdown-menu > .active > a,
|
||||||
|
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||||
|
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||||
|
color: #fff;
|
||||||
|
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||||
|
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.alert {
|
||||||
|
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
|
||||||
|
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||||
|
}
|
||||||
|
.alert-success {
|
||||||
|
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
|
||||||
|
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #b2dba1;
|
||||||
|
}
|
||||||
|
.alert-info {
|
||||||
|
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
|
||||||
|
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #9acfea;
|
||||||
|
}
|
||||||
|
.alert-warning {
|
||||||
|
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
|
||||||
|
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #f5e79e;
|
||||||
|
}
|
||||||
|
.alert-danger {
|
||||||
|
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
|
||||||
|
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #dca7a7;
|
||||||
|
}
|
||||||
|
.progress {
|
||||||
|
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
|
||||||
|
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.progress-bar {
|
||||||
|
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
|
||||||
|
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.progress-bar-success {
|
||||||
|
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
|
||||||
|
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.progress-bar-info {
|
||||||
|
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
|
||||||
|
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.progress-bar-warning {
|
||||||
|
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
|
||||||
|
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.progress-bar-danger {
|
||||||
|
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
|
||||||
|
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.progress-bar-striped {
|
||||||
|
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||||
|
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||||
|
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||||
|
}
|
||||||
|
.list-group {
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||||
|
}
|
||||||
|
.list-group-item.active,
|
||||||
|
.list-group-item.active:hover,
|
||||||
|
.list-group-item.active:focus {
|
||||||
|
text-shadow: 0 -1px 0 #286090;
|
||||||
|
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
|
||||||
|
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #2b669a;
|
||||||
|
}
|
||||||
|
.list-group-item.active .badge,
|
||||||
|
.list-group-item.active:hover .badge,
|
||||||
|
.list-group-item.active:focus .badge {
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
.panel {
|
||||||
|
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||||
|
}
|
||||||
|
.panel-default > .panel-heading {
|
||||||
|
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||||
|
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.panel-primary > .panel-heading {
|
||||||
|
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||||
|
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.panel-success > .panel-heading {
|
||||||
|
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
|
||||||
|
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.panel-info > .panel-heading {
|
||||||
|
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
|
||||||
|
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.panel-warning > .panel-heading {
|
||||||
|
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
|
||||||
|
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.panel-danger > .panel-heading {
|
||||||
|
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
|
||||||
|
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
}
|
||||||
|
.well {
|
||||||
|
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
|
||||||
|
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #dcdcdc;
|
||||||
|
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||||
|
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||||
|
}
|
||||||
|
/*# sourceMappingURL=bootstrap-theme.css.map */
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue