Compare commits
29 Commits
1.36.12_he
...
release-1.
Author | SHA1 | Date |
---|---|---|
Isaac Connor | bdb9acc0fe | |
Isaac Connor | 484827bdeb | |
Isaac Connor | aaf391fc65 | |
Isaac Connor | 8822463ac7 | |
Isaac Connor | 9cc17024c5 | |
Isaac Connor | 687818e1ec | |
Isaac Connor | 3abacfa488 | |
Isaac Connor | 66336106ca | |
Isaac Connor | 2396e98fb9 | |
Isaac Connor | 6268652520 | |
Isaac Connor | b10bb9d8b0 | |
Isaac Connor | 2b0398b35a | |
Isaac Connor | 5b9ccc6889 | |
Isaac Connor | 9973b1fbaf | |
Isaac Connor | df16099463 | |
Isaac Connor | b28f97c5c3 | |
Isaac Connor | 4501a7c2a1 | |
Isaac Connor | 0125efb93e | |
Isaac Connor | 1bdb4f302c | |
Isaac Connor | df7e34a51d | |
Isaac Connor | 988f118ba9 | |
Isaac Connor | ae17b2316e | |
Isaac Connor | 8891feec74 | |
Isaac Connor | 42d5101f08 | |
Isaac Connor | 01030e9850 | |
Isaac Connor | 9893d37bf1 | |
makers-mark | 9f8fc65cd3 | |
Isaac Connor | 4a51253aa9 | |
Isaac Connor | 3ee649406c |
|
@ -56,7 +56,7 @@ EXECUTE stmt;
|
||||||
SET @s = (SELECT IF(
|
SET @s = (SELECT IF(
|
||||||
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
AND table_name = 'Monitor_Status'
|
AND table_name = 'Monitor_Status'
|
||||||
AND column_name = 'DayEvents'
|
AND column_name = 'DayEventDiskSpace'
|
||||||
) > 0,
|
) > 0,
|
||||||
"ALTER TABLE `Monitor_Status` DROP `DayEventDiskSpace`",
|
"ALTER TABLE `Monitor_Status` DROP `DayEventDiskSpace`",
|
||||||
"SELECT 'Column DayEventDiskSpace already removed from Monitor_Status'"
|
"SELECT 'Column DayEventDiskSpace already removed from Monitor_Status'"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit cd7fd49becad6010a1b8466bfebbd93999a39878
|
Subproject commit eab32851421ffe54fec0229c3efc44c642bc8d46
|
|
@ -51,11 +51,21 @@ sub open {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
$self->loadMonitor();
|
$self->loadMonitor();
|
||||||
if ( $self->{Monitor}->{ControlAddress} !~ /^\w+:\/\// ) {
|
|
||||||
# Has no scheme at the beginning, so won't parse as a URI
|
if ($self->{Monitor}->{ControlAddress} and ($self->{Monitor}->{ControlAddress} ne 'user:pass@ip')) {
|
||||||
$self->{Monitor}->{ControlAddress} = 'http://'.$self->{Monitor}->{ControlAddress};
|
Debug("Getting connection details from Control Address " . $self->{Monitor}->{ControlAddress});
|
||||||
}
|
if ( $self->{Monitor}->{ControlAddress} !~ /^\w+:\/\// ) {
|
||||||
$uri = URI->new($self->{Monitor}->{ControlAddress});
|
# Has no scheme at the beginning, so won't parse as a URI
|
||||||
|
$self->{Monitor}->{ControlAddress} = 'http://'.$self->{Monitor}->{ControlAddress};
|
||||||
|
}
|
||||||
|
$uri = URI->new($self->{Monitor}->{ControlAddress});
|
||||||
|
} elsif ($self->{Monitor}->{Path}) {
|
||||||
|
Debug("Getting connection details from Path " . $self->{Monitor}->{Path});
|
||||||
|
$uri = URI->new($self->{Monitor}->{Path});
|
||||||
|
$uri->scheme('http');
|
||||||
|
$uri->port(80);
|
||||||
|
$uri->path('');
|
||||||
|
}
|
||||||
|
|
||||||
use LWP::UserAgent;
|
use LWP::UserAgent;
|
||||||
$self->{ua} = LWP::UserAgent->new;
|
$self->{ua} = LWP::UserAgent->new;
|
||||||
|
@ -64,6 +74,7 @@ sub open {
|
||||||
$self->{state} = 'closed';
|
$self->{state} = 'closed';
|
||||||
|
|
||||||
my ( $username, $password, $host ) = ( $uri->authority() =~ /^([^:]+):([^@]*)@(.+)$/ );
|
my ( $username, $password, $host ) = ( $uri->authority() =~ /^([^:]+):([^@]*)@(.+)$/ );
|
||||||
|
Debug("Have username: $username password: $password host: $host from authority:" . $uri->authority());
|
||||||
|
|
||||||
$uri->userinfo(undef);
|
$uri->userinfo(undef);
|
||||||
|
|
||||||
|
@ -75,40 +86,47 @@ sub open {
|
||||||
# test auth
|
# test auth
|
||||||
my $res = $self->{ua}->get($uri->canonical().$url);
|
my $res = $self->{ua}->get($uri->canonical().$url);
|
||||||
|
|
||||||
if ( $res->is_success ) {
|
if ($res->is_success) {
|
||||||
if ( $res->content() ne "Properties.PTZ.PTZ=yes\n" ) {
|
if ($res->content() ne "Properties.PTZ.PTZ=yes\n") {
|
||||||
Warning('Response suggests that camera doesn\'t support PTZ. Content:('.$res->content().')');
|
Warning('Response suggests that camera doesn\'t support PTZ. Content:('.$res->content().')');
|
||||||
}
|
}
|
||||||
$self->{state} = 'open';
|
$self->{state} = 'open';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ($res->status_line() eq '404 Not Found') {
|
||||||
|
#older style
|
||||||
|
$url = 'axis-cgi/com/ptz.cgi';
|
||||||
|
$res = $self->{ua}->get($uri->canonical().$url);
|
||||||
|
Debug("Result from getting ".$uri->canonical().$url . ':' . $res->status_line());
|
||||||
|
}
|
||||||
|
|
||||||
if ( $res->status_line() eq '401 Unauthorized' ) {
|
if ($res->status_line() eq '401 Unauthorized') {
|
||||||
|
|
||||||
my $headers = $res->headers();
|
my $headers = $res->headers();
|
||||||
foreach my $k ( keys %$headers ) {
|
foreach my $k ( keys %$headers ) {
|
||||||
Debug("Initial Header $k => $$headers{$k}");
|
Debug("Initial Header $k => $$headers{$k}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $$headers{'www-authenticate'} ) {
|
if ( $$headers{'www-authenticate'} ) {
|
||||||
my ( $auth, $tokens ) = $$headers{'www-authenticate'} =~ /^(\w+)\s+(.*)$/;
|
foreach my $auth_header ( ref $$headers{'www-authenticate'} eq 'ARRAY' ? @{$$headers{'www-authenticate'}} : ($$headers{'www-authenticate'})) {
|
||||||
if ( $tokens =~ /\w+="([^"]+)"/i ) {
|
my ( $auth, $tokens ) = $auth_header =~ /^(\w+)\s+(.*)$/;
|
||||||
if ( $realm ne $1 ) {
|
if ( $tokens =~ /\w+="([^"]+)"/i ) {
|
||||||
$realm = $1;
|
if ( $realm ne $1 ) {
|
||||||
$self->{ua}->credentials($uri->host_port(), $realm, $username, $password);
|
$realm = $1;
|
||||||
$res = $self->{ua}->get($uri->canonical().$url);
|
$self->{ua}->credentials($uri->host_port(), $realm, $username, $password);
|
||||||
if ( $res->is_success() ) {
|
$res = $self->{ua}->get($uri->canonical().$url);
|
||||||
Info("Auth succeeded after setting realm to $realm. You can set this value in the Control Device field to speed up connections and remove these log entries.");
|
if ( $res->is_success() ) {
|
||||||
$self->{state} = 'open';
|
Info("Auth succeeded after setting realm to $realm. You can set this value in the Control Device field to speed up connections and remove these log entries.");
|
||||||
return;
|
$self->{state} = 'open';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Error('Authentication still failed after updating REALM status: '.$res->status_line);
|
||||||
|
} else {
|
||||||
|
Error('Authentication failed, not a REALM problem');
|
||||||
}
|
}
|
||||||
Error('Authentication still failed after updating REALM status: '.$res->status_line);
|
|
||||||
} else {
|
} else {
|
||||||
Error('Authentication failed, not a REALM problem');
|
Error('Failed to match realm in tokens');
|
||||||
}
|
} # end if
|
||||||
} else {
|
} # end foreach auth header
|
||||||
Error('Failed to match realm in tokens');
|
|
||||||
} # end if
|
|
||||||
} else {
|
} else {
|
||||||
Debug('No headers line');
|
Debug('No headers line');
|
||||||
} # end if headers
|
} # end if headers
|
||||||
|
|
|
@ -244,6 +244,7 @@ class Socket : public CommsBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ssize_t recv(std::string &msg) const {
|
virtual ssize_t recv(std::string &msg) const {
|
||||||
|
msg.reserve(ZM_NETWORK_BUFSIZ);
|
||||||
std::vector<char> buffer(msg.capacity());
|
std::vector<char> buffer(msg.capacity());
|
||||||
ssize_t nBytes;
|
ssize_t nBytes;
|
||||||
if ((nBytes = ::recv(mSd, buffer.data(), buffer.size(), 0)) < 0) {
|
if ((nBytes = ::recv(mSd, buffer.data(), buffer.size(), 0)) < 0) {
|
||||||
|
|
|
@ -107,8 +107,8 @@ bool zmDbConnect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmDbClose() {
|
void zmDbClose() {
|
||||||
|
std::lock_guard<std::mutex> lck(db_mutex);
|
||||||
if (zmDbConnected) {
|
if (zmDbConnected) {
|
||||||
std::lock_guard<std::mutex> lck(db_mutex);
|
|
||||||
mysql_close(&dbconn);
|
mysql_close(&dbconn);
|
||||||
// mysql_init() call implicitly mysql_library_init() but
|
// mysql_init() call implicitly mysql_library_init() but
|
||||||
// mysql_close() does not call mysql_library_end()
|
// mysql_close() does not call mysql_library_end()
|
||||||
|
@ -237,8 +237,12 @@ zmDbQueue::~zmDbQueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmDbQueue::stop() {
|
void zmDbQueue::stop() {
|
||||||
mTerminate = true;
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mMutex);
|
||||||
|
mTerminate = true;
|
||||||
|
}
|
||||||
mCondition.notify_all();
|
mCondition.notify_all();
|
||||||
|
|
||||||
if (mThread.joinable()) mThread.join();
|
if (mThread.joinable()) mThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -295,8 +295,8 @@ void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
|
||||||
Debug(1, "ids [0x%x]", st->id);
|
Debug(1, "ids [0x%x]", st->id);
|
||||||
if (lang)
|
if (lang)
|
||||||
Debug(1, "language (%s)", lang->value);
|
Debug(1, "language (%s)", lang->value);
|
||||||
Debug(1, "frames:%d, frame_size:%d stream timebase: %d/%d",
|
Debug(1, "frame_size:%d stream timebase: %d/%d",
|
||||||
st->codec_info_nb_frames, codec->frame_size,
|
codec->frame_size,
|
||||||
st->time_base.num, st->time_base.den
|
st->time_base.num, st->time_base.den
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1175,7 +1175,7 @@ void Monitor::AddPrivacyBitmask() {
|
||||||
|
|
||||||
int Monitor::GetImage(int32_t index, int scale) {
|
int Monitor::GetImage(int32_t index, int scale) {
|
||||||
if (index < 0 || index > image_buffer_count) {
|
if (index < 0 || index > image_buffer_count) {
|
||||||
Warning("Invalid index %d passed. image_buffer_count = %d", index, image_buffer_count);
|
Debug(1, "Invalid index %d passed. image_buffer_count = %d", index, image_buffer_count);
|
||||||
index = shared_data->last_write_index;
|
index = shared_data->last_write_index;
|
||||||
}
|
}
|
||||||
if (!image_buffer.size() or static_cast<size_t>(index) >= image_buffer.size()) {
|
if (!image_buffer.size() or static_cast<size_t>(index) >= image_buffer.size()) {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "zm_config.h"
|
#include "zm_config.h"
|
||||||
#include "zm_monitor.h"
|
#include "zm_monitor.h"
|
||||||
#include "zm_packet.h"
|
#include "zm_packet.h"
|
||||||
|
#include "zm_signal.h"
|
||||||
|
|
||||||
#if HAVE_LIBAVFORMAT
|
#if HAVE_LIBAVFORMAT
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ int RemoteCameraRtsp::Disconnect() {
|
||||||
|
|
||||||
int RemoteCameraRtsp::PrimeCapture() {
|
int RemoteCameraRtsp::PrimeCapture() {
|
||||||
Debug(2, "Waiting for sources");
|
Debug(2, "Waiting for sources");
|
||||||
for ( int i = 0; (i < 100) && !rtspThread->hasSources(); i++ ) {
|
for ( int i = 100; i &&zm_terminate && !rtspThread->hasSources(); i-- ) {
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
}
|
}
|
||||||
if ( !rtspThread->hasSources() ) {
|
if ( !rtspThread->hasSources() ) {
|
||||||
|
@ -169,8 +170,10 @@ int RemoteCameraRtsp::PrimeCapture() {
|
||||||
}
|
}
|
||||||
} // end foreach stream
|
} // end foreach stream
|
||||||
|
|
||||||
if ( mVideoStreamId == -1 )
|
if ( mVideoStreamId == -1 ) {
|
||||||
Fatal("Unable to locate video stream");
|
Error("Unable to locate video stream");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if ( mAudioStreamId == -1 )
|
if ( mAudioStreamId == -1 )
|
||||||
Debug(3, "Unable to locate audio stream");
|
Debug(3, "Unable to locate audio stream");
|
||||||
|
|
||||||
|
@ -184,8 +187,10 @@ int RemoteCameraRtsp::PrimeCapture() {
|
||||||
|
|
||||||
// Find the decoder for the video stream
|
// Find the decoder for the video stream
|
||||||
AVCodec *codec = avcodec_find_decoder(mVideoCodecContext->codec_id);
|
AVCodec *codec = avcodec_find_decoder(mVideoCodecContext->codec_id);
|
||||||
if ( codec == nullptr )
|
if ( codec == nullptr ) {
|
||||||
Panic("Unable to locate codec %d decoder", mVideoCodecContext->codec_id);
|
Error("Unable to locate codec %d decoder", mVideoCodecContext->codec_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Open codec
|
// Open codec
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
|
||||||
|
@ -193,7 +198,10 @@ int RemoteCameraRtsp::PrimeCapture() {
|
||||||
#else
|
#else
|
||||||
if ( avcodec_open2(mVideoCodecContext, codec, 0) < 0 )
|
if ( avcodec_open2(mVideoCodecContext, codec, 0) < 0 )
|
||||||
#endif
|
#endif
|
||||||
Panic("Can't open codec");
|
{
|
||||||
|
Error("Can't open codec");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
int pSize = av_image_get_buffer_size(imagePixFormat, width, height, 1);
|
int pSize = av_image_get_buffer_size(imagePixFormat, width, height, 1);
|
||||||
|
@ -202,7 +210,8 @@ int RemoteCameraRtsp::PrimeCapture() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( (unsigned int)pSize != imagesize ) {
|
if ( (unsigned int)pSize != imagesize ) {
|
||||||
Fatal("Image size mismatch. Required: %d Available: %llu", pSize, imagesize);
|
Error("Image size mismatch. Required: %d Available: %llu", pSize, imagesize);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -221,18 +230,13 @@ int RemoteCameraRtsp::PreCapture() {
|
||||||
int RemoteCameraRtsp::Capture(std::shared_ptr<ZMPacket> &zm_packet) {
|
int RemoteCameraRtsp::Capture(std::shared_ptr<ZMPacket> &zm_packet) {
|
||||||
int frameComplete = false;
|
int frameComplete = false;
|
||||||
AVPacket *packet = &zm_packet->packet;
|
AVPacket *packet = &zm_packet->packet;
|
||||||
if ( !zm_packet->image ) {
|
|
||||||
Debug(1, "Allocating image %dx%d %d colours %d", width, height, colours, subpixelorder);
|
|
||||||
zm_packet->image = new Image(width, height, colours, subpixelorder);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
while (!frameComplete) {
|
while (!frameComplete) {
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
if (!rtspThread || rtspThread->IsStopped())
|
if (!rtspThread || rtspThread->IsStopped())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ( rtspThread->getFrame(buffer) ) {
|
if (rtspThread->getFrame(buffer)) {
|
||||||
Debug(3, "Read frame %d bytes", buffer.size());
|
Debug(3, "Read frame %d bytes", buffer.size());
|
||||||
Hexdump(4, buffer.head(), 16);
|
Hexdump(4, buffer.head(), 16);
|
||||||
|
|
||||||
|
@ -267,49 +271,20 @@ int RemoteCameraRtsp::Capture(std::shared_ptr<ZMPacket> &zm_packet) {
|
||||||
|
|
||||||
//while ( (!frameComplete) && (buffer.size() > 0) ) {
|
//while ( (!frameComplete) && (buffer.size() > 0) ) {
|
||||||
if ( buffer.size() > 0 ) {
|
if ( buffer.size() > 0 ) {
|
||||||
packet->data = buffer.head();
|
packet->data = (uint8_t*)av_malloc(buffer.size());
|
||||||
|
memcpy(packet->data, buffer.head(), buffer.size());
|
||||||
|
//packet->data = buffer.head();
|
||||||
packet->size = buffer.size();
|
packet->size = buffer.size();
|
||||||
bytes += packet->size;
|
bytes += packet->size;
|
||||||
|
buffer -= packet->size;
|
||||||
|
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, nullptr);
|
||||||
packet->pts = packet->dts = now.tv_sec*1000000+now.tv_usec;
|
packet->pts = packet->dts = now.tv_sec*1000000+now.tv_usec;
|
||||||
|
zm_packet->codec_type = mVideoCodecContext->codec_type;
|
||||||
int bytes_consumed = zm_packet->decode(mVideoCodecContext);
|
zm_packet->stream = mVideoStream;
|
||||||
if ( bytes_consumed < 0 ) {
|
frameComplete = true;
|
||||||
Error("Error while decoding frame %d", frameCount);
|
Debug(2, "Frame: %d - %d/%d", frameCount, packet->size, buffer.size());
|
||||||
//Hexdump(Logger::ERROR, buffer.head(), buffer.size()>256?256:buffer.size());
|
|
||||||
}
|
|
||||||
buffer -= packet->size;
|
|
||||||
if ( bytes_consumed ) {
|
|
||||||
zm_dump_video_frame(zm_packet->in_frame, "remote_rtsp_decode");
|
|
||||||
if ( ! mVideoStream->
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
|
||||||
codecpar
|
|
||||||
#else
|
|
||||||
codec
|
|
||||||
#endif
|
|
||||||
->width ) {
|
|
||||||
zm_dump_codec(mVideoCodecContext);
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
|
||||||
zm_dump_codecpar(mVideoStream->codecpar);
|
|
||||||
mVideoStream->codecpar->width = zm_packet->in_frame->width;
|
|
||||||
mVideoStream->codecpar->height = zm_packet->in_frame->height;
|
|
||||||
#else
|
|
||||||
mVideoStream->codec->width = zm_packet->in_frame->width;
|
|
||||||
mVideoStream->codec->height = zm_packet->in_frame->height;
|
|
||||||
#endif
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
|
||||||
zm_dump_codecpar(mVideoStream->codecpar);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
zm_packet->codec_type = mVideoCodecContext->codec_type;
|
|
||||||
zm_packet->stream = mVideoStream;
|
|
||||||
frameComplete = true;
|
|
||||||
Debug(2, "Frame: %d - %d/%d", frameCount, bytes_consumed, buffer.size());
|
|
||||||
packet->data = nullptr;
|
|
||||||
packet->size = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} /* getFrame() */
|
} /* getFrame() */
|
||||||
} // end while true
|
} // end while true
|
||||||
|
|
|
@ -279,7 +279,7 @@ void RtpCtrlThread::Run() {
|
||||||
time_t last_receive = time(nullptr);
|
time_t last_receive = time(nullptr);
|
||||||
bool timeout = false; // used as a flag that we had a timeout, and then sent an RR to see if we wake back up. Real timeout will happen when this is true.
|
bool timeout = false; // used as a flag that we had a timeout, and then sent an RR to see if we wake back up. Real timeout will happen when this is true.
|
||||||
|
|
||||||
while (!mTerminate && select.wait() >= 0) {
|
while (!mTerminate && (select.wait() >= 0)) {
|
||||||
time_t now = time(nullptr);
|
time_t now = time(nullptr);
|
||||||
ZM::Select::CommsList readable = select.getReadable();
|
ZM::Select::CommsList readable = select.getReadable();
|
||||||
if ( readable.size() == 0 ) {
|
if ( readable.size() == 0 ) {
|
||||||
|
|
|
@ -47,8 +47,10 @@ RtpSource::RtpSource(
|
||||||
mFrame(65536),
|
mFrame(65536),
|
||||||
mFrameCount(0),
|
mFrameCount(0),
|
||||||
mFrameGood(true),
|
mFrameGood(true),
|
||||||
|
prevM(false),
|
||||||
mFrameReady(false),
|
mFrameReady(false),
|
||||||
mFrameProcessed(false)
|
mFrameProcessed(false),
|
||||||
|
mTerminate(false)
|
||||||
{
|
{
|
||||||
char hostname[256] = "";
|
char hostname[256] = "";
|
||||||
gethostname(hostname, sizeof(hostname));
|
gethostname(hostname, sizeof(hostname));
|
||||||
|
|
|
@ -92,8 +92,6 @@ private:
|
||||||
bool mFrameGood;
|
bool mFrameGood;
|
||||||
bool prevM;
|
bool prevM;
|
||||||
|
|
||||||
bool mTerminate;
|
|
||||||
|
|
||||||
bool mFrameReady;
|
bool mFrameReady;
|
||||||
std::condition_variable mFrameReadyCv;
|
std::condition_variable mFrameReadyCv;
|
||||||
std::mutex mFrameReadyMutex;
|
std::mutex mFrameReadyMutex;
|
||||||
|
@ -101,6 +99,7 @@ private:
|
||||||
bool mFrameProcessed;
|
bool mFrameProcessed;
|
||||||
std::condition_variable mFrameProcessedCv;
|
std::condition_variable mFrameProcessedCv;
|
||||||
std::mutex mFrameProcessedMutex;
|
std::mutex mFrameProcessedMutex;
|
||||||
|
bool mTerminate;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(uint16_t seq);
|
void init(uint16_t seq);
|
||||||
|
|
|
@ -486,7 +486,7 @@ int main(int argc, char *argv[]) {
|
||||||
exit_zmu(-1);
|
exit_zmu(-1);
|
||||||
}
|
}
|
||||||
if ( !ValidateAccess(user, mon_id, function) ) {
|
if ( !ValidateAccess(user, mon_id, function) ) {
|
||||||
Error("Insufficient privileges for requested action");
|
Error("Insufficient privileges for user %s for requested function %x", username, function);
|
||||||
exit_zmu(-1);
|
exit_zmu(-1);
|
||||||
}
|
}
|
||||||
} // end if auth
|
} // end if auth
|
||||||
|
@ -730,7 +730,7 @@ int main(int argc, char *argv[]) {
|
||||||
if ( function & ZMU_QUERY ) {
|
if ( function & ZMU_QUERY ) {
|
||||||
#if ZM_HAS_V4L
|
#if ZM_HAS_V4L
|
||||||
char vidString[0x10000] = "";
|
char vidString[0x10000] = "";
|
||||||
bool ok = LocalCamera::GetCurrentSettings(device.c_str(), vidString, v4lVersion, verbose);
|
bool ok = LocalCamera::GetCurrentSettings(device.empty()?nullptr:device.c_str(), vidString, v4lVersion, verbose);
|
||||||
printf("%s", vidString);
|
printf("%s", vidString);
|
||||||
exit_zmu(ok ? 0 : -1);
|
exit_zmu(ok ? 0 : -1);
|
||||||
#else // ZM_HAS_V4L
|
#else // ZM_HAS_V4L
|
||||||
|
|
|
@ -136,13 +136,6 @@ else
|
||||||
echo "Defaulting to master branch";
|
echo "Defaulting to master branch";
|
||||||
BRANCH="master";
|
BRANCH="master";
|
||||||
fi;
|
fi;
|
||||||
if [ "$SNAPSHOT" == "NOW" ]; then
|
|
||||||
SNAPSHOT=`date +%Y%m%d%H%M%S`;
|
|
||||||
else
|
|
||||||
if [ "$SNAPSHOT" == "CURRENT" ]; then
|
|
||||||
SNAPSHOT="`date +%Y%m%d.`$(git rev-list ${versionhash}..HEAD --count)"
|
|
||||||
fi;
|
|
||||||
fi;
|
|
||||||
fi;
|
fi;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -150,6 +143,8 @@ if [ "$PACKAGE_VERSION" == "NOW" ]; then
|
||||||
PACKAGE_VERSION=`date +%Y%m%d%H%M%S`;
|
PACKAGE_VERSION=`date +%Y%m%d%H%M%S`;
|
||||||
else
|
else
|
||||||
if [ "$PACKAGE_VERSION" == "CURRENT" ]; then
|
if [ "$PACKAGE_VERSION" == "CURRENT" ]; then
|
||||||
|
# git the latest (short) commit hash of the version file
|
||||||
|
versionhash=$(git log -n1 --pretty=format:%h version)
|
||||||
PACKAGE_VERSION="`date +%Y%m%d.`$(git rev-list ${versionhash}..HEAD --count)"
|
PACKAGE_VERSION="`date +%Y%m%d.`$(git rev-list ${versionhash}..HEAD --count)"
|
||||||
fi;
|
fi;
|
||||||
fi;
|
fi;
|
||||||
|
@ -200,10 +195,19 @@ else
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
cd "${GITHUB_FORK}_zoneminder_release"
|
cd "${GITHUB_FORK}_zoneminder_release"
|
||||||
git checkout $BRANCH
|
git checkout $BRANCH
|
||||||
cd ../
|
|
||||||
|
|
||||||
VERSION=`cat ${GITHUB_FORK}_zoneminder_release/version`
|
VERSION=`cat version`
|
||||||
|
if [ "$SNAPSHOT" == "NOW" ]; then
|
||||||
|
SNAPSHOT=`date +%Y%m%d%H%M%S`;
|
||||||
|
else
|
||||||
|
if [ "$SNAPSHOT" == "CURRENT" ]; then
|
||||||
|
# git the latest (short) commit hash of the version file
|
||||||
|
versionhash=$(git log -n1 --pretty=format:%h version)
|
||||||
|
SNAPSHOT="`date +%Y%m%d.`$(git rev-list ${versionhash}..HEAD --count)"
|
||||||
|
fi;
|
||||||
|
fi;
|
||||||
|
cd ../
|
||||||
|
|
||||||
if [ -z "$VERSION" ]; then
|
if [ -z "$VERSION" ]; then
|
||||||
exit 1;
|
exit 1;
|
||||||
|
|
|
@ -182,6 +182,9 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim
|
||||||
$sort = $sort == 'Monitor' ? 'M.Name' : 'E.'.$sort;
|
$sort = $sort == 'Monitor' ? 'M.Name' : 'E.'.$sort;
|
||||||
$col_str = 'E.*, M.Name AS Monitor';
|
$col_str = 'E.*, M.Name AS Monitor';
|
||||||
$sql = 'SELECT ' .$col_str. ' FROM `Events` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.' ORDER BY '.$sort.' '.$order;
|
$sql = 'SELECT ' .$col_str. ' FROM `Events` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.' ORDER BY '.$sort.' '.$order;
|
||||||
|
if ($filter->limit() and !count($filter->pre_sql_conditions()) and !count($filter->post_sql_conditions())) {
|
||||||
|
$sql .= ' LIMIT '.$filter->limit();
|
||||||
|
}
|
||||||
|
|
||||||
$storage_areas = ZM\Storage::find();
|
$storage_areas = ZM\Storage::find();
|
||||||
$StorageById = array();
|
$StorageById = array();
|
||||||
|
@ -208,6 +211,12 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim
|
||||||
$unfiltered_rows[] = $row;
|
$unfiltered_rows[] = $row;
|
||||||
} # end foreach row
|
} # end foreach row
|
||||||
|
|
||||||
|
# Filter limits come before pagination limits.
|
||||||
|
if ($filter->limit() and ($filter->limit() > count($unfiltered_rows))) {
|
||||||
|
ZM\Debug("Filtering rows due to filter->limit " . count($unfiltered_rows)." limit: ".$filter->limit());
|
||||||
|
$unfiltered_rows = array_slice($unfiltered_rows, 0, $filter->limit());
|
||||||
|
}
|
||||||
|
|
||||||
ZM\Debug('Have ' . count($unfiltered_rows) . ' events matching base filter.');
|
ZM\Debug('Have ' . count($unfiltered_rows) . ' events matching base filter.');
|
||||||
|
|
||||||
$filtered_rows = null;
|
$filtered_rows = null;
|
||||||
|
@ -246,8 +255,10 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim
|
||||||
$filtered_rows = $unfiltered_rows;
|
$filtered_rows = $unfiltered_rows;
|
||||||
} # end if search_filter->terms() > 1
|
} # end if search_filter->terms() > 1
|
||||||
|
|
||||||
if ($limit)
|
if ($limit) {
|
||||||
|
ZM\Debug("Filtering rows due to limit " . count($filtered_rows)." offset: $offset limit: $limit");
|
||||||
$filtered_rows = array_slice($filtered_rows, $offset, $limit);
|
$filtered_rows = array_slice($filtered_rows, $offset, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
$returned_rows = array();
|
$returned_rows = array();
|
||||||
foreach ($filtered_rows as $row) {
|
foreach ($filtered_rows as $row) {
|
||||||
|
|
|
@ -112,6 +112,7 @@ $statusData = array(
|
||||||
'StartTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
'StartTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
||||||
'StartDateTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
'StartDateTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
||||||
'EndDateTime' => true,
|
'EndDateTime' => true,
|
||||||
|
'EndDateTimeShort' => array( 'sql' => 'date_format( EndDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
||||||
'Width' => true,
|
'Width' => true,
|
||||||
'Height' => true,
|
'Height' => true,
|
||||||
'Length' => true,
|
'Length' => true,
|
||||||
|
@ -140,6 +141,7 @@ $statusData = array(
|
||||||
'StartTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
'StartTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
||||||
'StartDateTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
'StartDateTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
||||||
'EndDateTime' => true,
|
'EndDateTime' => true,
|
||||||
|
'EndDateTimeShort' => array( 'sql' => 'date_format( EndDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ),
|
||||||
'Width' => true,
|
'Width' => true,
|
||||||
'Height' => true,
|
'Height' => true,
|
||||||
'Length' => true,
|
'Length' => true,
|
||||||
|
|
|
@ -227,7 +227,7 @@ class Filter extends ZM_Object {
|
||||||
}
|
}
|
||||||
if ( isset( $this->Query()['limit'] ) )
|
if ( isset( $this->Query()['limit'] ) )
|
||||||
return $this->{'Query'}['limit'];
|
return $this->{'Query'}['limit'];
|
||||||
return 100;
|
return 0;
|
||||||
#return $this->defaults{'limit'};
|
#return $this->defaults{'limit'};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ if ( !canEdit('System') ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global $error_message;
|
||||||
|
|
||||||
if ( $action == 'delete' ) {
|
if ( $action == 'delete' ) {
|
||||||
if ( isset($_REQUEST['object']) ) {
|
if ( isset($_REQUEST['object']) ) {
|
||||||
if ( $_REQUEST['object'] == 'server' ) {
|
if ( $_REQUEST['object'] == 'server' ) {
|
||||||
|
@ -65,10 +67,19 @@ if ( $action == 'delete' ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isset($newValue) && ($newValue != $config['Value']) ) {
|
if ( isset($newValue) && ($newValue != $config['Value']) ) {
|
||||||
|
# Handle special cases first
|
||||||
|
if ($config['Name'] == 'ZM_LANG_DEFAULT') {
|
||||||
|
# Verify that the language file exists in the lang directory.
|
||||||
|
if (!file_exists(ZM_PATH_WEB.'/lang/'.$newValue.'.php')) {
|
||||||
|
$error_message .= 'Error setting ' . $config['Name'].'. New value ' .$newValue.' not saved because '.ZM_PATH_WEB.'/lang/'.$newValue.'.php doesn\'t exist.<br/>';
|
||||||
|
ZM\Error($error_message);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
dbQuery('UPDATE Config SET Value=? WHERE Name=?', array($newValue, $config['Name']));
|
dbQuery('UPDATE Config SET Value=? WHERE Name=?', array($newValue, $config['Name']));
|
||||||
$changed = true;
|
$changed = true;
|
||||||
}
|
} # end if value changed
|
||||||
}
|
} # end foreach config entry
|
||||||
if ( $changed ) {
|
if ( $changed ) {
|
||||||
switch ( $_REQUEST['tab'] ) {
|
switch ( $_REQUEST['tab'] ) {
|
||||||
case 'system' :
|
case 'system' :
|
||||||
|
|
|
@ -44,12 +44,21 @@ if ($action == 'Save') {
|
||||||
} else {
|
} else {
|
||||||
unset($_REQUEST['newUser']['Password']);
|
unset($_REQUEST['newUser']['Password']);
|
||||||
}
|
}
|
||||||
|
if (isset($_REQUEST['newUser']['Language']) and $_REQUEST['newUser']['Language']) {
|
||||||
|
# Verify that the language file exists in the lang directory.
|
||||||
|
if (!file_exists(ZM_PATH_WEB.'/lang/'.$_REQUEST['newUser']['Language'].'.php')) {
|
||||||
|
$error_message .= 'Error setting Language. New value ' .$_REQUEST['newUser']['Language'].' not saved because '.ZM_PATH_WEB.'/lang/'.$_REQUEST['newUser']['Language'].'.php doesn\'t exist.<br/>';
|
||||||
|
ZM\Error($error_message);
|
||||||
|
unset($_REQUEST['newUser']['Language']);
|
||||||
|
unset($_REQUEST['redirect']);
|
||||||
|
}
|
||||||
|
}
|
||||||
$changes = $dbUser->changes($_REQUEST['newUser']);
|
$changes = $dbUser->changes($_REQUEST['newUser']);
|
||||||
ZM\Debug("Changes: " . print_r($changes, true));
|
ZM\Debug('Changes: ' . print_r($changes, true));
|
||||||
|
|
||||||
if (count($changes)) {
|
if (count($changes)) {
|
||||||
if (!$dbUser->save($changes)) {
|
if (!$dbUser->save($changes)) {
|
||||||
$error_message = $dbUser->get_last_error();
|
$error_message .= $dbUser->get_last_error().'<br/>';
|
||||||
unset($_REQUEST['redirect']);
|
unset($_REQUEST['redirect']);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -73,6 +82,15 @@ if ($action == 'Save') {
|
||||||
} else {
|
} else {
|
||||||
unset($_REQUEST['newUser']['Password']);
|
unset($_REQUEST['newUser']['Password']);
|
||||||
}
|
}
|
||||||
|
if (isset($_REQUEST['newUser']['Language']) and $_REQUEST['newUser']['Language']) {
|
||||||
|
# Verify that the language file exists in the lang directory.
|
||||||
|
if (!file_exists(ZM_PATH_WEB.'/lang/'.$_REQUEST['newUser']['Language'].'.php')) {
|
||||||
|
$error_message .= 'Error setting Language. New value ' .$_REQUEST['newUser']['Language'].' not saved because '.ZM_PATH_WEB.'/lang/'.$_REQUEST['newUser']['Language'].'.php doesn\'t exist.<br/>';
|
||||||
|
ZM\Error($error_message);
|
||||||
|
unset($_REQUEST['newUser']['Language']);
|
||||||
|
unset($_REQUEST['redirect']);
|
||||||
|
}
|
||||||
|
}
|
||||||
$fields = array('Password'=>'', 'Language'=>'', 'HomeView'=>'');
|
$fields = array('Password'=>'', 'Language'=>'', 'HomeView'=>'');
|
||||||
ZM\Debug("changes: ".print_r(array_intersect_key($_REQUEST['newUser'], $fields),true));
|
ZM\Debug("changes: ".print_r(array_intersect_key($_REQUEST['newUser'], $fields),true));
|
||||||
$changes = $dbUser->changes(array_intersect_key($_REQUEST['newUser'], $fields));
|
$changes = $dbUser->changes(array_intersect_key($_REQUEST['newUser'], $fields));
|
||||||
|
@ -80,7 +98,7 @@ if ($action == 'Save') {
|
||||||
|
|
||||||
if (count($changes)) {
|
if (count($changes)) {
|
||||||
if (!$dbUser->save($changes)) {
|
if (!$dbUser->save($changes)) {
|
||||||
$error_message = $dbUser->get_last_error();
|
$error_message .= $dbUser->get_last_error();
|
||||||
unset($_REQUEST['redirect']);
|
unset($_REQUEST['redirect']);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,7 @@ return false;
|
||||||
return $value === csrf_hash($_COOKIE[$n], $time);
|
return $value === csrf_hash($_COOKIE[$n], $time);
|
||||||
case 'key':
|
case 'key':
|
||||||
if (!$GLOBALS['csrf']['key']) {
|
if (!$GLOBALS['csrf']['key']) {
|
||||||
Debug("Checking key: no key set" );
|
ZM\Debug("Checking key: no key set" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#Debug("Checking sid: $value === " . csrf_hash($GLOBALS['csrf']['key'], $time) );
|
#Debug("Checking sid: $value === " . csrf_hash($GLOBALS['csrf']['key'], $time) );
|
||||||
|
|
|
@ -30,20 +30,21 @@ function translate($name) {
|
||||||
function loadLanguage($prefix='') {
|
function loadLanguage($prefix='') {
|
||||||
global $user;
|
global $user;
|
||||||
|
|
||||||
if ( $prefix )
|
if ($prefix)
|
||||||
$prefix = $prefix.'/';
|
$prefix = $prefix.'/';
|
||||||
|
|
||||||
if ( isset($user['Language']) and $user['Language'] ) {
|
if (isset($user['Language']) and $user['Language']) {
|
||||||
$userLangFile = $prefix.'lang/'.$user['Language'].'.php';
|
# Languages can only have letters, numbers and underscore
|
||||||
|
$userLangFile = $prefix.'lang/'.preg_replace('/[^[:alnum:]_]+/', '', $user['Language']).'.php';
|
||||||
|
|
||||||
if ( file_exists($userLangFile) ) {
|
if (file_exists($userLangFile)) {
|
||||||
return $userLangFile;
|
return $userLangFile;
|
||||||
} else {
|
} else {
|
||||||
ZM\Warning("User language file $userLangFile does not exist.");
|
ZM\Warning("User language file $userLangFile does not exist.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$systemLangFile = $prefix.'lang/'.ZM_LANG_DEFAULT.'.php';
|
$systemLangFile = $prefix.'lang/'.preg_replace('/[^[:alnum:]_]+/', '', ZM_LANG_DEFAULT).'.php';
|
||||||
if ( file_exists($systemLangFile) ) {
|
if ( file_exists($systemLangFile) ) {
|
||||||
return $systemLangFile;
|
return $systemLangFile;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -340,6 +340,14 @@ ul.tabList li.active a {
|
||||||
.alarm, .errorText, .error {
|
.alarm, .errorText, .error {
|
||||||
color: #ff3f34;
|
color: #ff3f34;
|
||||||
}
|
}
|
||||||
|
/* Refers to the error box at the top of the web UI */
|
||||||
|
#error {
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: white;
|
||||||
|
color: #ff3f34;
|
||||||
|
}
|
||||||
|
|
||||||
.timedErrorBox {
|
.timedErrorBox {
|
||||||
color:white;
|
color:white;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea,
|
textarea,
|
||||||
|
input[name="newMonitor[Host]"],
|
||||||
input[name="newMonitor[Name]"],
|
input[name="newMonitor[Name]"],
|
||||||
input[name="newMonitor[Path]"],
|
input[name="newMonitor[Path]"],
|
||||||
input[name="newMonitor[SecondPath]"],
|
input[name="newMonitor[SecondPath]"],
|
||||||
|
|
|
@ -169,7 +169,7 @@ function getBodyTopHTML() {
|
||||||
';
|
';
|
||||||
global $error_message;
|
global $error_message;
|
||||||
if ( $error_message ) {
|
if ( $error_message ) {
|
||||||
echo '<div class="error">'.$error_message.'</div>';
|
echo '<div id="error">'.$error_message.'</div>';
|
||||||
}
|
}
|
||||||
} // end function getBodyTopHTML
|
} // end function getBodyTopHTML
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ function getNormalNavBarHTML($running, $user, $bandwidth_options, $view, $skin)
|
||||||
$status = runtimeStatus($running);
|
$status = runtimeStatus($running);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div class="fixed-top container-fluid p-0">
|
<div class="container-fluid p-0">
|
||||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark justify-content-center flex-row">
|
<nav class="navbar navbar-expand-md navbar-dark bg-dark justify-content-center flex-row">
|
||||||
|
|
||||||
<div class="navbar-brand justify-content-start align-self-start">
|
<div class="navbar-brand justify-content-start align-self-start">
|
||||||
|
|
|
@ -52,14 +52,19 @@ function vjsReplay() {
|
||||||
var overLaid = $j("#videoobj");
|
var overLaid = $j("#videoobj");
|
||||||
overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;">No more events</p>');
|
overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;">No more events</p>');
|
||||||
} else {
|
} else {
|
||||||
var endTime = (Date.parse(eventData.EndDateTime)).getTime();
|
if (!eventData.EndDateTime) {
|
||||||
|
// No EndTime but have a next event, just go to it.
|
||||||
|
streamNext(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var endTime = Date.parse(eventData.EndDateTime).getTime();
|
||||||
var nextStartTime = nextEventStartTime.getTime(); //nextEventStartTime.getTime() is a mootools workaround, highjacks Date.parse
|
var nextStartTime = nextEventStartTime.getTime(); //nextEventStartTime.getTime() is a mootools workaround, highjacks Date.parse
|
||||||
if ( nextStartTime <= endTime ) {
|
if ( nextStartTime <= endTime ) {
|
||||||
streamNext(true);
|
streamNext(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var overLaid = $j("#videoobj");
|
|
||||||
vid.pause();
|
vid.pause();
|
||||||
|
var overLaid = $j("#videoobj");
|
||||||
overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;"></p>');
|
overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;"></p>');
|
||||||
var gapDuration = (new Date().getTime()) + (nextStartTime - endTime);
|
var gapDuration = (new Date().getTime()) + (nextStartTime - endTime);
|
||||||
var messageP = $j('.vjsMessage');
|
var messageP = $j('.vjsMessage');
|
||||||
|
|
|
@ -51,6 +51,7 @@ var eventData = {
|
||||||
StartDateTime: '<?php echo $Event->StartDateTime() ?>',
|
StartDateTime: '<?php echo $Event->StartDateTime() ?>',
|
||||||
StartDateTimeShort: '<?php echo strftime(STRF_FMT_DATETIME_SHORT, strtotime($Event->StartDateTime())) ?>',
|
StartDateTimeShort: '<?php echo strftime(STRF_FMT_DATETIME_SHORT, strtotime($Event->StartDateTime())) ?>',
|
||||||
EndDateTime: '<?php echo $Event->EndDateTime() ?>',
|
EndDateTime: '<?php echo $Event->EndDateTime() ?>',
|
||||||
|
EndDateTimeShort: '<?php echo $Event->EndDateTime()? strftime(STRF_FMT_DATETIME_SHORT, strtotime($Event->EndDateTime())) : '' ?>',
|
||||||
Frames: '<?php echo $Event->Frames() ?>',
|
Frames: '<?php echo $Event->Frames() ?>',
|
||||||
AlarmFrames: '<?php echo $Event->AlarmFrames() ?>',
|
AlarmFrames: '<?php echo $Event->AlarmFrames() ?>',
|
||||||
TotScore: '<?php echo $Event->TotScore() ?>',
|
TotScore: '<?php echo $Event->TotScore() ?>',
|
||||||
|
@ -73,6 +74,7 @@ var eventDataStrings = {
|
||||||
MonitorName: '<?php echo translate('AttrMonitorName') ?>',
|
MonitorName: '<?php echo translate('AttrMonitorName') ?>',
|
||||||
Cause: '<?php echo translate('Cause') ?>',
|
Cause: '<?php echo translate('Cause') ?>',
|
||||||
StartDateTimeShort: '<?php echo translate('AttrStartTime') ?>',
|
StartDateTimeShort: '<?php echo translate('AttrStartTime') ?>',
|
||||||
|
EndDateTimeShort: '<?php echo translate('AttrEndTime') ?>',
|
||||||
Length: '<?php echo translate('Duration') ?>',
|
Length: '<?php echo translate('Duration') ?>',
|
||||||
Frames: '<?php echo translate('AttrFrames') ?>',
|
Frames: '<?php echo translate('AttrFrames') ?>',
|
||||||
AlarmFrames: '<?php echo translate('AttrAlarmFrames') ?>',
|
AlarmFrames: '<?php echo translate('AttrAlarmFrames') ?>',
|
||||||
|
|
|
@ -850,7 +850,7 @@ function initPage() {
|
||||||
// Load the PTZ Preset modal into the DOM
|
// Load the PTZ Preset modal into the DOM
|
||||||
if (monitorControllable) getCtrlPresetModal();
|
if (monitorControllable) getCtrlPresetModal();
|
||||||
// Load the settings modal into the DOM
|
// Load the settings modal into the DOM
|
||||||
if (monitorType == "Local") getSettingsModal();
|
if (monitorType == 'Local') getSettingsModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monitorType != 'WebSite') {
|
if (monitorType != 'WebSite') {
|
||||||
|
@ -917,7 +917,15 @@ function initPage() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only enable the settings button for local cameras
|
// Only enable the settings button for local cameras
|
||||||
settingsBtn.prop('disabled', !(canView.Control && (monitorType == 'Local')));
|
if (!canView.Control) {
|
||||||
|
settingsBtn.prop('disabled', true);
|
||||||
|
settingsBtn.prop('title', 'Disbled due to lack of Control View permission.');
|
||||||
|
} else if (monitorType != 'Local') {
|
||||||
|
settingsBtn.prop('disabled', true);
|
||||||
|
settingsBtn.prop('title', 'Settings only available for Local monitors.');
|
||||||
|
} else {
|
||||||
|
settingsBtn.prop('disabled', false);
|
||||||
|
}
|
||||||
|
|
||||||
// Init the bootstrap-table
|
// Init the bootstrap-table
|
||||||
if (monitorType != 'WebSite') table.bootstrapTable({icons: icons});
|
if (monitorType != 'WebSite') table.bootstrapTable({icons: icons});
|
||||||
|
|
|
@ -770,9 +770,18 @@ include('_monitor_source_nvsocket.php');
|
||||||
?>
|
?>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td class="text-right pr-3"><?php echo translate('RemoteHostName') ?></td><td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>"/></td></tr>
|
<tr>
|
||||||
<tr><td><?php echo translate('RemoteHostPort') ?></td><td><input type="number" name="newMonitor[Port]" value="<?php echo validHtmlStr($monitor->Port()) ?>" min="0" max="65535"/></td></tr>
|
<td class="text-right pr-3"><?php echo translate('RemoteHostName') ?></td>
|
||||||
<tr><td><?php echo translate('RemoteHostPath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
|
<td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-right pr-3"><?php echo translate('RemoteHostPort') ?></td>
|
||||||
|
<td><input type="number" name="newMonitor[Port]" value="<?php echo validHtmlStr($monitor->Port()) ?>" min="0" max="65535" step="1"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-right pr-3"><?php echo translate('RemoteHostPath') ?></td>
|
||||||
|
<td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td>
|
||||||
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
} else if ( $monitor->Type() == 'File' ) {
|
} else if ( $monitor->Type() == 'File' ) {
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -54,9 +54,9 @@ else
|
||||||
$focusWindow = true;
|
$focusWindow = true;
|
||||||
|
|
||||||
xhtmlHeaders(__FILE__, translate('Options'));
|
xhtmlHeaders(__FILE__, translate('Options'));
|
||||||
|
getBodyTopHTML();
|
||||||
|
echo getNavBarHTML();
|
||||||
?>
|
?>
|
||||||
<body>
|
|
||||||
<?php echo getNavBarHTML(); ?>
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row flex-nowrap">
|
<div class="row flex-nowrap">
|
||||||
<nav id="sidebar">
|
<nav id="sidebar">
|
||||||
|
|
|
@ -65,7 +65,7 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
|
|
||||||
if ( empty($_REQUEST['fid']) ) {
|
if ( empty($_REQUEST['fid']) ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal('No Frame ID specified');
|
ZM\Error('No Frame ID specified');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,47 +73,50 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
$Event = ZM\Event::find_one(array('Id'=>$_REQUEST['eid']));
|
$Event = ZM\Event::find_one(array('Id'=>$_REQUEST['eid']));
|
||||||
if ( !$Event ) {
|
if ( !$Event ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal('Event '.$_REQUEST['eid'].' Not found');
|
ZM\Error('Event '.$_REQUEST['eid'].' Not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $_REQUEST['fid'] == 'objdetect' ) {
|
if ( $_REQUEST['fid'] == 'objdetect' ) {
|
||||||
// if animation file is found, return that, else return image
|
// if animation file is found, return that, else return image
|
||||||
// we are only looking for GIF or jpg here, not mp4
|
// we are only looking for GIF or jpg here, not mp4
|
||||||
// as most often, browsers asking for this link will be expecting
|
// as most often, browsers asking for this link will be expecting
|
||||||
// media types that can be rendered as <img src=>
|
// media types that can be rendered as <img src=>
|
||||||
$path_anim_gif = $Event->Path().'/objdetect.gif';
|
$path_anim_gif = $Event->Path().'/objdetect.gif';
|
||||||
$path_image = $Event->Path().'/objdetect.jpg';
|
$path_image = $Event->Path().'/objdetect.jpg';
|
||||||
if (file_exists($path_anim_gif)) {
|
if (file_exists($path_anim_gif)) {
|
||||||
// we found the animation gif file
|
// we found the animation gif file
|
||||||
$media_type = 'image/gif';
|
$media_type = 'image/gif';
|
||||||
ZM\Debug("Animation file found at $path");
|
ZM\Debug("Animation file found at $path");
|
||||||
$path = $path_anim_gif;
|
$path = $path_anim_gif;
|
||||||
} else if (file_exists($path_image)) {
|
} else if (file_exists($path_image)) {
|
||||||
// animation not found, but image found
|
// animation not found, but image found
|
||||||
ZM\Debug("Image file found at $path");
|
ZM\Debug("Image file found at $path");
|
||||||
$path = $path_image;
|
$path = $path_image;
|
||||||
} else {
|
} else {
|
||||||
// neither animation nor image found
|
// neither animation nor image found
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal("Object detection animation and image not found for this event");
|
ZM\Error('Object detection animation and image not found for this event');
|
||||||
}
|
return;
|
||||||
$Frame = new ZM\Frame();
|
}
|
||||||
$Frame->Id('objdetect');
|
$Frame = new ZM\Frame();
|
||||||
} else if ( $_REQUEST['fid'] == 'objdetect_mp4' ) {
|
$Frame->Id('objdetect');
|
||||||
$path = $Event->Path().'/objdetect.mp4';
|
} else if ( $_REQUEST['fid'] == 'objdetect_mp4' ) {
|
||||||
if ( !file_exists($path) ) {
|
$path = $Event->Path().'/objdetect.mp4';
|
||||||
header('HTTP/1.0 404 Not Found');
|
if ( !file_exists($path) ) {
|
||||||
ZM\Fatal("File $path does not exist. You might not have enabled create_animation in objectconfig.ini. If you have, inspect debug logs for errors during creation");
|
header('HTTP/1.0 404 Not Found');
|
||||||
}
|
ZM\Error("File $path does not exist. You might not have enabled create_animation in objectconfig.ini. If you have, inspect debug logs for errors during creation");
|
||||||
$Frame = new ZM\Frame();
|
return;
|
||||||
$Frame->Id('objdetect');
|
}
|
||||||
$media_type = 'video/mp4';
|
$Frame = new ZM\Frame();
|
||||||
} else if ( $_REQUEST['fid'] == 'objdetect_gif' ) {
|
$Frame->Id('objdetect');
|
||||||
$path = $Event->Path().'/objdetect.gif';
|
$media_type = 'video/mp4';
|
||||||
if ( !file_exists($path) ) {
|
} else if ( $_REQUEST['fid'] == 'objdetect_gif' ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
$path = $Event->Path().'/objdetect.gif';
|
||||||
ZM\Fatal("File $path does not exist. You might not have enabled create_animation in objectconfig.ini. If you have, inspect debug logs for errors during creation");
|
if ( !file_exists($path) ) {
|
||||||
|
header('HTTP/1.0 404 Not Found');
|
||||||
|
ZM\Error("File $path does not exist. You might not have enabled create_animation in objectconfig.ini. If you have, inspect debug logs for errors during creation");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
$Frame = new ZM\Frame();
|
$Frame = new ZM\Frame();
|
||||||
$Frame->Id('objdetect');
|
$Frame->Id('objdetect');
|
||||||
|
@ -122,7 +125,8 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
$path = $Event->Path().'/objdetect.jpg';
|
$path = $Event->Path().'/objdetect.jpg';
|
||||||
if ( !file_exists($path) ) {
|
if ( !file_exists($path) ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal("File $path does not exist. Please make sure store_frame_in_zm is enabled in the object detection config");
|
ZM\Error("File $path does not exist. Please make sure store_frame_in_zm is enabled in the object detection config");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
$Frame = new ZM\Frame();
|
$Frame = new ZM\Frame();
|
||||||
$Frame->Id('objdetect');
|
$Frame->Id('objdetect');
|
||||||
|
@ -149,7 +153,7 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d', $Frame->FrameId()).'-'.$show.'.jpg';
|
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d', $Frame->FrameId()).'-'.$show.'.jpg';
|
||||||
} else {
|
} else {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal('No alarm jpg found for event '.$_REQUEST['eid']);
|
ZM\Error('No alarm jpg found for event '.$_REQUEST['eid']);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -189,11 +193,12 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
ZM\Debug("Command: $command, retval: $retval, output: " . implode("\n", $output));
|
ZM\Debug("Command: $command, retval: $retval, output: " . implode("\n", $output));
|
||||||
if ( ! file_exists($path) ) {
|
if ( ! file_exists($path) ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal('Can\'t create frame images from video for this event '.$Event->DefaultVideo().'
|
ZM\Error('Can\'t create frame images from video for this event '.$Event->DefaultVideo().'
|
||||||
|
|
||||||
Command was: '.$command.'
|
Command was: '.$command.'
|
||||||
|
|
||||||
Output was: '.implode(PHP_EOL,$output) );
|
Output was: '.implode(PHP_EOL,$output) );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
# Generating an image file will use up more disk space, so update the Event record.
|
# Generating an image file will use up more disk space, so update the Event record.
|
||||||
if ( $Event->EndDateTime() ) {
|
if ( $Event->EndDateTime() ) {
|
||||||
|
@ -202,7 +207,7 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal('No snapshot jpg found for event '.$_REQUEST['eid']);
|
ZM\Error('No snapshot jpg found for event '.$_REQUEST['eid']);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} # end if stored jpgs
|
} # end if stored jpgs
|
||||||
|
@ -231,7 +236,8 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
$Frame->Delta($previousBulkFrame['Delta'] + floor( 100* ( $nextBulkFrame['Delta'] - $previousBulkFrame['Delta'] ) * $percentage )/100);
|
$Frame->Delta($previousBulkFrame['Delta'] + floor( 100* ( $nextBulkFrame['Delta'] - $previousBulkFrame['Delta'] ) * $percentage )/100);
|
||||||
ZM\Debug('Got virtual frame from Bulk Frames previous delta: ' . $previousBulkFrame['Delta'] . ' + nextdelta:' . $nextBulkFrame['Delta'] . ' - ' . $previousBulkFrame['Delta'] . ' * ' . $percentage );
|
ZM\Debug('Got virtual frame from Bulk Frames previous delta: ' . $previousBulkFrame['Delta'] . ' + nextdelta:' . $nextBulkFrame['Delta'] . ' - ' . $previousBulkFrame['Delta'] . ' * ' . $percentage );
|
||||||
} else {
|
} else {
|
||||||
ZM\Fatal('No Frame found for event('.$_REQUEST['eid'].') and frame id('.$_REQUEST['fid'].')');
|
ZM\Error('No Frame found for event('.$_REQUEST['eid'].') and frame id('.$_REQUEST['fid'].')');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} # end if !Frame
|
} # end if !Frame
|
||||||
// Frame can be non-existent. We have Bulk frames. So now we should try to load the bulk frame
|
// Frame can be non-existent. We have Bulk frames. So now we should try to load the bulk frame
|
||||||
|
@ -244,14 +250,14 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
$Frame = ZM\Frame::find_one(array('Id'=>$_REQUEST['fid']));
|
$Frame = ZM\Frame::find_one(array('Id'=>$_REQUEST['fid']));
|
||||||
if ( !$Frame ) {
|
if ( !$Frame ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal('Frame ' . $_REQUEST['fid'] . ' Not Found');
|
ZM\Error('Frame ' . $_REQUEST['fid'] . ' Not Found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$Event = ZM\Event::find_one(array('Id'=>$Frame->EventId()));
|
$Event = ZM\Event::find_one(array('Id'=>$Frame->EventId()));
|
||||||
if ( !$Event ) {
|
if ( !$Event ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal('Event ' . $Frame->EventId() . ' Not Found');
|
ZM\Error('Event ' . $Frame->EventId() . ' Not Found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
|
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
|
||||||
|
@ -263,7 +269,8 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
if ( ($show == 'capture') and $Event->DefaultVideo() ) {
|
if ( ($show == 'capture') and $Event->DefaultVideo() ) {
|
||||||
if ( !file_exists($Event->Path().'/'.$Event->DefaultVideo()) ) {
|
if ( !file_exists($Event->Path().'/'.$Event->DefaultVideo()) ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal("Can't create frame images from video because there is no video file for this event at (".$Event->Path().'/'.$Event->DefaultVideo() );
|
ZM\Error("Can't create frame images from video because there is no video file for this event at (".$Event->Path().'/'.$Event->DefaultVideo() );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
$command = ZM_PATH_FFMPEG.' -ss '. $Frame->Delta() .' -i '.$Event->Path().'/'.$Event->DefaultVideo().' -frames:v 1 '.$path . ' 2>&1';
|
$command = ZM_PATH_FFMPEG.' -ss '. $Frame->Delta() .' -i '.$Event->Path().'/'.$Event->DefaultVideo().' -frames:v 1 '.$path . ' 2>&1';
|
||||||
#$command ='ffmpeg -ss '. $Frame->Delta() .' -i '.$Event->Path().'/'.$Event->DefaultVideo().' -vf "select=gte(n\\,'.$Frame->FrameId().'),setpts=PTS-STARTPTS" '.$path;
|
#$command ='ffmpeg -ss '. $Frame->Delta() .' -i '.$Event->Path().'/'.$Event->DefaultVideo().' -vf "select=gte(n\\,'.$Frame->FrameId().'),setpts=PTS-STARTPTS" '.$path;
|
||||||
|
@ -275,11 +282,12 @@ if ( empty($_REQUEST['path']) ) {
|
||||||
ZM\Debug("Command: $command, retval: $retval, output: " . implode("\n", $output));
|
ZM\Debug("Command: $command, retval: $retval, output: " . implode("\n", $output));
|
||||||
if ( ! file_exists($path) ) {
|
if ( ! file_exists($path) ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal('Can\'t create frame images from video for this event '.$Event->DefaultVideo().'
|
ZM\Error('Can\'t create frame images from video for this event '.$Event->DefaultVideo().'
|
||||||
|
|
||||||
Command was: '.$command.'
|
Command was: '.$command.'
|
||||||
|
|
||||||
Output was: '.implode(PHP_EOL,$output) );
|
Output was: '.implode(PHP_EOL,$output) );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
# Generating an image file will use up more disk space, so update the Event record.
|
# Generating an image file will use up more disk space, so update the Event record.
|
||||||
if ( $Event->EndDateTime() ) {
|
if ( $Event->EndDateTime() ) {
|
||||||
|
@ -288,8 +296,9 @@ Output was: '.implode(PHP_EOL,$output) );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal("Can't create frame $show images from video because there is no video file for this event at ".
|
ZM\Error("Can't create frame $show images from video because there is no video file for this event at ".
|
||||||
$Event->Path().'/'.$Event->DefaultVideo() );
|
$Event->Path().'/'.$Event->DefaultVideo() );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} # end if ! file_exists($path)
|
} # end if ! file_exists($path)
|
||||||
|
|
||||||
|
@ -317,7 +326,8 @@ Output was: '.implode(PHP_EOL,$output) );
|
||||||
}
|
}
|
||||||
if ( !file_exists($path) ) {
|
if ( !file_exists($path) ) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
ZM\Fatal("Image not found at $path");
|
ZM\Error("Image not found at $path");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue