Merge branch 'master' of github.com:ZoneMinder/zoneminder
This commit is contained in:
commit
ee129ba2e3
|
@ -60,6 +60,7 @@ set(ZM_BIN_SRC_FILES
|
||||||
zm_signal.cpp
|
zm_signal.cpp
|
||||||
zm_stream.cpp
|
zm_stream.cpp
|
||||||
zm_swscale.cpp
|
zm_swscale.cpp
|
||||||
|
zm_time.cpp
|
||||||
zm_user.cpp
|
zm_user.cpp
|
||||||
zm_utils.cpp
|
zm_utils.cpp
|
||||||
zm_videostore.cpp
|
zm_videostore.cpp
|
||||||
|
|
|
@ -663,7 +663,7 @@ bool EventStream::checkEventLoaded() {
|
||||||
else
|
else
|
||||||
curr_frame_id = 1;
|
curr_frame_id = 1;
|
||||||
Debug(2, "New frame id = %ld", curr_frame_id);
|
Debug(2, "New frame id = %ld", curr_frame_id);
|
||||||
start = std::chrono::system_clock::now();
|
start = std::chrono::steady_clock::now();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Debug(2, "No next event loaded using %s. Pausing", sql.c_str());
|
Debug(2, "No next event loaded using %s. Pausing", sql.c_str());
|
||||||
|
@ -851,13 +851,13 @@ void EventStream::runStream() {
|
||||||
}
|
}
|
||||||
updateFrameRate(fps);
|
updateFrameRate(fps);
|
||||||
|
|
||||||
start = std::chrono::system_clock::now();
|
start = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
SystemTimePoint::duration last_frame_offset = Seconds(0);
|
SystemTimePoint::duration last_frame_offset = Seconds(0);
|
||||||
SystemTimePoint::duration time_to_event = Seconds(0);
|
SystemTimePoint::duration time_to_event = Seconds(0);
|
||||||
|
|
||||||
while ( !zm_terminate ) {
|
while ( !zm_terminate ) {
|
||||||
now = std::chrono::system_clock::now();
|
now = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
Microseconds delta = Microseconds(0);
|
Microseconds delta = Microseconds(0);
|
||||||
send_frame = false;
|
send_frame = false;
|
||||||
|
@ -904,7 +904,7 @@ void EventStream::runStream() {
|
||||||
|
|
||||||
// time_to_event > 0 means that we are not in the event
|
// time_to_event > 0 means that we are not in the event
|
||||||
if (time_to_event > Seconds(0) and mode == MODE_ALL) {
|
if (time_to_event > Seconds(0) and mode == MODE_ALL) {
|
||||||
SystemTimePoint::duration time_since_last_send = now - last_frame_sent;
|
TimePoint::duration time_since_last_send = now - last_frame_sent;
|
||||||
Debug(1, "Time since last send = %.2f s", FPSeconds(time_since_last_send).count());
|
Debug(1, "Time since last send = %.2f s", FPSeconds(time_since_last_send).count());
|
||||||
if (time_since_last_send > Seconds(1)) {
|
if (time_since_last_send > Seconds(1)) {
|
||||||
char frame_text[64];
|
char frame_text[64];
|
||||||
|
@ -976,7 +976,7 @@ void EventStream::runStream() {
|
||||||
// +/- 1? What if we are skipping frames?
|
// +/- 1? What if we are skipping frames?
|
||||||
curr_frame_id += (replay_rate>0) ? frame_mod : -1*frame_mod;
|
curr_frame_id += (replay_rate>0) ? frame_mod : -1*frame_mod;
|
||||||
// sending the frame may have taken some time, so reload now
|
// sending the frame may have taken some time, so reload now
|
||||||
now = std::chrono::system_clock::now();
|
now = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
// we incremented by replay_rate, so might have jumped past frame_count
|
// we incremented by replay_rate, so might have jumped past frame_count
|
||||||
if ( (mode == MODE_SINGLE) && (
|
if ( (mode == MODE_SINGLE) && (
|
||||||
|
|
|
@ -76,7 +76,7 @@ class EventStream : public StreamBase {
|
||||||
long curr_frame_id;
|
long curr_frame_id;
|
||||||
SystemTimePoint curr_stream_time;
|
SystemTimePoint curr_stream_time;
|
||||||
bool send_frame;
|
bool send_frame;
|
||||||
SystemTimePoint start; // clock time when started the event
|
TimePoint start; // clock time when started the event
|
||||||
|
|
||||||
EventData *event_data;
|
EventData *event_data;
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ void FifoStream::runStream() {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!zm_terminate) {
|
while (!zm_terminate) {
|
||||||
now = std::chrono::system_clock::now();
|
now = std::chrono::steady_clock::now();
|
||||||
checkCommandQueue();
|
checkCommandQueue();
|
||||||
|
|
||||||
if (stream_type == MJPEG) {
|
if (stream_type == MJPEG) {
|
||||||
|
|
|
@ -134,6 +134,18 @@ void MonitorStream::processCommand(const CmdMsg *msg) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CMD_MAXFPS :
|
||||||
|
{
|
||||||
|
double int_part = ((unsigned char) msg->msg_data[1] << 24) | ((unsigned char) msg->msg_data[2] << 16)
|
||||||
|
| ((unsigned char) msg->msg_data[3] << 8) | (unsigned char) msg->msg_data[4];
|
||||||
|
double dec_part = ((unsigned char) msg->msg_data[5] << 24) | ((unsigned char) msg->msg_data[6] << 16)
|
||||||
|
| ((unsigned char) msg->msg_data[7] << 8) | (unsigned char) msg->msg_data[8];
|
||||||
|
|
||||||
|
maxfps = (int_part + dec_part / 1000000.0);
|
||||||
|
|
||||||
|
Debug(1, "Got MAXFPS %f", maxfps);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CMD_SLOWFWD :
|
case CMD_SLOWFWD :
|
||||||
Debug(1, "Got SLOW FWD command");
|
Debug(1, "Got SLOW FWD command");
|
||||||
paused = true;
|
paused = true;
|
||||||
|
@ -268,7 +280,7 @@ void MonitorStream::processCommand(const CmdMsg *msg) {
|
||||||
} else {
|
} else {
|
||||||
FPSeconds elapsed = now - last_fps_update;
|
FPSeconds elapsed = now - last_fps_update;
|
||||||
if (elapsed.count()) {
|
if (elapsed.count()) {
|
||||||
actual_fps = (frame_count - last_frame_count) / elapsed.count();
|
actual_fps = (actual_fps + (frame_count - last_frame_count) / elapsed.count())/2;
|
||||||
last_frame_count = frame_count;
|
last_frame_count = frame_count;
|
||||||
last_fps_update = now;
|
last_fps_update = now;
|
||||||
}
|
}
|
||||||
|
@ -288,7 +300,7 @@ void MonitorStream::processCommand(const CmdMsg *msg) {
|
||||||
status_data.delayed = delayed;
|
status_data.delayed = delayed;
|
||||||
status_data.paused = paused;
|
status_data.paused = paused;
|
||||||
status_data.rate = replay_rate;
|
status_data.rate = replay_rate;
|
||||||
status_data.delay = FPSeconds(now - last_frame_timestamp).count();
|
status_data.delay = FPSeconds(now - last_frame_sent).count();
|
||||||
status_data.zoom = zoom;
|
status_data.zoom = zoom;
|
||||||
Debug(2, "viewing fps: %.2f capture_fps: %.2f analysis_fps: %.2f Buffer Level:%d, Delayed:%d, Paused:%d, Rate:%d, delay:%.3f, Zoom:%d, Enabled:%d Forced:%d",
|
Debug(2, "viewing fps: %.2f capture_fps: %.2f analysis_fps: %.2f Buffer Level:%d, Delayed:%d, Paused:%d, Rate:%d, delay:%.3f, Zoom:%d, Enabled:%d Forced:%d",
|
||||||
status_data.fps,
|
status_data.fps,
|
||||||
|
@ -382,6 +394,9 @@ bool MonitorStream::sendFrame(Image *image, SystemTimePoint timestamp) {
|
||||||
Image *send_image = prepareImage(image);
|
Image *send_image = prepareImage(image);
|
||||||
|
|
||||||
fputs("--" BOUNDARY "\r\n", stdout);
|
fputs("--" BOUNDARY "\r\n", stdout);
|
||||||
|
// Calculate how long it takes to actually send the frame
|
||||||
|
TimePoint send_start_time = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
if ( type == STREAM_MPEG ) {
|
if ( type == STREAM_MPEG ) {
|
||||||
if ( !vid_stream ) {
|
if ( !vid_stream ) {
|
||||||
vid_stream = new VideoStream("pipe:", format, bitrate, effective_fps, send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height());
|
vid_stream = new VideoStream("pipe:", format, bitrate, effective_fps, send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height());
|
||||||
|
@ -402,8 +417,6 @@ bool MonitorStream::sendFrame(Image *image, SystemTimePoint timestamp) {
|
||||||
int img_buffer_size = 0;
|
int img_buffer_size = 0;
|
||||||
unsigned char *img_buffer = temp_img_buffer;
|
unsigned char *img_buffer = temp_img_buffer;
|
||||||
|
|
||||||
// Calculate how long it takes to actually send the frame
|
|
||||||
TimePoint send_start_time = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
switch ( type ) {
|
switch ( type ) {
|
||||||
case STREAM_JPEG :
|
case STREAM_JPEG :
|
||||||
|
@ -445,21 +458,22 @@ bool MonitorStream::sendFrame(Image *image, SystemTimePoint timestamp) {
|
||||||
fputs("\r\n", stdout);
|
fputs("\r\n", stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
TimePoint send_end_time = std::chrono::steady_clock::now();
|
|
||||||
TimePoint::duration frame_send_time = send_end_time - send_start_time;
|
|
||||||
TimePoint::duration maxfps_milliseconds = Milliseconds(lround(Milliseconds::period::den / maxfps));
|
|
||||||
|
|
||||||
if (frame_send_time > maxfps_milliseconds) {
|
|
||||||
//maxfps /= 1.5;
|
|
||||||
Warning("Frame send time %" PRIi64 " msec too slow (> %" PRIi64 ", throttling maxfps to %.3f",
|
|
||||||
static_cast<int64>(std::chrono::duration_cast<Milliseconds>(frame_send_time).count()),
|
|
||||||
static_cast<int64>(std::chrono::duration_cast<Milliseconds>(maxfps_milliseconds).count()),
|
|
||||||
maxfps);
|
|
||||||
}
|
|
||||||
} // Not mpeg
|
} // Not mpeg
|
||||||
last_frame_sent = now;
|
|
||||||
|
TimePoint send_end_time = std::chrono::steady_clock::now();
|
||||||
|
TimePoint::duration frame_send_time = send_end_time - send_start_time;
|
||||||
|
TimePoint::duration maxfps_milliseconds = Milliseconds(lround(Milliseconds::period::den / maxfps));
|
||||||
|
|
||||||
|
if (frame_send_time > maxfps_milliseconds) {
|
||||||
|
//maxfps /= 1.5;
|
||||||
|
Warning("Frame send time %" PRIi64 " msec too slow (> %" PRIi64 ", throttling maxfps to %.3f",
|
||||||
|
static_cast<int64>(std::chrono::duration_cast<Milliseconds>(frame_send_time).count()),
|
||||||
|
static_cast<int64>(std::chrono::duration_cast<Milliseconds>(maxfps_milliseconds).count()),
|
||||||
|
maxfps);
|
||||||
|
}
|
||||||
|
last_frame_sent = send_end_time;
|
||||||
return true;
|
return true;
|
||||||
}
|
} // end bool MonitorStream::sendFrame(Image *image, SystemTimePoint timestamp)
|
||||||
|
|
||||||
void MonitorStream::runStream() {
|
void MonitorStream::runStream() {
|
||||||
if (type == STREAM_SINGLE) {
|
if (type == STREAM_SINGLE) {
|
||||||
|
@ -502,7 +516,8 @@ void MonitorStream::runStream() {
|
||||||
// point to end which is theoretically not a valid value because all indexes are % image_buffer_count
|
// point to end which is theoretically not a valid value because all indexes are % image_buffer_count
|
||||||
int32_t last_read_index = monitor->image_buffer_count;
|
int32_t last_read_index = monitor->image_buffer_count;
|
||||||
|
|
||||||
SystemTimePoint stream_start_time = std::chrono::system_clock::now();
|
TimePoint stream_start_time = std::chrono::steady_clock::now();
|
||||||
|
when_to_send_next_frame = stream_start_time; // initialize it to now so that we spit out a frame immediately
|
||||||
|
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
|
|
||||||
|
@ -571,7 +586,7 @@ void MonitorStream::runStream() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
now = std::chrono::system_clock::now();
|
now = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
bool was_paused = paused;
|
bool was_paused = paused;
|
||||||
bool got_command = false; // commands like zoom should output a frame even if paused
|
bool got_command = false; // commands like zoom should output a frame even if paused
|
||||||
|
@ -618,7 +633,7 @@ void MonitorStream::runStream() {
|
||||||
temp_read_index = MOD_ADD(temp_read_index, (replay_rate>=0?-1:1), temp_image_buffer_count);
|
temp_read_index = MOD_ADD(temp_read_index, (replay_rate>=0?-1:1), temp_image_buffer_count);
|
||||||
} else {
|
} else {
|
||||||
FPSeconds expected_delta_time = ((FPSeconds(swap_image->timestamp - last_frame_timestamp)) * ZM_RATE_BASE) / replay_rate;
|
FPSeconds expected_delta_time = ((FPSeconds(swap_image->timestamp - last_frame_timestamp)) * ZM_RATE_BASE) / replay_rate;
|
||||||
SystemTimePoint::duration actual_delta_time = now - last_frame_sent;
|
TimePoint::duration actual_delta_time = now - last_frame_sent;
|
||||||
|
|
||||||
// If the next frame is due
|
// If the next frame is due
|
||||||
if (actual_delta_time > expected_delta_time) {
|
if (actual_delta_time > expected_delta_time) {
|
||||||
|
@ -684,7 +699,8 @@ void MonitorStream::runStream() {
|
||||||
if (last_read_index != monitor->shared_data->last_write_index) {
|
if (last_read_index != monitor->shared_data->last_write_index) {
|
||||||
// have a new image to send
|
// have a new image to send
|
||||||
int index = monitor->shared_data->last_write_index % monitor->image_buffer_count;
|
int index = monitor->shared_data->last_write_index % monitor->image_buffer_count;
|
||||||
if ((frame_mod == 1) || ((frame_count%frame_mod) == 0)) {
|
//if ((frame_mod == 1) || ((frame_count%frame_mod) == 0)) {
|
||||||
|
if ( now >= when_to_send_next_frame ) {
|
||||||
if (!paused && !delayed) {
|
if (!paused && !delayed) {
|
||||||
last_read_index = monitor->shared_data->last_write_index;
|
last_read_index = monitor->shared_data->last_write_index;
|
||||||
Debug(2, "Sending frame index: %d: frame_mod: %d frame count: %d paused(%d) delayed(%d)",
|
Debug(2, "Sending frame index: %d: frame_mod: %d frame count: %d paused(%d) delayed(%d)",
|
||||||
|
@ -743,9 +759,9 @@ void MonitorStream::runStream() {
|
||||||
} // end if actual_delta_time > 5
|
} // end if actual_delta_time > 5
|
||||||
} // end if change in zoom
|
} // end if change in zoom
|
||||||
} // end if paused or not
|
} // end if paused or not
|
||||||
} else {
|
//} else {
|
||||||
frame_count++;
|
//frame_count++;
|
||||||
} // end if should send frame
|
} // end if should send frame now > when_to_send_next_frame
|
||||||
|
|
||||||
if (buffered_playback && !paused) {
|
if (buffered_playback && !paused) {
|
||||||
if (monitor->shared_data->valid) {
|
if (monitor->shared_data->valid) {
|
||||||
|
@ -776,15 +792,35 @@ void MonitorStream::runStream() {
|
||||||
}
|
}
|
||||||
} // end if buffered playback
|
} // end if buffered playback
|
||||||
} else {
|
} else {
|
||||||
Debug(3, "Waiting for capture last_write_index=%u", monitor->shared_data->last_write_index);
|
Debug(3, "Waiting for capture last_write_index=%u == last_read_index=%u",
|
||||||
|
monitor->shared_data->last_write_index,
|
||||||
|
last_read_index);
|
||||||
} // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index )
|
} // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index )
|
||||||
|
|
||||||
FPSeconds sleep_time =
|
FPSeconds sleep_time;
|
||||||
FPSeconds(1 / ((base_fps ? base_fps : 1) * (replay_rate ? abs(replay_rate) : 1)));
|
if (now >= when_to_send_next_frame) {
|
||||||
if (last_frame_sent.time_since_epoch() != Seconds(0)) {
|
// sent a frame, so update
|
||||||
sleep_time -= (now - last_frame_sent);
|
|
||||||
if (sleep_time < Seconds(0))
|
double capture_fps = monitor->GetFPS();
|
||||||
sleep_time = Seconds(0);
|
double fps = (maxfps && (capture_fps > maxfps)) ? maxfps : capture_fps;
|
||||||
|
double sleep_time_seconds = (1 / ((fps ? fps : 1))) // 1 second / fps
|
||||||
|
* (replay_rate ? abs(replay_rate)/ZM_RATE_BASE : 1); // replay_rate is 100 for 1x
|
||||||
|
Debug(3, "Using %f for maxfps. capture_fps: %f maxfps %f * replay_rate: %d = %f", fps, capture_fps, maxfps, replay_rate, sleep_time_seconds);
|
||||||
|
|
||||||
|
sleep_time = FPSeconds(sleep_time_seconds);
|
||||||
|
if (when_to_send_next_frame > now)
|
||||||
|
sleep_time -= when_to_send_next_frame - now;
|
||||||
|
|
||||||
|
when_to_send_next_frame = now + std::chrono::duration_cast<Microseconds>(sleep_time);
|
||||||
|
|
||||||
|
if (last_frame_sent > now) {
|
||||||
|
FPSeconds elapsed = last_frame_sent - now;
|
||||||
|
if (sleep_time > elapsed) {
|
||||||
|
sleep_time -= elapsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sleep_time = when_to_send_next_frame - now;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sleep_time > MonitorStream::MAX_SLEEP) {
|
if (sleep_time > MonitorStream::MAX_SLEEP) {
|
||||||
|
|
|
@ -386,7 +386,7 @@ void StreamBase::openComms() {
|
||||||
strncpy(rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path));
|
strncpy(rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path));
|
||||||
rem_addr.sun_family = AF_UNIX;
|
rem_addr.sun_family = AF_UNIX;
|
||||||
|
|
||||||
last_comm_update = std::chrono::system_clock::now();
|
last_comm_update = std::chrono::steady_clock::now();
|
||||||
Debug(3, "comms open at %s", loc_sock_path);
|
Debug(3, "comms open at %s", loc_sock_path);
|
||||||
} // end if connKey > 0
|
} // end if connKey > 0
|
||||||
} // end void StreamBase::openComms()
|
} // end void StreamBase::openComms()
|
||||||
|
|
|
@ -88,6 +88,7 @@ protected:
|
||||||
CMD_VARPLAY,
|
CMD_VARPLAY,
|
||||||
CMD_GET_IMAGE,
|
CMD_GET_IMAGE,
|
||||||
CMD_QUIT,
|
CMD_QUIT,
|
||||||
|
CMD_MAXFPS,
|
||||||
CMD_QUERY=99
|
CMD_QUERY=99
|
||||||
} MsgCommand;
|
} MsgCommand;
|
||||||
|
|
||||||
|
@ -118,21 +119,22 @@ protected:
|
||||||
bool paused;
|
bool paused;
|
||||||
int step;
|
int step;
|
||||||
|
|
||||||
SystemTimePoint now;
|
TimePoint now;
|
||||||
SystemTimePoint last_comm_update;
|
TimePoint last_comm_update;
|
||||||
|
|
||||||
double maxfps;
|
double maxfps;
|
||||||
double base_fps; // Should be capturing fps, hence a rough target
|
double base_fps; // Should be capturing fps, hence a rough target
|
||||||
double effective_fps; // Target fps after taking max_fps into account
|
double effective_fps; // Target fps after taking max_fps into account
|
||||||
double actual_fps; // sliding calculated actual streaming fps achieved
|
double actual_fps; // sliding calculated actual streaming fps achieved
|
||||||
SystemTimePoint last_fps_update;
|
TimePoint last_fps_update;
|
||||||
int frame_count; // Count of frames sent
|
int frame_count; // Count of frames sent
|
||||||
int last_frame_count; // Used in calculating actual_fps from frame_count - last_frame_count
|
int last_frame_count; // Used in calculating actual_fps from frame_count - last_frame_count
|
||||||
|
|
||||||
int frame_mod;
|
int frame_mod;
|
||||||
|
|
||||||
SystemTimePoint last_frame_sent;
|
TimePoint last_frame_sent;
|
||||||
SystemTimePoint last_frame_timestamp;
|
SystemTimePoint last_frame_timestamp;
|
||||||
|
TimePoint when_to_send_next_frame; // When to send next frame so if now < send_next_frame, skip
|
||||||
|
|
||||||
VideoStream *vid_stream;
|
VideoStream *vid_stream;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
//
|
||||||
|
// ZoneMinder Time Functions & Definitions, $Date$, $Revision$
|
||||||
|
// Copyright (C) 2001-2008 Philip Coombes
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "zm_time.h"
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
|
std::string SystemTimePointToString(SystemTimePoint tp) {
|
||||||
|
time_t tp_sec = std::chrono::system_clock::to_time_t(tp);
|
||||||
|
Microseconds now_frac = std::chrono::duration_cast<Microseconds>(
|
||||||
|
tp.time_since_epoch() - std::chrono::duration_cast<Seconds>(tp.time_since_epoch()));
|
||||||
|
|
||||||
|
std::string timeString;
|
||||||
|
timeString.reserve(64);
|
||||||
|
char *timePtr = timeString.data();
|
||||||
|
tm tp_tm = {};
|
||||||
|
timePtr += strftime(timePtr, timeString.capacity(), "%x %H:%M:%S", localtime_r(&tp_sec, &tp_tm));
|
||||||
|
snprintf(timePtr, timeString.capacity() - (timePtr - timeString.data()), ".%06" PRIi64, static_cast<int64_t>(now_frac.count()));
|
||||||
|
return timeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TimePointToString(TimePoint tp) {
|
||||||
|
time_t tp_sec = std::chrono::system_clock::to_time_t(
|
||||||
|
std::chrono::system_clock::now() + (tp - std::chrono::steady_clock::now()));
|
||||||
|
|
||||||
|
Microseconds now_frac = std::chrono::duration_cast<Microseconds>(
|
||||||
|
tp.time_since_epoch() - std::chrono::duration_cast<Seconds>(tp.time_since_epoch()));
|
||||||
|
|
||||||
|
std::string timeString;
|
||||||
|
timeString.reserve(64);
|
||||||
|
char *timePtr = timeString.data();
|
||||||
|
tm tp_tm = {};
|
||||||
|
timePtr += strftime(timePtr, timeString.capacity(), "%x %H:%M:%S", localtime_r(&tp_sec, &tp_tm));
|
||||||
|
snprintf(timePtr, timeString.capacity() - (timePtr - timeString.data()), ".%06" PRIi64, static_cast<int64_t>(now_frac.count()));
|
||||||
|
return timeString;
|
||||||
|
}
|
|
@ -21,6 +21,7 @@
|
||||||
#define ZM_TIME_H
|
#define ZM_TIME_H
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
typedef std::chrono::microseconds Microseconds;
|
typedef std::chrono::microseconds Microseconds;
|
||||||
|
@ -120,4 +121,7 @@ class TimeSegmentAdder {
|
||||||
bool finished_;
|
bool finished_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string SystemTimePointToString(SystemTimePoint tp);
|
||||||
|
std::string TimePointToString(TimePoint tp);
|
||||||
|
|
||||||
#endif // ZM_TIME_H
|
#endif // ZM_TIME_H
|
||||||
|
|
|
@ -52,6 +52,13 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
||||||
intval($_REQUEST['offset']),
|
intval($_REQUEST['offset']),
|
||||||
1000000*( $_REQUEST['offset']-intval($_REQUEST['offset'])));
|
1000000*( $_REQUEST['offset']-intval($_REQUEST['offset'])));
|
||||||
break;
|
break;
|
||||||
|
case CMD_MAXFPS :
|
||||||
|
ZM\Debug('Maxfps to '.$_REQUEST['maxfps']);
|
||||||
|
# Pack int two 32 bit integers instead of trying to deal with floats
|
||||||
|
$msg = pack('lcNN', MSG_CMD, $_REQUEST['command'],
|
||||||
|
intval($_REQUEST['maxfps']),
|
||||||
|
1000000*( $_REQUEST['maxfps']-intval($_REQUEST['maxfps'])));
|
||||||
|
break;
|
||||||
default :
|
default :
|
||||||
ZM\Debug('Sending command ' . $_REQUEST['command']);
|
ZM\Debug('Sending command ' . $_REQUEST['command']);
|
||||||
$msg = pack('lc', MSG_CMD, $_REQUEST['command']);
|
$msg = pack('lc', MSG_CMD, $_REQUEST['command']);
|
||||||
|
|
|
@ -119,6 +119,7 @@ define('CMD_NEXT', 13);
|
||||||
define('CMD_SEEK', 14 );
|
define('CMD_SEEK', 14 );
|
||||||
define('CMD_VARPLAY', 15);
|
define('CMD_VARPLAY', 15);
|
||||||
define('CMD_QUIT', 17);
|
define('CMD_QUIT', 17);
|
||||||
|
define('CMD_MAXFPS', 18);
|
||||||
define('CMD_QUERY', 99);
|
define('CMD_QUERY', 99);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -2070,7 +2070,9 @@ function getStreamHTML($monitor, $options = array()) {
|
||||||
if ( ! isset($options['height'] ) )
|
if ( ! isset($options['height'] ) )
|
||||||
$options['height'] = 0;
|
$options['height'] = 0;
|
||||||
|
|
||||||
$options['maxfps'] = ZM_WEB_VIDEO_MAXFPS;
|
if (!isset($options['maxfps'])) {
|
||||||
|
$options['maxfps'] = ZM_WEB_VIDEO_MAXFPS;
|
||||||
|
}
|
||||||
if ( $monitor->StreamReplayBuffer() )
|
if ( $monitor->StreamReplayBuffer() )
|
||||||
$options['buffer'] = $monitor->StreamReplayBuffer();
|
$options['buffer'] = $monitor->StreamReplayBuffer();
|
||||||
//Warning("width: " . $options['width'] . ' height: ' . $options['height']. ' scale: ' . $options['scale'] );
|
//Warning("width: " . $options['width'] . ' height: ' . $options['height']. ' scale: ' . $options['scale'] );
|
||||||
|
|
|
@ -130,6 +130,7 @@ function changeSize() {
|
||||||
|
|
||||||
function changeScale() {
|
function changeScale() {
|
||||||
var scale = $j('#scale').val();
|
var scale = $j('#scale').val();
|
||||||
|
setCookie('zmWatchScale'+monitorId, scale, 3600);
|
||||||
$j('#width').val('auto');
|
$j('#width').val('auto');
|
||||||
$j('#height').val('auto');
|
$j('#height').val('auto');
|
||||||
setCookie('zmCycleScale', scale, 3600);
|
setCookie('zmCycleScale', scale, 3600);
|
||||||
|
@ -140,11 +141,16 @@ function changeScale() {
|
||||||
var newHeight;
|
var newHeight;
|
||||||
var autoScale;
|
var autoScale;
|
||||||
|
|
||||||
|
var streamImg = $j('#liveStream'+monitorId);
|
||||||
|
if (!streamImg.length) {
|
||||||
|
console.error('No element found for liveStream'+monitorId);
|
||||||
|
}
|
||||||
|
|
||||||
// Always turn it off, we will re-add it below. I don't know if you can add a callback multiple
|
// Always turn it off, we will re-add it below. I don't know if you can add a callback multiple
|
||||||
// times and what the consequences would be
|
// times and what the consequences would be
|
||||||
$j(window).off('resize', endOfResize); //remove resize handler when Scale to Fit is not active
|
$j(window).off('resize', endOfResize); //remove resize handler when Scale to Fit is not active
|
||||||
if (scale == '0' || scale == 'auto') {
|
if (scale == '0' || scale == 'auto') {
|
||||||
const newSize = scaleToFit(monitorWidth, monitorHeight, $j('#liveStream'+monitorId), $j('#replayStatus'));
|
const newSize = scaleToFit(monitorWidth, monitorHeight, streamImg, $j('#dvrControls'));
|
||||||
newWidth = newSize.width;
|
newWidth = newSize.width;
|
||||||
newHeight = newSize.height;
|
newHeight = newSize.height;
|
||||||
autoScale = newSize.autoScale;
|
autoScale = newSize.autoScale;
|
||||||
|
@ -154,24 +160,21 @@ function changeScale() {
|
||||||
newHeight = monitorHeight * scale / SCALE_BASE;
|
newHeight = monitorHeight * scale / SCALE_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCookie('zmWatchScale'+monitorId, scale, 3600);
|
if (streamImg.prop('nodeName') == 'IMG') {
|
||||||
|
const oldSrc = streamImg.attr('src');
|
||||||
|
streamImg.attr('src', '');
|
||||||
|
// This is so that we don't waste bandwidth and let the browser do all the scaling.
|
||||||
|
if (autoScale > 100) autoScale = 100;
|
||||||
|
if (scale > 100) scale = 100;
|
||||||
|
const newSrc = oldSrc.replace(/scale=\d+/i, 'scale='+((scale == 'auto' || scale == '0') ? autoScale : scale));
|
||||||
|
|
||||||
var streamImg = $j('#liveStream'+monitorId);
|
streamImg.css('width', newWidth+'px');
|
||||||
if (streamImg) {
|
streamImg.width(newWidth);
|
||||||
if (streamImg.nodeName == 'IMG') {
|
streamImg.css('height', newHeight+'px');
|
||||||
const oldSrc = streamImg.attr('src');
|
streamImg.height(newHeight);
|
||||||
streamImg.attr('src', '');
|
streamImg.attr('src', newSrc);
|
||||||
// This is so that we don't waste bandwidth and let the browser do all the scaling.
|
|
||||||
if (autoScale > 100) autoScale = 100;
|
|
||||||
if (scale > 100) scale = 100;
|
|
||||||
const newSrc = oldSrc.replace(/scale=\d+/i, 'scale='+((scale == 'auto' || scale == '0') ? autoScale : scale));
|
|
||||||
|
|
||||||
streamImg.width(newWidth);
|
|
||||||
streamImg.height(newHeight);
|
|
||||||
streamImg.attr('src', newSrc);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
console.error('No element found for liveStream'+monitorId);
|
console.log("Not an IMG, can't set size");
|
||||||
}
|
}
|
||||||
} // end function changeScale
|
} // end function changeScale
|
||||||
|
|
||||||
|
@ -226,6 +229,15 @@ function setAlarmState(currentAlarmState) {
|
||||||
lastAlarmState = alarmState;
|
lastAlarmState = alarmState;
|
||||||
} // end function setAlarmState( currentAlarmState )
|
} // end function setAlarmState( currentAlarmState )
|
||||||
|
|
||||||
|
function streamCmdReq(data) {
|
||||||
|
if (auth_hash) data.auth = auth_hash;
|
||||||
|
$j.getJSON(monitorUrl + '?view=request&request=stream&connkey='+connKey, data)
|
||||||
|
.done(getStreamCmdResponse)
|
||||||
|
.fail(getStreamCmdError);
|
||||||
|
|
||||||
|
streamCmdTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
function getStreamCmdError(text, error) {
|
function getStreamCmdError(text, error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
// Error are normally due to failed auth. reload the page.
|
// Error are normally due to failed auth. reload the page.
|
||||||
|
@ -347,7 +359,9 @@ function getStreamCmdResponse(respObj, respText) {
|
||||||
} // end if have a new auth hash
|
} // end if have a new auth hash
|
||||||
} // end if respObj.status
|
} // end if respObj.status
|
||||||
} else {
|
} else {
|
||||||
|
console.log("Not ok");
|
||||||
checkStreamForErrors('getStreamCmdResponse', respObj);//log them
|
checkStreamForErrors('getStreamCmdResponse', respObj);//log them
|
||||||
|
fetchImage($j('#imageFeed img'));
|
||||||
}
|
}
|
||||||
|
|
||||||
var streamCmdTimeout = statusRefreshTimeout;
|
var streamCmdTimeout = statusRefreshTimeout;
|
||||||
|
@ -357,6 +371,10 @@ function getStreamCmdResponse(respObj, respText) {
|
||||||
streamCmdTimer = setTimeout(streamCmdQuery, streamCmdTimeout);
|
streamCmdTimer = setTimeout(streamCmdQuery, streamCmdTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function streamCmdQuery() {
|
||||||
|
streamCmdReq({command: CMD_QUERY});
|
||||||
|
}
|
||||||
|
|
||||||
function streamCmdPause(action) {
|
function streamCmdPause(action) {
|
||||||
setButtonState('pauseBtn', 'active');
|
setButtonState('pauseBtn', 'active');
|
||||||
setButtonState('playBtn', 'inactive');
|
setButtonState('playBtn', 'inactive');
|
||||||
|
@ -396,21 +414,10 @@ function streamCmdPlay(action) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (action) {
|
if (action) {
|
||||||
var data = {};
|
streamCmdReq({command: CMD_PLAY});
|
||||||
if (auth_hash) data.auth = auth_hash;
|
|
||||||
data.command = CMD_PLAY;
|
|
||||||
streamCmdReq(data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamCmdReq(data) {
|
|
||||||
if (auth_hash) data.auth = auth_hash;
|
|
||||||
$j.getJSON(monitorUrl + '?view=request&request=stream&connkey='+connKey, data)
|
|
||||||
.done(getStreamCmdResponse)
|
|
||||||
.fail(getStreamCmdError);
|
|
||||||
|
|
||||||
streamCmdTimer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function streamCmdStop(action) {
|
function streamCmdStop(action) {
|
||||||
setButtonState('pauseBtn', 'inactive');
|
setButtonState('pauseBtn', 'inactive');
|
||||||
|
@ -440,9 +447,7 @@ function streamCmdFastFwd(action) {
|
||||||
setButtonState('fastRevBtn', 'inactive');
|
setButtonState('fastRevBtn', 'inactive');
|
||||||
}
|
}
|
||||||
if (action) {
|
if (action) {
|
||||||
var data = {};
|
streamCmdReq({command: CMD_FASTFWD});
|
||||||
data.command = CMD_FASTFWD;
|
|
||||||
streamCmdReq(data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,9 +462,7 @@ function streamCmdSlowFwd(action) {
|
||||||
setButtonState('fastRevBtn', 'inactive');
|
setButtonState('fastRevBtn', 'inactive');
|
||||||
}
|
}
|
||||||
if (action) {
|
if (action) {
|
||||||
var data = {};
|
streamCmdReq({command: CMD_SLOWFWD});
|
||||||
data.command = CMD_SLOWFWD;
|
|
||||||
streamCmdReq(data);
|
|
||||||
}
|
}
|
||||||
setButtonState('pauseBtn', 'active');
|
setButtonState('pauseBtn', 'active');
|
||||||
if (monitorStreamReplayBuffer) {
|
if (monitorStreamReplayBuffer) {
|
||||||
|
@ -478,9 +481,7 @@ function streamCmdSlowRev(action) {
|
||||||
setButtonState('fastRevBtn', 'inactive');
|
setButtonState('fastRevBtn', 'inactive');
|
||||||
}
|
}
|
||||||
if (action) {
|
if (action) {
|
||||||
var data = {};
|
streamCmdReq({command: CMD_SLOWREV});
|
||||||
data.command = CMD_SLOWREV;
|
|
||||||
streamCmdReq(data);
|
|
||||||
}
|
}
|
||||||
setButtonState('pauseBtn', 'active');
|
setButtonState('pauseBtn', 'active');
|
||||||
if (monitorStreamReplayBuffer) {
|
if (monitorStreamReplayBuffer) {
|
||||||
|
@ -499,9 +500,7 @@ function streamCmdFastRev(action) {
|
||||||
setButtonState('fastRevBtn', 'inactive');
|
setButtonState('fastRevBtn', 'inactive');
|
||||||
}
|
}
|
||||||
if (action) {
|
if (action) {
|
||||||
var data = {};
|
streamCmdReq({command: CMD_FASTREV});
|
||||||
data.command = CMD_FASTREV;
|
|
||||||
streamCmdReq(data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,9 +513,7 @@ function streamCmdZoomIn(x, y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamCmdZoomOut() {
|
function streamCmdZoomOut() {
|
||||||
var data = {};
|
streamCmdReq({command: CMD_ZOOMOUT});
|
||||||
data.command = CMD_ZOOMOUT;
|
|
||||||
streamCmdReq(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamCmdScale(scale) {
|
function streamCmdScale(scale) {
|
||||||
|
@ -534,11 +531,6 @@ function streamCmdPan(x, y) {
|
||||||
streamCmdReq(data);
|
streamCmdReq(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function streamCmdQuery() {
|
|
||||||
var data = {};
|
|
||||||
data.command = CMD_QUERY;
|
|
||||||
streamCmdReq(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* getStatusCmd is used when not streaming, since there is no persistent zms */
|
/* getStatusCmd is used when not streaming, since there is no persistent zms */
|
||||||
function getStatusCmdResponse(respObj, respText) {
|
function getStatusCmdResponse(respObj, respText) {
|
||||||
|
@ -713,7 +705,9 @@ function controlCmdImage(x, y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchImage(streamImage) {
|
function fetchImage(streamImage) {
|
||||||
streamImage.attr('src', streamImage.attr('src').replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) )));
|
const oldsrc = streamImage.attr('src');
|
||||||
|
streamImage.attr('src', '');
|
||||||
|
streamImage.attr('src', oldsrc.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) )));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClick(event) {
|
function handleClick(event) {
|
||||||
|
@ -904,10 +898,10 @@ function initPage() {
|
||||||
|
|
||||||
if (monitorType != 'WebSite') {
|
if (monitorType != 'WebSite') {
|
||||||
if (streamMode == 'single') {
|
if (streamMode == 'single') {
|
||||||
statusCmdTimer = setTimeout(statusCmdQuery, 100);
|
statusCmdTimer = setTimeout(statusCmdQuery, 200);
|
||||||
setInterval(watchdogCheck, statusRefreshTimeout*2, 'status');
|
setInterval(watchdogCheck, statusRefreshTimeout*2, 'status');
|
||||||
} else {
|
} else {
|
||||||
streamCmdTimer = setTimeout(streamCmdQuery, 100);
|
streamCmdTimer = setTimeout(streamCmdQuery, 200);
|
||||||
setInterval(watchdogCheck, statusRefreshTimeout*2, 'stream');
|
setInterval(watchdogCheck, statusRefreshTimeout*2, 'stream');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -927,6 +921,7 @@ function initPage() {
|
||||||
streamImg.on("error", function(thing) {
|
streamImg.on("error", function(thing) {
|
||||||
console.log("Error loading image");
|
console.log("Error loading image");
|
||||||
console.log(thing);
|
console.log(thing);
|
||||||
|
setInterval(fetchImage, 100, $j('#imageFeed img'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} // end if have streamImg
|
} // end if have streamImg
|
||||||
|
@ -942,6 +937,9 @@ function initPage() {
|
||||||
el.onchange = window['changeScale'];
|
el.onchange = window['changeScale'];
|
||||||
});
|
});
|
||||||
changeScale();
|
changeScale();
|
||||||
|
document.querySelectorAll('select[name="changeRate"]').forEach(function(el) {
|
||||||
|
el.onchange = window['changeRate'].bind(el, el);
|
||||||
|
});
|
||||||
} else if (monitorRefresh > 0) {
|
} else if (monitorRefresh > 0) {
|
||||||
setInterval(reloadWebSite, monitorRefresh*1000);
|
setInterval(reloadWebSite, monitorRefresh*1000);
|
||||||
}
|
}
|
||||||
|
@ -1084,5 +1082,27 @@ function cycleToggle(e) {
|
||||||
button.toggleClass('btn-primary');
|
button.toggleClass('btn-primary');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeRate(e) {
|
||||||
|
const newvalue = $j(e).val();
|
||||||
|
if (1) {
|
||||||
|
var data = {};
|
||||||
|
data.command = CMD_MAXFPS;
|
||||||
|
data.maxfps = newvalue;
|
||||||
|
streamCmdReq(data);
|
||||||
|
} else {
|
||||||
|
streamImage = $j('#liveStream'+monitorData[monIdx].id);
|
||||||
|
const oldsrc = streamImage.attr('src');
|
||||||
|
streamImage.attr('src', ''); // stop streaming
|
||||||
|
console.log(newvalue);
|
||||||
|
if (newvalue == '0') {
|
||||||
|
// Unlimited
|
||||||
|
streamImage.attr('src', oldsrc.replace(/maxfps=\d+/i, 'maxfps=0.00100'));
|
||||||
|
} else {
|
||||||
|
streamImage.attr('src', oldsrc.replace(/maxfps=\d+/i, 'maxfps='+newvalue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCookie('zmWatchRate', newvalue, 3600);
|
||||||
|
}
|
||||||
|
|
||||||
// Kick everything off
|
// Kick everything off
|
||||||
$j(document).ready(initPage);
|
$j(document).ready(initPage);
|
||||||
|
|
|
@ -32,6 +32,7 @@ var CMD_PREV = <?php echo CMD_PREV ?>;
|
||||||
var CMD_NEXT = <?php echo CMD_NEXT ?>;
|
var CMD_NEXT = <?php echo CMD_NEXT ?>;
|
||||||
var CMD_SEEK = <?php echo CMD_SEEK ?>;
|
var CMD_SEEK = <?php echo CMD_SEEK ?>;
|
||||||
var CMD_QUERY = <?php echo CMD_QUERY ?>;
|
var CMD_QUERY = <?php echo CMD_QUERY ?>;
|
||||||
|
var CMD_MAXFPS = <?php echo CMD_MAXFPS ?>;
|
||||||
|
|
||||||
var SOUND_ON_ALARM = <?php echo ZM_WEB_SOUND_ON_ALARM ?>;
|
var SOUND_ON_ALARM = <?php echo ZM_WEB_SOUND_ON_ALARM ?>;
|
||||||
var POPUP_ON_ALARM = <?php echo ZM_WEB_POPUP_ON_ALARM ?>;
|
var POPUP_ON_ALARM = <?php echo ZM_WEB_POPUP_ON_ALARM ?>;
|
||||||
|
|
|
@ -81,23 +81,27 @@ $monitor = new ZM\Monitor($mid);
|
||||||
$nextMid = ($monitor_index == count($monitors)-1) ? $monitors[0]->Id() : $monitors[$monitor_index+1]->Id();
|
$nextMid = ($monitor_index == count($monitors)-1) ? $monitors[0]->Id() : $monitors[$monitor_index+1]->Id();
|
||||||
$cycle = isset($_REQUEST['cycle']) and ($_REQUEST['cycle'] == 'true');
|
$cycle = isset($_REQUEST['cycle']) and ($_REQUEST['cycle'] == 'true');
|
||||||
$showCycle = $cycle;
|
$showCycle = $cycle;
|
||||||
ZM\Error("Show cycle: $showCycle");
|
|
||||||
if (isset($_COOKIE['zmCycleShow'])) {
|
if (isset($_COOKIE['zmCycleShow'])) {
|
||||||
$showCycle = $_COOKIE['zmCycleShow'] == 'true';
|
$showCycle = $_COOKIE['zmCycleShow'] == 'true';
|
||||||
ZM\Error("Show cycle: $showCycle");
|
|
||||||
} else {
|
|
||||||
ZM\Error("Show cycle: not set");
|
|
||||||
}
|
}
|
||||||
#Whether to show the controls button
|
#Whether to show the controls button
|
||||||
$showPtzControls = ( ZM_OPT_CONTROL && $monitor->Controllable() && canView('Control') && $monitor->Type() != 'WebSite' );
|
$showPtzControls = ( ZM_OPT_CONTROL && $monitor->Controllable() && canView('Control') && $monitor->Type() != 'WebSite' );
|
||||||
|
|
||||||
$options = array();
|
$options = array();
|
||||||
if (empty($_REQUEST['mode'])) {
|
if (!empty($_REQUEST['mode']) and ($_REQUEST['mode']=='still' or $_REQUEST['mode']=='stream')) {
|
||||||
$options['mode'] = canStream() ? 'stream' : 'still';
|
|
||||||
} else {
|
|
||||||
$options['mode'] = validHtmlStr($_REQUEST['mode']);
|
$options['mode'] = validHtmlStr($_REQUEST['mode']);
|
||||||
|
} else if (isset($_COOKIE['zmWatchMode'])) {
|
||||||
|
$options['mode'] = $_COOKIE['zmWatchMode'];
|
||||||
|
} else {
|
||||||
|
$options['mode'] = canStream() ? 'stream' : 'still';
|
||||||
|
}
|
||||||
|
if (!empty($_REQUEST['maxfps']) and validFloat($_REQUEST['maxfps']) and ($_REQUEST['maxfps']>0)) {
|
||||||
|
$options['maxfps'] = validHtmlStr($_REQUEST['maxfps']);
|
||||||
|
} else if (isset($_COOKIE['zmWatchRate'])) {
|
||||||
|
$options['maxfps'] = $_COOKIE['zmWatchRate'];
|
||||||
|
} else {
|
||||||
|
$options['maxfps'] = ''; // unlimited
|
||||||
}
|
}
|
||||||
zm_session_start();
|
|
||||||
|
|
||||||
$period = ZM_WEB_REFRESH_CYCLE;
|
$period = ZM_WEB_REFRESH_CYCLE;
|
||||||
if (isset($_REQUEST['period'])) {
|
if (isset($_REQUEST['period'])) {
|
||||||
|
@ -118,22 +122,17 @@ $options['scale'] = $scale;
|
||||||
if (isset($_REQUEST['width'])) {
|
if (isset($_REQUEST['width'])) {
|
||||||
$options['width'] = validInt($_REQUEST['width']);
|
$options['width'] = validInt($_REQUEST['width']);
|
||||||
} else if ( isset($_COOKIE['zmCycleWidth']) and $_COOKIE['zmCycleWidth'] ) {
|
} else if ( isset($_COOKIE['zmCycleWidth']) and $_COOKIE['zmCycleWidth'] ) {
|
||||||
$_SESSION['zmCycleWidth'] = $options['width'] = $_COOKIE['zmCycleWidth'];
|
$options['width'] = $_COOKIE['zmCycleWidth'];
|
||||||
#} elseif ( isset($_SESSION['zmCycleWidth']) and $_SESSION['zmCycleWidth'] ) {
|
|
||||||
#$options['width'] = $_SESSION['zmCycleWidth'];
|
|
||||||
} else {
|
} else {
|
||||||
$options['width'] = '';
|
$options['width'] = '';
|
||||||
}
|
}
|
||||||
if (isset($_REQUEST['height'])) {
|
if (isset($_REQUEST['height'])) {
|
||||||
$options['height'] =validInt($_REQUEST['height']);
|
$options['height'] =validInt($_REQUEST['height']);
|
||||||
} else if (isset($_COOKIE['zmCycleHeight']) and $_COOKIE['zmCycleHeight']) {
|
} else if (isset($_COOKIE['zmCycleHeight']) and $_COOKIE['zmCycleHeight']) {
|
||||||
$_SESSION['zmCycleHeight'] = $options['height'] = $_COOKIE['zmCycleHeight'];
|
$options['height'] = $_COOKIE['zmCycleHeight'];
|
||||||
#else if ( isset($_SESSION['zmCycleHeight']) and $_SESSION['zmCycleHeight'] )
|
|
||||||
#$options['height'] = $_SESSION['zmCycleHeight'];
|
|
||||||
} else {
|
} else {
|
||||||
$options['height'] = '';
|
$options['height'] = '';
|
||||||
}
|
}
|
||||||
session_write_close();
|
|
||||||
|
|
||||||
$connkey = generateConnKey();
|
$connkey = generateConnKey();
|
||||||
$streamMode = getStreamMode();
|
$streamMode = getStreamMode();
|
||||||
|
@ -161,15 +160,24 @@ xhtmlHeaders(__FILE__, $monitor->Name().' - '.translate('Feed'));
|
||||||
</div>
|
</div>
|
||||||
<div id="headerButtons">
|
<div id="headerButtons">
|
||||||
<!--
|
<!--
|
||||||
<?php if ( $options['mode'] == 'stream' ) { ?>
|
<button type="button" id="streamToggle" class="btn <?php echo $options['mode'] == 'stream' ? 'btn-primary':'btn-secondary'?>" title="<?php echo translate('Toggle Streaming/Stills')?>">
|
||||||
<a href="?view=<?php echo $view ?>&mode=still&mid=<?php echo $monitor ? $monitor->Id() : '' ?>"><?php echo translate('Stills') ?></a>
|
<span class="material-icons md-18">switch_video</span>
|
||||||
<?php } else { ?>
|
</button>
|
||||||
<a href="?view=<?php echo $view ?>&mode=stream&mid=<?php echo $monitor ? $monitor->Id() : '' ?>"><?php echo translate('Stream') ?></a>
|
|
||||||
<?php } ?>
|
|
||||||
-->
|
-->
|
||||||
<button type="button" id="cycleToggle" class="btn <?php echo $showCycle ? 'btn-primary':'btn-secondary'?>" title="<?php echo translate('Toggle cycle sidebar')?>">
|
<button type="button" id="cycleToggle" class="btn <?php echo $showCycle ? 'btn-primary':'btn-secondary'?>" title="<?php echo translate('Toggle cycle sidebar')?>">
|
||||||
<span class="material-icons md-18">view_carousel</span>
|
<span class="material-icons md-18">view_carousel</span>
|
||||||
</button>
|
</button>
|
||||||
|
<?php
|
||||||
|
$maxfps_options = array(''=>translate('Unlimited'),
|
||||||
|
'0' => translate('Stills'),
|
||||||
|
'1' => '1 '.translate('FPS'),
|
||||||
|
'2' => '2 '.translate('FPS'),
|
||||||
|
'5' => '5 '.translate('FPS'),
|
||||||
|
'10' => '10 '.translate('FPS'),
|
||||||
|
'20' => '20 '.translate('FPS'),
|
||||||
|
);
|
||||||
|
echo htmlSelect('changeRate', $maxfps_options, $options['maxfps']);
|
||||||
|
?>
|
||||||
</div>
|
</div>
|
||||||
<div id="sizeControl">
|
<div id="sizeControl">
|
||||||
<span id="widthControl">
|
<span id="widthControl">
|
||||||
|
@ -241,9 +249,8 @@ if ($streamMode == 'jpeg') {
|
||||||
echo 'title="Click to zoom, shift click to pan, ctrl click to zoom out"';
|
echo 'title="Click to zoom, shift click to pan, ctrl click to zoom out"';
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
><?php echo getStreamHTML($monitor, array('scale'=>$scale)); ?>
|
><?php echo getStreamHTML($monitor, $options); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($monitor->Type() != 'WebSite') { ?>
|
<?php if ($monitor->Type() != 'WebSite') { ?>
|
||||||
<div id="monitorStatus">
|
<div id="monitorStatus">
|
||||||
<div id="monitorState">
|
<div id="monitorState">
|
||||||
|
@ -262,8 +269,7 @@ if ($streamMode == 'jpeg') {
|
||||||
<span id="level"><?php echo translate('Buffer') ?>: <span id="levelValue"></span>%</span>
|
<span id="level"><?php echo translate('Buffer') ?>: <span id="levelValue"></span>%</span>
|
||||||
<span id="zoom"><?php echo translate('Zoom') ?>: <span id="zoomValue"></span>x</span>
|
<span id="zoom"><?php echo translate('Zoom') ?>: <span id="zoomValue"></span>x</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons">
|
<div class="buttons" id="dvrControls">
|
||||||
<div id="dvrControls">
|
|
||||||
<?php
|
<?php
|
||||||
if ($streamMode == 'jpeg') {
|
if ($streamMode == 'jpeg') {
|
||||||
if ($monitor->StreamReplayBuffer() != 0) {
|
if ($monitor->StreamReplayBuffer() != 0) {
|
||||||
|
@ -308,7 +314,6 @@ if ($streamMode == 'jpeg') {
|
||||||
} // end if streamMode==jpeg
|
} // end if streamMode==jpeg
|
||||||
?>
|
?>
|
||||||
</div><!--dvrButtons-->
|
</div><!--dvrButtons-->
|
||||||
</div>
|
|
||||||
<?php } // end if $monitor->Type() != 'WebSite' ?>
|
<?php } // end if $monitor->Type() != 'WebSite' ?>
|
||||||
<?php
|
<?php
|
||||||
if ( $showPtzControls ) {
|
if ( $showPtzControls ) {
|
||||||
|
|
Loading…
Reference in New Issue