Merge branch 'release-1.34' of github.com:ZoneMinder/zoneminder into release-1.34
This commit is contained in:
commit
1f6e68c129
|
@ -28,7 +28,7 @@
|
|||
%global _hardened_build 1
|
||||
|
||||
Name: zoneminder
|
||||
Version: 1.34.10
|
||||
Version: 1.34.11
|
||||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
|
|
32
src/zm_box.h
32
src/zm_box.h
|
@ -33,37 +33,33 @@
|
|||
// Class used for storing a box, which is defined as a region
|
||||
// defined by two coordinates
|
||||
//
|
||||
class Box
|
||||
{
|
||||
class Box {
|
||||
private:
|
||||
Coord lo, hi;
|
||||
Coord size;
|
||||
|
||||
public:
|
||||
inline Box()
|
||||
{
|
||||
}
|
||||
inline Box() { }
|
||||
explicit inline Box( int p_size ) : lo( 0, 0 ), hi ( p_size-1, p_size-1 ), size( Coord::Range( hi, lo ) ) { }
|
||||
inline Box( int p_x_size, int p_y_size ) : lo( 0, 0 ), hi ( p_x_size-1, p_y_size-1 ), size( Coord::Range( hi, lo ) ) { }
|
||||
inline Box( int lo_x, int lo_y, int hi_x, int hi_y ) : lo( lo_x, lo_y ), hi( hi_x, hi_y ), size( Coord::Range( hi, lo ) ) { }
|
||||
inline Box( const Coord &p_lo, const Coord &p_hi ) : lo( p_lo ), hi( p_hi ), size( Coord::Range( hi, lo ) ) { }
|
||||
|
||||
inline const Coord &Lo() const { return( lo ); }
|
||||
inline int LoX() const { return( lo.X() ); }
|
||||
inline int LoY() const { return( lo.Y() ); }
|
||||
inline const Coord &Hi() const { return( hi ); }
|
||||
inline int HiX() const { return( hi.X() ); }
|
||||
inline int HiY() const { return( hi.Y() ); }
|
||||
inline const Coord &Size() const { return( size ); }
|
||||
inline int Width() const { return( size.X() ); }
|
||||
inline int Height() const { return( size.Y() ); }
|
||||
inline int Area() const { return( size.X()*size.Y() ); }
|
||||
inline const Coord &Lo() const { return lo; }
|
||||
inline int LoX() const { return lo.X(); }
|
||||
inline int LoY() const { return lo.Y(); }
|
||||
inline const Coord &Hi() const { return hi; }
|
||||
inline int HiX() const { return hi.X(); }
|
||||
inline int HiY() const { return hi.Y(); }
|
||||
inline const Coord &Size() const { return size; }
|
||||
inline int Width() const { return size.X(); }
|
||||
inline int Height() const { return size.Y(); }
|
||||
inline int Area() const { return size.X()*size.Y(); }
|
||||
|
||||
inline const Coord Centre() const
|
||||
{
|
||||
inline const Coord Centre() const {
|
||||
int mid_x = int(round(lo.X()+(size.X()/2.0)));
|
||||
int mid_y = int(round(lo.Y()+(size.Y()/2.0)));
|
||||
return( Coord( mid_x, mid_y ) );
|
||||
return Coord( mid_x, mid_y );
|
||||
}
|
||||
inline bool Inside( const Coord &coord ) const
|
||||
{
|
||||
|
|
|
@ -63,7 +63,9 @@ void zmLoadConfig() {
|
|||
closedir(configSubFolder);
|
||||
}
|
||||
|
||||
zmDbConnect();
|
||||
if ( !zmDbConnect() ) {
|
||||
Fatal("Can't connect to db. Can't continue.");
|
||||
}
|
||||
config.Load();
|
||||
config.Assign();
|
||||
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
//
|
||||
// Class used for storing an x,y pair, i.e. a coordinate
|
||||
//
|
||||
class Coord
|
||||
{
|
||||
class Coord {
|
||||
private:
|
||||
int x, y;
|
||||
|
||||
|
@ -44,8 +43,7 @@ public:
|
|||
inline int &Y() { return( y ); }
|
||||
inline const int &Y() const { return( y ); }
|
||||
|
||||
inline static Coord Range( const Coord &coord1, const Coord &coord2 )
|
||||
{
|
||||
inline static Coord Range( const Coord &coord1, const Coord &coord2 ) {
|
||||
Coord result( (coord1.x-coord2.x)+1, (coord1.y-coord2.y)+1 );
|
||||
return( result );
|
||||
}
|
||||
|
|
|
@ -164,7 +164,22 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
|||
event_data->Orientation = (Monitor::Orientation)(dbrow[8] == NULL ? 0 : atoi(dbrow[8]));
|
||||
mysql_free_result(result);
|
||||
|
||||
Storage * storage = new Storage(event_data->storage_id);
|
||||
if ( !monitor ) {
|
||||
monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY);
|
||||
} else if ( monitor->Id() != event_data->monitor_id ) {
|
||||
delete monitor;
|
||||
monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY);
|
||||
}
|
||||
if ( !monitor ) {
|
||||
Fatal("Unable to load monitor id %d for streaming", event_data->monitor_id);
|
||||
}
|
||||
|
||||
if ( !storage ) {
|
||||
storage = new Storage(event_data->storage_id);
|
||||
} else if ( storage->Id() != event_data->storage_id ) {
|
||||
delete storage;
|
||||
storage = new Storage(event_data->storage_id);
|
||||
}
|
||||
const char *storage_path = storage->Path();
|
||||
|
||||
if ( event_data->scheme == Storage::DEEP ) {
|
||||
|
@ -206,7 +221,6 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
|||
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
|
||||
event_data->event_id);
|
||||
}
|
||||
delete storage; storage = NULL;
|
||||
|
||||
updateFrameRate((double)event_data->frame_count/event_data->duration);
|
||||
Debug(3, "fps set by frame_count(%d)/duration(%f)",
|
||||
|
@ -246,7 +260,7 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
|||
event_data->frames[i-1].timestamp = last_timestamp + ((i-last_id)*frame_delta);
|
||||
event_data->frames[i-1].offset = event_data->frames[i-1].timestamp - event_data->start_time;
|
||||
event_data->frames[i-1].in_db = false;
|
||||
Debug(3,"Frame %d timestamp:(%f), offset(%f) delta(%f), in_db(%d)",
|
||||
Debug(3, "Frame %d timestamp:(%f), offset(%f) delta(%f), in_db(%d)",
|
||||
i,
|
||||
event_data->frames[i-1].timestamp,
|
||||
event_data->frames[i-1].offset,
|
||||
|
@ -277,7 +291,10 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
|||
|
||||
mysql_free_result(result);
|
||||
|
||||
if ( event_data->video_file[0] ) {
|
||||
if ( event_data->video_file[0] || (monitor->GetOptVideoWriter() > 0) ) {
|
||||
if ( !event_data->video_file[0] ) {
|
||||
snprintf(event_data->video_file, sizeof(event_data->video_file), "%" PRIu64 "-%s", event_data->event_id, "video.mp4");
|
||||
}
|
||||
std::string filepath = std::string(event_data->path) + "/" + std::string(event_data->video_file);
|
||||
//char filepath[PATH_MAX];
|
||||
//snprintf(filepath, sizeof(filepath), "%s/%s", event_data->path, event_data->video_file);
|
||||
|
@ -305,7 +322,7 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
|||
void EventStream::processCommand(const CmdMsg *msg) {
|
||||
Debug(2, "Got message, type %d, msg %d", msg->msg_type, msg->msg_data[0]);
|
||||
// Check for incoming command
|
||||
switch( (MsgCommand)msg->msg_data[0] ) {
|
||||
switch ( (MsgCommand)msg->msg_data[0] ) {
|
||||
case CMD_PAUSE :
|
||||
Debug(1, "Got PAUSE command");
|
||||
|
||||
|
@ -657,7 +674,8 @@ bool EventStream::sendFrame(int delta_us) {
|
|||
Image *send_image = prepareImage(&image);
|
||||
|
||||
if ( !vid_stream ) {
|
||||
vid_stream = new VideoStream("pipe:", format, bitrate, effective_fps, send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height());
|
||||
vid_stream = new VideoStream("pipe:", format, bitrate, effective_fps,
|
||||
send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height());
|
||||
fprintf(stdout, "Content-type: %s\r\n\r\n", vid_stream->MimeType());
|
||||
vid_stream->OpenStream();
|
||||
}
|
||||
|
@ -700,9 +718,10 @@ Debug(1, "Loading image");
|
|||
} else if ( ffmpeg_input ) {
|
||||
// Get the frame from the mp4 input
|
||||
Debug(1,"Getting frame from ffmpeg");
|
||||
AVFrame *frame;
|
||||
FrameData *frame_data = &event_data->frames[curr_frame_id-1];
|
||||
frame = ffmpeg_input->get_frame( ffmpeg_input->get_video_stream_id(), frame_data->offset );
|
||||
AVFrame *frame = ffmpeg_input->get_frame(
|
||||
ffmpeg_input->get_video_stream_id(),
|
||||
frame_data->offset);
|
||||
if ( frame ) {
|
||||
image = new Image(frame);
|
||||
//av_frame_free(&frame);
|
||||
|
@ -982,8 +1001,8 @@ void EventStream::runStream() {
|
|||
// you can calculate the relationship between now and the start
|
||||
// or calc the relationship from the last frame. I think from the start is better as it self-corrects
|
||||
|
||||
if ( send_frame && type != STREAM_MPEG ) {
|
||||
if ( delta_us > 0) {
|
||||
if ( send_frame && (type != STREAM_MPEG) ) {
|
||||
if ( delta_us > 0 ) {
|
||||
if ( delta_us > MAX_SLEEP_USEC ) {
|
||||
Debug(1, "Limiting sleep to %d because calculated sleep is too long %d", MAX_SLEEP_USEC, delta_us);
|
||||
delta_us = MAX_SLEEP_USEC;
|
||||
|
@ -1026,18 +1045,12 @@ void EventStream::runStream() {
|
|||
closeComms();
|
||||
} // void EventStream::runStream()
|
||||
|
||||
void EventStream::setStreamStart( uint64_t init_event_id, unsigned int init_frame_id=0 ) {
|
||||
void EventStream::setStreamStart(
|
||||
uint64_t init_event_id,
|
||||
unsigned int init_frame_id=0) {
|
||||
loadInitialEventData(init_event_id, init_frame_id);
|
||||
if ( !(monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY)) ) {
|
||||
Fatal("Unable to load monitor id %d for streaming", event_data->monitor_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // end void EventStream::setStreamStart(init_event_id,init_frame_id=0)
|
||||
|
||||
void EventStream::setStreamStart(int monitor_id, time_t event_time) {
|
||||
loadInitialEventData(monitor_id, event_time);
|
||||
if ( !(monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY)) ) {
|
||||
Fatal("Unable to load monitor id %d for streaming", monitor_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,6 @@
|
|||
#ifndef ZM_EVENTSTREAM_H
|
||||
#define ZM_EVENTSTREAM_H
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include "zm_image.h"
|
||||
#include "zm_stream.h"
|
||||
#include "zm_video.h"
|
||||
|
@ -83,7 +80,6 @@ class EventStream : public StreamBase {
|
|||
struct timeval start; // clock time when started the event
|
||||
|
||||
EventData *event_data;
|
||||
FFmpeg_Input *ffmpeg_input;
|
||||
|
||||
protected:
|
||||
bool loadEventData( uint64_t event_id );
|
||||
|
@ -95,23 +91,40 @@ class EventStream : public StreamBase {
|
|||
bool sendFrame( int delta_us );
|
||||
|
||||
public:
|
||||
EventStream() {
|
||||
mode = DEFAULT_MODE;
|
||||
replay_rate = DEFAULT_RATE;
|
||||
|
||||
forceEventChange = false;
|
||||
|
||||
curr_frame_id = 0;
|
||||
curr_stream_time = 0.0;
|
||||
send_frame = false;
|
||||
|
||||
event_data = 0;
|
||||
|
||||
EventStream() :
|
||||
mode(DEFAULT_MODE),
|
||||
forceEventChange(false),
|
||||
curr_frame_id(0),
|
||||
curr_stream_time(0.0),
|
||||
send_frame(false),
|
||||
event_data(0),
|
||||
storage(NULL),
|
||||
ffmpeg_input(NULL),
|
||||
// Used when loading frames from an mp4
|
||||
input_codec_context = 0;
|
||||
input_codec = 0;
|
||||
|
||||
ffmpeg_input = NULL;
|
||||
input_codec_context(0),
|
||||
input_codec(0)
|
||||
{}
|
||||
~EventStream() {
|
||||
if ( event_data ) {
|
||||
if ( event_data->frames ) {
|
||||
delete[] event_data->frames;
|
||||
event_data->frames = NULL;
|
||||
}
|
||||
delete event_data;
|
||||
event_data = NULL;
|
||||
}
|
||||
if ( monitor ) {
|
||||
delete monitor;
|
||||
monitor = NULL;
|
||||
}
|
||||
if ( storage ) {
|
||||
delete storage;
|
||||
storage = NULL;
|
||||
}
|
||||
if ( ffmpeg_input ) {
|
||||
delete ffmpeg_input;
|
||||
ffmpeg_input = NULL;
|
||||
}
|
||||
}
|
||||
void setStreamStart( uint64_t init_event_id, unsigned int init_frame_id );
|
||||
void setStreamStart( int monitor_id, time_t event_time );
|
||||
|
@ -121,8 +134,10 @@ class EventStream : public StreamBase {
|
|||
void runStream();
|
||||
Image *getImage();
|
||||
private:
|
||||
AVCodecContext *input_codec_context;
|
||||
AVCodec *input_codec;
|
||||
Storage *storage;
|
||||
FFmpeg_Input *ffmpeg_input;
|
||||
AVCodecContext *input_codec_context;
|
||||
AVCodec *input_codec;
|
||||
};
|
||||
|
||||
#endif // ZM_EVENTSTREAM_H
|
||||
|
|
|
@ -321,6 +321,7 @@ void zm_dump_codecpar(const AVCodecParameters *par);
|
|||
frame->pts \
|
||||
);
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 4, 0, 74, 100)
|
||||
#define zm_dump_video_frame(frame,text) Debug(1, "%s: format %d %s %dx%d linesize:%dx%d pts: %" PRId64, \
|
||||
text, \
|
||||
frame->format, \
|
||||
|
@ -331,6 +332,18 @@ void zm_dump_codecpar(const AVCodecParameters *par);
|
|||
frame->pts \
|
||||
);
|
||||
|
||||
#else
|
||||
#define zm_dump_video_frame(frame,text) Debug(1, "%s: format %d %s %dx%d linesize:%dx%d pts: %" PRId64, \
|
||||
text, \
|
||||
frame->format, \
|
||||
"unsupported", \
|
||||
frame->width, \
|
||||
frame->height, \
|
||||
frame->linesize[0], frame->linesize[1], \
|
||||
frame->pts \
|
||||
);
|
||||
#endif
|
||||
|
||||
#if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100)
|
||||
#define zm_av_packet_unref( packet ) av_packet_unref( packet )
|
||||
#define zm_av_packet_ref( dst, src ) av_packet_ref( dst, src )
|
||||
|
|
|
@ -15,10 +15,26 @@ FFmpeg_Input::FFmpeg_Input() {
|
|||
|
||||
FFmpeg_Input::~FFmpeg_Input() {
|
||||
if ( streams ) {
|
||||
for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) {
|
||||
avcodec_close(streams[i].context);
|
||||
streams[i].context = NULL;
|
||||
}
|
||||
delete streams;
|
||||
streams = NULL;
|
||||
}
|
||||
}
|
||||
if ( frame ) {
|
||||
av_frame_free(&frame);
|
||||
frame = NULL;
|
||||
}
|
||||
if ( input_format_context ) {
|
||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0)
|
||||
av_close_input_file(input_format_context);
|
||||
#else
|
||||
avformat_close_input(&input_format_context);
|
||||
#endif
|
||||
input_format_context = NULL;
|
||||
}
|
||||
} // end ~FFmpeg_Input()
|
||||
|
||||
int FFmpeg_Input::Open(const char *filepath) {
|
||||
|
||||
|
@ -90,6 +106,7 @@ int FFmpeg_Input::Open(const char *filepath) {
|
|||
avcodec_free_context(&streams[i].context);
|
||||
#endif
|
||||
avformat_close_input(&input_format_context);
|
||||
input_format_context = NULL;
|
||||
return error;
|
||||
}
|
||||
} // end foreach stream
|
||||
|
@ -103,7 +120,6 @@ int FFmpeg_Input::Open(const char *filepath) {
|
|||
} // end int FFmpeg_Input::Open( const char * filepath )
|
||||
|
||||
AVFrame *FFmpeg_Input::get_frame(int stream_id) {
|
||||
|
||||
int frameComplete = false;
|
||||
AVPacket packet;
|
||||
av_init_packet(&packet);
|
||||
|
@ -139,8 +155,8 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) {
|
|||
}
|
||||
ret = zm_send_packet_receive_frame(context, frame, packet);
|
||||
if ( ret < 0 ) {
|
||||
Error("Unable to decode frame at frame %d: %s, continuing",
|
||||
streams[packet.stream_index].frame_count, av_make_error_string(ret).c_str());
|
||||
Error("Unable to decode frame at frame %d: %d %s, continuing",
|
||||
streams[packet.stream_index].frame_count, ret, av_make_error_string(ret).c_str());
|
||||
zm_av_packet_unref(&packet);
|
||||
av_frame_free(&frame);
|
||||
continue;
|
||||
|
@ -211,15 +227,17 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
|
|||
last_seek_request = seek_target;
|
||||
|
||||
// Seeking seems to typically seek to a keyframe, so then we have to decode until we get the frame we want.
|
||||
if ( frame->pts <= seek_target ) {
|
||||
if ( frame->pts <= seek_target ) {
|
||||
zm_dump_frame(frame, "pts <= seek_target");
|
||||
while ( frame && (frame->pts < seek_target) ) {
|
||||
if ( !get_frame(stream_id) )
|
||||
if ( !get_frame(stream_id) ) {
|
||||
Warning("Got no frame. returning nothing");
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
zm_dump_frame(frame, "frame->pts <= seek_target, got");
|
||||
return frame;
|
||||
}
|
||||
|
||||
return get_frame(stream_id);
|
||||
|
||||
} // end AVFrame *FFmpeg_Input::get_frame( int stream_id, struct timeval at)
|
||||
} // end AVFrame *FFmpeg_Input::get_frame( int stream_id, struct timeval at)
|
||||
|
|
|
@ -48,6 +48,8 @@ static short *g_v_table;
|
|||
static short *g_u_table;
|
||||
static short *b_u_table;
|
||||
|
||||
struct SwsContext *sws_convert_context = NULL;
|
||||
|
||||
jpeg_compress_struct *Image::writejpg_ccinfo[101] = { 0 };
|
||||
jpeg_compress_struct *Image::encodejpg_ccinfo[101] = { 0 };
|
||||
jpeg_decompress_struct *Image::readjpg_dcinfo = 0;
|
||||
|
@ -160,15 +162,17 @@ Image::Image( int p_width, int p_height, int p_colours, int p_subpixelorder, uin
|
|||
update_function_pointers();
|
||||
}
|
||||
|
||||
Image::Image( const AVFrame *frame ) {
|
||||
Image::Image(const AVFrame *frame) {
|
||||
AVFrame *dest_frame = zm_av_frame_alloc();
|
||||
text[0] = '\0';
|
||||
|
||||
width = frame->width;
|
||||
height = frame->height;
|
||||
pixels = width*height;
|
||||
|
||||
colours = ZM_COLOUR_RGB32;
|
||||
subpixelorder = ZM_SUBPIX_ORDER_RGBA;
|
||||
|
||||
size = pixels*colours;
|
||||
buffer = 0;
|
||||
holdbuffer = 0;
|
||||
|
@ -183,26 +187,28 @@ Image::Image( const AVFrame *frame ) {
|
|||
#endif
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
struct SwsContext *mConvertContext = sws_getContext(
|
||||
sws_convert_context = sws_getCachedContext(
|
||||
sws_convert_context,
|
||||
width,
|
||||
height,
|
||||
(AVPixelFormat)frame->format,
|
||||
width, height,
|
||||
AV_PIX_FMT_RGBA, SWS_BICUBIC, NULL,
|
||||
NULL, NULL);
|
||||
if ( mConvertContext == NULL )
|
||||
Fatal( "Unable to create conversion context" );
|
||||
if ( sws_convert_context == NULL )
|
||||
Fatal("Unable to create conversion context");
|
||||
|
||||
if ( sws_scale(mConvertContext, frame->data, frame->linesize, 0, frame->height, dest_frame->data, dest_frame->linesize) < 0 )
|
||||
if ( sws_scale(sws_convert_context, frame->data, frame->linesize, 0, frame->height,
|
||||
dest_frame->data, dest_frame->linesize) < 0 )
|
||||
Fatal("Unable to convert raw format %u to target format %u", frame->format, AV_PIX_FMT_RGBA);
|
||||
#else // HAVE_LIBSWSCALE
|
||||
Fatal("You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras");
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
av_frame_free( &dest_frame );
|
||||
av_frame_free(&dest_frame);
|
||||
update_function_pointers();
|
||||
}
|
||||
} // end Image::Image(const AVFrame *frame)
|
||||
|
||||
Image::Image( const Image &p_image ) {
|
||||
Image::Image(const Image &p_image) {
|
||||
if ( !initialised )
|
||||
Initialise();
|
||||
width = p_image.width;
|
||||
|
@ -215,7 +221,7 @@ Image::Image( const Image &p_image ) {
|
|||
holdbuffer = 0;
|
||||
AllocImgBuffer(size);
|
||||
(*fptr_imgbufcpy)(buffer, p_image.buffer, size);
|
||||
strncpy( text, p_image.text, sizeof(text) );
|
||||
strncpy(text, p_image.text, sizeof(text));
|
||||
update_function_pointers();
|
||||
}
|
||||
|
||||
|
@ -225,35 +231,39 @@ Image::~Image() {
|
|||
|
||||
/* Should be called as part of program shutdown to free everything */
|
||||
void Image::Deinitialise() {
|
||||
if ( initialised ) {
|
||||
/*
|
||||
delete[] y_table;
|
||||
delete[] uv_table;
|
||||
delete[] r_v_table;
|
||||
delete[] g_v_table;
|
||||
delete[] g_u_table;
|
||||
delete[] b_u_table;
|
||||
if ( !initialised ) return;
|
||||
/*
|
||||
delete[] y_table;
|
||||
delete[] uv_table;
|
||||
delete[] r_v_table;
|
||||
delete[] g_v_table;
|
||||
delete[] g_u_table;
|
||||
delete[] b_u_table;
|
||||
*/
|
||||
initialised = false;
|
||||
if ( readjpg_dcinfo ) {
|
||||
jpeg_destroy_decompress( readjpg_dcinfo );
|
||||
delete readjpg_dcinfo;
|
||||
readjpg_dcinfo = 0;
|
||||
}
|
||||
if ( decodejpg_dcinfo ) {
|
||||
jpeg_destroy_decompress( decodejpg_dcinfo );
|
||||
delete decodejpg_dcinfo;
|
||||
decodejpg_dcinfo = 0;
|
||||
}
|
||||
for ( unsigned int quality=0; quality <= 100; quality += 1 ) {
|
||||
if ( writejpg_ccinfo[quality] ) {
|
||||
jpeg_destroy_compress( writejpg_ccinfo[quality] );
|
||||
delete writejpg_ccinfo[quality];
|
||||
writejpg_ccinfo[quality] = NULL;
|
||||
}
|
||||
} // end foreach quality
|
||||
initialised = false;
|
||||
if ( readjpg_dcinfo ) {
|
||||
jpeg_destroy_decompress( readjpg_dcinfo );
|
||||
delete readjpg_dcinfo;
|
||||
readjpg_dcinfo = 0;
|
||||
}
|
||||
}
|
||||
if ( decodejpg_dcinfo ) {
|
||||
jpeg_destroy_decompress( decodejpg_dcinfo );
|
||||
delete decodejpg_dcinfo;
|
||||
decodejpg_dcinfo = 0;
|
||||
}
|
||||
for ( unsigned int quality=0; quality <= 100; quality += 1 ) {
|
||||
if ( writejpg_ccinfo[quality] ) {
|
||||
jpeg_destroy_compress( writejpg_ccinfo[quality] );
|
||||
delete writejpg_ccinfo[quality];
|
||||
writejpg_ccinfo[quality] = NULL;
|
||||
}
|
||||
} // end foreach quality
|
||||
|
||||
if ( sws_convert_context ) {
|
||||
sws_freeContext(sws_convert_context);
|
||||
sws_convert_context = NULL;
|
||||
}
|
||||
} // end void Image::Deinitialise()
|
||||
|
||||
void Image::Initialise() {
|
||||
/* Assign the blend pointer to function */
|
||||
|
@ -655,15 +665,16 @@ void Image::Assign( const Image &image ) {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( !buffer || image.width != width || image.height != height || image.colours != colours || image.subpixelorder != subpixelorder) {
|
||||
if ( !buffer || image.width != width || image.height != height
|
||||
|| image.colours != colours || image.subpixelorder != subpixelorder) {
|
||||
|
||||
if (holdbuffer && buffer) {
|
||||
if (new_size > allocation) {
|
||||
if ( holdbuffer && buffer ) {
|
||||
if ( new_size > allocation ) {
|
||||
Error("Held buffer is undersized for assigned buffer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(new_size > allocation || !buffer) {
|
||||
if ( new_size > allocation || !buffer) {
|
||||
// DumpImgBuffer(); This is also done in AllocImgBuffer
|
||||
AllocImgBuffer(new_size);
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ protected:
|
|||
};
|
||||
|
||||
inline void DumpImgBuffer() {
|
||||
DumpBuffer(buffer,buffertype);
|
||||
DumpBuffer(buffer, buffertype);
|
||||
buffer = NULL;
|
||||
allocation = 0;
|
||||
}
|
||||
|
|
|
@ -1655,7 +1655,7 @@ bool Monitor::Analyse() {
|
|||
Info("%s: %03d - Left alarm state (%" PRIu64 ") - %d(%d) images",
|
||||
name, image_count, event->Id(), event->Frames(), event->AlarmFrames());
|
||||
//if ( function != MOCORD || event_close_mode == CLOSE_ALARM || event->Cause() == SIGNAL_CAUSE )
|
||||
if ( function != MOCORD || event_close_mode == CLOSE_ALARM ) {
|
||||
if ( ( function != MOCORD && function != RECORD ) || event_close_mode == CLOSE_ALARM ) {
|
||||
shared_data->state = state = IDLE;
|
||||
Info("%s: %03d - Closing event %" PRIu64 ", alarm end%s",
|
||||
name, image_count, event->Id(), (function==MOCORD)?", section truncated":"");
|
||||
|
|
|
@ -26,11 +26,9 @@
|
|||
#include <cmath>
|
||||
#endif
|
||||
|
||||
void Polygon::calcArea()
|
||||
{
|
||||
void Polygon::calcArea() {
|
||||
double float_area = 0.0L;
|
||||
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ )
|
||||
{
|
||||
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) {
|
||||
double trap_area = ((coords[i].X()-coords[j].X())*((coords[i].Y()+coords[j].Y())))/2.0L;
|
||||
float_area += trap_area;
|
||||
//printf( "%.2f (%.2f)\n", float_area, trap_area );
|
||||
|
@ -38,13 +36,11 @@ void Polygon::calcArea()
|
|||
area = (int)round(fabs(float_area));
|
||||
}
|
||||
|
||||
void Polygon::calcCentre()
|
||||
{
|
||||
void Polygon::calcCentre() {
|
||||
if ( !area && n_coords )
|
||||
calcArea();
|
||||
double float_x = 0.0L, float_y = 0.0L;
|
||||
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ )
|
||||
{
|
||||
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) {
|
||||
float_x += ((coords[i].Y()-coords[j].Y())*((coords[i].X()*2)+(coords[i].X()*coords[j].X())+(coords[j].X()*2)));
|
||||
float_y += ((coords[j].X()-coords[i].X())*((coords[i].Y()*2)+(coords[i].Y()*coords[j].Y())+(coords[j].Y()*2)));
|
||||
}
|
||||
|
@ -54,16 +50,14 @@ void Polygon::calcCentre()
|
|||
centre = Coord( (int)round(float_x), (int)round(float_y) );
|
||||
}
|
||||
|
||||
Polygon::Polygon( int p_n_coords, const Coord *p_coords ) : n_coords( p_n_coords )
|
||||
{
|
||||
Polygon::Polygon(int p_n_coords, const Coord *p_coords) : n_coords( p_n_coords ) {
|
||||
coords = new Coord[n_coords];
|
||||
|
||||
int min_x = -1;
|
||||
int max_x = -1;
|
||||
int min_y = -1;
|
||||
int max_y = -1;
|
||||
for( int i = 0; i < n_coords; i++ )
|
||||
{
|
||||
for ( int i = 0; i < n_coords; i++ ) {
|
||||
coords[i] = p_coords[i];
|
||||
if ( min_x == -1 || coords[i].X() < min_x )
|
||||
min_x = coords[i].X();
|
||||
|
@ -79,38 +73,36 @@ Polygon::Polygon( int p_n_coords, const Coord *p_coords ) : n_coords( p_n_coords
|
|||
calcCentre();
|
||||
}
|
||||
|
||||
Polygon::Polygon( const Polygon &p_polygon ) : n_coords( p_polygon.n_coords ), extent( p_polygon.extent ), area( p_polygon.area ), centre( p_polygon.centre )
|
||||
Polygon::Polygon( const Polygon &p_polygon ) :
|
||||
n_coords(p_polygon.n_coords),
|
||||
extent(p_polygon.extent),
|
||||
area(p_polygon.area),
|
||||
centre(p_polygon.centre)
|
||||
{
|
||||
coords = new Coord[n_coords];
|
||||
for( int i = 0; i < n_coords; i++ )
|
||||
{
|
||||
for( int i = 0; i < n_coords; i++ ) {
|
||||
coords[i] = p_polygon.coords[i];
|
||||
}
|
||||
}
|
||||
|
||||
Polygon &Polygon::operator=( const Polygon &p_polygon )
|
||||
{
|
||||
if ( n_coords < p_polygon.n_coords )
|
||||
{
|
||||
Polygon &Polygon::operator=( const Polygon &p_polygon ) {
|
||||
if ( n_coords < p_polygon.n_coords ) {
|
||||
delete[] coords;
|
||||
coords = new Coord[p_polygon.n_coords];
|
||||
}
|
||||
n_coords = p_polygon.n_coords;
|
||||
for( int i = 0; i < n_coords; i++ )
|
||||
{
|
||||
for ( int i = 0; i < n_coords; i++ ) {
|
||||
coords[i] = p_polygon.coords[i];
|
||||
}
|
||||
extent = p_polygon.extent;
|
||||
area = p_polygon.area;
|
||||
centre = p_polygon.centre;
|
||||
return( *this );
|
||||
return *this ;
|
||||
}
|
||||
|
||||
bool Polygon::isInside( const Coord &coord ) const
|
||||
{
|
||||
bool Polygon::isInside( const Coord &coord ) const {
|
||||
bool inside = false;
|
||||
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ )
|
||||
{
|
||||
for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) {
|
||||
if ( (((coords[i].Y() <= coord.Y()) && (coord.Y() < coords[j].Y()) )
|
||||
|| ((coords[j].Y() <= coord.Y()) && (coord.Y() < coords[i].Y())))
|
||||
&& (coord.X() < (coords[j].X() - coords[i].X()) * (coord.Y() - coords[i].Y()) / (coords[j].Y() - coords[i].Y()) + coords[i].X()))
|
||||
|
@ -118,5 +110,5 @@ bool Polygon::isInside( const Coord &coord ) const
|
|||
inside = !inside;
|
||||
}
|
||||
}
|
||||
return( inside );
|
||||
return inside;
|
||||
}
|
||||
|
|
|
@ -41,13 +41,13 @@ protected:
|
|||
static int CompareYX( const void *p1, const void *p2 ) {
|
||||
const Edge *e1 = reinterpret_cast<const Edge *>(p1), *e2 = reinterpret_cast<const Edge *>(p2);
|
||||
if ( e1->min_y == e2->min_y )
|
||||
return( int(e1->min_x - e2->min_x) );
|
||||
return int(e1->min_x - e2->min_x);
|
||||
else
|
||||
return( int(e1->min_y - e2->min_y) );
|
||||
return int(e1->min_y - e2->min_y);
|
||||
}
|
||||
static int CompareX( const void *p1, const void *p2 ) {
|
||||
const Edge *e1 = reinterpret_cast<const Edge *>(p1), *e2 = reinterpret_cast<const Edge *>(p2);
|
||||
return( int(e1->min_x - e2->min_x) );
|
||||
return int(e1->min_x - e2->min_x);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -83,32 +83,32 @@ protected:
|
|||
void calcCentre();
|
||||
|
||||
public:
|
||||
inline Polygon() : n_coords( 0 ), coords( 0 ), area( 0 ), edges(0), slices(0) {
|
||||
inline Polygon() : n_coords(0), coords(0), area(0), edges(0), slices(0) {
|
||||
}
|
||||
Polygon( int p_n_coords, const Coord *p_coords );
|
||||
Polygon( const Polygon &p_polygon );
|
||||
Polygon(int p_n_coords, const Coord *p_coords);
|
||||
Polygon(const Polygon &p_polygon);
|
||||
~Polygon() {
|
||||
delete[] coords;
|
||||
}
|
||||
|
||||
Polygon &operator=( const Polygon &p_polygon );
|
||||
|
||||
inline int getNumCoords() const { return( n_coords ); }
|
||||
inline int getNumCoords() const { return n_coords; }
|
||||
inline const Coord &getCoord( int index ) const {
|
||||
return( coords[index] );
|
||||
return coords[index];
|
||||
}
|
||||
|
||||
inline const Box &Extent() const { return( extent ); }
|
||||
inline int LoX() const { return( extent.LoX() ); }
|
||||
inline int HiX() const { return( extent.HiX() ); }
|
||||
inline int LoY() const { return( extent.LoY() ); }
|
||||
inline int HiY() const { return( extent.HiY() ); }
|
||||
inline int Width() const { return( extent.Width() ); }
|
||||
inline int Height() const { return( extent.Height() ); }
|
||||
inline const Box &Extent() const { return extent; }
|
||||
inline int LoX() const { return extent.LoX(); }
|
||||
inline int HiX() const { return extent.HiX(); }
|
||||
inline int LoY() const { return extent.LoY(); }
|
||||
inline int HiY() const { return extent.HiY(); }
|
||||
inline int Width() const { return extent.Width(); }
|
||||
inline int Height() const { return extent.Height(); }
|
||||
|
||||
inline int Area() const { return( area ); }
|
||||
inline int Area() const { return area; }
|
||||
inline const Coord &Centre() const {
|
||||
return( centre );
|
||||
return centre;
|
||||
}
|
||||
bool isInside( const Coord &coord ) const;
|
||||
};
|
||||
|
|
|
@ -114,7 +114,7 @@ bool StreamBase::checkCommandQueue() {
|
|||
return false;
|
||||
}
|
||||
|
||||
Image *StreamBase::prepareImage( Image *image ) {
|
||||
Image *StreamBase::prepareImage(Image *image) {
|
||||
|
||||
// Do not bother to scale zoomed in images, just crop them and let the browser scale
|
||||
// Works in FF2 but breaks FF3 which doesn't like image sizes changing in mid stream.
|
||||
|
@ -124,50 +124,51 @@ Image *StreamBase::prepareImage( Image *image ) {
|
|||
|
||||
int mag = (scale * zoom) / ZM_SCALE_BASE;
|
||||
int act_mag = optimisedScaling?(mag > ZM_SCALE_BASE?ZM_SCALE_BASE:mag):mag;
|
||||
Debug( 3, "Scaling by %d, zooming by %d = magnifying by %d(%d)", scale, zoom, mag, act_mag );
|
||||
|
||||
int last_mag = (last_scale * last_zoom) / ZM_SCALE_BASE;
|
||||
int last_act_mag = last_mag > ZM_SCALE_BASE?ZM_SCALE_BASE:last_mag;
|
||||
Debug( 3, "Last scaling by %d, zooming by %d = magnifying by %d(%d)", last_scale, last_zoom, last_mag, last_act_mag );
|
||||
|
||||
int base_image_width = image->Width(), base_image_height = image->Height();
|
||||
Debug( 3, "Base image width = %d, height = %d", base_image_width, base_image_height );
|
||||
|
||||
int virt_image_width = (base_image_width * mag) / ZM_SCALE_BASE, virt_image_height = (base_image_height * mag) / ZM_SCALE_BASE;
|
||||
Debug( 3, "Virtual image width = %d, height = %d", virt_image_width, virt_image_height );
|
||||
|
||||
int last_virt_image_width = (base_image_width * last_mag) / ZM_SCALE_BASE, last_virt_image_height = (base_image_height * last_mag) / ZM_SCALE_BASE;
|
||||
Debug( 3, "Last virtual image width = %d, height = %d", last_virt_image_width, last_virt_image_height );
|
||||
|
||||
int act_image_width = (base_image_width * act_mag ) / ZM_SCALE_BASE, act_image_height = (base_image_height * act_mag ) / ZM_SCALE_BASE;
|
||||
Debug( 3, "Actual image width = %d, height = %d", act_image_width, act_image_height );
|
||||
|
||||
int last_act_image_width = (base_image_width * last_act_mag ) / ZM_SCALE_BASE, last_act_image_height = (base_image_height * last_act_mag ) / ZM_SCALE_BASE;
|
||||
Debug( 3, "Last actual image width = %d, height = %d", last_act_image_width, last_act_image_height );
|
||||
|
||||
int disp_image_width = (image->Width() * scale) / ZM_SCALE_BASE, disp_image_height = (image->Height() * scale) / ZM_SCALE_BASE;
|
||||
Debug( 3, "Display image width = %d, height = %d", disp_image_width, disp_image_height );
|
||||
|
||||
int last_disp_image_width = (image->Width() * last_scale) / ZM_SCALE_BASE, last_disp_image_height = (image->Height() * last_scale) / ZM_SCALE_BASE;
|
||||
Debug( 3, "Last display image width = %d, height = %d", last_disp_image_width, last_disp_image_height );
|
||||
|
||||
int send_image_width = (disp_image_width * act_mag ) / mag, send_image_height = (disp_image_height * act_mag ) / mag;
|
||||
Debug( 3, "Send image width = %d, height = %d", send_image_width, send_image_height );
|
||||
|
||||
int last_send_image_width = (last_disp_image_width * last_act_mag ) / last_mag, last_send_image_height = (last_disp_image_height * last_act_mag ) / last_mag;
|
||||
Debug( 3, "Last send image width = %d, height = %d", last_send_image_width, last_send_image_height );
|
||||
|
||||
if ( mag != ZM_SCALE_BASE ) {
|
||||
if ( act_mag != ZM_SCALE_BASE ) {
|
||||
Debug(3, "Magnifying by %d", mag);
|
||||
if ( !image_copied ) {
|
||||
static Image copy_image;
|
||||
copy_image.Assign(*image);
|
||||
image = ©_image;
|
||||
image_copied = true;
|
||||
}
|
||||
image->Scale(mag);
|
||||
}
|
||||
Debug(3,
|
||||
"Scaling by %d, zooming by %d = magnifying by %d(%d)\n"
|
||||
"Last scaling by %d, zooming by %d = magnifying by %d(%d)\n"
|
||||
"Base image width = %d, height = %d\n"
|
||||
"Virtual image width = %d, height = %d\n"
|
||||
"Last virtual image width = %d, height = %d\n"
|
||||
"Actual image width = %d, height = %d\n"
|
||||
"Last actual image width = %d, height = %d\n"
|
||||
"Display image width = %d, height = %d\n"
|
||||
"Last display image width = %d, height = %d\n"
|
||||
"Send image width = %d, height = %d\n"
|
||||
"Last send image width = %d, height = %d\n",
|
||||
scale, zoom, mag, act_mag,
|
||||
last_scale, last_zoom, last_mag, last_act_mag,
|
||||
base_image_width, base_image_height,
|
||||
virt_image_width, virt_image_height,
|
||||
last_virt_image_width, last_virt_image_height,
|
||||
act_image_width, act_image_height,
|
||||
last_act_image_width, last_act_image_height,
|
||||
disp_image_width, disp_image_height,
|
||||
last_disp_image_width, last_disp_image_height,
|
||||
send_image_width, send_image_height,
|
||||
last_send_image_width, last_send_image_height
|
||||
);
|
||||
|
||||
if ( ( mag != ZM_SCALE_BASE ) && (act_mag != ZM_SCALE_BASE) ) {
|
||||
Debug(3, "Magnifying by %d", mag);
|
||||
static Image copy_image;
|
||||
copy_image.Assign(*image);
|
||||
image = ©_image;
|
||||
image_copied = true;
|
||||
image->Scale(mag);
|
||||
}
|
||||
|
||||
Debug(3, "Real image width = %d, height = %d", image->Width(), image->Height());
|
||||
|
@ -176,26 +177,22 @@ Image *StreamBase::prepareImage( Image *image ) {
|
|||
static Box last_crop;
|
||||
|
||||
if ( mag != last_mag || x != last_x || y != last_y ) {
|
||||
Debug( 3, "Got click at %d,%d x %d", x, y, mag );
|
||||
|
||||
//if ( !last_mag )
|
||||
//last_mag = mag;
|
||||
Debug(3, "Got click at %d,%d x %d", x, y, mag);
|
||||
|
||||
if ( !(last_disp_image_width < last_virt_image_width || last_disp_image_height < last_virt_image_height) )
|
||||
last_crop = Box();
|
||||
|
||||
Debug( 3, "Recalculating crop" );
|
||||
// Recalculate crop parameters, as %ges
|
||||
int click_x = (last_crop.LoX() * 100 ) / last_act_image_width; // Initial crop offset from last image
|
||||
click_x += ( x * 100 ) / last_virt_image_width;
|
||||
int click_y = (last_crop.LoY() * 100 ) / last_act_image_height; // Initial crop offset from last image
|
||||
click_y += ( y * 100 ) / last_virt_image_height;
|
||||
Debug( 3, "Got adjusted click at %d%%,%d%%", click_x, click_y );
|
||||
Debug(3, "Got adjusted click at %d%%,%d%%", click_x, click_y);
|
||||
|
||||
// Convert the click locations to the current image pixels
|
||||
click_x = ( click_x * act_image_width ) / 100;
|
||||
click_y = ( click_y * act_image_height ) / 100;
|
||||
Debug( 3, "Got readjusted click at %d,%d", click_x, click_y );
|
||||
Debug(3, "Got readjusted click at %d,%d", click_x, click_y);
|
||||
|
||||
int lo_x = click_x - (send_image_width/2);
|
||||
if ( lo_x < 0 )
|
||||
|
@ -214,23 +211,25 @@ Image *StreamBase::prepareImage( Image *image ) {
|
|||
lo_y = hi_y - (send_image_height - 1);
|
||||
}
|
||||
last_crop = Box( lo_x, lo_y, hi_x, hi_y );
|
||||
}
|
||||
Debug( 3, "Cropping to %d,%d -> %d,%d", last_crop.LoX(), last_crop.LoY(), last_crop.HiX(), last_crop.HiY() );
|
||||
} // end if ( mag != last_mag || x != last_x || y != last_y )
|
||||
|
||||
Debug(3, "Cropping to %d,%d -> %d,%d", last_crop.LoX(), last_crop.LoY(), last_crop.HiX(), last_crop.HiY());
|
||||
if ( !image_copied ) {
|
||||
static Image copy_image;
|
||||
copy_image.Assign( *image );
|
||||
copy_image.Assign(*image);
|
||||
image = ©_image;
|
||||
image_copied = true;
|
||||
}
|
||||
image->Crop( last_crop );
|
||||
}
|
||||
image->Crop(last_crop);
|
||||
} // end if difference in image vs displayed dimensions
|
||||
|
||||
last_scale = scale;
|
||||
last_zoom = zoom;
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
|
||||
return image;
|
||||
}
|
||||
} // end Image *StreamBase::prepareImage(Image *image)
|
||||
|
||||
bool StreamBase::sendTextFrame(const char *frame_text) {
|
||||
Debug(2, "Sending %dx%d * %d text frame '%s'",
|
||||
|
@ -349,7 +348,7 @@ void StreamBase::openComms() {
|
|||
}
|
||||
|
||||
snprintf(rem_sock_path, sizeof(rem_sock_path), "%s/zms-%06dw.sock", staticConfig.PATH_SOCKS.c_str(), connkey);
|
||||
strncpy(rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path)-1);
|
||||
strncpy(rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path));
|
||||
rem_addr.sun_family = AF_UNIX;
|
||||
|
||||
gettimeofday(&last_comm_update, NULL);
|
||||
|
|
|
@ -77,11 +77,11 @@ protected:
|
|||
protected:
|
||||
int connkey;
|
||||
int sd;
|
||||
char loc_sock_path[PATH_MAX];
|
||||
char loc_sock_path[108];
|
||||
struct sockaddr_un loc_addr;
|
||||
char rem_sock_path[PATH_MAX];
|
||||
char rem_sock_path[108];
|
||||
struct sockaddr_un rem_addr;
|
||||
char sock_path_lock[PATH_MAX];
|
||||
char sock_path_lock[108];
|
||||
int lock_fd;
|
||||
|
||||
protected:
|
||||
|
|
296
src/zm_user.cpp
296
src/zm_user.cpp
|
@ -26,6 +26,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <utility>
|
||||
|
||||
#if HAVE_GNUTLS_GNUTLS_H
|
||||
#include <gnutls/gnutls.h>
|
||||
|
@ -35,7 +36,7 @@
|
|||
#include <gcrypt.h>
|
||||
#elif HAVE_LIBCRYPTO
|
||||
#include <openssl/md5.h>
|
||||
#endif // HAVE_L || HAVE_LIBCRYPTO
|
||||
#endif // HAVE_GCRYPT_H || HAVE_LIBCRYPTO
|
||||
|
||||
#include "zm_utils.h"
|
||||
#include "zm_crypt.h"
|
||||
|
@ -52,7 +53,7 @@ User::User(const MYSQL_ROW &dbrow) {
|
|||
id = atoi(dbrow[index++]);
|
||||
strncpy(username, dbrow[index++], sizeof(username)-1);
|
||||
strncpy(password, dbrow[index++], sizeof(password)-1);
|
||||
enabled = (bool)atoi(dbrow[index++]);
|
||||
enabled = static_cast<bool>(atoi(dbrow[index++]));
|
||||
stream = (Permission)atoi(dbrow[index++]);
|
||||
events = (Permission)atoi(dbrow[index++]);
|
||||
control = (Permission)atoi(dbrow[index++]);
|
||||
|
@ -61,7 +62,7 @@ User::User(const MYSQL_ROW &dbrow) {
|
|||
char *monitor_ids_str = dbrow[index++];
|
||||
if ( monitor_ids_str && *monitor_ids_str ) {
|
||||
StringVector ids = split(monitor_ids_str, ",");
|
||||
for( StringVector::iterator i = ids.begin(); i < ids.end(); ++i ) {
|
||||
for ( StringVector::iterator i = ids.begin(); i < ids.end(); ++i ) {
|
||||
monitor_ids.push_back(atoi((*i).c_str()));
|
||||
}
|
||||
}
|
||||
|
@ -72,9 +73,9 @@ User::~User() {
|
|||
}
|
||||
|
||||
void User::Copy(const User &u) {
|
||||
id=u.id;
|
||||
strncpy(username, u.username, sizeof(username)-1);
|
||||
strncpy(password, u.password, sizeof(password)-1);
|
||||
id = u.id;
|
||||
strncpy(username, u.username, sizeof(username));
|
||||
strncpy(password, u.password, sizeof(password));
|
||||
enabled = u.enabled;
|
||||
stream = u.stream;
|
||||
events = u.events;
|
||||
|
@ -88,7 +89,8 @@ bool User::canAccess(int monitor_id) {
|
|||
if ( monitor_ids.empty() )
|
||||
return true;
|
||||
|
||||
for ( std::vector<int>::iterator i = monitor_ids.begin(); i != monitor_ids.end(); ++i ) {
|
||||
for ( std::vector<int>::iterator i = monitor_ids.begin();
|
||||
i != monitor_ids.end(); ++i ) {
|
||||
if ( *i == monitor_id ) {
|
||||
return true;
|
||||
}
|
||||
|
@ -103,18 +105,23 @@ User *zmLoadUser(const char *username, const char *password) {
|
|||
int username_length = strlen(username);
|
||||
char *safer_username = new char[(username_length * 2) + 1];
|
||||
|
||||
// According to docs, size of safer_whatever must be 2*length+1 due to unicode conversions + null terminator.
|
||||
// According to docs, size of safer_whatever must be 2*length+1
|
||||
// due to unicode conversions + null terminator.
|
||||
mysql_real_escape_string(&dbconn, safer_username, username, username_length);
|
||||
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0, `MonitorIds`"
|
||||
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", safer_username);
|
||||
"SELECT `Id`, `Username`, `Password`, `Enabled`,"
|
||||
" `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0,"
|
||||
" `MonitorIds`"
|
||||
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1",
|
||||
safer_username);
|
||||
delete[] safer_username;
|
||||
safer_username = NULL;
|
||||
|
||||
if ( mysql_query(&dbconn, sql) ) {
|
||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||
exit(mysql_errno(&dbconn));
|
||||
}
|
||||
delete safer_username;
|
||||
|
||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
||||
if ( !result ) {
|
||||
|
@ -122,162 +129,157 @@ User *zmLoadUser(const char *username, const char *password) {
|
|||
exit(mysql_errno(&dbconn));
|
||||
}
|
||||
|
||||
if ( mysql_num_rows(result) != 1 ) {
|
||||
if ( mysql_num_rows(result) == 1 ) {
|
||||
MYSQL_ROW dbrow = mysql_fetch_row(result);
|
||||
User *user = new User(dbrow);
|
||||
mysql_free_result(result);
|
||||
Warning("Unable to authenticate user %s", username);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MYSQL_ROW dbrow = mysql_fetch_row(result);
|
||||
User *user = new User(dbrow);
|
||||
if (
|
||||
(! password ) // relay type must be none
|
||||
||
|
||||
verifyPassword(username, password, user->getPassword()) ) {
|
||||
Info("Authenticated user '%s'", user->getUsername());
|
||||
return user;
|
||||
}
|
||||
} // end if 1 result from db
|
||||
mysql_free_result(result);
|
||||
|
||||
if ( !password ) {
|
||||
// relay type must be none
|
||||
return user;
|
||||
}
|
||||
|
||||
if ( verifyPassword(username, password, user->getPassword()) ) {
|
||||
Info("Authenticated user '%s'", user->getUsername());
|
||||
return user;
|
||||
}
|
||||
|
||||
Warning("Unable to authenticate user %s", username);
|
||||
return NULL;
|
||||
}
|
||||
} // end User *zmLoadUser(const char *username, const char *password)
|
||||
|
||||
User *zmLoadTokenUser (std::string jwt_token_str, bool use_remote_addr ) {
|
||||
User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr) {
|
||||
std::string key = config.auth_hash_secret;
|
||||
std::string remote_addr = "";
|
||||
|
||||
if (use_remote_addr) {
|
||||
remote_addr = std::string(getenv( "REMOTE_ADDR" ));
|
||||
if ( use_remote_addr ) {
|
||||
remote_addr = std::string(getenv("REMOTE_ADDR"));
|
||||
if ( remote_addr == "" ) {
|
||||
Warning( "Can't determine remote address, using null" );
|
||||
Warning("Can't determine remote address, using null");
|
||||
remote_addr = "";
|
||||
}
|
||||
key += remote_addr;
|
||||
}
|
||||
|
||||
Debug (1,"Inside zmLoadTokenUser, formed key=%s", key.c_str());
|
||||
Debug(1, "Inside zmLoadTokenUser, formed key=%s", key.c_str());
|
||||
|
||||
std::pair<std::string, unsigned int> ans = verifyToken(jwt_token_str, key);
|
||||
std::string username = ans.first;
|
||||
unsigned int iat = ans.second;
|
||||
Debug (1,"retrieved user '%s' from token", username.c_str());
|
||||
Debug(1, "retrieved user '%s' from token", username.c_str());
|
||||
|
||||
if (username != "") {
|
||||
char sql[ZM_SQL_MED_BUFSIZ] = "";
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0, `MonitorIds`, `TokenMinExpiry`"
|
||||
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", username.c_str() );
|
||||
|
||||
if ( mysql_query(&dbconn, sql) ) {
|
||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||
exit(mysql_errno(&dbconn));
|
||||
}
|
||||
|
||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
||||
if ( !result ) {
|
||||
Error("Can't use query result: %s", mysql_error(&dbconn));
|
||||
exit(mysql_errno(&dbconn));
|
||||
}
|
||||
int n_users = mysql_num_rows(result);
|
||||
|
||||
if ( n_users != 1 ) {
|
||||
mysql_free_result(result);
|
||||
Error("Unable to authenticate user '%s'", username.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MYSQL_ROW dbrow = mysql_fetch_row(result);
|
||||
User *user = new User(dbrow);
|
||||
unsigned int stored_iat = strtoul(dbrow[10], NULL,0 );
|
||||
|
||||
if (stored_iat > iat ) { // admin revoked tokens
|
||||
mysql_free_result(result);
|
||||
Error("Token was revoked for '%s'", username.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Debug (1,"Got last token revoke time of: %u",stored_iat);
|
||||
Debug (1,"Authenticated user '%s' via token", username.c_str());
|
||||
mysql_free_result(result);
|
||||
return user;
|
||||
|
||||
}
|
||||
else {
|
||||
if ( username == "" ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
char sql[ZM_SQL_MED_BUFSIZ] = "";
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0,"
|
||||
" `Control`+0, `Monitors`+0, `System`+0, `MonitorIds`, `TokenMinExpiry`"
|
||||
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", username.c_str());
|
||||
|
||||
if ( mysql_query(&dbconn, sql) ) {
|
||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
||||
if ( !result ) {
|
||||
Error("Can't use query result: %s", mysql_error(&dbconn));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int n_users = mysql_num_rows(result);
|
||||
if ( n_users != 1 ) {
|
||||
mysql_free_result(result);
|
||||
Error("Unable to authenticate user '%s'", username.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MYSQL_ROW dbrow = mysql_fetch_row(result);
|
||||
User *user = new User(dbrow);
|
||||
unsigned int stored_iat = strtoul(dbrow[10], NULL, 0);
|
||||
|
||||
if ( stored_iat > iat ) { // admin revoked tokens
|
||||
mysql_free_result(result);
|
||||
Error("Token was revoked for '%s'", username.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Debug(1, "Authenticated user '%s' via token with last revoke time: %u",
|
||||
username.c_str(), stored_iat);
|
||||
mysql_free_result(result);
|
||||
return user;
|
||||
} // User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr)
|
||||
|
||||
// Function to validate an authentication string
|
||||
User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) {
|
||||
User *zmLoadAuthUser(const char *auth, bool use_remote_addr) {
|
||||
#if HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
// Special initialisation for libgcrypt
|
||||
if ( !gcry_check_version( GCRYPT_VERSION ) ) {
|
||||
Fatal( "Unable to initialise libgcrypt" );
|
||||
if ( !gcry_check_version(GCRYPT_VERSION) ) {
|
||||
Fatal("Unable to initialise libgcrypt");
|
||||
}
|
||||
gcry_control( GCRYCTL_DISABLE_SECMEM, 0 );
|
||||
gcry_control( GCRYCTL_INITIALIZATION_FINISHED, 0 );
|
||||
#endif // HAVE_GCRYPT_H
|
||||
gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
|
||||
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif // HAVE_GCRYPT_H
|
||||
|
||||
const char *remote_addr = "";
|
||||
if ( use_remote_addr ) {
|
||||
remote_addr = getenv( "REMOTE_ADDR" );
|
||||
remote_addr = getenv("REMOTE_ADDR");
|
||||
if ( !remote_addr ) {
|
||||
Warning( "Can't determine remote address, using null" );
|
||||
Warning("Can't determine remote address, using null");
|
||||
remote_addr = "";
|
||||
}
|
||||
}
|
||||
|
||||
Debug( 1, "Attempting to authenticate user from auth string '%s'", auth );
|
||||
Debug(1, "Attempting to authenticate user from auth string '%s'", auth);
|
||||
char sql[ZM_SQL_SML_BUFSIZ] = "";
|
||||
snprintf( sql, sizeof(sql), "SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0, `MonitorIds` FROM `Users` WHERE `Enabled` = 1" );
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT `Id`, `Username`, `Password`, `Enabled`,"
|
||||
" `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0,"
|
||||
" `MonitorIds` FROM `Users` WHERE `Enabled` = 1");
|
||||
|
||||
if ( mysql_query( &dbconn, sql ) ) {
|
||||
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
if ( mysql_query(&dbconn, sql) ) {
|
||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||
exit(mysql_errno(&dbconn));
|
||||
}
|
||||
|
||||
MYSQL_RES *result = mysql_store_result( &dbconn );
|
||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
||||
if ( !result ) {
|
||||
Error( "Can't use query result: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
Error("Can't use query result: %s", mysql_error(&dbconn));
|
||||
return NULL;
|
||||
}
|
||||
int n_users = mysql_num_rows( result );
|
||||
|
||||
int n_users = mysql_num_rows(result);
|
||||
if ( n_users < 1 ) {
|
||||
mysql_free_result( result );
|
||||
Warning( "Unable to authenticate user" );
|
||||
return( 0 );
|
||||
mysql_free_result(result);
|
||||
Warning("Unable to authenticate user");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while( MYSQL_ROW dbrow = mysql_fetch_row( result ) ) {
|
||||
time_t now = time(0);
|
||||
unsigned int hours = config.auth_hash_ttl;
|
||||
if ( ! hours ) {
|
||||
Warning("No value set for ZM_AUTH_HASH_TTL. Defaulting to 2.");
|
||||
hours = 2;
|
||||
} else {
|
||||
Debug(1, "AUTH_HASH_TTL is %d", hours);
|
||||
}
|
||||
char auth_key[512] = "";
|
||||
char auth_md5[32+1] = "";
|
||||
size_t md5len = 16;
|
||||
unsigned char md5sum[md5len];
|
||||
|
||||
const char * hex = "0123456789abcdef";
|
||||
while ( MYSQL_ROW dbrow = mysql_fetch_row(result) ) {
|
||||
const char *user = dbrow[1];
|
||||
const char *pass = dbrow[2];
|
||||
|
||||
char auth_key[512] = "";
|
||||
char auth_md5[32+1] = "";
|
||||
size_t md5len = 16;
|
||||
unsigned char md5sum[md5len];
|
||||
time_t our_now = now;
|
||||
for ( unsigned int i = 0; i < hours; i++, our_now -= 3600 ) {
|
||||
struct tm *now_tm = localtime(&our_now);
|
||||
|
||||
time_t now = time( 0 );
|
||||
unsigned int hours = config.auth_hash_ttl;
|
||||
|
||||
if ( ! hours ) {
|
||||
Warning("No value set for ZM_AUTH_HASH_TTL. Defaulting to 2.");
|
||||
hours = 2;
|
||||
} else {
|
||||
Debug( 1, "AUTH_HASH_TTL is %d", hours );
|
||||
}
|
||||
|
||||
for ( unsigned int i = 0; i < hours; i++, now -= 3600 ) {
|
||||
struct tm *now_tm = localtime( &now );
|
||||
|
||||
snprintf( auth_key, sizeof(auth_key), "%s%s%s%s%d%d%d%d",
|
||||
snprintf(auth_key, sizeof(auth_key)-1, "%s%s%s%s%d%d%d%d",
|
||||
config.auth_hash_secret,
|
||||
user,
|
||||
pass,
|
||||
|
@ -285,51 +287,57 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) {
|
|||
now_tm->tm_hour,
|
||||
now_tm->tm_mday,
|
||||
now_tm->tm_mon,
|
||||
now_tm->tm_year
|
||||
);
|
||||
now_tm->tm_year);
|
||||
|
||||
#if HAVE_DECL_MD5
|
||||
MD5( (unsigned char *)auth_key, strlen(auth_key), md5sum );
|
||||
MD5((unsigned char *)auth_key, strlen(auth_key), md5sum);
|
||||
#elif HAVE_DECL_GNUTLS_FINGERPRINT
|
||||
gnutls_datum_t md5data = { (unsigned char *)auth_key, strlen(auth_key) };
|
||||
gnutls_fingerprint( GNUTLS_DIG_MD5, &md5data, md5sum, &md5len );
|
||||
gnutls_datum_t md5data = { (unsigned char *)auth_key, (unsigned int)strlen(auth_key) };
|
||||
gnutls_fingerprint(GNUTLS_DIG_MD5, &md5data, md5sum, &md5len);
|
||||
#endif
|
||||
auth_md5[0] = '\0';
|
||||
unsigned char *md5sum_ptr = md5sum;
|
||||
char *auth_md5_ptr = auth_md5;
|
||||
|
||||
for ( unsigned int j = 0; j < md5len; j++ ) {
|
||||
sprintf( &auth_md5[2*j], "%02x", md5sum[j] );
|
||||
*auth_md5_ptr++ = hex[(*md5sum_ptr>>4)&0xf];
|
||||
*auth_md5_ptr++ = hex[(*md5sum_ptr++)&0xf];
|
||||
}
|
||||
Debug( 1, "Checking auth_key '%s' -> auth_md5 '%s' == '%s'", auth_key, auth_md5, auth );
|
||||
*auth_md5_ptr = 0;
|
||||
|
||||
if ( !strcmp( auth, auth_md5 ) ) {
|
||||
Debug(1, "Checking auth_key '%s' -> auth_md5 '%s' == '%s'",
|
||||
auth_key, auth_md5, auth);
|
||||
|
||||
if ( !strcmp(auth, auth_md5) ) {
|
||||
// We have a match
|
||||
User *user = new User( dbrow );
|
||||
Debug(1, "Authenticated user '%s'", user->getUsername() );
|
||||
mysql_free_result( result );
|
||||
return( user );
|
||||
User *user = new User(dbrow);
|
||||
Debug(1, "Authenticated user '%s'", user->getUsername());
|
||||
mysql_free_result(result);
|
||||
return user;
|
||||
} else {
|
||||
Debug(1, "No match for %s", auth );
|
||||
Debug(1, "No match for %s", auth);
|
||||
}
|
||||
}
|
||||
}
|
||||
mysql_free_result( result );
|
||||
#else // HAVE_DECL_MD5
|
||||
Error( "You need to build with gnutls or openssl installed to use hash based authentication" );
|
||||
#endif // HAVE_DECL_MD5
|
||||
Debug(1, "No user found for auth_key %s", auth );
|
||||
return 0;
|
||||
}
|
||||
} // end foreach hour
|
||||
} // end foreach user
|
||||
mysql_free_result(result);
|
||||
#else // HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT
|
||||
Error("You need to build with gnutls or openssl to use hash based auth");
|
||||
#endif // HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT
|
||||
Debug(1, "No user found for auth_key %s", auth);
|
||||
return NULL;
|
||||
} // end User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
|
||||
|
||||
//Function to check Username length
|
||||
bool checkUser ( const char *username) {
|
||||
if ( ! username )
|
||||
// Function to check Username length
|
||||
bool checkUser(const char *username) {
|
||||
if ( !username )
|
||||
return false;
|
||||
if ( strlen(username) > 32 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
//Function to check password length
|
||||
bool checkPass (const char *password) {
|
||||
|
||||
// Function to check password length
|
||||
bool checkPass(const char *password) {
|
||||
if ( !password )
|
||||
return false;
|
||||
if ( strlen(password) > 64 )
|
||||
|
|
24
src/zms.cpp
24
src/zms.cpp
|
@ -184,7 +184,7 @@ int main(int argc, const char *argv[]) {
|
|||
logInit(log_id_string);
|
||||
|
||||
if ( config.opt_use_auth ) {
|
||||
User *user = 0;
|
||||
User *user = NULL;
|
||||
|
||||
if ( jwt_token_str != "" ) {
|
||||
// user = zmLoadTokenUser(jwt_token_str, config.auth_hash_ips);
|
||||
|
@ -195,19 +195,11 @@ int main(int argc, const char *argv[]) {
|
|||
} else {
|
||||
Error("Bad username");
|
||||
}
|
||||
|
||||
} else {
|
||||
// if ( strcmp( config.auth_relay, "hashed" ) == 0 )
|
||||
{
|
||||
if ( *auth ) {
|
||||
user = zmLoadAuthUser(auth, config.auth_hash_ips);
|
||||
}
|
||||
}
|
||||
// else if ( strcmp( config.auth_relay, "plain" ) == 0 )
|
||||
{
|
||||
if ( username.length() && password.length() ) {
|
||||
user = zmLoadUser(username.c_str(), password.c_str());
|
||||
}
|
||||
if ( *auth ) {
|
||||
user = zmLoadAuthUser(auth, config.auth_hash_ips);
|
||||
} else if ( username.length() && password.length() ) {
|
||||
user = zmLoadUser(username.c_str(), password.c_str());
|
||||
}
|
||||
}
|
||||
if ( !user ) {
|
||||
|
@ -218,11 +210,15 @@ int main(int argc, const char *argv[]) {
|
|||
return 0;
|
||||
}
|
||||
if ( !ValidateAccess(user, monitor_id) ) {
|
||||
delete user;
|
||||
user = NULL;
|
||||
fputs("HTTP/1.0 403 Forbidden\r\n\r\n", stdout);
|
||||
logTerm();
|
||||
zmDbClose();
|
||||
return 0;
|
||||
}
|
||||
delete user;
|
||||
user = NULL;
|
||||
} // end if config.opt_use_auth
|
||||
|
||||
hwcaps_detect();
|
||||
|
@ -336,5 +332,5 @@ int main(int argc, const char *argv[]) {
|
|||
logTerm();
|
||||
zmDbClose();
|
||||
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ class Monitor extends ZM_Object {
|
|||
'Height' => null,
|
||||
'Colours' => 4,
|
||||
'Palette' => '0',
|
||||
'Orientation' => null,
|
||||
'Orientation' => 'ROTATE_0',
|
||||
'Deinterlacing' => 0,
|
||||
'DecoderHWAccelName' => null,
|
||||
'DecoderHWAccelDevice' => null,
|
||||
|
@ -495,12 +495,16 @@ class Monitor extends ZM_Object {
|
|||
}
|
||||
}
|
||||
if ( !count($options) ) {
|
||||
if ( $command == 'quit' ) {
|
||||
$options['command'] = 'quit';
|
||||
} else if ( $command == 'start' ) {
|
||||
$options['command'] = 'start';
|
||||
} else if ( $command == 'stop' ) {
|
||||
$options['command'] = 'stop';
|
||||
|
||||
if ( $command == 'quit' or $command == 'start' or $command == 'stop' ) {
|
||||
# These are special as we now run zmcontrol as a daemon through zmdc.
|
||||
$status = daemonStatus('zmcontrol.pl', array('--id', $this->{'Id'}));
|
||||
Logger::Debug("Current status $status");
|
||||
if ( $status or ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) ) {
|
||||
daemonControl($command, 'zmcontrol.pl', '--id '.$this->{'Id'});
|
||||
return;
|
||||
}
|
||||
$options['command'] = $command;
|
||||
} else {
|
||||
Warning("No commands to send to zmcontrol from $command");
|
||||
return false;
|
||||
|
@ -538,12 +542,12 @@ class Monitor extends ZM_Object {
|
|||
$url = ZM_BASE_PROTOCOL . '://'.$Server->Hostname().'/zm/api/monitors/daemonControl/'.$this->{'Id'}.'/'.$command.'/zmcontrol.pl.json';
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||
$url .= '?auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||
$url .= '?auth='.generateAuthHash(ZM_AUTH_HASH_IPS);
|
||||
} else if ( ZM_AUTH_RELAY == 'plain' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
$url = '?pass='.$_SESSION['password'];
|
||||
$url .= '?user='.$_SESSION['username'];
|
||||
$url .= '?pass='.$_SESSION['password'];
|
||||
} else if ( ZM_AUTH_RELAY == 'none' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
$url .= '?user='.$_SESSION['username'];
|
||||
}
|
||||
}
|
||||
Logger::Debug("sending command to $url");
|
||||
|
|
|
@ -249,7 +249,7 @@ class ZM_Object {
|
|||
}
|
||||
}
|
||||
} else if ( array_key_exists($field, $this->defaults) ) {
|
||||
if ( is_array($this->defaults[$field]) ) {
|
||||
if ( is_array($this->defaults[$field]) and isset($this->defaults[$field]['default']) ) {
|
||||
$default = $this->defaults[$field]['default'];
|
||||
} else {
|
||||
$default = $this->defaults[$field];
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
namespace ZM;
|
||||
require_once('database.php');
|
||||
require_once('Object.php');
|
||||
|
||||
|
||||
class Zone extends ZM_Object {
|
||||
protected static $table = 'Zones';
|
||||
|
||||
protected $defaults = array(
|
||||
'Id' => null,
|
||||
'Name' => '',
|
||||
'Type' => 'Active',
|
||||
'Units' => 'Pixels',
|
||||
'CheckMethod' => 'Blobs',
|
||||
'MinPixelThreshold' => null,
|
||||
'MaxPixelThreshold' => null,
|
||||
'MinAlarmPixels' => null,
|
||||
'MaxAlarmPixels' => null,
|
||||
'FilterX' => null,
|
||||
'FilterY' => null,
|
||||
'MinFilterPixels' => null,
|
||||
'MaxFilterPixels' => null,
|
||||
'MinBlobPixels' => null,
|
||||
'MaxBlobPixels' => null,
|
||||
'MinBlobs' => null,
|
||||
'MaxBlobs' => null,
|
||||
'OverloadFrames' => 0,
|
||||
'ExtendAlarmFrames' => 0,
|
||||
);
|
||||
|
||||
public static function find( $parameters = array(), $options = array() ) {
|
||||
return ZM_Object::_find(get_class(), $parameters, $options);
|
||||
}
|
||||
|
||||
public static function find_one( $parameters = array(), $options = array() ) {
|
||||
return ZM_Object::_find_one(get_class(), $parameters, $options);
|
||||
}
|
||||
|
||||
} # end class Zone
|
||||
?>
|
|
@ -52,6 +52,9 @@ require_once('includes/Event.php');
|
|||
require_once('includes/Group.php');
|
||||
require_once('includes/Monitor.php');
|
||||
|
||||
global $Servers;
|
||||
$Servers = ZM\Server::find();
|
||||
|
||||
if (
|
||||
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
|
||||
or
|
||||
|
@ -71,7 +74,7 @@ define('ZM_BASE_URL', '');
|
|||
|
||||
require_once('includes/functions.php');
|
||||
if ( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ) {
|
||||
ZM\Logger::Debug("OPTIONS Method, only doing CORS");
|
||||
ZM\Logger::Debug('OPTIONS Method, only doing CORS');
|
||||
# Add Cross domain access headers
|
||||
CORSHeaders();
|
||||
return;
|
||||
|
@ -152,8 +155,6 @@ if (
|
|||
setcookie('zmCSS', $css, time()+3600*24*30*12*10);
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Running is global but only do the daemonCheck if it is actually needed
|
||||
$running = null;
|
||||
|
||||
|
@ -174,7 +175,6 @@ $user = null;
|
|||
if ( isset($_REQUEST['view']) )
|
||||
$view = detaintPath($_REQUEST['view']);
|
||||
|
||||
|
||||
# Add CSP Headers
|
||||
$cspNonce = bin2hex(zm_random_bytes(16));
|
||||
|
||||
|
|
|
@ -25,15 +25,15 @@ function controlFocus($monitor, $cmds) {
|
|||
?>
|
||||
<div class="arrowControl focusControls">
|
||||
<div class="arrowLabel"><?php echo translate('Near') ?></div>
|
||||
<button type="button" class="longArrowBtn upBtn" value="<?php echo $cmds['FocusNear'] ?>" data-on-click-this="controlCmd" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowCenter"<?php if ( $control->CanFocusCon() ) { ?> data-on-click-this="controlCmd" value="<?php echo $cmds['FocusStop'] ?>"<?php } ?>><?php echo translate('Focus') ?></button>
|
||||
<button type="button" class="longArrowBtn downBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['FocusFar'] ?>" data-xtell="0" data-ytell="1"></button>
|
||||
<button type="button" class="longArrowBtn upBtn" value="<?php echo $cmds['FocusNear'] ?>" data-on-click="controlCmd" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowCenter"<?php if ( $control->CanFocusCon() ) { ?> data-on-click="controlCmd" value="<?php echo $cmds['FocusStop'] ?>"<?php } ?>><?php echo translate('Focus') ?></button>
|
||||
<button type="button" class="longArrowBtn downBtn" data-on-click="controlCmd" value="<?php echo $cmds['FocusFar'] ?>" data-xtell="0" data-ytell="1"></button>
|
||||
<div class="arrowLabel"><?php echo translate('Far') ?></div>
|
||||
<?php
|
||||
if ( $control->CanAutoFocus() ) {
|
||||
?>
|
||||
<button type="button" class="ptzTextBtn" value="<?php echo $cmds['FocusAuto'] ?>" data-on-click-this="controlCmd"><?php echo translate('Auto') ?></button>
|
||||
<button type="button" class="ptzTextBtn" value="<?php echo $cmds['FocusMan'] ?>" data-on-click-this="controlCmd"><?php echo translate('Man') ?></button>
|
||||
<button type="button" class="ptzTextBtn" value="<?php echo $cmds['FocusAuto'] ?>" data-on-click="controlCmd"><?php echo translate('Auto') ?></button>
|
||||
<button type="button" class="ptzTextBtn" value="<?php echo $cmds['FocusMan'] ?>" data-on-click="controlCmd"><?php echo translate('Man') ?></button>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -48,15 +48,15 @@ function controlZoom($monitor, $cmds) {
|
|||
?>
|
||||
<div class="arrowControl zoomControls">
|
||||
<div class="arrowLabel"><?php echo translate('Tele') ?></div>
|
||||
<button type="button" class="longArrowBtn upBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['ZoomTele'] ?>" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowCenter"<?php if ( $control->CanZoomCon() ) { ?> data-on-click-this="controlCmd" value="<?php echo $cmds['ZoomStop'] ?>"<?php } ?>><?php echo translate('Zoom') ?></button>
|
||||
<button type="button" class="longArrowBtn downBtn" data-on-click-data="controlCmd" value="<?php echo $cmds['ZoomWide'] ?>" data-xtell="0" data-ytell="1"></button>
|
||||
<button type="button" class="longArrowBtn upBtn" data-on-click="controlCmd" value="<?php echo $cmds['ZoomTele'] ?>" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowCenter"<?php if ( $control->CanZoomCon() ) { ?> data-on-click="controlCmd" value="<?php echo $cmds['ZoomStop'] ?>"<?php } ?>><?php echo translate('Zoom') ?></button>
|
||||
<button type="button" class="longArrowBtn downBtn" data-on-click="controlCmd" value="<?php echo $cmds['ZoomWide'] ?>" data-xtell="0" data-ytell="1"></button>
|
||||
<div class="arrowLabel"><?php echo translate('Wide') ?></div>
|
||||
<?php
|
||||
if ( $control->CanAutoZoom() ) {
|
||||
?>
|
||||
<button type="button" class="ptzTextBtn" value="Auto" data-on-click-this="controlCmd" value="<?php echo $cmds['ZoomAuto'] ?>"><?php echo translate('Auto') ?></button>
|
||||
<button type="button" class="ptzTextBtn" value="Man" data-on-click-this="controlCmd" value="<?php echo $cmds['ZoomMan'] ?>"><?php echo translate('Man') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['ZoomAuto'] ?>"><?php echo translate('Auto') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['ZoomMan'] ?>"><?php echo translate('Man') ?></button>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -70,15 +70,15 @@ function controlIris($monitor, $cmds) {
|
|||
?>
|
||||
<div class="arrowControl irisControls">
|
||||
<div class="arrowLabel"><?php echo translate('Open') ?></div>
|
||||
<button type="button" class="longArrowBtn upBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['IrisOpen'] ?>" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowCenter"<?php if ( $control->CanIrisCon() ) { ?> data-on-click-this="controlCmd" value="<?php echo $cmds['IrisStop'] ?>"<?php } ?>><?php echo translate('Iris') ?></button>
|
||||
<button type="button" class="longArrowBtn downBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['IrisClose'] ?>" data-xtell="0" data-ytell="1"></button>
|
||||
<button type="button" class="longArrowBtn upBtn" data-on-click="controlCmd" value="<?php echo $cmds['IrisOpen'] ?>" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowCenter"<?php if ( $control->CanIrisCon() ) { ?> data-on-click="controlCmd" value="<?php echo $cmds['IrisStop'] ?>"<?php } ?>><?php echo translate('Iris') ?></button>
|
||||
<button type="button" class="longArrowBtn downBtn" data-on-click="controlCmd" value="<?php echo $cmds['IrisClose'] ?>" data-xtell="0" data-ytell="1"></button>
|
||||
<div class="arrowLabel"><?php echo translate('Close') ?></div>
|
||||
<?php
|
||||
if ( $control->CanAutoIris() ) {
|
||||
?>
|
||||
<button type="button" class="ptzTextBtn" value="Auto" data-on-click-this="controlCmd" value="<?php echo $cmds['IrisAuto'] ?>"><?php echo translate('Auto') ?></button>
|
||||
<button type="button" class="ptzTextBtn" value="Man" data-on-click-this="controlCmd" value="<?php echo $cmds['IrisMan'] ?>"><?php echo translate('Man') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['IrisAuto'] ?>"><?php echo translate('Auto') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['IrisMan'] ?>"><?php echo translate('Man') ?></button>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -93,15 +93,15 @@ function controlWhite($monitor, $cmds) {
|
|||
?>
|
||||
<div class="arrowControl whiteControls">
|
||||
<div class="arrowLabel"><?php echo translate('In') ?></div>
|
||||
<button type="button" class="longArrowBtn upBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteIn'] ?>" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowCenter"<?php if ( $control->CanWhiteCon() ) { ?> data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteStop'] ?>"<?php } ?>><?php echo translate('White') ?></button>
|
||||
<button type="button" class="longArrowBtn downBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteOut'] ?>" data-xtell="0" data-ytell="1)"></button>
|
||||
<button type="button" class="longArrowBtn upBtn" data-on-click="controlCmd" value="<?php echo $cmds['WhiteIn'] ?>" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowCenter"<?php if ( $control->CanWhiteCon() ) { ?> data-on-click="controlCmd" value="<?php echo $cmds['WhiteStop'] ?>"<?php } ?>><?php echo translate('White') ?></button>
|
||||
<button type="button" class="longArrowBtn downBtn" data-on-click="controlCmd" value="<?php echo $cmds['WhiteOut'] ?>" data-xtell="0" data-ytell="1)"></button>
|
||||
<div class="arrowLabel"><?php echo translate('Out') ?></div>
|
||||
<?php
|
||||
if ( $control->CanAutoWhite() ) {
|
||||
?>
|
||||
<button type="button" class="ptzTextBtn" value="Auto" data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteAuto'] ?>"><?php echo translate('Auto') ?></button>
|
||||
<button type="button" class="ptzTextBtn" value="Man" data-on-click-this="controlCmd" value="<?php echo $cmds['WhiteMan'] ?>"><?php echo translate('Man') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['WhiteAuto'] ?>"><?php echo translate('Auto') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['WhiteMan'] ?>"><?php echo translate('Man') ?></button>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -122,19 +122,19 @@ function controlPanTilt($monitor, $cmds) {
|
|||
$hasTilt = $control->CanTilt();
|
||||
$hasDiag = $hasPan && $hasTilt && $control->CanMoveDiag();
|
||||
?>
|
||||
<button type="button" class="arrowBtn upLeftBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveUpLeft'] ?>" data-xtell="-1" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowBtn upBtn<?php echo $hasTilt?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveUp'] ?>" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowBtn upRightBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveUpRight'] ?>" data-xtell="1" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowBtn leftBtn<?php echo $hasPan?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveLeft'] ?>" data-xtell="-1" data-ytell="0"></button>
|
||||
<button type="button" class="arrowBtn upLeftBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveUpLeft'] ?>" data-xtell="-1" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowBtn upBtn<?php echo $hasTilt?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveUp'] ?>" data-xtell="0" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowBtn upRightBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveUpRight'] ?>" data-xtell="1" data-ytell="-1"></button>
|
||||
<button type="button" class="arrowBtn leftBtn<?php echo $hasPan?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveLeft'] ?>" data-xtell="-1" data-ytell="0"></button>
|
||||
<?php if ( isset($cmds['Center']) ) { ?>
|
||||
<button type="button" class="arrowBtn centerBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Center'] ?>"></button>
|
||||
<button type="button" class="arrowBtn centerBtn" data-on-click="controlCmd" value="<?php echo $cmds['Center'] ?>"></button>
|
||||
<?php } else { ?>
|
||||
<button type="button" class="arrowBtn NocenterBtn"></button>
|
||||
<?php } ?>
|
||||
<button type="button" class="arrowBtn rightBtn<?php echo $hasPan?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveRight'] ?>" data-xtell="1" data-ytell="0"></button>
|
||||
<button type="button" class="arrowBtn downLeftBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveDownLeft'] ?>" data-xtell="-1" data-ytell="1"></button>
|
||||
<button type="button" class="arrowBtn downBtn<?php echo $hasTilt?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveDown'] ?>" data-xtell="0" data-ytell="1"></button>
|
||||
<button type="button" class="arrowBtn downRightBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['MoveDownRight'] ?>" data-xtell="1" data-ytell="1"></button>
|
||||
<button type="button" class="arrowBtn rightBtn<?php echo $hasPan?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveRight'] ?>" data-xtell="1" data-ytell="0"></button>
|
||||
<button type="button" class="arrowBtn downLeftBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveDownLeft'] ?>" data-xtell="-1" data-ytell="1"></button>
|
||||
<button type="button" class="arrowBtn downBtn<?php echo $hasTilt?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveDown'] ?>" data-xtell="0" data-ytell="1"></button>
|
||||
<button type="button" class="arrowBtn downRightBtn<?php echo $hasDiag?'':' invisible' ?>" data-on-click="controlCmd" value="<?php echo $cmds['MoveDownRight'] ?>" data-xtell="1" data-ytell="1"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
@ -162,7 +162,7 @@ function controlPresets($monitor, $cmds) {
|
|||
<?php
|
||||
for ( $i = 1; $i <= $control->NumPresets(); $i++ ) {
|
||||
?>
|
||||
<button type="button" class="ptzNumBtn" title="<?php echo isset($labels[$i])?htmlentities($labels[$i]):'' ?>" value="<?php echo $i ?>" data-on-click-this="controlCmd" value="<?php echo $cmds['PresetGoto'] ?><?php echo $i ?>"/><?php echo $i ?></button>
|
||||
<button type="button" class="ptzNumBtn" title="<?php echo isset($labels[$i])?htmlentities($labels[$i]):'' ?>" data-on-click="controlCmd" value="<?php echo $cmds['PresetGoto'].$i ?>"/><?php echo $i ?></button>
|
||||
<?php
|
||||
} // end foreach preset
|
||||
?>
|
||||
|
@ -171,7 +171,7 @@ function controlPresets($monitor, $cmds) {
|
|||
<?php
|
||||
if ( $control->HasHomePreset() ) {
|
||||
?>
|
||||
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['PresetHome'] ?>"><?php echo translate('Home') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['PresetHome'] ?>"><?php echo translate('Home') ?></button>
|
||||
<?php
|
||||
}
|
||||
if ( canEdit('Monitors') && $control->CanSetPresets() ) {
|
||||
|
@ -196,22 +196,22 @@ function controlPower($monitor, $cmds) {
|
|||
<?php
|
||||
if ( $control->CanWake() ) {
|
||||
?>
|
||||
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Wake'] ?>"><?php echo translate('Wake') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['Wake'] ?>"><?php echo translate('Wake') ?></button>
|
||||
<?php
|
||||
}
|
||||
if ( $control->CanSleep() ) {
|
||||
?>
|
||||
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Sleep'] ?>"><?php echo translate('Sleep') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['Sleep'] ?>"><?php echo translate('Sleep') ?></button>
|
||||
<?php
|
||||
}
|
||||
if ( $control->CanReset() ) {
|
||||
?>
|
||||
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Reset'] ?>"><?php echo translate('Reset') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['Reset'] ?>"><?php echo translate('Reset') ?></button>
|
||||
<?php
|
||||
}
|
||||
if ( $control->CanReboot() ) {
|
||||
?>
|
||||
<button type="button" class="ptzTextBtn" data-on-click-this="controlCmd" value="<?php echo $cmds['Reboot'] ?>"><?php echo translate('Reboot') ?></button>
|
||||
<button type="button" class="ptzTextBtn" data-on-click="controlCmd" value="<?php echo $cmds['Reboot'] ?>"><?php echo translate('Reboot') ?></button>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -223,9 +223,7 @@ function controlPower($monitor, $cmds) {
|
|||
|
||||
function ptzControls($monitor) {
|
||||
$control = $monitor->Control();
|
||||
//ZM\Error("Control: " . print_r($control,true));
|
||||
$cmds = $control->commands();
|
||||
//ZM\Error("Cmds: " . print_r($cmds, true));
|
||||
ob_start();
|
||||
?>
|
||||
<div class="controlsPanel">
|
||||
|
|
|
@ -182,8 +182,8 @@ window.addEventListener("DOMContentLoaded", function onSkinDCL() {
|
|||
return;
|
||||
}
|
||||
|
||||
el.onclick = function() {
|
||||
window[fnName]();
|
||||
el.onclick = function(ev) {
|
||||
window[fnName](ev);
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -71,6 +71,22 @@ var focusWindow = <?php echo !empty($focusWindow)?'true':'false' ?>;
|
|||
var imagePrefix = "<?php echo '?view=image&eid=' ?>";
|
||||
|
||||
var auth_hash;
|
||||
<?php if ( ZM_OPT_USE_AUTH && ZM_AUTH_HASH_LOGINS ) { ?>
|
||||
auth_hash = '<?php echo generateAuthHash(ZM_AUTH_HASH_IPS) ?>';
|
||||
<?php } ?>
|
||||
var auth_relay;
|
||||
<?php
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||
echo ' auth_hash = \''.generateAuthHash(ZM_AUTH_HASH_IPS).'\';
|
||||
';
|
||||
} else if ( ZM_AUTH_RELAY == 'plain' ) {
|
||||
// password probably needs to be escaped
|
||||
echo ' auth_relay=\'username='.$_SESSION['username'].'&password='.$_SESSION['password'].'\';
|
||||
';
|
||||
} else if ( ZM_AUTH_RELAY == 'none' ) {
|
||||
// password probably needs to be escaped
|
||||
echo ' auth_relay=\'username='.$_SESSION['username'].'\';
|
||||
';
|
||||
} else {
|
||||
ZM\Error('Unknown value for ZM_AUTH_RELAY ' . ZM_AUTH_RELAY);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -258,7 +258,7 @@ while ( $event_row = dbFetchNext($results) ) {
|
|||
echo '<td class="colThumbnail">';
|
||||
$imgSrc = $event->getThumbnailSrc(array(),'&');
|
||||
$streamSrc = $event->getStreamSrc(array(
|
||||
'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single'), '&');
|
||||
'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single', 'rate'=>'400'), '&');
|
||||
|
||||
$imgHtml = '<img id="thumbnail'.$event->Id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($event->ThumbnailWidth()) .'px;height:'. validInt($event->ThumbnailHeight()).'px;" stream_src="'.$streamSrc.'" still_src="'.$imgSrc.'"/>';
|
||||
echo '<a href="?view=event&eid='. $event->Id().$filterQuery.$sortQuery.'&page=1">'.$imgHtml.'</a>';
|
||||
|
|
|
@ -13,6 +13,8 @@ function Monitor(monitorData) {
|
|||
this.streamCmdParms = 'view=request&request=stream&connkey='+this.connKey;
|
||||
if ( auth_hash ) {
|
||||
this.streamCmdParms += '&auth='+auth_hash;
|
||||
} else if ( auth_relay ) {
|
||||
this.streamCmdParms += '&'+auth_relay;
|
||||
}
|
||||
this.streamCmdTimer = null;
|
||||
this.type = monitorData.type;
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
}
|
||||
?>';
|
||||
|
||||
if ( querySuffix == '?view=login' ) {
|
||||
if ( querySuffix == '?view=login' || querySuffix == '' ) {
|
||||
// If we didn't redirect elsewhere, then don't show login page, go to console
|
||||
querySuffix = '?view=console';
|
||||
}
|
||||
var newUrl = querySuffix;
|
||||
|
||||
console.log("Redirecting to" + newUrl + ' ' + thisUrl);
|
||||
console.log("Current location: " + window.location);
|
||||
console.log("Redirecting to (" + newUrl + ') from :' + thisUrl);
|
||||
window.location.replace(newUrl);
|
||||
}
|
||||
).delay( 500 );
|
||||
|
|
|
@ -546,42 +546,62 @@ function getEventCmdResponse( respObj, respText ) {
|
|||
} );
|
||||
|
||||
for ( var i = 0; i < dbEvents.length; i++ ) {
|
||||
var event = dbEvents[i];
|
||||
var row = $('event'+event.Id);
|
||||
var zm_event = dbEvents[i];
|
||||
var row = $('event'+zm_event.Id);
|
||||
var newEvent = (row == null ? true : false);
|
||||
if ( newEvent ) {
|
||||
row = new Element( 'tr', {'id': 'event'+event.Id} );
|
||||
new Element( 'td', {'class': 'colId'} ).inject( row );
|
||||
new Element( 'td', {'class': 'colName'} ).inject( row );
|
||||
new Element( 'td', {'class': 'colTime'} ).inject( row );
|
||||
new Element( 'td', {'class': 'colSecs'} ).inject( row );
|
||||
new Element( 'td', {'class': 'colFrames'} ).inject( row );
|
||||
new Element( 'td', {'class': 'colScore'} ).inject( row );
|
||||
new Element( 'td', {'class': 'colDelete'} ).inject( row );
|
||||
row = new Element('tr', {'id': 'event'+zm_event.Id});
|
||||
new Element('td', {'class': 'colId'}).inject(row);
|
||||
new Element('td', {'class': 'colName'}).inject(row);
|
||||
new Element('td', {'class': 'colTime'}).inject(row);
|
||||
new Element('td', {'class': 'colSecs'}).inject(row);
|
||||
new Element('td', {'class': 'colFrames'}).inject(row);
|
||||
new Element('td', {'class': 'colScore'}).inject(row);
|
||||
new Element('td', {'class': 'colDelete'}).inject(row);
|
||||
|
||||
var link = new Element( 'a', {'href': '#', 'events': {'click': createEventPopup.pass( [event.Id, '&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId+'&page=1&popup=1', event.Width, event.Height] )}});
|
||||
link.set( 'text', event.Id );
|
||||
link.inject( row.getElement( 'td.colId' ) );
|
||||
var link = new Element('a', {
|
||||
'href': '#',
|
||||
'events': {
|
||||
'click': createEventPopup.pass( [
|
||||
zm_event.Id,
|
||||
'&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId+'&page=1&popup=1',
|
||||
zm_event.Width,
|
||||
zm_event.Height
|
||||
] )
|
||||
}
|
||||
});
|
||||
link.set('text', zm_event.Id);
|
||||
link.inject(row.getElement('td.colId'));
|
||||
|
||||
link = new Element( 'a', {'href': '#', 'events': {'click': createEventPopup.pass( [event.Id, '&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId+'&page=1&popup=1', event.Width, event.Height] )}});
|
||||
link.set( 'text', event.Name );
|
||||
link.inject( row.getElement( 'td.colName' ) );
|
||||
link = new Element('a', {
|
||||
'href': '#',
|
||||
'events': {
|
||||
'click': createEventPopup.pass( [
|
||||
zm_event.Id,
|
||||
'&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId+'&page=1&popup=1',
|
||||
zm_event.Width,
|
||||
zm_event.Height
|
||||
] )
|
||||
}
|
||||
});
|
||||
link.set('text', zm_event.Name);
|
||||
link.inject(row.getElement('td.colName'));
|
||||
|
||||
row.getElement( 'td.colTime' ).set( 'text', event.StartTime );
|
||||
row.getElement( 'td.colSecs' ).set( 'text', event.Length );
|
||||
row.getElement('td.colTime').set('text', zm_event.StartTime);
|
||||
row.getElement('td.colSecs').set('text', zm_event.Length);
|
||||
|
||||
link = new Element( 'a', {'href': '#', 'events': {'click': createFramesPopup.pass( [event.Id, event.Width, event.Height] )}});
|
||||
link.set( 'text', event.Frames+'/'+event.AlarmFrames );
|
||||
link.inject( row.getElement( 'td.colFrames' ) );
|
||||
link = new Element('a', {'href': '#', 'events': {'click': createFramesPopup.pass( [zm_event.Id, zm_event.Width, zm_event.Height] )}});
|
||||
link.set('text', zm_event.Frames+'/'+zm_event.AlarmFrames);
|
||||
link.inject(row.getElement('td.colFrames'));
|
||||
|
||||
link = new Element( 'a', {'href': '#', 'events': {'click': createFramePopup.pass( [event.Id, '0', event.Width, event.Height] )}});
|
||||
link.set( 'text', event.AvgScore+'/'+event.MaxScore );
|
||||
link.inject( row.getElement( 'td.colScore' ) );
|
||||
link = new Element('a', {'href': '#', 'events': {'click': createFramePopup.pass( [zm_event.Id, '0', zm_event.Width, zm_event.Height] )}});
|
||||
link.set('text', zm_event.AvgScore+'/'+zm_event.MaxScore);
|
||||
link.inject(row.getElement('td.colScore'));
|
||||
|
||||
link = new Element( 'button', {
|
||||
link = new Element('button', {
|
||||
'type': 'button',
|
||||
'title': deleteString,
|
||||
'data-event-id': event.Id,
|
||||
'data-event-id': zm_event.Id,
|
||||
'events': {
|
||||
'click': function(e) {
|
||||
var event_id = e.target.getAttribute('data-event-id');
|
||||
|
@ -608,14 +628,14 @@ function getEventCmdResponse( respObj, respText ) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
row.getElement('td.colName a').set('text', event.Name);
|
||||
row.getElement('td.colSecs').set('text', event.Length);
|
||||
row.getElement('td.colFrames a').set('text', event.Frames+'/'+event.AlarmFrames);
|
||||
row.getElement('td.colScore a').set('text', event.AvgScore+'/'+event.MaxScore);
|
||||
row.getElement('td.colName a').set('text', zm_event.Name);
|
||||
row.getElement('td.colSecs').set('text', zm_event.Length);
|
||||
row.getElement('td.colFrames a').set('text', zm_event.Frames+'/'+zm_event.AlarmFrames);
|
||||
row.getElement('td.colScore a').set('text', zm_event.AvgScore+'/'+zm_event.MaxScore);
|
||||
row.removeClass('recent');
|
||||
}
|
||||
row.addClass('updated');
|
||||
}
|
||||
} // end foreach event
|
||||
|
||||
var rows = $(eventListBody).getElements('tr');
|
||||
for ( var i = 0; i < rows.length; i++ ) {
|
||||
|
@ -631,7 +651,7 @@ function getEventCmdResponse( respObj, respText ) {
|
|||
}
|
||||
} else {
|
||||
checkStreamForErrors('getEventCmdResponse', respObj);
|
||||
}
|
||||
} // end if objresult == ok
|
||||
|
||||
var eventCmdTimeout = eventsRefreshTimeout;
|
||||
if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT ) {
|
||||
|
@ -672,7 +692,8 @@ function getControlResponse(respObj, respText) {
|
|||
}
|
||||
}
|
||||
|
||||
function controlCmd(button) {
|
||||
function controlCmd(event) {
|
||||
button = event.target;
|
||||
control = button.getAttribute('value');
|
||||
xtell = button.getAttribute('xtell');
|
||||
ytell = button.getAttribute('ytell');
|
||||
|
@ -687,7 +708,7 @@ function controlCmd(button) {
|
|||
var y = event.pageY - coords.top;
|
||||
|
||||
if ( xtell ) {
|
||||
var xge = parseInt( (x*100)/coords.width );
|
||||
var xge = parseInt((x*100)/coords.width);
|
||||
if ( xtell == -1 ) {
|
||||
xge = 100 - xge;
|
||||
} else if ( xtell == 2 ) {
|
||||
|
@ -696,7 +717,7 @@ function controlCmd(button) {
|
|||
locParms += '&xge='+xge;
|
||||
}
|
||||
if ( ytell ) {
|
||||
var yge = parseInt( (y*100)/coords.height );
|
||||
var yge = parseInt((y*100)/coords.height);
|
||||
if ( ytell == -1 ) {
|
||||
yge = 100 - yge;
|
||||
} else if ( ytell == 2 ) {
|
||||
|
|
|
@ -782,20 +782,23 @@ include('_monitor_source_nvsocket.php');
|
|||
} else if ( $monitor->Type() == 'Remote' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('RemoteProtocol') ?></td><td><?php echo htmlSelect( "newMonitor[Protocol]", $remoteProtocols, $monitor->Protocol(), "updateMethods( this );if(this.value=='rtsp'){\$('RTSPDescribe').setStyle('display','table-row');}else{\$('RTSPDescribe').hide();}" ); ?></td></tr>
|
||||
<?php
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo translate('RemoteMethod') ?></td>
|
||||
<td>
|
||||
<?php
|
||||
if ( !$monitor->Protocol() || $monitor->Protocol() == 'http' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('RemoteMethod') ?></td><td><?php echo htmlSelect( "newMonitor[Method]", $httpMethods, $monitor->Method() ); ?></td></tr>
|
||||
<?php
|
||||
echo htmlSelect('newMonitor[Method]', $httpMethods, $monitor->Method() );
|
||||
} else {
|
||||
?>
|
||||
<tr><td><?php echo translate('RemoteMethod') ?></td><td><?php echo htmlSelect( "newMonitor[Method]", $rtspMethods, $monitor->Method() ); ?></td></tr>
|
||||
<?php
|
||||
echo htmlSelect('newMonitor[Method]', $rtspMethods, $monitor->Method() );
|
||||
}
|
||||
?>
|
||||
<tr><td><?php echo translate('RemoteHostName') ?></td><td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>" size="36"/></td></tr>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><?php echo translate('RemoteHostName') ?></td><td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>"/></td></tr>
|
||||
<tr><td><?php echo translate('RemoteHostPort') ?></td><td><input type="number" name="newMonitor[Port]" value="<?php echo validHtmlStr($monitor->Port()) ?>" size="6"/></td></tr>
|
||||
<tr><td><?php echo translate('RemoteHostPath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
|
||||
<tr><td><?php echo translate('RemoteHostPath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
|
||||
<?php
|
||||
} else if ( $monitor->Type() == 'File' ) {
|
||||
?>
|
||||
|
@ -803,23 +806,44 @@ include('_monitor_source_nvsocket.php');
|
|||
<?php
|
||||
} elseif ( $monitor->Type() == 'cURL' ) {
|
||||
?>
|
||||
<tr><td><?php echo 'URL' ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
|
||||
<tr><td><?php echo 'Username' ?></td><td><input type="text" name="newMonitor[User]" value="<?php echo validHtmlStr($monitor->User()) ?>" size="12"/></td></tr>
|
||||
<tr><td><?php echo 'Password' ?></td><td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($monitor->Pass()) ?>" size="12"/></td></tr>
|
||||
<tr><td><?php echo 'URL' ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
|
||||
<tr><td><?php echo 'Username' ?></td><td><input type="text" name="newMonitor[User]" value="<?php echo validHtmlStr($monitor->User()) ?>"/></td></tr>
|
||||
<tr><td><?php echo 'Password' ?></td><td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($monitor->Pass()) ?>"/></td></tr>
|
||||
<?php
|
||||
} elseif ( $monitor->Type() == 'WebSite' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('WebSiteUrl') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
|
||||
<tr><td><?php echo translate('Width') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" size="4";"/></td></tr>
|
||||
<tr><td><?php echo translate('Height') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" size="4";"/></td></tr>
|
||||
<tr><td><?php echo 'Web Site Refresh (Optional)' ?></td><td><input type="number" name="newMonitor[Refresh]" value="<?php echo validHtmlStr($monitor->Refresh()); ?>"/></td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('WebSiteUrl') ?></td>
|
||||
<td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('Width') ?> (<?php echo translate('Pixels') ?>)</td>
|
||||
<td><input type="number" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" size="4"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('Height') ?> (<?php echo translate('Pixels') ?>)</td>
|
||||
<td><input type="number" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" size="4"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo 'Web Site Refresh (Optional)' ?></td>
|
||||
<td><input type="number" name="newMonitor[Refresh]" value="<?php echo validHtmlStr($monitor->Refresh()) ?>"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
} elseif ( $monitor->Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) {
|
||||
} else if ( $monitor->Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) {
|
||||
?>
|
||||
<tr class="SourcePath"><td><?php echo translate('SourcePath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" /></td></tr>
|
||||
<tr><td><?php echo translate('RemoteMethod') ?> (<?php echo makePopupLink('?view=optionhelp&option=OPTIONS_RTSPTrans', 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td><td><?php echo htmlSelect( "newMonitor[Method]", $rtspFFMpegMethods, $monitor->Method() ); ?></td></tr>
|
||||
<tr class="SourcePath">
|
||||
<td><?php echo translate('SourcePath') ?></td>
|
||||
<td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php
|
||||
echo translate('RemoteMethod');
|
||||
echo makePopupLink('?view=optionhelp&option=OPTIONS_RTSPTrans', 'zmOptionHelp', 'optionhelp', '?' );
|
||||
?>)</td>
|
||||
<td><?php echo htmlSelect('newMonitor[Method]', $rtspFFMpegMethods, $monitor->Method()) ?></td>
|
||||
</tr>
|
||||
<tr class="SourceOptions">
|
||||
<td><?php echo translate('Options') ?> (<?php echo makePopupLink( '?view=optionhelp&option=OPTIONS_'.strtoupper($monitor->Type()), 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td>
|
||||
<td><?php echo translate('Options') ?> (<?php echo makePopupLink('?view=optionhelp&option=OPTIONS_'.strtoupper($monitor->Type()), 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td>
|
||||
<td><input type="text" name="newMonitor[Options]" value="<?php echo validHtmlStr($monitor->Options()) ?>"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
|
@ -840,10 +864,12 @@ include('_monitor_source_nvsocket.php');
|
|||
</tr>
|
||||
<?php
|
||||
}
|
||||
if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
|
||||
if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('TargetColorspace') ?></td><td><?php echo htmlSelect('newMonitor[Colours]', $Colours, $monitor->Colours() ); ?>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TargetColorspace') ?></td>
|
||||
<td><?php echo htmlSelect('newMonitor[Colours]', $Colours, $monitor->Colours()) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('CaptureResolution') ?> (<?php echo translate('Pixels') ?>)</td>
|
||||
<td>
|
||||
|
@ -884,18 +910,22 @@ if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
|
|||
<td><?php echo htmlselect('newMonitor[Orientation]', $orientations, $monitor->Orientation());?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
if ( $monitor->Type() == 'Local' ) {
|
||||
}
|
||||
if ( $monitor->Type() == 'Local' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts_v4l2 as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
|
||||
<?php
|
||||
<tr>
|
||||
<td><?php echo translate('Deinterlacing') ?></td>
|
||||
<td><?php echo htmlselect('newMonitor[Deinterlacing]', $deinterlaceopts_v4l2, $monitor->Deinterlacing())?></td>
|
||||
</tr>
|
||||
<?php
|
||||
} else if ( $monitor->Type() != 'WebSite' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('Deinterlacing') ?></td>
|
||||
<td><?php echo htmlselect('newMonitor[Deinterlacing]', $deinterlaceopts, $monitor->Deinterlacing())?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
if ( $monitor->Type() == 'Remote' ) {
|
||||
?>
|
||||
<tr id="RTSPDescribe"<?php if ( $monitor->Protocol()!= 'rtsp' ) { echo ' style="display:none;"'; } ?>><td><?php echo translate('RTSPDescribe') ?> (<?php echo makePopupLink( '?view=optionhelp&option=OPTIONS_RTSPDESCRIBE', 'zmOptionHelp', 'optionhelp', '?' ) ?>) </td><td><input type="checkbox" name="newMonitor[RTSPDescribe]" value="1"<?php if ( $monitor->RTSPDescribe() ) { ?> checked="checked"<?php } ?>/></td></tr>
|
||||
|
@ -939,15 +969,17 @@ if ( $monitor->Type() == 'Local' ) {
|
|||
|
||||
$videowriteropts[1] = 'X264 Encode';
|
||||
|
||||
if ($monitor->Type() == 'Ffmpeg' )
|
||||
if ( $monitor->Type() == 'Ffmpeg' )
|
||||
$videowriteropts[2] = 'H264 Camera Passthrough';
|
||||
else
|
||||
$videowriteropts[2] = array('text'=>'H264 Camera Passthrough - only for FFMPEG','disabled'=>1);
|
||||
|
||||
echo htmlselect( 'newMonitor[VideoWriter]', $videowriteropts, $monitor->VideoWriter() );
|
||||
echo htmlselect('newMonitor[VideoWriter]', $videowriteropts, $monitor->VideoWriter());
|
||||
?>
|
||||
</td></tr>
|
||||
<tr><td><?php echo translate('OptionalEncoderParam') ?></td><td><textarea name="newMonitor[EncoderParameters]" rows="4" cols="36"><?php echo validHtmlStr($monitor->EncoderParameters()) ?></textarea></td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('OptionalEncoderParam') ?></td>
|
||||
<td><textarea name="newMonitor[EncoderParameters]" rows="4" cols="36"><?php echo validHtmlStr($monitor->EncoderParameters()) ?></textarea></td></tr>
|
||||
<tr><td><?php echo translate('RecordAudio') ?></td><td>
|
||||
<?php if ( $monitor->Type() == 'Ffmpeg' ) { ?>
|
||||
<input type="checkbox" name="newMonitor[RecordAudio]" value="1"<?php if ( $monitor->RecordAudio() ) { ?> checked="checked"<?php } ?>/>
|
||||
|
@ -962,22 +994,52 @@ if ( $monitor->Type() == 'Local' ) {
|
|||
case 'timestamp' :
|
||||
{
|
||||
?>
|
||||
<tr><td><?php echo translate('TimestampLabelFormat') ?></td><td><input type="text" name="newMonitor[LabelFormat]" value="<?php echo validHtmlStr($monitor->LabelFormat()) ?>" size="32"/></td></tr>
|
||||
<tr><td><?php echo translate('TimestampLabelX') ?></td><td><input type="text" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($monitor->LabelX()) ?>" size="4"/></td></tr>
|
||||
<tr><td><?php echo translate('TimestampLabelY') ?></td><td><input type="text" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($monitor->LabelY()) ?>" size="4"/></td></tr>
|
||||
<tr><td><?php echo translate('TimestampLabelSize') ?></td><td><select name="newMonitor[LabelSize]"><?php foreach ( $label_size as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->LabelSize() ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TimestampLabelFormat') ?></td>
|
||||
<td><input type="text" name="newMonitor[LabelFormat]" value="<?php echo validHtmlStr($monitor->LabelFormat()) ?>"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TimestampLabelX') ?></td>
|
||||
<td><input type="number" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($monitor->LabelX()) ?>" size="4"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TimestampLabelY') ?></td>
|
||||
<td><input type="number" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($monitor->LabelY()) ?>" size="4"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TimestampLabelSize') ?></td>
|
||||
<td><?php echo htmlselect('newMonitor[LabelSize]', $label_size, $monitor->LabelSize()) ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
case 'buffers' :
|
||||
{
|
||||
?>
|
||||
<tr><td><?php echo translate('ImageBufferSize') ?></td><td><input type="text" name="newMonitor[ImageBufferCount]" value="<?php echo validHtmlStr($monitor->ImageBufferCount()) ?>" size="6"/></td></tr>
|
||||
<tr><td><?php echo translate('WarmupFrames') ?></td><td><input type="text" name="newMonitor[WarmupCount]" value="<?php echo validHtmlStr($monitor->WarmupCount()) ?>" size="4"/></td></tr>
|
||||
<tr><td><?php echo translate('PreEventImageBuffer') ?></td><td><input type="text" name="newMonitor[PreEventCount]" value="<?php echo validHtmlStr($monitor->PreEventCount()) ?>" size="4"/></td></tr>
|
||||
<tr><td><?php echo translate('PostEventImageBuffer') ?></td><td><input type="text" name="newMonitor[PostEventCount]" value="<?php echo validHtmlStr($monitor->PostEventCount()) ?>" size="4"/></td></tr>
|
||||
<tr><td><?php echo translate('StreamReplayBuffer') ?></td><td><input type="text" name="newMonitor[StreamReplayBuffer]" value="<?php echo validHtmlStr($monitor->StreamReplayBuffer()) ?>" size="6"/></td></tr>
|
||||
<tr><td><?php echo translate('AlarmFrameCount') ?></td><td><input type="text" name="newMonitor[AlarmFrameCount]" value="<?php echo validHtmlStr($monitor->AlarmFrameCount()) ?>" size="4"/></td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('ImageBufferSize') ?></td>
|
||||
<td><input type="number" name="newMonitor[ImageBufferCount]" value="<?php echo validHtmlStr($monitor->ImageBufferCount()) ?>" size="6"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('WarmupFrames') ?></td>
|
||||
<td><input type="number" name="newMonitor[WarmupCount]" value="<?php echo validHtmlStr($monitor->WarmupCount()) ?>" size="4"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('PreEventImageBuffer') ?></td>
|
||||
<td><input type="number" name="newMonitor[PreEventCount]" value="<?php echo validHtmlStr($monitor->PreEventCount()) ?>" size="4"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('PostEventImageBuffer') ?></td>
|
||||
<td><input type="number" name="newMonitor[PostEventCount]" value="<?php echo validHtmlStr($monitor->PostEventCount()) ?>" size="4"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('StreamReplayBuffer') ?></td>
|
||||
<td><input type="number" name="newMonitor[StreamReplayBuffer]" value="<?php echo validHtmlStr($monitor->StreamReplayBuffer()) ?>" size="6"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('AlarmFrameCount') ?></td>
|
||||
<td><input type="number" name="newMonitor[AlarmFrameCount]" value="<?php echo validHtmlStr($monitor->AlarmFrameCount()) ?>" size="4"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
|
@ -986,7 +1048,8 @@ if ( $monitor->Type() == 'Local' ) {
|
|||
?>
|
||||
<tr>
|
||||
<td><?php echo translate('Controllable') ?></td>
|
||||
<td><input type="checkbox" name="newMonitor[Controllable]" value="1"<?php if ( $monitor->Controllable() ) { ?> checked="checked"<?php } ?>/></td></tr>
|
||||
<td><input type="checkbox" name="newMonitor[Controllable]" value="1"<?php if ( $monitor->Controllable() ) { ?> checked="checked"<?php } ?>/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('ControlType') ?></td>
|
||||
<td><?php echo htmlSelect('newMonitor[ControlId]', $controlTypes, $monitor->ControlId());
|
||||
|
@ -1011,20 +1074,19 @@ if ( canEdit('Control') ) {
|
|||
<td><?php echo translate('TrackMotion') ?></td>
|
||||
<td><input type="checkbox" name="newMonitor[TrackMotion]" value="1"<?php if ( $monitor->TrackMotion() ) { ?> checked="checked"<?php } ?>/></td>
|
||||
</tr>
|
||||
<?php
|
||||
$return_options = array(
|
||||
'-1' => translate('None'),
|
||||
'0' => translate('Home'),
|
||||
'1' => translate('Preset').' 1',
|
||||
);
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo translate('TrackDelay') ?></td>
|
||||
<td><input type="number" name="newMonitor[TrackDelay]" value="<?php echo validHtmlStr($monitor->TrackDelay()) ?>"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('ReturnLocation') ?></td>
|
||||
<td><?php echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnLocation()); ?></td>
|
||||
<td><?php
|
||||
$return_options = array(
|
||||
'-1' => translate('None'),
|
||||
'0' => translate('Home'),
|
||||
'1' => translate('Preset').' 1',
|
||||
);
|
||||
echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnLocation()); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('ReturnDelay') ?></td>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
//
|
||||
// ZoneMinder web watch feed view file, $Date$, $Revision$
|
||||
// ZoneMinder web watch feed view file
|
||||
// Copyright (C) 2001-2008 Philip Coombes
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
|
@ -46,17 +46,16 @@ if ( isset($_REQUEST['scale']) ) {
|
|||
} else if ( isset($_COOKIE['zmWatchScale'.$mid]) ) {
|
||||
$scale = $_COOKIE['zmWatchScale'.$mid];
|
||||
} else {
|
||||
$scale = reScale(SCALE_BASE, $monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE);
|
||||
$scale = $monitor->DefaultScale();
|
||||
}
|
||||
|
||||
$connkey = generateConnKey();
|
||||
|
||||
$streamMode = getStreamMode();
|
||||
|
||||
noCacheHeaders();
|
||||
|
||||
$popup = ((isset($_REQUEST['popup'])) && ($_REQUEST['popup'] == 1));
|
||||
|
||||
noCacheHeaders();
|
||||
xhtmlHeaders(__FILE__, $monitor->Name().' - '.translate('Feed'));
|
||||
?>
|
||||
<body>
|
||||
|
@ -77,7 +76,7 @@ if ( canView('Control') && $monitor->Type() == 'Local' ) {
|
|||
<div id="closeControl"><a href="#" data-on-click="<?php echo $popup ? 'closeWindow' : 'backWindow' ?>"><?php echo $popup ? translate('Close') : translate('Back') ?></a></div>
|
||||
</div>
|
||||
<?php
|
||||
if ( $monitor->Status() != 'Connected' ) {
|
||||
if ( $monitor->Status() != 'Connected' and $monitor->Type() != 'WebSite' ) {
|
||||
echo '<div class="warning">Monitor is not capturing. We will be unable to provide an image</div>';
|
||||
}
|
||||
?>
|
||||
|
|
Loading…
Reference in New Issue