Merge branch 'master' into zma_to_thread
This commit is contained in:
commit
284b9f963f
|
@ -59,7 +59,7 @@ if(NOT HOST_OS)
|
||||||
endif(NOT HOST_OS)
|
endif(NOT HOST_OS)
|
||||||
|
|
||||||
set (CMAKE_CXX_STANDARD 11)
|
set (CMAKE_CXX_STANDARD 11)
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
|
||||||
# Default CLFAGS and CXXFLAGS:
|
# Default CLFAGS and CXXFLAGS:
|
||||||
set(CMAKE_C_FLAGS_RELEASE "-Wall -D__STDC_CONSTANT_MACROS -O2")
|
set(CMAKE_C_FLAGS_RELEASE "-Wall -D__STDC_CONSTANT_MACROS -O2")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-Wall -D__STDC_CONSTANT_MACROS -O2")
|
set(CMAKE_CXX_FLAGS_RELEASE "-Wall -D__STDC_CONSTANT_MACROS -O2")
|
||||||
|
|
|
@ -482,7 +482,7 @@ CREATE TABLE `Monitors` (
|
||||||
`SaveJPEGs` TINYINT NOT NULL DEFAULT '3' ,
|
`SaveJPEGs` TINYINT NOT NULL DEFAULT '3' ,
|
||||||
`VideoWriter` TINYINT NOT NULL DEFAULT '0',
|
`VideoWriter` TINYINT NOT NULL DEFAULT '0',
|
||||||
`OutputCodec` int(10) unsigned NOT NULL default 0,
|
`OutputCodec` int(10) unsigned NOT NULL default 0,
|
||||||
`Encoder` enum('auto','h264','h264_omx','mjpeg','mpeg1','mpeg2'),
|
`Encoder` enum('auto','h264','libx264','h264_omx','h264_vaapi','mjpeg','mpeg1','mpeg2'),
|
||||||
`OutputContainer` enum('auto','mp4','mkv'),
|
`OutputContainer` enum('auto','mp4','mkv'),
|
||||||
`EncoderParameters` TEXT,
|
`EncoderParameters` TEXT,
|
||||||
`RecordAudio` TINYINT NOT NULL DEFAULT '0',
|
`RecordAudio` TINYINT NOT NULL DEFAULT '0',
|
||||||
|
|
|
@ -239,7 +239,7 @@ use Sys::MemInfo qw(totalmem freemem totalswap freeswap);
|
||||||
use ZoneMinder::Server qw(CpuLoad);
|
use ZoneMinder::Server qw(CpuLoad);
|
||||||
#use Data::Dumper;
|
#use Data::Dumper;
|
||||||
|
|
||||||
use constant KILL_DELAY => 60; # seconds to wait between sending TERM and sending KILL
|
use constant KILL_DELAY => 10; # seconds to wait between sending TERM and sending KILL
|
||||||
|
|
||||||
our %cmd_hash;
|
our %cmd_hash;
|
||||||
our %pid_hash;
|
our %pid_hash;
|
||||||
|
|
|
@ -156,7 +156,7 @@ while( 1 ) {
|
||||||
Error("Error reading shared data for $$monitor{Id} $$monitor{Name}");
|
Error("Error reading shared data for $$monitor{Id} $$monitor{Name}");
|
||||||
} elsif ( !$image_time ) {
|
} elsif ( !$image_time ) {
|
||||||
# We can't get the last capture time so can't be sure it's died.
|
# We can't get the last capture time so can't be sure it's died.
|
||||||
$restart = 1;
|
#$restart = 1;
|
||||||
Error("Last analyse time for $$monitor{Id} $$monitor{Name} was zero.");
|
Error("Last analyse time for $$monitor{Id} $$monitor{Name} was zero.");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ public:
|
||||||
inline unsigned int SubpixelOrder() const { return subpixelorder; }
|
inline unsigned int SubpixelOrder() const { return subpixelorder; }
|
||||||
inline unsigned int Size() const { return size; }
|
inline unsigned int Size() const { return size; }
|
||||||
|
|
||||||
inline unsigned int AVPixFormat() {
|
inline AVPixelFormat AVPixFormat() {
|
||||||
if ( colours == ZM_COLOUR_RGB32 ) {
|
if ( colours == ZM_COLOUR_RGB32 ) {
|
||||||
return AV_PIX_FMT_RGBA;
|
return AV_PIX_FMT_RGBA;
|
||||||
} else if ( colours == ZM_COLOUR_RGB24 ) {
|
} else if ( colours == ZM_COLOUR_RGB24 ) {
|
||||||
|
|
|
@ -999,6 +999,7 @@ bool Monitor::connect() {
|
||||||
shared_data->format = camera->SubpixelOrder();
|
shared_data->format = camera->SubpixelOrder();
|
||||||
shared_data->imagesize = camera->ImageSize();
|
shared_data->imagesize = camera->ImageSize();
|
||||||
shared_data->alarm_cause[0] = 0;
|
shared_data->alarm_cause[0] = 0;
|
||||||
|
shared_data->last_frame_score = 0;
|
||||||
trigger_data->size = sizeof(TriggerData);
|
trigger_data->size = sizeof(TriggerData);
|
||||||
trigger_data->trigger_state = TRIGGER_CANCEL;
|
trigger_data->trigger_state = TRIGGER_CANCEL;
|
||||||
trigger_data->trigger_score = 0;
|
trigger_data->trigger_score = 0;
|
||||||
|
@ -1955,7 +1956,7 @@ bool Monitor::Analyse() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
noteSet.insert(linked_monitors[i]->Name());
|
noteSet.insert(linked_monitors[i]->Name());
|
||||||
score += 50;
|
score += linked_monitors[i]->lastFrameScore(); // 50;
|
||||||
} else {
|
} else {
|
||||||
Debug(4, "Linked monitor %d %s is not alarmed",
|
Debug(4, "Linked monitor %d %s is not alarmed",
|
||||||
linked_monitors[i]->Id(), linked_monitors[i]->Name());
|
linked_monitors[i]->Id(), linked_monitors[i]->Name());
|
||||||
|
@ -2195,6 +2196,7 @@ bool Monitor::Analyse() {
|
||||||
snap->unlock();
|
snap->unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
shared_data->last_frame_score = score;
|
||||||
} else {
|
} else {
|
||||||
Debug(3, "trigger == off");
|
Debug(3, "trigger == off");
|
||||||
if ( event ) {
|
if ( event ) {
|
||||||
|
@ -2512,7 +2514,7 @@ int Monitor::Capture() {
|
||||||
Debug(1, "Not decoding");
|
Debug(1, "Not decoding");
|
||||||
} else {
|
} else {
|
||||||
Debug(2,"About to decode %p", packet);
|
Debug(2,"About to decode %p", packet);
|
||||||
if ( ! packet->decode(camera->get_VideoCodecContext()) ) {
|
if ( packet->decode(camera->get_VideoCodecContext()) < 0 ) {
|
||||||
Error("decode failed");
|
Error("decode failed");
|
||||||
} // end if decode
|
} // end if decode
|
||||||
} // end if decoding
|
} // end if decoding
|
||||||
|
|
|
@ -135,7 +135,8 @@ protected:
|
||||||
uint8_t signal; /* +54 */
|
uint8_t signal; /* +54 */
|
||||||
uint8_t format; /* +55 */
|
uint8_t format; /* +55 */
|
||||||
uint32_t imagesize; /* +56 */
|
uint32_t imagesize; /* +56 */
|
||||||
uint32_t epadding1; /* +60 */
|
uint32_t last_frame_score; /* +60 */
|
||||||
|
// uint32_t epadding1; /* +60 */
|
||||||
/*
|
/*
|
||||||
** This keeps 32bit time_t and 64bit time_t identical and compatible as long as time is before 2038.
|
** This keeps 32bit time_t and 64bit time_t identical and compatible as long as time is before 2038.
|
||||||
** Shared memory layout should be identical for both 32bit and 64bit and is multiples of 16.
|
** Shared memory layout should be identical for both 32bit and 64bit and is multiples of 16.
|
||||||
|
@ -228,6 +229,10 @@ protected:
|
||||||
inline bool isConnected() const { return connected && shared_data->valid; }
|
inline bool isConnected() const { return connected && shared_data->valid; }
|
||||||
inline time_t getLastConnectTime() const { return last_connect_time; }
|
inline time_t getLastConnectTime() const { return last_connect_time; }
|
||||||
|
|
||||||
|
inline uint32_t lastFrameScore() {
|
||||||
|
return shared_data->last_frame_score;
|
||||||
|
}
|
||||||
|
|
||||||
bool connect();
|
bool connect();
|
||||||
bool disconnect();
|
bool disconnect();
|
||||||
|
|
||||||
|
|
|
@ -216,11 +216,12 @@ AVFrame *ZMPacket::get_out_frame( const AVCodecContext *ctx ) {
|
||||||
Error("Unable to allocate a frame");
|
Error("Unable to allocate a frame");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
codec_imgsize = av_image_get_buffer_size(
|
codec_imgsize = av_image_get_buffer_size(
|
||||||
ctx->pix_fmt,
|
ctx->pix_fmt,
|
||||||
ctx->width,
|
ctx->width,
|
||||||
ctx->height, 1);
|
ctx->height, 32);
|
||||||
buffer = (uint8_t *)av_malloc(codec_imgsize);
|
buffer = (uint8_t *)av_malloc(codec_imgsize);
|
||||||
av_image_fill_arrays(
|
av_image_fill_arrays(
|
||||||
out_frame->data,
|
out_frame->data,
|
||||||
|
@ -229,7 +230,7 @@ AVFrame *ZMPacket::get_out_frame( const AVCodecContext *ctx ) {
|
||||||
ctx->pix_fmt,
|
ctx->pix_fmt,
|
||||||
ctx->width,
|
ctx->width,
|
||||||
ctx->height,
|
ctx->height,
|
||||||
1);
|
32);
|
||||||
#else
|
#else
|
||||||
codec_imgsize = avpicture_get_size(
|
codec_imgsize = avpicture_get_size(
|
||||||
ctx->pix_fmt,
|
ctx->pix_fmt,
|
||||||
|
|
|
@ -28,11 +28,10 @@ zm_packetqueue::zm_packetqueue(
|
||||||
int p_video_stream_id,
|
int p_video_stream_id,
|
||||||
int p_audio_stream_id
|
int p_audio_stream_id
|
||||||
):
|
):
|
||||||
video_stream_id(p_video_stream_id),
|
video_stream_id(p_video_stream_id),
|
||||||
|
max_video_packet_count(video_image_count),
|
||||||
deleting(false)
|
deleting(false)
|
||||||
{
|
{
|
||||||
video_stream_id = p_video_stream_id;
|
|
||||||
max_video_packet_count = video_image_count-1;
|
|
||||||
analysis_it = pktQueue.begin();
|
analysis_it = pktQueue.begin();
|
||||||
|
|
||||||
max_stream_id = p_video_stream_id > p_audio_stream_id ? p_video_stream_id : p_audio_stream_id;
|
max_stream_id = p_video_stream_id > p_audio_stream_id ? p_video_stream_id : p_audio_stream_id;
|
||||||
|
@ -43,7 +42,6 @@ video_stream_id(p_video_stream_id),
|
||||||
|
|
||||||
zm_packetqueue::~zm_packetqueue() {
|
zm_packetqueue::~zm_packetqueue() {
|
||||||
deleting = true;
|
deleting = true;
|
||||||
Debug(4, "In destructor");
|
|
||||||
/* zma might be waiting. Must have exclusive access */
|
/* zma might be waiting. Must have exclusive access */
|
||||||
while ( ! mutex.try_lock() ) {
|
while ( ! mutex.try_lock() ) {
|
||||||
Debug(4, "Waiting for exclusive access");
|
Debug(4, "Waiting for exclusive access");
|
||||||
|
@ -51,12 +49,9 @@ zm_packetqueue::~zm_packetqueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( !pktQueue.empty() ) {
|
while ( !pktQueue.empty() ) {
|
||||||
Debug(4, "Fronting packet %d", pktQueue.empty());
|
|
||||||
ZMPacket * packet = pktQueue.front();
|
ZMPacket * packet = pktQueue.front();
|
||||||
Debug(4, "poppng packet %d", packet->image_index);
|
|
||||||
pktQueue.pop_front();
|
pktQueue.pop_front();
|
||||||
if ( packet->image_index == -1 ) {
|
if ( packet->image_index == -1 ) {
|
||||||
Debug(4, "Deletng packet");
|
|
||||||
delete packet;
|
delete packet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,6 +74,8 @@ bool zm_packetqueue::queuePacket(ZMPacket* zm_packet) {
|
||||||
|
|
||||||
pktQueue.push_back(zm_packet);
|
pktQueue.push_back(zm_packet);
|
||||||
packet_counts[zm_packet->packet.stream_index] += 1;
|
packet_counts[zm_packet->packet.stream_index] += 1;
|
||||||
|
Debug(1, "packet counts for %d is %d",
|
||||||
|
zm_packet->packet.stream_index, packet_counts[zm_packet->packet.stream_index]);
|
||||||
if ( analysis_it == pktQueue.end() ) {
|
if ( analysis_it == pktQueue.end() ) {
|
||||||
// Analsys_it should only point to end when queue is empty
|
// Analsys_it should only point to end when queue is empty
|
||||||
Debug(4, "pointing analysis_it to back");
|
Debug(4, "pointing analysis_it to back");
|
||||||
|
@ -95,8 +92,8 @@ bool zm_packetqueue::queuePacket(ZMPacket* zm_packet) {
|
||||||
while ( packet_counts[video_stream_id] > max_video_packet_count ) {
|
while ( packet_counts[video_stream_id] > max_video_packet_count ) {
|
||||||
//clearQueue(max_video_packet_count, video_stream_id);
|
//clearQueue(max_video_packet_count, video_stream_id);
|
||||||
//clearQueue is rather heavy. Since this is the only packet injection spot, we can just start at the beginning of the queue and remove packets until we get to the next video keyframe
|
//clearQueue is rather heavy. Since this is the only packet injection spot, we can just start at the beginning of the queue and remove packets until we get to the next video keyframe
|
||||||
Debug(1, "Deleting a packet with stream index (%d) with keyframe(%d), Image_index(%d) video_frames_to_keep is (%d) max: %d",
|
Debug(1, "Deleting a packet with stream index (%d) with keyframe(%d), video_frames_to_keep is (%d) max: %d",
|
||||||
zm_packet->packet.stream_index, zm_packet->keyframe, zm_packet->image_index, packet_counts[video_stream_id] , max_video_packet_count);
|
zm_packet->packet.stream_index, zm_packet->keyframe, packet_counts[video_stream_id], max_video_packet_count);
|
||||||
ZMPacket *zm_packet = *pktQueue.begin();
|
ZMPacket *zm_packet = *pktQueue.begin();
|
||||||
pktQueue.pop_front();
|
pktQueue.pop_front();
|
||||||
packet_counts[zm_packet->packet.stream_index] -= 1;
|
packet_counts[zm_packet->packet.stream_index] -= 1;
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
|
|
||||||
#if HAVE_LIBSWSCALE && HAVE_LIBAVUTIL
|
#if HAVE_LIBSWSCALE && HAVE_LIBAVUTIL
|
||||||
SWScale::SWScale() : gotdefaults(false), swscale_ctx(nullptr), input_avframe(nullptr), output_avframe(nullptr) {
|
SWScale::SWScale() : gotdefaults(false), swscale_ctx(nullptr), input_avframe(nullptr), output_avframe(nullptr) {
|
||||||
Debug(4,"SWScale object created");
|
Debug(4, "SWScale object created");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SWScale::init() {
|
bool SWScale::init() {
|
||||||
|
@ -68,10 +67,14 @@ SWScale::~SWScale() {
|
||||||
swscale_ctx = nullptr;
|
swscale_ctx = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug(4,"SWScale object destroyed");
|
Debug(4, "SWScale object destroyed");
|
||||||
}
|
}
|
||||||
|
|
||||||
int SWScale::SetDefaults(enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height) {
|
int SWScale::SetDefaults(
|
||||||
|
enum _AVPIXELFORMAT in_pf,
|
||||||
|
enum _AVPIXELFORMAT out_pf,
|
||||||
|
unsigned int width,
|
||||||
|
unsigned int height) {
|
||||||
|
|
||||||
/* Assign the defaults */
|
/* Assign the defaults */
|
||||||
default_input_pf = in_pf;
|
default_input_pf = in_pf;
|
||||||
|
@ -109,16 +112,16 @@ int SWScale::Convert(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Get the context */
|
/* Get the context */
|
||||||
swscale_ctx = sws_getCachedContext( swscale_ctx,
|
swscale_ctx = sws_getCachedContext(swscale_ctx,
|
||||||
in_frame->width, in_frame->height, format,
|
in_frame->width, in_frame->height, format,
|
||||||
out_frame->width, out_frame->height, (AVPixelFormat)out_frame->format,
|
out_frame->width, out_frame->height, (AVPixelFormat)out_frame->format,
|
||||||
SWS_FAST_BILINEAR, NULL, NULL, NULL );
|
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
||||||
if ( swscale_ctx == NULL ) {
|
if ( swscale_ctx == NULL ) {
|
||||||
Error("Failed getting swscale context");
|
Error("Failed getting swscale context");
|
||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
/* Do the conversion */
|
/* Do the conversion */
|
||||||
if(!sws_scale(swscale_ctx, in_frame->data, in_frame->linesize, 0, in_frame->height, out_frame->data, out_frame->linesize ) ) {
|
if ( !sws_scale(swscale_ctx, in_frame->data, in_frame->linesize, 0, in_frame->height, out_frame->data, out_frame->linesize ) ) {
|
||||||
Error("swscale conversion failed");
|
Error("swscale conversion failed");
|
||||||
return -10;
|
return -10;
|
||||||
}
|
}
|
||||||
|
@ -138,6 +141,8 @@ int SWScale::Convert(
|
||||||
unsigned int new_width,
|
unsigned int new_width,
|
||||||
unsigned int new_height
|
unsigned int new_height
|
||||||
) {
|
) {
|
||||||
|
Debug(1, "Convert: in_buffer %p in_buffer_size %d out_buffer %p size %d width %d height %d width %d height %d",
|
||||||
|
in_buffer, in_buffer_size, out_buffer, out_buffer_size, width, height, new_width, new_height);
|
||||||
/* Parameter checking */
|
/* Parameter checking */
|
||||||
if ( in_buffer == nullptr ) {
|
if ( in_buffer == nullptr ) {
|
||||||
Error("NULL Input buffer");
|
Error("NULL Input buffer");
|
||||||
|
@ -151,7 +156,7 @@ int SWScale::Convert(
|
||||||
// Error("Invalid input or output pixel formats");
|
// Error("Invalid input or output pixel formats");
|
||||||
// return -2;
|
// return -2;
|
||||||
// }
|
// }
|
||||||
if (!width || !height || !new_height || !new_width) {
|
if ( !width || !height || !new_height || !new_width ) {
|
||||||
Error("Invalid width or height");
|
Error("Invalid width or height");
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +193,7 @@ int SWScale::Convert(
|
||||||
|
|
||||||
/* Check the buffer sizes */
|
/* Check the buffer sizes */
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
size_t insize = av_image_get_buffer_size(in_pf, width, height, 1);
|
size_t insize = av_image_get_buffer_size(in_pf, width, height, 32);
|
||||||
#else
|
#else
|
||||||
size_t insize = avpicture_get_size(in_pf, width, height);
|
size_t insize = avpicture_get_size(in_pf, width, height);
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,7 +202,7 @@ int SWScale::Convert(
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
size_t outsize = av_image_get_buffer_size(out_pf, new_width, new_height, 1);
|
size_t outsize = av_image_get_buffer_size(out_pf, new_width, new_height, 32);
|
||||||
#else
|
#else
|
||||||
size_t outsize = avpicture_get_size(out_pf, new_width, new_height);
|
size_t outsize = avpicture_get_size(out_pf, new_width, new_height);
|
||||||
#endif
|
#endif
|
||||||
|
@ -208,7 +213,9 @@ int SWScale::Convert(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the context */
|
/* Get the context */
|
||||||
swscale_ctx = sws_getCachedContext( swscale_ctx, width, height, in_pf, new_width, new_height, out_pf, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr );
|
swscale_ctx = sws_getCachedContext(
|
||||||
|
swscale_ctx, width, height, in_pf, new_width, new_height,
|
||||||
|
out_pf, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);
|
||||||
if ( swscale_ctx == nullptr ) {
|
if ( swscale_ctx == nullptr ) {
|
||||||
Error("Failed getting swscale context");
|
Error("Failed getting swscale context");
|
||||||
return -6;
|
return -6;
|
||||||
|
@ -216,7 +223,7 @@ int SWScale::Convert(
|
||||||
|
|
||||||
/* Fill in the buffers */
|
/* Fill in the buffers */
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
if (av_image_fill_arrays(input_avframe->data, input_avframe->linesize,
|
if ( av_image_fill_arrays(input_avframe->data, input_avframe->linesize,
|
||||||
(uint8_t*) in_buffer, in_pf, width, height, 1) <= 0) {
|
(uint8_t*) in_buffer, in_pf, width, height, 1) <= 0) {
|
||||||
#else
|
#else
|
||||||
if (avpicture_fill((AVPicture*) input_avframe, (uint8_t*) in_buffer,
|
if (avpicture_fill((AVPicture*) input_avframe, (uint8_t*) in_buffer,
|
||||||
|
@ -226,10 +233,10 @@ int SWScale::Convert(
|
||||||
return -7;
|
return -7;
|
||||||
}
|
}
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
if (av_image_fill_arrays(output_avframe->data, output_avframe->linesize,
|
if ( av_image_fill_arrays(output_avframe->data, output_avframe->linesize,
|
||||||
out_buffer, out_pf, new_width, new_height, 1) <= 0) {
|
out_buffer, out_pf, new_width, new_height, 1) <= 0) {
|
||||||
#else
|
#else
|
||||||
if (avpicture_fill((AVPicture*) output_avframe, out_buffer, out_pf, new_width,
|
if ( avpicture_fill((AVPicture*) output_avframe, out_buffer, out_pf, new_width,
|
||||||
new_height) <= 0) {
|
new_height) <= 0) {
|
||||||
#endif
|
#endif
|
||||||
Error("Failed filling output frame with output buffer");
|
Error("Failed filling output frame with output buffer");
|
||||||
|
@ -237,7 +244,9 @@ int SWScale::Convert(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the conversion */
|
/* Do the conversion */
|
||||||
if(!sws_scale(swscale_ctx, input_avframe->data, input_avframe->linesize, 0, height, output_avframe->data, output_avframe->linesize ) ) {
|
if ( !sws_scale(swscale_ctx,
|
||||||
|
input_avframe->data, input_avframe->linesize,
|
||||||
|
0, height, output_avframe->data, output_avframe->linesize ) ) {
|
||||||
Error("swscale conversion failed");
|
Error("swscale conversion failed");
|
||||||
return -10;
|
return -10;
|
||||||
}
|
}
|
||||||
|
@ -245,18 +254,33 @@ int SWScale::Convert(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height) {
|
int SWScale::Convert(
|
||||||
|
const uint8_t* in_buffer,
|
||||||
|
const size_t in_buffer_size,
|
||||||
|
uint8_t* out_buffer,
|
||||||
|
const size_t out_buffer_size,
|
||||||
|
enum _AVPIXELFORMAT in_pf,
|
||||||
|
enum _AVPIXELFORMAT out_pf,
|
||||||
|
unsigned int width,
|
||||||
|
unsigned int height) {
|
||||||
return Convert(in_buffer, in_buffer_size, out_buffer, out_buffer_size, in_pf, out_pf, width, height, width, height);
|
return Convert(in_buffer, in_buffer_size, out_buffer, out_buffer_size, in_pf, out_pf, width, height, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SWScale::Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height) {
|
int SWScale::Convert(
|
||||||
|
const Image* img,
|
||||||
|
uint8_t* out_buffer,
|
||||||
|
const size_t out_buffer_size,
|
||||||
|
enum _AVPIXELFORMAT in_pf,
|
||||||
|
enum _AVPIXELFORMAT out_pf,
|
||||||
|
unsigned int width,
|
||||||
|
unsigned int height) {
|
||||||
if ( img->Width() != width ) {
|
if ( img->Width() != width ) {
|
||||||
Error("Source image width differs. Source: %d Output: %d",img->Width(), width);
|
Error("Source image width differs. Source: %d Output: %d", img->Width(), width);
|
||||||
return -12;
|
return -12;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( img->Height() != height ) {
|
if ( img->Height() != height ) {
|
||||||
Error("Source image height differs. Source: %d Output: %d",img->Height(), height);
|
Error("Source image height differs. Source: %d Output: %d", img->Height(), height);
|
||||||
return -13;
|
return -13;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,10 +88,12 @@ VideoStore::VideoStore(
|
||||||
audio_next_pts = 0;
|
audio_next_pts = 0;
|
||||||
out_format = NULL;
|
out_format = NULL;
|
||||||
oc = NULL;
|
oc = NULL;
|
||||||
|
|
||||||
|
swscale.init();
|
||||||
} // VideoStore::VideoStore
|
} // VideoStore::VideoStore
|
||||||
|
|
||||||
bool VideoStore::open() {
|
bool VideoStore::open() {
|
||||||
Info("Opening video storage stream %s format: %s", filename, format);
|
Debug(1, "Opening video storage stream %s format: %s", filename, format);
|
||||||
|
|
||||||
int ret = avformat_alloc_output_context2(&oc, nullptr, nullptr, filename);
|
int ret = avformat_alloc_output_context2(&oc, nullptr, nullptr, filename);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
|
@ -132,6 +134,19 @@ bool VideoStore::open() {
|
||||||
zm_dump_codecpar(video_in_stream->codecpar);
|
zm_dump_codecpar(video_in_stream->codecpar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wanted_codec = monitor->OutputCodec();
|
||||||
|
if ( !wanted_codec ) {
|
||||||
|
// default to h264
|
||||||
|
Debug(2, "Defaulting to H264");
|
||||||
|
wanted_codec = AV_CODEC_ID_H264;
|
||||||
|
// FIXME what is the optimal codec? Probably low latency h264 which is effectively mjpeg
|
||||||
|
} else {
|
||||||
|
Debug(2, "Codec is %d, wanted %d", video_in_ctx->codec_id, wanted_codec);
|
||||||
|
}
|
||||||
|
std::string wanted_encoder = monitor->Encoder();
|
||||||
|
|
||||||
|
// FIXME Should check that we are set to passthrough. Might be same codec, but want privacy overlays
|
||||||
|
if ( (!wanted_codec) or (video_in_ctx->codec_id == wanted_codec) ) {
|
||||||
video_out_ctx = avcodec_alloc_context3(NULL);
|
video_out_ctx = avcodec_alloc_context3(NULL);
|
||||||
if ( oc->oformat->flags & AVFMT_GLOBALHEADER ) {
|
if ( oc->oformat->flags & AVFMT_GLOBALHEADER ) {
|
||||||
#if LIBAVCODEC_VERSION_CHECK(56, 35, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(56, 35, 0, 64, 0)
|
||||||
|
@ -140,23 +155,19 @@ bool VideoStore::open() {
|
||||||
video_out_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
video_out_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !video_out_ctx->codec_tag ) {
|
if ( !video_out_ctx->codec_tag ) {
|
||||||
video_out_ctx->codec_tag =
|
video_out_ctx->codec_tag =
|
||||||
av_codec_get_tag(oc->oformat->codec_tag, video_in_ctx->codec_id);
|
av_codec_get_tag(oc->oformat->codec_tag, video_out_ctx->codec_id);
|
||||||
Debug(2, "No codec_tag, setting to %d", video_out_ctx->codec_tag);
|
Debug(2, "No codec_tag, setting to %d", video_out_ctx->codec_tag);
|
||||||
}
|
}
|
||||||
int wanted_codec = monitor->OutputCodec();
|
video_out_ctx->time_base = video_in_ctx->time_base;
|
||||||
if ( !wanted_codec ) {
|
if ( ! (video_out_ctx->time_base.num && video_out_ctx->time_base.den) ) {
|
||||||
// default to h264
|
Debug(2,"No timebase found in video in context, defaulting to Q");
|
||||||
//Debug(2, "Defaulting to H264");
|
video_out_ctx->time_base = AV_TIME_BASE_Q;
|
||||||
//wanted_codec = AV_CODEC_ID_H264;
|
}
|
||||||
} else {
|
// Copy params from instream to ctx
|
||||||
Debug(2, "Codec is %d, wanted %d", video_in_ctx->codec_id, wanted_codec);
|
// There might not be a useful video_in_stream. v4l in might not populate this very
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME Should check that we are set to passthrough. Might be same codec, but want privacy overlays
|
|
||||||
if ( (!wanted_codec) or (video_in_ctx->codec_id == wanted_codec) ) {
|
|
||||||
// Copy params from instream to ctx
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
ret = avcodec_parameters_to_context(video_out_ctx, video_in_stream->codecpar);
|
ret = avcodec_parameters_to_context(video_out_ctx, video_in_stream->codecpar);
|
||||||
#else
|
#else
|
||||||
|
@ -167,7 +178,6 @@ bool VideoStore::open() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//video_out_ctx->time_base = (AVRational){1, 1000000}; // microseconds as base frame rate
|
//video_out_ctx->time_base = (AVRational){1, 1000000}; // microseconds as base frame rate
|
||||||
video_out_ctx->time_base = video_in_ctx->time_base;
|
|
||||||
// Fix deprecated formats
|
// Fix deprecated formats
|
||||||
switch ( video_out_ctx->pix_fmt ) {
|
switch ( video_out_ctx->pix_fmt ) {
|
||||||
case AV_PIX_FMT_YUVJ422P :
|
case AV_PIX_FMT_YUVJ422P :
|
||||||
|
@ -187,18 +197,44 @@ bool VideoStore::open() {
|
||||||
}
|
}
|
||||||
} else { // Either no video in or not the desired codec
|
} else { // Either no video in or not the desired codec
|
||||||
for ( unsigned int i = 0; i < sizeof(codec_data) / sizeof(*codec_data); i++ ) {
|
for ( unsigned int i = 0; i < sizeof(codec_data) / sizeof(*codec_data); i++ ) {
|
||||||
|
if ( wanted_encoder != "" ) {
|
||||||
|
if ( wanted_encoder != codec_data[i].codec_name ) {
|
||||||
|
Debug(1, "Not the right codec name %s != %s", codec_data[i].codec_name, wanted_encoder.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
if ( codec_data[i].codec_id != wanted_codec ) {
|
if ( codec_data[i].codec_id != wanted_codec ) {
|
||||||
Debug(1, "Not the right codec %d != %d", codec_data[i].codec_id, wanted_codec);
|
Debug(1, "Not the right codec %d != %d", codec_data[i].codec_id, wanted_codec);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
video_out_codec = avcodec_find_encoder_by_name(codec_data[i].codec_name);
|
video_out_codec = avcodec_find_encoder_by_name(codec_data[i].codec_name);
|
||||||
if ( ! video_out_codec ) {
|
if ( !video_out_codec ) {
|
||||||
Debug(1, "Didn't find encoder for %s", codec_data[i].codec_name);
|
Debug(1, "Didn't find encoder for %s", codec_data[i].codec_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Debug(1, "Found video codec for %s", codec_data[i].codec_name);
|
Debug(1, "Found video codec for %s", codec_data[i].codec_name);
|
||||||
|
video_out_ctx = avcodec_alloc_context3(video_out_codec);
|
||||||
|
if ( oc->oformat->flags & AVFMT_GLOBALHEADER ) {
|
||||||
|
#if LIBAVCODEC_VERSION_CHECK(56, 35, 0, 64, 0)
|
||||||
|
video_out_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||||
|
#else
|
||||||
|
video_out_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !video_out_ctx->codec_tag ) {
|
||||||
|
video_out_ctx->codec_tag =
|
||||||
|
av_codec_get_tag(oc->oformat->codec_tag, video_out_ctx->codec_id);
|
||||||
|
Debug(2, "No codec_tag, setting to %d", video_out_ctx->codec_tag);
|
||||||
|
}
|
||||||
|
video_out_ctx->time_base = video_in_ctx->time_base;
|
||||||
|
if ( ! (video_out_ctx->time_base.num && video_out_ctx->time_base.den) ) {
|
||||||
|
Debug(2,"No timebase found in video in context, defaulting to Q");
|
||||||
|
video_out_ctx->time_base = AV_TIME_BASE_Q;
|
||||||
|
}
|
||||||
|
|
||||||
|
video_out_ctx->codec_id = codec_data[i].codec_id;
|
||||||
video_out_ctx->pix_fmt = codec_data[i].pix_fmt;
|
video_out_ctx->pix_fmt = codec_data[i].pix_fmt;
|
||||||
video_out_ctx->level = 32;
|
video_out_ctx->level = 32;
|
||||||
|
|
||||||
|
@ -207,22 +243,22 @@ bool VideoStore::open() {
|
||||||
video_out_ctx->height = monitor->Height();
|
video_out_ctx->height = monitor->Height();
|
||||||
video_out_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
video_out_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||||
|
|
||||||
// Just copy them from the in, no reason to choose different
|
|
||||||
video_out_ctx->time_base = video_in_ctx->time_base;
|
|
||||||
if ( ! (video_out_ctx->time_base.num && video_out_ctx->time_base.den) ) {
|
|
||||||
Debug(2,"No timebase found in video in context, defaulting to Q");
|
|
||||||
video_out_ctx->time_base = AV_TIME_BASE_Q;
|
|
||||||
}
|
|
||||||
video_out_stream->time_base = video_in_stream ? video_in_stream->time_base : AV_TIME_BASE_Q;
|
|
||||||
|
|
||||||
if ( video_out_ctx->codec_id == AV_CODEC_ID_H264 ) {
|
if ( video_out_ctx->codec_id == AV_CODEC_ID_H264 ) {
|
||||||
|
/*
|
||||||
|
video_out_ctx->bit_rate = 2000000;
|
||||||
|
video_out_ctx->gop_size = 12;
|
||||||
video_out_ctx->max_b_frames = 1;
|
video_out_ctx->max_b_frames = 1;
|
||||||
if ( video_out_ctx->priv_data ) {
|
if ( video_out_ctx->priv_data ) {
|
||||||
//av_opt_set(video_out_ctx->priv_data, "crf", "1", AV_OPT_SEARCH_CHILDREN);
|
Debug(2, "setting priv_data crf");
|
||||||
//av_opt_set(video_out_ctx->priv_data, "preset", "ultrafast", 0);
|
av_opt_set(video_out_ctx->priv_data, "crf", "1", AV_OPT_SEARCH_CHILDREN);
|
||||||
|
Debug(2, "setting priv_data preset");
|
||||||
|
av_opt_set(video_out_ctx->priv_data, "preset", "ultrafast", 0);
|
||||||
} else {
|
} else {
|
||||||
Debug(2, "Not setting priv_data");
|
Debug(2, "Not setting priv_data");
|
||||||
|
av_opt_set(video_out_ctx->priv_data, "preset", "fast", 0);
|
||||||
|
Debug(2, "Not setting priv_data");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} else if ( video_out_ctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ) {
|
} else if ( video_out_ctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ) {
|
||||||
/* just for testing, we also add B frames */
|
/* just for testing, we also add B frames */
|
||||||
video_out_ctx->max_b_frames = 2;
|
video_out_ctx->max_b_frames = 2;
|
||||||
|
@ -235,13 +271,12 @@ bool VideoStore::open() {
|
||||||
|
|
||||||
AVDictionary *opts = 0;
|
AVDictionary *opts = 0;
|
||||||
std::string Options = monitor->GetEncoderOptions();
|
std::string Options = monitor->GetEncoderOptions();
|
||||||
Debug(2, "Options?");
|
|
||||||
Debug(2, "Options? %s", Options.c_str());
|
Debug(2, "Options? %s", Options.c_str());
|
||||||
ret = av_dict_parse_string(&opts, Options.c_str(), "=", ",#\n", 0);
|
ret = av_dict_parse_string(&opts, Options.c_str(), "=", ",#\n", 0);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Warning("Could not parse ffmpeg encoder options list '%s'\n", Options.c_str());
|
Warning("Could not parse ffmpeg encoder options list '%s'\n", Options.c_str());
|
||||||
} else {
|
} else {
|
||||||
AVDictionaryEntry *e = NULL;
|
AVDictionaryEntry *e = nullptr;
|
||||||
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
||||||
Debug(3, "Encoder Option %s=%s", e->key, e->value);
|
Debug(3, "Encoder Option %s=%s", e->key, e->value);
|
||||||
}
|
}
|
||||||
|
@ -252,16 +287,15 @@ bool VideoStore::open() {
|
||||||
video_out_codec->name,
|
video_out_codec->name,
|
||||||
av_make_error_string(ret).c_str()
|
av_make_error_string(ret).c_str()
|
||||||
);
|
);
|
||||||
video_out_codec = NULL;
|
video_out_codec = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVDictionaryEntry *e = NULL;
|
AVDictionaryEntry *e = nullptr;
|
||||||
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != nullptr ) {
|
||||||
Warning("Encoder Option %s not recognized by ffmpeg codec", e->key);
|
Warning("Encoder Option %s not recognized by ffmpeg codec", e->key);
|
||||||
}
|
}
|
||||||
av_dict_free(&opts);
|
av_dict_free(&opts);
|
||||||
if ( video_out_codec ) break;
|
if ( video_out_codec ) break;
|
||||||
|
|
||||||
} // end foreach codec
|
} // end foreach codec
|
||||||
|
|
||||||
if ( !video_out_codec ) {
|
if ( !video_out_codec ) {
|
||||||
|
@ -270,12 +304,12 @@ bool VideoStore::open() {
|
||||||
// We allocate and copy in newer ffmpeg, so need to free it
|
// We allocate and copy in newer ffmpeg, so need to free it
|
||||||
avcodec_free_context(&video_out_ctx);
|
avcodec_free_context(&video_out_ctx);
|
||||||
#endif
|
#endif
|
||||||
video_out_ctx = NULL;
|
video_out_ctx = nullptr;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} // end if can't open codec
|
} // end if can't open codec
|
||||||
|
|
||||||
Debug(2, "Sucess opening codec");
|
Debug(2, "Success opening codec");
|
||||||
|
|
||||||
} // end if copying or transcoding
|
} // end if copying or transcoding
|
||||||
} // end if video_in_stream
|
} // end if video_in_stream
|
||||||
|
@ -1026,11 +1060,11 @@ bool VideoStore::setup_resampler() {
|
||||||
#endif
|
#endif
|
||||||
} // end bool VideoStore::setup_resampler()
|
} // end bool VideoStore::setup_resampler()
|
||||||
|
|
||||||
int VideoStore::writePacket( ZMPacket *ipkt ) {
|
int VideoStore::writePacket(ZMPacket *ipkt) {
|
||||||
if ( ipkt->packet.stream_index == video_in_stream_index ) {
|
if ( ipkt->packet.stream_index == video_in_stream_index ) {
|
||||||
return writeVideoFramePacket( ipkt );
|
return writeVideoFramePacket(ipkt);
|
||||||
} else if ( ipkt->packet.stream_index == audio_in_stream_index ) {
|
} else if ( ipkt->packet.stream_index == audio_in_stream_index ) {
|
||||||
return writeAudioFramePacket( ipkt );
|
return writeAudioFramePacket(ipkt);
|
||||||
}
|
}
|
||||||
Error("Unknown stream type in packet (%d) out input video stream is (%d) and audio is (%d)",
|
Error("Unknown stream type in packet (%d) out input video stream is (%d) and audio is (%d)",
|
||||||
ipkt->packet.stream_index, video_in_stream_index, ( audio_in_stream ? audio_in_stream_index : -1 )
|
ipkt->packet.stream_index, video_in_stream_index, ( audio_in_stream ? audio_in_stream_index : -1 )
|
||||||
|
@ -1044,10 +1078,10 @@ int VideoStore::writeVideoFramePacket(ZMPacket *zm_packet) {
|
||||||
|
|
||||||
// if we have to transcode
|
// if we have to transcode
|
||||||
if ( video_out_ctx->codec_id != video_in_ctx->codec_id ) {
|
if ( video_out_ctx->codec_id != video_in_ctx->codec_id ) {
|
||||||
//Debug(3, "Have encoding video frame count (%d)", frame_count);
|
Debug(3, "Have encoding video frame count (%d)", frame_count);
|
||||||
|
|
||||||
if ( !zm_packet->out_frame ) {
|
if ( !zm_packet->out_frame ) {
|
||||||
//Debug(3, "Have no out frame");
|
Debug(3, "Have no out frame");
|
||||||
AVFrame *out_frame = zm_packet->get_out_frame(video_out_ctx);
|
AVFrame *out_frame = zm_packet->get_out_frame(video_out_ctx);
|
||||||
if ( !out_frame ) {
|
if ( !out_frame ) {
|
||||||
Error("Unable to allocate a frame");
|
Error("Unable to allocate a frame");
|
||||||
|
@ -1055,23 +1089,23 @@ int VideoStore::writeVideoFramePacket(ZMPacket *zm_packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !zm_packet->in_frame ) {
|
if ( !zm_packet->in_frame ) {
|
||||||
//Debug(2,"Have no in_frame");
|
Debug(2, "Have no in_frame");
|
||||||
if ( zm_packet->packet.size ) {
|
if ( zm_packet->packet.size ) {
|
||||||
//Debug(2,"Decoding");
|
Debug(2, "Decoding");
|
||||||
if ( !zm_packet->decode(video_in_ctx) ) {
|
if ( !zm_packet->decode(video_in_ctx) ) {
|
||||||
Debug(2, "unable to decode yet.");
|
Debug(2, "unable to decode yet.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//Go straight to out frame
|
// Go straight to out frame
|
||||||
swscale.Convert(zm_packet->in_frame, out_frame);
|
swscale.Convert(zm_packet->in_frame, out_frame);
|
||||||
} else if ( zm_packet->image ) {
|
} else if ( zm_packet->image ) {
|
||||||
//Debug(2,"Have an image, convert it");
|
Debug(2, "Have an image, convert it");
|
||||||
//Go straight to out frame
|
//Go straight to out frame
|
||||||
swscale.Convert(
|
swscale.Convert(
|
||||||
zm_packet->image,
|
zm_packet->image,
|
||||||
zm_packet->buffer,
|
zm_packet->buffer,
|
||||||
zm_packet->codec_imgsize,
|
zm_packet->codec_imgsize,
|
||||||
(AVPixelFormat)zm_packet->image->AVPixFormat(),
|
zm_packet->image->AVPixFormat(),
|
||||||
video_out_ctx->pix_fmt,
|
video_out_ctx->pix_fmt,
|
||||||
video_out_ctx->width,
|
video_out_ctx->width,
|
||||||
video_out_ctx->height
|
video_out_ctx->height
|
||||||
|
@ -1120,7 +1154,7 @@ int VideoStore::writeVideoFramePacket(ZMPacket *zm_packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
av_init_packet(&opkt);
|
av_init_packet(&opkt);
|
||||||
opkt.data = NULL;
|
opkt.data = nullptr;
|
||||||
opkt.size = 0;
|
opkt.size = 0;
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
// Do this to allow the encoder to choose whether to use I/P/B frame
|
// Do this to allow the encoder to choose whether to use I/P/B frame
|
||||||
|
@ -1168,37 +1202,41 @@ int VideoStore::writeVideoFramePacket(ZMPacket *zm_packet) {
|
||||||
opkt.dts = av_rescale_q(opkt.dts, video_out_ctx->time_base, video_out_stream->time_base);
|
opkt.dts = av_rescale_q(opkt.dts, video_out_ctx->time_base, video_out_stream->time_base);
|
||||||
|
|
||||||
int64_t duration;
|
int64_t duration;
|
||||||
if ( zm_packet->in_frame->pkt_duration ) {
|
if ( zm_packet->in_frame ) {
|
||||||
duration = av_rescale_q(
|
if ( zm_packet->in_frame->pkt_duration ) {
|
||||||
zm_packet->in_frame->pkt_duration,
|
duration = av_rescale_q(
|
||||||
video_in_stream->time_base,
|
zm_packet->in_frame->pkt_duration,
|
||||||
video_out_stream->time_base);
|
|
||||||
Debug(1, "duration from ipkt: pts(%" PRId64 ") - last_pts(%" PRId64 ") = (%" PRId64 ") => (%" PRId64 ") (%d/%d) (%d/%d)",
|
|
||||||
zm_packet->in_frame->pts,
|
|
||||||
video_last_pts,
|
|
||||||
zm_packet->in_frame->pkt_duration,
|
|
||||||
duration,
|
|
||||||
video_in_stream->time_base.num,
|
|
||||||
video_in_stream->time_base.den,
|
|
||||||
video_out_stream->time_base.num,
|
|
||||||
video_out_stream->time_base.den
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
duration =
|
|
||||||
av_rescale_q(
|
|
||||||
zm_packet->in_frame->pts - video_last_pts,
|
|
||||||
video_in_stream->time_base,
|
video_in_stream->time_base,
|
||||||
video_out_stream->time_base);
|
video_out_stream->time_base);
|
||||||
Debug(1, "duration calc: pts(%" PRId64 ") - last_pts(%" PRId64 ") = (%" PRId64 ") => (%" PRId64 ")",
|
Debug(1, "duration from ipkt: pts(%" PRId64 ") - last_pts(%" PRId64 ") = (%" PRId64 ") => (%" PRId64 ") (%d/%d) (%d/%d)",
|
||||||
zm_packet->in_frame->pts,
|
zm_packet->in_frame->pts,
|
||||||
video_last_pts,
|
video_last_pts,
|
||||||
zm_packet->in_frame->pts - video_last_pts,
|
zm_packet->in_frame->pkt_duration,
|
||||||
duration
|
duration,
|
||||||
);
|
video_in_stream->time_base.num,
|
||||||
if ( duration <= 0 ) {
|
video_in_stream->time_base.den,
|
||||||
duration = zm_packet->in_frame->pkt_duration ? zm_packet->in_frame->pkt_duration : av_rescale_q(1,video_in_stream->time_base, video_out_stream->time_base);
|
video_out_stream->time_base.num,
|
||||||
}
|
video_out_stream->time_base.den
|
||||||
}
|
);
|
||||||
|
} else {
|
||||||
|
duration =
|
||||||
|
av_rescale_q(
|
||||||
|
zm_packet->in_frame->pts - video_last_pts,
|
||||||
|
video_in_stream->time_base,
|
||||||
|
video_out_stream->time_base);
|
||||||
|
Debug(1, "duration calc: pts(%" PRId64 ") - last_pts(%" PRId64 ") = (%" PRId64 ") => (%" PRId64 ")",
|
||||||
|
zm_packet->in_frame->pts,
|
||||||
|
video_last_pts,
|
||||||
|
zm_packet->in_frame->pts - video_last_pts,
|
||||||
|
duration
|
||||||
|
);
|
||||||
|
if ( duration <= 0 ) {
|
||||||
|
duration = zm_packet->in_frame->pkt_duration ? zm_packet->in_frame->pkt_duration : av_rescale_q(1,video_in_stream->time_base, video_out_stream->time_base);
|
||||||
|
}
|
||||||
|
} // end if in_frmae->pkt_duration
|
||||||
|
} else {
|
||||||
|
duration = av_rescale_q(1,video_in_stream->time_base, video_out_stream->time_base);
|
||||||
|
} // end if in_frmae
|
||||||
opkt.duration = duration;
|
opkt.duration = duration;
|
||||||
|
|
||||||
} else { // codec matches, we are doing passthrough
|
} else { // codec matches, we are doing passthrough
|
||||||
|
|
|
@ -24,7 +24,7 @@ class VideoStore {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct CodecData {
|
struct CodecData {
|
||||||
const int codec_id;
|
const AVCodecID codec_id;
|
||||||
const char *codec_codec;
|
const char *codec_codec;
|
||||||
const char *codec_name;
|
const char *codec_name;
|
||||||
const enum AVPixelFormat pix_fmt;
|
const enum AVPixelFormat pix_fmt;
|
||||||
|
|
|
@ -156,32 +156,21 @@ class MonitorsController extends AppController {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$monitor = $this->Monitor->find('first', array(
|
||||||
|
'conditions' => array('Id' => $id)
|
||||||
|
))['Monitor'];
|
||||||
|
|
||||||
$message = '';
|
$message = '';
|
||||||
if ( $this->Monitor->save($this->request->data) ) {
|
if ( $this->Monitor->save($this->request->data) ) {
|
||||||
$message = 'Saved';
|
$message = 'Saved';
|
||||||
$Monitor = $this->Monitor->find('first', array(
|
|
||||||
'fields' => array('Function','ServerId'),
|
// Stop the monitor. Should happen before saving
|
||||||
|
$this->Monitor->daemonControl($monitor, 'stop');
|
||||||
|
$monitor = $this->Monitor->find('first', array(
|
||||||
'conditions' => array('Id' => $id)
|
'conditions' => array('Id' => $id)
|
||||||
))['Monitor'];
|
))['Monitor'];
|
||||||
|
|
||||||
// - restart or stop this monitor after change
|
$this->Monitor->daemonControl($monitor, 'start');
|
||||||
$func = $Monitor['Function'];
|
|
||||||
// We don't pass the request data as the monitor object because it may be a subset of the full monitor array
|
|
||||||
$this->daemonControl($this->Monitor->id, 'stop');
|
|
||||||
if (
|
|
||||||
( $func != 'None' )
|
|
||||||
and
|
|
||||||
(
|
|
||||||
(!defined('ZM_SERVER_ID'))
|
|
||||||
or
|
|
||||||
($Monitor['ServerId']==ZM_SERVER_ID)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
if ( !defined('ZM_SERVER_ID')) {
|
|
||||||
ZM\Debug("Not defined ZM_SERVER_ID");
|
|
||||||
}
|
|
||||||
$this->daemonControl($this->Monitor->id, 'start');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$message = 'Error ' . print_r($this->Monitor->invalidFields(), true);
|
$message = 'Error ' . print_r($this->Monitor->invalidFields(), true);
|
||||||
}
|
}
|
||||||
|
@ -353,7 +342,6 @@ class MonitorsController extends AppController {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function daemonControl($id, $command, $daemon=null) {
|
public function daemonControl($id, $command, $daemon=null) {
|
||||||
|
|
||||||
// Need to see if it is local or remote
|
// Need to see if it is local or remote
|
||||||
$monitor = $this->Monitor->find('first', array(
|
$monitor = $this->Monitor->find('first', array(
|
||||||
'fields' => array('Type', 'Function', 'Device'),
|
'fields' => array('Type', 'Function', 'Device'),
|
||||||
|
@ -361,35 +349,8 @@ class MonitorsController extends AppController {
|
||||||
));
|
));
|
||||||
$monitor = $monitor['Monitor'];
|
$monitor = $monitor['Monitor'];
|
||||||
|
|
||||||
$daemons = array();
|
$status_text = $this->Monitor->daemonControl($monitor, $command, $daemon);
|
||||||
if ( ! $daemon ) {
|
|
||||||
if ( $monitor['Function'] == 'Monitor' ) {
|
|
||||||
array_push($daemons, 'zmc');
|
|
||||||
} else {
|
|
||||||
array_push($daemons, 'zmc', 'zma');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
array_push($daemons, $daemon);
|
|
||||||
}
|
|
||||||
|
|
||||||
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
|
||||||
|
|
||||||
$status_text = '';
|
|
||||||
foreach ( $daemons as $daemon ) {
|
|
||||||
$args = '';
|
|
||||||
if ( $daemon == 'zmc' and $monitor['Type'] == 'Local' ) {
|
|
||||||
$args = '-d ' . $monitor['Device'];
|
|
||||||
} else if ( $daemon == 'zmcontrol.pl' ) {
|
|
||||||
$args = '--id '.$id;
|
|
||||||
} else {
|
|
||||||
$args = '-m ' . $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$shellcmd = escapeshellcmd("$zm_path_bin/zmdc.pl $command $daemon $args");
|
|
||||||
ZM\Debug("Command $shellcmd");
|
|
||||||
$status = exec($shellcmd);
|
|
||||||
$status_text .= $status."\n";
|
|
||||||
}
|
|
||||||
$this->set(array(
|
$this->set(array(
|
||||||
'status' => 'ok',
|
'status' => 'ok',
|
||||||
'statustext' => $status_text,
|
'statustext' => $status_text,
|
||||||
|
|
|
@ -136,4 +136,44 @@ class Monitor extends AppModel {
|
||||||
'joinTable' => 'Monitor_Status',
|
'joinTable' => 'Monitor_Status',
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public function daemonControl($monitor, $command, $daemon=null) {
|
||||||
|
if ( $monitor['Function'] == 'None' ) {
|
||||||
|
ZM\Debug('Calling daemonControl when Function == None');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( defined('ZM_SERVER_ID') and ($monitor['ServerId']!=ZM_SERVER_ID) ) {
|
||||||
|
ZM\Debug('Calling daemonControl for Monitor assigned to different server');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$daemons = array();
|
||||||
|
if ( ! $daemon ) {
|
||||||
|
if ( $monitor['Function'] == 'Monitor' ) {
|
||||||
|
array_push($daemons, 'zmc');
|
||||||
|
} else {
|
||||||
|
array_push($daemons, 'zmc', 'zma');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
array_push($daemons, $daemon);
|
||||||
|
}
|
||||||
|
|
||||||
|
$status_text = '';
|
||||||
|
foreach ( $daemons as $daemon ) {
|
||||||
|
$args = '';
|
||||||
|
if ( $daemon == 'zmc' and $monitor['Type'] == 'Local' ) {
|
||||||
|
$args = '-d ' . $monitor['Device'];
|
||||||
|
} else if ( $daemon == 'zmcontrol.pl' ) {
|
||||||
|
$args = '--id '.$monitor['Id'];
|
||||||
|
} else {
|
||||||
|
$args = '-m ' . $monitor['Id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$shellcmd = escapeshellcmd(ZM_PATH_BIN.'/zmdc.pl '.$command.' '.$daemon.' '.$args);
|
||||||
|
ZM\Debug("Command $shellcmd");
|
||||||
|
$status = exec($shellcmd);
|
||||||
|
$status_text .= $status.PHP_EOL;
|
||||||
|
} # end foreach daemon
|
||||||
|
return $status_text;
|
||||||
|
} # end function daemonControl
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,6 +202,9 @@ if ( $action == 'save' ) {
|
||||||
} // end foreach zone
|
} // end foreach zone
|
||||||
} // end if rotation or just size change
|
} // end if rotation or just size change
|
||||||
} // end if changes in width or height
|
} // end if changes in width or height
|
||||||
|
} else {
|
||||||
|
global $error_message;
|
||||||
|
$error_message = dbError();
|
||||||
} // end if successful save
|
} // end if successful save
|
||||||
$restart = true;
|
$restart = true;
|
||||||
} else { // new monitor
|
} else { // new monitor
|
||||||
|
|
|
@ -112,10 +112,10 @@ function dbLog($sql, $update=false) {
|
||||||
function dbError($sql) {
|
function dbError($sql) {
|
||||||
global $dbConn;
|
global $dbConn;
|
||||||
$error = $dbConn->errorInfo();
|
$error = $dbConn->errorInfo();
|
||||||
if ( ! $error[0] )
|
if ( !$error[0] )
|
||||||
return '';
|
return '';
|
||||||
|
|
||||||
$message = "SQL-ERR '".implode("\n",$dbConn->errorInfo())."', statement was '".$sql."'";
|
$message = "SQL-ERR '".implode("\n", $dbConn->errorInfo())."', statement was '".$sql."'";
|
||||||
ZM\Error($message);
|
ZM\Error($message);
|
||||||
return $message;
|
return $message;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
//
|
//
|
||||||
|
$j.ajaxSetup({timeout: AJAX_TIMEOUT});
|
||||||
|
var reportLogs = true;
|
||||||
|
|
||||||
if ( !window.console ) {
|
if ( !window.console ) {
|
||||||
window.console =
|
window.console =
|
||||||
|
@ -28,55 +30,63 @@ if ( !window.console ) {
|
||||||
error: function() {}
|
error: function() {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !console.debug ) {
|
if ( !console.debug ) {
|
||||||
// IE8 has console but doesn't have console.debug so lets alias it.
|
// IE8 has console but doesn't have console.debug so lets alias it.
|
||||||
console.debug = console.log;
|
console.debug = console.log;
|
||||||
}
|
}
|
||||||
|
|
||||||
var reportLogs = true;
|
window.onerror = function(message, url, line) {
|
||||||
|
logReport("ERR", message, url, line);
|
||||||
|
};
|
||||||
|
|
||||||
var debugParms;
|
window.addEventListener("securitypolicyviolation", function logCSP(evt) {
|
||||||
var debugReq;
|
var level = evt.disposition == "enforce" ? "ERR" : "DBG";
|
||||||
|
var message = evt.blockedURI + " violated CSP " + evt.violatedDirective;
|
||||||
|
|
||||||
|
if ( evt.sample ) message += " (Sample: " + evt.sample + ")";
|
||||||
|
logReport(level, message, evt.sourceFile, evt.lineNumber);
|
||||||
|
});
|
||||||
|
|
||||||
function logReport( level, message, file, line ) {
|
function logReport( level, message, file, line ) {
|
||||||
if ( !reportLogs ) {
|
if ( !reportLogs ) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( typeof(MooTools) == "undefined" ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* eslint-disable no-caller */
|
/* eslint-disable no-caller */
|
||||||
if ( arguments && arguments.callee && arguments.callee.caller && arguments.callee.caller.caller && arguments.callee.caller.caller.name ) {
|
if ( arguments && arguments.callee && arguments.callee.caller && arguments.callee.caller.caller && arguments.callee.caller.caller.name ) {
|
||||||
message += ' - '+arguments.callee.caller.caller.name+'()';
|
message += ' - '+arguments.callee.caller.caller.name+'()';
|
||||||
//console.log("arguments");
|
//console.log("arguments");
|
||||||
} else {
|
|
||||||
//message += new Error().stack;
|
|
||||||
//console.log("stack");
|
|
||||||
}
|
}
|
||||||
/* eslint-enable no-caller */
|
|
||||||
|
|
||||||
if ( !debugReq ) {
|
var browser = {};
|
||||||
debugParms = "view=request&request=log&task=create";
|
if ( Browser ) {
|
||||||
if ( Browser ) {
|
browser.name = Browser.name;
|
||||||
debugParms += "&browser[name]="+Browser.name+"&browser[version]="+Browser.version+"&browser[platform]="+(Browser.Platform?Browser.Platform.name:'unknown');
|
browser.version = Browser.version;
|
||||||
} else {
|
browser.platform = Browser.Platform ? Browser.Platform.name : 'unknown';
|
||||||
debugParms += "&browser[name]=unknown&browser[version]=unknown&browser[platform]=unknown";
|
} else {
|
||||||
}
|
browser.name = 'unknown';
|
||||||
debugReq = new Request.JSON({url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'chain'});
|
browser.version = 'unknown';
|
||||||
|
browser.platform = 'unknown';
|
||||||
}
|
}
|
||||||
var requestParms = debugParms;
|
|
||||||
requestParms += "&level="+level+"&message="+encodeURIComponent(message);
|
var data = {
|
||||||
|
view: 'request',
|
||||||
|
request: 'log',
|
||||||
|
task: 'create',
|
||||||
|
level: level,
|
||||||
|
message: encodeURIComponent(message),
|
||||||
|
browser: browser
|
||||||
|
};
|
||||||
|
|
||||||
if ( file ) {
|
if ( file ) {
|
||||||
requestParms += "&file="+file;
|
data.file = file;
|
||||||
} else if ( location.search ) {
|
} else if ( location.search ) {
|
||||||
//location.search is the querystring part, so ?blah=blah but there is almost never any value to this
|
//location.search is the querystring part, so ?blah=blah but there is almost never any value to this
|
||||||
requestParms += "&file="+location.search;
|
data.file = location.search;
|
||||||
}
|
}
|
||||||
if ( line ) {
|
|
||||||
requestParms += "&line="+line;
|
if ( line ) data.line = line;
|
||||||
}
|
|
||||||
debugReq.send(requestParms);
|
$j.getJSON(thisUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Panic(message) {
|
function Panic(message) {
|
||||||
|
@ -112,22 +122,6 @@ function Debug(message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function Dump(value, label) {
|
function Dump(value, label) {
|
||||||
if ( label ) {
|
if ( label ) console.debug(label+" => ");
|
||||||
console.debug(label+" => ");
|
|
||||||
}
|
|
||||||
console.debug(value);
|
console.debug(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onerror =
|
|
||||||
function( message, url, line ) {
|
|
||||||
logReport("ERR", message, url, line);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener("securitypolicyviolation", function logCSP(evt) {
|
|
||||||
var level = evt.disposition == "enforce" ? "ERR" : "DBG";
|
|
||||||
var message = evt.blockedURI + " violated CSP " + evt.violatedDirective;
|
|
||||||
if ( evt.sample ) {
|
|
||||||
message += " (Sample: " + evt.sample + ")";
|
|
||||||
}
|
|
||||||
logReport(level, message, evt.sourceFile, evt.lineNumber);
|
|
||||||
});
|
|
||||||
|
|
|
@ -437,9 +437,9 @@ function secsToTime( seconds ) {
|
||||||
|
|
||||||
function submitTab(evt) {
|
function submitTab(evt) {
|
||||||
var tab = this.getAttribute("data-tab-name");
|
var tab = this.getAttribute("data-tab-name");
|
||||||
var form = $('contentForm');
|
var form = $j('#contentForm');
|
||||||
form.action.value = "";
|
form.attr('action', '');
|
||||||
form.tab.value = tab;
|
form.attr('tab', tab);
|
||||||
form.submit();
|
form.submit();
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -599,11 +599,11 @@ function scaleToFit(baseWidth, baseHeight, scaleEl, bottomEl) {
|
||||||
return {width: Math.floor(newWidth), height: Math.floor(newHeight), autoScale: autoScale};
|
return {width: Math.floor(newWidth), height: Math.floor(newHeight), autoScale: autoScale};
|
||||||
}
|
}
|
||||||
|
|
||||||
function setButtonState(element_id, butClass) {
|
function setButtonState(element_id, btnClass) {
|
||||||
var element = $(element_id);
|
var element = document.getElementById(element_id);
|
||||||
if ( element ) {
|
if ( element ) {
|
||||||
element.className = butClass;
|
element.className = btnClass;
|
||||||
if (butClass == 'unavail' || (butClass == 'active' && (element.id == 'pauseBtn' || element.id == 'playBtn'))) {
|
if (btnClass == 'unavail' || (btnClass == 'active' && (element.id == 'pauseBtn' || element.id == 'playBtn'))) {
|
||||||
element.disabled = true;
|
element.disabled = true;
|
||||||
} else {
|
} else {
|
||||||
element.disabled = false;
|
element.disabled = false;
|
||||||
|
|
|
@ -156,6 +156,7 @@ if ( !$Event->Id() ) {
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<button id="statsBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Stats') ?>" ><i class="fa fa-info"></i></button>
|
<button id="statsBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Stats') ?>" ><i class="fa fa-info"></i></button>
|
||||||
|
<button id="framesBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Frames') ?>" ><i class="fa fa-picture-o"></i></button>
|
||||||
<button id="deleteBtn" class="btn btn-danger" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Delete') ?>"><i class="fa fa-trash"></i></button>
|
<button id="deleteBtn" class="btn btn-danger" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Delete') ?>"><i class="fa fa-trash"></i></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ getBodyTopHTML();
|
||||||
<th data-sortable="true" data-field="Archived"><?php echo translate('Archived') ?></th>
|
<th data-sortable="true" data-field="Archived"><?php echo translate('Archived') ?></th>
|
||||||
<th data-sortable="true" data-field="Emailed"><?php echo translate('Emailed') ?></th>
|
<th data-sortable="true" data-field="Emailed"><?php echo translate('Emailed') ?></th>
|
||||||
<th data-sortable="true" data-field="Monitor"><?php echo translate('Monitor') ?></th>
|
<th data-sortable="true" data-field="Monitor"><?php echo translate('Monitor') ?></th>
|
||||||
<th data-sortable="true" data-field="Cause"><?php echo translate('Cause') ?></th>
|
<th data-sortable="true" data-field="Cause" data-click-to-select="false"><?php echo translate('Cause') ?></th>
|
||||||
<th data-sortable="true" data-field="StartDateTime"><?php echo translate('AttrStartTime') ?></th>
|
<th data-sortable="true" data-field="StartDateTime"><?php echo translate('AttrStartTime') ?></th>
|
||||||
<th data-sortable="true" data-field="EndDateTime"><?php echo translate('AttrEndTime') ?></th>
|
<th data-sortable="true" data-field="EndDateTime"><?php echo translate('AttrEndTime') ?></th>
|
||||||
<th data-sortable="true" data-field="Length"><?php echo translate('Duration') ?></th>
|
<th data-sortable="true" data-field="Length"><?php echo translate('Duration') ?></th>
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
|
var ProbeResults;
|
||||||
var probeReq = new Request.JSON( {url: thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getProbeResponse} );
|
|
||||||
|
|
||||||
function probe( url_e ) {
|
function probe( url_e ) {
|
||||||
probeReq.send( "request=add_monitors&action=probe&url="+url_e.value );
|
$j.getJSON(thisUrl + '?view=request&request=add_monitors&action=probe&url=' + url_e.value)
|
||||||
|
.done(getProbeResponse)
|
||||||
|
.fail(logAjaxFail);
|
||||||
}
|
}
|
||||||
|
|
||||||
var ProbeResults;
|
|
||||||
|
|
||||||
function getProbeResponse( respObj, respText ) {
|
function getProbeResponse( respObj, respText ) {
|
||||||
if ( checkStreamForErrors( "getProbeResponse", respObj ) ) {
|
if ( checkStreamForErrors( "getProbeResponse", respObj ) ) {
|
||||||
return;
|
return;
|
||||||
|
@ -82,7 +81,6 @@ function addMonitor(url) {
|
||||||
function import_csv( form ) {
|
function import_csv( form ) {
|
||||||
var formData = new FormData( form );
|
var formData = new FormData( form );
|
||||||
console.log(formData);
|
console.log(formData);
|
||||||
//formData.append('file', $('#file')[0].files[0]);
|
|
||||||
|
|
||||||
$j.ajax({
|
$j.ajax({
|
||||||
url: thisUrl+"?request=add_monitors&action=import",
|
url: thisUrl+"?request=add_monitors&action=import",
|
||||||
|
@ -90,16 +88,19 @@ function import_csv( form ) {
|
||||||
data: formData,
|
data: formData,
|
||||||
processData: false, // tell jQuery not to process the data
|
processData: false, // tell jQuery not to process the data
|
||||||
contentType: false, // tell jQuery not to set contentType
|
contentType: false, // tell jQuery not to set contentType
|
||||||
success: function(data) {
|
done: function(data) {
|
||||||
var json = JSON.parse(data);
|
var json = JSON.parse(data);
|
||||||
parseStreams( json.Streams );
|
parseStreams( json.Streams );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initPage() {
|
function initPage() {
|
||||||
url = $j('#Url')[0];
|
var url = $j('#Url')[0];
|
||||||
|
|
||||||
if ( url.value ) {
|
if ( url.value ) {
|
||||||
probe(url);
|
probe(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.addEventListener( 'DOMContentLoaded', initPage );
|
|
||||||
|
$j(document).ready(initPage);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
$j.ajaxSetup({timeout: AJAX_TIMEOUT}); //sets timeout for all getJSON.
|
|
||||||
var table = $j('#eventStatsTable');
|
var table = $j('#eventStatsTable');
|
||||||
var backBtn = $j('#backBtn');
|
var backBtn = $j('#backBtn');
|
||||||
var renameBtn = $j('#renameBtn');
|
var renameBtn = $j('#renameBtn');
|
||||||
|
@ -27,14 +26,20 @@ var streamCmdTimer = null;
|
||||||
var streamStatus = null;
|
var streamStatus = null;
|
||||||
var lastEventId = 0;
|
var lastEventId = 0;
|
||||||
var zmsBroke = false; //Use alternate navigation if zms has crashed
|
var zmsBroke = false; //Use alternate navigation if zms has crashed
|
||||||
var streamParms = "view=request&request=stream&connkey="+connKey;
|
|
||||||
if ( auth_hash ) streamParms += '&auth='+auth_hash;
|
|
||||||
var frameBatch = 40;
|
var frameBatch = 40;
|
||||||
var currFrameId = null;
|
var currFrameId = null;
|
||||||
var eventReq = new Request.JSON( {url: thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getEventResponse} );
|
var auth_hash;
|
||||||
var actReq = new Request.JSON( {url: thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getActResponse} );
|
|
||||||
var frameReq = new Request.JSON( {url: thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'chain', onSuccess: getFrameResponse} );
|
function streamReq(data) {
|
||||||
var streamReq = new Request.JSON( {url: monitorUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'chain', onSuccess: getCmdResponse} );
|
if ( auth_hash ) data.auth = auth_hash;
|
||||||
|
data.connkey = connKey;
|
||||||
|
data.view = 'request';
|
||||||
|
data.request = 'stream';
|
||||||
|
|
||||||
|
$j.getJSON(thisUrl, data)
|
||||||
|
.done(getCmdResponse)
|
||||||
|
.fail(logAjaxFail);
|
||||||
|
}
|
||||||
|
|
||||||
// Function called when video.js hits the end of the video
|
// Function called when video.js hits the end of the video
|
||||||
function vjsReplay() {
|
function vjsReplay() {
|
||||||
|
@ -208,7 +213,7 @@ function changeScale() {
|
||||||
} // end function changeScale
|
} // end function changeScale
|
||||||
|
|
||||||
function changeReplayMode() {
|
function changeReplayMode() {
|
||||||
var replayMode = $('replayMode').get('value');
|
var replayMode = $j('#replayMode').val();
|
||||||
|
|
||||||
Cookie.write('replayMode', replayMode, {duration: 10*365, samesite: 'strict'});
|
Cookie.write('replayMode', replayMode, {duration: 10*365, samesite: 'strict'});
|
||||||
|
|
||||||
|
@ -217,6 +222,7 @@ function changeReplayMode() {
|
||||||
|
|
||||||
function changeRate() {
|
function changeRate() {
|
||||||
var rate = parseInt($j('select[name="rate"]').val());
|
var rate = parseInt($j('select[name="rate"]').val());
|
||||||
|
|
||||||
if ( ! rate ) {
|
if ( ! rate ) {
|
||||||
pauseClicked();
|
pauseClicked();
|
||||||
} else if ( rate < 0 ) {
|
} else if ( rate < 0 ) {
|
||||||
|
@ -233,13 +239,13 @@ function changeRate() {
|
||||||
}
|
}
|
||||||
}, 500); //500ms is a compromise between smooth reverse and realistic performance
|
}, 500); //500ms is a compromise between smooth reverse and realistic performance
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_VARPLAY+"&rate="+rate);
|
streamReq({command: CMD_VARPLAY, rate: rate});
|
||||||
} // end if vid
|
} // end if vid
|
||||||
} else { // Forward rate
|
} else { // Forward rate
|
||||||
if ( vid ) {
|
if ( vid ) {
|
||||||
vid.playbackRate(rate/100);
|
vid.playbackRate(rate/100);
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_VARPLAY+"&rate="+rate);
|
streamReq({command: CMD_VARPLAY, rate: rate});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Cookie.write('zmEventRate', rate, {duration: 10*365, samesite: 'strict'});
|
Cookie.write('zmEventRate', rate, {duration: 10*365, samesite: 'strict'});
|
||||||
|
@ -291,9 +297,9 @@ function getCmdResponse( respObj, respText ) {
|
||||||
$j('#progressValue').html(secsToTime(parseInt(streamStatus.progress)));
|
$j('#progressValue').html(secsToTime(parseInt(streamStatus.progress)));
|
||||||
$j('#zoomValue').html(streamStatus.zoom);
|
$j('#zoomValue').html(streamStatus.zoom);
|
||||||
if ( streamStatus.zoom == "1.0" ) {
|
if ( streamStatus.zoom == "1.0" ) {
|
||||||
setButtonState( $('zoomOutBtn'), 'unavail' );
|
setButtonState( 'zoomOutBtn', 'unavail' );
|
||||||
} else {
|
} else {
|
||||||
setButtonState( $('zoomOutBtn'), 'inactive' );
|
setButtonState( 'zoomOutBtn', 'inactive' );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProgressBar();
|
updateProgressBar();
|
||||||
|
@ -316,23 +322,24 @@ function pauseClicked() {
|
||||||
}
|
}
|
||||||
vid.pause();
|
vid.pause();
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_PAUSE);
|
streamReq({command: CMD_PAUSE});
|
||||||
}
|
}
|
||||||
streamPause();
|
streamPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamPause() {
|
function streamPause() {
|
||||||
$j('#modeValue').html('Paused');
|
$j('#modeValue').html('Paused');
|
||||||
setButtonState( $('pauseBtn'), 'active' );
|
setButtonState( 'pauseBtn', 'active' );
|
||||||
setButtonState( $('playBtn'), 'inactive' );
|
setButtonState( 'playBtn', 'inactive' );
|
||||||
setButtonState( $('fastFwdBtn'), 'unavail' );
|
setButtonState( 'fastFwdBtn', 'unavail' );
|
||||||
setButtonState( $('slowFwdBtn'), 'inactive' );
|
setButtonState( 'slowFwdBtn', 'inactive' );
|
||||||
setButtonState( $('slowRevBtn'), 'inactive' );
|
setButtonState( 'slowRevBtn', 'inactive' );
|
||||||
setButtonState( $('fastRevBtn'), 'unavail' );
|
setButtonState( 'fastRevBtn', 'unavail' );
|
||||||
}
|
}
|
||||||
|
|
||||||
function playClicked( ) {
|
function playClicked( ) {
|
||||||
var rate_select = $j('select[name="rate"]');
|
var rate_select = $j('select[name="rate"]');
|
||||||
|
|
||||||
if ( ! rate_select.val() ) {
|
if ( ! rate_select.val() ) {
|
||||||
$j('select[name="rate"]').val(100);
|
$j('select[name="rate"]').val(100);
|
||||||
}
|
}
|
||||||
|
@ -343,7 +350,7 @@ function playClicked( ) {
|
||||||
vjsPlay(); //handles fast forward and rewind
|
vjsPlay(); //handles fast forward and rewind
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_PLAY);
|
streamReq({command: CMD_PLAY});
|
||||||
}
|
}
|
||||||
streamPlay();
|
streamPlay();
|
||||||
}
|
}
|
||||||
|
@ -358,31 +365,31 @@ function vjsPlay() { //catches if we change mode programatically
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamPlay( ) {
|
function streamPlay( ) {
|
||||||
setButtonState( $('pauseBtn'), 'inactive' );
|
setButtonState( 'pauseBtn', 'inactive' );
|
||||||
setButtonState( $('playBtn'), 'active' );
|
setButtonState( 'playBtn', 'active' );
|
||||||
setButtonState( $('fastFwdBtn'), 'inactive' );
|
setButtonState( 'fastFwdBtn', 'inactive' );
|
||||||
setButtonState( $('slowFwdBtn'), 'unavail' );
|
setButtonState( 'slowFwdBtn', 'unavail' );
|
||||||
setButtonState( $('slowRevBtn'), 'unavail' );
|
setButtonState( 'slowRevBtn', 'unavail' );
|
||||||
setButtonState( $('fastRevBtn'), 'inactive' );
|
setButtonState( 'fastRevBtn', 'inactive' );
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamFastFwd( action ) {
|
function streamFastFwd( action ) {
|
||||||
setButtonState( $('pauseBtn'), 'inactive' );
|
setButtonState( 'pauseBtn', 'inactive' );
|
||||||
setButtonState( $('playBtn'), 'inactive' );
|
setButtonState( 'playBtn', 'inactive' );
|
||||||
setButtonState( $('fastFwdBtn'), 'active' );
|
setButtonState( 'fastFwdBtn', 'active' );
|
||||||
setButtonState( $('slowFwdBtn'), 'unavail' );
|
setButtonState( 'slowFwdBtn', 'unavail' );
|
||||||
setButtonState( $('slowRevBtn'), 'unavail' );
|
setButtonState( 'slowRevBtn', 'unavail' );
|
||||||
setButtonState( $('fastRevBtn'), 'inactive' );
|
setButtonState( 'fastRevBtn', 'inactive' );
|
||||||
if ( vid ) {
|
if ( vid ) {
|
||||||
if ( revSpeed != .5 ) stopFastRev();
|
if ( revSpeed != .5 ) stopFastRev();
|
||||||
vid.playbackRate(rates[rates.indexOf(vid.playbackRate()*100)-1]/100);
|
vid.playbackRate(rates[rates.indexOf(vid.playbackRate()*100)-1]/100);
|
||||||
if ( rates.indexOf(vid.playbackRate()*100)-1 == -1 ) {
|
if ( rates.indexOf(vid.playbackRate()*100)-1 == -1 ) {
|
||||||
setButtonState($('fastFwdBtn'), 'unavail');
|
setButtonState('fastFwdBtn', 'unavail');
|
||||||
}
|
}
|
||||||
$j('select[name="rate"]').val(vid.playbackRate()*100);
|
$j('select[name="rate"]').val(vid.playbackRate()*100);
|
||||||
Cookie.write('zmEventRate', vid.playbackRate()*100, {duration: 10*365, samesite: 'strict'});
|
Cookie.write('zmEventRate', vid.playbackRate()*100, {duration: 10*365, samesite: 'strict'});
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_FASTFWD);
|
streamReq({command: CMD_FASTFWD});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +398,7 @@ function streamSlowFwd( action ) {
|
||||||
if ( vid ) {
|
if ( vid ) {
|
||||||
vid.currentTime(vid.currentTime() + spf);
|
vid.currentTime(vid.currentTime() + spf);
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_SLOWFWD);
|
streamReq({command: CMD_SLOWFWD});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,7 +406,7 @@ function streamSlowRev( action ) {
|
||||||
if ( vid ) {
|
if ( vid ) {
|
||||||
vid.currentTime(vid.currentTime() - spf);
|
vid.currentTime(vid.currentTime() - spf);
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_SLOWREV);
|
streamReq({command: CMD_SLOWREV});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,16 +419,16 @@ function stopFastRev() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamFastRev( action ) {
|
function streamFastRev( action ) {
|
||||||
setButtonState( $('pauseBtn'), 'inactive' );
|
setButtonState( 'pauseBtn', 'inactive' );
|
||||||
setButtonState( $('playBtn'), 'inactive' );
|
setButtonState( 'playBtn', 'inactive' );
|
||||||
setButtonState( $('fastFwdBtn'), 'inactive' );
|
setButtonState( 'fastFwdBtn', 'inactive' );
|
||||||
setButtonState( $('slowFwdBtn'), 'unavail' );
|
setButtonState( 'slowFwdBtn', 'unavail' );
|
||||||
setButtonState( $('slowRevBtn'), 'unavail' );
|
setButtonState( 'slowRevBtn', 'unavail' );
|
||||||
setButtonState( $('fastRevBtn'), 'active' );
|
setButtonState( 'fastRevBtn', 'active' );
|
||||||
if ( vid ) { //There is no reverse play with mp4. Set the speed to 0 and manually set the time back.
|
if ( vid ) { //There is no reverse play with mp4. Set the speed to 0 and manually set the time back.
|
||||||
revSpeed = rates[rates.indexOf(revSpeed*100)-1]/100;
|
revSpeed = rates[rates.indexOf(revSpeed*100)-1]/100;
|
||||||
if ( rates.indexOf(revSpeed*100) == 0 ) {
|
if ( rates.indexOf(revSpeed*100) == 0 ) {
|
||||||
setButtonState( $('fastRevBtn'), 'unavail' );
|
setButtonState( 'fastRevBtn', 'unavail' );
|
||||||
}
|
}
|
||||||
clearInterval(intervalRewind);
|
clearInterval(intervalRewind);
|
||||||
$j('select[name="rate"]').val(-revSpeed*100);
|
$j('select[name="rate"]').val(-revSpeed*100);
|
||||||
|
@ -436,7 +443,7 @@ function streamFastRev( action ) {
|
||||||
}
|
}
|
||||||
}, 500); //500ms is a compromise between smooth reverse and realistic performance
|
}, 500); //500ms is a compromise between smooth reverse and realistic performance
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_FASTREV);
|
streamReq({command: CMD_FASTREV});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +459,7 @@ function streamPrev(action) {
|
||||||
} else if (zmsBroke || (vid && PrevEventDefVideoPath.indexOf("view_video") < 0) || $j("#vjsMessage").length || PrevEventDefVideoPath.indexOf("view_video") > 0) {//zms broke, leaving videojs, last event, moving to videojs
|
} else if (zmsBroke || (vid && PrevEventDefVideoPath.indexOf("view_video") < 0) || $j("#vjsMessage").length || PrevEventDefVideoPath.indexOf("view_video") > 0) {//zms broke, leaving videojs, last event, moving to videojs
|
||||||
location.replace(thisUrl + '?view=event&eid=' + prevEventId + filterQuery + sortQuery);
|
location.replace(thisUrl + '?view=event&eid=' + prevEventId + filterQuery + sortQuery);
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_PREV);
|
streamReq({command: CMD_PREV});
|
||||||
streamPlay();
|
streamPlay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,7 +487,7 @@ function streamNext(action) {
|
||||||
} else if ( zmsBroke || (vid && NextEventDefVideoPath.indexOf("view_video") < 0) || NextEventDefVideoPath.indexOf("view_video") > 0) {//reload zms, leaving vjs, moving to vjs
|
} else if ( zmsBroke || (vid && NextEventDefVideoPath.indexOf("view_video") < 0) || NextEventDefVideoPath.indexOf("view_video") > 0) {//reload zms, leaving vjs, moving to vjs
|
||||||
location.replace(thisUrl + '?view=event&eid=' + nextEventId + filterQuery + sortQuery);
|
location.replace(thisUrl + '?view=event&eid=' + nextEventId + filterQuery + sortQuery);
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_NEXT);
|
streamReq({command: CMD_NEXT});
|
||||||
streamPlay();
|
streamPlay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,7 +538,7 @@ function streamZoomIn( x, y ) {
|
||||||
if (vid) {
|
if (vid) {
|
||||||
vjsPanZoom('zoom', x, y);
|
vjsPanZoom('zoom', x, y);
|
||||||
} else {
|
} else {
|
||||||
streamReq.send( streamParms+"&command="+CMD_ZOOMIN+"&x="+x+"&y="+y );
|
streamReq({command: CMD_ZOOMIN, x: x, y: y});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,28 +546,28 @@ function streamZoomOut() {
|
||||||
if (vid) {
|
if (vid) {
|
||||||
vjsPanZoom('zoomOut');
|
vjsPanZoom('zoomOut');
|
||||||
} else {
|
} else {
|
||||||
streamReq.send( streamParms+"&command="+CMD_ZOOMOUT );
|
streamReq({command: CMD_ZOOMOUT});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamScale( scale ) {
|
function streamScale( scale ) {
|
||||||
streamReq.send( streamParms+"&command="+CMD_SCALE+"&scale="+scale );
|
streamReq({command: CMD_SCALE, scale: scale});
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamPan( x, y ) {
|
function streamPan( x, y ) {
|
||||||
if (vid) {
|
if (vid) {
|
||||||
vjsPanZoom('pan', x, y);
|
vjsPanZoom('pan', x, y);
|
||||||
} else {
|
} else {
|
||||||
streamReq.send( streamParms+"&command="+CMD_PAN+"&x="+x+"&y="+y );
|
streamReq({command: CMD_PAN, x: x, y: y});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamSeek( offset ) {
|
function streamSeek( offset ) {
|
||||||
streamReq.send( streamParms+"&command="+CMD_SEEK+"&offset="+offset );
|
streamReq({command: CMD_SEEK, offset: offset});
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamQuery() {
|
function streamQuery() {
|
||||||
streamReq.send( streamParms+"&command="+CMD_QUERY );
|
streamReq({command: CMD_QUERY});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEventResponse(respObj, respText) {
|
function getEventResponse(respObj, respText) {
|
||||||
|
@ -570,9 +577,9 @@ function getEventResponse(respObj, respText) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eventData = respObj.event;
|
eventData = respObj.event;
|
||||||
var eventStills = $('eventStills');
|
var eventStills = $j('#eventStills');
|
||||||
|
|
||||||
if ( eventStills && !$('eventStills').hasClass( 'hidden' ) && currEventId != eventData.Id ) {
|
if ( eventStills && !eventStills.hasClass('hidden') && currEventId != eventData.Id ) {
|
||||||
resetEventStills();
|
resetEventStills();
|
||||||
}
|
}
|
||||||
currEventId = eventData.Id;
|
currEventId = eventData.Id;
|
||||||
|
@ -602,9 +609,6 @@ function getEventResponse(respObj, respText) {
|
||||||
unarchiveBtn.prop('disabled', !(eventData.Archived && canEdit.Events));
|
unarchiveBtn.prop('disabled', !(eventData.Archived && canEdit.Events));
|
||||||
|
|
||||||
history.replaceState(null, null, '?view=event&eid=' + eventData.Id + filterQuery + sortQuery); //if popup removed, check if this allows forward
|
history.replaceState(null, null, '?view=event&eid=' + eventData.Id + filterQuery + sortQuery); //if popup removed, check if this allows forward
|
||||||
// Technically, events can be different sizes, so may need to update the size of the image, but it might be better to have it stay scaled...
|
|
||||||
//var eventImg = $('eventImage');
|
|
||||||
//eventImg.setStyles( { 'width': eventData.width, 'height': eventData.height } );
|
|
||||||
if ( vid && CurEventDefVideoPath ) {
|
if ( vid && CurEventDefVideoPath ) {
|
||||||
vid.src({type: 'video/mp4', src: CurEventDefVideoPath}); //Currently mp4 is all we use
|
vid.src({type: 'video/mp4', src: CurEventDefVideoPath}); //Currently mp4 is all we use
|
||||||
console.log('getEventResponse');
|
console.log('getEventResponse');
|
||||||
|
@ -621,12 +625,14 @@ function getEventResponse(respObj, respText) {
|
||||||
nearEventsQuery( eventData.Id );
|
nearEventsQuery( eventData.Id );
|
||||||
} // end function getEventResponse
|
} // end function getEventResponse
|
||||||
|
|
||||||
function eventQuery( eventId ) {
|
function eventQuery(eventId) {
|
||||||
var eventParms = 'view=request&request=status&entity=event&id='+eventId;
|
var data = {};
|
||||||
if ( auth_hash ) {
|
data.id = eventId;
|
||||||
eventParms += '&auth='+auth_hash;
|
if ( auth_hash ) data.auth = auth_hash;
|
||||||
}
|
|
||||||
eventReq.send( eventParms );
|
$j.getJSON(thisUrl + '?view=request&request=status&entity=event', data)
|
||||||
|
.done(getEventResponse)
|
||||||
|
.fail(logAjaxFail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNearEventsResponse( respObj, respText ) {
|
function getNearEventsResponse( respObj, respText ) {
|
||||||
|
@ -640,10 +646,8 @@ function getNearEventsResponse( respObj, respText ) {
|
||||||
PrevEventDefVideoPath = respObj.nearevents.PrevEventDefVideoPath;
|
PrevEventDefVideoPath = respObj.nearevents.PrevEventDefVideoPath;
|
||||||
NextEventDefVideoPath = respObj.nearevents.NextEventDefVideoPath;
|
NextEventDefVideoPath = respObj.nearevents.NextEventDefVideoPath;
|
||||||
|
|
||||||
var prevEventBtn = $('prevEventBtn');
|
$j('#prevEventBtn').prop('disabled', !prevEventId);
|
||||||
if ( prevEventBtn ) prevEventBtn.disabled = !prevEventId;
|
$j('#nextEventBtn').prop('disabled', !nextEventId);
|
||||||
var nextEventBtn = $('nextEventBtn');
|
|
||||||
if ( nextEventBtn ) nextEventBtn.disabled = !nextEventId;
|
|
||||||
$j('#prevBtn').prop('disabled', prevEventId == 0 ? true : false).attr('class', prevEventId == 0 ? 'unavail' : 'inactive');
|
$j('#prevBtn').prop('disabled', prevEventId == 0 ? true : false).attr('class', prevEventId == 0 ? 'unavail' : 'inactive');
|
||||||
$j('#nextBtn').prop('disabled', nextEventId == 0 ? true : false).attr('class', nextEventId == 0 ? 'unavail' : 'inactive');
|
$j('#nextBtn').prop('disabled', nextEventId == 0 ? true : false).attr('class', nextEventId == 0 ? 'unavail' : 'inactive');
|
||||||
}
|
}
|
||||||
|
@ -656,7 +660,7 @@ function nearEventsQuery( eventId ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadEventThumb( event, frame, loadImage ) {
|
function loadEventThumb( event, frame, loadImage ) {
|
||||||
var thumbImg = $('eventThumb'+frame.FrameId);
|
var thumbImg = $j('#eventThumb'+frame.FrameId);
|
||||||
if ( !thumbImg ) {
|
if ( !thumbImg ) {
|
||||||
console.error('No holder found for frame '+frame.FrameId);
|
console.error('No holder found for frame '+frame.FrameId);
|
||||||
return;
|
return;
|
||||||
|
@ -664,12 +668,12 @@ function loadEventThumb( event, frame, loadImage ) {
|
||||||
var img = new Asset.image( imagePrefix+frame.EventId+"&fid="+frame.FrameId,
|
var img = new Asset.image( imagePrefix+frame.EventId+"&fid="+frame.FrameId,
|
||||||
{
|
{
|
||||||
'onload': ( function( loadImage ) {
|
'onload': ( function( loadImage ) {
|
||||||
thumbImg.setProperty( 'src', img.getProperty( 'src' ) );
|
thumbImg.prop('src', img.prop('src'));
|
||||||
thumbImg.removeClass( 'placeholder' );
|
thumbImg.prop('class', frame.Type=='Alarm'?'alarm':'normal');
|
||||||
thumbImg.setProperty( 'class', frame.Type=='Alarm'?'alarm':'normal' );
|
thumbImg.prop('title', frame.FrameId+' / '+((frame.Type=='Alarm')?frame.Score:0));
|
||||||
thumbImg.setProperty( 'title', frame.FrameId+' / '+((frame.Type=='Alarm')?frame.Score:0) );
|
thumbImg.removeClass('placeholder');
|
||||||
thumbImg.removeEvents( 'click' );
|
thumbImg.off('click');
|
||||||
thumbImg.addEvent( 'click', function() {
|
thumbImg.click(function() {
|
||||||
locateImage( frame.FrameId, true );
|
locateImage( frame.FrameId, true );
|
||||||
} );
|
} );
|
||||||
if ( loadImage ) {
|
if ( loadImage ) {
|
||||||
|
@ -682,72 +686,73 @@ function loadEventThumb( event, frame, loadImage ) {
|
||||||
|
|
||||||
function loadEventImage(event, frame) {
|
function loadEventImage(event, frame) {
|
||||||
console.debug('Loading '+event.Id+'/'+frame.FrameId);
|
console.debug('Loading '+event.Id+'/'+frame.FrameId);
|
||||||
var eventImg = $('eventImage');
|
var eventImg = $j('#eventImage');
|
||||||
var thumbImg = $('eventThumb'+frame.FrameId);
|
var thumbImg = $j('#eventThumb'+frame.FrameId);
|
||||||
if ( eventImg.getProperty('src') != thumbImg.getProperty('src') ) {
|
if ( eventImg.prop('src') != thumbImg.prop('src') ) {
|
||||||
var eventImagePanel = $('eventImagePanel');
|
var eventImagePanel = $j('#eventImagePanel');
|
||||||
|
|
||||||
if ( eventImagePanel.getStyle('display') != 'none' ) {
|
if ( eventImagePanel.css('display') != 'none' ) {
|
||||||
var lastThumbImg = $('eventThumb'+eventImg.getProperty('alt'));
|
var lastThumbImg = $j('#eventThumb' + eventImg.prop('alt'));
|
||||||
lastThumbImg.removeClass('selected');
|
lastThumbImg.removeClass('selected');
|
||||||
lastThumbImg.setOpacity(1.0);
|
lastThumbImg.css('opacity', '1.0');
|
||||||
}
|
}
|
||||||
|
|
||||||
$('eventImageBar').setStyle('width', event.Width);
|
$j('#eventImageBar').css('width', event.Width);
|
||||||
if ( frame.Type == 'Alarm' ) {
|
if ( frame.Type == 'Alarm' ) {
|
||||||
$('eventImageStats').removeClass('hidden');
|
$j('#eventImageStats').removeClass('hidden');
|
||||||
} else {
|
} else {
|
||||||
$('eventImageStats').addClass('hidden');
|
$j('#eventImageStats').addClass('hidden');
|
||||||
}
|
}
|
||||||
thumbImg.addClass('selected');
|
thumbImg.addClass('selected');
|
||||||
thumbImg.setOpacity(0.5);
|
thumbImg.css('opacity', '0.5');
|
||||||
|
|
||||||
if ( eventImagePanel.getStyle('display') == 'none' ) {
|
if ( eventImagePanel.css('display') == 'none' ) {
|
||||||
eventImagePanel.setOpacity(0);
|
eventImagePanel.css('opacity', '0');
|
||||||
eventImagePanel.setStyle('display', 'inline-block');
|
eventImagePanel.css('display', 'inline-block');
|
||||||
new Fx.Tween( eventImagePanel, {duration: 500, transition: Fx.Transitions.Sine} ).start( 'opacity', 0, 1 );
|
new Fx.Tween( eventImagePanel, {duration: 500, transition: Fx.Transitions.Sine} ).start( 'opacity', 0, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
eventImg.setProperties( {
|
eventImg.prop( {
|
||||||
'class': frame.Type=='Alarm'?'alarm':'normal',
|
'class': frame.Type=='Alarm'?'alarm':'normal',
|
||||||
'src': thumbImg.getProperty( 'src' ),
|
'src': thumbImg.prop('src'),
|
||||||
'title': thumbImg.getProperty( 'title' ),
|
'title': thumbImg.prop('title'),
|
||||||
'alt': thumbImg.getProperty( 'alt' ),
|
'alt': thumbImg.prop('alt'),
|
||||||
'height': $j('#eventThumbs').height() - $j('#eventImageBar').outerHeight(true)-10
|
'height': $j('#eventThumbs').height() - $j('#eventImageBar').outerHeight(true)-10
|
||||||
} );
|
} );
|
||||||
|
|
||||||
$('eventImageNo').set('text', frame.FrameId);
|
$j('#eventImageNo').text(frame.FrameId);
|
||||||
$('prevImageBtn').disabled = (frame.FrameId==1);
|
$j('#prevImageBtn').prop('disabled', !frame.FrameId == 1);
|
||||||
$('nextImageBtn').disabled = (frame.FrameId==event.Frames);
|
$j('#nextImageBtn').prop('disabled', !frame.FrameId == event.Frames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideEventImageComplete() {
|
function hideEventImageComplete() {
|
||||||
var thumbImg = $('eventThumb'+$('eventImage').getProperty('alt'));
|
var thumbImg = $j('#eventThumb'+$j('#eventImage').prop('alt'));
|
||||||
if ( thumbImg ) {
|
if ( thumbImg ) {
|
||||||
thumbImg.removeClass('selected');
|
thumbImg.removeClass('selected');
|
||||||
thumbImg.setOpacity(1.0);
|
thumbImg.css('opacity', '1.0');
|
||||||
} else {
|
} else {
|
||||||
console.log('Unable to find eventThumb at eventThumb'+$('eventImage').getProperty('alt'));
|
console.log('Unable to find eventThumb at eventThumb'+$j('#eventImage').prop('alt'));
|
||||||
}
|
}
|
||||||
$('prevImageBtn').disabled = true;
|
$j('#prevImageBtn').prop('disabled', true);
|
||||||
$('nextImageBtn').disabled = true;
|
$j('#nextImageBtn').prop('disabled', true);
|
||||||
$('eventImagePanel').setStyle('display', 'none');
|
$j('#eventImagePanel').css('display', 'none');
|
||||||
$('eventImageStats').addClass('hidden');
|
$j('#eventImageStats').addClass('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideEventImage() {
|
function hideEventImage() {
|
||||||
if ( $('eventImagePanel').getStyle('display') != 'none' ) {
|
if ( $j('#eventImagePanel').css('display') != 'none' ) {
|
||||||
new Fx.Tween( $('eventImagePanel'), {duration: 500, transition: Fx.Transitions.Sine, onComplete: hideEventImageComplete} ).start('opacity', 1, 0);
|
new Fx.Tween( $j('#eventImagePanel'), {duration: 500, transition: Fx.Transitions.Sine, onComplete: hideEventImageComplete} ).start('opacity', 1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetEventStills() {
|
function resetEventStills() {
|
||||||
hideEventImage();
|
hideEventImage();
|
||||||
$('eventThumbs').empty();
|
$j('#eventThumbs').empty();
|
||||||
if ( true || !slider ) {
|
if ( true || !slider ) {
|
||||||
slider = new Slider( $('thumbsSlider'), $('thumbsKnob'), {
|
slider = new Slider( '#thumbsSlider', '#thumbsKnob', {
|
||||||
/*steps: eventData.Frames,*/
|
/*steps: eventData.Frames,*/
|
||||||
|
value: 0,
|
||||||
onChange: function( step ) {
|
onChange: function( step ) {
|
||||||
if ( !step ) {
|
if ( !step ) {
|
||||||
step = 0;
|
step = 0;
|
||||||
|
@ -761,7 +766,7 @@ function resetEventStills() {
|
||||||
checkFrames( eventData.Id, fid, ($j('#eventImagePanel').css('display')=='none'?'':'true'));
|
checkFrames( eventData.Id, fid, ($j('#eventImagePanel').css('display')=='none'?'':'true'));
|
||||||
scroll.toElement( 'eventThumb'+fid );
|
scroll.toElement( 'eventThumb'+fid );
|
||||||
}
|
}
|
||||||
} ).set( 0 );
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -787,8 +792,13 @@ function getFrameResponse(respObj, respText) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function frameQuery( eventId, frameId, loadImage ) {
|
function frameQuery( eventId, frameId, loadImage ) {
|
||||||
var parms = "view=request&request=status&entity=frameimage&id[0]="+eventId+"&id[1]="+frameId+"&loopback="+loadImage;
|
var data = {};
|
||||||
frameReq.send(parms);
|
data.loopback = loadImage;
|
||||||
|
data.id = {eventId, frameId};
|
||||||
|
|
||||||
|
$j.getJSON(thisUrl + '?view=request&request=status&entity=frameimage', data)
|
||||||
|
.done(getFrameResponse)
|
||||||
|
.fail(logAjaxFail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkFrames( eventId, frameId, loadImage ) {
|
function checkFrames( eventId, frameId, loadImage ) {
|
||||||
|
@ -813,23 +823,30 @@ function checkFrames( eventId, frameId, loadImage ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( var fid = loFid; fid <= hiFid; fid++ ) {
|
for ( var fid = loFid; fid <= hiFid; fid++ ) {
|
||||||
if ( !$('eventThumb'+fid) ) {
|
if ( !$j('#eventThumb'+fid) ) {
|
||||||
var img = new Element('img', {'id': 'eventThumb'+fid, 'src': 'graphics/transparent.png', 'alt': fid, 'class': 'placeholder'});
|
var img = $j('<img>');
|
||||||
img.addEvent('click', function() {
|
img.attr({
|
||||||
|
'id': 'eventThumb'+fid,
|
||||||
|
'src': 'graphics/transparent.png',
|
||||||
|
'alt': fid,
|
||||||
|
'class': 'placeholder'
|
||||||
|
});
|
||||||
|
|
||||||
|
img.click(function() {
|
||||||
eventData['frames'][fid] = null;
|
eventData['frames'][fid] = null;
|
||||||
checkFrames(eventId, fid);
|
checkFrames(eventId, fid);
|
||||||
});
|
});
|
||||||
frameQuery(eventId, fid, loadImage && (fid == frameId));
|
frameQuery(eventId, fid, loadImage && (fid == frameId));
|
||||||
var imgs = $('eventThumbs').getElements('img');
|
var imgs = $j('#eventThumbs img');
|
||||||
var injected = false;
|
var injected = false;
|
||||||
if ( fid < imgs.length ) {
|
if ( fid < imgs.length ) {
|
||||||
img.inject(imgs[fid-1], 'before');
|
imgs.before(img);
|
||||||
injected = true;
|
injected = true;
|
||||||
} else {
|
} else {
|
||||||
injected = imgs.some(
|
injected = imgs.toArray().some(
|
||||||
function( thumbImg, index ) {
|
function( thumbImg, index ) {
|
||||||
if ( parseInt(img.getProperty('alt')) < parseInt(thumbImg.getProperty('alt')) ) {
|
if ( parseInt(img.prop('alt')) < parseInt(thumbImg.prop('alt')) ) {
|
||||||
img.inject(thumbImg, 'before');
|
thumbImg.before(img);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -837,10 +854,10 @@ function checkFrames( eventId, frameId, loadImage ) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ( !injected ) {
|
if ( !injected ) {
|
||||||
img.inject($('eventThumbs'));
|
$j('#eventThumbs').append(img);
|
||||||
}
|
}
|
||||||
var scale = parseInt(img.getStyle('height'));
|
var scale = parseInt(img.css('height'));
|
||||||
img.setStyles( {
|
img.css( {
|
||||||
'width': parseInt((eventData.Width*scale)/100),
|
'width': parseInt((eventData.Width*scale)/100),
|
||||||
'height': parseInt((eventData.Height*scale)/100)
|
'height': parseInt((eventData.Height*scale)/100)
|
||||||
} );
|
} );
|
||||||
|
@ -850,8 +867,8 @@ function checkFrames( eventId, frameId, loadImage ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$('prevThumbsBtn').disabled = (frameId==1);
|
$j('#prevThumbsBtn').prop('disabled', frameId == 1);
|
||||||
$('nextThumbsBtn').disabled = (frameId==eventData.Frames);
|
$j('#nextThumbsBtn').prop('disabled', frameId == eventData.Frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
function locateImage( frameId, loadImage ) {
|
function locateImage( frameId, loadImage ) {
|
||||||
|
@ -876,13 +893,13 @@ function nextImage() {
|
||||||
|
|
||||||
function prevThumbs() {
|
function prevThumbs() {
|
||||||
if ( currFrameId > 1 ) {
|
if ( currFrameId > 1 ) {
|
||||||
locateImage( parseInt(currFrameId)>10?(parseInt(currFrameId)-10):1, $('eventImagePanel').getStyle('display')!="none" );
|
locateImage( parseInt(currFrameId)>10?(parseInt(currFrameId)-10):1, $j('#eventImagePanel').css('display')!="none" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextThumbs() {
|
function nextThumbs() {
|
||||||
if ( currFrameId < eventData.Frames ) {
|
if ( currFrameId < eventData.Frames ) {
|
||||||
locateImage( parseInt(currFrameId)<(eventData.Frames-10)?(parseInt(currFrameId)+10):eventData.Frames, $('eventImagePanel').getStyle('display')!="none" );
|
locateImage( parseInt(currFrameId)<(eventData.Frames-10)?(parseInt(currFrameId)+10):eventData.Frames, $j('#eventImagePanel').css('display')!="none" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -911,14 +928,15 @@ function getActResponse( respObj, respText ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function actQuery(action, parms) {
|
function actQuery(action, parms) {
|
||||||
var actParms = "view=request&request=event&id="+eventData.Id+"&action="+action;
|
var data = {};
|
||||||
if ( auth_hash ) {
|
if ( parms ) data = parms;
|
||||||
actParms += '&auth='+auth_hash;
|
if ( auth_hash ) data.auth = auth_hash;
|
||||||
}
|
data.id = eventData.Id;
|
||||||
if ( parms != null ) {
|
data.action = action;
|
||||||
actParms += "&"+Object.toQueryString(parms);
|
|
||||||
}
|
$j.getJSON(thisUrl + '?view=request&request=event', data)
|
||||||
actReq.send(actParms);
|
.done(getActResponse)
|
||||||
|
.fail(logAjaxFail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renameEvent() {
|
function renameEvent() {
|
||||||
|
@ -937,19 +955,19 @@ function showEventFrames() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function showStream() {
|
function showStream() {
|
||||||
$('eventStills').addClass('hidden');
|
$j('#eventStills').addClass('hidden');
|
||||||
$('eventVideo').removeClass('hidden');
|
$j('#eventVideo').removeClass('hidden');
|
||||||
|
|
||||||
$('stillsEvent').removeClass('hidden');
|
$j('#stillsEvent').removeClass('hidden');
|
||||||
$('streamEvent').addClass('hidden');
|
$j('#streamEvent').addClass('hidden');
|
||||||
|
|
||||||
streamMode = 'video';
|
streamMode = 'video';
|
||||||
if (scale == 'auto') changeScale();
|
if (scale == 'auto') changeScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
function showStills() {
|
function showStills() {
|
||||||
$('eventStills').removeClass('hidden');
|
$j('#eventStills').removeClass('hidden');
|
||||||
$('eventVideo').addClass('hidden');
|
$j('#eventVideo').addClass('hidden');
|
||||||
|
|
||||||
if (vid && ( vid.paused != true ) ) {
|
if (vid && ( vid.paused != true ) ) {
|
||||||
// Pause the video
|
// Pause the video
|
||||||
|
@ -960,8 +978,8 @@ function showStills() {
|
||||||
//playButton.innerHTML = "Play";
|
//playButton.innerHTML = "Play";
|
||||||
}
|
}
|
||||||
|
|
||||||
$('stillsEvent').addClass('hidden');
|
$j('#stillsEvent').addClass('hidden');
|
||||||
$('streamEvent').removeClass('hidden');
|
$j('#streamEvent').removeClass('hidden');
|
||||||
|
|
||||||
streamMode = 'stills';
|
streamMode = 'stills';
|
||||||
|
|
||||||
|
@ -980,7 +998,7 @@ function showStills() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function showFrameStats() {
|
function showFrameStats() {
|
||||||
var fid = $('eventImageNo').get('text');
|
var fid = $j('#eventImageNo').text();
|
||||||
window.location.assign('?view=stats&eid='+eventData.Id+'&fid='+fid);
|
window.location.assign('?view=stats&eid='+eventData.Id+'&fid='+fid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,13 +1032,14 @@ function progressBarNav() {
|
||||||
|
|
||||||
function handleClick( event ) {
|
function handleClick( event ) {
|
||||||
var target = event.target;
|
var target = event.target;
|
||||||
|
var rect = target.getBoundingClientRect();
|
||||||
if ( vid ) {
|
if ( vid ) {
|
||||||
if (target.id != 'videoobj') return; // ignore clicks on control bar
|
if (target.id != 'videoobj') return; // ignore clicks on control bar
|
||||||
var x = event.offsetX;
|
var x = event.offsetX;
|
||||||
var y = event.offsetY;
|
var y = event.offsetY;
|
||||||
} else {
|
} else {
|
||||||
var x = event.page.x - $(target).getLeft();
|
var x = event.page.x - rect.left;
|
||||||
var y = event.page.y - $(target).getTop();
|
var y = event.page.y - rect.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( event.shift || event.shiftKey ) { // handle both jquery and mootools
|
if ( event.shift || event.shiftKey ) { // handle both jquery and mootools
|
||||||
|
@ -1069,8 +1088,26 @@ function getStat() {
|
||||||
table.empty().append('<tbody>');
|
table.empty().append('<tbody>');
|
||||||
$j.each( eventDataStrings, function( key ) {
|
$j.each( eventDataStrings, function( key ) {
|
||||||
var th = $j('<th>').addClass('text-right').text(eventDataStrings[key]);
|
var th = $j('<th>').addClass('text-right').text(eventDataStrings[key]);
|
||||||
var tdString = ( eventData[key].length ) ? eventData[key] : 'n/a';
|
var tdString;
|
||||||
var td = $j('<td>').text(tdString);
|
|
||||||
|
switch (eventData[key].length ? key : 'n/a') {
|
||||||
|
case 'Frames':
|
||||||
|
tdString = '<a href="?view=frames&eid=' + eventData.Id + '">' + eventData[key] + '</a>';
|
||||||
|
break;
|
||||||
|
case 'AlarmFrames':
|
||||||
|
tdString = '<a href="?view=frames&eid=' + eventData.Id + '">' + eventData[key] + '</a>';
|
||||||
|
break;
|
||||||
|
case 'MaxScore':
|
||||||
|
tdString = '<a href="?view=frame&eid=' + eventData.Id + '&fid=0">' + eventData[key] + '</a>';
|
||||||
|
break;
|
||||||
|
case 'n/a':
|
||||||
|
tdString = 'n/a';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tdString = eventData[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
var td = $j('<td>').html(tdString);
|
||||||
var row = $j('<tr>').append(th, td);
|
var row = $j('<tr>').append(th, td);
|
||||||
|
|
||||||
$j('#eventStatsTable tbody').append(row);
|
$j('#eventStatsTable tbody').append(row);
|
||||||
|
@ -1114,15 +1151,14 @@ function initPage() {
|
||||||
progressBarNav();
|
progressBarNav();
|
||||||
streamCmdTimer = streamQuery.delay(250);
|
streamCmdTimer = streamQuery.delay(250);
|
||||||
if ( canStreamNative ) {
|
if ( canStreamNative ) {
|
||||||
var imageFeed = $('imageFeed');
|
if ( !$j('#imageFeed') ) {
|
||||||
if ( !imageFeed ) {
|
|
||||||
console.log('No element with id tag imageFeed found.');
|
console.log('No element with id tag imageFeed found.');
|
||||||
} else {
|
} else {
|
||||||
var streamImg = imageFeed.getElement('img');
|
var streamImg = $j('#imageFeed img');
|
||||||
if ( !streamImg ) {
|
if ( !streamImg ) {
|
||||||
streamImg = imageFeed.getElement('object');
|
streamImg = $j('#imageFeed object');
|
||||||
}
|
}
|
||||||
$(streamImg).addEvent('click', function(event) {
|
$j(streamImg).click(function(event) {
|
||||||
handleClick(event);
|
handleClick(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1253,6 +1289,12 @@ function initPage() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Manage the FRAMES Button
|
||||||
|
document.getElementById("framesBtn").addEventListener("click", function onFramesClick(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
window.location.assign('?view=frames&eid='+eventData.Id);
|
||||||
|
});
|
||||||
|
|
||||||
// Manage the DELETE button
|
// Manage the DELETE button
|
||||||
document.getElementById("deleteBtn").addEventListener("click", function onDeleteClick(evt) {
|
document.getElementById("deleteBtn").addEventListener("click", function onDeleteClick(evt) {
|
||||||
if ( ! canEdit.Events ) {
|
if ( ! canEdit.Events ) {
|
||||||
|
|
|
@ -126,19 +126,24 @@ function previewEvent(slot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadEventImage( imagePath, eid, fid ) {
|
function loadEventImage( imagePath, eid, fid ) {
|
||||||
|
var eventData = $j('#eventData');
|
||||||
var imageSrc = $j('#imageSrc');
|
var imageSrc = $j('#imageSrc');
|
||||||
|
|
||||||
imageSrc.show();
|
imageSrc.show();
|
||||||
imageSrc.attr('src', imagePath);
|
imageSrc.attr('src', imagePath);
|
||||||
imageSrc.attr('data-event-id', eid);
|
imageSrc.attr('data-event-id', eid);
|
||||||
imageSrc.attr('data-frame-id', fid);
|
imageSrc.attr('data-frame-id', fid);
|
||||||
imageSrc.click(window['showEvent'].bind(imageSrc, imageSrc));
|
imageSrc.off('click');
|
||||||
|
imageSrc.click(function() {
|
||||||
|
showEvent(this);
|
||||||
|
});
|
||||||
|
|
||||||
var eventData = $j('#eventData');
|
eventData.attr('data-event-id', eid);
|
||||||
|
eventData.attr('data-frame-id', fid);
|
||||||
eventData.off('click');
|
eventData.off('click');
|
||||||
eventData.click(showEvent.pass());
|
eventData.click(function() {
|
||||||
|
showEvent(this);
|
||||||
divDataOnClick();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function tlZoomBounds(event) {
|
function tlZoomBounds(event) {
|
||||||
|
|
|
@ -974,6 +974,8 @@ echo htmlSelect('newMonitor[OutputCodec]', $videowriter_codecs, $monitor->Output
|
||||||
$videowriter_encoders = array(
|
$videowriter_encoders = array(
|
||||||
'' => translate('Auto'),
|
'' => translate('Auto'),
|
||||||
'h264_omx' => 'h264_omx',
|
'h264_omx' => 'h264_omx',
|
||||||
|
'libx264' => 'libx264',
|
||||||
|
'h264_vaapi' => 'h264_vaapi',
|
||||||
'h264' => 'h264',
|
'h264' => 'h264',
|
||||||
'mjpeg' => 'mjpeg',
|
'mjpeg' => 'mjpeg',
|
||||||
'mpeg1' => 'mpeg1',
|
'mpeg1' => 'mpeg1',
|
||||||
|
|
Loading…
Reference in New Issue