Some Updates and Fixes
- Add Branding Engine - Lock PM2 install to 3.0.0 (newer versions cannot catch `uncaughtException`. - Update macOS installer - Update OpenALPR (CPU) installer - Add Portuguese Language - Fix Language Selector - Lay-In ability to create Matrix from Pam-Diff detection blob - createEventBasedRecording called for Traditional Recording labelled 5 seconds before real time to capture event - fix NaN for new user created in Superuser - count space used for Timelapse Frames and Files tables (does not purge Timelapse data yet) - Update TimelapseJpeg, lay-in MP4 builder, many fixes, additonal page - add `impervious` to gitignore in `web/libs` for custom static files - Fix delete button for quick video list - Fix Super form appearancemerge-requests/60/head
parent
9877ac480f
commit
89a70b6438
|
@ -113,7 +113,7 @@ sudo npm install --unsafe-perm
|
|||
sudo npm audit fix --force
|
||||
echo "============="
|
||||
echo "Shinobi - Install PM2"
|
||||
sudo npm install pm2 -g
|
||||
sudo npm install pm2@3.0.0 -g
|
||||
echo "Shinobi - Finished"
|
||||
sudo chmod -R 755 .
|
||||
touch INSTALL/installed.txt
|
||||
|
|
|
@ -3,12 +3,32 @@ echo "------------------------------------------"
|
|||
echo "-- Installing CUDA Toolkit and CUDA DNN --"
|
||||
echo "------------------------------------------"
|
||||
# Install CUDA Drivers and Toolkit
|
||||
wget https://cdn.shinobi.video/installers/cuda-repo-ubuntu1710_9.2.148-1_amd64.deb -O cuda.deb
|
||||
sudo dpkg -i cuda.deb
|
||||
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1710/x86_64/7fa2af80.pub
|
||||
echo "============="
|
||||
echo " Detecting Ubuntu Version"
|
||||
echo "============="
|
||||
getubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1)
|
||||
echo "============="
|
||||
echo " Ubuntu Version: $getubuntuversion"
|
||||
echo "============="
|
||||
if [ "$getubuntuversion" = "17" ] || [ "$getubuntuversion" > "17" ]; then
|
||||
wget https://cdn.shinobi.video/installers/cuda-repo-ubuntu1710_9.2.148-1_amd64.deb -O cuda.deb
|
||||
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1710/x86_64/7fa2af80.pub
|
||||
sudo dpkg -i cuda.deb
|
||||
fi
|
||||
if [ "$getubuntuversion" = "16" ]; then
|
||||
wget https://cdn.shinobi.video/installers/cuda-repo-ubuntu1604_9.2.148-1_amd64.deb -O cuda.deb
|
||||
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
|
||||
sudo dpkg -i cuda.deb
|
||||
fi
|
||||
sudo apt-get update -y
|
||||
sudo apt-get -o Dpkg::Options::="--force-overwrite" install cuda -y
|
||||
sudo apt-get -o Dpkg::Options::="--force-overwrite" install --fix-broken -y
|
||||
if [ "$getubuntuversion" = "17" ] || [ "$getubuntuversion" > "17" ]; then
|
||||
sudo apt-get -o Dpkg::Options::="--force-overwrite" install cuda -y --no-install-recommends
|
||||
sudo apt-get -o Dpkg::Options::="--force-overwrite" install --fix-broken -y
|
||||
fi
|
||||
if [ "$getubuntuversion" = "16" ]; then
|
||||
sudo apt-get install libcuda1-384 -y --no-install-recommends
|
||||
sudo apt-get install nvidia-cuda-toolkit -y
|
||||
fi
|
||||
# Install CUDA DNN
|
||||
wget https://cdn.shinobi.video/installers/libcudnn7_7.2.1.38-1+cuda9.2_amd64.deb -O cuda-dnn.deb
|
||||
sudo dpkg -i cuda-dnn.deb
|
||||
|
|
|
@ -46,7 +46,7 @@ npm install --unsafe-perm
|
|||
sudo npm audit fix --force
|
||||
echo "============="
|
||||
echo "Shinobi - Install PM2"
|
||||
npm install pm2 -g
|
||||
npm install pm2@3.0.0 -g
|
||||
if (! -e "./conf.json" ) then
|
||||
cp conf.sample.json conf.json
|
||||
endif
|
||||
|
|
|
@ -21,7 +21,7 @@ npm i npm -g
|
|||
#There are some errors in here that I don't want you to see. Redirecting to dev null :D
|
||||
npm install --unsafe-perm > & /dev/null
|
||||
npm audit fix --force > & /dev/null
|
||||
npm install pm2 -g
|
||||
npm install pm2@3.0.0 -g
|
||||
cp conf.sample.json conf.json
|
||||
cp super.sample.json super.json
|
||||
pm2 start camera.js
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
if [ -f /etc/os-release ]; then
|
||||
# freedesktop.org and systemd
|
||||
. /etc/os-release
|
||||
OS=$NAME
|
||||
VER=$VERSION_ID
|
||||
elif type lsb_release >/dev/null 2>&1; then
|
||||
# linuxbase.org
|
||||
OS=$(lsb_release -si)
|
||||
VER=$(lsb_release -sr)
|
||||
elif [ -f /etc/lsb-release ]; then
|
||||
# For some versions of Debian/Ubuntu without lsb_release command
|
||||
. /etc/lsb-release
|
||||
OS=$DISTRIB_ID
|
||||
VER=$DISTRIB_RELEASE
|
||||
elif [ -f /etc/debian_version ]; then
|
||||
# Older Debian/Ubuntu/etc.
|
||||
OS=Debian
|
||||
VER=$(cat /etc/debian_version)
|
||||
elif [ -f /etc/SuSe-release ]; then
|
||||
# Older SuSE/etc.
|
||||
...
|
||||
elif [ -f /etc/redhat-release ]; then
|
||||
# Older Red Hat, CentOS, etc.
|
||||
...
|
||||
else
|
||||
# Fall back to uname, e.g. "Linux <version>", also works for BSD, etc.
|
||||
OS=$(uname -s)
|
||||
VER=$(uname -r)
|
||||
fi
|
||||
echo $OS
|
|
@ -9,13 +9,8 @@ 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
|
||||
sudo mysql -e "source sql/user.sql" || true
|
||||
sudo mysql -e "source sql/framework.sql" || true
|
||||
fi
|
||||
echo "============="
|
||||
echo "Shinobi - Install NPM Libraries"
|
||||
|
@ -24,7 +19,7 @@ sudo npm install --unsafe-perm
|
|||
sudo npm audit fix --unsafe-perm
|
||||
echo "============="
|
||||
echo "Shinobi - Install PM2"
|
||||
sudo npm install pm2 -g
|
||||
sudo npm install pm2@3.0.0 -g
|
||||
if [ ! -e "./conf.json" ]; then
|
||||
sudo cp conf.sample.json conf.json
|
||||
fi
|
||||
|
@ -35,6 +30,8 @@ if [ ! -e "./super.json" ]; then
|
|||
fi
|
||||
echo "Shinobi - Finished"
|
||||
touch INSTALL/installed.txt
|
||||
dos2unix /home/Shinobi/INSTALL/shinobi
|
||||
ln -s /home/Shinobi/INSTALL/shinobi /usr/bin/shinobi
|
||||
sudo chmod -R 755 .
|
||||
echo "=====================================" > INSTALL/installed.txt
|
||||
echo "======= Login Credentials =======" >> INSTALL/installed.txt
|
||||
|
|
|
@ -24,27 +24,59 @@ if [ "$ffmpeginstall" = "y" ]; then
|
|||
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 mv ffmpeg-3.4.1-macos/ffmpeg /usr/local/bin/ffmpeg
|
||||
sudo mv ffmpeg-3.4.1-macos/ffplay /usr/local/bin/ffplay
|
||||
sudo mv ffmpeg-3.4.1-macos/ffprobe /usr/local/bin/ffprobe
|
||||
sudo mv ffmpeg-3.4.1-macos/ffserver /usr/local/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)
|
||||
if [ ! -e "./shinobi.sqlite" ]; then
|
||||
sudo npm install jsonfile
|
||||
sudo cp sql/shinobi.sample.sqlite shinobi.sqlite
|
||||
sudo node tools/modifyConfiguration.js databaseType=sqlite3
|
||||
fi
|
||||
echo "Shinobi - Install NPM Libraries"
|
||||
sudo npm i npm -g
|
||||
sudo npm install --unsafe-perm
|
||||
sudo npm audit fix --unsafe-perm
|
||||
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 "============="
|
||||
echo "Shinobi - Install PM2"
|
||||
sudo npm install pm2@3.0.0 -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"
|
||||
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
|
||||
pm2 start camera.js
|
||||
pm2 startup
|
||||
pm2 save
|
||||
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 "====================================="
|
||||
|
|
|
@ -9,6 +9,9 @@ if ! [ -x "$(command -v opencv_version)" ]; then
|
|||
else
|
||||
echo "OpenCV found... : $(opencv_version)"
|
||||
fi
|
||||
# get tesseract repo because ubuntu repo is serving a broken version
|
||||
sudo add-apt-repository ppa:alex-p/tesseract-ocr -y
|
||||
sudo apt-get update -y
|
||||
# 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
|
||||
|
|
|
@ -11,7 +11,7 @@ else
|
|||
fi
|
||||
# get tesseract repo because ubuntu repo is serving a broken version
|
||||
sudo add-apt-repository ppa:alex-p/tesseract-ocr -y
|
||||
sudo apt-get update
|
||||
sudo apt-get update -y
|
||||
# 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
|
||||
|
|
|
@ -109,7 +109,7 @@ npm install --unsafe-perm
|
|||
sudo npm audit fix --force
|
||||
echo "============="
|
||||
echo "Shinobi - Install PM2"
|
||||
sudo npm install pm2 -g
|
||||
sudo npm install pm2@3.0.0 -g
|
||||
echo "Shinobi - Finished"
|
||||
sudo chmod -R 755 .
|
||||
touch INSTALL/installed.txt
|
||||
|
|
|
@ -154,7 +154,7 @@ echo "============="
|
|||
|
||||
#Install PM2
|
||||
echo "Shinobi - Install PM2"
|
||||
sudo npm install pm2 -g
|
||||
sudo npm install pm2@3.0.0 -g
|
||||
if [ ! -e "./conf.json" ]; then
|
||||
cp conf.sample.json conf.json
|
||||
fi
|
||||
|
|
|
@ -18,6 +18,9 @@ if [ "$getubuntuversion" = "18" ] || [ "$getubuntuversion" > "18" ]; then
|
|||
sudo apt install -y software-properties-common
|
||||
sudo add-apt-repository universe -y
|
||||
fi
|
||||
if [ "$getubuntuversion" = "16" ]; then
|
||||
apt install gnupg-curl -y
|
||||
fi
|
||||
#create conf.json
|
||||
if [ ! -e "./conf.json" ]; then
|
||||
sudo cp conf.sample.json conf.json
|
||||
|
@ -121,7 +124,7 @@ sudo npm install --unsafe-perm
|
|||
sudo npm audit fix --force
|
||||
echo "============="
|
||||
echo "Shinobi - Install PM2"
|
||||
sudo npm install pm2 -g
|
||||
sudo npm install pm2@3.0.0 -g
|
||||
echo "Shinobi - Finished"
|
||||
sudo chmod -R 755 .
|
||||
touch INSTALL/installed.txt
|
||||
|
|
|
@ -73,6 +73,8 @@ loadLib('ffmpeg')(s,config,lang,function(ffmpeg){
|
|||
loadLib('dropInEvents')(s,config,lang,app,io)
|
||||
//form fields to drive the internals
|
||||
loadLib('definitions')(s,config,lang,app,io)
|
||||
//branding functions and config defaults
|
||||
loadLib('branding')(s,config,lang,app,io)
|
||||
//custom module loader
|
||||
loadLib('customAutoLoad')(s,config,lang,app,io)
|
||||
//scheduling engine
|
||||
|
|
|
@ -1481,7 +1481,7 @@ module.exports = function(s,config,lang){
|
|||
"name": "height",
|
||||
"field": lang["Record Height"],
|
||||
"description": "Height of the stream image.",
|
||||
"default": "480",
|
||||
"default": "",
|
||||
"example": "720",
|
||||
"form-group-class": "h_vc_input h_vc_libvpx h_vc_libvpx-vp9 h_vc_libx264 h_vc_libx265 h_vc_hevc_nvenc h_vc_h264_nvenc h_vc_h264_vaapi h_vc_hevc_vaapi h_vc_h264_qsv h_vc_hevc_qsv h_vc_mpeg2_qsv h_vc_default h_vc_none",
|
||||
"possible": ""
|
||||
|
@ -1490,7 +1490,7 @@ module.exports = function(s,config,lang){
|
|||
"name": "width",
|
||||
"field": lang["Record Width"],
|
||||
"description": "Width of the stream image.",
|
||||
"default": "640",
|
||||
"default": "",
|
||||
"example": "1280",
|
||||
"form-group-class": "h_vc_input h_vc_libvpx h_vc_libvpx-vp9 h_vc_libx264 h_vc_libx265 h_vc_hevc_nvenc h_vc_h264_nvenc h_vc_h264_vaapi h_vc_hevc_vaapi h_vc_h264_qsv h_vc_hevc_qsv h_vc_mpeg2_qsv h_vc_default h_vc_none",
|
||||
"possible": ""
|
||||
|
@ -1768,6 +1768,10 @@ module.exports = function(s,config,lang){
|
|||
"name": `5 ${lang.minutes}`,
|
||||
"value": "300"
|
||||
},
|
||||
{
|
||||
"name": `10 ${lang.minutes}`,
|
||||
"value": "600"
|
||||
},
|
||||
{
|
||||
"name": `15 ${lang.minutes}`,
|
||||
"value": "900"
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
"Zoom Out": "Zoom Out <small>URL Address</small>",
|
||||
"Enable Nightvision": "Enable Nightvision",
|
||||
"Disable Nightvision": "Disable Nightvision",
|
||||
"Date": "Date",
|
||||
"Current": "Current",
|
||||
"Monitors": "Monitors",
|
||||
"Video": "Video",
|
||||
|
@ -93,6 +94,8 @@
|
|||
"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.",
|
||||
"Building": "Building",
|
||||
"Started Building": "Started Building",
|
||||
"Add": "Add",
|
||||
"Save": "Save",
|
||||
"Close": "Close",
|
||||
|
@ -391,6 +394,7 @@
|
|||
"Logging": "Logging",
|
||||
"Timelapse": "Timelapse",
|
||||
"Nothing exists": "Nothing exists",
|
||||
"Already exists": "Already exists",
|
||||
"Creation Interval": "Creation Interval",
|
||||
"Plugin": "Plugin",
|
||||
"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.",
|
||||
|
|
|
@ -0,0 +1,909 @@
|
|||
{
|
||||
"\"No Motion\" Detector": "\"Sem movimento\" Detector",
|
||||
"# of Allow MJPEG Clients": "# para permitir clientes MJPEG <small>0 para infinito</small>",
|
||||
"180 Degrees": "180 Graus",
|
||||
"2-Factor Authentication": "Autenticação de 2 fatores",
|
||||
"90 Clockwise": "90 no sentido horário",
|
||||
"90 Clockwise and Vertical Flip": "90 no sentido horário e vertical",
|
||||
"90 Counter Clockwise and Vertical Flip (default)": "90 no sentido anti-horário e vertical (Padrão)",
|
||||
"AND": "E",
|
||||
"API": "API",
|
||||
"API Key": "Chave de API",
|
||||
"API Key Added": "Chave da API adicionada",
|
||||
"API Key Deleted": "Chave da API excluída",
|
||||
"API Keys": "Chaves da API",
|
||||
"APIKeyAddedText": "Você pode usar essa chave agora",
|
||||
"APIKeyDeletedText": "A chave foi excluída. Não funcionará mais.",
|
||||
"ASC": "ASC",
|
||||
"Accelerator": "Acelerador",
|
||||
"Account Info": "Informações da conta",
|
||||
"AccountEditText1": "Não foi possível editar. Atualize a página se o problema continuar",
|
||||
"Accounts": "Contas",
|
||||
"Action for Selected": "Ação para Selecionado",
|
||||
"Add": "Adicionar",
|
||||
"Add Channel": "Adicionar Canal",
|
||||
"Add Input Feed": "Adicionar Entrada De Alimentação",
|
||||
"Add Map": "Adicionar O Mapa",
|
||||
"Add Monitor": "Adicionar monitor",
|
||||
"Add New": "Adicionar novo",
|
||||
"Admin": "Admin",
|
||||
"Advanced": "Avançado",
|
||||
"Again": "De novo",
|
||||
"Age": "Idade",
|
||||
"Alert Sound": "Som De Alerta",
|
||||
"Alert Sound Delay": "Som De Alerta Para Atraso",
|
||||
"All Logs": "Todos logs",
|
||||
"All Monitors": "Todos Monitores",
|
||||
"All Monitors and Privileges": "Todos monitores e privilégios",
|
||||
"All Privileges": "Todos Privilégios",
|
||||
"All Warnings": "Todos avisos",
|
||||
"All streams in first feed": "Todos os fluxos no primeiro feed",
|
||||
"Allow Next Command": "Habilitar próximo comando <small>em minutos</small>",
|
||||
"Allow Next Discord Alert": "Permitir Junto a Discórdia Alerta <small>em Minutos</small>",
|
||||
"Allow Next Email": "Permitir próximo e-mail <small>em minutos</small>",
|
||||
"Allow Next Trigger": "Habilitar próxima ação <small>em milissegundos</small>",
|
||||
"Allowed IPs": "IPs Permitidos",
|
||||
"Amazon S3": "O Amazon S3",
|
||||
"Amazon S3 Upload Error": "O Amazon S3 Erro De Upload",
|
||||
"Analyzation Duration": "Duração da análise",
|
||||
"Archive": "Arquivar",
|
||||
"Are you sure?": "Tem a certeza?",
|
||||
"Attach Video Clip": "Anexar Vídeo Clip",
|
||||
"Audio": "Áudio",
|
||||
"Audio Bit Rate": "Taxa De Bits De Áudio",
|
||||
"Audio Codec": "Codec De Áudio",
|
||||
"Audio Detection": "Detecção De Áudio",
|
||||
"Audio Detector": "Detector De Áudio",
|
||||
"Audio stream only from first feed": "Fluxo de áudio somente a partir de primeiro de alimentação",
|
||||
"Audio streams only": "Fluxos de áudio apenas",
|
||||
"Authenticate": "Autenticar",
|
||||
"Authentication Failed": "Autenticação falhou",
|
||||
"Auto": "Auto",
|
||||
"Automatic": "Automática",
|
||||
"Autosave": "Auto salvar",
|
||||
"Backblaze B2": "Backblaze B2",
|
||||
"Backblaze Error": "Backblaze Erro",
|
||||
"Base64 over Websocket": "Base64 sobre Websocket",
|
||||
"Basic Authentication": "Autenticação básica",
|
||||
"Batch": "Lote",
|
||||
"Bind Credentials": "Vincular Credenciais (Senha)",
|
||||
"Blank for No Change": "Em branco para Não Alterar",
|
||||
"Bottom Left": "Inferior esquerdo",
|
||||
"Bottom Right": "Inferior direito",
|
||||
"Browser Console Log": "Navegador de logs",
|
||||
"Bucket": "Balde",
|
||||
"Buffer Preview": "Buffer De Pré-Visualização",
|
||||
"CPU": "CPU",
|
||||
"CPU indicator will not work. Continuing...": "Indicador de CPU não irá funcionar. Continuando...",
|
||||
"CPU used by this stream": "CPU usada por este fluxo",
|
||||
"CSS": "CSS <small>Personalize seu painel de controle.</small>",
|
||||
"Calendar": "Calendário",
|
||||
"Call Method": "Método De Chamada",
|
||||
"Camera Password": "Senha da câmera",
|
||||
"Camera Username": "Usuário da câmera",
|
||||
"Camera is not recording": "Câmera não está gravando",
|
||||
"Camera is not running": "A câmera não está em execução",
|
||||
"Camera is not streaming": "Câmera não está transmitindo",
|
||||
"CameraNotRecordingText": "As configurações podem ser incompatíveis. Verifique os encoders. Reiniciando...",
|
||||
"Can Authenticate Websocket": "Pode Autenticar Websocket",
|
||||
"Can Change User Settings": "Pode Alterar As Definições De Utilizador",
|
||||
"Can Control Monitors": "Pode Controlar Monitores",
|
||||
"Can Create and Delete Monitors": "Pode Criar e Excluir Monitores",
|
||||
"Can Delete Videos": "Pode Deletar Vídeos",
|
||||
"Can Delete Videos and Events": "Pode Deletar Vídeos e Eventos",
|
||||
"Can Edit Monitor": "Pode Editar Monitores",
|
||||
"Can Get Logs": "Pode Obter Logs",
|
||||
"Can Get Monitors": "Pode Obter Monitores",
|
||||
"Can View Logs": "Pode Ver Os Logs",
|
||||
"Can View Monitor": "Pode Visualizar Monitores",
|
||||
"Can View Snapshots": "Pode Visualizar Snapshots",
|
||||
"Can View Streams": "Pode Visualizar Transmissões",
|
||||
"Can View Videos": "Pode Visualizar Vídeos",
|
||||
"Can View Videos and Events": "Pode Visualizar Vídeos e Eventos",
|
||||
"Can edit Max Days": "Pode editar Máximo de Dias",
|
||||
"Can edit Max Storage": "Pode editar Armazenamento Máximo",
|
||||
"Can edit how long to keep Events": "Pode editar quanto tempo manter eventos",
|
||||
"Can edit how long to keep Logs": "Pode editar por quanto tempo maneter logs",
|
||||
"Can use Admin Panel": "Pode usar Painel Administrativo",
|
||||
"Can use Amazon S3": "Pode usar o Amazon S3",
|
||||
"Can use Discord Bot": "Pode usar a Discórdia Bot",
|
||||
"Can use LDAP": "Pode usar LDAP",
|
||||
"Can use SFTP": "Pode usar SFTP",
|
||||
"Can use Wasabi Hot Cloud Storage": "Pode usar Wasabi Quente de Armazenamento em Nuvem",
|
||||
"Can use WebDAV": "Pode usar WebDAV",
|
||||
"Can't Connect": "Não pode conectar",
|
||||
"Cannot watch a monitor that isn't running.": "Não pode assistir um monitor que não está rodando.",
|
||||
"Cards": "Cartões",
|
||||
"Center": "Centro <small>URL Address</small>",
|
||||
"Channel": "Canal",
|
||||
"Channel ID": "ID do canal",
|
||||
"Chat on Discord": "Conversar no Discord",
|
||||
"Check": "Verificar",
|
||||
"Check Signal Interval": "Verifique o intervalo do sinal <small>em minutos</small>",
|
||||
"Check for Motion First": "Verifique primeiro o movimento",
|
||||
"Clear Recorder Process": "Claro Gravador De Processo",
|
||||
"Close": "Fechar",
|
||||
"Closed": "Fechado",
|
||||
"Color Threshold": "Limiar De Cores",
|
||||
"Command": "Comando",
|
||||
"Command on Trigger": "Comando quando acionado",
|
||||
"Complete Stream URL": "URL de transmissão completa",
|
||||
"Confidence": "Confiança",
|
||||
"Confidence of Detection": "A confiança de Detecção de",
|
||||
"Configuration": "Configuração",
|
||||
"Confirm": "Confirmar",
|
||||
"Connected": "Conectado",
|
||||
"Connection": "Conexão",
|
||||
"Connection Type": "Tipo de conexão",
|
||||
"Connection timed out": "Conexão esgotado",
|
||||
"Contains": "Contém",
|
||||
"Control": "Controle",
|
||||
"Control Error": "Erro de controle",
|
||||
"ControlErrorText1": "Controle não está ativado",
|
||||
"ControlErrorText2": "Verifique sua conexão detalhes. Você pode precisar ponto a URL Base em port 8000 ou 80. Verifique a sua informação de autenticação.",
|
||||
"Controllable": "Controlável",
|
||||
"Copy Connection Settings": "Copiar Configurações De Conexão",
|
||||
"Copy Custom Settings": "Copiar Configurações Personalizadas",
|
||||
"Copy Detector Settings": "Copiar As Configurações Do Detector",
|
||||
"Copy Group Settings": "Copiar Configurações Do Grupo",
|
||||
"Copy Input Settings": "Copiar As Configurações De Entrada De",
|
||||
"Copy JPEG API Settings": "Cópia JPEG API de Configurações",
|
||||
"Copy Logging Settings": "Copiar As Configurações De Log",
|
||||
"Copy Mode": "Modo De Cópia",
|
||||
"Copy Recording Settings": "Copiar Configurações De Gravação",
|
||||
"Copy Settings": "Configurações De Cópia",
|
||||
"Copy Stream Channel Settings": "Copiar Configurações De Canal Stream",
|
||||
"Copy Stream Settings": "Copiar Definições Da Sequência",
|
||||
"Copy to Settings": "Copiar Configurações",
|
||||
"Could not create Bucket.": "Não foi possível criar o Balde.",
|
||||
"Country of Plates": "País das placas",
|
||||
"Counts of Motion": "Contagem de movimento",
|
||||
"Create Sub-Accounts at /admin": "Criação de Sub-Contas em /admin",
|
||||
"Creating New Account": "Criando Nova Conta",
|
||||
"Creation Interval": "Intervalo De Criação De",
|
||||
"Current": "Atual",
|
||||
"Currently viewing": "Visualizando atualmente",
|
||||
"Custom": "Customizado",
|
||||
"Custom Base URL": "URL Customizada <small>Deixe em branco para usar URL do Host</small>",
|
||||
"Custom Endpoint": "Ponto Final Personalizado",
|
||||
"DB Lost.. Retrying..": "Banco de dados perdido... Repetindo...",
|
||||
"DESC": "DESC",
|
||||
"Dashboard": "Painel de Controle",
|
||||
"Dashboard Language": "Idioma do Painel de Controle",
|
||||
"Dashcam": "Dashcam",
|
||||
"Dashcam (Streamer v2)": "Dashcam (Streamer v2)",
|
||||
"Database": "Banco de dados",
|
||||
"Database Not Found": "Banco De Dados Não Encontrado",
|
||||
"Database row does not exist": "Linha de base de dados não existe",
|
||||
"Date Range": "Intervalo de Data",
|
||||
"Debug": "Debugar",
|
||||
"Default": "Padrão",
|
||||
"Delete": "Deletar",
|
||||
"Delete Filter": "Excluir filtro",
|
||||
"Delete Matches": "Deletar Combinações",
|
||||
"Delete Monitor": "Deletar Monitor",
|
||||
"Delete Monitor State?": "Apagar O Monitor De Estado",
|
||||
"Delete Monitor States Preset": "Apagar O Monitor De Estados Predefinidos",
|
||||
"Delete Motionless Video": "Deletar vídeos sem movimento",
|
||||
"Delete Motionless Videos (Record)": "Eliminar vídeos sem movimento (Gravação)",
|
||||
"Delete Selected Videos": "Excluir vídeos selecionados",
|
||||
"Delete Video": "Deletar Vídeo",
|
||||
"Delete selected": "Deletar Selecionado",
|
||||
"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.",
|
||||
"DeleteMonitorsText": "Você deseja excluir esses monitores? Você não pode recuperá-los. Você pode optar por manter os arquivos para essas Identificações no sistema de arquivos. Se você escolher para recriar um monitor com uma das Identificações vídeos e eventos tornam-se visíveis no painel de controle.",
|
||||
"DeleteSelectedVideosMsg": "Deseja excluir esses vídeos? Você não poderá recuperá-los.",
|
||||
"DeleteVideoMsg": "Deseja excluir este vídeo? Você não poderá recuperá-lo.",
|
||||
"Deleted": "Deletado",
|
||||
"Deleted Schedule Configuration": "Excluído Agenda De Configuração",
|
||||
"Deleted State Configuration": "Excluído O Estado De Configuração",
|
||||
"Detect Objects": "Detectar objetos <small class=\"\">Veja abaixo</small>",
|
||||
"Detection Engine": "O Motor De Detecção De",
|
||||
"Detector": "Detector de",
|
||||
"Detector Buffer": "Detector De Buffer",
|
||||
"Detector Filters": "Detector De Filtros",
|
||||
"Detector Flags": "Detector de Flags",
|
||||
"Detector Grouping": "Detector de Agrupamento <small>Adicionar grupos de <b>Configurações</b></small>",
|
||||
"Detector Rate": "Taxa do detector <small>(FPS)</small>",
|
||||
"Detector Recording Complete": "Detector De Gravação Completo",
|
||||
"Detector Recording Process Exited Prematurely. Restarting.": "Detector Processo De Gravação Foi Encerrado Prematuramente. Reiniciar.",
|
||||
"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>",
|
||||
"Died": "Morreu",
|
||||
"Digest Authentication": "A Autenticação Digest",
|
||||
"Disable Night Vision": "Desativar visão noturna <small>URL Address</small>",
|
||||
"Disable Nightvision": "Desativar Visão Noturna",
|
||||
"Disabled": "Desabilitado",
|
||||
"Discord": "Discórdia",
|
||||
"Discord Alert on Trigger": "A discórdia Alerta no Gatilho",
|
||||
"Discord Bot": "A Discórdia Bot",
|
||||
"DiscordErrorText": "Enviar a Discórdia causou um Erro",
|
||||
"DiscordFailedText": "Enviar a Discórdia Falha",
|
||||
"DiscordLoggedIn": "A Discórdia Bot Autenticado",
|
||||
"DiscordNotEnabledText": "A discórdia Bot Não Habilitada, Habilite-o em suas Configurações de Conta.",
|
||||
"Documentation": "Documentação",
|
||||
"Does Not Contain": "Não Contém",
|
||||
"Don't show this anymore": "Não mostre isso mais",
|
||||
"Double Quote Directory": "Diretório com aspas duplas <small>Alguns diretórios têm espaços. Usar isso pode bloquear algumas câmeras.</small>",
|
||||
"Down": "Baixo <small>URL Address</small>",
|
||||
"Down Stop": "Baixo máximo <small>URL Address</small>",
|
||||
"Download": "Baixar",
|
||||
"EU": "UE",
|
||||
"Edit": "Editar",
|
||||
"Edit Selected": "Edit Selected",
|
||||
"Edited Schedule Configuration": "Editado Agenda De Configuração",
|
||||
"Edited State Configuration": "Editado Estado De Configuração",
|
||||
"Email": "E-mail",
|
||||
"Email Details": "Detalhes do E-mail",
|
||||
"Email address is in use.": "Endereço de e-mail está em uso.",
|
||||
"Email and Password fields cannot be empty": "E-mail e campos de palavra-Passe não pode ser vazio",
|
||||
"Email on No Motion": "E-mail em \"Sem movimento\"",
|
||||
"Email on Trigger": "E-mail quando acionado <small>Emails vão para o endereço de login do titular da conta principal.</small>",
|
||||
"Emotion": "Emoção",
|
||||
"Emotion Average": "Emoção Média",
|
||||
"Enable": "Habilitar",
|
||||
"Enable Night Vision": "Ativar visão noturna <small>URL Address</small>",
|
||||
"Enable Nightvision": "Ativar Visão Noturna",
|
||||
"Enabled": "Habilitado",
|
||||
"End": "Finalizar",
|
||||
"End Time": "Hora de Término",
|
||||
"Ended": "Finalizado",
|
||||
"Endpoint": "Ponto final",
|
||||
"Endpoint Address": "Endereço De Ponto De Extremidade",
|
||||
"Enlarge": "Prolongar",
|
||||
"Enter this code to proceed": "Informe este código para prosseguir",
|
||||
"Equal to": "Igual a",
|
||||
"Error Connecting": "Erro ao conectar",
|
||||
"Error While Decoding": "Erro Durante A Decodificação",
|
||||
"ErrorWhileDecodingText": "Seu hardware pode ter uma conexão instável para a rede. Verifique suas conexões de rede.",
|
||||
"Event": "Evento",
|
||||
"Event Limit": "Limite de Evento",
|
||||
"Event Webhook Error": "Evento Webhook Erro",
|
||||
"EventText1": "Disparou um evento de movimento",
|
||||
"EventText2": "Não foi possível enviar imagem de e-mail, o arquivo não foi acessado",
|
||||
"Events": "Eventos",
|
||||
"Example": "Exemplo",
|
||||
"Execute Command": "Executar Comando",
|
||||
"Executed": "Executado",
|
||||
"Export": "Exportar",
|
||||
"Export Selected Videos": "Exportar Vídeos Selecionados",
|
||||
"Export Video": "Exportação De Vídeo",
|
||||
"ExportSelectedVideosMsg": "Você deseja exportar esses vídeos? Pode levar algum tempo para zip e fazer o download.",
|
||||
"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.",
|
||||
"FFmpegTip": "FFprobe é um simples fluxos multimídia analyzer. Você pode usá-lo para a saída de todos os tipos de informações sobre uma entrada, incluindo duração, taxa de quadros, tamanho do quadro, etc.",
|
||||
"FFprobe": "Sonda",
|
||||
"FLV": "FLV",
|
||||
"FLV Stream Type": "FLV Tipo de Fluxo",
|
||||
"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",
|
||||
"Fatal": "Fatal",
|
||||
"Fatal Maximum Reached": "Máximo atingido, parando câmera.",
|
||||
"FatalMaximumReachedText": "Erro JPEG fatal.",
|
||||
"Feed-in Image Height": "Altura da imagem de entrada",
|
||||
"Feed-in Image Width": "Largura da imagem de entrada",
|
||||
"Female": "Feminino",
|
||||
"Fields cannot be empty": "Campos não podem estar vazios",
|
||||
"File Delete Error": "Excluir O Arquivo De Erro",
|
||||
"File Not Exist": "Arquivo inexistente",
|
||||
"File Not Found": "Arquivo não encontrado",
|
||||
"File Not Found in Database": "Arquivo Não Encontrado no Banco de dados",
|
||||
"File Not Found in Filesystem": "Arquivo Não Encontrado no sistema de arquivos",
|
||||
"File Type": "Tipo de Arquivo",
|
||||
"FileNotExistText": "Não é possível salvar o arquivo inexistente. Algo deu errado.",
|
||||
"Filename": "Nome do Arquivo",
|
||||
"Filesize": "Tamanho do Arquivo",
|
||||
"Filter ID": "Filtrar ID",
|
||||
"Filter Matches": "Combinações de filtro",
|
||||
"Filter Name": "Filtrar Nome",
|
||||
"Filter for Objects only": "Filtro para que somente os Objetos",
|
||||
"FilterMatchesText1": "Este filtro atingiu as condições.",
|
||||
"FilterMatchesText2": "vídeos encontrados.",
|
||||
"Filters": "Filtros",
|
||||
"Filters Updated": "Filtros atualizados",
|
||||
"FiltersUpdatedText": "Suas alterações foram salvas e aplicadas.",
|
||||
"Find Where": "Encontrar Onde",
|
||||
"First stream in feed": "Primeiro fluxo de alimentação",
|
||||
"Fix": "Corrigir",
|
||||
"Fix Video": "Corrigir Vídeo",
|
||||
"FixVideoMsg": "Você deseja corrigir esse vídeo? Você não poderá desfazer essa ação..",
|
||||
"Flush PM2 Logs": "Flush Logs de PM2",
|
||||
"Font Path": "Caminho da fonte",
|
||||
"Font Size": "Tamanho da fonte",
|
||||
"For Group": "Para grupo",
|
||||
"Force Monitors Per Row": "Força De Monitores Por Linha",
|
||||
"Force Port": "Forçar porta",
|
||||
"Form Data Not Found": "Formulário De Dados Não Encontrado",
|
||||
"Found Devices": "Dispositivos encontrados",
|
||||
"Frame Rate": "Taxa de quadros <small>(FPS)</small>",
|
||||
"Full Frame Detection": "Detecção de quadro completo",
|
||||
"Full Stream URL": "Total URL de Fluxo",
|
||||
"Full URL Path": "Caminho completo da URL",
|
||||
"Fullscreen": "Tela cheia",
|
||||
"Gender": "Sexo",
|
||||
"Generate Subtitles": "Gerar legendas",
|
||||
"Get Logs to Client": "Obter Logs do Cliente",
|
||||
"Global Detector Settings": "Global As Configurações Do Detector",
|
||||
"Greater Than": "Maior que",
|
||||
"Greater Than or Equal to": "Maior ou Igual a",
|
||||
"Group Key": "Chave do Grupo",
|
||||
"Group Key is in use.": "Chave de grupo está em uso.",
|
||||
"Group Name": "Nome do grupo",
|
||||
"Grouping": "Agrupando <small>Adicione grupos em <b>Configurações</b></small>",
|
||||
"H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ",
|
||||
"HEVC (H.265)": "HEVC (H. 265)",
|
||||
"HLS (.m3u8)": "HLS (.m3u8)",
|
||||
"HLS (includes Audio)": "HLS (inclui áudio)",
|
||||
"HLS Audio Encoder": "Codificador de áudio HLS",
|
||||
"HLS List Size": "Tamanho da lista HLS",
|
||||
"HLS Live Start Index": "HLS ao Vivo Índice de Início",
|
||||
"HLS Preset": "Pré-definição HLS",
|
||||
"HLS Segment Length": "Comprimento do segmento HLS <small>em segundos</small>",
|
||||
"HLS Start Number": "HLS Número de Início",
|
||||
"HLS Video Encoder": "Codificador de vídeo HLS",
|
||||
"HTTP": "HTTP",
|
||||
"HTTPS": "HTTPS",
|
||||
"Hardware Accelerated": "Aceleração De Hardware",
|
||||
"Height": "Altura",
|
||||
"Help": "Ajuda",
|
||||
"Hide List": "Esconder Lista",
|
||||
"Hide Notes": "Esconder Notas",
|
||||
"Host": "Host",
|
||||
"Host Type": "Tipo De Host",
|
||||
"Hotswap Modes (Watch-Only)": "Hotswap Modes (Visualizar Apenas)",
|
||||
"How to Record": "Como gravar",
|
||||
"IP Address": "Endereço IP",
|
||||
"Identity": "Identidade",
|
||||
"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.",
|
||||
"Idle": "Inativo",
|
||||
"Image Height": "Altura da imagem",
|
||||
"Image Location": "Localização da imagem <small>Caminho Absoluto ou deixar em branco para usar global</small>",
|
||||
"Image Position": "Posição da imagem",
|
||||
"Image Width": "Largura da imagem",
|
||||
"Import": "Importar",
|
||||
"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>.",
|
||||
"ImportMultiMonitorConfigurationText": "Fazendo isso vai overrwrite qualquer monitores com IDs existentes no arquivo de importação.",
|
||||
"In": "Em",
|
||||
"Incorrect Settings Chosen": "Configuração incorreta escolhida",
|
||||
"Indifference": "Indiferença",
|
||||
"Input": "Entrada",
|
||||
"Input Feed": "Entrada De Alimentação",
|
||||
"Input Flags": "Flags de entrada",
|
||||
"Input Selector": "Selector De Entrada",
|
||||
"Input Settings": "Configurações De Entrada De",
|
||||
"Input Type": "Tipo de entrada",
|
||||
"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.",
|
||||
"Inserted Schedule Configuration": "Inserido Agenda De Configuração",
|
||||
"Inserted State Configuration": "Inserido Estado De Configuração",
|
||||
"Invalid Data": "Dados Inválidos",
|
||||
"Invalid JSON": "JSON inválido",
|
||||
"InvalidJSONText": "Certifique-se de que esta seja uma string JSON válida para a configuração do monitor Shinobi.",
|
||||
"JPEG": "JPEG",
|
||||
"JPEG (Auto Enables JPEG API)": "JPEG (Auto habilitado JPEG API)",
|
||||
"JPEG API": "JPEG API <small>Snapshot (cgi-bin)</small>",
|
||||
"JPEG Error": "Erro JPEG",
|
||||
"JPEG Mode": "Modo JPEG",
|
||||
"JPEGErrorText": "Houve um problema ao obter dados da sua câmera.",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP Success": "LDAP Sucesso",
|
||||
"LDAP User Authenticated": "Usuário LDAP Usuário Autenticado",
|
||||
"LDAP User is New": "Usuário LDAP é Novo",
|
||||
"Launch in New Window": "O lançamento na Nova Janela",
|
||||
"Leave blank for random.": "Deixe em branco para aleatório.",
|
||||
"Leave blank for unlimited": "Deixe em branco para ilimitado",
|
||||
"Left": "Esquerda <small>URL Address</small>",
|
||||
"Left Stop": "Esquerda máxima <small>URL Address</small>",
|
||||
"Less Than": "Menor que",
|
||||
"Less Than or Equal to": "Menor ou Igual a",
|
||||
"License Plate Detector": "Placa De Licença Detector De",
|
||||
"Like": "Como",
|
||||
"Limited": "Limitado",
|
||||
"Link Shinobi": "Link Shinobi",
|
||||
"Lisence Plate Detector": "Detector de placas",
|
||||
"List Toggle": "Mostrar lista",
|
||||
"List of Videos Delete Error": "Lista de Vídeos Apagar Erro",
|
||||
"Live Stream Toggle": "Mostrar transmissão ao vivo",
|
||||
"Live View": "Visualização ao vivo",
|
||||
"Local": "Local",
|
||||
"Log Level": "Nível de registro",
|
||||
"Log Signal Event": "Evento de sinal de registro <small>Apenas cliente</small>",
|
||||
"Log Stream": "Fluxo De Log",
|
||||
"Logging": "Registo",
|
||||
"Login": "Entrar",
|
||||
"Logout": "Sair",
|
||||
"Logs": "Logs",
|
||||
"Loop Stream": "Loop Stream",
|
||||
"MB": "MB",
|
||||
"MJPEG": "MJPEG",
|
||||
"MP4 (copy, libx264, libx265)": "MP4 (copiar, libx264, libx265)",
|
||||
"MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)",
|
||||
"MPEG-DASH (includes Audio)": "MPEG-DASH (inclui Áudio)",
|
||||
"MailError": "MAIL ERROR : Não foi possível enviar e-mail, verifique conf.json. Ignorando qualquer recurso que dependa do envio",
|
||||
"Main": "Principal",
|
||||
"Male": "Masculino",
|
||||
"Manual": "Manual",
|
||||
"Map": "Mapa",
|
||||
"Matches": "Combina",
|
||||
"Max Indifference": "Max Indiferença",
|
||||
"Max Latency": "Max Latência",
|
||||
"Max Number of Cameras": "Número máximo de câmeras",
|
||||
"Max Storage Amount": "Montante máximo de armazenamento <small>em Megabytes</small>",
|
||||
"Maximum dB": "Máximo dB",
|
||||
"Merge Selected Videos": "Mesclar Vídeos Selecionados",
|
||||
"Merge Video": "Vídeo De Impressão",
|
||||
"Merge and Download": "De mala e fazer o Download",
|
||||
"MergeSelectedVideosMsg": "Você deseja mesclar esses vídeos? Pode levar algum tempo para mesclar e fazer o download. O momento em que a conexão é fechada, o arquivo será excluído. Certifique-se de manter o navegador aberto até que seja concluída.",
|
||||
"Migrator": "Migrator",
|
||||
"Minimum dB": "Mínimo dB",
|
||||
"Mode": "Modo",
|
||||
"Monitor": "Monitor",
|
||||
"Monitor Added by user": "Monitor adicionado pelo usuário",
|
||||
"Monitor Capture Rate": "Taxa de captura do monitor <small>(FPS)</small>",
|
||||
"Monitor Groups": "Grupos de monitores",
|
||||
"Monitor ID": "ID do Monitor",
|
||||
"Monitor Idling": "Monitor ocioso",
|
||||
"Monitor Name": "Nome do monitor",
|
||||
"Monitor Settings": "Configurações do monitor",
|
||||
"Monitor States": "Monitor De Estados",
|
||||
"Monitor States and Schedules": "Monitor de Estados e Horários",
|
||||
"Monitor Stopped": "Monitor parado",
|
||||
"Monitor Updated by user": "Monitor atualizado pelo usuário",
|
||||
"Monitor is now Disabled": "O Monitor é Desativado",
|
||||
"Monitor is now Idle": "O Monitor está agora Inactiva",
|
||||
"Monitor is now Recording": "O Monitor é agora de Gravação",
|
||||
"Monitor is now Watching": "O Monitor está agora Assistindo",
|
||||
"Monitor mode changed": "Modo de monitor mudou",
|
||||
"Monitor mode is already": "Modo de monitor já está em uso",
|
||||
"Monitor or Key does not exist.": "Monitor ou chave não existe",
|
||||
"MonitorIdlingText": "A sessão do monitor foi ordenada para ocioso.",
|
||||
"MonitorStoppedText": "A sessão do monitor foi ordenada a parar.",
|
||||
"Monitors": "Monitores",
|
||||
"Monitors per row": "Monitores por linha <small>para montagem</small>",
|
||||
"Monitors to Copy to": "Monitores para Copiar para",
|
||||
"Montage": "Montagem",
|
||||
"Motion": "Movimento",
|
||||
"Motion Detection": "Detecção De Movimento",
|
||||
"Motion GUI": "GUI de Movimento",
|
||||
"Motion Meter": "Medidos de Movimento",
|
||||
"Mp4Frag": "Mp4Frag",
|
||||
"Must be atleast one row": "Deve ser pelo menos uma linha",
|
||||
"Mute Audio": "Silenciar Áudio",
|
||||
"NVIDIA": "NVIDIA",
|
||||
"Name": "Nome",
|
||||
"Name cannot be empty.": "O nome não pode estar vazia.",
|
||||
"New Authentication Token": "Novo token de autenticação",
|
||||
"New Monitor": "Novo Monitor",
|
||||
"No": "Não",
|
||||
"No Audio": "Sem áudio",
|
||||
"No Data": "Sem Dados",
|
||||
"No Events found for this video": "Nenhum evento encontrado para este vídeo",
|
||||
"No Group with this key exists": "Nenhum grupo com esta chave foi encontrado",
|
||||
"No Monitor Exists with this ID.": "Não existem monitores com esse ID.",
|
||||
"No Monitor Found, Ignoring Request": "Monitor não encontrado, ignorando requisição",
|
||||
"No Monitor ID Present in Form": "Nenhum ID do Monitor Presente no Formulário",
|
||||
"No Monitors Selected": "Não Há Monitores Selecionados",
|
||||
"No Rotation": "Sem rotação",
|
||||
"No Videos Found": "Nenhum Vídeo Encontrado",
|
||||
"No such file": "Arquivo inexistente",
|
||||
"NoLogsFoundForDateRange": "Sem Registos encontrados neste intervalo de data. Tente alargar o intervalo de data.",
|
||||
"NoMotionEmailText1": "Nenhum movimento para",
|
||||
"NoMotionEmailText2": "Não houve nenhum movimento detectado na câmera para",
|
||||
"NoVideosFoundForDateRange": "Nenhum vídeo encontrado neste intervalo de datas. Tente definir a data de início mais adiante.",
|
||||
"Noise Filter": "Filtro De Ruído",
|
||||
"Noise Filter Range": "Filtro De Ruído Faixa De",
|
||||
"Not Authorized": "Não autorizados",
|
||||
"Not Connected": "Não conectado",
|
||||
"Not Equal to": "Não Igual a",
|
||||
"Not In": "Não Em",
|
||||
"Not Matches": "Não Combina",
|
||||
"Not Permitted": "Não permitidos",
|
||||
"Not Saved": "Não Salvo",
|
||||
"Not an Administrator Account": "Não é uma conta de Administrador",
|
||||
"NotAuthorizedText1": "Não autorizado, envie o comando inicial com \"auth\",\"ke\", e \"uid\"",
|
||||
"Notes": "Notas",
|
||||
"NotesPlacholder": "Comentários que você quer deixar para as configurações desta câmera.",
|
||||
"Nothing exists": "Nada existe",
|
||||
"Notification Sound": "Som De Notificação",
|
||||
"Notification Video Length": "Notificação De Duração Do Vídeo",
|
||||
"Number of Days to keep": "Número de dias para manter",
|
||||
"ONVIF": "ONVIF",
|
||||
"ONVIF Port": "ONVIF Porta",
|
||||
"ONVIF Scanner": "ONVIF Scanner",
|
||||
"ONVIFEventsNotAvailable": "ONVIF Eventos não Disponível",
|
||||
"ONVIFnotCompliantProfileT": "A câmera não está ONVIF Perfil T Complacente",
|
||||
"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.",
|
||||
"OR": "OU",
|
||||
"Object": "Objeto",
|
||||
"Object Detection": "A Detecção De Objetos",
|
||||
"Object Tag": "Objeto Tag",
|
||||
"OpenCV Cascades": "OpenCV Cascatas",
|
||||
"Operating Hours": "Horário De Funcionamento",
|
||||
"Options": "Opções",
|
||||
"Order Streams": "Ordenar transmissões",
|
||||
"Output Method": "Método de saída",
|
||||
"Password": "Senha",
|
||||
"Password Again": "Senha novamente",
|
||||
"Passwords don't match": "As senhas não combinam",
|
||||
"Paste JSON here.": "Cole o JSON aqui.",
|
||||
"Path": "Caminho",
|
||||
"Permissions": "Permissões",
|
||||
"Ping Failed": "O Ping",
|
||||
"Please Check Your Settings": "Por Favor Verifique As Suas Definições",
|
||||
"Please Wait for Completion": "Por favor, Aguarde a Conclusão, Dependendo do número de arquivos selecionados isso pode levar algum tempo. Atualizar para verificar novamente.",
|
||||
"Plugin": "Plugin",
|
||||
"Points": "Pontos <small>Ao adicionar pontos, clique na borda do polígono.</small>",
|
||||
"Pop": "Pop",
|
||||
"Popout Monitor on Event": "Popout Monitor de Eventos",
|
||||
"Port": "Porta",
|
||||
"Pose": "Pose",
|
||||
"Poseidon": "Poseidon",
|
||||
"Position X": "Posição X",
|
||||
"Position Y": "Posição Y",
|
||||
"Power Video Viewer": "Ligar visualizador de vídeo",
|
||||
"Power Viewer": "Ligar visualizador",
|
||||
"Preferences": "Preferências",
|
||||
"Preset": "Pré-definição",
|
||||
"Presets": "Predefinições",
|
||||
"Preview": "Visualização",
|
||||
"Primary Engine": "Motor Principal",
|
||||
"Primary Input": "Entrada Principal",
|
||||
"Privileges": "Privilégios",
|
||||
"Probe Size": "Sonda Tamanho",
|
||||
"Process Crashed for Monitor": "Processo de Monitor quebrado",
|
||||
"Process Started": "Processo Iniciado",
|
||||
"Process Unexpected Exit": "Saída inesperado do processo",
|
||||
"Processor": "Processador",
|
||||
"Profile": "Perfil",
|
||||
"Quality": "Qualidade <small>1 para alta, 23 para Low</small>",
|
||||
"Query": "Pesquisa",
|
||||
"Quick Sync Video": "Quick Sync Video",
|
||||
"RAM": "RAM",
|
||||
"RTMP": "RTMP",
|
||||
"RTMP Stream": "RTMP Stream",
|
||||
"RTMP Stream Flags": "RTMP Fluxo de Sinalizadores",
|
||||
"RTMPS": "RTMPS",
|
||||
"RTSP": "RTSP",
|
||||
"RTSP Transport": "Transporte RTSP",
|
||||
"Range or Single": "Intervalo ou Único",
|
||||
"Raspberry Pi": "Raspberry Pi",
|
||||
"Rate": "Taxa <small>(FPS)</small>",
|
||||
"Raw": "Matérias",
|
||||
"Raw H.264 Stream": "Matérias H. 264 Stream",
|
||||
"Reason": "Razão",
|
||||
"Recent Videos": "Vídeos Recentes",
|
||||
"Recommended": "Recomendado",
|
||||
"Record": "Gravar",
|
||||
"Record File Type": "Tipo de arquivo de gravação",
|
||||
"Record Height": "Altura da gravação",
|
||||
"Record Video Filter": "Gravar filtro de vídeo",
|
||||
"Record Width": "Largura da gravação",
|
||||
"Recorded Buffer": "Gravado Buffer",
|
||||
"Recording": "Gravando",
|
||||
"Recording FPS": "Gravação de FPS",
|
||||
"Recording FPS Change on Start": "Gravação de FPS Alterar em Iniciar",
|
||||
"Recording Flags": "Gravando Flags",
|
||||
"Recording Segment Interval": "Intervalo de Segmento de Gravação <small>em minutos</small>",
|
||||
"Recording Timeout": "Gravando Timeout <small>em minutos</small>",
|
||||
"Recording Timestamp": "Gravando horário",
|
||||
"Recording Watermark": "Gravando marca d'água",
|
||||
"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>.",
|
||||
"Refresh List of Cascades": "Atualizar Lista de Cascatas",
|
||||
"Region": "Região",
|
||||
"Region Editor": "Editor de região",
|
||||
"Region Name": "Nome da região",
|
||||
"RegionNote": "Os pontos só são salvos quando você pressiona <b>Salvar</b> na janela de <b>Configurações do Monitor</b>.",
|
||||
"Regions": "Regiões",
|
||||
"Remember Me": "Lembrar",
|
||||
"Request": "Pedido",
|
||||
"Require Object to be in Region": "Exigir Objeto a ser na Região",
|
||||
"Reset Timer": "Temporizador de reinicialização",
|
||||
"Restart": "Reinicie",
|
||||
"Restart CRON": "Reinicie o CRON",
|
||||
"Restart Core": "Reinicie O Núcleo",
|
||||
"Restarting": "Reiniciar",
|
||||
"Restarting Process": "Reiniciado processo",
|
||||
"Retry Connection": "Tentar novamente a conexão <small>Número de vezes permitido falhar</small>",
|
||||
"Retrying...": "Repetindo...",
|
||||
"Right": "Direita <small>URL Address</small>",
|
||||
"Right Stop": "Direita máxima <small>URL Address</small>",
|
||||
"Rotate": "Rotação",
|
||||
"S3-Based Network Storage": "S3-Armazenamento Em Rede",
|
||||
"SFTP": "SFTP",
|
||||
"SFTP (SSH File Transfer)": "SFTP (SSH File Transfer)",
|
||||
"SFTP Error": "SFTP Erro",
|
||||
"Save": "Salvar",
|
||||
"Save Directory": "Salvar diretório",
|
||||
"Save Events to SQL": "Salvar eventos no SQL",
|
||||
"Save Frames to Events": "Salvar Quadros para Eventos",
|
||||
"Save Links to Database": "Salvar Links para Banco de dados",
|
||||
"Save Log in SQL": "Salvar log em SQL <small>Isso pode encher rapidamente.</small>",
|
||||
"Save as": "Salvar como",
|
||||
"Saved Filters": "Filtros Salvos",
|
||||
"Saved Presets": "Salvo Presets",
|
||||
"Saved Schedules": "Salvo Horários",
|
||||
"Scan Settings": "Configurações de digitalização",
|
||||
"Schedule": "Programação",
|
||||
"Schedule Configuration Not Found": "Agenda De Configuração Não Encontrado",
|
||||
"Schedules": "Horários",
|
||||
"Search": "Procurar",
|
||||
"Search Base": "Base de Pesquisa",
|
||||
"Search Filter": "Procurar Filtro",
|
||||
"Search Images": "Procurar Imagens",
|
||||
"Second stream in feed": "Segundo fluxo de alimentação",
|
||||
"Secure": "Seguro",
|
||||
"Send Frames": "Enviar quadros <small>Envie os quadros a serem analisados</small>",
|
||||
"Separate with commas, no spaces": "Separar com vírgulas, sem espaços",
|
||||
"Server URL": "URL do servidor",
|
||||
"Set to Watch Only": "Definir para apenas visualizar",
|
||||
"Settings": "Configurações",
|
||||
"Settings Changed": "Configurações Alteradas",
|
||||
"SettingsChangedText": "Suas configurações foram salvas e aplicadas.",
|
||||
"Shinobi": "Shinobi",
|
||||
"Shinobi Streamer": "Shinobi Streamer",
|
||||
"Show Logs": "Mostrar logs",
|
||||
"Show Matrices": "Mostrar Matrizes",
|
||||
"Show Matrix": "Mostrar A Matriz",
|
||||
"Show Regions of Interest": "Mostrar as Regiões de Interesse",
|
||||
"Show Stream HUD": "Show Stream HUD",
|
||||
"Show Thumbnails in Video List": "Mostrar Miniaturas na Lista de filmes",
|
||||
"Silent": "Silencioso",
|
||||
"Simple": "Simples",
|
||||
"Size (mb)": "Tamanho (mb)",
|
||||
"Skip Ping": "Pular Ping",
|
||||
"Snapshot": "Instantâneo",
|
||||
"Snapshot Flags": "Instantâneo Bandeiras",
|
||||
"Snapshots": "Instantâneos",
|
||||
"Sort By": "Ordenar Por",
|
||||
"Space Used": "Espaço Utilizado",
|
||||
"Start": "Iniciar",
|
||||
"Start Recording": "Iniciar gravação",
|
||||
"Start Time": "Hora de Início",
|
||||
"Start Time cannot be empty.": "Horário de início não pode estar vazia.",
|
||||
"Started": "Iniciado",
|
||||
"Starting": "Partida",
|
||||
"State Configuration Not Found": "Estado De Configuração Não Encontrado",
|
||||
"State Configuration has no monitors associated": "Configuração de estado não tem monitores associados",
|
||||
"Status Changed": "Status Alterado",
|
||||
"Status Indicator": "Indicador de status",
|
||||
"Stop": "Parar",
|
||||
"Stop Command": "Comando De Parada",
|
||||
"Stop URL": "Parar URL",
|
||||
"Stopped": "Parado",
|
||||
"Storage Location": "Local De Armazenamento",
|
||||
"Stream": "Transmissão",
|
||||
"Stream Channel": "Canal De Transmissão Em Sequência",
|
||||
"Stream Flags": "Flags de Transmissão",
|
||||
"Stream Key": "Chave De Fluxo",
|
||||
"Stream Timestamp": "Transmitindo horário",
|
||||
"Stream Type": "Tipo de transmissão",
|
||||
"Stream Watermark": "Transmitindo marca d'água",
|
||||
"Stream to YouTube": "Transmitir para o YouTube",
|
||||
"Stream to YouTube Flags": "Transmitir para o YouTube Flags",
|
||||
"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>",
|
||||
"Streamer": "Transmissor",
|
||||
"Streams": "Transmissões",
|
||||
"Subdivision": "Subdivisão",
|
||||
"Success": "Sucesso",
|
||||
"Superuser": "Superusuário",
|
||||
"Superuser Logs": "Logs do Superusuário",
|
||||
"Switch on for Still Image": "Ligar para manter imagem",
|
||||
"System": "Sistema",
|
||||
"TCP": "TCP",
|
||||
"TV Channel": "TV Canal",
|
||||
"TV Channel Group": "Canal de TV do Grupo",
|
||||
"TV Channel ID": "TV Canal ID",
|
||||
"Text Box Color": "Cor da caixa de texto",
|
||||
"Text Color": "Cor do texto",
|
||||
"Themes": "Temas",
|
||||
"There are no monitors that you can view with this account.": "Não há monitores que você pode ver com esta conta.",
|
||||
"Thumbnail": "Miniatura",
|
||||
"Time": "Horário",
|
||||
"Time Left": "Tempo Restante",
|
||||
"Time Occurred": "Tempo Ocorreu",
|
||||
"Time-lapse": "Time-lapse",
|
||||
"Time-lapse Tool": "Ferramenta Time-laps",
|
||||
"Timelapse": "Timelapse",
|
||||
"Timeout": "Tempo de espera",
|
||||
"Timeout Reset on Next Event": "Tempo limite de Reset no Próximo Evento",
|
||||
"Timeout Reset on Next Motion": "Timeout reiniciará no próximo movimento",
|
||||
"Toggle Sidebar": "Mostrar barra lateral",
|
||||
"Token": "Token",
|
||||
"Top Left": "Superior esquerdo",
|
||||
"Top Right": "Superior direito",
|
||||
"Traditional (Watch-Only, Includes Buffer)": "Tradicional (Veja Só, Inclui Buffer)",
|
||||
"Traditional Recording": "Tradicional De Gravação",
|
||||
"Traditional Recording Flags": "A Tradicional Gravação De Sinalizadores",
|
||||
"Train": "De trem",
|
||||
"TrainConfirm": "Tem certeza de que deseja para começar a treinar? Isto pode demorar mais de 12 horas, com mais de 500 imagens. Isto irá consumir uma grande quantidade de recursos, como memória RAM ou CPU.",
|
||||
"Trainer Engine": "Treinador Do Motor",
|
||||
"Trigger Camera Groups": "Disparador Da Câmera Grupos",
|
||||
"Trigger Group to Record": "Gatilho do Grupo para Gravar",
|
||||
"Trigger Record": "Acionar registro",
|
||||
"Trigger Successful": "Disparou bem sucedido",
|
||||
"Trigger Threshold": "Gatilho Limite",
|
||||
"UDP": "UDP",
|
||||
"URL": "URL",
|
||||
"URL Stop Timeout": "URL timeout máximo <small>Parar URL depois de X milissegundos</small>",
|
||||
"US": "EUA",
|
||||
"Unable to Launch": "Incapaz de executar",
|
||||
"UnabletoLaunchText": "Salve primeiro o monitor novo. Em seguida, tente iniciar o editor da região.",
|
||||
"Uniform": "Uniforme",
|
||||
"Up": "Cima <small>URL Address</small>",
|
||||
"Up Stop": "Cima máximo <small>URL Address</small>",
|
||||
"Update": "Atualização",
|
||||
"Update to Development": "Actualização para o Desenvolvimento",
|
||||
"Update to Master": "Atualização para o Mestre de",
|
||||
"Upload File": "Upload Do Arquivo",
|
||||
"Uploaders": "Uploaders",
|
||||
"Use Built-In": "Use Built-In",
|
||||
"Use Global Amazon S3 Video Storage": "Uso Global Do Amazon S3 Armazenamento De Vídeo",
|
||||
"Use Global Backblaze B2 Video Storage": "Use Global Backblaze B2 Armazenamento De Vídeo",
|
||||
"Use Global Wasabi Hot Cloud Storage Video Storage": "Uso Global Do Wasabi Quente De Armazenamento Em Nuvem De Armazenamento De Vídeo",
|
||||
"Use Global WebDAV Video Storage": "Uso Global Do WebDAV Armazenamento De Vídeo",
|
||||
"Use HTML5 Play Method": "Utilizar o HTML5 Método Play",
|
||||
"Use Max Storage Amount": "Usar O Max Quantidade De Armazenamento",
|
||||
"Use coProcessor": "O uso de co-processador",
|
||||
"User Not Found": "Usuário Não Encontrado",
|
||||
"Username": "Usuário",
|
||||
"VA-API": "VA-API",
|
||||
"Value": "Valor",
|
||||
"Video": "Vídeo",
|
||||
"Video Bit Rate": "Taxa De Bits De Vídeo",
|
||||
"Video Codec": "Codec De Vídeo",
|
||||
"Video Filter": "Filtro de vídeo",
|
||||
"Video Finished": "Vídeo finalizado",
|
||||
"Video Length (minutes) and Motion Count per video": "Comprimento do vídeo (minutos) e Contagem de movimento por vídeo",
|
||||
"Video Limit": "Limite de vídeo",
|
||||
"Video Record Rate": "Taxa de gravação de vídeo <small>(FPS)</small>",
|
||||
"Video Set": "Conjunto De Vídeo",
|
||||
"Video Status": "Status do Vídeo",
|
||||
"Video and Time Span (Minutes)": "Vídeo e intervalo de tempo (minutos)",
|
||||
"Video stream only from first feed": "Fluxo de vídeo somente a partir de primeiro de alimentação",
|
||||
"Video streams only": "Fluxos de vídeo informativo",
|
||||
"Videos": "Vídeos",
|
||||
"Videos List": "Lista de vídeos",
|
||||
"Videos Merge": "Vídeos De Mesclagem",
|
||||
"Warning": "Aviso",
|
||||
"Wasabi Hot Cloud Storage": "Wasabi Quente De Armazenamento Em Nuvem",
|
||||
"Wasabi Hot Cloud Storage Upload Error": "Wasabi Quente De Armazenamento Na Nuvem, Erro De Upload",
|
||||
"Watch": "Assistir",
|
||||
"Watch Only": "Visualizar apenas",
|
||||
"Watch-Only": "Assistir-Apenas",
|
||||
"Watching": "Assistindo",
|
||||
"Web Page": "Página Da Web",
|
||||
"WebDAV": "WebDAV",
|
||||
"WebM (libvpx)": "WebM (libvpx)",
|
||||
"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?",
|
||||
"WebdavErrorTextCreatingDir": "Não é possível criar diretório.",
|
||||
"WebdavErrorTextTryCreatingDir": "Não é possível salvar. Tentando criar o directório.",
|
||||
"Webhook": "Webhook",
|
||||
"Webhook URL": "Webhook URL",
|
||||
"Websocket": "Websocket",
|
||||
"Websocket Connected": "Websocket conectado",
|
||||
"Websocket Disconnected": "Websocket desconectado",
|
||||
"Width": "Largura",
|
||||
"X Point": "X Ponto",
|
||||
"Y Point": "Y Ponto De",
|
||||
"Yes": "Sim",
|
||||
"Zip and Download": "Zip e Download",
|
||||
"Zoom In": "Mais Zoom <small>URL Address</small>",
|
||||
"Zoom In Stop": "Parar mais zoom <small>URL Address</small>",
|
||||
"Zoom Out": "Menos Zoom <small>URL Address</small>",
|
||||
"Zoom Out Stop": "Parar menos zoom <small>URL Address</small>",
|
||||
"a day": "um dia",
|
||||
"a few seconds": "alguns segundos",
|
||||
"a minute": "um minuto",
|
||||
"a month": "um mês",
|
||||
"a year": "um ano",
|
||||
"aac": "aac",
|
||||
"aac (Default)": "aac (Padrão)",
|
||||
"ac3": "ac3",
|
||||
"accountId": "ID da conta",
|
||||
"ago": "atrás",
|
||||
"an hour": "uma hora",
|
||||
"applicationKey": "Chave De Aplicativo",
|
||||
"aws_accessKeyId": "Id Da Chave De Acesso",
|
||||
"aws_secretAccessKey": "A Chave De Acesso Secreta",
|
||||
"bindDN": "Vincular DN",
|
||||
"blankPassword": "Deixe em branco para manter a mesma senha",
|
||||
"clientStreamFailedattemptingReconnect": "A verificação ctream do lado do cliente falhou, tentando reconectar.",
|
||||
"coProcess Crashed for Monitor": "coProcess Caiu para Monitor",
|
||||
"coProcess Unexpected Exit": "coProcess Inesperado Sair",
|
||||
"coProcessor": "co-processador",
|
||||
"coProcessor Started": "co-processador matemático Começou",
|
||||
"coProcessor Stopped": "co-processador Parado",
|
||||
"coProcessorTextStarted": "co-processador matemático foi iniciado pela CPU, apenas saídas.",
|
||||
"coProcessorTextStopped": "co-processador terminou.",
|
||||
"confirmDeleteFilter": "Deseja excluir este filtro? Você não poderá recuperá-lo.",
|
||||
"copy": "copiar",
|
||||
"cuvid": "cuvid (NVIDIA NVENC)",
|
||||
"days": "dias",
|
||||
"deleteMonitorStateText1": "Você deseja excluir este Monitor Estados Preset?",
|
||||
"deleteMonitorStateText2": "Você deseja excluir este Monitor do Preset?",
|
||||
"drm": "DRM objeto de partilha",
|
||||
"dropBoxSuccess": "Sucesso! Arquivos salvos em seu Dropbox.",
|
||||
"dxva2": "dxva2 (Vídeo DirectX, Windows)",
|
||||
"failedLoginText1": "Falhou o início de sessão muitas vezes. Você deve aguardar 15 minutos antes de tentar novamente.",
|
||||
"failedLoginText2": "Por favor verifique as suas credenciais de início de sessão.",
|
||||
"flv": "flv",
|
||||
"for Global Access": "para Acesso Global",
|
||||
"h264_cuvid": "H. 264 CUVID",
|
||||
"h264_mmal": "H. 264 (Raspberry Pi)",
|
||||
"h264_nvenc": "H. 264 NVENC (NVIDIA HARDWARE de Aceleração)",
|
||||
"h264_omx": "H. 264 openMAX (Raspberry Pi)",
|
||||
"h264_qsv": "H. 264 (Quick Sync Vídeo)",
|
||||
"h264_vaapi": "H. 264 VA-API (Intel HARDWARE de Aceleração)",
|
||||
"h265BrowserText1": "Se você estiver tentando reproduzir um H. 265 arquivo, você pode precisar para fazer o download e abri-lo em outro aplicativo, como o VLC.",
|
||||
"hevc_cuvid": "H. 265 CUVID",
|
||||
"hevc_nvenc": "H. 265 NVENC (NVIDIA HARDWARE de Aceleração)",
|
||||
"hevc_qsv": "H. 265 (Quick Sync Vídeo)",
|
||||
"hevc_vaapi": "H. 265 VA-API (Intel HARDWARE de Aceleração)",
|
||||
"hours": "horas",
|
||||
"hwaccel": "A Aceleração Do Motor",
|
||||
"hwaccel_device": "HWAccel Dispositivo",
|
||||
"hwaccel_vcodec": "O Decodificador De Vídeo",
|
||||
"ifYouSeeNothingHereThenJustDownloadThisPackageOfCascadesDropThemIntoPluginsopencvcascadesThenPressRefresh": "Se você não vê nada aqui, então, basta baixar este pacote de <a href=\"https://cdn.shinobi.video/weights/cascades.zip\">cascatas</a>. Solte-os em <code>plugins/opencv/cascatas</code> , em seguida, pressione atualizar <i class=\"fa fa-retweet\"></i>.",
|
||||
"in": "em",
|
||||
"in Days": "em Dias",
|
||||
"itIsRecommendedThatYouSetRecordFileTypeToWebmmp4AndVideoCodecToLibvpxcopyOrLibx264BecauseYourInputTypeIsSetTo": "É recomendável que você defina o <b>Registro de Tipo de Arquivo</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>Codec de Vídeo</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\">copiar 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 o <b>Tipo de Entrada</b> é definida como <b class=\"h_t_text\"></b>.",
|
||||
"libmp3lame": "libmp3lame",
|
||||
"libopus": "libopus",
|
||||
"libvorbis (Default)": "libvorbis (Padrão)",
|
||||
"libvpx (Default)": "libvpx (Padrão)",
|
||||
"libvpx-vp9": "libvpx-vp9",
|
||||
"libx264": "libx264",
|
||||
"libx264 (Default)": "libx264 (Padrão)",
|
||||
"libx265": "libx265",
|
||||
"migrateText1": "<b>Tipo de entrada</b> não pode ser analisada. Por favor configure-a manualmente.",
|
||||
"minutes": "minutos",
|
||||
"mjpeg_cuvid": "MJPEG CUVID",
|
||||
"modifyVideoText1": "Método não existe. Verifique se o último valor da URL não está em branco",
|
||||
"monSavedButNotCopied": "O monitor foi salvo, mas não é copiado para qualquer outro monitor.",
|
||||
"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.",
|
||||
"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",
|
||||
"monitorGetText1": "Requisição incompleta. Remova a última barra da URL ou informe um valor válido",
|
||||
"months": "meses",
|
||||
"mpeg2_mmal": "MPEG-2 (Raspberry Pi)",
|
||||
"mpeg2_qsv": "MPEG2 (Quick Sync Vídeo)",
|
||||
"mpeg4_cuvid": "MPEG4 CUVID",
|
||||
"mpeg4_mmal": "MPEG-4 (Raspberry Pi)",
|
||||
"noSpecialCharacters": "Sem espaços ou caracteres especiais.",
|
||||
"notPermitted1": "Esta ação não é permitido pelo administrador da sua conta.'",
|
||||
"on": "ligado",
|
||||
"on Error": "em Erro",
|
||||
"opencvCascadesText": "Se você não vê nada aqui, então, basta baixar este pacote de <a href=\"https://cdn.shinobi.video/weights/cascades.zip\">cascatas</a>. Solte-os em <code>plugins/opencv/cascatas</code> , em seguida, pressione atualizar <i class=\"fa fa-retweet\"></i>.",
|
||||
"possibleInternalError": "Possível Erro Interno",
|
||||
"postDataBroken": "Verifique o formato JSON. Certifique-é stringified e definidos em 'dados'",
|
||||
"powerVideoEventLimit": "Você tem de definir um alto limite de evento. Tem certeza de que quer fazer esse pedido?",
|
||||
"privateKey": "Chave Privada",
|
||||
"qsv": "qsv",
|
||||
"sizePurgeLockedText": "O Tamanho de Purga de Bloqueio (deleteOverMax) parece ter falhado para desbloquear. Desbloqueio agora...",
|
||||
"skipPingText1": "Tente definir \"Ignorar Ping\" para Sim.",
|
||||
"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.",
|
||||
"startUpText6": "Órfão Vídeos Encontrados e Inserido",
|
||||
"superAdminText": "\"super.json\" não existe. Por favor, renomeie \"super.sample.json\" para \"super.json\".",
|
||||
"superAdminTitle": "Shinobi : Super Admin",
|
||||
"thisIsHowTheSystemWillIdentifyTheDataForThisStreamYouCannotChangeTheMonitorIdOnceYouHavePressedSaveIfYouWantYouCanMakeTheMonitorIdMoreHumanReadableBeforeYouContinueyouCanDuplicateAMonitorByModifyingTheMonitorIdThenPressingSaveYouCannotUseTheIdOfAMonitorThatAlreadyExistsOrItWillSaveOverThatMonitorsDatabaseInformation": "<div class=\"am_notice am_notice_new\">Esta é a forma como o sistema irá identificar os dados para este fluxo. Você não pode alterar o <b>ID do Monitor</b> depois de ter pressionado salvar. Se você quiser você pode fazer o <b>Monitor de IDENTIFICAÇÃO</b> mais legível para humanos antes de continuar.</div><div class=\"am_notice am_notice_edit\">Você pode duplicar um monitor modificando o <b>Monitor de IDENTIFICAÇÃO</b> , em seguida, pressionando salvar. Você <b>não pode</b> usar o ID de um monitor que já existe, ou ele vai economizar mais que o monitor de informações do banco de dados.</div>",
|
||||
"thisSectionTellsShinobiHowToConsumeAStreamForOptimalPerformanceTryTuningYourCamerasInternalSettingsFindTheFollowingOptionsAndSetThemAsShownToFindYourCameraYouCanUseTheBuiltInOnvifScannerOfShinobiSomeOnvifCamerasRequireTheUseOfAManagementToolToModifyTheirInternalSettingsIfYouCantFindYourCamerasYouCanTryOnvifDeviceManagerForWindowsFramerateFpsHigh1015FpsLow25FpsiframeInterval1bitRateTypeVbrVariableBitRatebitRateBetween256kbps1000kbpsIfYouNeedHelpFiguringOutWhatInputTypeYourCameraIsYouCanTakeALookInTheCameraUrlsListOnTheShinobiWebsite": "<p>Esta secção diz Shinobi como consumir um fluxo. Para melhor desempenho, tente afinar a sua câmera configurações internas. Encontrar as seguintes opções e defina-as como mostrado. Para encontrar a sua câmera, você pode usar o <b>construída em ONVIF Scanner</b> de Shinobi. Alguns ONVIF câmeras exigem o uso de uma ferramenta de gestão para modificar suas configurações internas. Se você não pode encontrar câmeras, você pode tentar <a href=\"https://s3.amazonaws.com/cloudcamio/odm-v2.2.250.msi\">ONVIF Gerenciador de Dispositivos do Windows</a>.</p> <ul><li><b>A taxa de quadros (FPS) :</b> Alta : de 10 a 15 FPS, Baixa : de 2 a 5 FPS</li><li><b>I-intervalo :</b> 1</li><li><b>A Taxa de bits do Tipo :</b> VBR (Taxa de Bit Variável)</li><li><b>Taxa de bits :</b> entre 256kbps - 1000kbps</li></ul> <p>Se você precisar de ajuda para descobrir que tipo de entrada de sua câmera é que você pode dar uma olhada na <a href=\"http://shinobi.video/docs/cameras\" target=\"_blank\">Câmera Lista de URLs</a> no Shinobi site.</p>",
|
||||
"thisSectionWillDesignateThePrimaryMethodOfStreamingOutAndItsSettingsThisStreamWillBeDisplayedInTheDashboardIfYouChooseToUseHlsJpegOrMjpegThenYouCanConsumeTheStreamThroughOtherProgramsusingJpegStreamEssentiallyTurnsOffThePrimaryStreamAndUsesTheSnapshotBinToGetFrames": "<p>Esta seção irá designar o principal método de transmissão e suas configurações. Este fluxo será exibida no painel de controle. Se você escolher usar HLS, JPEG, ou MJPEG, em seguida, você pode consumir o fluxo através de outros programas.</p><p class=\"h_st_input h_st_jpeg\">Usando JPEG fluxo essencialmente desliga o fluxo principal e usa o instantâneo bin para obter quadros.</p>",
|
||||
"total": "total",
|
||||
"updateKeyText1": "\"updateKey\" faltando em \"conf.json\", não é possível atualizar dessa maneira até você adicionar",
|
||||
"updateKeyText2": "\"updateKey\" incorreta",
|
||||
"vaapi": "vaapi (VA-API)",
|
||||
"vda": "vda (Apple VDA Aceleração de Hardware)",
|
||||
"vdpau": "vdpau",
|
||||
"videotoolbox": "videotoolbox",
|
||||
"vp8_cuvid": "VP8 NVENC (NVIDIA HARDWARE de Aceleração)",
|
||||
"vp8_qsv": "VP8 (Quick Sync Vídeo)",
|
||||
"vp9_cuvid": "VP9 NVENC (NVIDIA HARDWARE de Aceleração)",
|
||||
"whenTheWidthAndHeightBoxesAreShownYouShouldSetThemTo640x480OrBelowThisWillOptimizeTheReadSpeedOfFrames\n": "<p>Quando as caixas Largura e Altura são mostradas, você deve configurá-los para 640x480 ou abaixo. Isto irá otimizar a velocidade de leitura dos quadros.</p>\n<p class=\"shinobi-detector-msg\"></p>",
|
||||
"years": "anos"
|
||||
}
|
|
@ -121,7 +121,9 @@ module.exports = function(s,config,lang){
|
|||
var adminUsersSelected = null
|
||||
try{
|
||||
var success = function(){
|
||||
var chosenConfig = config
|
||||
if(req && res){
|
||||
chosenConfig = s.getConfigWithBranding(req.hostname)
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
var ip = req.headers['cf-connecting-ip']||req.headers["CF-Connecting-IP"]||req.headers["'x-forwarded-for"]||req.connection.remoteAddress;
|
||||
var resp = {
|
||||
|
@ -143,7 +145,7 @@ module.exports = function(s,config,lang){
|
|||
ip : ip,
|
||||
$user:userSelected,
|
||||
users:adminUsersSelected,
|
||||
config:config,
|
||||
config: chosenConfig,
|
||||
lang:lang
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
module.exports = function(s,config,lang,app,io){
|
||||
if(config.showPoweredByShinobi === undefined){config.showPoweredByShinobi=true}
|
||||
if(config.poweredByShinobi === undefined){config.poweredByShinobi='Powered by Shinobi.Systems'}
|
||||
if(config.poweredByShinobiClass === undefined){config.poweredByShinobiClass='margin:15px 0 0 0;text-align:center;color:#777;font-family: sans-serif;text-transform: uppercase;letter-spacing: 3;font-size: 8pt;'}
|
||||
if(config.webPageTitle === undefined){config.webPageTitle='Shinobi'}
|
||||
if(config.showLoginCardHeader === undefined){config.showLoginCardHeader=true}
|
||||
if(config.webFavicon === undefined){config.webFavicon='libs/img/icon/favicon.ico'}
|
||||
if(config.logoLocation76x76 === undefined){config.logoLocation76x76='libs/img/icon/apple-touch-icon-76x76.png'}
|
||||
if(config.logoLocation76x76Link === undefined){config.logoLocation76x76Link='https://shinobi.video'}
|
||||
if(config.logoLocation76x76Style === undefined){config.logoLocation76x76Style='border-radius:50%'}
|
||||
if(config.showLoginSelector === undefined){config.showLoginSelector=true}
|
||||
|
||||
s.getConfigWithBranding = function(domain){
|
||||
var configCopy = Object.assign({},config)
|
||||
if(config.brandingConfig && config.brandingConfig[domain]){
|
||||
return Object.assign(configCopy,config.brandingConfig[domain])
|
||||
}
|
||||
return config
|
||||
}
|
||||
}
|
|
@ -9,14 +9,6 @@ module.exports = function(s){
|
|||
config.productType = 'CE'
|
||||
}
|
||||
//config defaults
|
||||
if(config.showPoweredByShinobi === undefined){config.showPoweredByShinobi=true}
|
||||
if(config.poweredByShinobi === undefined){config.poweredByShinobi='Powered by Shinobi.Systems'}
|
||||
if(config.poweredByShinobiClass === undefined){config.poweredByShinobiClass='margin:15px 0 0 0;text-align:center;color:#777;font-family: sans-serif;text-transform: uppercase;letter-spacing: 3;font-size: 8pt;'}
|
||||
if(config.webPageTitle === undefined){config.webPageTitle='Shinobi'}
|
||||
if(config.showLoginCardHeader === undefined){config.showLoginCardHeader=true}
|
||||
if(config.logoLocation76x76 === undefined){config.logoLocation76x76='libs/img/icon/apple-touch-icon-76x76.png'}
|
||||
if(config.logoLocation76x76Link === undefined){config.logoLocation76x76Link='https://shinobi.video'}
|
||||
if(config.logoLocation76x76Style === undefined){config.logoLocation76x76Style='border-radius:50%'}
|
||||
if(config.cpuUsageMarker === undefined){config.cpuUsageMarker='%Cpu'}
|
||||
if(config.customCpuCommand === undefined){config.customCpuCommand=null}
|
||||
if(config.autoDropCache === undefined){config.autoDropCache=true}
|
||||
|
|
|
@ -7,7 +7,13 @@ module.exports = function(s,config,lang,app,io){
|
|||
}catch(er){
|
||||
console.error(er)
|
||||
console.log('There was an error loading your definition file.')
|
||||
var definitions = require(s.location.definitions+'/en_CA.json');
|
||||
try{
|
||||
var definitions = require(s.location.definitions+'/en_CA.js')(s,config,lang)
|
||||
}catch(er){
|
||||
console.error(er)
|
||||
console.log('There was an error loading your definition file.')
|
||||
var definitions = require(s.location.definitions+'/en_CA.json');
|
||||
}
|
||||
}
|
||||
//load defintions dynamically
|
||||
s.copySystemDefaultDefinitions = function(){
|
||||
|
|
|
@ -57,12 +57,14 @@ module.exports = function(s,config){
|
|||
e.triggerTimer = {}
|
||||
|
||||
var regions = s.createPamDiffRegionArray(regionJson,globalColorThreshold,globalSensitivity,fullFrame)
|
||||
|
||||
s.group[e.ke].mon[e.id].pamDiff = new PamDiff({
|
||||
var pamDiffOptions = {
|
||||
grayscale: 'luminosity',
|
||||
regions : regions.forPam,
|
||||
drawMatrix : e.details.detector_show_matrix
|
||||
});
|
||||
regions : regions.forPam
|
||||
}
|
||||
if(e.details.detector_show_matrix==='1'){
|
||||
pamDiffOptions.response = 'bounds'
|
||||
}
|
||||
s.group[e.ke].mon[e.id].pamDiff = new PamDiff(pamDiffOptions);
|
||||
s.group[e.ke].mon[e.id].p2p = new P2P()
|
||||
var regionArray = Object.values(regionJson)
|
||||
if(config.detectorMergePamRegionTriggers === true){
|
||||
|
@ -94,7 +96,7 @@ module.exports = function(s,config){
|
|||
++filteredCount
|
||||
if(!err1 && !err2)++filteredCountSuccess
|
||||
if(filteredCount === trigger.merged.length && filteredCountSuccess > 0){
|
||||
detectorObject.doObjectDetection = (s.ocv && e.details.detector_use_detect_object === '1')
|
||||
detectorObject.doObjectDetection = (s.isAtleatOneDetectorPluginConnected && e.details.detector_use_detect_object === '1')
|
||||
s.triggerEvent(detectorObject)
|
||||
}
|
||||
})
|
||||
|
@ -106,7 +108,7 @@ module.exports = function(s,config){
|
|||
s.checkMaximumSensitivity(e, region, detectorObject, function(err1) {
|
||||
s.checkTriggerThreshold(e, region, detectorObject, function(err2) {
|
||||
if(!err1 && !err2){
|
||||
detectorObject.doObjectDetection = (s.ocv && e.details.detector_use_detect_object === '1')
|
||||
detectorObject.doObjectDetection = (s.isAtleatOneDetectorPluginConnected && e.details.detector_use_detect_object === '1')
|
||||
s.triggerEvent(detectorObject)
|
||||
}
|
||||
})
|
||||
|
@ -161,7 +163,7 @@ module.exports = function(s,config){
|
|||
s.checkMaximumSensitivity(e, region, detectorObject, function(err1) {
|
||||
s.checkTriggerThreshold(e, region, detectorObject, function(err2) {
|
||||
if(!err1 && ! err2){
|
||||
detectorObject.doObjectDetection = (s.ocv && e.details.detector_use_detect_object === '1')
|
||||
detectorObject.doObjectDetection = (s.isAtleatOneDetectorPluginConnected && e.details.detector_use_detect_object === '1')
|
||||
s.triggerEvent(detectorObject)
|
||||
}
|
||||
})
|
||||
|
@ -176,13 +178,17 @@ module.exports = function(s,config){
|
|||
s.group[e.ke].mon[e.id].pamDiff.on('diff', (data) => {
|
||||
data.trigger.forEach(function(trigger){
|
||||
s.filterTheNoise(e,noiseFilterArray,regions,trigger,function(){
|
||||
s.createMatrixFromPamTrigger(trigger)
|
||||
buildTriggerEvent(trigger)
|
||||
})
|
||||
})
|
||||
})
|
||||
}else{
|
||||
s.group[e.ke].mon[e.id].pamDiff.on('diff', (data) => {
|
||||
data.trigger.forEach(buildTriggerEvent)
|
||||
data.trigger.forEach(function(trigger){
|
||||
s.createMatrixFromPamTrigger(trigger)
|
||||
buildTriggerEvent(trigger)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +311,7 @@ module.exports = function(s,config){
|
|||
name.push(trigger.name + ' ('+trigger.percent+'%)')
|
||||
++n
|
||||
sum += trigger.percent
|
||||
s.createMatrixFromPamTrigger(trigger)
|
||||
if(trigger.matrix)matrices.push(trigger.matrix)
|
||||
})
|
||||
var average = sum / n
|
||||
|
@ -318,6 +325,7 @@ module.exports = function(s,config){
|
|||
}
|
||||
}else{
|
||||
var trigger = data.trigger[0]
|
||||
s.createMatrixFromPamTrigger(trigger)
|
||||
trigger.matrices = [trigger.matrix]
|
||||
}
|
||||
return trigger
|
||||
|
@ -357,4 +365,28 @@ module.exports = function(s,config){
|
|||
if(callback)callback(foundInRegion,collisions)
|
||||
return foundInRegion
|
||||
}
|
||||
s.createMatrixFromPamTrigger = function(trigger){
|
||||
if(
|
||||
trigger.minX &&
|
||||
trigger.maxX &&
|
||||
trigger.minY &&
|
||||
trigger.maxY
|
||||
){
|
||||
var coordinates = [
|
||||
{"x" : trigger.minX, "y" : trigger.minY},
|
||||
{"x" : trigger.maxX, "y" : trigger.minY},
|
||||
{"x" : trigger.maxX, "y" : trigger.maxY}
|
||||
]
|
||||
var width = Math.sqrt( Math.pow(coordinates[1].x - coordinates[0].x, 2) + Math.pow(coordinates[1].y - coordinates[0].y, 2));
|
||||
var height = Math.sqrt( Math.pow(coordinates[2].x - coordinates[1].x, 2) + Math.pow(coordinates[2].y - coordinates[1].y, 2))
|
||||
trigger.matrix = {
|
||||
x: coordinates[0].x,
|
||||
y: coordinates[0].y,
|
||||
width: width,
|
||||
height: height,
|
||||
tag: trigger.name
|
||||
}
|
||||
}
|
||||
return trigger
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,6 +185,7 @@ module.exports = function(s,config,lang){
|
|||
d.details.matrices = reviewedMatrix
|
||||
}
|
||||
}
|
||||
var eventTime = new Date()
|
||||
//motion counter
|
||||
if(filter.addToMotionCounter && filter.record){
|
||||
if(!s.group[d.ke].mon[d.id].detector_motion_count){
|
||||
|
@ -254,7 +255,7 @@ module.exports = function(s,config,lang){
|
|||
}
|
||||
//save this detection result in SQL, only coords. not image.
|
||||
if(filter.save && currentConfig.detector_save === '1'){
|
||||
s.sqlQuery('INSERT INTO Events (ke,mid,details,time) VALUES (?,?,?,?)',[d.ke,d.id,detailString,new Date()])
|
||||
s.sqlQuery('INSERT INTO Events (ke,mid,details,time) VALUES (?,?,?,?)',[d.ke,d.id,detailString,eventTime])
|
||||
}
|
||||
if(currentConfig.detector_notrigger === '1'){
|
||||
var detector_notrigger_timeout
|
||||
|
@ -273,7 +274,7 @@ module.exports = function(s,config,lang){
|
|||
detector_timeout = parseFloat(currentConfig.detector_timeout)
|
||||
}
|
||||
if(filter.record && d.mon.mode=='start'&¤tConfig.detector_trigger==='1'&¤tConfig.detector_record_method==='sip'){
|
||||
s.createEventBasedRecording(d)
|
||||
s.createEventBasedRecording(d,moment(eventTime).subtract(5,'seconds').format('YYYY-MM-DDTHH-mm-ss'))
|
||||
}else if(filter.record && d.mon.mode!=='stop'&¤tConfig.detector_trigger=='1'&¤tConfig.detector_record_method==='hot'){
|
||||
if(!d.auth){
|
||||
d.auth=s.gid();
|
||||
|
@ -331,7 +332,8 @@ module.exports = function(s,config,lang){
|
|||
d.cx={f:'detector_trigger',id:d.id,ke:d.ke,details:d.details,doObjectDetection:d.doObjectDetection};
|
||||
s.tx(d.cx,'DETECTOR_'+d.ke+d.id);
|
||||
}
|
||||
s.createEventBasedRecording = function(d){
|
||||
s.createEventBasedRecording = function(d,fileTime){
|
||||
if(!fileTime)fileTime = s.formattedTime()
|
||||
d.mon = s.group[d.ke].mon_conf[d.id]
|
||||
var currentConfig = s.group[d.ke].mon[d.id].details
|
||||
if(currentConfig.detector !== '1'){
|
||||
|
@ -355,7 +357,7 @@ module.exports = function(s,config,lang){
|
|||
if(!s.group[d.ke].mon[d.id].eventBasedRecording.process){
|
||||
s.group[d.ke].mon[d.id].eventBasedRecording.allowEnd = false;
|
||||
var runRecord = function(){
|
||||
var filename = s.formattedTime()+'.mp4'
|
||||
var filename = fileTime+'.mp4'
|
||||
s.userLog(d,{type:lang["Traditional Recording"],msg:lang["Started"]})
|
||||
//-t 00:'+s.timeObject(new Date(detector_timeout * 1000 * 60)).format('mm:ss')+'
|
||||
s.group[d.ke].mon[d.id].eventBasedRecording.process = spawn(config.ffmpegDir,s.splitForFFPMEG(('-loglevel warning -analyzeduration 1000000 -probesize 1000000 -re -i "'+s.dir.streams+'/'+d.ke+'/'+d.id+'/detectorStream.m3u8" -c:v copy -strftime 1 "'+s.getVideoDirectory(d.mon) + filename + '"')))
|
||||
|
|
|
@ -924,6 +924,7 @@ module.exports = function(s,config,lang){
|
|||
}
|
||||
var timeNow = new Date()
|
||||
s.sqlQuery('INSERT INTO `Timelapse Frames` (ke,mid,details,filename,size,time) VALUES (?,?,?,?,?,?)',[e.ke,e.id,s.s(details),filename,fileStats.size,timeNow])
|
||||
s.setDiskUsedForGroup(e,fileStats.size / 1000000)
|
||||
})
|
||||
s.group[e.ke].mon[e.id].recordTimelapseWriter = fileStream
|
||||
}
|
||||
|
|
|
@ -77,13 +77,27 @@ module.exports = function(s,config,lang,io){
|
|||
user.size = 0
|
||||
user.limit = userDetails.size
|
||||
s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND status!=?',[user.ke,0],function(err,videos){
|
||||
if(videos && videos[0]){
|
||||
videos.forEach(function(video){
|
||||
user.size += video.size
|
||||
s.sqlQuery('SELECT * FROM `Timelapse Frames` WHERE ke=?',[user.ke],function(err,timelapseFrames){
|
||||
s.sqlQuery('SELECT * FROM `Files` WHERE ke=?',[user.ke],function(err,files){
|
||||
if(videos && videos[0]){
|
||||
videos.forEach(function(video){
|
||||
user.size += video.size
|
||||
})
|
||||
}
|
||||
if(timelapseFrames && timelapseFrames[0]){
|
||||
timelapseFrames.forEach(function(frame){
|
||||
user.size += frame.size
|
||||
})
|
||||
}
|
||||
if(files && files[0]){
|
||||
files.forEach(function(file){
|
||||
user.size += file.size
|
||||
})
|
||||
}
|
||||
s.systemLog(user.mail+' : '+lang.startUpText1+' : '+videos.length,user.size)
|
||||
callback()
|
||||
})
|
||||
}
|
||||
s.systemLog(user.mail+' : '+lang.startUpText1+' : '+videos.length,user.size)
|
||||
callback()
|
||||
})
|
||||
})
|
||||
}
|
||||
var loadCloudDiskUseForUser = function(user,callback){
|
||||
|
|
|
@ -131,9 +131,9 @@ module.exports = function(s,config){
|
|||
if(!s.group[e.ke].sizePurgeQueue){s.group[e.ke].sizePurgeQueue=[]}
|
||||
if(!e.limit||e.limit===''){e.limit=10000}else{e.limit=parseFloat(e.limit)}
|
||||
//save global space limit for group key (mb)
|
||||
s.group[e.ke].sizeLimit=e.limit;
|
||||
s.group[e.ke].sizeLimit = e.limit
|
||||
//save global used space as megabyte value
|
||||
s.group[e.ke].usedSpace=e.size/1000000;
|
||||
s.group[e.ke].usedSpace = (e.size || 0) / 1000000
|
||||
//emit the changes to connected users
|
||||
s.sendDiskUsedAmountToClients(e)
|
||||
}
|
||||
|
|
|
@ -414,4 +414,80 @@ module.exports = function(s,config,lang){
|
|||
file.pipe(res)
|
||||
return file
|
||||
}
|
||||
s.createVideoFromTimelapse = function(timelapseFrames,callback){
|
||||
var frames = timelapseFrames.reverse()
|
||||
var ke = frames[0].ke
|
||||
var mid = frames[0].mid
|
||||
var finalFileName = frames[0].filename.split('T')[0]
|
||||
var concatFiles = []
|
||||
var createLocation
|
||||
frames.forEach(function(frame,frameNumber){
|
||||
var selectedDate = frame.filename.split('T')[0]
|
||||
var fileLocationMid = `${frame.ke}/${frame.mid}_timelapse/${selectedDate}/`
|
||||
frame.details = s.parseJSON(frame.details)
|
||||
var fileLocation
|
||||
if(frame.details.dir){
|
||||
fileLocation = `${s.checkCorrectPathEnding(frame.details.dir)}`
|
||||
}else{
|
||||
fileLocation = `${s.dir.videos}`
|
||||
}
|
||||
fileLocation = `${fileLocation}${fileLocationMid}${frame.filename}`
|
||||
concatFiles.push(fileLocation)
|
||||
if(frameNumber === 0){
|
||||
createLocation = fileLocationMid
|
||||
}
|
||||
})
|
||||
var commandTempLocation = `${s.dir.streams}${ke}/${mid}/mergeJpegs_${finalFileName}.sh`
|
||||
var finalMp4OutputLocation = `${s.dir.fileBin}${ke}/${mid}/${finalFileName}.mp4`
|
||||
if(!s.group[ke].mon[mid].buildingTimelapseVideo){
|
||||
if(!fs.existsSync(finalMp4OutputLocation)){
|
||||
var currentFile = 0
|
||||
var completionTimeout
|
||||
var commandString = `ffmpeg -y -pattern_type glob -f image2pipe -vcodec mjpeg -r 2 -i - -q:v 1 -c:v libx264 -r 2 "${finalMp4OutputLocation}"`
|
||||
fs.writeFileSync(commandTempLocation,commandString)
|
||||
var videoBuildProcess = spawn('sh',[commandTempLocation])
|
||||
videoBuildProcess.stderr.on('data',function(data){
|
||||
console.log(data.toString())
|
||||
clearTimeout(completionTimeout)
|
||||
completionTimeout = setTimeout(function(){
|
||||
if(currentFile === concatFiles.length - 1){
|
||||
videoBuildProcess.kill('SIGTERM')
|
||||
}
|
||||
},4000)
|
||||
})
|
||||
videoBuildProcess.on('exit',function(data){
|
||||
var timeNow = new Date()
|
||||
var fileStats = fs.statSync(finalMp4OutputLocation)
|
||||
var details = {}
|
||||
s.sqlQuery('INSERT INTO `Files` (ke,mid,details,name,size,time) VALUES (?,?,?,?,?,?)',[ke,mid,s.s(details),finalFileName + '.mp4',fileStats.size,timeNow])
|
||||
s.setDiskUsedForGroup({ke: ke},fileStats.size / 1000000)
|
||||
fs.unlink(commandTempLocation,function(){
|
||||
|
||||
})
|
||||
delete(s.group[ke].mon[mid].buildingTimelapseVideo)
|
||||
})
|
||||
var readFile = function(){
|
||||
var filePath = concatFiles[currentFile]
|
||||
console.log(filePath,currentFile,'/',concatFiles.length - 1)
|
||||
videoBuildProcess.stdin.write(fs.readFileSync(filePath))
|
||||
if(currentFile === concatFiles.length - 1){
|
||||
//is last
|
||||
|
||||
}else{
|
||||
setTimeout(function(){
|
||||
++currentFile
|
||||
readFile()
|
||||
},500)
|
||||
}
|
||||
}
|
||||
readFile()
|
||||
s.group[ke].mon[mid].buildingTimelapseVideo = videoBuildProcess
|
||||
callback({ok: true, fileExists: false, fileLocation: finalMp4OutputLocation, msg: lang['Started Building']})
|
||||
}else{
|
||||
callback({ok: false, fileExists: true, fileLocation: finalMp4OutputLocation, msg: lang['Already exists']})
|
||||
}
|
||||
}else{
|
||||
callback({ok: false, fileExists: false, fileLocation: finalMp4OutputLocation, msg: lang.Building})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ module.exports = function(s,config,lang,io){
|
|||
if(config.renderPaths.dashcam === undefined){config.renderPaths.dashcam='pages/dashcam'}
|
||||
//embeddable widget page
|
||||
if(config.renderPaths.embed === undefined){config.renderPaths.embed='pages/embed'}
|
||||
//timelapse page (not modal)
|
||||
if(config.renderPaths.timelapse === undefined){config.renderPaths.timelapse='pages/timelapse'}
|
||||
//mjpeg full screen page
|
||||
if(config.renderPaths.mjpeg === undefined){config.renderPaths.mjpeg='pages/mjpeg'}
|
||||
//gridstack only page
|
||||
|
|
|
@ -19,7 +19,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
s.renderPage = function(req,res,paths,passables,callback){
|
||||
passables.window = {}
|
||||
passables.originalURL = s.getOriginalUrl(req)
|
||||
passables.config = config
|
||||
passables.config = s.getConfigWithBranding(req.hostname)
|
||||
res.render(paths,passables,callback)
|
||||
}
|
||||
//child node proxy check
|
||||
|
@ -94,7 +94,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
* Page : Login Screen
|
||||
*/
|
||||
app.get(config.webPaths.home, function (req,res){
|
||||
s.renderPage(req,res,config.renderPaths.index,{lang:lang,config:config,screen:'dashboard'},function(err,html){
|
||||
s.renderPage(req,res,config.renderPaths.index,{lang:lang,config: s.getConfigWithBranding(req.hostname),screen:'dashboard'},function(err,html){
|
||||
if(err){
|
||||
s.systemLog(err)
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
* Page : Administrator Login Screen
|
||||
*/
|
||||
app.get(config.webPaths.admin, function (req,res){
|
||||
s.renderPage(req,res,config.renderPaths.index,{lang:lang,config:config,screen:'admin'},function(err,html){
|
||||
s.renderPage(req,res,config.renderPaths.index,{lang:lang,config: s.getConfigWithBranding(req.hostname),screen:'admin'},function(err,html){
|
||||
if(err){
|
||||
s.systemLog(err)
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
*/
|
||||
app.get(config.webPaths.super, function (req,res){
|
||||
|
||||
s.renderPage(req,res,config.renderPaths.index,{lang:lang,config:config,screen:'super'},function(err,html){
|
||||
s.renderPage(req,res,config.renderPaths.index,{lang:lang,config: s.getConfigWithBranding(req.hostname),screen:'super'},function(err,html){
|
||||
if(err){
|
||||
s.systemLog(err)
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
failedLogin: true,
|
||||
message: lang.failedLoginText1,
|
||||
lang: s.copySystemDefaultLanguage(),
|
||||
config: config,
|
||||
config: s.getConfigWithBranding(req.hostname),
|
||||
screen: screenChooser(req.params.screen)
|
||||
},function(err,html){
|
||||
if(err){
|
||||
|
@ -241,7 +241,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
failedLogin: true,
|
||||
message: lang.failedLoginText2,
|
||||
lang: s.copySystemDefaultLanguage(),
|
||||
config: config,
|
||||
config: s.getConfigWithBranding(req.hostname),
|
||||
screen: screenChooser(req.params.screen)
|
||||
},function(err,html){
|
||||
if(err){
|
||||
|
@ -284,7 +284,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"dashcam"],function(err,rr){
|
||||
req.resp.mons=rr;
|
||||
renderPage(config.renderPaths.dashcam,{
|
||||
// config: config,
|
||||
// config: s.getConfigWithBranding(req.hostname),
|
||||
$user: req.resp,
|
||||
lang: r.lang,
|
||||
define: s.getDefinitonFile(r.details.lang),
|
||||
|
@ -296,7 +296,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"socket"],function(err,rr){
|
||||
req.resp.mons=rr;
|
||||
renderPage(config.renderPaths.streamer,{
|
||||
// config: config,
|
||||
// config: s.getConfigWithBranding(req.hostname),
|
||||
$user: req.resp,
|
||||
lang: r.lang,
|
||||
define: s.getDefinitonFile(r.details.lang),
|
||||
|
@ -309,7 +309,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
s.sqlQuery('SELECT uid,mail,details FROM Users WHERE ke=? AND details LIKE \'%"sub"%\'',[r.ke],function(err,rr) {
|
||||
s.sqlQuery('SELECT * FROM Monitors WHERE ke=?',[r.ke],function(err,rrr) {
|
||||
renderPage(config.renderPaths.admin,{
|
||||
config: config,
|
||||
config: s.getConfigWithBranding(req.hostname),
|
||||
$user: req.resp,
|
||||
$subs: rr,
|
||||
$mons: rrr,
|
||||
|
@ -323,7 +323,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
//not admin user
|
||||
renderPage(config.renderPaths.home,{
|
||||
$user:req.resp,
|
||||
config:config,
|
||||
config: s.getConfigWithBranding(req.hostname),
|
||||
lang:r.lang,
|
||||
define:s.getDefinitonFile(r.details.lang),
|
||||
addStorage:s.dir.addStorage,
|
||||
|
@ -336,7 +336,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
default:
|
||||
renderPage(config.renderPaths.home,{
|
||||
$user:req.resp,
|
||||
config:config,
|
||||
config: s.getConfigWithBranding(req.hostname),
|
||||
lang:r.lang,
|
||||
define:s.getDefinitonFile(r.details.lang),
|
||||
addStorage:s.dir.addStorage,
|
||||
|
@ -689,7 +689,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
s.renderPage(req,res,page,{
|
||||
data:Object.assign(req.params,req.query),
|
||||
baseUrl:req.protocol+'://'+req.hostname,
|
||||
config:config,
|
||||
config: s.getConfigWithBranding(req.hostname),
|
||||
lang:user.lang,
|
||||
$user:user,
|
||||
monitors:r,
|
||||
|
@ -1137,7 +1137,13 @@ module.exports = function(s,config,lang,app,io){
|
|||
if(req.params.date.indexOf('-') === -1 && !isNaN(req.params.date)){
|
||||
req.params.date = parseInt(req.params.date)
|
||||
}
|
||||
var selectedDate = new Date(req.params.date)
|
||||
var isMp4Call = false
|
||||
var selectedDate = req.params.date
|
||||
if(typeof req.params.date === 'string' && req.params.date.indexOf('.') > -1){
|
||||
isMp4Call = true
|
||||
selectedDate = req.params.date.split('.')[0]
|
||||
}
|
||||
selectedDate = new Date(selectedDate)
|
||||
var utcSelectedDate = new Date(selectedDate.getTime() + selectedDate.getTimezoneOffset() * 60000)
|
||||
req.query.start = moment(utcSelectedDate).format('YYYY-MM-DD HH:mm:ss')
|
||||
var dayAfter = utcSelectedDate
|
||||
|
@ -1166,13 +1172,33 @@ module.exports = function(s,config,lang,app,io){
|
|||
if(!req.query.limit||req.query.limit==''){req.query.limit=288}
|
||||
req.sql+=' ORDER BY `time` DESC LIMIT '+req.query.limit+'';
|
||||
s.sqlQuery(req.sql,req.ar,function(err,r){
|
||||
if(r && r[0]){
|
||||
r.forEach(function(file){
|
||||
file.details = s.parseJSON(file.details)
|
||||
})
|
||||
res.end(s.prettyPrint(r))
|
||||
if(isMp4Call){
|
||||
if(r && r[0]){
|
||||
s.createVideoFromTimelapse(r,function(response){
|
||||
if(response.fileExists){
|
||||
res.setHeader('Content-Type', 'video/mp4')
|
||||
s.streamMp4FileOverHttp(response.fileLocation,req,res)
|
||||
}else{
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
res.end(s.prettyPrint({
|
||||
ok : response.ok,
|
||||
msg : response.msg,
|
||||
}))
|
||||
}
|
||||
})
|
||||
}else{
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(s.prettyPrint([]))
|
||||
}
|
||||
}else{
|
||||
res.end(s.prettyPrint([]))
|
||||
if(r && r[0]){
|
||||
r.forEach(function(file){
|
||||
file.details = s.parseJSON(file.details)
|
||||
})
|
||||
res.end(s.prettyPrint(r))
|
||||
}else{
|
||||
res.end(s.prettyPrint([]))
|
||||
}
|
||||
}
|
||||
})
|
||||
},res,req);
|
||||
|
@ -1247,6 +1273,30 @@ module.exports = function(s,config,lang,app,io){
|
|||
},res,req);
|
||||
});
|
||||
/**
|
||||
* Page : Get Timelapse Page (Not Modal)
|
||||
*/
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.error('uncaughtExceptioasdasdasdasdasdn',err);
|
||||
});
|
||||
app.get(config.webPaths.apiPrefix+':auth/timelapsePage/:ke', function (req,res){
|
||||
req.params.protocol=req.protocol;
|
||||
s.auth(req.params,function(user){
|
||||
// if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
|
||||
// res.end(user.lang['Not Permitted'])
|
||||
// return
|
||||
// }
|
||||
req.params.uid = user.uid
|
||||
s.renderPage(req,res,config.renderPaths.timelapse,{
|
||||
$user: user,
|
||||
data: req.params,
|
||||
baseUrl: req.protocol+'://'+req.hostname,
|
||||
config: s.getConfigWithBranding(req.hostname),
|
||||
lang: user.lang,
|
||||
originalURL: s.getOriginalUrl(req)
|
||||
})
|
||||
},res,req);
|
||||
});
|
||||
/**
|
||||
* API : Get Events
|
||||
*/
|
||||
app.get([config.webPaths.apiPrefix+':auth/events/:ke',config.webPaths.apiPrefix+':auth/events/:ke/:id',config.webPaths.apiPrefix+':auth/events/:ke/:id/:limit',config.webPaths.apiPrefix+':auth/events/:ke/:id/:limit/:start',config.webPaths.apiPrefix+':auth/events/:ke/:id/:limit/:start/:end'], function (req,res){
|
||||
|
|
|
@ -25,7 +25,7 @@ module.exports = function(s,config,lang,app){
|
|||
if(s.group[req.params.ke]&&s.group[req.params.ke].mon[req.params.id]){
|
||||
if(s.group[req.params.ke].mon[req.params.id].isStarted === true){
|
||||
req.params.uid=user.uid;
|
||||
s.renderPage(req,res,config.renderPaths.embed,{data:req.params,baseUrl:req.protocol+'://'+req.hostname,config:config,lang:user.lang,mon:CircularJSON.parse(CircularJSON.stringify(s.group[req.params.ke].mon_conf[req.params.id])),originalURL:s.getOriginalUrl(req)});
|
||||
s.renderPage(req,res,config.renderPaths.embed,{data:req.params,baseUrl:req.protocol+'://'+req.hostname,config: s.getConfigWithBranding(req.hostname),lang:user.lang,mon:CircularJSON.parse(CircularJSON.stringify(s.group[req.params.ke].mon_conf[req.params.id])),originalURL:s.getOriginalUrl(req)});
|
||||
res.end()
|
||||
}else{
|
||||
res.end(user.lang['Cannot watch a monitor that isn\'t running.'])
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
demo
|
||||
impervious
|
|
@ -76,3 +76,39 @@
|
|||
top:0;
|
||||
left:0;
|
||||
}
|
||||
#timelapsejpeg .playBackView img{
|
||||
width:calc(100% - 40px)
|
||||
}
|
||||
/* stand alone */
|
||||
#timelapsejpeg.standalone {
|
||||
background: #2f2f2f;
|
||||
color:#fff;
|
||||
}
|
||||
#timelapsejpeg.standalone .fieldHolder{
|
||||
padding-top: 20px;
|
||||
}
|
||||
.scroll-style-6::-webkit-scrollbar-track
|
||||
{
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||
background-color: #333;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.scroll-style-6::-webkit-scrollbar
|
||||
{
|
||||
width: 10px;
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.scroll-style-6::-webkit-scrollbar-thumb
|
||||
{
|
||||
background-color: #555;
|
||||
background-image: -webkit-linear-gradient(45deg,
|
||||
rgba(255, 255, 255, .2) 25%,
|
||||
transparent 25%,
|
||||
transparent 50%,
|
||||
rgba(255, 255, 255, .2) 50%,
|
||||
rgba(255, 255, 255, .2) 75%,
|
||||
transparent 75%,
|
||||
transparent)
|
||||
}
|
||||
|
|
|
@ -20,8 +20,13 @@ $.ccio.tm=function(x,d,z,user){
|
|||
d.per=parseInt(d.hr/24*100);
|
||||
d.circle='<div title="at '+d.hr+' hours of '+d.startMoment.format('MMMM DD')+'" '+href+' video="launch" class="progress-circle progress-'+d.per+'"><span>'+d.hr+'</span></div>'
|
||||
tmp+='<li class="video-item glM'+d.mid+user.auth_token+'" auth="'+user.auth_token+'" mid="'+d.mid+'" ke="'+d.ke+'" status="'+d.status+'" status="'+d.status+'" file="'+d.filename+'">'+d.circle+'<div><span title="'+d.endMoment.format()+'" class="livestamp"></span></div><div><div class="small"><b>'+lang.Start+'</b> : '+d.startMoment.format('h:mm:ss , MMMM Do YYYY')+'</div><div class="small"><b>'+lang.End+'</b> : '+d.endMoment.format('h:mm:ss , MMMM Do YYYY')+'</div></div><div><span class="pull-right">'+(parseInt(d.size)/1000000).toFixed(2)+'mb</span><div class="controls btn-group"><a class="btn btn-sm btn-primary" video="launch" '+href+'><i class="fa fa-play-circle"></i></a> <a download="'+d.dlname+'" '+href+' class="btn btn-sm btn-default"><i class="fa fa-download"></i></a>'
|
||||
if($.ccio.DropboxAppKey){ tmp+='<a video="download" host="dropbox" download="'+d.dlname+'" '+href+' class="btn btn-sm btn-default"><i class="fa fa-dropbox"></i></a>' }
|
||||
tmp+='<a title="'+lang['Delete Video']+'" video="delete" href="'+$.ccio.init('videoHrefToDelete',url)+'" class="btn btn-sm btn-danger permission_video_delete"><i class="fa fa-trash"></i></a></div></div></li>';
|
||||
if($.ccio.DropboxAppKey){
|
||||
tmp+='<a video="download" host="dropbox" download="'+d.dlname+'" '+href+' class="btn btn-sm btn-default"><i class="fa fa-dropbox"></i></a>'
|
||||
}
|
||||
if($.ccio.permissionCheck('video_delete',d.mid)){
|
||||
tmp += '<a title="'+lang['Delete Video']+'" video="delete" href="'+$.ccio.init('videoHrefToDelete',url)+'" class="btn btn-sm btn-danger"><i class="fa fa-trash"></i></a>'
|
||||
}
|
||||
tmp += '</div></div></li>';
|
||||
$(z).each(function(n,v){
|
||||
v=$(v);
|
||||
if(v.find('.video-item').length>10){v.find('.video-item:last').remove()}
|
||||
|
|
|
@ -10,10 +10,14 @@ $(document).ready(function(e){
|
|||
$.timelapseJpeg.frameStripContainer = $.timelapseJpeg.e.find('.frameStripContainer')
|
||||
$.timelapseJpeg.playBackViewImg = $.timelapseJpeg.e.find('.playBackView img')
|
||||
$.timelapseJpeg.monitors=$.timelapseJpeg.e.find('.monitors_list')
|
||||
$.timelapseJpeg.pointer = $.ccio.init('location',$user)
|
||||
setTimeout(function(){
|
||||
$.timelapseJpeg.datepicker.val(moment().subtract(1, 'days').format('YYYY-MM-DD')).change()
|
||||
},5000)
|
||||
$.timelapseJpeg.datepicker.daterangepicker({
|
||||
singleDatePicker: true,
|
||||
showDropdowns: true,
|
||||
// startDate: moment().subtract(1, 'days'),
|
||||
// startDate: moment().subtract(2, 'days'),
|
||||
locale: {
|
||||
format: 'YYYY-MM-DD'
|
||||
}
|
||||
|
@ -26,7 +30,7 @@ $(document).ready(function(e){
|
|||
var frameStripHtml = ''
|
||||
var frameIconsHtml = ''
|
||||
var selectedMonitor = $.timelapseJpeg.monitors.val()
|
||||
var apiURL = $.ccio.init('location',$user)+$user.auth_token+'/timelapse/'+$user.ke+'/'+selectedMonitor+'/'+selectedDate
|
||||
var apiURL = $.timelapseJpeg.pointer+$user.auth_token+'/timelapse/'+$user.ke+'/'+selectedMonitor+'/'+selectedDate
|
||||
$.timelapseJpeg.frameStripHrefPrefix = apiURL + '/'
|
||||
$.getJSON(apiURL,function(data){
|
||||
if(data && data[0]){
|
||||
|
@ -37,26 +41,27 @@ $(document).ready(function(e){
|
|||
$.each(data.reverse(),function(n,fileInfo){
|
||||
fileInfo.href = apiURL + '/' + fileInfo.filename
|
||||
fileInfo.number = n
|
||||
// frameStripHtml += '<div class="frame" data-filename="' + fileInfo.filename + '"><img src="' + fileInfo.href + '"></div>'
|
||||
frameStripHtml += '<div class="frame" data-filename="' + fileInfo.filename + '"><img src="' + fileInfo.href + '"></div>'
|
||||
frameIconsHtml += '<div class="col-md-4"><div class="frame" data-filename="' + fileInfo.filename + '" style="background-image:url(\'' + fileInfo.href + '\')"><div class="shade">' + moment(fileInfo.time).format('YYYY-MM-DD HH:mm:ss') + '</div></div></div>'
|
||||
$.timelapseJpeg.playlist[fileInfo.filename] = fileInfo
|
||||
})
|
||||
$.timelapseJpeg.playlistArray = data
|
||||
// $.timelapseJpeg.frameStrip.html(frameStripHtml)
|
||||
$.timelapseJpeg.frameStrip.html(frameStripHtml)
|
||||
$.timelapseJpeg.frameIcons.html(frameIconsHtml)
|
||||
$.timelapseJpeg.resetFilmStripPositions()
|
||||
}else{
|
||||
html = lang['No Data']
|
||||
$.timelapseJpeg.frameStrip.html(html)
|
||||
frameIconsHtml = lang['No Data']
|
||||
$.timelapseJpeg.frameIcons.html(frameIconsHtml)
|
||||
}
|
||||
})
|
||||
}
|
||||
$.timelapseJpeg.fieldHolderCssHeightModifier = 0
|
||||
$.timelapseJpeg.resetFilmStripPositions = function(){
|
||||
// var numberOfFrames = Object.keys($.timelapseJpeg.playlist).length
|
||||
// var frameStripWidth = $.timelapseJpeg.frameStrip.width()
|
||||
// var widthForEachFrame = frameStripWidth / numberOfFrames
|
||||
// $.timelapseJpeg.frameStrip.find('.frame').css('width',widthForEachFrame)
|
||||
var fieldHolderHeight = $.timelapseJpeg.fieldHolder.height()
|
||||
var numberOfFrames = Object.keys($.timelapseJpeg.playlist).length
|
||||
var frameStripWidth = $.timelapseJpeg.frameStrip.width()
|
||||
var widthForEachFrame = frameStripWidth / numberOfFrames
|
||||
$.timelapseJpeg.frameStrip.find('.frame').css('width',widthForEachFrame)
|
||||
var fieldHolderHeight = $.timelapseJpeg.fieldHolder.height() + $.timelapseJpeg.fieldHolderCssHeightModifier
|
||||
console.log("calc(100% - " + fieldHolderHeight + "px)")
|
||||
$.timelapseJpeg.frameIcons.css({height:"calc(100% - " + fieldHolderHeight + "px)"})
|
||||
}
|
||||
|
@ -68,8 +73,8 @@ $(document).ready(function(e){
|
|||
var selectedFrame = $.timelapseJpeg.playlist[$.timelapseJpeg.frameSelected]
|
||||
var selectedFrameNumber = $.timelapseJpeg.playlist[$.timelapseJpeg.frameSelected].number
|
||||
$.timelapseJpeg.setPlayBackFrame(selectedFrame.href)
|
||||
// $.timelapseJpeg.frameStrip.find(`.frameStrip .frame.selected`).removeClass('selected')
|
||||
// $.timelapseJpeg.frameStrip.find(`.frameStrip .frame[data-filename="${selectedFrame.filename}"]`).addClass('selected')
|
||||
$.timelapseJpeg.frameStrip.find(`.frameStrip .frame.selected`).removeClass('selected')
|
||||
$.timelapseJpeg.frameStrip.find(`.frameStrip .frame[data-filename="${selectedFrame.filename}"]`).addClass('selected')
|
||||
clearTimeout($.timelapseJpeg.playIntervalTimer)
|
||||
$.timelapseJpeg.playIntervalTimer = setTimeout(function(){
|
||||
++selectedFrameNumber
|
||||
|
@ -116,6 +121,9 @@ $(document).ready(function(e){
|
|||
// $.timelapseJpeg.e.on('mouseout','.frame',function(e){
|
||||
//
|
||||
// })
|
||||
$.timelapseJpeg.e.on('shown.bs.modal', function (e) {
|
||||
$.timelapseJpeg.datepicker.change()
|
||||
})
|
||||
$.timelapseJpeg.e.on('hidden.bs.modal', function (e) {
|
||||
$.timelapseJpeg.destroy()
|
||||
})
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<%
|
||||
if(!window.libURL)window.libURL = originalURL
|
||||
%>
|
||||
<link rel="icon" href="<%-window.libURL%>libs/img/icon/favicon.ico" type="image/x-icon" />
|
||||
<link rel="shortcut icon" href="<%-window.libURL%>libs/img/icon/favicon.ico" type="image/x-icon" />
|
||||
<link rel="icon" href="<%-window.libURL%><%-config.webFavicon%>" type="image/x-icon" />
|
||||
<link rel="shortcut icon" href="<%-window.libURL%><%-config.webFavicon%>" type="image/x-icon" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="Shinobi">
|
||||
<meta name="apple-mobile-web-app-title" content="<%-config.webPageTitle%>">
|
||||
<link rel="apple-touch-icon" href="<%-window.libURL%>libs/img/icon/apple-touch-icon.png" />
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="<%-window.libURL%>libs/img/icon/apple-touch-icon-57x57.png" />
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="<%-window.libURL%>libs/img/icon/apple-touch-icon-72x72.png" />
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
var attributes = []
|
||||
var styles = []
|
||||
var sectionClass = []
|
||||
var headerTitle = userSettings.headerTitle || lang[userSettings.name]
|
||||
var headerTitle = userSettings.headerTitle || lang[userSettings.name] || userSettings.name
|
||||
if(userSettings.hidden === true){
|
||||
styles.push('display:none')
|
||||
}
|
||||
|
@ -71,7 +71,13 @@
|
|||
if(userSettings.id){
|
||||
attributes.push(`id="${userSettings.id}"`)
|
||||
}else{
|
||||
var userSettingsId = userSettings.name.replace(/[^a-zA-Z ]/g, '').replace(/[^a-zA-Z ]/g, '').replace(/ /g, '')
|
||||
var userSettingsId
|
||||
if(userSettings.name){
|
||||
userSettingsId = userSettings.name.replace(/[^a-zA-Z ]/g, '').replace(/[^a-zA-Z ]/g, '').replace(/ /g, '')
|
||||
}else{
|
||||
userSettingsId = "NO NAME"
|
||||
}
|
||||
userSettings.id = userSettingsId
|
||||
attributes.push(`id="${userSettingsId}"`)
|
||||
}
|
||||
if(userSettings.color){
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="panel panel-login">
|
||||
<% if(config.showLoginCardHeader){
|
||||
<% if(config.showLoginCardHeader === true){
|
||||
var logoImageLink
|
||||
if(config.logoLocation76x76.indexOf('//') === -1){
|
||||
logoImageLink = window.libURL + config.logoLocation76x76
|
||||
|
@ -45,36 +45,52 @@
|
|||
<div class="form-group f_i_input f_i_ldap" style="display:none">
|
||||
<input name="key" id="key" tabindex="2" class="monospace form-control" placeholder="Group Key">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-12 monospace" style="width:calc(100% - 48px)">
|
||||
<select class="form-control" name="function" selector="f_i">
|
||||
<% switch(screen){
|
||||
case'super': %>
|
||||
<option value="super"><%- lang.Superuser %></option>
|
||||
<% break;
|
||||
case'admin': %>
|
||||
<option value="admin"><%- lang.Admin %></option>
|
||||
<% break;
|
||||
default: %>
|
||||
<option value="dash" selected><%- lang.Dashboard %></option>
|
||||
<% if(config.productType==='Pro'){ %>
|
||||
<option value="ldap"><%- lang.LDAP %></option>
|
||||
<% } %>
|
||||
<option value="streamer"><%- lang.Streamer %></option>
|
||||
<option value="cam"><%- lang.Dashcam %> (<%- lang.Streamer %> v2)</option>
|
||||
<% break;
|
||||
} %>
|
||||
</select>
|
||||
</div>
|
||||
<div class="text-right" title="<%- lang['Remember Me'] %>" style="display:inline-block">
|
||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="remember_me">
|
||||
<input type="checkbox" id="remember_me" value="1" name="remember" class="mdl-switch__input">
|
||||
<span class="monospace mdl-switch__label"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if(config.showLoginSelector === true){ %>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-12 monospace" style="width:calc(100% - 48px)">
|
||||
<select class="form-control" name="function" selector="f_i">
|
||||
<% switch(screen){
|
||||
case'super': %>
|
||||
<option value="super"><%- lang.Superuser %></option>
|
||||
<% break;
|
||||
case'admin': %>
|
||||
<option value="admin"><%- lang.Admin %></option>
|
||||
<% break;
|
||||
default: %>
|
||||
<option value="dash" selected><%- lang.Dashboard %></option>
|
||||
<% if(config.productType==='Pro'){ %>
|
||||
<option value="ldap"><%- lang.LDAP %></option>
|
||||
<% } %>
|
||||
<option value="streamer"><%- lang.Streamer %></option>
|
||||
<option value="cam"><%- lang.Dashcam %> (<%- lang.Streamer %> v2)</option>
|
||||
<% break;
|
||||
} %>
|
||||
</select>
|
||||
</div>
|
||||
<div class="text-right" title="<%- lang['Remember Me'] %>" style="display:inline-block">
|
||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="remember_me">
|
||||
<input type="checkbox" id="remember_me" value="1" name="remember" class="mdl-switch__input">
|
||||
<span class="monospace mdl-switch__label"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }else{ %>
|
||||
<select class="form-control" name="function" style="display:none">
|
||||
<% switch(screen){
|
||||
case'super': %>
|
||||
<option value="super"><%- lang.Superuser %></option>
|
||||
<% break;
|
||||
case'admin': %>
|
||||
<option value="admin"><%- lang.Admin %></option>
|
||||
<% break;
|
||||
default: %>
|
||||
<option value="dash" selected><%- lang.Dashboard %></option>
|
||||
<% break;
|
||||
} %>
|
||||
</select>
|
||||
<% } %>
|
||||
<div class="form-group" style="margin:0">
|
||||
<button type="submit" name="login-submit" id="login-submit" tabindex="4" class="btn btn-success btn-block"><%- lang.Login %></button>
|
||||
</div>
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css" />
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/pnotify.custom.min.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/now-ui-kit.css?v=1.1.0" />
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.basic.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.forms.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/super-page.css" />
|
||||
<script src="<%-window.libURL%>libs/js/jquery.min.js"></script>
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
<%
|
||||
if(config.ssl&&config.ssl.port&&data.protocol==='https'){
|
||||
data.port=config.ssl.port
|
||||
}else{
|
||||
data.port=config.port
|
||||
}
|
||||
data.url = baseUrl
|
||||
if(data.addon && data.addon.indexOf('relative')>-1){
|
||||
data.url=''
|
||||
}
|
||||
%>
|
||||
<link rel="stylesheet" href="<%=data.url%>/libs/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="<%=data.url%>/libs/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/daterangepicker.css">
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/dash2.basic.css">
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/dash2.forms.css">
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/dash2.darktheme.css">
|
||||
|
||||
|
||||
<div id="timelapsejpeg" class="standalone dark">
|
||||
<div class="modal-body text-center" style="padding-top:0;padding-bottom:0;">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="fieldHolder text-left">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Monitor']%></span></div>
|
||||
<div><select class="form-control dark monitors_list"></select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Date']%></span></div>
|
||||
<div><input type="text" id="timelapsejpeg_date" class="form-control" value="" /></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="">
|
||||
</div>
|
||||
<div class="frameIcons row scroll-style-6"></div>
|
||||
</div>
|
||||
<div class="col-md-8 frameStripContainer contained">
|
||||
<div class="playBackView"><img></div>
|
||||
<!-- <div class="frames"></div>
|
||||
<div class="frameStripPreview"></div>
|
||||
<div class="frameStrip"></div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="<%=data.url%>/libs/js/jquery.min.js"></script>
|
||||
<script src="<%=data.url%>/libs/js/jquery-ui.min.js"></script>
|
||||
<script>$.ccio = {mon:{}}</script>
|
||||
<script><% include ../libs/js/moment.js %></script>
|
||||
<script src="<%-data.url%>/libs/js/daterangepicker.js"></script>
|
||||
<script src="<%-data.url%>/libs/js/dash2.init.js"></script>
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/dash2.timelapse.jpeg.css">
|
||||
<script src="<%-data.url%>/libs/js/dash2.timelapse.jpeg.js"></script>
|
||||
<script>
|
||||
var data = <%- JSON.stringify(data) %>
|
||||
var $user = <%- JSON.stringify($user) %>
|
||||
var lang = <%- JSON.stringify(lang) %>
|
||||
$user.auth_token = data.auth
|
||||
$(document).ready(function(){
|
||||
$.timelapseJpeg.pointer = data.url + '/'
|
||||
$.timelapseJpeg.fieldHolderCssHeightModifier = 50
|
||||
$.timelapseJpeg.monitors.find('.monitor').remove()
|
||||
$.getJSON(data.url+'/'+$user.auth_token+'/monitor/'+$user.ke,function(d){
|
||||
console.log(d)
|
||||
$.each(d,function(n,monitor){
|
||||
$.ccio.mon[monitor.ke + monitor.mid + $user.auth_token] = monitor
|
||||
})
|
||||
$.each($.ccio.mon,function(n,v){
|
||||
$.timelapseJpeg.monitors.append('<option class="monitor" value="'+v.mid+'">'+v.name+'</option>')
|
||||
})
|
||||
$.timelapseJpeg.monitors.find('.monitor').prop('selected',false)
|
||||
// if(monitor.mid !== ''){
|
||||
// $.timelapseJpeg.monitors.find('.monitor[value="'+e.mid+'"]')
|
||||
// }
|
||||
})
|
||||
})
|
||||
</script>
|
Loading…
Reference in New Issue